⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sstdisk.8

📁 tiny bios--了解BIOS非常好的资料
💻 8
字号:
	;
	; ROM disk driver for SST 28SF040 flash, P3SX / M6117 platform.
	; Update fldpage and romseg depending on your hardware !
	;
	; (C)1998 Pascal Dornier / PC Engines; All rights reserved.
	; This file is licensed pursuant to the COMMON PUBLIC LICENSE 0.5.
	;

	;
	; equates
	;
#if def	DEBUG
FLD_DEBUG: 		;enable for debug code
#endif

romseg	equ	0e000h	;ROM segment
disktab	equ	0522h	;DOS drive parameter table &&&
secsize	equ	512	;sector size (hard coded)
maxsec	equ	1024-32	;sector count -> top of disk
			;(deducting BIOS)
secpertrk	equ	9	;(hard coded)
	;
	; variables (allocated on stack)
	;
fl_secno	equ	0FFFEh	;sector number
fl_seccnt	equ	0FFFCh	;sector count
	;
	; Flash disk INT 13 entry
	;
fldisk:	sti
	push	ds	;save registers
	push	es
	pusha
	mov	bp,sp	;access to stack frame
	sub	sp,4	;allocate variables
#if def	FLD_DEBUG
	call	v_dump	;& dump registers
#endif
	xor	di,di	;access BIOS segment
	mov	ds,di
	
	cmp	ah,1	;status: return last status
	jz	fldstat
	mov	byte [bp._ah],0	;clear status
	cmp	ah,2	;:read
	jz	fldread
	cmp	ah,0	;:reset -> ok status
	jz	fldexit
	cmp	ah,4	;:verify
	jnz	fldisk3
	jmp	fldverf
fldisk3:	cmp	ah,3	;:write
	jnz	fldisk4
	jmp	fldwrt
fldisk4:	cmp	ah,5	;:format
	jnz	fldisk5
	jmp	fldform
fldisk5:	cmp	ah,15h	;:drive type
	jz	fldtype
	cmp	ah,8	;:drive parameters
	jz	fldparm
	mov	al,1	;bad command
	jmp	short flderr
	;
	; return last status
	;
fldstat:	mov	al,[m_fdstat]
flderr:	mov	[bp._ah],al
       	;
       	; return status
       	;
fldexit:	xor	bx,bx	;set BIOS segment
	mov	ds,bx
	mov	al,[bp._ah]	;status code
	mov	[m_fdstat],al	;store in status flag
	and	al,al	;error ?
	jz	fld_exit2
	or	byte [bp+18h],1	;yes: set carry
fld_exit2:
#if def	FLD_DEBUG
	call	v_dump2	;& dump registers
#endif
	add	sp,4	;deallocate variables
	popa		;restore registers
	pop	es
	pop	ds
	iret		;return from interrupt
	;
	; return disk type
	;
fldtype:	mov	al,1	;1 = floppy, no drive change
	jmp	flderr
	;
	; return disk parameters
	;
fldparm:	mov	[bp._es],cs	;ES: CS
	mov	word [bp._bx],3	;drive type = 3 (720 KB)
	mov	word [bp._cx],79*256+9	;40 tracks, 9 sectors
	mov	word [bp._dx],1*256+2	;2 heads (DH), 2 drives
	mov	word [bp._di],fd_ptab	;^drive parameters
	jmp	fldexit
	;
	; read sectors
	;	
	; AL = #sectors	-> AL = #sectors read
	; 		-> AH = status
	; CH = track
	; CL = sector
	; DH = head
	; DL = drive (0)
	; ES:BX = destination address
	;
fldread:	call	fldcalc	;calculate sector number
	mov	di,bx	;destination address
	;
	; transfer loop
	;
	cmp 	byte [bp.fl_seccnt],0	;another sector to do ?
	jz	fldread9	;:no
	;
	; convert sector number into page number
	;
fldread1:	call	fldpage	;set page register, AX = offset
	mov	si,ax	;^ROM data
	jnb	fldread2	;:ok
	mov 	byte [bp._ah],10h	;CRC error
	jmp	short fldread9
	;
	; transfer data
	;
fldread2:	mov	cx,secsize/4
fldread3:	lodsd		;data is inverted
	not 	eax
	stosd
	loop	fldread3
	inc	word [bp.fl_secno]	;next sector number
	inc	byte [bp._al]	;count sectors transferred
	dec 	byte [bp.fl_seccnt]	;another block ?
	jnz	fldread1	;:yes
fldread9:	jmp	fldexit
	;
	; verify sectors
	;	
	; AL = #sectors	-> AL = #sectors verified
	; 		-> AH = status
	; CH = track
	; CL = sector
	; DH = head
	; DL = drive (0)
	;
fldverf:	call	fldcalc	;calculate sector number
	cmp 	byte [bp.fl_seccnt],0	;another sector to do ?
	jz	fldread9	;:no
	;
	; verify loop
	;
fldverf1:	cmp	word [bp.fl_secno],maxsec	;ok sector number ?
	jb	fldverf2	;:yes
	mov 	byte [bp._ah],10h	;CRC error
	jmp	short fldread9
fldverf2:	inc	word [bp.fl_secno]	;next sector number
	inc 	byte [bp._al]	;count sectors transferred
	dec 	byte [bp.fl_seccnt]	;another block ?
	jnz	fldverf1	;:yes
	jmp	fldexit	;return
	;
	; write sectors
	;	
	; AL = #sectors	-> AL = #sectors written
	; 		-> AH = status
	; CH = track
	; CL = sector
	; DH = head
	; DL = drive (0)
	; ES:BX = source address
	;
fldwrt:	call	fldcalc	;calculate sector number
	mov	si,bx	;source address
	;
	; transfer loop
	;
	cmp 	byte [bp.fl_seccnt],0	;another sector to do ?
	jz	fldwrt9	;:no
	;
	; convert sector number into page number
	;
fldwrt1:	call	fldpage	;set page register, AX = offset
	jnb	fldwrt2	;:ok
	mov 	byte [bp._ah],4	;sector not found
	jmp	short fldwrt9
	;
	; write sector
	;
fldwrt2:	mov	di,ax	;^ROM data
	call	fldwbk	;write 256 byte block
	call	fldwbk	;write 256 byte block
	inc	word [bp.fl_secno]	;next sector number
	inc 	byte [bp._al]	;count sectors transferred
	dec 	byte [bp.fl_seccnt]	;another block ?
	jnz	fldwrt1	;:yes
fldwrt9:	jmp	fldexit
	;
	; format track
	;
	; AL = #sectors (ignored)	-> AL = clobbered
	; 		-> AH = status
	; CH = track
	; DH = head
	; DL = drive (0)
	; ES:BX -> format buffer (ignored)
	;
fldform:	mov	cl,1	;first sector of track
	call	fldcalc2	;calculate sector number
	mov	word [bp.fl_seccnt],9
	;
	; format loop
	;
fldform1:	cmp	word [bp.fl_secno],maxsec	;ok sector number ?
	jb	fldform2	;:ok
	mov 	byte [bp._ah],4
	jmp	fldwrt9
fldform2:	mov	al,[1823h]	;unlock -> write enable
	mov	al,[1820h]
	mov	al,[1822h]
	mov	al,[0418h]
	mov	al,[041Bh]
	mov	al,[0419h]
	mov	al,[041Ah]
	call	fldpage	;set page, offset
	mov	di,ax
	mov	byte [di],20h	;sector erase setup command
	mov	byte [di],0d0h	;sector erase execute command
	call	fldwait
	add	di,256
	mov	byte [di],20h	;sector erase setup command
	mov	byte [di],0d0h	;sector erase execute command
	call	fldwait
	inc	word [bp.fl_secno]	;next sector number
	dec 	byte [bp.fl_seccnt]	;another block ?
	jnz	fldform1	;:yes
	mov	al,[1823h]	;lock -> write disable
	mov	al,[1820h]
	mov	al,[1822h]
	mov	al,[0418h]
	mov	al,[041Bh]
	mov	al,[0419h]
	mov	al,[040Ah]
	jmp	fldwrt9	;return
	;
	; write a 256 byte block
	;
fldwbk:	push	si
	push	di
	mov	al,[1823h]	;unlock -> write enable
	mov	al,[1820h]
	mov	al,[1822h]
	mov	al,[0418h]
	mov	al,[041Bh]
	mov	al,[0419h]
	mov	al,[041Ah]
	mov	cx,128
fldwbk1:	mov	ax,[es:si]	;write data OR flash = flash ?
	not	ax
	mov	dx,[di]	;(we can clear bits, but not set them
	or	ax,dx	;without erase)
	cmp	ax,dx
	jnz	fldwbk2	;:no, we need to erase block
	add	si,2
	add	di,2
	loop	fldwbk1
	jmp	short fldwbk3	;skip erase
	;
	; erase 256 byte block
	;
fldwbk2:	mov	byte [di],20h	;sector erase setup command
	mov	byte [di],0d0h	;sector erase execute command
	call	fldwait
	;
	; write 256 byte block
	;
fldwbk3:	pop	di	;restore pointers
	pop	si
	mov	cx,256
fldwbk4:	mov	al,[es:si]	;source data
	not	al	;invert data
	mov	byte [di],10h	;byte program command
	mov	[di],al	;write data
	xor	dx,dx	;time-out counter
fldwbk5:	dec	dx
	jz	fldwbk6	;:bail out
	cmp	[di],al	;= data written ?
	jnz	fldwbk5	;:no
	cmp	[di],al	;= data written, second time ?
	jnz	fldwbk5
fldwbk6:	inc	si
	inc	di
	loop	fldwbk4	;:next byte	
	mov	al,[1823h]	;lock -> write disable
	mov	al,[1820h]
	mov	al,[1822h]
	mov	al,[0418h]
	mov	al,[041Bh]
	mov	al,[0419h]
	mov	al,[040Ah]
	ret
	;
	; wait for completion of write cycle
	;
fldwait:	xor	cx,cx	;timeout counter
	mov	al,[di]	;ROM status
fldwait1:	mov	ah,al
	mov	al,[di]
	cmp	al,ah
	jz	fldwait2	;end if same data for two reads
	loop	fldwait1	;timeout to prevent hangs
fldwait2:	ret
	;
	; calculate sector number -> secno
	;
fldcalc:	mov	byte [bp._al],0	;clear transfer count
fldcalc2:	mov	[bp.fl_seccnt],al	;save sector count
	xor	ax,ax	;clear sector number
	xchg	al,ch	;swap 0 with track number
	shl	al,1	;assume two heads
	add	al,dh	;head
	add	cx,ax	;sector + cylinder -> CX
	shl	ax,3	;cylinder * 8 -> AX
	add	ax,cx	;sector + cylinder * 9 -> AX
	dec	ax	;-1 for sector num starting at 1
	mov	[bp.fl_secno],ax
	cld		;forward move
	mov	ax,romseg	;set flash segment
	mov	ds,ax
	ret
	;
	; set page register, offset in AX from secno
	;
	; CY set = error; DS must point to ROM segment
	;
fldpage:	mov	al,68h	;set chipset index
	out	idx,al
	mov	ax,[bp.fl_secno]	;sector number
	cmp	ax,maxsec	;reached maximum sector number ?
	jae	fldpage9	;:yes, limit and overflow
	shr	ax,7	;-> page number
	out	dat,al	;set page register
	mov	al,73h	;strobe page register
	out	idx,al
	out	dat,al
	mov	ax,[bp.fl_secno]	;sector number again
	shl	ax,9	;-> page offset
	clc		;ok: return
	ret	
fldpage9:	stc		;error: sector number to high
	ret
	;
	; initialize flash disk
	;
fld_init:	mov	al,10h	;enable E000 ROM decode
	out	idx,al
	in	al,dat
	mov	ah,al
	mov	al,10h
	out	idx,al
	mov	al,ah
	or	al,1
	out	dat,al
	
	mov	al,15h	;disable E000 shadow RAM
	out	idx,al
	in	al,dat
	mov	ah,al
	mov	al,15h
	out	idx,al
	mov	al,ah
	and	al,0f0h
	out	dat,al
	
	mov	al,20h	;enable write to flash ROM
	out	idx,al
	in	al,dat
	mov	ah,al
	mov	al,20h
	out	idx,al
	mov	al,ah
	or	al,4
	out	dat,al

	mov	ax,romseg	;flash segment
	mov	ds,ax
	mov	al,[1823h]	;lock -> write disable
	mov	al,[1820h]
	mov	al,[1822h]
	mov	al,[0418h]
	mov	al,[041Bh]
	mov	al,[0419h]
	mov	al,[040Ah]
	;
	; update number of drives in equipment flag
	;
	xor	ax,ax	;access BIOS segment
	mov	ds,ax
	mov	al,[m_devflg]
	test	al,1	;any boot drive ?
	jz	fldini0	;:nothing yet
      	add	al,40h	;increment number of drives
	jmp	short fldini1
fldini0:	or	al,1	;yes, there's one drive
	and	al,3fh	;1 drive
fldini1:	mov	[m_devflg],al	;update equipment flag
	ret

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -