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

📄 fs.asm

📁 6502bios,关于6502的sbc,有lcd,time,irq,模块
💻 ASM
字号:
; Hard disk filesystem
; Chris Ward, 21/1/2000

;partition table filesystem codes
FS_HDFS	EQU 01

HDFSVER	EQU 01		;filesystem version

MAGPART	fcs "CNWPART"	;magic word for partition table
MAGHDFS	fcs "CNWHDFS"	;magic word for file system

; *** FSINIT: Initialise filesystem
FSINIT	LDY #7		;fill logical drive table with 00 (no drive)
	LDA #$00
FSINIT0	STA DRIVES,Y
	DEY
	BPL FSINIT0

	LDA #0		;set up to read partition table (sector 0)
	STA IDELBA0
	STA IDELBA1
	STA IDELBA2
	STA IDELBA3
	LDA #IDEBUF0
	STA IDEBUFP
	LDA #IDEBUF0/256
	STA IDEBUFP+1
	JSR IDERSEC	;read sector into buffer

	LDX #6		;check for 7-letter magic word
FSINIT1	LDA IDEBUF0,X
	CMP MAGPART,X
	BNE FSINIT5	;fail
	DEX
	BPL FSINIT1	;check next letter

	LDX #16		;offset of first partition entry
	LDA #1		;count partition number
	STA ZTMP1
	LDY #0		;count logical drive number
FSINIT2	LDA IDEBUF0,X	;get filesystem type
	BEQ FSINIT3	;00 = no partition
	CMP FS_HDFS	;check for HDFS
	BNE FSINIT3
	LDA ZTMP1
	STA DRIVES,Y	;store drive code
	JSR HDFSINIT	;initialise HDFS on this partition
	INY
FSINIT3	INC ZTMP1		;increment partition number
	LDA ZTMP1
	CMP #7		;max 7 partitions
	BEQ FSINIT5
	TXA
	CLC
	ADC #16		;move to next partition entry
	TAX
	JMP FSINIT2

FSINIT5
	RTS

; *** HDFSINIT: Initialise HDFS filesystem on a given partition
; (called from FSINIT)
; X=offset of partition entry in IDEBUF0
; Y=logical drive number
HDFSINIT	STX ZTMP2		;save X and Y
	STY ZTMP3

	TYA
	ASL		;offset in drive table = drive number * 16
	ASL
	ASL
	ASL
	STA ZTMP4		;save for later
	TAY		;use Y to index drive table
	LDX ZTMP2		;use X to index IDE buffer
	LDA #15		;will copy 16 bytes
	STA ZTMP5		;use ZTMP5 as loop counter
HDFSINI0	LDA IDEBUF0,X
	STA DRIVETAB,Y
	INX
	INY
	DEC ZTMP5
	BPL HDFSINI0

	LDY ZTMP4		;offset in drive table
	INY		;skip first two bytes
	INY
	LDA DRIVETAB,Y	;get LBA start sector of partition
	STA IDELBA0
	INY
	LDA DRIVETAB,Y
	STA IDELBA1
	INY
	LDA DRIVETAB,Y
	STA IDELBA2
	INY
	LDA DRIVETAB,Y
	STA IDELBA3
	LDA #IDEBUF1
	STA IDEBUFP
	LDA #IDEBUF1/256
	STA IDEBUFP+1
	JSR IDERSEC	;read first sector of partition

	LDA ZTMP4
	CLC
	ADC #15		;index of last byte of drive table entry
	TAY
	LDX #6		;check for 7-letter magic word
HDFSINI1	LDA IDEBUF1,X
	CMP MAGHDFS,X
	BNE HDFSINI2	;fail
	DEX
	BPL HDFSINI1	;check next letter
	LDA #1		;set flag to indicate test passed
	JMP HDFSINI3
HDFSINI2	LDA #0		;test failed - partition unformatted
HDFSINI3	STA DRIVETAB,Y

	LDX ZTMP2		;restore X and Y
	LDY ZTMP3
	RTS

