progress on FAT16 support

This commit is contained in:
Dennis Gunia
2024-01-12 13:29:20 +01:00
parent ee2f22df09
commit 507eb3a017
40 changed files with 19699 additions and 6346 deletions

View File

@@ -45,3 +45,6 @@ CS_PIO_BD .EQU 0xF5
CS_PIO_BC .EQU 0xF7
CS_PIO_AD .EQU 0xF4
CS_PIO_AC .EQU 0xF6
CS_APU_DATA .EQU 0xF8
CS_APU_CTRL .EQU 0xF9

View File

@@ -6,33 +6,32 @@
;------------------------------------------------------------------------------
beep:
push AF
push BC
push DE
beep_loop:
LD A,0x08
OUT (CS_PIO_AD), A
LD BC, 0x28
CALL beep_pause
LD A,0x00
OUT (CS_PIO_AD), A
LD BC, 0x24
CALL beep_pause
DEC DE
ld A,D
or E
jr NZ, beep_loop
pop de
pop bc
pop af
ret
beep_pause:
NEG ; 8 T-states
NEG ; 8 T-states
PUSH BC
_beep_pause_l1:
;NEG ; 8 T-states
;NEG ; 8 T-states
NEG ; 8 T-states
NEG ; 8 T-states
DEC BC ; 6 T-states
LD A,C ; 9 T-states
OR B ; 4 T-states
JP NZ,beep_pause ; 10 T-states
JP NZ,_beep_pause_l1 ; 10 T-states
POP BC
RET ; Pause complete, RETurn

View File

@@ -0,0 +1,201 @@
ADDR_RTC .equ 0xD0
OP_RTIME:
call print_newLine
_OP_RTIME_NN:
;set pointer
ld hl,[_OP_RTIME_RD_CMD]
ld b, 1
ld c, ADDR_RTC
call iic_send_buffer
or a
jp nz, _OP_IIC_ACK_ERR
;read RTC data
ld hl,[var_scratch]
ld b,8
ld c, ADDR_RTC
call iic_receive_buffer
or a
jp nz, _OP_IIC_ACK_ERR
;process display hours
ld a,(var_scratch+2)
and 00110000b
RRA
RRA
RRA
RRA
call print_bcd
ld a,(var_scratch+2)
and 00001111b
call print_bcd
ld a,':'
call print_char
;display minutes
ld a,(var_scratch+1)
and 01110000b
RRA
RRA
RRA
RRA
call print_bcd
ld a,(var_scratch+1)
and 00001111b
call print_bcd
ld a,':'
call print_char
;display seconds
ld a,(var_scratch+0)
and 01110000b
RRA
RRA
RRA
RRA
call print_bcd
ld a,(var_scratch+0)
and 00001111b
call print_bcd
ld a,' '
call print_char
;display date
ld a,(var_scratch+4)
and 00110000b
RRA
RRA
RRA
RRA
call print_bcd
ld a,(var_scratch+4)
and 00001111b
call print_bcd
ld a,'.'
call print_char
ld a,(var_scratch+5)
and 00010000b
RRA
RRA
RRA
RRA
call print_bcd
ld a,(var_scratch+5)
and 00001111b
call print_bcd
ld a,'.'
call print_char
ld a,'2'
call print_char
ld a,'0'
call print_char
ld a,(var_scratch+6)
and 11110000b
RRA
RRA
RRA
RRA
call print_bcd
ld a,(var_scratch+6)
and 00001111b
call print_bcd
RET
_OP_RTIME_RD_CMD:
db 0x00
_OP_STIME_STR_DAY: db 10,13,"Enter Date (00-31) : ",0
_OP_STIME_STR_MON: db 10,13,"Enter Month (00-12) : ",0
_OP_STIME_STR_YEAR: db 10,13,"Enter Year (00-99) : ",0
_OP_STIME_STR_HOUR: db 10,13,"Enter Hours (00-23) : ",0
_OP_STIME_STR_MIN: db 10,13,"Enter Minutes (00-59) : ",0
_OP_STIME_STR_SEC: db 10,13,"Enter Seconds (00-59) : ",0
_OP_STIME_INVALID: db " invaild input. Retry!",0
;HL contains pointer to stack
;BC returns value (BCD)
_OP_STIME_PROMPT:
push hl
call print_str
pop hl
call read_bcd
cp 0xFF ;if failed
jp Z, _OP_STIME_PROMPT_ERR
ld b,a
call read_bcd
cp 0xFF ;if failed
jp Z, _OP_STIME_PROMPT_ERR
ld c,a
ret
_OP_STIME_PROMPT_ERR:
push HL
ld hl, [_OP_STIME_INVALID]
call print_str
pop hl
jp _OP_STIME_PROMPT
OP_STIME:
xor a
ld (var_scratch),a ;set pointer
;date
ld hl, [_OP_STIME_STR_DAY]
call _OP_STIME_PROMPT
ld a,b
call _shift4
and 00110000b ;mask bits; bit6 low -> 24h mode
or c ;add second digit
ld (var_scratch+5),a
;month
ld hl, [_OP_STIME_STR_MON]
call _OP_STIME_PROMPT
ld a,b
call _shift4
and 00010000b ;mask bits; bit6 low -> 24h mode
or c ;add second digit
ld (var_scratch+6),a
;year
ld hl, [_OP_STIME_STR_YEAR]
call _OP_STIME_PROMPT
ld a,b
call _shift4
and 11110000b ;mask bits; bit6 low -> 24h mode
or c ;add second digit
ld (var_scratch+7),a
;hours
ld hl, [_OP_STIME_STR_HOUR]
call _OP_STIME_PROMPT
ld a,b
call _shift4
and 00110000b ;mask bits; bit6 low -> 24h mode
or c ;add second digit
ld (var_scratch+3),a
; minutes
ld hl, [_OP_STIME_STR_MIN]
call _OP_STIME_PROMPT
ld a,b
call _shift4
and 01110000b ;mask bits
or c ;add second digit
ld (var_scratch+2),a
; seconds
ld hl, [_OP_STIME_STR_SEC]
call _OP_STIME_PROMPT
ld a,b
call _shift4
and 01110000b ;mask bits / bit6 low -> 24h mode (enable clock)
or c ;add second digit
ld (var_scratch+1),a
inc de ;next
ld c, ADDR_RTC
ld b, 8
ld hl,[var_scratch]
call iic_send_buffer
or a
jp nz, _OP_IIC_ACK_ERR
ret
_shift4:
RLCA
RLCA
RLCA
RLCA
ret

View File

@@ -0,0 +1,26 @@
OP_LSDSK:
call ideif_prnt_devtable
ret
OP_SELDSK:
;DE contains pointer
push de
pop hl
ld a,(hl)
sbc 69
jr c,_OP_SELDSK_INVALID
cp 4
jr nc, _OP_SELDSK_INVALID
call 0x8000
ret
_OP_SELDSK_INVALID:
ld hl,[_OP_SELDSK_INVALID_STR]
call print_str
LD DE,0x20
LD BC,0x70
CALL beep
ret
_OP_SELDSK_INVALID_STR:
db 10,13,"Invalid drive letter",10,13,0

View File

@@ -0,0 +1,130 @@
OP_IO_IN:
push DE
pop HL
call DHEX_TO_BYTE
ld c,a ;store result in b
ld a,e ;check for error
and a
jp nz, ERR_SYNTAX
in a,(c)
push af
call print_newLine
pop af
call print_a_hex
ret
OP_IO_OUT:
push DE
pop HL
call DHEX_TO_BYTE
ld c,a ;store result in b
ld a,e ;check for error
and a
jp nz, ERR_SYNTAX
inc hl
inc hl
ld a,(hl)
cp ' '
jp nz, ERR_SYNTAX
inc hl
call DHEX_TO_BYTE
push af
ld a,e ;check for error
and a
jp nz, ERR_SYNTAX
pop af
out (c),a
ret
OP_IIC_OUT:
push DE
pop HL
call DHEX_TO_BYTE ;load start addr
ld (var_scratch+1),A ;store result in ram
ld a,e ;check for error
and a
jp nz, ERR_SYNTAX
inc hl
inc hl
LD BC,[var_scratch + 2]
XOR A
LD (var_scratch),A
_OP_IIC_OUT_LOOP:
ld a,(hl)
cp 0 ;if 0 then end
jp z,_OP_IIC_OUT_SEND
cp ' '
jp nz, ERR_SYNTAX
inc hl ;next byte
call DHEX_TO_BYTE
ld (bc),a
inc bc ;incerement pointer
ld a,(var_scratch)
inc a ;increment counter
ld (var_scratch),a
inc HL
inc HL
jr _OP_IIC_OUT_LOOP
_OP_IIC_OUT_SEND:
ld hl,[var_scratch + 2]
ld a,(var_scratch) ;load amount of bytes
ld b,a
ld a,(var_scratch+1) ;load start addr
ld c,a
call iic_send_buffer
or a
jp nz, _OP_IIC_ACK_ERR
ret
_OP_IIC_ACK_ERR:
LD HL,[_OP_IIC_ACK_ERR_str]
call print_str
ret
_OP_IIC_ACK_ERR_str:
db 10,13,"bus-error: no ACK",0
OP_IIC_IN:
push DE
pop HL
call DHEX_TO_BYTE ;load start addr
ld C,a ;store start addr to B
ld a,e ;check for error
and a
jp nz, ERR_SYNTAX
inc hl
inc hl
ld a,(hl)
cp ' '
jp nz, ERR_SYNTAX
inc hl
call DHEX_TO_BYTE ;read length
ld b,a ;store length in B
push bc
ld a,e ;check for error
and a
jp nz, ERR_SYNTAX
ld hl,[var_scratch]
call iic_receive_buffer
pop bc
or a
jp nz, _OP_IIC_ACK_ERR
ld hl,[_OP_IIC_IN_LOOP_TEXT]
call print_str
ld hl,[var_scratch]
;print data
_OP_IIC_IN_LOOP:
ld a,(hl)
call print_a_hex
ld a, ' '
call print_char
inc hl
djnz _OP_IIC_IN_LOOP
ret
_OP_IIC_IN_LOOP_TEXT:
db 10,13,"rec-buff: ",0
OP_CLR:
call print_clear
ret

View File

@@ -0,0 +1,148 @@
OP_EXEC:
;DE contains pointer
push DE
pop HL
call DHEX_TO_BYTE
ld b,a ;store result in b
ld a,e ;check for error
and a
jp nz, ERR_SYNTAX
inc HL
inc HL
call DHEX_TO_BYTE
ld c,a
ld a,e ;check for error
and a
jp nz, ERR_SYNTAX
ld h,b
ld l,c
jp (hl)
OP_CALL:
;DE contains pointer
push DE
pop HL
call DHEX_TO_BYTE
ld b,a ;store result in b
ld a,e ;check for error
and a
jp nz, ERR_SYNTAX
inc HL
inc HL
call DHEX_TO_BYTE
ld c,a
ld a,e ;check for error
and a
jp nz, ERR_SYNTAX
ld h,b
ld l,c
call _OP_CALL
call print_newLine
ret
_OP_CALL
jp (hl)
OP_DUMP:
;DE contains pointer
push DE
pop HL
call DHEX_TO_BYTE ;parse start address
ld b,a ;store result in b
ld a,e ;check for error
and a
jp nz, ERR_SYNTAX
inc HL
inc HL
call DHEX_TO_BYTE
ld c,a
ld a,e ;check for error
and a
jp nz, ERR_SYNTAX
inc HL
inc HL
ld a,(HL)
cp ' '
jp nz, ERR_SYNTAX
inc HL
call DHEX_TO_BYTE
push af
ld a,e ;check for error
and a
jp nz, ERR_SYNTAX
pop af
ld h,b
ld l,c
ld b,a
call dump_pretty
ret
OP_SET:
;DE contains pointer
push DE
pop HL
call DHEX_TO_BYTE ;parse start address
ld b,a ;store result in b
ld a,e ;check for error
and a
jp nz, ERR_SYNTAX
inc HL
inc HL
call DHEX_TO_BYTE
ld c,a
ld a,e ;check for error
and a
jp nz, ERR_SYNTAX
;bc now contains the start address
INC HL
INC HL
;hl now cointains start addr of data bytes
_OP_SET_LOOP:
ld a,(hl)
cp 0 ;if 0 then end
RET Z
cp ' '
jp nz, ERR_SYNTAX
inc hl ;next byte
call DHEX_TO_BYTE
ld (bc),a ;load byte to
ld a,e
and a
jp nz, ERR_SYNTAX
inc bc
inc hl
inc hl
jp _OP_SET_LOOP
OP_DASM:
push DE
pop HL
call DHEX_TO_BYTE
ld b,a ;store result in b
ld a,e ;check for error
and a
jp nz, ERR_SYNTAX
inc hl
inc hl
call DHEX_TO_BYTE
ld c,a
ld a,e ;check for error
and a
jp nz, ERR_SYNTAX
inc hl
inc hl
ld a,(HL)
cp ' '
jp nz, ERR_SYNTAX
inc hl
call DHEX_TO_BYTE
push af
ld a,e ;check for error
and a
jp nz, ERR_SYNTAX
ld h,b
ld l,c
pop af ;restore af
ld b,a
call disassemble
ret

View File

@@ -0,0 +1,165 @@
COMMAND_LUT:
db "date", 0 , [OP_RTIME], [OP_RTIME]>>8 ;Read time
db "setdate", 0 , [OP_STIME], [OP_STIME]>>8 ;Read time
db "pin ", 0 , [OP_IO_IN], [OP_IO_IN]>>8 ;Read port
db "dump ",0, [OP_DUMP], [OP_DUMP]>>8 ;print pretty hexdump
db "pout ", 0 , [OP_IO_OUT], [OP_IO_OUT]>>8 ;Write port
db "iin ", 0, [OP_IIC_IN], [OP_IIC_IN]>>8 ;Read IIC
db "iout ", 0, [OP_IIC_OUT], [OP_IIC_OUT]>>8 ;Write IIC
db "call ", 0, [OP_CALL], [OP_CALL]>>8 ;Call to addr
db "clr", 0, [OP_CLR], [OP_CLR]>>8 ;Call to addr
db "dasm ", 0, [OP_DASM], [OP_DASM]>>8 ;Call to addr
db "jp ", 0,[OP_EXEC], [OP_EXEC]>>8 ;jump to addr
db "rst", 0,0x00,0x00 ;soft reset
db "lsdsk", 0,[OP_LSDSK], [OP_LSDSK]>>8 ;list disks
db "seldsk ", 0,[OP_SELDSK], [OP_SELDSK]>>8 ;select disk
db "$", 0, [OP_EXEC], [OP_EXEC]>>8 ;jump to addr
db "i", 0, [OP_IO_IN], [OP_IO_IN]>>8 ;Read port
db "o", 0, [OP_IO_OUT], [OP_IO_OUT]>>8 ;Write port
db "!", 0, [OP_SET], [OP_SET]>>8 ;Write memory
db "?", 0, [OP_DUMP], [OP_DUMP]>>8 ;Print memory
db 0xFF ;End of Table
IN_BUFFER .equ var_buffer
COMMAND:
call print_newLine
ld a,'>'
call print_char
xor a ;reset buffer len
ld (var_buffer_len),a
COMMAND_READ:
call read_char
jp z, COMMAND_READ ;wait for input
cp 13 ; enter
jp z,COMMAND_PROCESS
cp 10
jp z, COMMAND_READ; skip LF for file load
cp 0x08 ; backspace 0x08 VT102 0x7f Putty
jp z,COMMAND_BACKSPACE
push af
; a contains latest char
ld hl,[var_buffer]
ld d,0
ld a,(var_buffer_len)
ld e,a
add hl,de ;hl now contains pointer to last position in buffer
inc a
ld (var_buffer_len),a ;store incremented buffer length
pop af
ld (hl),a
call print_char
inc hl
xor a ;a = 0
ld (hl),a ;always add null termination after last char
jp COMMAND_READ
COMMAND_BACKSPACE:
ld a,(var_buffer_len)
and a
jp z, COMMAND_READ ; do not continue if already at char 0
dec a ;decrement length
ld (var_buffer_len),a ;and store it
ld e,a ;load de with decremented value
ld d,0
ld hl,[var_buffer]
add hl,de ;hl now contains pointer to last position in buffer
xor a ; store null byte to current location
ld (hl),a
;call print_delete
ld a, 0x08
call print_char
ld a, 0x20
call print_char
ld a, 0x08
call print_char
jp COMMAND_READ
COMMAND_PROCESS:
;compare
LD HL,[COMMAND_LUT] ;Lookup table
COMMAND_PROCESS_LOOP:
LD DE,[var_buffer] ;Buffer
LD A,(HL) ;Load first byte of entry
CP 0xFF
JP Z,COMMAND_PROCESS_NOT_FOUND ;if first byte is 0xFF, End is reached
; compare string loop
COMMAND_PROCESS_LOOP_STR1:
LD A,(DE)
LD B,A
LD A,(HL)
OR B ;not 0 -> match
JP Z, COMMAND_PROCESS_FOUND ;match
LD A,(DE)
LD B,A
;LD A,(HL) ;Load first byte of entry
;call print_a_hex
LD A,(HL)
;compare byte
XOR B
OR A ;if identical = resoult shopuld be zero
JP Z, COMMAND_PROCESS_LOOP_STR2 ;then continue
; if not identical
LD A,(HL)
OR A ;if reached end of compare string
JP Z, COMMAND_PROCESS_FOUND ;match
JR COMMAND_PROCESS_NEXT_ENTRY ;next entry on no match
COMMAND_PROCESS_LOOP_STR2: ;continue with next char
INC HL
INC DE
JR COMMAND_PROCESS_LOOP_STR1
COMMAND_PROCESS_NEXT_ENTRYI: ;do not jump here
INC HL
COMMAND_PROCESS_NEXT_ENTRY: ;jump here
LD A,(HL)
OR A
JP NZ,COMMAND_PROCESS_NEXT_ENTRYI ;loop until end of string
INC HL ;skip pointer
INC HL
INC HL
JP COMMAND_PROCESS_LOOP
COMMAND_PROCESS_NOT_FOUND:
LD HL,[_STR_NOT_FOUND]
CALL print_str
JP COMMAND
COMMAND_PROCESS_FOUND:
PUSH HL
POP BC
INC BC
LD A,(BC)
LD L,A
INC BC
LD A,(BC)
LD H,A
;HL: pointer to start of routine
;DE: buffer start of arguments
CALL _COMMAND_PROCESS_FOUND
JP COMMAND
_COMMAND_PROCESS_FOUND
JP (HL)
NOT_IMPLEMENTED:
LD HL,[_STR_NOT_IMPLEMENTED]
CALL print_str
RET
ERR_SYNTAX:
LD HL,[_STR_SYNTAX]
CALL print_str
RET
_STR_NOT_IMPLEMENTED:
db 10,13,"not implemented",10,13,0
_STR_NOT_FOUND:
db 10,13,"invalid command",10,13,0
_STR_SYNTAX:
db 10,13,"invalid syntax",10,13,0

View File

@@ -99,6 +99,12 @@ print_a_hex:
pop de
pop bc
pop af
ret
print_bcd:
ADD 48 ;offset for ascii number
call print_char
ret
read_char:
call A_RTS_ON
@@ -112,6 +118,21 @@ read_char:
in a, (CS_SIO_A_D) ; read char if avail
ret ; return
read_bcd;
call read_char
jp z, read_bcd
call print_char
sbc 48 ;remove ascii offset
jp c, _read_bcd_invalid ;if carry, wrong input
cp 10
jp z, _read_bcd_invalid ;if equal or greater than 10, also error
and 0x0F ;mask unused bits
ret
_read_bcd_invalid
ld a, 0xFF
ret
;MSG_CRSR_0:
; db 0x1B, "[?25h",0
;MSG_CRSR_1:

View File

@@ -32,6 +32,11 @@
IDE_REG_ALTSTS .EQU 10110b ;Alternate Status/Digital Output
IDE_REG_DRVADDR .EQU 10111b ;Drive Address
IDE_REG_LBA0 .EQU 01011b ;Start sector register
IDE_REG_LBA1 .EQU 01100b ;Low byte of the cylinder number
IDE_REG_LBA2 .EQU 01101b ;High two bits of the cylinder number
IDE_REG_LBA3 .EQU 01110b ;Head and device select register
;================================================================
; I/O access functions

View File

@@ -12,73 +12,378 @@
;================================================================
; IDE Variables
;================================================================
MEM_IDE_BASE .EQU 0x5000
MEM_IDE_DEVICE .EQU MEM_IDE_BASE
MEM_IDE_STATUS .EQU MEM_IDE_BASE + 1 ;1Byte: 0x00 if status is okay
phase var_idebuffer
MEM_IDE_DEVICE:
defs 1
MEM_IDE_STATUS:
defs 1 ;1Byte: 0x00 if status is okay
MEM_IDE_PARTITION:
defs 4 ;4*16Bytes: LBA first sector
MEM_IDE_POINTER:
defs 4 ;4*16Bytes: LBA first sector
MEM_IDE_DEV_TABLE:
defs 16*4
MEM_IDE_SELECTED:
defs 1
MEM_IDE_STRING_0:
defs 40
MEM_IDE_STRING_1:
defs 40
MEM_IDE_STRING_2:
defs 40
MEM_IDE_STRING_3:
defs 40
MEM_IDE_BUFFER:
defs 512
MEM_IDE_FSBUFFER:
defs 256
dephase
;DEV-Table layout
;<STATUS> <TYPE> <FIRST-SECTOR (4-byte)> <Length (4-byte)> <I/O Addr> <Master/Slave> 0x00 0x00
;Status: 0x00 -> Ready
; 0x01 -> Not found
; 0x02 -> No supported filesystem
;I/O Addr: Base addr of 82C55
;Type: File system type
MEM_IDE_PARTITION .EQU MEM_IDE_BASE + 2 ;4*16Bytes: LBA first sector
MEM_IDE_POINTER .EQU MEM_IDE_BASE + 6 ;4*16Bytes: LBA first sector
MEM_IDE_BUFFER .EQU MEM_IDE_BASE + 65 ;512Byte: buffer for read/write data
IDE_DEV_TABLE:
db 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, [MEM_IDE_STRING_0], [MEM_IDE_STRING_0]>>8, 0x00, 0x00
db 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x01, [MEM_IDE_STRING_1], [MEM_IDE_STRING_1]>>8, 0x00, 0x00
db 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, [MEM_IDE_STRING_2], [MEM_IDE_STRING_2]>>8, 0x00, 0x00
db 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, [MEM_IDE_STRING_3], [MEM_IDE_STRING_3]>>8, 0x00, 0x00
;================================================================
; IDE funtions
;================================================================
;------------------------------------------------------------------------------
; ideif_init_table
;
; initializes drive table
;------------------------------------------------------------------------------
ideif_init_devtable:
;copy default values to ram
ld hl,[IDE_DEV_TABLE]
ld de,[MEM_IDE_DEV_TABLE]
ld bc,16*4
ldir
;set selected device
ld a,0
ld (MEM_IDE_SELECTED),a
;set empty names
xor a
ld (MEM_IDE_STRING_0),a
ld (MEM_IDE_STRING_1),a
ld (MEM_IDE_STRING_2),a
ld (MEM_IDE_STRING_3),a
ret
;------------------------------------------------------------------------------
; ideif_prnt_devtable
;
; prints drive table
;------------------------------------------------------------------------------
ideif_prnt_devtable:
call print_newLine
ld hl,[_ideif_prnt_devtable_hdr]
call print_str
ld hl,[MEM_IDE_DEV_TABLE]
ld b,0 ;device number
_ideif_prnt_devtable_l1: ;loop 1 -> for each device
;print if selected
ld a,(MEM_IDE_SELECTED)
cp b
jp z,_ideif_prnt_devtable_l1_sel
ld a, ' '
jr _ideif_prnt_devtable_l1_nxt
_ideif_prnt_devtable_l1_sel:
ld a, '*'
_ideif_prnt_devtable_l1_nxt:
call print_char
;print drive letter
ld a,b
add 69 ;offset letter to D
call print_char
ld a, ':'
call print_char
ld a, ' '
call print_char
;print status
push hl
ld a,(HL)
or a
jr z, _ideif_prnt_devtable_l1_s00
cp 0x01
jr z, _ideif_prnt_devtable_l1_s01
cp 0x02
jr z, _ideif_prnt_devtable_l1_s02
cp 0xFF
jr z, _ideif_prnt_devtable_l1_sFF
jr _ideif_prnt_devtable_l1_sFF
_ideif_prnt_devtable_l1_s00
ld hl,[_ideif_prnt_devtable_s00]
jr _ideif_prnt_devtable_l1_es
_ideif_prnt_devtable_l1_s01
ld hl,[_ideif_prnt_devtable_s01]
jr _ideif_prnt_devtable_l1_es
_ideif_prnt_devtable_l1_s02
ld hl,[_ideif_prnt_devtable_s02]
jr _ideif_prnt_devtable_l1_es
_ideif_prnt_devtable_l1_sFF
ld hl,[_ideif_prnt_devtable_sFF]
_ideif_prnt_devtable_l1_es
call print_str
pop hl
inc hl
;print FS-Type
ld a,'0'
call print_char
ld a,'x'
call print_char
ld a,(HL)
call print_a_hex
ld a,' '
call print_char
inc hl
;print first sector
push hl
pop ix
inc hl
inc hl
inc hl
inc hl
inc hl
inc hl
inc hl
inc hl
ld a,(ix+3)
call print_a_hex
ld a,(ix+2)
call print_a_hex
ld a,(ix+1)
call print_a_hex
ld a,(ix+0)
call print_a_hex
ld a,' '
call print_char
;print length
ld a,(ix+7)
call print_a_hex
ld a,(ix+6)
call print_a_hex
ld a,(ix+5)
call print_a_hex
ld a,(ix+4)
call print_a_hex
ld a,' '
call print_char
;print Port
ld a,'0'
call print_char
ld a,'x'
call print_char
ld a,(HL)
call print_a_hex
ld a,' '
call print_char
inc hl
;print M/S
ld a,(HL)
push hl
or a
jp z,_ideif_prnt_devtable_l1_ms
ld hl,[_ideif_prnt_devtable_slave]
jp _ideif_prnt_devtable_l1_e2
_ideif_prnt_devtable_l1_ms
ld hl,[_ideif_prnt_devtable_master]
_ideif_prnt_devtable_l1_e2
call print_str
pop hl
inc hl
;print str
push bc
ld a,(hl)
ld c,a
inc hl
ld a,(hl)
ld b,a
inc hl
push hl
ld h,b
ld l,c
call print_str
call print_newLine
pop hl
pop bc
;next
inc hl
inc hl
inc b
ld a,b
cp 4
ret z
jp _ideif_prnt_devtable_l1
;------------------------------------------------------------------------------
; ideif_init_drive
;
; initializes drive
; initializes selected drive in table
;------------------------------------------------------------------------------
ideif_init_drive:
xor a
ld (MEM_IDE_DEVICE),A ;Set device to 0
ld (MEM_IDE_STATUS),A ;Set status to 0 (OK)
di ;disable interrupt
call ide_reset ;Reset drives on bus
ld hl, [str_dev_waitready]
call print_str ;print waiting message
ld DE, 0x1FFF ;preload timeout counter
ideif_init_drive_loop1:
call ideif_get_drv_pointer
; load addresses. not used atm
;ld a,(IX+6) ;load IO Addr
;ld d,a
;ld a,(IX+7) ;load Master/Slave bit
;ld e,a
call ide_reset
ld bc, 0x5FFF ;preload timeout counter
_ideif_init_drive_loop:
ld b, IDE_REG_CMDSTS
call ide_regread_8 ;read drive status register
OR A
JR Z, ideif_init_drive_nodrv ;no drive found
BIT 6,A ;Wait for device ready
JR NZ, ideif_init_drive_detected
DEC DE ; decrement timeout
LD A,D
OR E
JR Z, ideif_init_drive_nodrv
JR ideif_init_drive_loop1
or a
jr z,_ideif_init_drive_nodrv ;no drive found
bit 6,a
jr nz, _ideif_init_drive_found
dec de
ld a,d
or e
jr z, _ideif_init_drive_nodrv
jr _ideif_init_drive_loop
ideif_init_drive_nodrv:
ld hl, [str_dev_notfound]
call print_str
RET
_ideif_init_drive_nodrv:
ld(ix+0),0x01
ret
ideif_init_drive_detected:
ld hl, [str_dev_ready]
call print_str
LD B, IDE_REG_CMDSTS ;Get drive identification
LD A, IDE_CMD_IDENT
_ideif_init_drive_found:
ld (ix+0),0x02
;get drive name
ld b, IDE_REG_CMDSTS ;Get drive identification
ld a, IDE_CMD_IDENT
call ide_regwrite_8 ;Write command to drive
LD HL,MEM_IDE_BUFFER ;set read/write buffer start address
ld hl, MEM_IDE_BUFFER ;set read/write buffer start address
call ide_readsector_256 ;read 256 words from device
LD HL,MEM_IDE_BUFFER + 20 ;print device serial
LD B, 20
CALL print_str_fixed
ld hl, [str_dev_ready2]
ld hl,MEM_IDE_BUFFER + 54 ;print device serial
ld a,(ix+12) ;load str pointer into de
ld e,a
ld a,(ix+13)
ld d,a
ld bc,40 ;copy 40 char
ldir
;get partition table
;read bootsector
ld a,1 ;read 1 sector
ld B,IDE_REG_SECTOR
call ide_regwrite_8
ld a,1 ;read sector 0
ld b,IDE_REG_SSECTOR
call ide_regwrite_8
ld a,0 ;read cylinder 0
ld b,IDE_REG_LCYL
call ide_regwrite_8
ld a,0
ld b,IDE_REG_HCYL
call ide_regwrite_8
ld a,10100000b ;read head 0
ld b,IDE_REG_HEAD
call ide_regwrite_8
ld a,IDE_CMD_READSEC ;send read command
ld b,IDE_REG_CMDSTS
call ide_regwrite_8
ld hl, MEM_IDE_BUFFER ;set read/write buffer start address
call ide_readsector_512_inv ;read 256 words from device
;prepare partitions
ld b,4 ;Partition table length
ld c,0 ;Partition ID counter
ld iy,MEM_IDE_BUFFER+446 ;Load offest of first partition table entry
_ideif_init_drive_prt_l1:
ld a,(iy+4) ;load status byte
or a
jp NZ, _ideif_init_drive_prt_fnd ;If not zero, jump to print function
jp _ideif_init_drive_prt_ln
_ideif_init_drive_prt_ln:
ld de,16
add iy,de
djnz _ideif_init_drive_prt_l1
ret
_ideif_init_drive_prt_fnd;
ld a,(iy+4)
ld (ix+1),a ;store partition type
cp 0x0E ;if not 0xE0, continue with next entry
jr nz, _ideif_init_drive_prt_ln
;get start LBA
ld a,(iy+0x08)
ld (ix+0x02),a
ld a,(iy+0x09)
ld (ix+0x03),a
ld a,(iy+0x0A)
ld (ix+0x04),a
ld a,(iy+0x0B)
ld (ix+0x05),a
ld (ix+0),0x00
;get count LBA
ld a,(iy+0x0C)
ld (ix+0x06),a
ld a,(iy+0x0D)
ld (ix+0x07),a
ld a,(iy+0x0E)
ld (ix+0x08),a
ld a,(iy+0x0F)
ld (ix+0x09),a
ld (ix+0),0x00
ret
;------------------------------------------------------------------------------
; ideif_get_drv_pointer
;
; gets pointer to selected drive in table in IX
;------------------------------------------------------------------------------
ideif_get_drv_pointer:
push af
push bc
;get selected drive
ld a,(MEM_IDE_SELECTED)
;multiply a *8
rlca ;*2
rlca ;*4
rlca ;*8
ld b,0
ld c,a
ld ix,[MEM_IDE_DEV_TABLE]
add ix,bc
pop bc
pop af
ret
;------------------------------------------------------------------------------
; ideif_init_all
;
; initializes interface
;------------------------------------------------------------------------------
ideif_init_all:
ld hl, [str_dev_waitready]
call print_str ;print waiting message
call ideif_init_devtable
call ideif_init_drive
ld hl, [str_dev_done]
call print_str
LD HL,MEM_IDE_BUFFER + 54 ;print device name
LD B, 40
CALL print_str_fixed
LD A,10 ;New line
CALL print_char
LD A,13
CALL print_char
RET
;------------------------------------------------------------------------------
; ideif_drv_sel
;
; Selects drive from table and initializes the fat16 file system
; A contains drive id
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; read_lba_sector
;
@@ -90,24 +395,23 @@ read_lba_sector:
LD B,IDE_REG_SECTOR ;amount of sectores
CALL ide_regwrite_8
LD A,(HL)
LD B,IDE_REG_LBA0
CALL ide_regwrite_8
INC HL
LD A,(HL)
LD B,IDE_REG_LBA1
CALL ide_regwrite_8
INC HL
LD A,(HL)
LD B,IDE_REG_LBA2
CALL ide_regwrite_8
INC HL
LD A,(HL)
AND 00001111b
OR 11100000b
LD B,IDE_REG_HEAD
LD B,IDE_REG_LBA3
CALL ide_regwrite_8
INC HL
LD A,(HL)
LD B,IDE_REG_HCYL
CALL ide_regwrite_8
INC HL
LD A,(HL)
LD B,IDE_REG_LCYL
CALL ide_regwrite_8
INC HL
LD A,(HL)
LD B,IDE_REG_SSECTOR
CALL ide_regwrite_8
INC HL
LD A,IDE_CMD_READSEC ;send read command
LD B,IDE_REG_CMDSTS
@@ -117,17 +421,29 @@ read_lba_sector:
ret
;================================================================
; IDE strings
;===============================================================
str_dev_waitready:
db 13,10,"Detecting drives ",0
db 13,10,"Detecting drives ... ",0
str_dev_done:
db "done!",13,10,0
str_dev_ready:
db "found!",13,10,"ID: ",0
str_dev_ready2:
db " Desc: ",0
str_dev_notfound:
db "no drive",13,10,0
_ideif_prnt_devtable_hdr:
db "DRV Status Type LBA Length Port M/S Name",10,13,0
_ideif_prnt_devtable_s00:
db "Avail ",0
_ideif_prnt_devtable_s01:
db "Not Found ",0
_ideif_prnt_devtable_s02:
db "Unkown FS ",0
_ideif_prnt_devtable_sFF:
db "Ctrl. Err ",0
_ideif_prnt_devtable_master:
db "Master ",0
_ideif_prnt_devtable_slave:
db "Slave ",0

View File

@@ -0,0 +1,289 @@
;----------------------------------------------------------------
;BIOS Driver for I2C Protocol (Software)
;by Dennis Gunia (01/2024)
;
; SCL is connected to PA1 of PIO (U6) with pull-up
; SDA is connected to PA0 of PIO (U6) with pull-up
;----------------------------------------------------------------
;================================================================
; I/O registers
;================================================================
;================================================================
; I/O pins
;================================================================
IIC_CLK .EQU 00000001b
IIC_DATA .EQU 00000010b
;================================================================
; basic access functions
;================================================================
;HL contains buffer location
;B defines amount of bytes to send
;C contains device address
iic_send_buffer:
CALL iic_send_sbit ;Send startbit
LD A,C
AND 0xFE ;Mask R/W bit (must be 0 for write)
CALL iic_send_byte ;Send Address
CALL iic_read_ack
OR A ; if no ack, error
JP NZ, iic_send_buffer_err
iic_send_buffer_loop;
LD A,(HL)
INC HL
CALL iic_send_byte
CALL iic_read_ack
OR A ; if no ack, error
JP NZ, iic_send_buffer_err
DJNZ iic_send_buffer_loop ;loop for remaining bytes
iic_send_buffer_done:
CALL iic_send_ebit
LD A,0
RET
iic_send_buffer_err:
CALL iic_send_ebit
LD A,1
RET
;HL contains buffer location
;B defines amount of bytes to send
;C contains device address
iic_receive_buffer:
DEC B
CALL iic_send_sbit ;Send startbit
LD A,C
OR 0x01 ;set R/W bit (must be 1 for read)
CALL iic_send_byte ;Send Address
CALL iic_read_ack
OR A ; if no ack, error
JP NZ, iic_receive_buffer_err
iic_receive_buffer_loop:
CALL iic_receive_byte
LD (HL),A
INC HL
CALL iic_send_ack
DJNZ iic_receive_buffer_loop
; last time:
CALL iic_receive_byte
LD (HL),A
INC HL
CALL iic_send_nack
iic_receive_buffer_done:
CALL iic_send_ebit
LD A,0
RET
iic_receive_buffer_err:
CALL iic_send_ebit
LD A,1
RET
;================================================================
; I/O access functions
;================================================================
;Reset PIO configuration
iic_init:
;Set port to controll mode (MODE3)
LD A,0xCF
OUT (CS_PIO_AC), A
;Set inputs/outputs
LD A,0xF0
OUT (CS_PIO_AC), A
RET
; send start bit
iic_send_sbit:
;Set port to controll mode (MODE3)
LD A,0xCF
OUT (CS_PIO_AC), A
;Set inputs/outputs (SDA and SCL is now output)
LD A,0xFC
OUT (CS_PIO_AC), A
;SCL HIGH, SDA LOW
LD A,0x02
OUT (CS_PIO_AD), A
NOP
NOP
LD A,0x00
OUT (CS_PIO_AD), A
NOP
NOP
RET
; send end/stop bit
iic_send_ebit:
;Set port to controll mode (MODE3)
LD A,0xCF
OUT (CS_PIO_AC), A
;Set inputs/outputs (SDA and SCL is now output)
LD A,0xFC
OUT (CS_PIO_AC), A
;SCL HIGH, SDA LOW
LD A,0x02
OUT (CS_PIO_AD), A
NOP
NOP
LD A,0x03 ; both high
OUT (CS_PIO_AD), A
NOP
NOP
;release bus
;Set port to controll mode (MODE3)
LD A,0xCF
OUT (CS_PIO_AC), A
NOP
NOP
;Set inputs/outputs (SDA and SCL is now input, sound enabled)
LD A,11110111b
OUT (CS_PIO_AC), A
NOP
NOP
RET
iic_read_ack:
LD A,0xCF
OUT (CS_PIO_AC), A
;Set inputs/outputs (SCL is now output, SDA input)
LD A,0xFD
OUT (CS_PIO_AC), A
NOP
NOP
LD A,0x00 ;set SCL LOW
OUT (CS_PIO_AD), A
NOP
NOP
XOR 0x02 ;set SCL HIGH
OUT (CS_PIO_AD), A
NOP
IN A,(CS_PIO_AD) ; Read SDA
NOP
NOP
PUSH AF
AND 0xFE ; Filter input
XOR 0x02 ;set SCL LOW
OUT (CS_PIO_AD), A
NOP
NOP
POP AF
AND 1
RET
iic_send_ack:
;Set port to controll mode (MODE3)
LD A,0xCF
OUT (CS_PIO_AC), A
;Set inputs/outputs (SDA and SCL is now output)
LD A,0xFC
OUT (CS_PIO_AC), A
NOP
NOP
LD A,0x00 ; SCL LOW, SDA LOW
OUT (CS_PIO_AD), A
NOP
NOP
LD A,0x02 ; SCL HIGH, SDA LOW
OUT (CS_PIO_AD), A
NOP
NOP
LD A,0x00 ; SCL LOW, SDA LOW
OUT (CS_PIO_AD), A
NOP
NOP
RET
iic_send_nack:
;Set port to controll mode (MODE3)
LD A,0xCF
OUT (CS_PIO_AC), A
;Set inputs/outputs (SDA and SCL is now output)
LD A,0xFC
OUT (CS_PIO_AC), A
NOP
NOP
LD A,0x02 ; SCL LOW, SDA HIGH
OUT (CS_PIO_AD), A
NOP
NOP
LD A,0x03 ; both high
OUT (CS_PIO_AD), A
NOP
NOP
LD A,0x02 ; SCL LOW, SDA HIGH
OUT (CS_PIO_AD), A
NOP
NOP
RET
;A contains byte
iic_send_byte:
PUSH BC
LD C,A ;buffer
;Set port to controll mode (MODE3)
LD A,0xCF
OUT (CS_PIO_AC), A
;Set inputs/outputs (SDA and SCL is now output)
LD A,0xFC
OUT (CS_PIO_AC), A
LD B,8 ;bit counter
iic_send_byte_loop:
;prepare data
RL C
LD A,0
RLA ; set SCA bit from carry, SCL LOW
OUT (CS_PIO_AD), A
NOP
NOP
XOR 0x02 ;set SCL HIGH
OUT (CS_PIO_AD), A
NOP
NOP
XOR 0x02 ;set SCL LOW
OUT (CS_PIO_AD), A
NOP
NOP
DJNZ iic_send_byte_loop ;loop until counter is 0
;transmittion end / end loop
LD A,C
POP BC
RET
iic_receive_byte:
PUSH BC
;Set port to controll mode (MODE3)
LD A,0xCF
OUT (CS_PIO_AC), A
;Set inputs/outputs (SCL is now output, SDA input)
LD A,0xFD
OUT (CS_PIO_AC), A
LD B,8 ;bit counter
LD C,0
iic_receive_byte_loop:
XOR A ;set SCL LOW
OUT (CS_PIO_AD), A
NOP
NOP
LD A,2 ;set SCL HIGH
OUT (CS_PIO_AD), A
NOP
IN A, (CS_PIO_AD)
NOP
RRA ;read SDA bit
RL C ;store bit
XOR A ;set SCL LOW again
OUT (CS_PIO_AD), A
NOP
NOP
DJNZ iic_receive_byte_loop
LD A,C
POP BC
RET

View File

@@ -0,0 +1,120 @@
;Power-On self test
POST_START:
call POST_CHECK_PIO
call POST_CHECK_APU
call POST_TEST_RTC
call POST_CHECK_IDE_30
call POST_CHECK_IDE_40
ret
POST_CHECK_PIO:
ld hl,[str_post_pio]
call print_str
in a,(CS_PIO_AC) ;test read from pio
cp 0x00 ;0x78 when not installed
jp nz, _POST_CHECK_PIO_FAILED
ld a, 0x00 ;set present flag
ld (var_pio_present),a
ld hl,[str_post_ok]
call print_str
ret
_POST_CHECK_PIO_FAILED:
ld a, 0xFF
ld (var_pio_present),a
ld hl,[str_post_nd]
call print_str
ret
POST_CHECK_APU:
ld hl,[str_post_apu]
call print_str
ld a, 0xFF
out (CS_APU_DATA),a
nop
nop
in a,(CS_APU_DATA)
cp 0xFF
jp nz, _POST_CHECK_APU_FAILED
ld a, 0x00 ;set present flag
ld (var_apu_present),a
ld hl,[str_post_ok]
call print_str
ret
_POST_CHECK_APU_FAILED:
ld a, 0xFF
ld (var_apu_present),a
ld hl,[str_post_nd]
call print_str
ret
POST_CHECK_IDE_30:
ld hl,[str_post_ide_30]
call print_str
in a,(0x30)
or a
jp nz, _POST_CHECK_IDE_FAILED
ld hl,[str_post_ok]
call print_str
ret
POST_CHECK_IDE_40:
ld hl,[str_post_ide_40]
call print_str
in a,(0x40)
or a
jp nz, _POST_CHECK_IDE_FAILED
ld hl,[str_post_ok]
call print_str
ret
_POST_CHECK_IDE_FAILED
ld hl,[str_post_nd]
call print_str
ret
POST_TEST_RTC:
ld a, 0x06
ld (var_scratch),a
ld hl,[str_post_rtc]
call print_str
ld hl,[var_scratch]
ld b, 1
ld c, ADDR_RTC
call iic_send_buffer
or a
jp nz, _POST_TEST_RTC_NOTFOUND
ld hl,[var_scratch]
ld b, 1
ld c, ADDR_RTC
call iic_receive_buffer
ld a, (var_scratch)
or a
jp z, _POST_TEST_RTC_INVALID
ld hl,[str_post_ok]
call print_str
jp _OP_RTIME_NN
_POST_TEST_RTC_NOTFOUND:
ld hl,[str_post_nd]
call print_str
ret
_POST_TEST_RTC_INVALID:
ld hl,[str_post_rtc_iv]
call print_str
ret
str_post_ide_30:
db 13,10,"Check Diskctrl.@030h... ",0
str_post_ide_40:
db 13,10,"Check Diskctrl.@040h... ",0
str_post_pio:
db 13,10,"Check IO-Controller ... ",0
str_post_apu:
db 13,10,"Check AMD8911 APU ... ",0
str_post_rtc:
db 13,10,"Check DS1307 RTC ... ",0
str_post_nd:
db "not detected!",0
str_post_rtc_iv:
db "not set. Check battery and run 'setdate'!",0
str_post_ok:
db "ok! ",0