apply to that specific program only; other changes apply to all of
them.
+Changes in 2.13:
+ * MEMDISK: Fix command-line parsing "brown paper bag" class
+ bug.
+ * MEMDISK: Add "raw" mode to support the DOS boot disk from
+ WinME/XP, which seems to deliberately crash the system
+ when someone uses the "INT 15h mover" highmem API.
+
Changes in 2.12:
* Simple C library, based on klibc, for writing COM32
programs.
mov ah,[bx] ; Copy last status
ret
+ReadMult:
+ TRACER 'm'
Read:
+ TRACER 'R'
call setup_regs
do_copy:
+ TRACER '<'
call bcopy
+ TRACER '>'
movzx ax,P_AL ; AH = 0, AL = transfer count
ret
+WriteMult:
+ TRACER 'M'
Write:
+ TRACER 'W'
test byte [ConfigFlags],01h
jnz .readonly
call setup_regs
ret
; Verify integrity; just bounds-check
+Seek:
Verify:
call setup_regs ; Returns error if appropriate
; And fall through to success
Recalibrate:
InitWithParms:
DetectChange:
-Seek:
+SetMode:
success:
xor ax,ax ; Always successful
ret
add esi,[DiskBuf] ; Get address in high memory
cmp eax,[DiskSize] ; Check the high mark against limit
ja .overrun
- shl ecx,SECTORSIZE_LG2-1 ; Convert count to 16-bit words
+ shl ecx,SECTORSIZE_LG2-2 ; Convert count to 32-bit words
ret
.overrun: pop ax ; Drop setup_regs return address
; Routine to copy in/out of high memory
; esi = linear source address
; edi = linear target address
-; ecx = 16-bit word count
+; ecx = 32-bit word count
;
; Assumes cs = ds = es
;
push ebx
push edx
push ebp
+
+ test byte [ConfigFlags],02h
+ jz .anymode
+
+ smsw ax ; Unprivileged!
+ test al,01h
+ jnz .protmode
+
+.realmode:
+ TRACER 'r'
+ ; We're in real mode, do it outselves
+
+ pushfd
+ push ds
+ push es
+
+ cli
+ cld
+
+ xor ebx,ebx
+ mov bx,cs
+ shl ebx,4
+ lea edx,[Shaker+ebx]
+ mov [Shaker+2],edx
+
+ ; Test to see if A20 is enabled or not
+ xor ax,ax
+ mov ds,ax
+ dec ax
+ mov es,ax
+
+ mov ax,[0]
+ mov bx,ax
+ xor bx,[es:10h]
+ not ax
+ mov [0],ax
+ mov dx,ax
+ xor dx,[es:10h]
+ not ax
+ mov [0],ax
+
+ or dx,bx
+ jnz .skip_a20e
+
+ mov ax,2401h ; Enable A20
+ int 15h
+.skip_a20e:
+
+ lgdt [cs:Shaker]
+ mov eax,cr0
+ or al,01h
+ mov cr0,eax
+
+ mov bx,8
+ mov ds,bx
+ mov es,bx
+
+ a32 rep movsd
+
+ add bx,bx ; BX <- 16
+ mov ds,bx
+ mov es,bx
+
+ and al,~01h
+ mov cr0,eax
+
+ pop es
+ pop ds
+
+ and dx,dx
+ jnz .skip_a20d
+ mov ax,2400h ; Disable A20
+ int 15h
+.skip_a20d:
+ popfd
+ jmp .done
+
+.protmode:
+ TRACER 'p'
+.anymode:
+
.copy_loop:
push esi
push edi
push ecx
- cmp ecx,8000h
+ cmp ecx,4000h
jna .safe_size
- mov ecx,8000h
+ mov ecx,4000h
.safe_size:
push ecx ; Transfer size this cycle
mov eax, esi
mov [Mover_dst2], ah
mov si,Mover
mov ah, 87h
+ shl cx,1 ; Convert to 16-bit words
int 15h
cli ; Some BIOSes enable interrupts on INT 15h
pop eax ; Transfer size this cycle
pop edi
pop esi
jc .error
- lea esi,[esi+2*eax]
- lea edi,[edi+2*eax]
+ lea esi,[esi+4*eax]
+ lea edi,[edi+4*eax]
sub ecx, eax
jnz .copy_loop
; CF = 0
.error:
+.done:
pop ebp
pop edx
pop ebx
dw Invalid ; 14h
dw GetDriveType ; 15h - GET DRIVE TYPE
dw DetectChange ; 16h - DETECT DRIVE CHANGE
+%if 0
+ dw Invalid ; 17h
+ dw Invalid ; 18h
+ dw Invalid ; 19h
+ dw Invalid ; 1Ah
+ dw Invalid ; 1Bh
+ dw Invalid ; 1Ch
+ dw Invalid ; 1Dh
+ dw Invalid ; 1Eh
+ dw Invalid ; 1Fh
+ dw Invalid ; 20h
+ dw ReadMult ; 21h - READ MULTIPLE
+ dw WriteMult ; 22h - WRITE MULTIPLE
+ dw SetMode ; 23h - SET CONTROLLER FEATURES
+ dw SetMode ; 24h - SET MULTIPLE MODE
+ dw Invalid ; 25h - IDENTIFY DRIVE
+ dw Invalid ; 26h
+ dw Invalid ; 27h
+ dw Invalid ; 28h
+ dw Invalid ; 29h
+ dw Invalid ; 2Ah
+ dw Invalid ; 2Bh
+ dw Invalid ; 2Ch
+ dw Invalid ; 2Dh
+ dw Invalid ; 2Eh
+ dw Invalid ; 2Fh
+ dw Invalid ; 30h
+ dw Invalid ; 31h
+ dw Invalid ; 32h
+ dw Invalid ; 33h
+ dw Invalid ; 34h
+ dw Invalid ; 35h
+ dw Invalid ; 36h
+ dw Invalid ; 37h
+ dw Invalid ; 38h
+ dw Invalid ; 39h
+ dw Invalid ; 3Ah
+ dw Invalid ; 3Bh
+ dw Invalid ; 3Ch
+ dw Invalid ; 3Dh
+ dw Invalid ; 3Eh
+ dw Invalid ; 3Fh
+ dw Invalid ; 40h
+ dw EDDPresence ; 41h - EDD PRESENCE DETECT
+ dw EDDRead ; 42h - EDD READ
+ dw EDDWrite ; 43h - EDD WRITE
+ dw EDDVerify ; 44h - EDD VERIFY
+ dw Invalid ; 45h - EDD LOCK/UNLOCK MEDIA
+ dw Invalid ; 46h - EDD EJECT
+ dw EDDSeek ; 47h - EDD SEEK
+ dw EDDGetParms ; 48h - EDD GET PARAMETERS
+%endif
+
Int13FuncsEnd equ $
Int13FuncsMax equ (Int13FuncsEnd-Int13Funcs) >> 1
alignb 8, db 0
+Shaker dw ShakerEnd-$
+ dd 0 ; Pointer to self
+ dw 0
+
+Shaker_DS: dd 0x0000ffff
+ dd 0x008f9300
+
+Shaker_RMDS: dd 0x0000ffff
+ dd 0x00009300
+
+ShakerEnd equ $
+
+ alignb 8, db 0
+
+
Mover dd 0, 0, 0, 0 ; Must be zero
dw 0ffffh ; 64 K segment size
Mover_src1: db 0, 0, 0 ; Low 24 bits of source addy
a) The disk image can be uncompressed or compressed with gzip or zip.
b) If the disk image is one of the following sizes, it's assumed to be a
-floppy image:
+ floppy image:
368,640 bytes - 360K floppy
737,280 bytes - 720K floppy
1,763,328 bytes - 1722K floppy (common extended format)
2,949,120 bytes - 2880K floppy
-For any other size, the image is assumed to be a hard disk image, and
-should typically have an MBR and a partition table. It may optionally
-have a DOSEMU geometry header; in which case the header is used to
-determine the C/H/S geometry of the disk. Otherwise, the geometry is
-determined by examining the partition table, so the entire image
-should be partitioned for proper operation (it may be divided between
-multiple partitions, however.)
+ For any other size, the image is assumed to be a hard disk image,
+ and should typically have an MBR and a partition table. It may
+ optionally have a DOSEMU geometry header; in which case the header
+ is used to determine the C/H/S geometry of the disk. Otherwise,
+ the geometry is determined by examining the partition table, so the
+ entire image should be partitioned for proper operation (it may be
+ divided between multiple partitions, however.)
-You can also specify the geometry manually with the following command
-line options (currently untested):
+ You can also specify the geometry manually with the following command
+ line options:
c=<number> Specify number of cylinders (max 1024[*])
h=<number> Specify number of heads (max 256[*])
floppy The image is a floppy image
harddisk The image is a hard disk image
-
-[*] MS-DOS only allows max 255 heads, and only allows 255 cylinders
- on floppy disks.
+ [*] MS-DOS only allows max 255 heads, and only allows 255 cylinders
+ on floppy disks.
c) The disk is normally writable (although, of course, there is
-nothing backing it up, so it only lasts until reset.) If you want,
-you can mimic a write-protected disk by specifying the command line
-option:
+ nothing backing it up, so it only lasts until reset.) If you want,
+ you can mimic a write-protected disk by specifying the command line
+ option:
ro Disk is readonly
+d) MEMDISK normally uses the BIOS "INT 15h mover" API to access high
+ memory. This is well-behaved with extended memory managers which load
+ later. Unfortunately it appears that the "DOS boot disk" from
+ WinME/XP *deliberately* crash the system when this API is invoked.
+ The following command-line option tells MEMDISK to enter protected
+ mode directly, whenever possible:
+
+ raw Use raw access to protected mode memory
+
+
Some interesting things to note:
section .text ; Must be first in image
bits 16
- times 497 db 0 ; Start of header
+cmdline times 497 db 0 ; We put the command line here
setup_sects db 0
root_flags dw 0
syssize dw 0
mov gs,ax
mov cx,496 ; Max number of bytes
.copycmd:
- lodsb
+ gs lodsb
and al,al
jz .endcmd
stosb
uint8_t drivecnt;
uint8_t configflags;
#define CONFIG_READONLY 0x01
+#define CONFIG_RAW 0x02
uint16_t mystack;
uint16_t statusptr;
asm volatile("hlt");
}
-#define STACK_NEEDED 256 /* Number of bytes of stack */
+#define STACK_NEEDED 512 /* Number of bytes of stack */
/*
* Actual setup routine
pptr->statusptr = (geometry->driveno & 0x80) ? 0x474 : 0x441;
pptr->configflags = 0;
- /* Readonly? */
+ /* Set config flags */
if ( getcmditem("ro") != CMD_NOTFOUND ) {
- printf("Marking disk readonly\n");
+ puts("Marking disk readonly\n");
pptr->configflags |= CONFIG_READONLY;
}
+ if ( getcmditem("raw") != CMD_NOTFOUND ) {
+ puts("Using raw access to high memory\n");
+ pptr->configflags |= CONFIG_RAW;
+ }
/* Set up a drive parameter table */
if ( geometry->driveno & 0x80 ) {