Harden drive.asm against unexpected DS and ES values
This commit is contained in:
		
							parent
							
								
									df243e668e
								
							
						
					
					
						commit
						440187c2a8
					
				
					 3 changed files with 87 additions and 69 deletions
				
			
		|  | @ -38,7 +38,9 @@ relinit:	; print banner | ||||||
| 		db "RDOS ",2,2, 0x0A, 0x0D, 0 | 		db "RDOS ",2,2, 0x0A, 0x0D, 0 | ||||||
| 
 | 
 | ||||||
| 		push dx | 		push dx | ||||||
|  | 		push ds | ||||||
| 		call dinit | 		call dinit | ||||||
|  | 		pop ds | ||||||
| 		pop dx | 		pop dx | ||||||
| 
 | 
 | ||||||
| 		mov word [0x21*4], int21 | 		mov word [0x21*4], int21 | ||||||
|  |  | ||||||
							
								
								
									
										116
									
								
								kernel/drive.asm
									
										
									
									
									
								
							
							
						
						
									
										116
									
								
								kernel/drive.asm
									
										
									
									
									
								
							|  | @ -34,63 +34,66 @@ section .text | ||||||
| 
 | 
 | ||||||
| 		; initial setup for disk i/o | 		; initial setup for disk i/o | ||||||
| dinit:		; copy previously set DPT to our data area | dinit:		; copy previously set DPT to our data area | ||||||
| 		lds si, [4*0x1E] | 		push cs | ||||||
|  | 		pop es | ||||||
|  | 		lds si, [es:4*0x1E] | ||||||
| 		mov di, dpt | 		mov di, dpt | ||||||
| 		mov cx, 11 | 		mov cx, 11 | ||||||
| 		rep movsb | 		rep movsb | ||||||
| 		; restore DS |  | ||||||
| 		xor ax, ax |  | ||||||
| 		mov ds, ax |  | ||||||
| 		; set vector | 		; set vector | ||||||
| 		mov word [4*0x1E], dpt | 		mov word [cs:4*0x1E], dpt | ||||||
| 		mov word [4*0x1E+2], ds | 		mov word [cs:4*0x1E+2], ds | ||||||
| 		; set to invalid drive | 		; set to invalid drive | ||||||
| 		mov byte [dsknum], 0xFF | 		mov byte [cs:dsknum], 0xFF | ||||||
| 		ret | 		ret | ||||||
| 
 | 
 | ||||||
| 		; int 13 stub | 		; int 13 stub | ||||||
| int13:		; debug output | int13:		; debug output | ||||||
| 		;push bx | 		push bx | ||||||
| 		;push dx | 		push dx | ||||||
| 		;push cx | 		push cx | ||||||
| 		;push ax | 		push ax | ||||||
| 		;call printf | 		call printf | ||||||
| 		;db "int13 CALL AX=",2," CX=",2," DX=",2," BX=",2,0x0A,0x0D,0 | 		db "int13 CALL AX=",2," CX=",2," DX=",2," BX=",2,0x0A,0x0D,0 | ||||||
| 		; do the call | 		; do the call | ||||||
| 		int 0x13 | 		int 0x13 | ||||||
| 		;jc .err | 		jc .err | ||||||
|  | 		ret | ||||||
|  | .err:		push ax | ||||||
|  | 		call printf | ||||||
|  | 		db "DISK ERR AX=",2,0x0A,0x0D,0 | ||||||
|  | 		stc | ||||||
| 		ret | 		ret | ||||||
| .err:		;push ax |  | ||||||
| 		;call printf |  | ||||||
| 		;db "DISK ERR AX=",2,0x0A,0x0D,0 |  | ||||||
| 		;stc |  | ||||||
| 		;ret |  | ||||||
| 
 | 
 | ||||||