; *** GETSAT: Look up a sector in the Sector Allocation Table
; input: DRIVE = logical drive number
;        ZTMP0-ZTMP3 = sector number relative to partition (not preserved)
; output: A = 0 : sector free
;         A = +ve : sector allocated
;         A = -ve : error
;         (A is set just before RTS, so flags can be tested on return)
; X,Y preserved
GETSAT	TXA
	PHA
	TYA
	PHA

	LDY DRIVE
	LDA DRIVES,Y	;get device code from drive table
	BEQ GETSAT_E	;drive code = 0, no drive
	CMP #8
	BMI GETSAT_E	;drive code > 7, invalid
	TYA
	ASL		;offset in drive table = drive number * 16
	ASL
	ASL
	ASL
	TAY
	LDA DRIVETAB,Y
	CMP FS_HDFS
	BNE GETSAT_E	;filesystem is not HDFS

	JSR RDSAT		;calculate position in SAT and read the SAT sector
	;ZTMP0-ZTMP3 = SAT sector number (LBA)
	;ZTMP8-ZTMP9 = byte within sector (0-512)
	;ZTMP10 = bit within byte (0-7)
	;SAT sector has been read into IDEBUF0 (pointed to by IDEBUFP)
	LDY ZTMP10
	LDA POW2,Y	;convert bit-number to bit-mask
	STA ZTMP10
	LDA ZTMP9		;test high-byte of byte-number...
	BEQ GETSAT1
	INC IDEBUFP+1	;...if 1, advance to second page of buffer
GETSAT1	LDY ZTMP8
	LDA (IDEBUFP),Y	;read relavent byte from SAT
	AND ZTMP10	;select relavent bit
	BEQ GETSAT_F	;bit = 0 : sector free
	JMP GETSAT_A	;bit = 1 : sector allocated

GETSAT_F	PLA
	TAY
	PLA
	TAX
	LDA #0
	RTS
GETSAT_A	PLA
	TAY
	PLA
	TAX
	LDA #1
	RTS
GETSAT_E	PLA
	TAY
	PLA
	TAX
	LDA #$FF
	RTS

; *** SETSAT: Set the status of a sector in the Sector Allocation Table
; input: DRIVE = logical drive number
;        ZTMP0-ZTMP3 = sector number relative to partition (not preserved)
;        A = 0 : mark sector free
;        A != 0 : mark sector allocated
; output: A = -ve : error
;         (A is set just before RTS, so flags can be tested on return)
; X,Y preserved
SETSAT	STA ZTMP11	;save A for later
	TXA
	PHA
	TYA
	PHA

	LDY DRIVE
	LDA DRIVES,Y	;get device code from drive table
	BEQ SETSAT_E	;drive code = 0, no drive
	CMP #8
	BMI SETSAT_E	;drive code > 7, invalid
	TYA
	ASL		;offset in drive table = drive number * 16
	ASL
	ASL
	ASL
	TAY
	LDA DRIVETAB,Y
	CMP FS_HDFS
	BNE SETSAT_E	;filesystem is not HDFS

	JSR RDSAT		;calculate position in SAT and read the SAT sector
	;ZTMP0-ZTMP3 = SAT sector number (LBA)
	;ZTMP8-ZTMP9 = byte (0-512)
	;ZTMP10 = bit (0-7)
	;SAT sector has been read into IDEBUF0 (pointed to by IDEBUFP)

	LDA ZTMP9		;test high-byte of byte-number...
	BEQ SETSAT1
	INC IDEBUFP+1	;...if 1, advance to second page of buffer
SETSAT1	LDX ZTMP10
	LDA POW2,X	;convert bit-number to bit-value
	STA ZTMP10
	LDY ZTMP8		;load Y with low-byte of buffer offset
	LDX ZTMP11	;read the set/clear argument
	BEQ SETSAT2

	;argument != 0 : set bit
	LDA (IDEBUFP),Y	;read relavent byte from SAT
	ORA ZTMP10	;set the bit
	STA (IDEBUFP),Y
	JMP SETSAT3

	;argument = 0 : clear bit
SETSAT2	LDA #$FF
	EOR ZTMP10	;invert bit pattern
	LDA (IDEBUFP),Y	;read relavent byte from SAT
	AND ZTMP10	;AND with inverted bit pattern to clear bit
	STA (IDEBUFP),Y

SETSAT3	LDA ZTMP9
	BEQ SETSAT4
	DEC IDEBUFP+1	;restore pointer if we changed it earlier
SETSAT4	LDA ZTMP0		;load LBA address (can't use old value because it
	STA IDELBA0	;may have been converted to CHS)
	LDA ZTMP1
	STA IDELBA1
	LDA ZTMP2
	STA IDELBA2
	LDA ZTMP3
	STA IDELBA3
	JSR IDEWSEC	;write the updated sector

	PLA
	TAY
	PLA
	TAX
	LDA #$00
	RTS

SETSAT_E	PLA
	TAY
	PLA
	TAX
	LDA #$FF
	RTS

; *** RDSAT: Used by GETSAT and SETSAT to read the SAT sector from disk
RDSAT	;Calculate position in SAT for sector 's':
	; sector = start_of_SAT + (s / 4096)
	; byte = (s % 4096) / 8
	; bit = (s % 4096) % 8

	;s % 4096 == s & 0xFFF
	LDA ZTMP0
	STA ZTMP8
	AND #7		;(s % 4096) % 8 == (s % 4096) & 7
	STA ZTMP10
	LDA ZTMP1
	AND #$0F
	STA ZTMP9

	;(s % 4096) / 8 == (s % 4096) >> 3
	LDX #3
RDSAT1	LSR ZTMP9
	ROR ZTMP8
	DEX
	BNE RDSAT1

	;s / 4096 == s >> 12
	LDX #12
RDSAT2	LSR ZTMP3
	ROR ZTMP2
	ROR ZTMP1
	ROR ZTMP0
	DEX
	BNE RDSAT2

	;now: ZTMP0-ZTMP3 = s / 4096
	;     ZTMP8-ZTMP9 = (s % 4096) / 8
	;     ZTMP10 = (s % 4096) % 8

	;sector = SAT_sector + partition_start + 1
	INY
	INY
	LDA DRIVETAB,Y
	STA ZTMP4
	INY
	LDA DRIVETAB,Y
	STA ZTMP5
	INY
	LDA DRIVETAB,Y
	STA ZTMP6
	INY
	LDA DRIVETAB,Y
	STA ZTMP7
	JSR ADD32
	INC ZTMP0
	BNE RDSAT3
	INC ZTMP1
	BNE RDSAT3
	INC ZTMP2
	BNE RDSAT3
	INC ZTMP3

	;read the sector
RDSAT3	LDA ZTMP0
	STA IDELBA0
	LDA ZTMP1
	STA IDELBA1
	LDA ZTMP2
	STA IDELBA2
	LDA ZTMP3
	STA IDELBA3
	LDA #IDEBUF0
	STA IDEBUFP
	LDA #IDEBUF0/256
	STA IDEBUFP+1
	JSR IDERSEC

	RTS

; *** DLPARTAB: Download partition table from serial port
DLPARTAB	JSR LCDCLR
	LDA #IDEBUF0	;set up pointer to IDE buffer
	STA IDEBUFP
	STA ZTMP0
	LDA #IDEBUF0/256
	STA IDEBUFP+1
	STA ZTMP1

	;read 512 bytes
	LDX #0		;will count the 2 pages
	LDY #0
DLPARTA0	JSR RXBYTE	;get byte from serial port
	STA (ZTMP0),Y
	INY
	TYA
	BNE DLPARTA0
	INC ZTMP1		;increment pointer high-byte
	INX
	CPX #2		;done 2 pages?
	BNE DLPARTA0

	LDA #0		;set sector number - partition table is sector 0
	STA IDELBA0
	STA IDELBA1
	STA IDELBA2
	STA IDELBA3
	JSR IDEWSEC	;write to drive

	RTS

⌨️ 快捷键说明

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