| 		; get drive parameters | 		; get drive parameters | ||||||
| 		; read BIOS int13h/AH=8 values | 		; read BIOS int13h/AH=8 values | ||||||
| 		; DPT data gets copied over our dpt | 		; DPT data gets copied over our dpt | ||||||
| 		; CHS data gets inserted into our bpb | 		; CHS data gets inserted into our bpb | ||||||
| getprm:		test byte [dskflag], 4 | getprm:		; skip if EBIOS extension enabled | ||||||
| 		jnz .nodpt | 		test byte [cs:dskflag], 4 | ||||||
|  | 		jnz .ret | ||||||
| 		; do the query | 		; do the query | ||||||
| 		mov ah, 8 | 		mov ah, 8 | ||||||
| 		mov dl, [biosnum] | 		mov dl, [cs:biosnum] | ||||||
| 		call int13 | 		call int13 | ||||||
| 		; bail out if error | 		; bail out if error | ||||||
| 		jc .nodpt | 		jc .ret | ||||||
|  | 		; ignore CHS values if odd | ||||||
|  | 		test cl, cl | ||||||
|  | 		jz .nochs | ||||||
| 		; get and store sector number | 		; get and store sector number | ||||||
| 		and cx, 0x3F | 		and cx, 0x3F | ||||||
| 		mov word [bpb+BPBSPT], cx | 		mov word [cs:bpb+BPBSPT], cx | ||||||
| 		; get and store number of heads | 		; get and store number of heads | ||||||
| 		xchg dl, dh | 		xchg dl, dh | ||||||
| 		and dx, 0xFF | 		and dx, 0xFF | ||||||
| 		inc dx | 		inc dx | ||||||
| 		mov [bpb+BPBNOS], dx | 		mov [cs:bpb+BPBNOS], dx | ||||||
| 		; test if DPT ptr is non-zero | 		; test if DPT ptr is non-zero | ||||||
| .nochs:		mov ax, es | .nochs:		mov ax, es | ||||||
| 		or ax, di | 		or ax, di | ||||||
| 		test ax, ax | 		test ax, ax | ||||||
| 		jz .nodpt | 		jz .ret | ||||||
| 		; DS:SI = ES:DI | 		; DS:SI = ES:DI | ||||||
| 		mov ax, es | 		mov ax, es | ||||||
| 		mov ds, ax | 		mov ds, ax | ||||||
|  | @ -102,20 +105,21 @@ getprm:		test byte [dskflag], 4 | ||||||
| 		; do the copy | 		; do the copy | ||||||
| 		mov cx, 11 | 		mov cx, 11 | ||||||
| 		rep movsb | 		rep movsb | ||||||
| .nodpt:		; restore segment registers | .ret:		ret | ||||||
| 		xor ax, ax |  | ||||||
| 		mov ds, ax |  | ||||||
| 		mov es, ax |  | ||||||
| 		ret |  | ||||||
| 
 | 
 | ||||||
| 		; log in drive | 		; log in drive | ||||||
| 		; IN	dl	drive number | 		; IN	dl	drive number | ||||||
| logdrv:		; dont do anything if drive already selected | logdrv:		; DS := CS | ||||||
|  | 		push cs | ||||||
|  | 		pop ds | ||||||
|  | 		; dont do anything if drive already selected | ||||||
| 		cmp dl, [dsknum] | 		cmp dl, [dsknum] | ||||||
| 		je logfdd.ret | 		je logfdd.ret | ||||||
| 		; clear out current contents | 		; clear out current contents | ||||||
| 		push dx | 		push dx | ||||||
|  | 		push ds | ||||||
| 		call flush | 		call flush | ||||||
|  | 		pop ds | ||||||
| 		mov ax, 0xFFFF | 		mov ax, 0xFFFF | ||||||
| 		mov [dskseek], ax | 		mov [dskseek], ax | ||||||
| 		mov [dskseek+2], ax | 		mov [dskseek+2], ax | ||||||
|  | @ -130,16 +134,22 @@ logdrv:		; dont do anything if drive already selected | ||||||
| logfdd:		; save info for bios | logfdd:		; save info for bios | ||||||
| 		mov [biosnum], dl | 		mov [biosnum], dl | ||||||
| 		; reset dpt to defaults | 		; reset dpt to defaults | ||||||
|  | 		push ds | ||||||
| 		call getprm | 		call getprm | ||||||
|  | 		pop ds | ||||||
| 		; set default geometry (1.44 MB floppy) | 		; set default geometry (1.44 MB floppy) | ||||||
| 		mov word [bpb+BPBNOS], 2 | 		mov word [bpb+BPBNOS], 2 | ||||||
| 		mov word [bpb+BPBSPT], 18 | 		mov word [bpb+BPBSPT], 18 | ||||||
| 		; load boot sector | 		; load boot sector | ||||||
|  | 		push ds | ||||||
| 		xor ax, ax | 		xor ax, ax | ||||||
| 		xor dx, dx | 		xor dx, dx | ||||||
| 		call mapabs | 		call mapabs | ||||||
|  | 		pop ds | ||||||
| 		; copy bios parameter block | 		; copy bios parameter block | ||||||
| 		; TODO: guess from first byte of FAT if BPB invalid | 		; TODO: guess from first byte of FAT if BPB invalid | ||||||
|  | 		push ds | ||||||
|  | 		pop es | ||||||
| 		mov si, dskbuf+BPBOFF | 		mov si, dskbuf+BPBOFF | ||||||
| 		mov di, bpb | 		mov di, bpb | ||||||
| 		mov cx, BPBSIZ4 | 		mov cx, BPBSIZ4 | ||||||
|  | @ -153,6 +163,7 @@ logfdd:		; save info for bios | ||||||
| 		mov [bpb+BPBHS+2], ax | 		mov [bpb+BPBHS+2], ax | ||||||
| .ret:		ret | .ret:		ret | ||||||
| 
 | 
 | ||||||
|  | 		; assumes that DS == CS | ||||||
| loghdd:		sub dl, 2 | loghdd:		sub dl, 2 | ||||||
| 		cmp dl, 4 | 		cmp dl, 4 | ||||||
| 		jnc logerr | 		jnc logerr | ||||||
|  | @ -187,17 +198,20 @@ loghdd:		sub dl, 2 | ||||||
| 		mov cl, 4 | 		mov cl, 4 | ||||||
| 		sal bx, cl | 		sal bx, cl | ||||||
| 		; bail out if no partition | 		; bail out if no partition | ||||||
| 		cmp byte [dskbuf+0x1be+bx+4], 0 | 		cmp byte [cs:dskbuf+0x1be+bx+4], 0 | ||||||
| 		je logerr | 		je logerr | ||||||
| 		; load partition offset | 		; load partition offset | ||||||
| 		mov ax, [dskbuf+0x1be+bx+8] | 		mov ax, [cs:dskbuf+0x1be+bx+8] | ||||||
| 		mov dx, [dskbuf+0x1be+bx+8+2] | 		mov dx, [cs:dskbuf+0x1be+bx+8+2] | ||||||
| 		; save to to stack | 		; save to to stack | ||||||
| 		push dx | 		push dx | ||||||
| 		push ax | 		push ax | ||||||
| 		; load vbr | 		; load vbr | ||||||
| 		call mapabs | 		call mapabs | ||||||
| 		; copy bpb | 		; copy bpb | ||||||
|  | 		mov ax, cs | ||||||
|  | 		mov ds, ax | ||||||
|  | 		mov es, ax | ||||||
| 		mov si, dskbuf+BPBOFF | 		mov si, dskbuf+BPBOFF | ||||||
| 		mov di, bpb | 		mov di, bpb | ||||||
| 		mov cx, BPBSIZ4 | 		mov cx, BPBSIZ4 | ||||||
|  | @ -207,15 +221,15 @@ loghdd:		sub dl, 2 | ||||||
| 		; fix partition offset | 		; fix partition offset | ||||||
| 		pop ax | 		pop ax | ||||||
| 		pop dx | 		pop dx | ||||||
| 		mov [bpb+BPBHS], ax | 		mov [cs:bpb+BPBHS], ax | ||||||
| 		mov [bpb+BPBHS+2], dx | 		mov [cs:bpb+BPBHS+2], dx | ||||||
| 		ret | 		ret | ||||||
| 
 | 
 | ||||||
| logerr:		stc | logerr:		stc | ||||||
| 		ret | 		ret | ||||||
| 
 | 
 | ||||||
| mapclu:		; counting from begin of cluster area | mapclu:		; counting from begin of cluster area | ||||||
| 		mov bx, [bpb+BPBRDE] | 		mov bx, [cs:bpb+BPBRDE] | ||||||
| 		mov cl, 4 | 		mov cl, 4 | ||||||
| 		shr bx, cl ; 32 bytes per entry | 		shr bx, cl ; 32 bytes per entry | ||||||
| 		add ax, bx | 		add ax, bx | ||||||
|  | @ -223,22 +237,22 @@ mapclu:		; counting from begin of cluster area | ||||||
| maprd:		; counting from beginning of dir | maprd:		; counting from beginning of dir | ||||||
| 		; add fat table sizes | 		; add fat table sizes | ||||||
| 		xor ch, ch | 		xor ch, ch | ||||||
| 		mov cl, byte [bpb+BPBFN] | 		mov cl, byte [cs:bpb+BPBFN] | ||||||
| .loop:		add ax, [bpb+BPBFS] | .loop:		add ax, [cs:bpb+BPBFS] | ||||||
| 		adc dx, 0 | 		adc dx, 0 | ||||||
| 		loop .loop | 		loop .loop | ||||||
| mapfat:		; counting from beginning of FAT | mapfat:		; counting from beginning of FAT | ||||||
| 		; add reserved sector count | 		; add reserved sector count | ||||||
| 		add ax, [bpb+BPBRSC] | 		add ax, [cs:bpb+BPBRSC] | ||||||
| 		adc dx, 0 | 		adc dx, 0 | ||||||
| map:		; count from partition start | map:		; count from partition start | ||||||
| 		add ax, [bpb+BPBHS] | 		add ax, [cs:bpb+BPBHS] | ||||||
| 		add dx, [bpb+BPBHS+2] | 		add dx, [cs:bpb+BPBHS+2] | ||||||
| mapabs:		; absolute sector count | mapabs:		; absolute sector count | ||||||
| 		; skip doing a read if sector number matches | 		; skip doing a read if sector number matches | ||||||
| 		cmp ax, [dskseek] | 		cmp ax, [cs:dskseek] | ||||||
| 		jne read | 		jne read | ||||||
| 		cmp dx, [dskseek+2] | 		cmp dx, [cs:dskseek+2] | ||||||
| 		jne read | 		jne read | ||||||
| 		ret | 		ret | ||||||
| 
 | 
 | ||||||
|  | @ -248,8 +262,8 @@ read:		push ax | ||||||
| 		pop dx | 		pop dx | ||||||
| 		pop ax | 		pop ax | ||||||
| 		; store the sector number | 		; store the sector number | ||||||
| 		mov [dskseek], ax | 		mov [cs:dskseek], ax | ||||||
| 		mov [dskseek+2], dx | 		mov [cs:dskseek+2], dx | ||||||
| 		; do the actual read | 		; do the actual read | ||||||
| 
 | 
 | ||||||
| 		; low level read and write | 		; low level read and write | ||||||
|  | @ -259,6 +273,10 @@ _read:		mov ch, 2 | ||||||
| 		db 0x3D ; cmp ax, imm16: causes next instr to be skipped | 		db 0x3D ; cmp ax, imm16: causes next instr to be skipped | ||||||
| _write:		mov ch, 3 | _write:		mov ch, 3 | ||||||
| 		mov cl, 1 ; read len | 		mov cl, 1 ; read len | ||||||
|  | 		; DS := ES := CS | ||||||
|  | 		mov ax, cs | ||||||
|  | 		mov ds, ax | ||||||
|  | 		mov es, ax | ||||||
| 		; check if ebios supported | 		; check if ebios supported | ||||||
| 		test byte [dskflag], 4 | 		test byte [dskflag], 4 | ||||||
| 		jz .l00 | 		jz .l00 | ||||||
|  | @ -322,11 +340,11 @@ _write:		mov ch, 3 | ||||||
| 		ret | 		ret | ||||||
| 
 | 
 | ||||||
| 		; mark dskbuf as containing unwritten changes | 		; mark dskbuf as containing unwritten changes | ||||||
| dirty:		or byte [dskflag], 1 ; dirty | dirty:		or byte [cs:dskflag], 1 ; dirty | ||||||
| 		ret | 		ret | ||||||
| 
 | 
 | ||||||
| 		; flush buffer if dirty | 		; flush buffer if dirty | ||||||
| flush:		test byte [dskflag], 1 | flush:		test byte [cs:dskflag], 1 | ||||||
| 		jz .ret | 		jz .ret | ||||||
| 		; TODO: error handling & retries | 		; TODO: error handling & retries | ||||||
| 		jmp _write | 		jmp _write | ||||||
|  |  | ||||||
|  | @ -3,7 +3,7 @@ section .text | ||||||
| 		; set default drive for current process | 		; set default drive for current process | ||||||
| 		; IN	dl	drive number | 		; IN	dl	drive number | ||||||
| setdd:		push ds | setdd:		push ds | ||||||
| 		mov ds, [ss:curpsp] | 		mov ds, [cs:curpsp] | ||||||
| 		mov [PSPDD], dl | 		mov [PSPDD], dl | ||||||
| 		pop ds | 		pop ds | ||||||
| 		ret | 		ret | ||||||
|  | @ -11,11 +11,23 @@ setdd:		push ds | ||||||
| 		; get default drive for current process | 		; get default drive for current process | ||||||
| 		; OUT	al	drive number | 		; OUT	al	drive number | ||||||
| getdd:		push ds | getdd:		push ds | ||||||
| 		mov ds, [ss:curpsp] | 		mov ds, [cs:curpsp] | ||||||
| 		mov al, [PSPDD] | 		mov al, [PSPDD] | ||||||
| 		pop ds | 		pop ds | ||||||
| 		ret | 		ret | ||||||
| 
 | 
 | ||||||
|  | 		; auto-complete drive field in fcb | ||||||
|  | 		; IN	ds:dx	far ptr FCB | ||||||
|  | 		; OUT	si	copy of dx | ||||||
|  | fixfcb:		mov si, dx | ||||||
|  | 		cmp byte [si], 0 | ||||||
|  | 		jne .ret | ||||||
|  | 		call getdd | ||||||
|  | 		inc dl | ||||||
|  | 		mov byte [si], dl | ||||||
|  | .ret:		mov dx, si | ||||||
|  | 		ret | ||||||
|  | 
 | ||||||
| 		; Load root directory entry | 		; Load root directory entry | ||||||
| 		; IN	ax	number of directory entry | 		; IN	ax	number of directory entry | ||||||
| lddir:		push ax | lddir:		push ax | ||||||
|  | @ -56,22 +68,8 @@ fnfile:		mov ax, [es:bx+FCBDEN] | ||||||
| .err:		stc | .err:		stc | ||||||
| 		ret | 		ret | ||||||
| 
 | 
 | ||||||
| 		; initialize a FCB for directory scanning | 		; Open file using FCB | ||||||
| open:		mov word [es:bx+FCBDEN], 0 | 		; IN	DS:DX	far ptr to FCB | ||||||
| .search:	call fnfile | open:		call fixfcb | ||||||
| 		mov al, 0xFF | 		int 3 | ||||||
| 		jc .ret |  | ||||||
| 		push si |  | ||||||
| 		lea di, [bx+1] |  | ||||||
| 		mov cx, 11 |  | ||||||
| 		rep cmpsb |  | ||||||
| 		pop si |  | ||||||
| 		jne .search |  | ||||||
| 		mov al, 0 |  | ||||||
| .ret:		ret |  | ||||||
| 
 |  | ||||||
| putfn:		mov cx, 11 |  | ||||||
| .loop:		lodsb |  | ||||||
| 		call pputc |  | ||||||
| 		loop .loop |  | ||||||
| 		ret | 		ret | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue