Browse Source

New disk driver interface logic

patch
Wayne Warthen 8 years ago
parent
commit
768e41c933
  1. 7
      Doc/ChangeLog.txt
  2. 878
      Source/HBIOS/fd.asm
  3. 914
      Source/HBIOS/hbios.asm
  4. 63
      Source/HBIOS/hdsk.asm
  5. 452
      Source/HBIOS/ide.asm
  6. 1269
      Source/HBIOS/ide.asm.new
  7. 273
      Source/HBIOS/md.asm
  8. 528
      Source/HBIOS/ppide.asm
  9. 260
      Source/HBIOS/ppp.asm
  10. 275
      Source/HBIOS/prp.asm
  11. 182
      Source/HBIOS/rf.asm
  12. 387
      Source/HBIOS/sd.asm
  13. 5
      Source/HBIOS/std.asm
  14. 10
      Source/HBIOS/util.asm
  15. 773
      Source/HBIOS/vga_old.asm

7
Doc/ChangeLog.txt

@ -1,3 +1,9 @@
Version 2.8.7
-------------
- WBW: Implemented multi-sector I/O in all disk drivers
- WBW: Added support for RC2014 SMB Floppy controller modules (SMC and WDC)
- WBW: New function dispatching for disk drivers
Version 2.8.6
-------------
- WBW: Added support for RC2014 (SIO and ACIA drivers primarily)
@ -6,6 +12,7 @@ Version 2.8.6
- WBW: Added console support to XModem (for RC2014 primarily)
- E?B: Fixed IDE/PPIDE when used with non-CF drives
- WBW: Patched SUBMIT.COM so that it always puts temp file on A: for immediate execution
- WBW: Accommodate spin up time for true IDE hard disks (IDE or PPIDE)
Version 2.8.5
-------------

878
Source/HBIOS/fd.asm

File diff suppressed because it is too large

914
Source/HBIOS/hbios.asm

File diff suppressed because it is too large

63
Source/HBIOS/hdsk.asm

@ -24,7 +24,7 @@ HDSK_LBA .EQU 2 ; OFFSET OF LBA (DWORD)
;
HDSK_CFGTBL:
; DEVICE 0
.DB 0 ; DEVICE NUMBER
.DB 0 ; DRIVER DEVICE NUMBER
.DB 0 ; DEVICE STATUS
.DW 0,0 ; CURRENT LBA
; DEVICE 1
@ -55,15 +55,12 @@ HDSK_INIT:
; SETUP THE DISPATCH TABLE ENTRIES
;
XOR A ; ZERO ACCUM
LD (HDSK_CURDEV),A ; SET CURRENT DEVICE NUM TO ZERO
LD (HDSK_CURDEV),A ; INIT CURRENT DEVICE NUM
LD IY,HDSK_CFGTBL ; START OF DEV CFG TABLE
HDSK_INIT0:
CALL HDSK_PROBE ; HARDWARE PROBE
JR NZ,HDSK_INIT1 ; SKIP DEVICE IF NOT PRESENT
LD A,(HDSK_CURDEV) ; GET CURRENT DEVICE
LD (IY+HDSK_DEV),A ; POPULATE DEVICE FIELD OF CFG ENTRY
LD B,A ; PUT IN B
LD C,DIODEV_HDSK ; DEVICE TYPE TO C
LD BC,HDSK_FNTBL ; BC := DRIVER FUNC TABLE ADDRESS
PUSH IY ; CFG ENTRY POINTER
POP DE ; ... TO DE
CALL DIO_ADDENT ; ADD ENTRY TO GLOBAL DISK TABLE
@ -74,7 +71,7 @@ HDSK_INIT1:
LD HL,HDSK_CURDEV ; POINT TO CURRENT DEVICE
INC (HL) ; AND INCREMENT IT
LD A,(IY) ; GET FIRST BYTE OF ENTRY
INC A ; TEST FOR $FF
INC A ; TEST FOR END OF TABLE ($FF)
JR NZ,HDSK_INIT0 ; IF NOT, LOOP
;
XOR A ; INIT SUCCEEDED
@ -98,35 +95,26 @@ HDSK_INITDEV:
XOR A ; SIGNAL SUCCESS (REDUNDANT)
RET ; AND DONE
;
; DRIVER FUNCTION TABLE
;
HDSK_FNTBL:
.DW HDSK_STATUS
.DW HDSK_RESET
.DW HDSK_SEEK
.DW HDSK_READ
.DW HDSK_WRITE
.DW HDSK_VERIFY
.DW HDSK_FORMAT
.DW HDSK_DEVICE
.DW HDSK_MEDIA
.DW HDSK_DEFMED
.DW HDSK_CAP
.DW HDSK_GEOM
#IF (($ - HDSK_FNTBL) != (DIO_FNCNT * 2))
.ECHO "*** INVALID HDSK FUNCTION TABLE ***\n"
#ENDIF
;
;
HDSK_DISPATCH:
; DISPATCH ACCORDING TO DISK SUB-FUNCTION
LD A,B ; GET REQUESTED FUNCTION
AND $0F ; ISOLATE SUB-FUNCTION
JP Z,HDSK_STATUS ; SUB-FUNC 0: STATUS
DEC A
JP Z,HDSK_RESET ; SUB-FUNC 1: RESET
DEC A
JP Z,HDSK_SEEK ; SUB-FUNC 2: SEEK
DEC A
JP Z,HDSK_READ ; SUB-FUNC 3: READ SECTORS
DEC A
JP Z,HDSK_WRITE ; SUB-FUNC 4: WRITE SECTORS
DEC A
JP Z,HDSK_VERIFY ; SUB-FUNC 5: VERIFY SECTORS
DEC A
JP Z,HDSK_FORMAT ; SUB-FUNC 6: FORMAT TRACK
DEC A
JP Z,HDSK_DEVICE ; SUB-FUNC 7: DEVICE REPORT
DEC A
JP Z,HDSK_MEDIA ; SUB-FUNC 8: MEDIA REPORT
DEC A
JP Z,HDSK_DEFMED ; SUB-FUNC 9: DEFINE MEDIA
DEC A
JP Z,HDSK_CAP ; SUB-FUNC 10: REPORT CAPACITY
DEC A
JP Z,HDSK_GEOM ; SUB-FUNC 11: REPORT GEOMETRY
;
HDSK_VERIFY:
HDSK_FORMAT:
@ -276,10 +264,8 @@ HDSK_RW0:
JR NZ,HDSK_RW5 ; BAIL OUT ON ERROR
; INCREMENT LBA
LD A,HDSK_LBA ; OFFSET OF LBA IN DEV CFG
PUSH IY ; COPY IT
POP HL ; ... TO HL
CALL ADDHLA ; SET HL := LBA ADDRESS
LD A,HDSK_LBA ; LBA OFFSET IN CFG ENTRY
CALL LDHLIYA ; HL := IY + A, REG A TRASHED
CALL INC32HL ; INCREMENT THE VALUE
; INCREMENT DMA
@ -290,7 +276,6 @@ HDSK_RW0:
XOR A ; A := 0 SIGNALS SUCCESS
HDSK_RW5:
POP BC ; RECOVER COUNTERS
JR NZ,HDSK_RW6 ; IF ERROR, GET OUT

452
Source/HBIOS/ide.asm

@ -11,7 +11,7 @@
; +-----------------------------------------------------------------------+
; | CONTROL BLOCK REGISTERS |
; +-----------------------+-------+-------+-------------------------------+
; | REGISTER | PORT | DIR | DESCRIPTION |
; | REGISTER | PORT | DIR | DESCRIPTION |
; +-----------------------+-------+-------+-------------------------------+
; | IDE_IO_ALTSTAT | 0x0E | R | ALTERNATE STATUS REGISTER |
; | IDE_IO_CTRL | 0x0E | W | DEVICE CONTROL REGISTER |
@ -21,7 +21,7 @@
; +-----------------------+-------+-------+-------------------------------+
; | COMMAND BLOCK REGISTERS |
; +-----------------------+-------+-------+-------------------------------+
; | REGISTER | PORT | DIR | DESCRIPTION |
; | REGISTER | PORT | DIR | DESCRIPTION |
; +-----------------------+-------+-------+-------------------------------+
; | IDE_IO_DATA | 0x00 | R/W | DATA INPUT/OUTPUT |
; | IDE_IO_ERR | 0x01 | R | ERROR REGISTER |
@ -31,7 +31,7 @@
; | IDE_IO_CYLLO | 0x04 | R/W | CYLINDER NUM REGISTER (LSB) |
; | IDE_IO_CYLHI | 0x05 | R/W | CYLINDER NUM REGISTER (MSB) |
; | IDE_IO_DRVHD | 0x06 | R/W | DRIVE/HEAD REGISTER |
; | IDE_IO_LBA0* | 0x03 | R/W | LBA BYTE 0 (BITS 0-7) |
; | IDE_IO_LBA0* | 0x03 | R/W | LBA BYTE 0 (BITS 0-7) |
; | IDE_IO_LBA1* | 0x04 | R/W | LBA BYTE 1 (BITS 8-15) |
; | IDE_IO_LBA2* | 0x05 | R/W | LBA BYTE 2 (BITS 16-23) |
; | IDE_IO_LBA3* | 0x06 | R/W | LBA BYTE 3 (BITS 24-27) |
@ -42,9 +42,9 @@
;
; === STATUS REGISTER ===
;
; 7 6 5 4 3 2 1 0
; 7 6 5 4 3 2 1 0
; +-------+-------+-------+-------+-------+-------+-------+-------+
; | BSY | DRDY | DWF | DSC | DRQ | CORR | IDX | ERR |
; | BSY | DRDY | DWF | DSC | DRQ | CORR | IDX | ERR |
; +-------+-------+-------+-------+-------+-------+-------+-------+
;
; BSY: BUSY
@ -58,9 +58,9 @@
;
; === ERROR REGISTER ===
;
; 7 6 5 4 3 2 1 0
; 7 6 5 4 3 2 1 0
; +-------+-------+-------+-------+-------+-------+-------+-------+
; | BBK | UNC | MC | IDNF | MCR | ABRT | TK0NF | AMNF |
; | BBK | UNC | MC | IDNF | MCR | ABRT | TK0NF | AMNF |
; +-------+-------+-------+-------+-------+-------+-------+-------+
; (VALID WHEN ERR BIT IS SET IN STATUS REGISTER)
;
@ -75,9 +75,9 @@
;
; === DRIVE/HEAD / LBA3 REGISTER ===
;
; 7 6 5 4 3 2 1 0
; 7 6 5 4 3 2 1 0
; +-------+-------+-------+-------+-------+-------+-------+-------+
; | 1 | L | 1 | DRV | HS3 | HS2 | HS1 | HS0 |
; | 1 | L | 1 | DRV | HS3 | HS2 | HS1 | HS0 |
; +-------+-------+-------+-------+-------+-------+-------+-------+
;
; L: 0 = CHS ADDRESSING, 1 = LBA ADDRESSING
@ -86,9 +86,9 @@
;
; === DEVICE CONTROL REGISTER ===
;
; 7 6 5 4 3 2 1 0
; 7 6 5 4 3 2 1 0
; +-------+-------+-------+-------+-------+-------+-------+-------+
; | X | X | X | X | 1 | SRST | ~IEN | 0 |
; | X | X | X | X | 1 | SRST | ~IEN | 0 |
; +-------+-------+-------+-------+-------+-------+-------+-------+
;
; SRST: SOFTWARE RESET
@ -106,8 +106,8 @@
; IDE2: SECONDARY MASTER
; IDE3: SECONDARY SLAVE
;
IDE_UNITCNT .EQU 2 ; ASSUME ONLY PRIMARY INTERFACE
IDE_IO_BASE .EQU $20 ; DEFAULT IO BASE (NOTE OVERRIDES BELOW)
IDE_DEVCNT .EQU 2 ; ASSUME ONLY PRIMARY INTERFACE
IDE_IO_BASE .EQU $20 ; DEFAULT IO BASE (NOTE OVERRIDES BELOW)
;
#IF (IDEMODE == IDEMODE_MK4)
IDE_IO_BASE .SET MK4_IDE
@ -123,46 +123,46 @@ IDE_IO_BASE .SET $E0
#IF ((IDEMODE == IDEMODE_DIO) | (IDEMODE == IDEMODE_MK4))
#IF (IDE8BIT)
IDE_IO_DATA .EQU $IDE_IO_BASE + $00 ; DATA PORT (8 BIT PIO) (R/W)
IDE_IO_DATA .EQU $IDE_IO_BASE + $00 ; DATA PORT (8 BIT PIO) (R/W)
#ELSE
IDE_IO_DATALO .EQU $IDE_IO_BASE + $00 ; DATA PORT (16 BIT PIO LO BYTE) (R/W)
IDE_IO_DATAHI .EQU $IDE_IO_BASE + $08 ; DATA PORT (16 BIT PIO HI BYTE) (R/W)
IDE_IO_DATALO .EQU $IDE_IO_BASE + $00 ; DATA PORT (16 BIT PIO LO BYTE) (R/W)
IDE_IO_DATAHI .EQU $IDE_IO_BASE + $08 ; DATA PORT (16 BIT PIO HI BYTE) (R/W)
IDE_IO_DATA .EQU IDE_IO_DATALO
#ENDIF
#ENDIF
;
#IF (IDEMODE == IDEMODE_DIDE)
IDE_UNITCNT .SET 4 ; DIDE HAS PRIMARY AND SECONDARY INTERACES
IDE_DEVCNT .SET 4 ; DIDE HAS PRIMARY AND SECONDARY INTERACES
#IF (IDE8BIT)
IDE_IO_DATA .EQU $IDE_IO_BASE + $00 ; DATA PORT (8 BIT PIO) (R/W)
IDE_IO_DATA .EQU $IDE_IO_BASE + $00 ; DATA PORT (8 BIT PIO) (R/W)
#ELSE
IDE_IO_DATA .EQU $IDE_IO_BASE + $08 ; DATA PORT (16 BIT PIO LO/HI BYTES) (R/W)
IDE_IO_DMA .EQU $IDE_IO_BASE + $09 ; DATA PORT (16 BIT DMA LO/HI BYTES) (R/W)
IDE_IO_DATA .EQU $IDE_IO_BASE + $08 ; DATA PORT (16 BIT PIO LO/HI BYTES) (R/W)
IDE_IO_DMA .EQU $IDE_IO_BASE + $09 ; DATA PORT (16 BIT DMA LO/HI BYTES) (R/W)
#ENDIF
#ENDIF
;
#IF ((IDEMODE == IDEMODE_RC) | (IDEMODE == IDEMODE_SMB))
IDE_UNITCNT .SET 1 ; RC2014 COMPACT FLASH SUPPORTS ONLY 1 DEVICE
IDE_DEVCNT .SET 1 ; RC2014 COMPACT FLASH SUPPORTS ONLY 1 DEVICE
IDE_IO_DATA .EQU $IDE_IO_BASE + $00 ; DATA PORT (8 BIT) (R/W)
#ENDIF
;
;IDE_IO_DATA .EQU $IDE_IO_BASE + $00 ; DATA INPUT/OUTPUT (R/W)
IDE_IO_ERR .EQU $IDE_IO_BASE + $01 ; ERROR REGISTER (R)
IDE_IO_FEAT .EQU $IDE_IO_BASE + $01 ; FEATURES REGISTER (W)
IDE_IO_COUNT .EQU $IDE_IO_BASE + $02 ; SECTOR COUNT REGISTER (R/W)
IDE_IO_SECT .EQU $IDE_IO_BASE + $03 ; SECTOR NUMBER REGISTER (R/W)
IDE_IO_CYLLO .EQU $IDE_IO_BASE + $04 ; CYLINDER NUM REGISTER (LSB) (R/W)
IDE_IO_CYLHI .EQU $IDE_IO_BASE + $05 ; CYLINDER NUM REGISTER (MSB) (R/W)
IDE_IO_DRVHD .EQU $IDE_IO_BASE + $06 ; DRIVE/HEAD REGISTER (R/W)
IDE_IO_ERR .EQU $IDE_IO_BASE + $01 ; ERROR REGISTER (R)
IDE_IO_FEAT .EQU $IDE_IO_BASE + $01 ; FEATURES REGISTER (W)
IDE_IO_COUNT .EQU $IDE_IO_BASE + $02 ; SECTOR COUNT REGISTER (R/W)
IDE_IO_SECT .EQU $IDE_IO_BASE + $03 ; SECTOR NUMBER REGISTER (R/W)
IDE_IO_CYLLO .EQU $IDE_IO_BASE + $04 ; CYLINDER NUM REGISTER (LSB) (R/W)
IDE_IO_CYLHI .EQU $IDE_IO_BASE + $05 ; CYLINDER NUM REGISTER (MSB) (R/W)
IDE_IO_DRVHD .EQU $IDE_IO_BASE + $06 ; DRIVE/HEAD REGISTER (R/W)
IDE_IO_LBA0 .EQU $IDE_IO_BASE + $03 ; LBA BYTE 0 (BITS 0-7) (R/W)
IDE_IO_LBA1 .EQU $IDE_IO_BASE + $03 ; LBA BYTE 1 (BITS 8-15) (R/W)
IDE_IO_LBA2 .EQU $IDE_IO_BASE + $03 ; LBA BYTE 2 (BITS 16-23) (R/W)
IDE_IO_LBA3 .EQU $IDE_IO_BASE + $03 ; LBA BYTE 3 (BITS 24-27) (R/W)
IDE_IO_STAT .EQU $IDE_IO_BASE + $07 ; STATUS REGISTER (R)
IDE_IO_CMD .EQU $IDE_IO_BASE + $07 ; COMMAND REGISTER (EXECUTE) (W)
IDE_IO_ALTSTAT .EQU $IDE_IO_BASE + $0E ; ALTERNATE STATUS REGISTER (R)
IDE_IO_CTRL .EQU $IDE_IO_BASE + $0E ; DEVICE CONTROL REGISTER (W)
IDE_IO_DRVADR .EQU $IDE_IO_BASE + $0F ; DRIVE ADDRESS REGISTER (R)
IDE_IO_STAT .EQU $IDE_IO_BASE + $07 ; STATUS REGISTER (R)
IDE_IO_CMD .EQU $IDE_IO_BASE + $07 ; COMMAND REGISTER (EXECUTE) (W)
IDE_IO_ALTSTAT .EQU $IDE_IO_BASE + $0E ; ALTERNATE STATUS REGISTER (R)
IDE_IO_CTRL .EQU $IDE_IO_BASE + $0E ; DEVICE CONTROL REGISTER (W)
IDE_IO_DRVADR .EQU $IDE_IO_BASE + $0F ; DRIVE ADDRESS REGISTER (R)
;
; COMMAND BYTES
;
@ -200,30 +200,73 @@ IDE_DRVSEL:
IDE_DRVMASTER .DB %11100000 ; LBA, MASTER DEVICE
IDE_DRVSLAVE .DB %11110000 ; LBA, SLAVE DEVICE
;
; PER UNIT DATA OFFSETS (CAREFUL NOT TO EXCEED PER UNIT SPACE IN IDE_UNITDATA)
; SEE IDE_UNITDATA IN DATA STORAGE BELOW
; IDE DEVICE CONFIGURATION
;
IDE_CFGSIZ .EQU 12 ; SIZE OF CFG TBL ENTRIES
;
; PER DEVICE DATA OFFSETS
;
IDE_DEV .EQU 0 ; OFFSET OF DEVICE NUMBER (BYTE)
IDE_STAT .EQU 1 ; LAST STATUS (BYTE)
IDE_TYPE .EQU 2 ; DEVICE TYPE (BYTE)
IDE_FLAGS .EQU 3 ; FLAG BITS BIT 0=CF, 1=LBA (BYTE)
IDE_MEDCAP .EQU 4 ; MEDIA CAPACITY (DWORD)
IDE_LBA .EQU 8 ; OFFSET OF LBA (DWORD)
;
IDE_CFGTBL:
; DEVICE 0, PRIMARY MASTER
.DB 0 ; DRIVER DEVICE NUMBER
.DB 0 ; DEVICE STATUS
.DB 0 ; DEVICE TYPE
.DB 0 ; FLAGS BYTE
.DW 0,0 ; DEVICE CAPACITY
.DW 0,0 ; CURRENT LBA
#IF (IDE_DEVCNT >= 2)
; DEVICE 1, PRIMARY SLAVE
.DB 1 ; DRIVER DEVICE NUMBER
.DB 0 ; DEVICE STATUS
.DB 0 ; DEVICE TYPE
.DB 0 ; FLAGS BYTE
.DW 0,0 ; DEVICE CAPACITY
.DW 0,0 ; CURRENT LBA
#ENDIF
#IF (IDE_DEVCNT >= 3)
; DEVICE 2, SECONDARY MASTER
.DB 2 ; DRIVER DEVICE NUMBER
.DB 0 ; DEVICE STATUS
.DB 0 ; DEVICE TYPE
.DB 0 ; FLAGS BYTE
.DW 0,0 ; DEVICE CAPACITY
.DW 0,0 ; CURRENT LBA
#ENDIF
#IF (IDE_DEVCNT >= 4)
; DEVICE 2, SECONDARY SLAVE
.DB 3 ; DRIVER DEVICE NUMBER
.DB 0 ; DEVICE STATUS
.DB 0 ; DEVICE TYPE
.DB 0 ; FLAGS BYTE
.DW 0,0 ; DEVICE CAPACITY
.DW 0,0 ; CURRENT LBA
#ENDIF
;
IDE_STAT .EQU 0 ; LAST STATUS (1 BYTE)
IDE_TYPE .EQU 1 ; DEVICE TYPE (1 BYTE)
IDE_CAPACITY .EQU 2 ; DEVICE CAPACITY (1 DWORD/4 BYTES)
IDE_CFFLAG .EQU 6 ; CF FLAG (1 BYTE), NON-ZERO=CF
#IF ($ - IDE_CFGTBL) != (IDE_DEVCNT * IDE_CFGSIZ)
.ECHO "*** INVALID IDE CONFIG TABLE ***\n"
#ENDIF
;
.DB $FF ; END MARKER
;
; THE IDE_WAITXXX FUNCTIONS ARE BUILT TO TIMEOUT AS NEEDED SO DRIVER WILL
; NOT HANG IF DEVICE IS UNRESPONSIVE. DIFFERENT TIMEOUTS ARE USED DEPENDING
; ON THE SITUATION. GENERALLY, THE FAST TIMEOUT IS USED TO PROBE FOR DEVICES
; USING FUNCTIONS THAT PERFORM NO I/O. OTHERWISE THE NORMAL TIMEOUT IS USED.
; USING FUNCTIONS THAT PERFORM NO I/O. OTHERWISE THE NORMAL TIMEOUT IS USED.
; IDE SPEC ALLOWS FOR UP TO 30 SECS MAX TO RESPOND. IN PRACTICE, THIS IS WAY
; TOO LONG, BUT IF YOU ARE USING A VERY OLD DEVICE, THESE TIMEOUTS MAY NEED TO
; BE ADJUSTED. NOTE THAT THESE ARE BYTE VALUES, SO YOU CANNOT EXCEED 255.
; BE ADJUSTED. NOTE THAT THESE ARE BYTE VALUES, SO YOU CANNOT EXCEED 255.
; THE TIMEOUTS ARE IN UNITS OF .05 SECONDS.
;
IDE_TONORM .EQU 200 ; NORMAL TIMEOUT IS 10 SECS
IDE_TOFAST .EQU 10 ; FAST TIMEOUT IS 0.5 SECS
;
; MACRO TO RETURN POINTER TO FIELD WITHIN UNIT DATA
;
#DEFINE IDE_DPTR(FIELD) CALL IDE_DPTRIMP \ .DB FIELD
;
;=============================================================================
; INITIALIZATION ENTRY POINT
;=============================================================================
@ -254,10 +297,6 @@ IDE_INIT:
LD A,IDE_IO_DATA ; GET IO ADDRESS
CALL PRTHEXBYTE ; PRINT IT
;
; PRINT UNIT COUNT
PRTS(" UNITS=$") ; PRINT LABEL FOR UNIT COUNT
LD A,IDE_UNITCNT ; GET UNIT COUNT
CALL PRTDECB ; PRINT IT IN DECIMAL
;
CALL IDE_DETECT ; CHECK FOR HARDWARE
JR Z,IDE_INIT00 ; CONTINUE IF PRESENT
@ -268,45 +307,47 @@ IDE_INIT:
RET
;
IDE_INIT00:
; PRINT UNIT COUNT
PRTS(" DEVICES=$") ; PRINT LABEL FOR DEVICE COUNT
LD A,IDE_DEVCNT ; GET UNIT COUNT
CALL PRTDECB ; PRINT IT IN DECIMAL
;
; SETUP THE DISPATCH TABLE ENTRIES
;
LD B,IDE_UNITCNT ; LOOP CONTROL
LD C,0 ; PHYSICAL UNIT INDEX
LD B,IDE_DEVCNT ; LOOP CONTROL
LD IY,IDE_CFGTBL ; START OF CFG TABLE
IDE_INIT0:
PUSH BC ; SAVE LOOP CONTROL
LD B,C ; PHYSICAL UNIT
LD C,DIODEV_IDE ; DEVICE TYPE
LD DE,0 ; UNIT DATA BLOB ADDRESS
CALL DIO_ADDENT ; ADD ENTRY, BC IS NOT DESTROYED
POP BC ; RESTORE LOOP CONTROL
INC C ; NEXT PHYSICAL UNIT
DJNZ IDE_INIT0 ; LOOP UNTIL DONE
PUSH BC ; SAVE LOOP CONTROL
LD BC,IDE_FNTBL ; BC := FUNC TABLE ADR
PUSH IY ; CFG ENTRY POINTER
POP DE ; COPY TO DE
CALL DIO_ADDENT ; ADD ENTRY, BC IS NOT DESTROYED
LD BC,IDE_CFGSIZ ; SIZE OF CFG ENTRY
ADD IY,BC ; BUMP IY TO NEXT ENTRY
POP BC ; RESTORE BC
DJNZ IDE_INIT0 ; LOOP AS NEEDED
;
; INITIALIZE THE IDE INTERFACE NOW
CALL IDE_RESET ; DO HARDWARE SETUP/INIT
RET NZ ; ABORT IF RESET FAILS
;
; DEVICE DISPLAY LOOP
LD B,IDE_UNITCNT ; LOOP ONCE PER UNIT
LD C,0 ; C IS UNIT INDEX
LD B,IDE_DEVCNT ; LOOP ONCE PER DEVICE
LD IY,IDE_CFGTBL ; START OF CFG TABLE
IDE_INIT1:
LD A,C ; UNIT NUM TO ACCUM
PUSH BC ; SAVE LOOP CONTROL
CALL IDE_INIT2 ; DISPLAY UNIT INFO
LD BC,IDE_CFGSIZ ; SIZE OF CFG ENTRY
ADD IY,BC ; BUMP IY TO NEXT ENTRY
POP BC ; RESTORE LOOP CONTROL
INC C ; INCREMENT UNIT INDEX
DJNZ IDE_INIT1 ; LOOP UNTIL DONE
RET ; DONE
;
IDE_INIT2:
LD (IDE_UNIT),A ; SET CURRENT UNIT
;
; CHECK FOR BAD STATUS
IDE_DPTR(IDE_STAT) ; GET STATUS ADR IN HL, AF TRASHED
LD A,(HL)
OR A
JP NZ,IDE_PRTSTAT
LD A,(IY+IDE_STAT) ; GET STATUS
OR A ; SET FLAGS
JP NZ,IDE_PRTSTAT ; EXIT VIA PRINT STATUS
;
CALL IDE_PRTPREFIX ; PRINT DEVICE PREFIX
;
@ -316,18 +357,15 @@ IDE_INIT2:
;
; PRINT LBA/NOLBA
CALL PC_SPACE ; FORMATTING
LD HL,HB_WRKBUF ; POINT TO BUFFER START
LD DE,98+1 ; OFFSET OF BYTE CONTAINING LBA FLAG
ADD HL,DE ; POINT TO FINAL BUFFER ADDRESS
LD A,(HL) ; GET THE BYTE
BIT 1,A ; CHECK THE LBA BIT
BIT 1,(IY+IDE_FLAGS) ; TEST LBA FLAG
LD DE,IDE_STR_NO ; POINT TO "NO" STRING
CALL Z,WRITESTR ; PRINT "NO" BEFORE "LBA" IF LBA NOT SUPPORTED
PRTS("LBA$") ; PRINT "LBA" REGARDLESS
;
; PRINT STORAGE CAPACITY (BLOCK COUNT)
PRTS(" BLOCKS=0x$") ; PRINT FIELD LABEL
IDE_DPTR(IDE_CAPACITY) ; SET HL TO ADR OF DEVICE CAPACITY
LD A,IDE_MEDCAP ; OFFSET TO CAPACITY FIELD
CALL LDHLIYA ; HL := IY + A, REG A TRASHED
CALL LD32 ; GET THE CAPACITY VALUE
CALL PRTHEX32 ; PRINT HEX VALUE
;
@ -356,48 +394,30 @@ IDE_DETECT:
RET ; AND RETURN
;
;=============================================================================
; FUNCTION DISPATCH ENTRY POINT
; DRIVER FUNCTION TABLE
;=============================================================================
;
IDE_DISPATCH:
; VERIFY AND SAVE THE TARGET DEVICE/UNIT LOCALLY IN DRIVER
LD A,C ; DEVICE/UNIT FROM C
AND $0F ; ISOLATE UNIT NUM
CP IDE_UNITCNT
CALL NC,PANIC ; PANIC IF TOO HIGH
LD (IDE_UNIT),A ; SAVE IT
;
; DISPATCH ACCORDING TO DISK SUB-FUNCTION
LD A,B ; GET REQUESTED FUNCTION
AND $0F ; ISOLATE SUB-FUNCTION
JP Z,IDE_STATUS ; SUB-FUNC 0: STATUS
DEC A
JP Z,IDE_RESET ; SUB-FUNC 1: RESET
DEC A
JP Z,IDE_SEEK ; SUB-FUNC 2: SEEK
DEC A
JP Z,IDE_READ ; SUB-FUNC 3: READ SECTORS
DEC A
JP Z,IDE_WRITE ; SUB-FUNC 4: WRITE SECTORS
DEC A
JP Z,IDE_VERIFY ; SUB-FUNC 5: VERIFY SECTORS
DEC A
JP Z,IDE_FORMAT ; SUB-FUNC 6: FORMAT TRACK
DEC A
JP Z,IDE_DEVICE ; SUB-FUNC 7: DEVICE REPORT
DEC A
JP Z,IDE_MEDIA ; SUB-FUNC 8: MEDIA REPORT
DEC A
JP Z,IDE_DEFMED ; SUB-FUNC 9: DEFINE MEDIA
DEC A
JP Z,IDE_CAP ; SUB-FUNC 10: REPORT CAPACITY
DEC A
JP Z,IDE_GEOM ; SUB-FUNC 11: REPORT GEOMETRY
IDE_FNTBL:
.DW IDE_STATUS
.DW IDE_RESET
.DW IDE_SEEK
.DW IDE_READ
.DW IDE_WRITE
.DW IDE_VERIFY
.DW IDE_FORMAT
.DW IDE_DEVICE
.DW IDE_MEDIA
.DW IDE_DEFMED
.DW IDE_CAP
.DW IDE_GEOM
#IF (($ - IDE_FNTBL) != (DIO_FNCNT * 2))
.ECHO "*** INVALID IDE FUNCTION TABLE ***\n"
#ENDIF
;
IDE_VERIFY:
IDE_FORMAT:
IDE_DEFMED:
CALL PANIC ; INVALID SUB-FUNCTION
CALL PANIC ; NOT IMPLEMENTED
;
;
;
@ -436,12 +456,11 @@ IDE_IO1:
LD HL,(IDE_IOFNADR) ; GET PENDING IO FUNCTION ADDRESS
CALL JPHL ; ... AND CALL IT
JR NZ,IDE_IO2 ; IF ERROR, SKIP INCREMENT
LD HL,HSTLBA ; POINT TO 32-BIT CURRENT LBA
PUSH HL ; SAVE POINTER
CALL LD32 ; LOAD 32-BIT LBA INTO DE:HL
CALL INC32 ; INCREMENT LBA FOR NEXT I/O
POP BC ; RECOVER LBA POINTER INTO BC
CALL ST32 ; AND SAVE IT
; INCREMENT LBA
LD A,IDE_LBA ; LBA OFFSET
CALL LDHLIYA ; HL := IY + A, REG A TRASHED
CALL INC32HL ; INCREMENT THE VALUE
; INCREMENT DMA
LD HL,IDE_DSKBUF+1 ; POINT TO MSB OF BUFFER ADR
INC (HL) ; BUMP DMA BY
INC (HL) ; ... 512 BYTES
@ -461,8 +480,7 @@ IDE_IO3:
;
IDE_STATUS:
; RETURN UNIT STATUS
IDE_DPTR(IDE_STAT) ; HL := ADR OF STATUS, AF TRASHED
LD A,(HL) ; GET STATUS OF SELECTED UNIT
LD A,(IY+IDE_STAT) ; GET STATUS OF SELECTED DEVICE
OR A ; SET FLAGS
RET ; AND RETURN
;
@ -470,14 +488,12 @@ IDE_STATUS:
;
IDE_DEVICE:
LD D,DIODEV_IDE ; D := DEVICE TYPE
LD E,C ; E := PHYSICAL UNIT
IDE_DPTR(IDE_CFFLAG) ; POINT TO CF FLAG
LD A,(HL) ; GET FLAG
OR A ; SET ACCUM FLAGS
LD E,(IY+IDE_DEV) ; E := PHYSICAL DEVICE NUMBER
BIT 0,(IY+IDE_FLAGS) ; TEST CF BIT IN FLAGS
LD C,%00000000 ; ASSUME NON-REMOVABLE HARD DISK
JR Z,IDE_DEVICE1 ; IF Z, WE ARE DONE
LD C,%01001000 ; OTHERWISE REMOVABLE COMPACT FLASH
IDE_DEVICE1:
IDE_DEVICE1:
XOR A ; SIGNAL SUCCESS
RET
;
@ -489,8 +505,7 @@ IDE_MEDIA:
JR Z,IDE_MEDIA2 ; JUST REPORT CURRENT STATUS AND MEDIA
;
; GET CURRENT STATUS
IDE_DPTR(IDE_STAT) ; POINT TO UNIT STATUS
LD A,(HL) ; GET STATUS
LD A,(IY+IDE_STAT) ; GET STATUS
OR A ; SET FLAGS
JR NZ,IDE_MEDIA1 ; ERROR ACTIVE, GO RIGHT TO RESET
;
@ -507,8 +522,7 @@ IDE_MEDIA1:
CALL IDE_RESET ; RESET IDE INTERFACE
;
IDE_MEDIA2:
IDE_DPTR(IDE_STAT) ; POINT TO UNIT STATUS
LD A,(HL) ; GET STATUS
LD A,(IY+IDE_STAT) ; GET STATUS
OR A ; SET FLAGS
LD D,0 ; NO MEDIA CHANGE DETECTED
LD E,MID_HD ; ASSUME WE ARE OK
@ -522,19 +536,21 @@ IDE_SEEK:
BIT 7,D ; CHECK FOR LBA FLAG
CALL Z,HB_CHS2LBA ; CLEAR MEANS CHS, CONVERT TO LBA
RES 7,D ; CLEAR FLAG REGARDLESS (DOES NO HARM IF ALREADY LBA)
LD BC,HSTLBA ; POINT TO LBA STORAGE
CALL ST32 ; SAVE LBA ADDRESS
LD (IY+IDE_LBA+0),L ; SAVE NEW LBA
LD (IY+IDE_LBA+1),H ; ...
LD (IY+IDE_LBA+2),E ; ...
LD (IY+IDE_LBA+3),D ; ...
XOR A ; SIGNAL SUCCESS
RET ; AND RETURN
;
;
;
IDE_CAP:
IDE_DPTR(IDE_STAT) ; POINT TO UNIT STATUS
LD A,(HL) ; GET STATUS
LD A,(IY+IDE_STAT) ; GET STATUS
PUSH AF ; SAVE IT
IDE_DPTR(IDE_CAPACITY) ; POINT HL TO CAPACITY OF CUR UNIT
CALL LD32 ; GET THE CURRENT CAPACITY DO DE:HL
LD A,IDE_MEDCAP ; OFFSET TO CAPACITY FIELD
CALL LDHLIYA ; HL := IY + A, REG A TRASHED
CALL LD32 ; GET THE CURRENT CAPACITY INTO DE:HL
LD BC,512 ; 512 BYTES PER BLOCK
POP AF ; RECOVER STATUS
OR A ; SET FLAGS
@ -639,7 +655,8 @@ IDE_SETADDR:
; IDE_IO_LBA3 HAS ALREADY BEEN SET
; HSTLBA2-0 --> IDE_IO_LBA2-0
LD C,IDE_IO_LBA0 + 3 ; STARTING IO PORT (NOT PRE-DEC BELOW)
LD HL,HSTLBA + 2 ; STARTING LBA BYTE ADR
LD A,IDE_LBA + 2 ; OFFSET OF 3RD BYTE OF LBA IN CFG
CALL LDHLIYA ; HL := IY + A, REG A TRASHED
LD B,3 ; SEND 3 BYTES
IDE_SETADDR1:
;
@ -704,7 +721,6 @@ IDE_GETBUF:
CALL IDE_WAITDRQ ; WAIT FOR BUFFER READY
RET NZ ; BAIL OUT IF TIMEOUT
;LD HL,(IDE_DSKBUF)
LD B,0
#IF (IDE8BIT | (IDEMODE == IDEMODE_DIDE))
@ -835,28 +851,28 @@ IDE_RESET:
LD DE,150000/16 ; ~???MS
CALL VDELAY
;
; CLEAR OUT ALL DATA (FOR ALL UNITS)
LD HL,IDE_UDATA
LD BC,IDE_UDLEN
XOR A
CALL FILL
;; CLEAR OUT ALL DATA (FOR ALL UNITS)
;LD HL,IDE_UDATA
;LD BC,IDE_UDLEN
;XOR A
;CALL FILL
;
LD A,(IDE_UNIT) ; GET THE CURRENT UNIT SELECTION
PUSH AF ; AND SAVE IT
;LD A,(IDE_UNIT) ; GET THE CURRENT UNIT SELECTION
;PUSH AF ; AND SAVE IT
PUSH IY ; SAVE CURRENT DEVICE CFG PTR
; PROBE / INITIALIZE ALL UNITS
LD B,IDE_UNITCNT ; NUMBER OF UNITS TO TRY
LD C,0 ; UNIT INDEX FOR LOOP
LD B,IDE_DEVCNT ; NUMBER OF UNITS TO TRY
LD IY,IDE_CFGTBL ; START OF CFG TABLE
IDE_RESET1:
LD A,C ; UNIT NUMBER TO A
PUSH BC
PUSH BC ; SAVE LOOP CONTROL
CALL IDE_INITUNIT ; PROBE/INIT UNIT
POP BC
INC C ; NEXT UNIT
LD BC,IDE_CFGSIZ ; SIZE OF CFG ENTRY
ADD IY,BC ; BUMP IY TO NEXT ENTRY
POP BC ; RESTORE BC
DJNZ IDE_RESET1 ; LOOP AS NEEDED
;
POP AF ; RECOVER ORIGINAL UNIT NUMBER
LD (IDE_UNIT),A ; AND SAVE IT
POP IY ; RECOVER DEVICE CFG PTR
;
XOR A ; SIGNAL SUCCESS
RET ; AND DONE
@ -864,8 +880,6 @@ IDE_RESET1:
;
;
IDE_INITUNIT:
LD (IDE_UNIT),A ; SET ACTIVE UNIT
CALL IDE_SELUNIT ; SELECT UNIT
RET NZ ; ABORT IF ERROR
@ -888,17 +902,18 @@ IDE_INITUNIT:
; REGISTER A IS DESTROYED
;
IDE_SELUNIT:
LD A,(IDE_UNIT) ; GET UNIT
CP IDE_UNITCNT ; CHECK VALIDITY (EXCEED UNIT COUNT?)
JP NC,IDE_INVUNIT ; HANDLE INVALID UNIT
#IF (IDETRACE >= 3)
CALL IDE_PRTPREFIX
PRTS(" SELUNIT$")
#ENDIF
;
#IF (IDEMODE == IDEMODE_DIDE)
; SELECT PRIMARY/SECONDARY INTERFACE FOR DIDE HARDWARE
#ENDIF
;
; DETERMINE AND SAVE DRIVE/HEAD VALUE FOR SELECTED UNIT
PUSH HL ; SAVE HL
LD A,(IDE_UNIT) ; GET CURRENT UNIT
PUSH HL ; SAVE HL, IT IS DESTROYED BELOW
PUSH IY
POP BC
LD A,(IY+IDE_DEV) ; GET DEVICE
AND $01 ; LS BIT DETERMINES MASTER/SLAVE
LD HL,IDE_DRVSEL
CALL ADDHLA
@ -921,7 +936,7 @@ IDE_PROBE:
OUT (IDE_IO_DRVHD),A
DCALL PC_SPACE
DCALL PRTHEXBYTE
CALL DELAY ; DELAY ~16US
;
LD C,IDE_IO_STAT
@ -974,8 +989,8 @@ IDE_PROBE0:
;
IDE_PROBE1:
; SIGNATURE MATCHES ATA DEVICE, RECORD TYPE AND RETURN SUCCESS
IDE_DPTR(IDE_TYPE) ; POINT HL TO UNIT TYPE FIELD, A IS TRASHED
LD (HL),IDE_TYPEATA ; SET THE DEVICE TYPE
LD A,IDE_TYPEATA ; TYPE = ATA
LD (IY+IDE_TYPE),A ; SET IT IN INSTANCE DATA
XOR A ; SIGNAL SUCCESS
RET ; DONE, NOTE THAT A=0 AND Z IS SET
;
@ -983,23 +998,22 @@ IDE_PROBE1:
;
IDE_INITDEV:
;
IDE_DPTR(IDE_TYPE) ; POINT HL TO UNIT TYPE FIELD, A IS TRASHED
LD A,(HL) ; GET THE DEVICE TYPE
LD A,(IY+IDE_TYPE) ; GET THE DEVICE TYPE
OR A ; SET FLAGS
JP Z,IDE_NOMEDIA ; EXIT SETTING NO MEDIA STATUS
;
; CLEAR OUT UNIT SPECIFIC DATA, BUT PRESERVE THE EXISTING
; VALUE OF THE UNIT TYPE WHICH WAS ESTABLISHED BY THE DEVICE
; PROBES WHEN THE IDE BUS WAS RESET
PUSH AF ; SAVE UNIT TYPE VALUE FROM ABOVE
PUSH HL ; SAVE UNIT TYPE FIELD POINTER
IDE_DPTR(0) ; SET HL TO START OF UNIT DATA
LD BC,IDE_UDLEN
XOR A
CALL FILL
POP HL ; RECOVER UNIT TYPE FIELD POINTER
POP AF ; RECOVER UNIT TYPE VALUE
LD (HL),A ; AND PUT IT BACK
;PUSH AF ; SAVE UNIT TYPE VALUE FROM ABOVE
;PUSH HL ; SAVE UNIT TYPE FIELD POINTER
;IDE_DPTR(0) ; SET HL TO START OF UNIT DATA
;LD BC,IDE_UDLEN
;XOR A
;CALL FILL
;POP HL ; RECOVER UNIT TYPE FIELD POINTER
;POP AF ; RECOVER UNIT TYPE VALUE
;LD (HL),A ; AND PUT IT BACK
;
#IF (IDE8BIT)
LD A,IDE_FEAT_ENABLE8BIT ; FEATURE VALUE = ENABLE 8-BIT PIO
@ -1022,6 +1036,9 @@ IDE_INITDEV:
LD DE,HB_WRKBUF ; POINT TO BUFFER
DCALL DUMP_BUFFER ; DUMP IT IF DEBUGGING
;
XOR A
LD (IY+IDE_FLAGS),0 ; CLEAR FLAGS
; DETERMINE IF CF DEVICE
LD HL,HB_WRKBUF ; FIRST WORD OF IDENTIFY DATA HAS CF FLAG
LD A,$8A ; FIRST BYTE OF MARKER IS $8A
@ -1031,13 +1048,19 @@ IDE_INITDEV:
LD A,$84 ; SECOND BYTE OF MARKER IS $84
CP (HL) ; COMPARE
JR NZ,IDE_INITDEV1 ; IF NOT MATCH, NOT CF
IDE_DPTR(IDE_CFFLAG) ; POINT HL TO CF FLAG FIELD
LD A,$FF ; SET FLAG VALUE TO NON-ZERO (TRUE)
LD (HL),A ; SAVE IT
SET 0,(IY+IDE_FLAGS) ; SET FLAGS BIT FOR CF MEDIA
;
IDE_INITDEV1:
; DETERMINE IF LBA CAPABLE
LD A,(HB_WRKBUF+98+1) ; GET BYTE WITH LBA BIT FROM BUFFER
BIT 1,A ; CHECK THE LBA BIT
JR Z,IDE_INITDEV2 ; NOT SET, BYPASS
SET 1,(IY+IDE_FLAGS) ; SET FLAGS BIT FOR LBA
;
IDE_INITDEV2:
; GET DEVICE CAPACITY AND SAVE IT
IDE_DPTR(IDE_CAPACITY) ; POINT HL TO UNIT CAPACITY FIELD
LD A,IDE_MEDCAP ; OFFSET TO CAPACITY FIELD
CALL LDHLIYA ; HL := IY + A, REG A TRASHED
PUSH HL ; SAVE POINTER
LD HL,HB_WRKBUF ; POINT TO BUFFER START
LD A,120 ; OFFSET OF SECTOR COUNT
@ -1047,18 +1070,16 @@ IDE_INITDEV1:
CALL ST32 ; SAVE CAPACITY
;
; RESET CARD STATUS TO 0 (OK)
IDE_DPTR(IDE_STAT) ; HL := ADR OF STATUS, AF TRASHED
XOR A ; A := 0 (STATUS = OK)
LD (HL),A ; SAVE IT
LD (IY+IDE_STAT),A ; SAVE IT
;
RET ; RETURN, A=0, Z SET
;
;
;
IDE_CHKDEVICE:
IDE_DPTR(IDE_STAT)
LD A,(HL)
OR A
LD A,(IY+IDE_STAT) ; GET STATUS
OR A ; SET FLAGS
RET Z ; RETURN IF ALL IS WELL
;
; ATTEMPT TO REINITIALIZE HERE???
@ -1098,7 +1119,7 @@ IDE_WAITDRQ2:
AND %10001000 ; TO FILL (OR READY TO FILL)
XOR %00001000
RET Z
DEC DE
DEC DE
LD A,D
OR E
JR NZ,IDE_WAITDRQ2
@ -1159,12 +1180,8 @@ IDE_BSYTO:
JR IDE_ERR
;
IDE_ERR:
PUSH HL ; IS THIS NEEDED?
PUSH AF ; SAVE INCOMING STATUS
IDE_DPTR(IDE_STAT) ; GET STATUS ADR IN HL, AF TRASHED
POP AF ; RESTORE INCOMING STATUS
LD (HL),A ; UPDATE STATUS
POP HL ; IS THIS NEEDED?
LD (IY+IDE_STAT),A ; SAVE NEW STATUS
;
IDE_ERR2:
#IF (IDETRACE >= 2)
CALL IDE_PRTSTAT
@ -1252,7 +1269,7 @@ IDE_PRTPREFIX:
PUSH AF
CALL NEWLINE
PRTS("IDE$")
LD A,(IDE_UNIT)
LD A,(IY+IDE_DEV) ; GET CURRENT DEVICE NUM
ADD A,'0'
CALL COUT
CALL PC_COLON
@ -1268,14 +1285,14 @@ IDE_DSKY:
LD (HL),A ; SAVE IN BUFFER
INC HL ; INCREMENT BUFFER POINTER
IN A,(IDE_IO_CYLHI) ; GET DRIVE/HEAD
LD (HL),A ; SAVE IN BUFFER
INC HL ; INCREMENT BUFFER POINTER
LD (HL),A ; SAVE IN BUFFER
INC HL ; INCREMENT BUFFER POINTER
IN A,(IDE_IO_CYLLO) ; GET DRIVE/HEAD
LD (HL),A ; SAVE IN BUFFER
INC HL ; INCREMENT BUFFER POINTER
LD (HL),A ; SAVE IN BUFFER
INC HL ; INCREMENT BUFFER POINTER
IN A,(IDE_IO_SECT) ; GET DRIVE/HEAD
LD (HL),A ; SAVE IN BUFFER
CALL DSKY_HEXOUT ; SEND IT TO DSKY
LD (HL),A ; SAVE IN BUFFER
CALL DSKY_HEXOUT ; SEND IT TO DSKY
RET
#ENDIF
;
@ -1299,40 +1316,11 @@ IDE_STR_NO .TEXT "NO$"
; DATA STORAGE
;=============================================================================
;
IDE_TIMEOUT .DB IDE_TONORM ; WAIT FUNCS TIMEOUT IN TENTHS OF SEC
IDE_TOSCALER .DW CPUMHZ * 961 ; WAIT FUNCS SCALER FOR CPU SPEED
IDE_TIMEOUT .DB IDE_TONORM ; WAIT FUNCS TIMEOUT IN TENTHS OF SEC
IDE_TOSCALER .DW CPUMHZ * 961 ; WAIT FUNCS SCALER FOR CPU SPEED
;
IDE_CMD .DB 0 ; PENDING COMMAND TO PROCESS
IDE_IOFNADR .DW 0 ; PENDING IO FUNCTION ADDRESS
IDE_DRVHD .DB 0 ; CURRENT DRIVE/HEAD MASK
;
IDE_UNIT .DB 0 ; ACTIVE UNIT, DEFAULT TO ZERO
IDE_DSKBUF .DW 0 ; ACTIVE DISK BUFFER
;
; UNIT SPECIFIC DATA STORAGE
;
IDE_UDATA .FILL IDE_UNITCNT*8,0 ; PER UNIT DATA, 8 BYTES
IDE_DLEN .EQU $ - IDE_UDATA ; LENGTH OF ENTIRE DATA STORAGE FOR ALL UNITS
IDE_UDLEN .EQU IDE_DLEN / IDE_UNITCNT ; LENGTH OF PER UNIT DATA
;
;=============================================================================
; HELPER ROUTINES
;=============================================================================
IDE_CMD .DB 0 ; PENDING COMMAND TO PROCESS
IDE_IOFNADR .DW 0 ; PENDING IO FUNCTION ADDRESS
IDE_DRVHD .DB 0 ; CURRENT DRIVE/HEAD MASK
;
; IMPLEMENTATION FOR MACRO IDE_DPTR
; SET HL TO ADDRESS OF FIELD WITHIN PER UNIT DATA
; HL := ADR OF IDE_UNITDATA[(IDE_UNIT)][(SP)]
; ENTER WITH TOP-OF-STACK = ADDRESS OF FIELD OFFSET
; AF IS TRASHED
;
IDE_DPTRIMP:
LD HL,IDE_UDATA ; POINT TO START OF UNIT DATA ARRAY
LD A,(IDE_UNIT) ; GET CURRENT UNIT NUM
RLCA ; MULTIPLY BY
RLCA ; ... SIZE OF PER UNIT DATA
RLCA ; ... (8 BYTES)
EX (SP),HL ; GET PTR TO FIELD OFFSET VALUE FROM TOS
ADD A,(HL) ; ADD IT TO START OF UNIT DATA IN ACCUM
INC HL ; BUMP HL TO NEXT REAL INSTRUCTION
EX (SP),HL ; AND PUT IT BACK ON STACK, HL GETS ADR OF START OF DATA
JP ADDHLA ; CALC FINAL ADR IN HL AND RETURN
IDE_DSKBUF .DW 0 ; ACTIVE DISK BUFFER

1269
Source/HBIOS/ide.asm.new

File diff suppressed because it is too large

273
Source/HBIOS/md.asm

@ -3,7 +3,32 @@
; MD DISK DRIVER (MEMORY DISK)
;==================================================================================================
;
MD_UNITCNT .EQU 2
; MD DEVICE CONFIGURATION
;
MD_DEVCNT .EQU 2 ; NUMBER OF MD DEVICES SUPPORTED
MD_CFGSIZ .EQU 6 ; SIZE OF CFG TBL ENTRIES
;
MD_DEV .EQU 0 ; OFFSET OF DEVICE NUMBER (BYTE)
MD_STAT .EQU 1 ; OFFSET OF STATUS (BYTE)
MD_LBA .EQU 2 ; OFFSET OF LBA (DWORD)
;
; DEVICE CONFIG TABLE (RAM DEVICE FIRST TO MAKE IT ALWAYS FIRST DRIVE)
;
MD_CFGTBL:
; DEVICE 1 (RAM)
.DB 1 ; DRIVER DEVICE NUMBER
.DB 0 ; DEVICE STATUS
.DW 0,0 ; CURRENT LBA
; DEVICE 0 (ROM)
.DB 0 ; DEVICE NUMBER
.DB 0 ; DEVICE STATUS
.DW 0,0 ; CURRENT LBA
;
#IF ($ - MD_CFGTBL) != (MD_DEVCNT * MD_CFGSIZ)
.ECHO "*** INVALID MD CONFIG TABLE ***\n"
#ENDIF
;
.DB $FF ; END MARKER
;
;
;
@ -18,102 +43,77 @@ MD_INIT:
CALL PRTDEC
PRTS("KB$")
;
; SETUP THE DISPATCH TABLE ENTRIES
;
LD B,$01 ; PHYSICAL UNIT=1 (RAM)
LD C,DIODEV_MD ; DEVICE TYPE
LD DE,MD_RAMDAT ; UNIT 1 DATA BLOB ADDRESS
CALL DIO_ADDENT ; ADD ENTRY
LD B,$00 ; PHYSICAL UNIT=0 (ROM)
LD C,DIODEV_MD ; DEVICE TYPE
LD DE,MD_ROMDAT ; UNIT 0 DATA BLOB ADDRESS
CALL DIO_ADDENT ; ADD ENTRY
;
XOR A ; INIT SUCCEEDED
RET ; RETURN
;
;
;
MD_ROMDAT: ; ROM UNIT DATA BLOB
.DB 0 ; UNIT NUMBER IS 0
;
MD_RAMDAT: ; RAM UNIT DATA BLOB
.DB 0 ; UNIT NUMBER IS 1
;
;
;
MD_DISPATCH:
; VERIFY AND SAVE THE TARGET DEVICE/UNIT LOCALLY IN DRIVER
LD A,C ; DEVICE/UNIT FROM C
AND $0F ; ISOLATE UNIT NUM
CP MD_UNITCNT
CALL NC,PANIC ; PANIC IF TOO HIGH
LD (MD_UNIT),A ; SAVE IT
;
; DISPATCH ACCORDING TO DISK SUB-FUNCTION
LD A,B ; GET REQUESTED FUNCTION
AND $0F ; ISOLATE SUB-FUNCTION
JP Z,MD_STATUS ; SUB-FUNC 0: STATUS
DEC A
JP Z,MD_RESET ; SUB-FUNC 1: RESET
DEC A
JP Z,MD_SEEK ; SUB-FUNC 2: SEEK
DEC A
JP Z,MD_READ ; SUB-FUNC 3: READ SECTORS
DEC A
JP Z,MD_WRITE ; SUB-FUNC 4: WRITE SECTORS
DEC A
JP Z,MD_VERIFY ; SUB-FUNC 5: VERIFY SECTORS
DEC A
JP Z,MD_FORMAT ; SUB-FUNC 6: FORMAT TRACK
DEC A
JP Z,MD_DEVICE ; SUB-FUNC 7: DEVICE REPORT
DEC A
JP Z,MD_MEDIA ; SUB-FUNC 8: MEDIA REPORT
DEC A
JP Z,MD_DEFMED ; SUB-FUNC 9: DEFINE MEDIA
DEC A
JP Z,MD_CAP ; SUB-FUNC 10: REPORT CAPACITY
DEC A
JP Z,MD_GEOM ; SUB-FUNC 11: REPORT GEOMETRY
; SETUP THE DIO TABLE ENTRIES
;
LD BC,MD_FNTBL
LD DE,MD_CFGTBL
PUSH BC
CALL DIO_ADDENT
POP BC
LD DE,MD_CFGTBL + MD_CFGSIZ
CALL DIO_ADDENT
;
XOR A ; INIT SUCCEEDED
RET ; RETURN
;
;
;
MD_FNTBL:
.DW MD_STATUS
.DW MD_RESET
.DW MD_SEEK
.DW MD_READ
.DW MD_WRITE
.DW MD_VERIFY
.DW MD_FORMAT
.DW MD_DEVICE
.DW MD_MEDIA
.DW MD_DEFMED
.DW MD_CAP
.DW MD_GEOM
#IF (($ - MD_FNTBL) != (DIO_FNCNT * 2))
.ECHO "*** INVALID MD FUNCTION TABLE ***\n"
#ENDIF
;
;
;
MD_VERIFY:
MD_FORMAT:
MD_DEFMED:
CALL PANIC ; INVALID SUB-FUNCTION
CALL PANIC ; INVALID SUB-FUNCTION
;
;
;
MD_STATUS:
XOR A ; ALWAYS OK
XOR A ; ALWAYS OK
RET
;
;
;
MD_RESET:
XOR A ; ALWAYS OK
XOR A ; ALWAYS OK
RET
;
;
;
MD_CAP:
LD A,C ; DEVICE/UNIT IS IN C
AND $0F ; ISOLATE UNIT NUM
JR Z,MD_CAP0 ; UNIT 0
DEC A ; TRY UNIT 1
JR Z,MD_CAP1 ; UNIT 1
CALL PANIC ; PANIC ON INVALID UNIT
LD A,(IY+MD_DEV) ; GET DEVICE NUMBER
OR A ; SET FLAGS
JR Z,MD_CAP0 ; UNIT 0
DEC A ; TRY UNIT 1
JR Z,MD_CAP1 ; UNIT 1
CALL PANIC ; PANIC ON INVALID UNIT
MD_CAP0:
LD A,(HCB + HCB_ROMBANKS) ; POINT TO ROM BANK COUNT
JR MD_CAP2
MD_CAP1:
LD A,(HCB + HCB_RAMBANKS) ; POINT TO RAM BANK COUNT
MD_CAP2:
SUB 4 ; SUBTRACT OUT RESERVED BANKS
LD H,A ; H := # BANKS
LD E,64 ; # 512 BYTE BLOCKS / BANK
CALL MULT8 ; HL := TOTAL # 512 BYTE BLOCKS
LD DE,0 ; NEVER EXCEEDS 64K, ZERO HIGH WORD
SUB 4 ; SUBTRACT OUT RESERVED BANKS
LD H,A ; H := # BANKS
LD E,64 ; # 512 BYTE BLOCKS / BANK
CALL MULT8 ; HL := TOTAL # 512 BYTE BLOCKS
LD DE,0 ; NEVER EXCEEDS 64K, ZERO HIGH WORD
XOR A
RET
;
@ -122,51 +122,53 @@ MD_CAP2:
MD_GEOM:
; RAM/ROM DISKS ALLOW CHS STYLE ACCESS BY EMULATING
; A DISK DEVICE WITH 1 HEAD AND 16 SECTORS / TRACK.
CALL MD_CAP ; HL := CAPACITY IN BLOCKS
LD D,1 | $80 ; HEADS / CYL := 1 BY DEFINITION, SET LBA CAPABILITY BIT
LD E,16 ; SECTORS / TRACK := 16 BY DEFINTION
LD B,4 ; PREPARE TO DIVIDE BY 16
CALL MD_CAP ; HL := CAPACITY IN BLOCKS
LD D,1 | $80 ; HEADS / CYL := 1 BY DEFINITION, SET LBA CAPABILITY BIT
LD E,16 ; SECTORS / TRACK := 16 BY DEFINTION
LD B,4 ; PREPARE TO DIVIDE BY 16
MD_GEOM1:
SRL H ; SHIFT H
RR L ; SHIFT L
DJNZ MD_GEOM1 ; DO 4 BITS TO DIVIDE BY 16
XOR A ; SIGNAL SUCCESS
RET ; DONE
SRL H ; SHIFT H
RR L ; SHIFT L
DJNZ MD_GEOM1 ; DO 4 BITS TO DIVIDE BY 16
XOR A ; SIGNAL SUCCESS
RET ; DONE
;
;
;
MD_DEVICE:
LD D,DIODEV_MD ; D := DEVICE TYPE
LD E,C ; E := PHYSICAL UNIT
LD A,C ; PHYSICAL UNIT TO A
OR A ; SET FLAGS
LD C,%00100000 ; ASSUME ROM DISK ATTRIBUTES
JR Z,MD_DEVICE1 ; IF ZERO, IT IS ROM DISK, DONE
LD C,%00101000 ; USE RAM DISK ATTRIBUTES
LD D,DIODEV_MD ; D := DEVICE TYPE
LD A,(IY+MD_DEV) ; GET DEVICE NUMBER
LD E,A ; PUT IN E FOR RETURN
OR A ; SET FLAGS
LD C,%00100000 ; ASSUME ROM DISK ATTRIBUTES
JR Z,MD_DEVICE1 ; IF ZERO, IT IS ROM DISK, DONE
LD C,%00101000 ; USE RAM DISK ATTRIBUTES
MD_DEVICE1:
XOR A ; SIGNAL SUCCESS
XOR A ; SIGNAL SUCCESS
RET
;
;
;
MD_MEDIA:
LD A,MID_MDROM ; SET MEDIA TYPE TO ROM
ADD A,C ; ADJUST BASED ON DEVICE
LD E,A ; RESULTANT MEDIA IT TO E
LD D,0 ; D:0=0 MEANS NO MEDIA CHANGE
XOR A ; SIGNAL SUCCESS
LD A,(IY+MD_DEV) ; GET DEVICE NUM
ADD A,MID_MDROM ; OFFSET BY MD ROM
LD E,A ; RESULTANT MEDIA ID TO E
LD D,0 ; D:0=0 MEANS NO MEDIA CHANGE
XOR A ; SIGNAL SUCCESS
RET
;
;
;
MD_SEEK:
BIT 7,D ; CHECK FOR LBA FLAG
CALL Z,HB_CHS2LBA ; CLEAR MEANS CHS, CONVERT TO LBA
RES 7,D ; CLEAR FLAG REGARDLESS (DOES NO HARM IF ALREADY LBA)
LD BC,HSTLBA ; POINT TO LBA STORAGE
CALL ST32 ; SAVE LBA ADDRESS
XOR A ; SIGNAL SUCCESS
RET ; AND RETURN
BIT 7,D ; CHECK FOR LBA FLAG
CALL Z,HB_CHS2LBA ; CLEAR MEANS CHS, CONVERT TO LBA
RES 7,D ; CLEAR FLAG REGARDLESS (DOES NO HARM IF ALREADY LBA)
LD (IY+MD_LBA+0),L ; SAVE NEW LBA
LD (IY+MD_LBA+1),H ; ...
LD (IY+MD_LBA+2),E ; ...
LD (IY+MD_LBA+3),D ; ...
XOR A ; SIGNAL SUCCESS
RET ; AND RETURN
;
;
@ -182,7 +184,7 @@ MD_READ:
MD_WRITE:
LD BC,MD_WRSEC ; GET ADR OF SECTOR WRITE FUNC
LD (MD_RWFNADR),BC ; SAVE IT AS PENDING IO FUNC
LD A,(MD_UNIT) ; GET UNIT NUMBER
LD A,(IY+MD_DEV) ; GET DEVICE NUMBER
OR A ; SET FLAGS TO TEST FOR ROM (UNIT 0)
JR NZ,MD_RW ; NOT ROM, SO OK TO WRITE, CONTINUE
LD E,0 ; UNIT IS READ ONLY, ZERO SECTORS WRITTEN
@ -203,12 +205,11 @@ MD_RW1:
LD HL,(MD_RWFNADR) ; GET PENDING IO FUNCTION ADDRESS
CALL JPHL ; ... AND CALL IT
JR NZ,MD_RW2 ; IF ERROR, SKIP INCREMENT
LD HL,HSTLBA ; POINT TO 32-BIT CURRENT LBA
PUSH HL ; SAVE POINTER
CALL LD32 ; LOAD 32-BIT LBA INTO DE:HL
CALL INC32 ; INCREMENT LBA FOR NEXT I/O
POP BC ; RECOVER LBA POINTER INTO BC
CALL ST32 ; AND SAVE IT
; INCREMENT LBA
LD A,MD_LBA ; LBA OFFSET IN CFG ENTRY
CALL LDHLIYA ; HL := IY + A, REG A TRASHED
CALL INC32HL ; INCREMENT THE VALUE
; INCREMENT DMA
LD HL,MD_DSKBUF+1 ; POINT TO MSB OF BUFFER ADR
INC (HL) ; BUMP DMA BY
INC (HL) ; ... 512 BYTES
@ -227,51 +228,51 @@ MD_RW3:
;
;
MD_RDSEC:
CALL MD_IOSETUP ; SETUP FOR MEMORY COPY
CALL MD_IOSETUP ; SETUP FOR MEMORY COPY
#IF (MDTRACE >= 2)
LD (MD_SRC),HL
LD (MD_DST),DE
LD (MD_LEN),BC
#ENDIF
PUSH BC
LD C,A ; SOURCE BANK
LD B,BID_BIOS ; DESTINATION BANK IS RAM BANK 1 (HBIOS)
LD C,A ; SOURCE BANK
LD B,BID_BIOS ; DESTINATION BANK IS RAM BANK 1 (HBIOS)
#IF (MDTRACE >= 2)
LD (MD_SRCBNK),BC
CALL MD_PRT
#ENDIF
LD A,C ; GET SOURCE BANK
LD (HB_SRCBNK),A ; SET IT
LD A,B ; GET DESTINATION BANK
LD (HB_DSTBNK),A ; SET IT
LD A,C ; GET SOURCE BANK
LD (HB_SRCBNK),A ; SET IT
LD A,B ; GET DESTINATION BANK
LD (HB_DSTBNK),A ; SET IT
POP BC
CALL HB_BNKCPY ; DO THE INTERBANK COPY
CALL HB_BNKCPY ; DO THE INTERBANK COPY
XOR A
RET
;
;
;
MD_WRSEC:
CALL MD_IOSETUP ; SETUP FOR MEMORY COPY
EX DE,HL ; SWAP SRC/DEST FOR WRITE
CALL MD_IOSETUP ; SETUP FOR MEMORY COPY
EX DE,HL ; SWAP SRC/DEST FOR WRITE
#IF (MDTRACE >= 2)
LD (MD_SRC),HL
LD (MD_DST),DE
LD (MD_LEN),BC
#ENDIF
PUSH BC
LD C,BID_BIOS ; SOURCE BANK IS RAM BANK 1 (HBIOS)
LD B,A ; DESTINATION BANK
LD C,BID_BIOS ; SOURCE BANK IS RAM BANK 1 (HBIOS)
LD B,A ; DESTINATION BANK
#IF (MDTRACE >= 2)
LD (MD_SRCBNK),BC
CALL MD_PRT
#ENDIF
LD A,C ; GET SOURCE BANK
LD (HB_SRCBNK),A ; SET IT
LD A,B ; GET DESTINATION BANK
LD (HB_DSTBNK),A ; SET IT
LD A,C ; GET SOURCE BANK
LD (HB_SRCBNK),A ; SET IT
LD A,B ; GET DESTINATION BANK
LD (HB_DSTBNK),A ; SET IT
POP BC
CALL HB_BNKCPY ; DO THE INTERBANK COPY
CALL HB_BNKCPY ; DO THE INTERBANK COPY
XOR A
RET
;
@ -289,8 +290,8 @@ MD_WRSEC:
; SO THE HIGH WORD (HSTLBAHI) IS IGNORED
;
; EACH RAM/ROM BANK IS 32K BY DEFINITION AND EACH SECTOR IS 512
; BYTES BY DEFINITION. SO, EACH RAM/ROM BANK CONTAINS 64 SECTORS
; (32,768 / 512 = 64). THEREFORE, YOU CAN THINK OF LBA AS
; BYTES BY DEFINITION. SO, EACH RAM/ROM BANK CONTAINS 64 SECTORS
; (32,768 / 512 = 64). THEREFORE, YOU CAN THINK OF LBA AS
; 00000BBB:BBOOOOOO IS WHERE THE 'B' BITS REPRESENT THE BANK NUMBER
; AND THE 'O' BITS REPRESENT THE SECTOR NUMBER WITHIN THE BANK.
;
@ -307,7 +308,8 @@ MD_WRSEC:
; DEALING WITH 512 BYTE BOUNDARIES.
;
MD_IOSETUP:
LD HL,(HSTLBALO) ; HL := LOW WORD OF LBA
LD L,(IY+MD_LBA+0) ; HL := LOW WORD OF LBA
LD H,(IY+MD_LBA+1) ; ...
; ALIGN BITS TO EXTRACT BANK NUMBER FROM H
SLA L ; LEFT SHIFT ONE BIT
RL H ; FULL WORD
@ -315,7 +317,7 @@ MD_IOSETUP:
RL H ; FULL WORD
LD C,H ; BANK NUMBER FROM H TO C
; GET BANK NUM TO A AND SET FLAG Z=ROM, NZ=RAM
LD A,(MD_UNIT) ; DEVICE/UNIT TO A
LD A,(IY+MD_DEV) ; DEVICE TO A
AND $01 ; ISOLATE LOW BIT, SET ZF
LD A,C ; BANK VALUE INTO A
PUSH AF ; SAVE IT FOR NOW
@ -348,9 +350,9 @@ MD_PRT:
CALL NEWLINE
LD DE,MDSTR_PREFIX
LD DE,MDSTR_PREFIX
CALL WRITESTR
CALL PC_SPACE
LD DE,MDSTR_SRC
CALL WRITESTR
@ -359,7 +361,7 @@ MD_PRT:
CALL PC_COLON
LD BC,(MD_SRC)
CALL PRTHEXWORD
CALL PC_SPACE
LD DE,MDSTR_DST
CALL WRITESTR
@ -368,13 +370,13 @@ MD_PRT:
CALL PC_COLON
LD BC,(MD_DST)
CALL PRTHEXWORD
CALL PC_SPACE
LD DE,MDSTR_LEN
CALL WRITESTR
LD BC,(MD_LEN)
CALL PRTHEXWORD
POP HL
POP DE
POP BC
@ -386,7 +388,6 @@ MD_PRT:
;
MD_RWFNADR .DW 0
;
MD_UNIT .DB 0
MD_DSKBUF .DW 0
;
MD_SRCBNK .DB 0

528
Source/HBIOS/ppide.asm

@ -31,7 +31,7 @@ PPIDE_IO_CTL .EQU PPIDE_IO_BASE + 2 ; IDE ADDRESS BUS AND CONTROL SIGNALS (8255
PPIDE_IO_PPI .EQU PPIDE_IO_BASE + 3 ; 8255 CONTROL PORT
;
; THE CONTROL PORT OF THE 8255 IS PROGRAMMED AS NEEDED TO READ OR WRITE
; DATA ON THE IDE BUS. PORT C OF THE 8255 IS ALWAYS IN OUTPUT MODE BECAUSE
; DATA ON THE IDE BUS. PORT C OF THE 8255 IS ALWAYS IN OUTPUT MODE BECAUSE
; IT IS DRIVING THE ADDRESS BUS AND CONTROL SIGNALS. PORTS A & B WILL BE
; PLACED IN READ OR WRITE MODE DEPENDING ON THE DIRECTION OF THE DATA BUS.
;
@ -39,7 +39,7 @@ PPIDE_DIR_READ .EQU %10010010 ; IDE BUS DATA INPUT MODE
PPIDE_DIR_WRITE .EQU %10000000 ; IDE BUS DATA OUTPUT MODE
;
; PORT C OF THE 8255 IS USED TO DRIVE THE IDE INTERFACE ADDRESS BUS
; AND VARIOUS CONTROL SIGNALS. THE CONSTANTS BELOW REFLECT THESE
; AND VARIOUS CONTROL SIGNALS. THE CONSTANTS BELOW REFLECT THESE
; ASSIGNMENTS.
;
PPIDE_CTL_DA0 .EQU %00000001 ; DRIVE ADDRESS BUS - BIT 0 (DA0)
@ -54,7 +54,7 @@ PPIDE_CTL_RESET .EQU %10000000 ; DRIVE RESET (ACTIVE LOW, INVERTED)
; +-----------------------------------------------------------------------+
; | CONTROL BLOCK REGISTERS (CS3FX) |
; +-----------------------+-------+-------+-------------------------------+
; | REGISTER | PORT | DIR | DESCRIPTION |
; | REGISTER | PORT | DIR | DESCRIPTION |
; +-----------------------+-------+-------+-------------------------------+
; | PPIDE_REG_ALTSTAT | 0x06 | R | ALTERNATE STATUS REGISTER |
; | PPIDE_REG_CTRL | 0x06 | W | DEVICE CONTROL REGISTER |
@ -64,7 +64,7 @@ PPIDE_CTL_RESET .EQU %10000000 ; DRIVE RESET (ACTIVE LOW, INVERTED)
; +-----------------------+-------+-------+-------------------------------+
; | COMMAND BLOCK REGISTERS (CS1FX) |
; +-----------------------+-------+-------+-------------------------------+
; | REGISTER | PORT | DIR | DESCRIPTION |
; | REGISTER | PORT | DIR | DESCRIPTION |
; +-----------------------+-------+-------+-------------------------------+
; | PPIDE_REG_DATA | 0x00 | R/W | DATA INPUT/OUTPUT |
; | PPIDE_REG_ERR | 0x01 | R | ERROR REGISTER |
@ -74,7 +74,7 @@ PPIDE_CTL_RESET .EQU %10000000 ; DRIVE RESET (ACTIVE LOW, INVERTED)
; | PPIDE_REG_CYLLO | 0x04 | R/W | CYLINDER NUM REGISTER (LSB) |
; | PPIDE_REG_CYLHI | 0x05 | R/W | CYLINDER NUM REGISTER (MSB) |
; | PPIDE_REG_DRVHD | 0x06 | R/W | DRIVE/HEAD REGISTER |
; | PPIDE_REG_LBA0* | 0x03 | R/W | LBA BYTE 0 (BITS 0-7) |
; | PPIDE_REG_LBA0* | 0x03 | R/W | LBA BYTE 0 (BITS 0-7) |
; | PPIDE_REG_LBA1* | 0x04 | R/W | LBA BYTE 1 (BITS 8-15) |
; | PPIDE_REG_LBA2* | 0x05 | R/W | LBA BYTE 2 (BITS 16-23) |
; | PPIDE_REG_LBA3* | 0x06 | R/W | LBA BYTE 3 (BITS 24-27) |
@ -85,9 +85,9 @@ PPIDE_CTL_RESET .EQU %10000000 ; DRIVE RESET (ACTIVE LOW, INVERTED)
;
; === STATUS REGISTER ===
;
; 7 6 5 4 3 2 1 0
; 7 6 5 4 3 2 1 0
; +-------+-------+-------+-------+-------+-------+-------+-------+
; | BSY | DRDY | DWF | DSC | DRQ | CORR | IDX | ERR |
; | BSY | DRDY | DWF | DSC | DRQ | CORR | IDX | ERR |
; +-------+-------+-------+-------+-------+-------+-------+-------+
;
; BSY: BUSY
@ -101,9 +101,9 @@ PPIDE_CTL_RESET .EQU %10000000 ; DRIVE RESET (ACTIVE LOW, INVERTED)
;
; === ERROR REGISTER ===
;
; 7 6 5 4 3 2 1 0
; 7 6 5 4 3 2 1 0
; +-------+-------+-------+-------+-------+-------+-------+-------+
; | BBK | UNC | MC | IDNF | MCR | ABRT | TK0NF | AMNF |
; | BBK | UNC | MC | IDNF | MCR | ABRT | TK0NF | AMNF |
; +-------+-------+-------+-------+-------+-------+-------+-------+
; (VALID WHEN ERR BIT IS SET IN STATUS REGISTER)
;
@ -118,9 +118,9 @@ PPIDE_CTL_RESET .EQU %10000000 ; DRIVE RESET (ACTIVE LOW, INVERTED)
;
; === DRIVE/HEAD / LBA3 REGISTER ===
;
; 7 6 5 4 3 2 1 0
; 7 6 5 4 3 2 1 0
; +-------+-------+-------+-------+-------+-------+-------+-------+
; | 1 | L | 1 | DRV | HS3 | HS2 | HS1 | HS0 |
; | 1 | L | 1 | DRV | HS3 | HS2 | HS1 | HS0 |
; +-------+-------+-------+-------+-------+-------+-------+-------+
;
; L: 0 = CHS ADDRESSING, 1 = LBA ADDRESSING
@ -129,9 +129,9 @@ PPIDE_CTL_RESET .EQU %10000000 ; DRIVE RESET (ACTIVE LOW, INVERTED)
;
; === DEVICE CONTROL REGISTER ===
;
; 7 6 5 4 3 2 1 0
; 7 6 5 4 3 2 1 0
; +-------+-------+-------+-------+-------+-------+-------+-------+
; | X | X | X | X | 1 | SRST | ~IEN | 0 |
; | X | X | X | X | 1 | SRST | ~IEN | 0 |
; +-------+-------+-------+-------+-------+-------+-------+-------+
;
; SRST: SOFTWARE RESET
@ -140,22 +140,22 @@ PPIDE_CTL_RESET .EQU %10000000 ; DRIVE RESET (ACTIVE LOW, INVERTED)
; CONTROL VALUES TO USE WHEN ACCESSING THE VARIOUS IDE DEVICE REGISTERS
;
PPIDE_REG_DATA .EQU PPIDE_CTL_CS1FX | $00 ; DATA INPUT/OUTPUT (R/W)
PPIDE_REG_ERR .EQU PPIDE_CTL_CS1FX | $01 ; ERROR REGISTER (R)
PPIDE_REG_FEAT .EQU PPIDE_CTL_CS1FX | $01 ; FEATURES REGISTER (W)
PPIDE_REG_COUNT .EQU PPIDE_CTL_CS1FX | $02 ; SECTOR COUNT REGISTER (R/W)
PPIDE_REG_SECT .EQU PPIDE_CTL_CS1FX | $03 ; SECTOR NUMBER REGISTER (R/W)
PPIDE_REG_CYLLO .EQU PPIDE_CTL_CS1FX | $04 ; CYLINDER NUM REGISTER (LSB) (R/W)
PPIDE_REG_CYLHI .EQU PPIDE_CTL_CS1FX | $05 ; CYLINDER NUM REGISTER (MSB) (R/W)
PPIDE_REG_DRVHD .EQU PPIDE_CTL_CS1FX | $06 ; DRIVE/HEAD REGISTER (R/W)
PPIDE_REG_ERR .EQU PPIDE_CTL_CS1FX | $01 ; ERROR REGISTER (R)
PPIDE_REG_FEAT .EQU PPIDE_CTL_CS1FX | $01 ; FEATURES REGISTER (W)
PPIDE_REG_COUNT .EQU PPIDE_CTL_CS1FX | $02 ; SECTOR COUNT REGISTER (R/W)
PPIDE_REG_SECT .EQU PPIDE_CTL_CS1FX | $03 ; SECTOR NUMBER REGISTER (R/W)
PPIDE_REG_CYLLO .EQU PPIDE_CTL_CS1FX | $04 ; CYLINDER NUM REGISTER (LSB) (R/W)
PPIDE_REG_CYLHI .EQU PPIDE_CTL_CS1FX | $05 ; CYLINDER NUM REGISTER (MSB) (R/W)
PPIDE_REG_DRVHD .EQU PPIDE_CTL_CS1FX | $06 ; DRIVE/HEAD REGISTER (R/W)
PPIDE_REG_LBA0 .EQU PPIDE_CTL_CS1FX | $03 ; LBA BYTE 0 (BITS 0-7) (R/W)
PPIDE_REG_LBA1 .EQU PPIDE_CTL_CS1FX | $04 ; LBA BYTE 1 (BITS 8-15) (R/W)
PPIDE_REG_LBA2 .EQU PPIDE_CTL_CS1FX | $05 ; LBA BYTE 2 (BITS 16-23) (R/W)
PPIDE_REG_LBA3 .EQU PPIDE_CTL_CS1FX | $06 ; LBA BYTE 3 (BITS 24-27) (R/W)
PPIDE_REG_STAT .EQU PPIDE_CTL_CS1FX | $07 ; STATUS REGISTER (R)
PPIDE_REG_CMD .EQU PPIDE_CTL_CS1FX | $07 ; COMMAND REGISTER (EXECUTE) (W)
PPIDE_REG_ALTSTAT .EQU PPIDE_CTL_CS3FX | $06 ; ALTERNATE STATUS REGISTER (R)
PPIDE_REG_CTRL .EQU PPIDE_CTL_CS3FX | $06 ; DEVICE CONTROL REGISTER (W)
PPIDE_REG_DRVADR .EQU PPIDE_CTL_CS3FX | $07 ; DRIVE ADDRESS REGISTER (R)
PPIDE_REG_STAT .EQU PPIDE_CTL_CS1FX | $07 ; STATUS REGISTER (R)
PPIDE_REG_CMD .EQU PPIDE_CTL_CS1FX | $07 ; COMMAND REGISTER (EXECUTE) (W)
PPIDE_REG_ALTSTAT .EQU PPIDE_CTL_CS3FX | $06 ; ALTERNATE STATUS REGISTER (R)
PPIDE_REG_CTRL .EQU PPIDE_CTL_CS3FX | $06 ; DEVICE CONTROL REGISTER (W)
PPIDE_REG_DRVADR .EQU PPIDE_CTL_CS3FX | $07 ; DRIVE ADDRESS REGISTER (R)
;
#IF (PPIDETRACE >= 3)
#DEFINE DCALL CALL
@ -169,7 +169,7 @@ PPIDE_REG_DRVADR .EQU PPIDE_CTL_CS3FX | $07 ; DRIVE ADDRESS REGISTER (R)
; PPIDE2: SECONDARY MASTER
; PPIDE3: SECONDARY SLAVE
;
PPIDE_UNITCNT .EQU 2 ; ASSUME ONLY PRIMARY INTERFACE
PPIDE_DEVCNT .EQU 2 ; ASSUME ONLY PRIMARY INTERFACE
;
; COMMAND BYTES
;
@ -207,31 +207,53 @@ PPIDE_DRVSEL:
PPIDE_DRVMASTER .DB %11100000 ; LBA, MASTER DEVICE
PPIDE_DRVSLAVE .DB %11110000 ; LBA, SLAVE DEVICE
;
; PER UNIT DATA OFFSETS (CAREFUL NOT TO EXCEED PER UNIT SPACE IN PPIDE_UNITDATA)
; SEE PPIDE_UNITDATA IN DATA STORAGE BELOW
; PPIDE DEVICE CONFIGURATION
;
PPIDE_CFGSIZ .EQU 12 ; SIZE OF CFG TBL ENTRIES
;
; PER DEVICE DATA OFFSETS
;
PPIDE_DEV .EQU 0 ; OFFSET OF DEVICE NUMBER (BYTE)
PPIDE_STAT .EQU 1 ; LAST STATUS (BYTE)
PPIDE_TYPE .EQU 2 ; DEVICE TYPE (BYTE)
PPIDE_FLAGS .EQU 3 ; FLAG BITS BIT 0=CF, 1=LBA (BYTE)
PPIDE_MEDCAP .EQU 4 ; MEDIA CAPACITY (DWORD)
PPIDE_LBA .EQU 8 ; OFFSET OF LBA (DWORD)
;
PPIDE_CFGTBL:
; DEVICE 0, PRIMARY MASTER
.DB 0 ; DRIVER DEVICE NUMBER
.DB 0 ; DEVICE STATUS
.DB 0 ; DEVICE TYPE
.DB 0 ; FLAGS BYTE
.DW 0,0 ; DEVICE CAPACITY
.DW 0,0 ; CURRENT LBA
; DEVICE 1, PRIMARY SLAVE
.DB 1 ; DRIVER DEVICE NUMBER
.DB 0 ; DEVICE STATUS
.DB 0 ; DEVICE TYPE
.DB 0 ; FLAGS BYTE
.DW 0,0 ; DEVICE CAPACITY
.DW 0,0 ; CURRENT LBA
;
#IF ($ - PPIDE_CFGTBL) != (PPIDE_DEVCNT * PPIDE_CFGSIZ)
.ECHO "*** INVALID PPIDE CONFIG TABLE ***\n"
#ENDIF
;
PPIDE_STAT .EQU 0 ; LAST STATUS (1 BYTE)
PPIDE_TYPE .EQU 1 ; DEVICE TYPE (1 BYTE)
PPIDE_CAPACITY .EQU 2 ; DEVICE CAPACITY (1 DWORD/4 BYTES)
PPIDE_CFFLAG .EQU 6 ; CF FLAG (1 BYTE), NON-ZERO=CF
.DB $FF ; END MARKER
;
; THE IDE_WAITXXX FUNCTIONS ARE BUILT TO TIMEOUT AS NEEDED SO DRIVER WILL
; NOT HANG IF DEVICE IS UNRESPONSIVE. DIFFERENT TIMEOUTS ARE USED DEPENDING
; ON THE SITUATION. GENERALLY, THE FAST TIMEOUT IS USED TO PROBE FOR DEVICES
; USING FUNCTIONS THAT PERFORM NO I/O. OTHERWISE THE NORMAL TIMEOUT IS USED.
; USING FUNCTIONS THAT PERFORM NO I/O. OTHERWISE THE NORMAL TIMEOUT IS USED.
; IDE SPEC ALLOWS FOR UP TO 30 SECS MAX TO RESPOND. IN PRACTICE, THIS IS WAY
; TOO LONG, BUT IF YOU ARE USING A VERY OLD DEVICE, THESE TIMEOUTS MAY NEED TO
; BE ADJUSTED. NOTE THAT THESE ARE BYTE VALUES, SO YOU CANNOT EXCEED 255.
; BE ADJUSTED. NOTE THAT THESE ARE BYTE VALUES, SO YOU CANNOT EXCEED 255.
; THE TIMEOUTS ARE IN UNITS OF .05 SECONDS.
;
PPIDE_TONORM .EQU 200 ; NORMAL TIMEOUT IS 10 SECS
PPIDE_TOFAST .EQU 10 ; FAST TIMEOUT IS 0.5 SECS
;
; MACRO TO RETURN POINTER TO FIELD WITHIN UNIT DATA
;
#DEFINE PPIDE_DPTR(FIELD) CALL PPIDE_DPTRIMP \ .DB FIELD
;
;=============================================================================
; INITIALIZATION ENTRY POINT
;=============================================================================
@ -255,10 +277,6 @@ PPIDE_INIT:
#IF (PPIDE8BIT)
PRTS(" 8BIT$")
#ENDIF
PRTS(" UNITS=$")
LD A,PPIDE_UNITCNT
CALL PRTDECB
;
CALL PPIDE_DETECT ; CHECK FOR HARDWARE
JR Z,PPIDE_INIT00 ; CONTINUE IF PRESENT
;
@ -268,45 +286,46 @@ PPIDE_INIT:
RET
;
PPIDE_INIT00:
PRTS(" DEVICES=$")
LD A,PPIDE_DEVCNT
CALL PRTDECB
;
; SETUP THE DISPATCH TABLE ENTRIES
;
LD B,PPIDE_UNITCNT ; LOOP CONTROL
LD C,0 ; PHYSICAL UNIT INDEX
LD B,PPIDE_DEVCNT ; LOOP CONTROL
LD IY,PPIDE_CFGTBL ; START OF CFG TABLE
PPIDE_INIT0:
PUSH BC ; SAVE LOOP CONTROL
LD B,C ; PHYSICAL UNIT
LD C,DIODEV_PPIDE ; DEVICE TYPE
LD DE,0 ; UNIT DATA BLOB ADDRESS
CALL DIO_ADDENT ; ADD ENTRY, BC IS NOT DESTROYED
POP BC ; RESTORE LOOP CONTROL
INC C ; NEXT PHYSICAL UNIT
DJNZ PPIDE_INIT0 ; LOOP UNTIL DONE
PUSH BC ; SAVE LOOP CONTROL
LD BC,PPIDE_FNTBL ; BC := FUNC TABLE ADR
PUSH IY ; CFG ENTRY POINTER
POP DE ; COPY TO DE
CALL DIO_ADDENT ; ADD ENTRY TO GLOBAL DISK DEV TABLE
LD BC,PPIDE_CFGSIZ ; SIZE OF CFG ENTRY
ADD IY,BC ; BUMP IY TO NEXT ENTRY
POP BC ; RESTORE BC
DJNZ PPIDE_INIT0 ; LOOP AS NEEDED
;
; INITIALIZE THE PPIDE INTERFACE NOW
CALL PPIDE_RESET ; DO HARDWARE SETUP/INIT
RET NZ ; ABORT IF RESET FAILS
;
; DEVICE DISPLAY LOOP
LD B,PPIDE_UNITCNT ; LOOP ONCE PER UNIT
LD C,0 ; C IS UNIT INDEX
LD B,PPIDE_DEVCNT ; LOOP ONCE PER DEVICE
LD IY,PPIDE_CFGTBL ; START OF CFG TABLE
PPIDE_INIT1:
LD A,C ; UNIT NUM TO ACCUM
PUSH BC ; SAVE LOOP CONTROL
CALL PPIDE_INIT2 ; DISPLAY UNIT INFO
LD BC,PPIDE_CFGSIZ ; SIZE OF CFG ENTRY
ADD IY,BC ; BUMP IY TO NEXT ENTRY
POP BC ; RESTORE LOOP CONTROL
INC C ; INCREMENT UNIT INDEX
DJNZ PPIDE_INIT1 ; LOOP UNTIL DONE
RET ; DONE
;
PPIDE_INIT2:
LD (PPIDE_UNIT),A ; SET CURRENT UNIT
;
; CHECK FOR BAD STATUS
PPIDE_DPTR(PPIDE_STAT) ; GET STATUS ADR IN HL, AF TRASHED
LD A,(HL)
OR A
JP NZ,PPIDE_PRTSTAT
LD A,(IY+PPIDE_STAT) ; GET STATUS
OR A ; SET FLAGS
JP NZ,PPIDE_PRTSTAT ; EXIT VIA PRINT STATUS
;
CALL PPIDE_PRTPREFIX ; PRINT DEVICE PREFIX
;
@ -316,18 +335,15 @@ PPIDE_INIT2:
;
; PRINT LBA/NOLBA
CALL PC_SPACE ; FORMATTING
LD HL,HB_WRKBUF ; POINT TO BUFFER START
LD DE,98+1 ; OFFSET OF BYTE CONTAINING LBA FLAG
ADD HL,DE ; POINT TO FINAL BUFFER ADDRESS
LD A,(HL) ; GET THE BYTE
BIT 1,A ; CHECK THE LBA BIT
BIT 1,(IY+PPIDE_FLAGS) ; TEST LBA FLAG
LD DE,PPIDE_STR_NO ; POINT TO "NO" STRING
CALL Z,WRITESTR ; PRINT "NO" BEFORE "LBA" IF LBA NOT SUPPORTED
PRTS("LBA$") ; PRINT "LBA" REGARDLESS
;
; PRINT STORAGE CAPACITY (BLOCK COUNT)
PRTS(" BLOCKS=0x$") ; PRINT FIELD LABEL
PPIDE_DPTR(PPIDE_CAPACITY) ; SET HL TO ADR OF DEVICE CAPACITY
LD A,PPIDE_MEDCAP ; OFFSET TO CAPACITY FIELD
CALL LDHLIYA ; HL := IY + A, REG A TRASHED
CALL LD32 ; GET THE CAPACITY VALUE
CALL PRTHEX32 ; PRINT HEX VALUE
;
@ -352,7 +368,7 @@ PPIDE_DETECT:
; TEST FOR PPI EXISTENCE
; WE SETUP THE PPI TO WRITE, THEN WRITE A VALUE OF ZERO
; TO PORT A (DATALO), THEN READ IT BACK. IF THE PPI IS THERE
; THEN THE BUS HOLD CIRCUITRY WILL READ BACK THE ZERO. SINCE
; THEN THE BUS HOLD CIRCUITRY WILL READ BACK THE ZERO. SINCE
; WE ARE IN WRITE MODE, AN IDE CONTROLLER WILL NOT BE ABLE TO
; INTERFERE WITH THE VALUE BEING READ.
LD A,PPIDE_DIR_WRITE ; SET DATA BUS DIRECTION TO WRITE
@ -367,48 +383,30 @@ PPIDE_DETECT:
RET ; AND RETURN
;
;=============================================================================
; FUNCTION DISPATCH ENTRY POINT
; DRIVER FUNCTION TABLE
;=============================================================================
;
PPIDE_DISPATCH:
; VERIFY AND SAVE THE TARGET DEVICE/UNIT LOCALLY IN DRIVER
LD A,C ; DEVICE/UNIT FROM C
AND $0F ; ISOLATE UNIT NUM
CP PPIDE_UNITCNT
CALL NC,PANIC ; PANIC IF TOO HIGH
LD (PPIDE_UNIT),A ; SAVE IT
;
; DISPATCH ACCORDING TO DISK SUB-FUNCTION
LD A,B ; GET REQUESTED FUNCTION
AND $0F ; ISOLATE SUB-FUNCTION
JP Z,PPIDE_STATUS ; SUB-FUNC 0: STATUS
DEC A
JP Z,PPIDE_RESET ; SUB-FUNC 1: RESET
DEC A
JP Z,PPIDE_SEEK ; SUB-FUNC 2: SEEK
DEC A
JP Z,PPIDE_READ ; SUB-FUNC 3: READ SECTORS
DEC A
JP Z,PPIDE_WRITE ; SUB-FUNC 4: WRITE SECTORS
DEC A
JP Z,PPIDE_VERIFY ; SUB-FUNC 5: VERIFY SECTORS
DEC A
JP Z,PPIDE_FORMAT ; SUB-FUNC 6: FORMAT TRACK
DEC A
JP Z,PPIDE_DEVICE ; SUB-FUNC 7: DEVICE REPORT
DEC A
JP Z,PPIDE_MEDIA ; SUB-FUNC 8: MEDIA REPORT
DEC A
JP Z,PPIDE_DEFMED ; SUB-FUNC 9: DEFINE MEDIA
DEC A
JP Z,PPIDE_CAP ; SUB-FUNC 10: REPORT CAPACITY
DEC A
JP Z,PPIDE_GEOM ; SUB-FUNC 11: REPORT GEOMETRY
PPIDE_FNTBL:
.DW PPIDE_STATUS
.DW PPIDE_RESET
.DW PPIDE_SEEK
.DW PPIDE_READ
.DW PPIDE_WRITE
.DW PPIDE_VERIFY
.DW PPIDE_FORMAT
.DW PPIDE_DEVICE
.DW PPIDE_MEDIA
.DW PPIDE_DEFMED
.DW PPIDE_CAP
.DW PPIDE_GEOM
#IF (($ - PPIDE_FNTBL) != (DIO_FNCNT * 2))
.ECHO "*** INVALID PPIDE FUNCTION TABLE ***\n"
#ENDIF
;
PPIDE_VERIFY:
PPIDE_FORMAT:
PPIDE_DEFMED:
CALL PANIC ; INVALID SUB-FUNCTION
CALL PANIC ; NOT IMPLEMENTED
;
;
;
@ -446,14 +444,12 @@ PPIDE_IO1:
PUSH BC ; SAVE COUNTERS
LD HL,(PPIDE_IOFNADR) ; GET PENDING IO FUNCTION ADDRESS
CALL JPHL ; ... AND CALL IT
CALL PPIDE_RDSEC ; READ NEXT SECTOR
JR NZ,PPIDE_IO2 ; IF ERROR, SKIP INCREMENT
LD HL,HSTLBA ; POINT TO 32-BIT CURRENT LBA
PUSH HL ; SAVE POINTER
CALL LD32 ; LOAD 32-BIT LBA INTO DE:HL
CALL INC32 ; INCREMENT LBA FOR NEXT I/O
POP BC ; RECOVER LBA POINTER INTO BC
CALL ST32 ; AND SAVE IT
; INCREMENT LBA
LD A,PPIDE_LBA ; LBA OFFSET
CALL LDHLIYA ; HL := IY + A, REG A TRASHED
CALL INC32HL ; INCREMENT THE VALUE
; INCREMENT DMA
LD HL,PPIDE_DSKBUF+1 ; POINT TO MSB OF BUFFER ADR
INC (HL) ; BUMP DMA BY
INC (HL) ; ... 512 BYTES
@ -473,43 +469,20 @@ PPIDE_IO3:
;
PPIDE_STATUS:
; RETURN UNIT STATUS
PPIDE_DPTR(PPIDE_STAT) ; HL := ADR OF STATUS, AF TRASHED
LD A,(HL) ; GET STATUS OF SELECTED UNIT
LD A,(IY+PPIDE_STAT) ; GET STATUS OF SELECTED DEVICE
OR A ; SET FLAGS
RET ; AND RETURN
;
; PPIDE_SENSE
;
PPIDE_SENSE:
; THE ONLY WAY TO RESET AN IDE DEVICE IS TO RESET
; THE ENTIRE INTERFACE. SO, TO HANDLE POSSIBLE HOT
; SWAP WE DO THAT, THEN RESELECT THE DESIRED UNIT AND
; CONTINUE.
CALL PPIDE_RESET ; RESET ALL DEVICES ON BUS
;
PPIDE_DPTR(PPIDE_STAT) ; POINT TO UNIT STATUS
LD A,(HL) ; GET STATUS
OR A ; SET FLAGS
#IF (PPIDETRACE == 1)
CALL PPIDE_PRTERR ; PRINT ANY ERRORS
#ENDIF
LD E,MID_HD ; ASSUME WE ARE OK
RET Z ; RETURN IF GOOD INIT
LD E,MID_NONE ; SIGNAL NO MEDA
RET ; AND RETURN
;
;
;
PPIDE_DEVICE:
LD D,DIODEV_PPIDE ; D := DEVICE TYPE
LD E,C ; E := PHYSICAL UNIT
PPIDE_DPTR(PPIDE_CFFLAG) ; POINT TO CF FLAG
LD A,(HL) ; GET FLAG
OR A ; SET ACCUM FLAGS
LD E,(IY+PPIDE_DEV) ; E := PHYSICAL DEVICE NUMBER
BIT 0,(IY+PPIDE_FLAGS) ; TEST CF BIT IN FLAGS
LD C,%00000000 ; ASSUME NON-REMOVABLE HARD DISK
JR Z,PPIDE_DEVICE1 ; IF Z, WE ARE DONE
LD C,%01001000 ; OTHERWISE REMOVABLE COMPACT FLASH
PPIDE_DEVICE1:
PPIDE_DEVICE1:
XOR A ; SIGNAL SUCCESS
RET
;
@ -521,10 +494,9 @@ PPIDE_MEDIA:
JR Z,PPIDE_MEDIA2 ; JUST REPORT CURRENT STATUS AND MEDIA
;
; GET CURRENT STATUS
PPIDE_DPTR(PPIDE_STAT) ; POINT TO UNIT STATUS
LD A,(HL) ; GET STATUS
LD A,(IY+PPIDE_STAT) ; GET STATUS
OR A ; SET FLAGS
JR NZ,PPIDE_MEDIA1 ; ERROR ACTIVE, TO RIGHT TO RESET
JR NZ,PPIDE_MEDIA1 ; ERROR ACTIVE, GO RIGHT TO RESET
;
; USE IDENTIFY COMMAND TO CHECK DEVICE
LD HL,PPIDE_TIMEOUT ; POINT TO TIMEOUT
@ -539,8 +511,7 @@ PPIDE_MEDIA1:
CALL PPIDE_RESET ; RESET IDE INTERFACE
;
PPIDE_MEDIA2:
PPIDE_DPTR(PPIDE_STAT) ; POINT TO UNIT STATUS
LD A,(HL) ; GET STATUS
LD A,(IY+PPIDE_STAT) ; GET STATUS
OR A ; SET FLAGS
LD D,0 ; NO MEDIA CHANGE DETECTED
LD E,MID_HD ; ASSUME WE ARE OK
@ -551,22 +522,24 @@ PPIDE_MEDIA2:
;
;
PPIDE_SEEK:
BIT 7,D ; CHECK FOR LBA FLAG
CALL Z,HB_CHS2LBA ; CLEAR MEANS CHS, CONVERT TO LBA
RES 7,D ; CLEAR FLAG REGARDLESS (DOES NO HARM IF ALREADY LBA)
LD BC,HSTLBA ; POINT TO LBA STORAGE
CALL ST32 ; SAVE LBA ADDRESS
XOR A ; SIGNAL SUCCESS
RET ; AND RETURN
BIT 7,D ; CHECK FOR LBA FLAG
CALL Z,HB_CHS2LBA ; CLEAR MEANS CHS, CONVERT TO LBA
RES 7,D ; CLEAR FLAG REGARDLESS (DOES NO HARM IF ALREADY LBA)
LD (IY+PPIDE_LBA+0),L ; SAVE NEW LBA
LD (IY+PPIDE_LBA+1),H ; ...
LD (IY+PPIDE_LBA+2),E ; ...
LD (IY+PPIDE_LBA+3),D ; ...
XOR A ; SIGNAL SUCCESS
RET ; AND RETURN
;
;
;
PPIDE_CAP:
PPIDE_DPTR(PPIDE_STAT) ; POINT TO UNIT STATUS
LD A,(HL) ; GET STATUS
LD A,(IY+PPIDE_STAT) ; GET STATUS
PUSH AF ; SAVE IT
PPIDE_DPTR(PPIDE_CAPACITY) ; POINT HL TO CAPACITY OF CUR UNIT
CALL LD32 ; GET THE CURRENT CAPACITY DO DE:HL
LD A,PPIDE_MEDCAP ; OFFSET TO CAPACITY FIELD
CALL LDHLIYA ; HL := IY + A, REG A TRASHED
CALL LD32 ; GET THE CURRENT CAPACITY INTO DE:HL
LD BC,512 ; 512 BYTES PER BLOCK
POP AF ; RECOVER STATUS
OR A ; SET FLAGS
@ -635,8 +608,6 @@ PPIDE_IDENTIFY:
;
;
PPIDE_RDSEC:
CALL PPIDE_CHKDEVICE
RET NZ
;
#IF (PPIDETRACE >= 3)
CALL PPIDE_PRTPREFIX
@ -659,8 +630,6 @@ PPIDE_RDSEC:
;
;
PPIDE_WRSEC:
CALL PPIDE_CHKDEVICE
RET NZ
;
#IF (PPIDETRACE >= 3)
CALL PPIDE_PRTPREFIX
@ -685,19 +654,19 @@ PPIDE_SETADDR:
; SEND 3 LOWEST BYTES OF LBA IN REVERSE ORDER
; IDE_IO_LBA3 HAS ALREADY BEEN SET
; HSTLBA2-0 --> IDE_IO_LBA2-0
LD A,(HSTLBA + 2)
LD A,(IY+PPIDE_LBA+2)
DCALL PC_SPACE
DCALL PRTHEXBYTE
CALL PPIDE_OUT
.DB PPIDE_REG_LBA2
LD A,(HSTLBA + 1)
LD A,(IY+PPIDE_LBA+1)
DCALL PC_SPACE
DCALL PRTHEXBYTE
CALL PPIDE_OUT
.DB PPIDE_REG_LBA1
LD A,(HSTLBA + 0)
LD A,(IY+PPIDE_LBA+0)
DCALL PC_SPACE
DCALL PRTHEXBYTE
CALL PPIDE_OUT
@ -763,7 +732,6 @@ PPIDE_GETBUF:
LD D,A ; D := READ ASSERTED
;
; LOOP SETUP
;LD HL,(PPIDE_DSKBUF) ; LOCATION OF BUFFER
LD B,0 ; 256 ITERATIONS
LD C,PPIDE_IO_DATALO ; SETUP C WITH IO PORT (LSB)
;
@ -822,7 +790,6 @@ PPIDE_PUTBUF:
LD D,A ; D := WRITE ASSERTED
;
; LOOP SETUP
;LD HL,(PPIDE_DSKBUF) ; LOCATION OF BUFFER
LD B,0 ; 256 ITERATIONS
LD C,PPIDE_IO_DATALO ; SETUP C WITH IO PORT (LSB)
;
@ -914,28 +881,26 @@ PPIDE_RESET:
LD DE,150000/16 ; ~???MS
CALL VDELAY
;
; CLEAR OUT ALL DATA (FOR ALL UNITS)
LD HL,PPIDE_UDATA
LD BC,PPIDE_UDLEN
XOR A
CALL FILL
;; CLEAR OUT ALL DATA (FOR ALL UNITS)
;LD HL,PPIDE_UDATA
;LD BC,PPIDE_UDLEN
;XOR A
;CALL FILL
;
LD A,(PPIDE_UNIT) ; GET THE CURRENT UNIT SELECTION
PUSH AF ; AND SAVE IT
PUSH IY ; SAVE CURRENT DEVICE CFG PTR
;
; PROBE / INITIALIZE ALL UNITS
LD B,PPIDE_UNITCNT ; NUMBER OF UNITS TO TRY
LD C,0 ; UNIT INDEX FOR LOOP
LD B,PPIDE_DEVCNT ; NUMBER OF UNITS TO TRY
LD IY,PPIDE_CFGTBL ; START OF CFG TABLE
PPIDE_RESET1:
LD A,C ; UNIT NUMBER TO A
PUSH BC
PUSH BC ; SAVE LOOP CONTROL
CALL PPIDE_INITUNIT ; PROBE/INIT UNIT
POP BC
INC C ; NEXT UNIT
LD BC,PPIDE_CFGSIZ ; SIZE OF CFG ENTRY
ADD IY,BC ; BUMP IY TO NEXT ENTRY
POP BC ; RESTORE BC
DJNZ PPIDE_RESET1 ; LOOP AS NEEDED
;
POP AF ; RECOVER ORIGINAL UNIT NUMBER
LD (PPIDE_UNIT),A ; AND SAVE IT
POP IY ; RECOVER DEVICE CFG PTR
;
XOR A ; SIGNAL SUCCESS
RET ; AND DONE
@ -943,34 +908,28 @@ PPIDE_RESET1:
;
;
PPIDE_INITUNIT:
LD (PPIDE_UNIT),A ; SET ACTIVE UNIT
CALL PPIDE_SELUNIT ; SELECT UNIT
RET NZ ; ABORT IF ERROR
;LD HL,PPIDE_TIMEOUT ; POINT TO TIMEOUT
;LD (HL),PPIDE_TOFAST ; USE FAST TIMEOUT DURING INIT
LD HL,PPIDE_TIMEOUT ; POINT TO TIMEOUT
LD (HL),PPIDE_TONORM ; SET NORMAL TIMEOUT
CALL PPIDE_PROBE ; DO PROBE
CALL Z,PPIDE_INITDEV ; IF FOUND, ATTEMPT TO INIT DEVICE
;LD HL,PPIDE_TIMEOUT ; POINT TO TIMEOUT
;LD (HL),PPIDE_TONORM ; BACK TO NORMAL TIMEOUT
RET
;
; TAKE ANY ACTIONS REQUIRED TO SELECT DESIRED PHYSICAL UNIT
;
PPIDE_SELUNIT:
LD A,(PPIDE_UNIT) ; GET UNIT
CP PPIDE_UNITCNT ; CHECK VALIDITY (EXCEED UNIT COUNT?)
JP NC,PPIDE_INVUNIT ; HANDLE INVALID UNIT
;
#IF (PPIDETRACE >= 3)
CALL PPIDE_PRTPREFIX
PRTS(" SELUNIT$")
#ENDIF
PUSH HL ; SAVE HL, IT IS DESTROYED BELOW
LD A,(PPIDE_UNIT) ; GET CURRENT UNIT
PUSH IY
POP BC
LD A,(IY+PPIDE_DEV) ; GET DEVICE
AND $01 ; LS BIT DETERMINES MASTER/SLAVE
LD HL,PPIDE_DRVSEL
CALL ADDHLA
@ -995,7 +954,7 @@ PPIDE_PROBE:
.DB PPIDE_REG_DRVHD
DCALL PC_SPACE
DCALL PRTHEXBYTE
CALL DELAY ; DELAY ~16US
;
; IN A,(PPIDE_REG_STAT) ; GET STATUS
@ -1069,8 +1028,8 @@ PPIDE_PROBE0:
;
PPIDE_PROBE1:
; SIGNATURE MATCHES ATA DEVICE, RECORD TYPE AND RETURN SUCCESS
PPIDE_DPTR(PPIDE_TYPE) ; POINT HL TO UNIT TYPE FIELD, A IS TRASHED
LD (HL),PPIDE_TYPEATA ; SET THE DEVICE TYPE
LD A,PPIDE_TYPEATA ; TYPE = ATA
LD (IY+PPIDE_TYPE),A ; SET IT IN INSTANCE DATA
XOR A ; SIGNAL SUCCESS
RET ; DONE, NOTE THAT A=0 AND Z IS SET
;
@ -1078,23 +1037,32 @@ PPIDE_PROBE1:
;
PPIDE_INITDEV:
;
PPIDE_DPTR(PPIDE_TYPE) ; POINT HL TO UNIT TYPE FIELD, A IS TRASHED
LD A,(HL) ; GET THE DEVICE TYPE
LD A,(IY+PPIDE_TYPE) ; GET THE DEVICE TYPE
OR A ; SET FLAGS
JP Z,PPIDE_NOMEDIA ; EXIT SETTING NO MEDIA STATUS
;
; CLEAR OUT UNIT SPECIFIC DATA, BUT PRESERVE THE EXISTING
; VALUE OF THE UNIT TYPE WHICH WAS ESTABLISHED BY THE DEVICE
; PROBES WHEN THE PPIDE BUS WAS RESET
PUSH AF ; SAVE UNIT TYPE VALUE FROM ABOVE
PUSH HL ; SAVE UNIT TYPE FIELD POINTER
PPIDE_DPTR(0) ; SET HL TO START OF UNIT DATA
LD BC,PPIDE_UDLEN
XOR A
CALL FILL
POP HL ; RECOVER UNIT TYPE FIELD POINTER
POP AF ; RECOVER UNIT TYPE VALUE
LD (HL),A ; AND PUT IT BACK
;PUSH AF ; SAVE UNIT TYPE VALUE FROM ABOVE
;LD A,(IY+PPIDE_DEV) ; GET CURRENT DEVICE NUMBER
;PUSH AF ; ... AND SAVE IT
;;PUSH HL ; SAVE UNIT TYPE FIELD POINTER
;;PPIDE_DPTR(0) ; SET HL TO START OF UNIT DATA
;;LD BC,PPIDE_UDLEN
;;XOR A
;;CALL FILL
;;POP HL ; RECOVER UNIT TYPE FIELD POINTER
;;POP AF ; RECOVER UNIT TYPE VALUE
;PUSH IY ; SET HL TO
;POP HL ; ... START OF DEVICE INSTANCE DATA
;LD BC,PPIDE_CFGSIZ ; SIZE OF CONFGI DATA TO CLEAR
;XOR A ; FILL WITH ZERO
;CALL FILL ; DO IT
;POP AF ; RECOVER DEVICE NUMBER VALUE
;LD (IY+PPIDE_DEV),A ; ... AND PUT IT BACK
;POP AF ; RECOVER DEVICE TYPE VALUE
;LD (IY+PPIDE_TYPE),A ; ... AND PUT IT BACK
;
#IF (PPIDE8BIT)
LD A,PPIDE_FEAT_ENABLE8BIT ; FEATURE VALUE = ENABLE 8-BIT PIO
@ -1116,6 +1084,9 @@ PPIDE_INITDEV:
LD DE,HB_WRKBUF ; POINT TO BUFFER
DCALL DUMP_BUFFER ; DUMP IT IF DEBUGGING
;
XOR A
LD (IY+PPIDE_FLAGS),0 ; CLEAR FLAGS
; DETERMINE IF CF DEVICE
LD HL,HB_WRKBUF ; FIRST WORD OF IDENTIFY DATA HAS CF FLAG
LD A,$8A ; FIRST BYTE OF MARKER IS $8A
@ -1125,13 +1096,19 @@ PPIDE_INITDEV:
LD A,$84 ; SECOND BYTE OF MARKER IS $84
CP (HL) ; COMPARE
JR NZ,PPIDE_INITDEV1 ; IF NOT MATCH, NOT CF
PPIDE_DPTR(PPIDE_CFFLAG) ; POINT HL TO CF FLAG FIELD
LD A,$FF ; SET FLAG VALUE TO NON-ZERO (TRUE)
LD (HL),A ; SAVE IT
SET 0,(IY+PPIDE_FLAGS) ; SET FLAGS BIT FOR CF MEDIA
;
PPIDE_INITDEV1:
; DETERMINE IF LBA CAPABLE
LD A,(HB_WRKBUF+98+1) ; GET BYTE WITH LBA BIT FROM BUFFER
BIT 1,A ; CHECK THE LBA BIT
JR Z,PPIDE_INITDEV2 ; NOT SET, BYPASS
SET 1,(IY+PPIDE_FLAGS) ; SET FLAGS BIT FOR LBA
;
PPIDE_INITDEV2:
; GET DEVICE CAPACITY AND SAVE IT
PPIDE_DPTR(PPIDE_CAPACITY) ; POINT HL TO UNIT CAPACITY FIELD
LD A,PPIDE_MEDCAP ; OFFSET TO CAPACITY FIELD
CALL LDHLIYA ; HL := IY + A, REG A TRASHED
PUSH HL ; SAVE POINTER
LD HL,HB_WRKBUF ; POINT TO BUFFER START
LD A,120 ; OFFSET OF SECTOR COUNT
@ -1141,18 +1118,16 @@ PPIDE_INITDEV1:
CALL ST32 ; SAVE CAPACITY
;
; RESET CARD STATUS TO 0 (OK)
PPIDE_DPTR(PPIDE_STAT) ; HL := ADR OF STATUS, AF TRASHED
XOR A ; A := 0 (STATUS = OK)
LD (HL),A ; SAVE IT
LD (IY+PPIDE_STAT),A ; SAVE IT
;
RET ; RETURN, A=0, Z SET
;
;
;
PPIDE_CHKDEVICE:
PPIDE_DPTR(PPIDE_STAT)
LD A,(HL)
OR A
LD A,(IY+PPIDE_STAT) ; GET STATUS
OR A ; SET FLAGS
RET Z ; RETURN IF ALL IS WELL
;
; ATTEMPT TO REINITIALIZE HERE???
@ -1168,23 +1143,23 @@ PPIDE_WAITRDY1:
LD DE,(PPIDE_TOSCALER) ; CPU SPPED SCALER TO INNER LOOP VAR
PPIDE_WAITRDY2:
;IN A,(PPIDE_REG_STAT) ; READ STATUS
CALL PPIDE_IN
.DB PPIDE_REG_STAT
LD C,A ; SAVE IT
AND %11000000 ; ISOLATE BUSY AND RDY BITS
CALL PPIDE_IN
.DB PPIDE_REG_STAT
LD C,A ; SAVE IT
AND %11000000 ; ISOLATE BUSY AND RDY BITS
XOR %01000000 ; WE WANT BUSY(7) TO BE 0 AND RDY(6) TO BE 1
RET Z ; ALL SET, RETURN WITH Z SET
DEC DE
LD A,D
OR E
JR NZ,PPIDE_WAITRDY2 ; INNER LOOP RETURN
DJNZ PPIDE_WAITRDY1 ; OUTER LOOP RETURN
JP PPIDE_RDYTO ; EXIT WITH RDYTO ERR
RET Z ; ALL SET, RETURN WITH Z SET
DEC DE
LD A,D
OR E
JR NZ,PPIDE_WAITRDY2 ; INNER LOOP RETURN
DJNZ PPIDE_WAITRDY1 ; OUTER LOOP RETURN
JP PPIDE_RDYTO ; EXIT WITH RDYTO ERR
;
;
;
PPIDE_WAITDRQ:
LD A,(PPIDE_TIMEOUT) ; GET TIMEOUT IN 0.05 SECS
LD A,(PPIDE_TIMEOUT) ; GET TIMEOUT IN 0.05 SECS
LD B,A ; PUT IN OUTER LOOP VAR
PPIDE_WAITDRQ1:
LD DE,(PPIDE_TOSCALER) ; CPU SPPED SCALER TO INNER LOOP VAR
@ -1206,24 +1181,24 @@ PPIDE_WAITDRQ2:
;
;
PPIDE_WAITBSY:
LD A,(PPIDE_TIMEOUT) ; GET TIMEOUT IN 0.05 SECS
LD A,(PPIDE_TIMEOUT) ; GET TIMEOUT IN 0.05 SECS
LD B,A ; PUT IN OUTER LOOP VAR
PPIDE_WAITBSY1:
LD DE,(PPIDE_TOSCALER) ; CPU SPPED SCALER TO INNER LOOP VAR
PPIDE_WAITBSY2:
;IN A,(PPIDE_REG_STAT) ; READ STATUS
CALL PPIDE_IN ; 17TS + 170TS
.DB PPIDE_REG_STAT ; 0TS
LD C,A ; SAVE IT ; 4TS
AND %10000000 ; TO FILL (OR READY TO FILL) ; 7TS
RET Z ; 5TS
DEC DE ; 6TS
LD A,D ; 4TS
OR E ; 4TS
JR NZ,PPIDE_WAITBSY2 ; 12TS
DJNZ PPIDE_WAITBSY1 ; -----
JP PPIDE_BSYTO ; EXIT WITH BSYTO ERR ; 229TS
;
.DB PPIDE_REG_STAT ; 0TS
LD C,A ; SAVE IT ; 4TS
AND %10000000 ; TO FILL (OR READY TO FILL) ; 7TS
RET Z ; 5TS
DEC DE ; 6TS
LD A,D ; 4TS
OR E ; 4TS
JR NZ,PPIDE_WAITBSY2 ; 12TS
DJNZ PPIDE_WAITBSY1 ; -----
JP PPIDE_BSYTO ; EXIT WITH BSYTO ERR ; 229TS
;
;
;
PPIDE_IN:
@ -1233,16 +1208,16 @@ PPIDE_IN:
PUSH BC ; SAVE INCOMING BC ; 11TS
LD B,(HL) ; GET CTL PORT VALUE ; 7TS
LD C,PPIDE_IO_CTL ; SETUP PORT TO WRITE ; 7TS
OUT (C),B ; SET ADDRESS LINES ; 12TS
SET 6,B ; TURN ON WRITE BIT ; 8TS
OUT (C),B ; ASSERT WRITE LINE ; 12TS
OUT (C),B ; SET ADDRESS LINES ; 12TS
SET 6,B ; TURN ON WRITE BIT ; 8TS
OUT (C),B ; ASSERT WRITE LINE ; 12TS
;NOP
;NOP
IN A,(PPIDE_IO_DATALO) ; GET DATA VALUE FROM DEVICE ; 11TS
;NOP
;NOP
RES 6,B ; CLEAR WRITE BIT ; 8TS
OUT (C),B ; DEASSERT WRITE LINE ; 12TS
RES 6,B ; CLEAR WRITE BIT ; 8TS
OUT (C),B ; DEASSERT WRITE LINE ; 12TS
POP BC ; RECOVER INCOMING BC ; 10TS
INC HL ; POINT PAST PARM ; 6TS
EX (SP),HL ; RESTORE STACK ; 19TS
@ -1309,12 +1284,8 @@ PPIDE_BSYTO:
JR PPIDE_ERR
;
PPIDE_ERR:
PUSH HL ; IS THIS NEEDED?
PUSH AF ; SAVE INCOMING STATUS
PPIDE_DPTR(PPIDE_STAT) ; GET STATUS ADR IN HL, AF TRASHED
POP AF ; RESTORE INCOMING STATUS
LD (HL),A ; UPDATE STATUS
POP HL ; IS THIS NEEDED?
LD (IY+PPIDE_STAT),A ; SAVE NEW STATUS
;
PPIDE_ERR2:
#IF (PPIDETRACE >= 2)
CALL PPIDE_PRTSTAT
@ -1410,7 +1381,7 @@ PPIDE_PRTPREFIX:
PUSH AF
CALL NEWLINE
PRTS("PPIDE$")
LD A,(PPIDE_UNIT)
LD A,(IY+PPIDE_DEV) ; GET CURRENT DEVICE NUM
ADD A,'0'
CALL COUT
CALL PC_COLON
@ -1426,14 +1397,14 @@ PPIDE_DSKY:
LD (HL),A ; SAVE IN BUFFER
INC HL ; INCREMENT BUFFER POINTER
IN A,(PPIDE_REG_CYLHI) ; GET DRIVE/HEAD
LD (HL),A ; SAVE IN BUFFER
INC HL ; INCREMENT BUFFER POINTER
LD (HL),A ; SAVE IN BUFFER
INC HL ; INCREMENT BUFFER POINTER
IN A,(PPIDE_REG_CYLLO) ; GET DRIVE/HEAD
LD (HL),A ; SAVE IN BUFFER
INC HL ; INCREMENT BUFFER POINTER
LD (HL),A ; SAVE IN BUFFER
INC HL ; INCREMENT BUFFER POINTER
IN A,(PPIDE_REG_SECT) ; GET DRIVE/HEAD
LD (HL),A ; SAVE IN BUFFER
CALL DSKY_HEXOUT ; SEND IT TO DSKY
LD (HL),A ; SAVE IN BUFFER
CALL DSKY_HEXOUT ; SEND IT TO DSKY
RET
#ENDIF
;
@ -1457,40 +1428,11 @@ PPIDE_STR_NO .TEXT "NO$"
; DATA STORAGE
;=============================================================================
;
PPIDE_TIMEOUT .DB PPIDE_TONORM ; WAIT FUNCS TIMEOUT IN TENTHS OF SEC
PPIDE_TOSCALER .DW CPUMHZ * 218 ; WAIT FUNCS SCALER FOR CPU SPEED
;
PPIDE_CMD .DB 0 ; PENDING COMMAND TO PROCESS
PPIDE_IOFNADR .DW 0 ; PENDING IO FUNCTION ADDRESS
PPIDE_DRVHD .DB 0 ; CURRENT DRIVE/HEAD MASK
;
PPIDE_UNIT .DB 0 ; ACTIVE UNIT, DEFAULT TO ZERO
PPIDE_DSKBUF .DW 0 ; ACTIVE DISK BUFFER
PPIDE_TIMEOUT .DB PPIDE_TONORM ; WAIT FUNCS TIMEOUT IN TENTHS OF SEC
PPIDE_TOSCALER .DW CPUMHZ * 218 ; WAIT FUNCS SCALER FOR CPU SPEED
;
; UNIT SPECIFIC DATA STORAGE
;
PPIDE_UDATA .FILL PPIDE_UNITCNT*8,0 ; PER UNIT DATA, 8 BYTES
PPIDE_DLEN .EQU $ - PPIDE_UDATA ; LENGTH OF ENTIRE DATA STORAGE FOR ALL UNITS
PPIDE_UDLEN .EQU PPIDE_DLEN / PPIDE_UNITCNT ; LENGTH OF PER UNIT DATA
;
;=============================================================================
; HELPER ROUTINES
;=============================================================================
PPIDE_CMD .DB 0 ; PENDING COMMAND TO PROCESS
PPIDE_IOFNADR .DW 0 ; PENDING IO FUNCTION ADDRESS
PPIDE_DRVHD .DB 0 ; CURRENT DRIVE/HEAD MASK
;
; IMPLEMENTATION FOR MACRO PPIDE_DPTR
; SET HL TO ADDRESS OF FIELD WITHIN PER UNIT DATA
; HL := ADR OF PPIDE_UNITDATA[(PPIDE_UNIT)][(SP)]
; ENTER WITH TOP-OF-STACK = ADDRESS OF FIELD OFFSET
; AF IS TRASHED
;
PPIDE_DPTRIMP:
LD HL,PPIDE_UDATA ; POINT TO START OF UNIT DATA ARRAY
LD A,(PPIDE_UNIT) ; GET CURRENT UNIT NUM
RLCA ; MULTIPLY BY
RLCA ; ... SIZE OF PER UNIT DATA
RLCA ; ... (8 BYTES)
EX (SP),HL ; GET PTR TO FIELD OFFSET VALUE FROM TOS
ADD A,(HL) ; ADD IT TO START OF UNIT DATA IN ACCUM
INC HL ; BUMP HL TO NEXT REAL INSTRUCTION
EX (SP),HL ; AND PUT IT BACK ON STACK, HL GETS ADR OF START OF DATA
JP ADDHLA ; CALC FINAL ADR IN HL AND RETURN
PPIDE_DSKBUF .DW 0 ; ACTIVE DISK BUFFER

260
Source/HBIOS/ppp.asm

@ -100,7 +100,7 @@ PPP_INITPPP:
LD A,%11000010 ; PPI MODE 2 (BI HANDSHAKE), PC0-2 OUT, PB IN
OUT (PPP_PPICTL),A ; NOTE: ALL OUTPUTS SET TO LOGIC ZERO ON MODE CHANGE
CALL DELAY ; PROBABLY NOT NEEDED
; RESET PROPELLER
LD A,%00000101 ; SET PC2 (ASSERT PROP RESET LINE)
OUT (PPP_PPICTL),A
@ -346,18 +346,16 @@ PPPCON_QUERY:
;
;
PPPCON_DEVICE:
LD D,CIODEV_PPPCON ; D := DEVICE TYPE
LD E,0 ; E := DEVICE NUM, ALWAYS 0
LD C,$FF ; $FF MEANS TERM W/ NO ATTACHED VDA
XOR A ; SIGNAL SUCCESS
LD D,CIODEV_PPPCON ; D := DEVICE TYPE
LD E,0 ; E := DEVICE NUM, ALWAYS 0
LD C,$FF ; $FF MEANS TERM W/ NO ATTACHED VDA
XOR A ; SIGNAL SUCCESS
RET
;
;==================================================================================================
; PARPORTPROP SD CARD DRIVER
;==================================================================================================
;
PPPSD_UNITCNT .EQU 1
;
; SD CARD TYPE
;
PPPSD_TYPEUNK .EQU 0 ; CARD TYPE UNKNOWN/UNDETERMINED
@ -380,25 +378,78 @@ PPPSD_STCRCERR .EQU -8 ; CRC ERROR ON RECEIVED DATA PACKET
PPPSD_STNOMEDIA .EQU -9 ; NO MEDIA IN CONNECTOR
PPPSD_STWRTPROT .EQU -10 ; ATTEMPT TO WRITE TO WRITE PROTECTED MEDIA
;
; PPPSD DEVICE CONFIGURATION
;
PPPSD_DEVCNT .EQU 1 ; ONE DEVICE SUPPORTED
PPPSD_CFGSIZ .EQU 12 ; SIZE OF CFG TBL ENTRIES
;
; PER DEVICE DATA OFFSETS
;
PPPSD_DEV .EQU 0 ; OFFSET OF DEVICE NUMBER (BYTE)
PPPSD_STAT .EQU 1 ; LAST STATUS (BYTE)
PPPSD_TYPE .EQU 2 ; DEVICE TYPE (BYTE)
PPPSD_FLAGS .EQU 3 ; FLAG BITS BIT 0=CF, 1=LBA (BYTE)
PPPSD_MEDCAP .EQU 4 ; MEDIA CAPACITY (DWORD)
PPPSD_LBA .EQU 8 ; OFFSET OF LBA (DWORD)
;
PPPSD_CFGTBL:
; DEVICE 0
.DB 0 ; DRIVER DEVICE NUMBER
.DB 0 ; DEVICE STATUS
.DB 0 ; DEVICE TYPE
.DB 0 ; FLAGS BYTE
.DW 0,0 ; DEVICE CAPACITY
.DW 0,0 ; CURRENT LBA
;
#IF ($ - PPPSD_CFGTBL) != (PPPSD_DEVCNT * PPPSD_CFGSIZ)
.ECHO "*** INVALID PPPSD CONFIG TABLE ***\n"
#ENDIF
;
.DB $FF ; END MARKER
;
; SD CARD INITIALIZATION
;
PPPSD_INIT:
;
; SETUP THE DISPATCH TABLE ENTRIES
;
LD B,0 ; PHYSICAL UNIT
LD C,DIODEV_PPPSD ; DEVICE TYPE
LD DE,0 ; UNIT DATA BLOB ADDRESS
CALL DIO_ADDENT ; ADD ENTRY, BC IS NOT DESTROYED
LD B,PPPSD_DEVCNT ; LOOP CONTROL
LD IY,PPPSD_CFGTBL ; START OF CFG TABLE
PPPSD_INIT0:
PUSH BC ; SAVE LOOP CONTROL
LD BC,PPPSD_FNTBL ; BC := FUNC TABLE ADR
PUSH IY ; CFG ENTRY POINTER
POP DE ; COPY TO DE
CALL DIO_ADDENT ; ADD ENTRY, BC IS NOT DESTROYED
LD BC,PPPSD_CFGSIZ ; SIZE OF CFG ENTRY
ADD IY,BC ; BUMP IY TO NEXT ENTRY
POP BC ; RESTORE BC
DJNZ PPPSD_INIT0 ; LOOP AS NEEDED
;
; INITIALIZE INDIVIDUAL UNIT(S) AND DISPLAY DEVICE INVENTORY
LD B,PPPSD_DEVCNT ; INIT LOOP COUNTER TO DEVICE COUNT
LD IY,PPPSD_CFGTBL ; START OF CFG TABLE
PPPSD_INIT1:
PUSH BC ; SAVE LOOP COUNTER/INDEX
CALL PPPSD_INITUNIT ; INITIALIZE IT
#IF (PPPSDTRACE < 2)
CALL NZ,PPPSD_PRTSTAT ; IF ERROR, SHOW IT
#ENDIF
LD BC,PPPSD_CFGSIZ ; SIZE OF CFG ENTRY
ADD IY,BC ; BUMP IY TO NEXT ENTRY
POP BC ; RESTORE LOOP CONTROL
DJNZ PPPSD_INIT1 ; DECREMENT LOOP COUNTER AND LOOP AS NEEDED
;
RET ; DONE
;
;
;
PPPSD_INITUNIT:
; REINITIALIZE THE CARD HERE
CALL PPPSD_INITCARD
#IF (PPPSDTRACE < 2)
JP NZ,PPPSD_PRTSTAT ; IF ERROR, SHOW IT
#ENDIF
RET NZ
;
CALL NEWLINE
PRTS("PPPSD:$")
CALL PPPSD_PRTPREFIX
;
; PRINT CARD TYPE
PRTS(" TYPE=$")
@ -406,7 +457,8 @@ PPPSD_INIT:
;
; PRINT STORAGE CAPACITY (BLOCK COUNT)
PRTS(" BLOCKS=0x$") ; PRINT FIELD LABEL
LD HL,PPPSD_BLKCNT ; POINT TO BLOCK COUNT
LD A,PPPSD_MEDCAP ; OFFSET TO CAPACITY FIELD
CALL LDHLIYA ; HL := IY + A, REG A TRASHED
CALL LD32 ; GET THE CAPACITY VALUE
CALL PRTHEX32 ; PRINT HEX VALUE
;
@ -422,45 +474,27 @@ PPPSD_INIT:
;
;
;
PPPSD_DISPATCH:
; VERIFY AND SAVE THE TARGET DEVICE/UNIT LOCALLY IN DRIVER
LD A,C ; DEVICE/UNIT FROM C
AND $0F ; ISOLATE UNIT NUM
CP PPPSD_UNITCNT
CALL NC,PANIC ; PANIC IF TOO HIGH
LD (PPPSD_UNIT),A ; SAVE IT
;
; DISPATCH ACCORDING TO DISK SUB-FUNCTION
LD A,B ; GET REQUESTED FUNCTION
AND $0F ; ISOLATE SUB-FUNCTION
JP Z,PPPSD_STATUS ; SUB-FUNC 0: STATUS
DEC A
JP Z,PPPSD_RESET ; SUB-FUNC 1: RESET
DEC A
JP Z,PPPSD_SEEK ; SUB-FUNC 2: SEEK
DEC A
JP Z,PPPSD_READ ; SUB-FUNC 3: READ SECTORS
DEC A
JP Z,PPPSD_WRITE ; SUB-FUNC 4: WRITE SECTORS
DEC A
JP Z,PPPSD_VERIFY ; SUB-FUNC 5: VERIFY SECTORS
DEC A
JP Z,PPPSD_FORMAT ; SUB-FUNC 6: FORMAT TRACK
DEC A
JP Z,PPPSD_DEVICE ; SUB-FUNC 7: DEVICE REPORT
DEC A
JP Z,PPPSD_MEDIA ; SUB-FUNC 8: MEDIA REPORT
DEC A
JP Z,PPPSD_DEFMED ; SUB-FUNC 9: DEFINE MEDIA
DEC A
JP Z,PPPSD_CAP ; SUB-FUNC 10: REPORT CAPACITY
DEC A
JP Z,PPPSD_GEOM ; SUB-FUNC 11: REPORT GEOMETRY
PPPSD_FNTBL:
.DW PPPSD_STATUS
.DW PPPSD_RESET
.DW PPPSD_SEEK
.DW PPPSD_READ
.DW PPPSD_WRITE
.DW PPPSD_VERIFY
.DW PPPSD_FORMAT
.DW PPPSD_DEVICE
.DW PPPSD_MEDIA
.DW PPPSD_DEFMED
.DW PPPSD_CAP
.DW PPPSD_GEOM
#IF (($ - PPPSD_FNTBL) != (DIO_FNCNT * 2))
.ECHO "*** INVALID PPPSD FUNCTION TABLE ***\n"
#ENDIF
;
PPPSD_VERIFY:
PPPSD_FORMAT:
PPPSD_DEFMED:
CALL PANIC ; INVALID SUB-FUNCTION
CALL PANIC ; INVALID SUB-FUNCTION
;
;
;
@ -498,7 +532,7 @@ PPPSD_IO:
PPPSD_IO1:
PUSH BC ; SAVE COUNTERS
#IF (PPPSDTRACE >= 3)
CALL PPPSD_PRTPREFIX
#ENDIF
@ -506,13 +540,11 @@ PPPSD_IO1:
LD HL,(PPPSD_IOFNADR) ; GET PENDING IO FUNCTION ADDRESS
CALL JPHL ; ... AND CALL IT
JR NZ,PPPSD_IO2 ; BAIL OUT ON ERROR
LD HL,HSTLBA ; POINT TO 32-BIT CURRENT LBA
PUSH HL ; SAVE POINTER
CALL LD32 ; LOAD 32-BIT LBA INTO DE:HL
CALL INC32 ; INCREMENT LBA FOR NEXT I/O
POP BC ; RECOVER LBA POINTER INTO BC
CALL ST32 ; AND SAVE IT
; INCREMENT LBA
LD A,PPPSD_LBA ; LBA OFFSET
CALL LDHLIYA ; HL := IY + A, REG A TRASHED
CALL INC32HL ; INCREMENT THE VALUE
; INCREMENT DMA
LD HL,PPPSD_DSKBUF+1 ; POINT TO MSB OF BUFFER ADR
INC (HL) ; BUMP DMA BY
INC (HL) ; ... 512 BYTES
@ -550,14 +582,14 @@ PPPSD_RDSEC:
CALL PC_SPACE
CALL PRTHEXBYTE
#ENDIF
OR A ; SET FLAGS
JR Z,PPPSD_RDSEC1
; HANDLE ERROR
CALL PPPSD_GETDSKSTAT ; GET FULL ERROR CODE
JP PPPSD_ERRCMD ; RETURN VIA ERROR HANDLER
PPPSD_RDSEC1:
; GET THE SECTOR DATA
LD D,PPP_CMDDSKGET ; COMMAND = DSKGET
@ -627,23 +659,23 @@ PPPSD_WRSEC1:
; REPORT SD CARD READY STATE
;
PPPSD_STATUS:
LD A,(PPPSD_STAT) ; GET THE CURRENT READY STATUS
LD A,(IY+PPPSD_STAT) ; GET THE CURRENT READY STATUS
OR A
RET
;
;
;
PPPSD_RESET:
XOR A ; ALWAYS OK
XOR A ; ALWAYS OK
RET
;
;
;
PPPSD_DEVICE:
LD D,DIODEV_PPPSD ; D := DEVICE TYPE
LD E,C ; E := PHYSICAL UNIT
LD C,%01010000 ; C := ATTRIBUTES, REMOVABLE, SD CARD
XOR A ; SIGNAL SUCCESS
LD D,DIODEV_PPPSD ; D := DEVICE TYPE
LD E,(IY+PPPSD_DEV) ; E := PHYSICAL DEVICE NUMBER
LD C,%01010000 ; C := ATTRIBUTES, REMOVABLE, SD CARD
XOR A ; SIGNAL SUCCESS
RET
;
; SETUP FOR SUBSEQUENT ACCESS
@ -663,21 +695,24 @@ PPPSD_MEDIA:
;
;
PPPSD_SEEK:
BIT 7,D ; CHECK FOR LBA FLAG
CALL Z,HB_CHS2LBA ; CLEAR MEANS CHS, CONVERT TO LBA
RES 7,D ; CLEAR FLAG REGARDLESS (DOES NO HARM IF ALREADY LBA)
LD BC,HSTLBA ; POINT TO LBA STORAGE
CALL ST32 ; SAVE LBA ADDRESS
XOR A ; SIGNAL SUCCESS
RET ; AND RETURN
BIT 7,D ; CHECK FOR LBA FLAG
CALL Z,HB_CHS2LBA ; CLEAR MEANS CHS, CONVERT TO LBA
RES 7,D ; CLEAR FLAG REGARDLESS (DOES NO HARM IF ALREADY LBA)
LD (IY+PPPSD_LBA+0),L ; SAVE NEW LBA
LD (IY+PPPSD_LBA+1),H ; ...
LD (IY+PPPSD_LBA+2),E ; ...
LD (IY+PPPSD_LBA+3),D ; ...
XOR A ; SIGNAL SUCCESS
RET ; AND RETURN
;
;
;
PPPSD_CAP:
LD HL,PPPSD_BLKCNT ; GET BLOCK COUNT
CALL LD32 ; GET THE CURRENT CAPACITY DO DE:HL
LD A,PPPSD_MEDCAP ; OFFSET TO CAPACITY FIELD
CALL LDHLIYA ; HL := IY + A, REG A TRASHED
CALL LD32 ; GET THE CURRENT CAPACITY INTO DE:HL
LD BC,512 ; 512 BYTES PER BLOCK
LD A,(PPPSD_STAT) ; GET CURRENT STATUS
LD A,(IY+PPPSD_STAT) ; GET CURRENT STATUS
OR A ; SET FLAGS
RET
;
@ -693,22 +728,16 @@ PPPSD_GEOM:
LD E,16 ; SECTORS / TRACK = 16
RET ; DONE, A STILL HAS PPPSD_CAP STATUS
;
; TAKE ANY ACTIONS REQUIRED TO SELECT DESIRED PHYSICAL UNIT
; UNIT IS SPECIFIED IN A
;
PPPSD_SELUNIT:
XOR A ; SIGNAL SUCCESS
RET ; DONE
;
; REINITIALIZE THE SD CARD
;
PPPSD_INITCARD:
; CLEAR ALL STATUS DATA
LD HL,PPPSD_UNITDATA
LD BC,PPPSD_UNITDATALEN
XOR A
CALL FILL
;; CLEAR ALL STATUS DATA
;LD HL,PPPSD_UNITDATA
;LD BC,PPPSD_UNITDATALEN
;XOR A
;CALL FILL
;
; RESET INTERFACE, RETURN WITH NZ ON FAILURE
#IF (PPPSDTRACE >= 3)
CALL PPPSD_PRTPREFIX
PRTS(" RESET$")
@ -728,7 +757,7 @@ PPPSD_INITCARD:
OR A
JR Z,PPPSD_INITCARD1
; HANDLE ERROR
CALL PPPSD_GETDSKSTAT ; GET FULL ERROR CODE
;JP PPPSD_ERRCMD ; HANDLE ERRORS
@ -755,10 +784,10 @@ PPPSD_INITCARD1:
; CHECK THE SD CARD, ATTEMPT TO REINITIALIZE IF NEEDED
;
PPPSD_CHKCARD:
LD A,(PPPSD_STAT) ; GET STATUS
LD A,(IY+PPPSD_STAT) ; GET STATUS
OR A ; SET FLAGS
CALL NZ,PPPSD_INITCARD ; INIT CARD IF NOT READY
RET ; RETURN WITH STATUS IN A
RET Z ; IF ALL GOOD, DONE
JP PPPSD_INITCARD ; OTHERWISE, REINIT
;
;
;
@ -802,7 +831,7 @@ PPPSD_GETTYPE:
CALL PPP_SNDCMD ; SEND COMMAND
RET NZ ; ABORT ON ERROR
CALL PPP_GETBYTE ; GET DISK TYPE VALUE
LD (PPPSD_CARDTYPE),A ; SAVE IT
LD (IY+PPPSD_TYPE),A ; SAVE IT
#IF (PPPSDTRACE >= 3)
CALL PC_SPACE
@ -824,8 +853,9 @@ PPPSD_GETCAP:
CALL PPP_SNDCMD ; SEND COMMAND
RET NZ ; ABORT ON ERROR
LD A,PPPSD_MEDCAP ; OFFSET OF CAPACITY
CALL LDHLIYA ; HL := IY + A, REG A TRASHED
LD B,4 ; GET 4 BYTES
LD HL,PPPSD_BLKCNT
PPPSD_GETCAP1:
CALL PPP_GETBYTE
LD (HL),A
@ -834,7 +864,8 @@ PPPSD_GETCAP1:
#IF (PPPSDTRACE >= 3)
CALL PC_SPACE
LD HL,PPPSD_BLKCNT
LD A,PPPSD_MEDCAP ; OFFSET OF CAPACITY
CALL LDHLIYA ; HL := IY + A, REG A TRASHED
CALL LD32
CALL PRTHEX32
#ENDIF
@ -883,12 +914,14 @@ PPPSD_SENDBLK:
#IF (PPPSDTRACE >= 3)
CALL PC_SPACE
LD HL,HSTLBA
LD A,PPPSD_LBA ; OFFSET OF LBA
CALL LDHLIYA ; HL := IY + A, REG A TRASHED
CALL LD32
CALL PRTHEX32
#ENDIF
LD HL,HSTLBA
LD A,PPPSD_LBA ; OFFSET OF LBA
CALL LDHLIYA ; HL := IY + A, REG A TRASHED
LD B,4
PPPSD_SENDBLK1:
LD A,(HL)
@ -948,7 +981,8 @@ PPPSD_WRTPROT:
JR PPPSD_ERR2 ; DO NOT UPDATE UNIT STATUS!
;
PPPSD_ERR:
LD (PPPSD_STAT),A ; UPDATE STATUS
LD (IY+PPPSD_STAT),A ; UPDATE STATUS
;
PPPSD_ERR2:
#IF (PPPSDTRACE >= 2)
CALL PPPSD_PRTSTAT
@ -1006,7 +1040,7 @@ PPPSD_PRTSTAT1:
CALL PPPSD_PRTPREFIX ; PRINT UNIT PREFIX
CALL PC_SPACE ; FORMATTING
CALL WRITESTR
LD A,(PPPSD_STAT)
LD A,(IY+PPPSD_STAT)
CP PPPSD_STCMDERR
CALL Z,PPPSD_PRTSTAT2
POP HL
@ -1037,14 +1071,20 @@ PPPSD_PRTERRCODE:
; PRINT DIAGNONSTIC PREFIX
;
PPPSD_PRTPREFIX:
PUSH AF
CALL NEWLINE
PRTS("PPPSD0:$")
PRTS("PPPSD$")
LD A,(IY+PPPSD_DEV) ; GET CURRENT DEVICE NUM
ADD A,'0'
CALL COUT
CALL PC_COLON
POP AF
RET
;
; PRINT THE CARD TYPE
;
PPPSD_PRTTYPE:
LD A,(PPPSD_CARDTYPE)
LD A,(IY+PPPSD_TYPE)
LD DE,PPPSD_STR_TYPEMMC
CP PPPSD_TYPEMMC
JR Z,PPPSD_PRTTYPE1
@ -1089,16 +1129,10 @@ PPPSD_STR_TYPESDXC .TEXT "SDXC$"
; DATA STORAGE
;=============================================================================
;
PPPSD_IOFNADR .DW 0 ; PENDING IO FUNCTION ADDRESS
PPPSD_IOFNADR .DW 0 ; PENDING IO FUNCTION ADDRESS
;
PPPSD_UNIT .DB 0
PPPSD_DSKBUF .DW 0
;
PPPSD_UNITDATA:
PPPSD_STAT .DB 0
PPPSD_DSKSTAT .DB 0
PPPSD_ERRCODE .DB $00, $00, $00, $00
PPPSD_CARDTYPE .DB 0
PPPSD_BLKCNT .DB $00, $00, $00, $00 ; ASSUME 1GB (LITTLE ENDIAN DWORD)
PPPSD_ERRCODE .DW 0,0
PPPSD_CSDBUF .FILL 16,0
PPPSD_UNITDATALEN .EQU $ - PPPSD_UNITDATA

275
Source/HBIOS/prp.asm

@ -130,8 +130,8 @@ PRPCON_INIT:
;LD B,0 ; PHYSICAL UNIT IS ZERO
;LD C,CIODEV_PRPCON ; DEVICE TYPE
;LD DE,0 ; UNIT DATA BLOB ADDRESS
LD D,0 ; PHYSICAL UNIT IS ZERO
LD E,CIODEV_PRPCON ; DEVICE TYPE
LD D,0 ; PHYSICAL UNIT IS ZERO
LD E,CIODEV_PRPCON ; DEVICE TYPE
LD BC,PRPCON_DISPATCH ; BC := DISPATCH ADDRESS
CALL CIO_ADDENT ; ADD ENTRY, A := UNIT ASSIGNED
LD (HCB + HCB_CRTDEV),A ; SET OURSELVES AS THE CRT DEVICE
@ -219,18 +219,16 @@ PRPCON_QUERY:
;
;
PRPCON_DEVICE:
LD D,CIODEV_PRPCON ; D := DEVICE TYPE
LD E,0 ; E := DEVICE NUM, ALWAYS 0
LD C,$FF ; $FF MEANS TERM W/ NO ATTACHED VDA
XOR A ; SIGNAL SUCCESS
LD D,CIODEV_PRPCON ; D := DEVICE TYPE
LD E,0 ; E := DEVICE NUM, ALWAYS 0
LD C,$FF ; $FF MEANS TERM W/ NO ATTACHED VDA
XOR A ; SIGNAL SUCCESS
RET
;
;==================================================================================================
; PROPIO SD CARD DRIVER
;==================================================================================================
;
PRPSD_UNITCNT .EQU 1
;
; IO PORT ADDRESSES
;
PRPSD_DSKCMD .EQU PRP_IOBASE + 2
@ -277,22 +275,76 @@ PRPSD_STCRCERR .EQU -8 ; CRC ERROR ON RECEIVED DATA PACKET
PRPSD_STNOMEDIA .EQU -9 ; NO MEDIA IN CONNECTOR
PRPSD_STWRTPROT .EQU -10 ; ATTEMPT TO WRITE TO WRITE PROTECTED MEDIA
;
; PRPSD DEVICE CONFIGURATION
;
PRPSD_DEVCNT .EQU 1 ; ONE DEVICE SUPPORTED
PRPSD_CFGSIZ .EQU 12 ; SIZE OF CFG TBL ENTRIES
;
; PER DEVICE DATA OFFSETS
;
PRPSD_DEV .EQU 0 ; OFFSET OF DEVICE NUMBER (BYTE)
PRPSD_STAT .EQU 1 ; LAST STATUS (BYTE)
PRPSD_TYPE .EQU 2 ; DEVICE TYPE (BYTE)
PRPSD_FLAGS .EQU 3 ; FLAG BITS BIT 0=CF, 1=LBA (BYTE)
PRPSD_MEDCAP .EQU 4 ; MEDIA CAPACITY (DWORD)
PRPSD_LBA .EQU 8 ; OFFSET OF LBA (DWORD)
;
PRPSD_CFGTBL:
; DEVICE 0
.DB 0 ; DRIVER DEVICE NUMBER
.DB 0 ; DEVICE STATUS
.DB 0 ; DEVICE TYPE
.DB 0 ; FLAGS BYTE
.DW 0,0 ; DEVICE CAPACITY
.DW 0,0 ; CURRENT LBA
;
#IF ($ - PRPSD_CFGTBL) != (PRPSD_DEVCNT * PRPSD_CFGSIZ)
.ECHO "*** INVALID PRPSD CONFIG TABLE ***\n"
#ENDIF
;
.DB $FF ; END MARKER
;
; SD CARD INITIALIZATION
;
PRPSD_INIT:
;
; SETUP THE DISPATCH TABLE ENTRIES
;
LD B,0 ; PHYSICAL UNIT
LD C,DIODEV_PRPSD ; DEVICE TYPE
LD DE,0 ; UNIT DATA BLOB ADDRESS
CALL DIO_ADDENT ; ADD ENTRY, BC IS NOT DESTROYED
LD B,PRPSD_DEVCNT ; LOOP CONTROL
LD IY,PRPSD_CFGTBL ; START OF CFG TABLE
PRPSD_INIT0:
PUSH BC ; SAVE LOOP CONTROL
LD BC,PRPSD_FNTBL ; BC := FUNC TABLE ADR
PUSH IY ; CFG ENTRY POINTER
POP DE ; COPY TO DE
CALL DIO_ADDENT ; ADD ENTRY, BC IS NOT DESTROYED
LD BC,PRPSD_CFGSIZ ; SIZE OF CFG ENTRY
ADD IY,BC ; BUMP IY TO NEXT ENTRY
POP BC ; RESTORE BC
DJNZ PRPSD_INIT0 ; LOOP AS NEEDED
;
; INITIALIZE INDIVIDUAL UNIT(S) AND DISPLAY DEVICE INVENTORY
LD B,PRPSD_DEVCNT ; INIT LOOP COUNTER TO DEVICE COUNT
LD IY,PRPSD_CFGTBL ; START OF CFG TABLE
PRPSD_INIT1:
PUSH BC ; SAVE LOOP COUNTER/INDEX
CALL PRPSD_INITUNIT ; INITIALIZE IT
#IF (PRPSDTRACE < 2)
CALL NZ,PRPSD_PRTSTAT ; IF ERROR, SHOW IT
#ENDIF
LD BC,PRPSD_CFGSIZ ; SIZE OF CFG ENTRY
ADD IY,BC ; BUMP IY TO NEXT ENTRY
POP BC ; RESTORE LOOP CONTROL
DJNZ PRPSD_INIT1 ; DECREMENT LOOP COUNTER AND LOOP AS NEEDED
;
RET ; DONE
;
;
;
PRPSD_INITUNIT:
; REINITIALIZE THE CARD HERE
CALL PRPSD_INITCARD
#IF (PRPSDTRACE < 2)
JP NZ,PRPSD_PRTSTAT ; IF ERROR, SHOW IT
#ENDIF
RET NZ
;
CALL PRPSD_PRTPREFIX
;
@ -302,7 +354,8 @@ PRPSD_INIT:
;
; PRINT STORAGE CAPACITY (BLOCK COUNT)
PRTS(" BLOCKS=0x$") ; PRINT FIELD LABEL
LD HL,PRPSD_BLKCNT ; POINT TO BLOCK COUNT
LD A,PRPSD_MEDCAP ; OFFSET TO CAPACITY FIELD
CALL LDHLIYA ; HL := IY + A, REG A TRASHED
CALL LD32 ; GET THE CAPACITY VALUE
CALL PRTHEX32 ; PRINT HEX VALUE
;
@ -318,45 +371,27 @@ PRPSD_INIT:
;
;
;
PRPSD_DISPATCH:
; VERIFY AND SAVE THE TARGET DEVICE/UNIT LOCALLY IN DRIVER
LD A,C ; DEVICE/UNIT FROM C
AND $0F ; ISOLATE UNIT NUM
CP PRPSD_UNITCNT
CALL NC,PANIC ; PANIC IF TOO HIGH
LD (PRPSD_UNIT),A ; SAVE IT
;
; DISPATCH ACCORDING TO DISK SUB-FUNCTION
LD A,B ; GET REQUESTED FUNCTION
AND $0F ; ISOLATE SUB-FUNCTION
JP Z,PRPSD_STATUS ; SUB-FUNC 0: STATUS
DEC A
JP Z,PRPSD_RESET ; SUB-FUNC 1: RESET
DEC A
JP Z,PRPSD_SEEK ; SUB-FUNC 2: SEEK
DEC A
JP Z,PRPSD_READ ; SUB-FUNC 3: READ SECTORS
DEC A
JP Z,PRPSD_WRITE ; SUB-FUNC 4: WRITE SECTORS
DEC A
JP Z,PRPSD_VERIFY ; SUB-FUNC 5: VERIFY SECTORS
DEC A
JP Z,PRPSD_FORMAT ; SUB-FUNC 6: FORMAT TRACK
DEC A
JP Z,PRPSD_DEVICE ; SUB-FUNC 7: DEVICE REPORT
DEC A
JP Z,PRPSD_MEDIA ; SUB-FUNC 8: MEDIA REPORT
DEC A
JP Z,PRPSD_DEFMED ; SUB-FUNC 9: DEFINE MEDIA
DEC A
JP Z,PRPSD_CAP ; SUB-FUNC 10: REPORT CAPACITY
DEC A
JP Z,PRPSD_GEOM ; SUB-FUNC 11: REPORT GEOMETRY
PRPSD_FNTBL:
.DW PRPSD_STATUS
.DW PRPSD_RESET
.DW PRPSD_SEEK
.DW PRPSD_READ
.DW PRPSD_WRITE
.DW PRPSD_VERIFY
.DW PRPSD_FORMAT
.DW PRPSD_DEVICE
.DW PRPSD_MEDIA
.DW PRPSD_DEFMED
.DW PRPSD_CAP
.DW PRPSD_GEOM
#IF (($ - PRPSD_FNTBL) != (DIO_FNCNT * 2))
.ECHO "*** INVALID PRPSD FUNCTION TABLE ***\n"
#ENDIF
;
PRPSD_VERIFY:
PRPSD_FORMAT:
PRPSD_DEFMED:
CALL PANIC ; INVALID SUB-FUNCTION
CALL PANIC ; INVALID SUB-FUNCTION
;
;
;
@ -394,7 +429,7 @@ PRPSD_IO:
PRPSD_IO1:
PUSH BC ; SAVE COUNTERS
#IF (PRPSDTRACE >= 3)
CALL PRPSD_PRTPREFIX
#ENDIF
@ -402,13 +437,11 @@ PRPSD_IO1:
LD HL,(PRPSD_IOFNADR) ; GET PENDING IO FUNCTION ADDRESS
CALL JPHL ; ... AND CALL IT
JR NZ,PRPSD_IO2 ; BAIL OUT ON ERROR
LD HL,HSTLBA ; POINT TO 32-BIT CURRENT LBA
PUSH HL ; SAVE POINTER
CALL LD32 ; LOAD 32-BIT LBA INTO DE:HL
CALL INC32 ; INCREMENT LBA FOR NEXT I/O
POP BC ; RECOVER LBA POINTER INTO BC
CALL ST32 ; AND SAVE IT
; INCREMENT LBA
LD A,PRPSD_LBA ; LBA OFFSET
CALL LDHLIYA ; HL := IY + A, REG A TRASHED
CALL INC32HL ; INCREMENT THE VALUE
; INCREMENT DMA
LD HL,PRPSD_DSKBUF+1 ; POINT TO MSB OF BUFFER ADR
INC (HL) ; BUMP DMA BY
INC (HL) ; ... 512 BYTES
@ -439,13 +472,13 @@ PRPSD_RDSEC:
LD A,PRPSD_CMDREAD ; READ COMMAND
CALL PRPSD_SNDCMD ; ... AND SEND COMMAND
RET NZ ; BAIL OUT ON ERROR
LD C,PRPSD_DSKIO ; SET PORT
LD B,0 ; SET LOOP COUNTER FOR 256 ITER
LD HL,(PRPSD_DSKBUF) ; SET BUF ADR
INIR ; READ 256 BYTES
INIR ; ... AND AGAIN FOR 512 TOTAL
XOR A ; SIGNAL SUCCESS
RET
;
@ -476,30 +509,30 @@ PRPSD_WRSEC:
LD A,PRPSD_CMDWRITE ; WRITE COMMAND
CALL PRPSD_SNDCMD ; SEND IT
RET NZ ; BAIL OUT ON ERROR
XOR A ; SIGNAL SUCCESS
RET ; RETURN
;
;
;
PRPSD_STATUS:
LD A,(PRPSD_STAT) ; GET THE CURRENT STATUS
LD A,(IY+PRPSD_STAT) ; GET STATUS OF SELECTED DEVICE
OR A
RET
;
;
;
PRPSD_RESET:
XOR A ; ALWAYS OK
XOR A ; ALWAYS OK
RET
;
;
;
PRPSD_DEVICE:
LD D,DIODEV_PRPSD ; D := DEVICE TYPE
LD E,C ; E := PHYSICAL UNIT
LD C,%01010000 ; C := ATTRIBUTES, REMOVABLE, SD CARD
XOR A ; SIGNAL SUCCESS
LD D,DIODEV_PRPSD ; D := DEVICE TYPE
LD E,(IY+PRPSD_DEV) ; E := PHYSICAL DEVICE NUMBER
LD C,%01010000 ; C := ATTRIBUTES, REMOVABLE, SD CARD
XOR A ; SIGNAL SUCCESS
RET
;
; PRPSD_SENSE
@ -518,21 +551,24 @@ PRPSD_MEDIA:
;
;
PRPSD_SEEK:
BIT 7,D ; CHECK FOR LBA FLAG
CALL Z,HB_CHS2LBA ; CLEAR MEANS CHS, CONVERT TO LBA
RES 7,D ; CLEAR FLAG REGARDLESS (DOES NO HARM IF ALREADY LBA)
LD BC,HSTLBA ; POINT TO LBA STORAGE
CALL ST32 ; SAVE LBA ADDRESS
XOR A ; SIGNAL SUCCESS
RET ; AND RETURN
BIT 7,D ; CHECK FOR LBA FLAG
CALL Z,HB_CHS2LBA ; CLEAR MEANS CHS, CONVERT TO LBA
RES 7,D ; CLEAR FLAG REGARDLESS (DOES NO HARM IF ALREADY LBA)
LD (IY+PRPSD_LBA+0),L ; SAVE NEW LBA
LD (IY+PRPSD_LBA+1),H ; ...
LD (IY+PRPSD_LBA+2),E ; ...
LD (IY+PRPSD_LBA+3),D ; ...
XOR A ; SIGNAL SUCCESS
RET ; AND RETURN
;
;
;
PRPSD_CAP:
LD HL,PRPSD_BLKCNT ; POINT TO BLOCK COUNT
CALL LD32 ; GET THE CURRENT CAPACITY TO DE:HL
LD A,PRPSD_MEDCAP ; OFFSET TO CAPACITY FIELD
CALL LDHLIYA ; HL := IY + A, REG A TRASHED
CALL LD32 ; GET THE CURRENT CAPACITY INTO DE:HL
LD BC,512 ; 512 BYTES PER BLOCK
LD A,(PRPSD_STAT) ; GET CURRENT STATUS
LD A,(IY+PRPSD_STAT) ; GET STATUS
OR A ; SET FLAGS
RET
;
@ -546,24 +582,16 @@ PRPSD_GEOM:
LD H,E ; ... HIGH BYTE DISCARDED, RESULT IN HL
LD D,16 | $80 ; HEADS / CYL = 16, SET LBA CAPABILITY BIT
LD E,16 ; SECTORS / TRACK = 16
XOR A ; SIGNAL SUCCESS
RET ; DONE, A STILL HAS PRPSD_CAP STATUS
;
; TAKE ANY ACTIONS REQUIRED TO SELECT DESIRED PHYSICAL UNIT
; UNIT IS SPECIFIED IN A
;
PRPSD_SELUNIT:
XOR A ; SIGNAL SUCCESS
RET ; DONE
;
;
;
PRPSD_INITCARD:
; CLEAR ALL STATUS DATA
LD HL,PRPSD_UNITDATA
LD BC,PRPSD_UNITDATALEN
XOR A
CALL FILL
;; CLEAR ALL STATUS DATA
;LD HL,PRPSD_UNITDATA
;LD BC,PRPSD_UNITDATALEN
;XOR A
;CALL FILL
;
; RESET INTERFACE, RETURN WITH NZ ON FAILURE
#IF (PRPSDTRACE >= 3)
@ -607,10 +635,10 @@ PRPSD_INITCARD:
; CHECK THE SD CARD, ATTEMPT TO REINITIALIZE IF NEEDED
;
PRPSD_CHKCARD:
LD A,(PRPSD_STAT) ; GET STATUS
LD A,(IY+PRPSD_STAT) ; GET CURRENT STATUS
OR A ; SET FLAGS
RET Z ; IF ALL GOOD, DONE
JP NZ,PRPSD_INITCARD ; OTHERWISE, REINIT
JP PRPSD_INITCARD ; OTHERWISE, REINIT
;
;
;
@ -661,7 +689,7 @@ PRPSD_GETTYPE:
RET NZ
IN A,(PRPSD_DSKIO)
LD (PRPSD_CARDTYPE),A
LD (IY+PRPSD_TYPE),A
#IF (PRPSDTRACE >= 3)
CALL PC_SPACE
@ -684,12 +712,14 @@ PRPSD_GETCAP:
LD C,PRPSD_DSKIO ; FROM PROPIO DISK PORT
LD B,4 ; 4 BYTES
LD HL,PRPSD_BLKCNT ; TO PRPSD_BLKCNT
LD A,PRPSD_MEDCAP ; ... OF CAPACITY
CALL LDHLIYA ; HL := IY + A, REG A TRASHED
INIR
#IF (PRPSDTRACE >= 3)
CALL PC_SPACE
LD HL,PRPSD_BLKCNT
LD A,PRPSD_MEDCAP ; ... OF CAPACITY
CALL LDHLIYA ; HL := IY + A, REG A TRASHED
CALL LD32
CALL PRTHEX32
#ENDIF
@ -817,13 +847,15 @@ PRPSD_SETBLK:
#IF (PRPSDTRACE >= 3)
CALL PC_SPACE
LD HL,HSTLBA
LD A,PRPSD_LBA ; OFFSET OF LBA
CALL LDHLIYA ; HL := IY + A, REG A TRASHED
CALL LD32
CALL PRTHEX32
#ENDIF
LD C,PRPSD_DSKIO ; SEND TO DISK I/O PORT
LD B,4 ; 4 BYTES
LD HL,HSTLBA ; OF LBA
LD A,PRPSD_LBA ; OFFSET OF LBA
CALL LDHLIYA ; HL := IY + A, REG A TRASHED
OTIR
RET
;
@ -874,12 +906,13 @@ PRPSD_WRTPROT:
JR PRPSD_ERR2 ; DO NOT UPDATE UNIT STATUS!
;
PRPSD_ERR:
LD (PRPSD_STAT),A ; UPDATE STATUS
LD (IY+PRPSD_STAT),A ; UPDATE STATUS
;
PRPSD_ERR2:
#IF (PRPSDTRACE >= 2)
CALL PRPSD_PRTSTAT
#ENDIF
OR A ; SET FLAGS
OR A ; SET FLAGS
RET
;
;
@ -932,7 +965,7 @@ PRPSD_PRTSTAT1:
CALL PRPSD_PRTPREFIX ; PRINT UNIT PREFIX
CALL PC_SPACE ; FORMATTING
CALL WRITESTR
LD A,(PRPSD_STAT)
LD A,(IY+PRPSD_STAT)
CP PRPSD_STCMDERR
CALL Z,PRPSD_PRTSTAT2
POP HL
@ -963,28 +996,34 @@ PRPSD_PRTERRCODE:
; PRINT DIAGNONSTIC PREFIX
;
PRPSD_PRTPREFIX:
PUSH AF
CALL NEWLINE
PRTS("PRPSD0:$")
PRTS("PRPSD$")
LD A,(IY+PRPSD_DEV) ; GET CURRENT DEVICE NUM
ADD A,'0'
CALL COUT
CALL PC_COLON
POP AF
RET
;
; PRINT THE CARD TYPE
;
PRPSD_PRTTYPE:
LD A,(PRPSD_CARDTYPE)
LD A,(IY+PRPSD_TYPE)
LD DE,PRPSD_STR_TYPEMMC
CP PRPSD_TYPEMMC
JR Z,PRPSD_INIT1
JR Z,PRPSD_PRTTYPE1
LD DE,PRPSD_STR_TYPESDSC
CP PRPSD_TYPESDSC
JR Z,PRPSD_INIT1
JR Z,PRPSD_PRTTYPE1
LD DE,PRPSD_STR_TYPESDHC
CP PRPSD_TYPESDHC
JR Z,PRPSD_INIT1
JR Z,PRPSD_PRTTYPE1
LD DE,PRPSD_STR_TYPESDXC
CP PRPSD_TYPESDXC
JR Z,PRPSD_INIT1
JR Z,PRPSD_PRTTYPE1
LD DE,PRPSD_STR_TYPEUNK
PRPSD_INIT1:
PRPSD_PRTTYPE1:
JP WRITESTR
;
;=============================================================================
@ -1005,11 +1044,11 @@ PRPSD_STR_STRDYTO .TEXT "READY TIMEOUT$"
PRPSD_STR_STINITTO .TEXT "INITIALIZATION TIMEOUT$"
PRPSD_STR_STCMDTO .TEXT "COMMAND TIMEOUT$"
PRPSD_STR_STCMDERR .TEXT "COMMAND ERROR$"
PRPSD_STR_STDATAERR .TEXT "DATA ERROR$"
PRPSD_STR_STDATAERR .TEXT "DATA ERROR$"
PRPSD_STR_STDATATO .TEXT "DATA TIMEOUT$"
PRPSD_STR_STCRCERR .TEXT "CRC ERROR$"
PRPSD_STR_STNOMEDIA .TEXT "NO MEDIA$"
PRPSD_STR_STWRTPROT .TEXT "WRITE PROTECTED$"
PRPSD_STR_STNOMEDIA .TEXT "NO MEDIA$"
PRPSD_STR_STWRTPROT .TEXT "WRITE PROTECTED$"
PRPSD_STR_STUNK .TEXT "UNKNOWN$"
;
PRPSD_STR_TYPEUNK .TEXT "UNK$"
@ -1022,22 +1061,16 @@ PRPSD_STR_TYPESDXC .TEXT "SDXC$"
; DATA STORAGE
;=============================================================================
;
PRP_FWVER .DB $00, $00, $00, $00 ; MMNNBBB (M=MAJOR, N=MINOR, B=BUILD)
PRP_FWVER .DW 0,0 ; MMNNBBB (M=MAJOR, N=MINOR, B=BUILD)
;
PRPSD_IOFNADR .DW 0 ; PENDING IO FUNCTION ADDRESS
PRPSD_IOFNADR .DW 0 ; PENDING IO FUNCTION ADDRESS
;
PRPSD_UNIT .DB 0
PRPSD_DSKBUF .DW 0
;
PRPSD_UNITDATA:
PRPSD_STAT .DB 0
PRPSD_DSKSTAT .DB 0
PRPSD_ERRCODE .DB $00, $00, $00, $00
PRPSD_CARDTYPE .DB 0
PRPSD_BLKCNT .DB $00, $00, $00, $00 ; ASSUME 1GB (LITTLE ENDIAN DWORD)
PRPSD_ERRCODE .DW 0,0
PRPSD_CSDBUF .FILL 16,0
PRPSD_UNITDATALEN .EQU $ - PRPSD_UNITDATA
;
PRPSD_CMD .DB 0
;
PRPSD_TIMEOUT .DW $0000 ; FIX: MAKE THIS CPU SPEED RELATIVE
PRPSD_TIMEOUT .DW $0000 ; FIX: MAKE THIS CPU SPEED RELATIVE

182
Source/HBIOS/rf.asm

@ -15,98 +15,102 @@ RF_AL .EQU 1
RF_AH .EQU 2
RF_ST .EQU 3
;
; MD DEVICE CONFIGURATION
;
RF_DEVCNT .EQU RFCNT ; NUMBER OF RF DEVICES SUPPORTED
RF_CFGSIZ .EQU 6 ; SIZE OF CFG TBL ENTRIES
;
RF_DEV .EQU 0 ; OFFSET OF DEVICE NUMBER (BYTE)
RF_STAT .EQU 1 ; OFFSET OF STATUS (BYTE)
RF_LBA .EQU 2 ; OFFSET OF LBA (DWORD)
;
; DEVICE CONFIG TABLE (RAM DEVICE FIRST TO MAKE IT ALWAYS FIRST DRIVE)
;
RF_CFGTBL:
; DEVICE 0 ($A0)
.DB 0 ; DRIVER DEVICE NUMBER
.DB 0 ; DEVICE STATUS
.DW 0,0 ; CURRENT LBA
#IF (RF_DEVCNT >= 2)
; DEVICE 1 ($A4)
.DB 1 ; DEVICE NUMBER
.DB 0 ; DEVICE STATUS
.DW 0,0 ; CURRENT LBA
#ENDIF
;
#IF ($ - RF_CFGTBL) != (RF_DEVCNT * RF_CFGSIZ)
.ECHO "*** INVALID RF CONFIG TABLE ***\n"
#ENDIF
;
.DB $FF ; END MARKER
;
;
;
RF_INIT:
CALL NEWLINE ; FORMATTING
PRTS("RF: UNITS=$")
LD A,RFCNT
LD A,RF_DEVCNT
CALL PRTDECB
;
; SETUP THE DISPATCH TABLE ENTRIES
; SETUP THE DIO TABLE ENTRIES
;
;
; SETUP THE DISPATCH TABLE ENTRIES
;
LD B,RFCNT ; LOOP CONTROL
LD C,0 ; PHYSICAL UNIT INDEX
LD B,RF_DEVCNT ; LOOP CONTROL
LD IY,RF_CFGTBL ; START OF CFG TABLE
RF_INIT0:
PUSH BC ; SAVE LOOP CONTROL
LD B,C ; PHYSICAL UNIT
LD C,DIODEV_RF ; DEVICE TYPE
LD DE,0 ; UNIT DATA BLOB ADDRESS
CALL DIO_ADDENT ; ADD ENTRY, BC IS NOT DESTROYED
POP BC ; RESTORE LOOP CONTROL
INC C ; NEXT PHYSICAL UNIT
DJNZ RF_INIT0 ; LOOP UNTIL DONE
;
XOR A ; INIT SUCCEEDED
RET ; RETURN
;
;
;
RF_DISPATCH:
; VERIFY AND SAVE THE TARGET DEVICE/UNIT LOCALLY IN DRIVER
LD A,C ; DEVICE/UNIT FROM C
AND $0F ; ISOLATE UNIT NUM
CP 2 ; CHECK FOR MAX UNIT EXCEEDED
LD (RF_UNIT),A ; SAVE IT
CALL NC,PANIC ; PANIC IF TOO HIGH
;
; DISPATCH ACCORDING TO DISK SUB-FUNCTION
LD A,B ; GET REQUESTED FUNCTION
AND $0F ; ISOLATE SUB-FUNCTION
JP Z,RF_STATUS ; SUB-FUNC 0: STATUS
DEC A
JP Z,RF_RESET ; SUB-FUNC 1: RESET
DEC A
JP Z,RF_SEEK ; SUB-FUNC 2: SEEK
DEC A
JP Z,RF_READ ; SUB-FUNC 3: READ SECTORS
DEC A
JP Z,RF_WRITE ; SUB-FUNC 4: WRITE SECTORS
DEC A
JP Z,RF_VERIFY ; SUB-FUNC 5: VERIFY SECTORS
DEC A
JP Z,RF_FORMAT ; SUB-FUNC 6: FORMAT TRACK
DEC A
JP Z,RF_DEVICE ; SUB-FUNC 7: DEVICE REPORT
DEC A
JP Z,RF_MEDIA ; SUB-FUNC 8: MEDIA REPORT
DEC A
JP Z,RF_DEFMED ; SUB-FUNC 9: DEFINE MEDIA
DEC A
JP Z,RF_CAP ; SUB-FUNC 10: REPORT CAPACITY
DEC A
JP Z,RF_GEOM ; SUB-FUNC 11: REPORT GEOMETRY
PUSH BC ; SAVE LOOP CONTROL
LD BC,RF_FNTBL ; BC := FUNC TABLE ADR
PUSH IY ; CFG ENTRY POINTER
POP DE ; COPY TO DE
CALL DIO_ADDENT ; ADD ENTRY, BC IS NOT DESTROYED
LD BC,RF_CFGSIZ ; SIZE OF CFG ENTRY
ADD IY,BC ; BUMP IY TO NEXT ENTRY
POP BC ; RESTORE BC
DJNZ RF_INIT0 ; LOOP AS NEEDED
;
XOR A ; INIT SUCCEEDED
RET ; RETURN
;
;
;
RF_FNTBL:
.DW RF_STATUS
.DW RF_RESET
.DW RF_SEEK
.DW RF_READ
.DW RF_WRITE
.DW RF_VERIFY
.DW RF_FORMAT
.DW RF_DEVICE
.DW RF_MEDIA
.DW RF_DEFMED
.DW RF_CAP
.DW RF_GEOM
#IF (($ - RF_FNTBL) != (DIO_FNCNT * 2))
.ECHO "*** INVALID MD FUNCTION TABLE ***\n"
#ENDIF
;
RF_VERIFY:
RF_FORMAT:
RF_DEFMED:
CALL PANIC ; INVALID SUB-FUNCTION
CALL PANIC ; INVALID SUB-FUNCTION
;
;
;
RF_STATUS:
XOR A ; STATUS ALWAYS OK
XOR A ; STATUS ALWAYS OK
RET
;
;
;
RF_RESET:
XOR A ; ALWAYS OK
XOR A ; ALWAYS OK
RET
;
;
;
RF_CAP:
LD A,C ; DEVICE/UNIT IS IN C
AND $0F ; ISOLATE UNIT NUM
CP RFCNT ; CHECK FOR MAX UNIT EXCEEDED
CALL NC,PANIC ; PANIC IF TOO HIGH
;
LD DE,0
LD HL,$2000 ; 8192 BLOCKS OF 512 BYTES
LD HL,$2000 ; 8192 BLOCKS OF 512 BYTES
XOR A
RET
;
@ -125,33 +129,35 @@ RF_GEOM:
;
;
RF_DEVICE:
LD D,DIODEV_RF ; D := DEVICE TYPE
LD E,C ; E := PHYSICAL UNIT
LD C,%00110000 ; C := ATTRIBUTES, NON-REMOVALBE RAM FLOPPY
XOR A ; SIGNAL SUCCESS
LD D,DIODEV_RF ; D := DEVICE TYPE
LD E,(IY+RF_DEV) ; E := PHYSICAL DEVICE NUMBER
LD C,%00110000 ; C := ATTRIBUTES, NON-REMOVALBE RAM FLOPPY
XOR A ; SIGNAL SUCCESS
RET
;
;
;
RF_MEDIA:
LD E,MID_RF ; RAM FLOPPY MEDIA
LD E,MID_RF ; RAM FLOPPY MEDIA
LD D,0 ; D:0=0 MEANS NO MEDIA CHANGE
XOR A ; SIGNAL SUCCESS
RET
;
;
;
RF_SEEK:
;
;
;
RF_SEEK:
BIT 7,D ; CHECK FOR LBA FLAG
CALL Z,HB_CHS2LBA ; CLEAR MEANS CHS, CONVERT TO LBA
RES 7,D ; CLEAR FLAG REGARDLESS (DOES NO HARM IF ALREADY LBA)
LD BC,HSTLBA ; POINT TO LBA STORAGE
CALL ST32 ; SAVE LBA ADDRESS
LD (IY+RF_LBA+0),L ; SAVE NEW LBA
LD (IY+RF_LBA+1),H ; ...
LD (IY+RF_LBA+2),E ; ...
LD (IY+RF_LBA+3),D ; ...
XOR A ; SIGNAL SUCCESS
RET ; AND RETURN
;
;
;
;
;
RF_READ:
LD BC,RF_RDSEC ; GET ADR OF SECTOR READ FUNC
LD (RF_RWFNADR),BC ; SAVE IT AS PENDING IO FUNC
@ -183,12 +189,11 @@ RF_RW1:
LD HL,(RF_RWFNADR) ; GET PENDING IO FUNCTION ADDRESS
CALL JPHL ; ... AND CALL IT
JR NZ,RF_RW2 ; IF ERROR, SKIP INCREMENT
LD HL,HSTLBA ; POINT TO 32-BIT CURRENT LBA
PUSH HL ; SAVE POINTER
CALL LD32 ; LOAD 32-BIT LBA INTO DE:HL
CALL INC32 ; INCREMENT LBA FOR NEXT I/O
POP BC ; RECOVER LBA POINTER INTO BC
CALL ST32 ; AND SAVE IT
; INCREMENT LBA
LD A,MD_LBA ; OFFSET OF LBA VALUE
CALL LDHLIYA ; HL := IY + A, REG A TRASHED
CALL INC32HL ; INCREMENT THE VALUE
; INCREMENT DMA
LD HL,RF_DSKBUF+1 ; POINT TO MSB OF BUFFER ADR
INC (HL) ; BUMP DMA BY
INC (HL) ; ... 512 BYTES
@ -235,8 +240,8 @@ RF_WRSEC:
;
;
RF_SETIO:
LD A,(RF_UNIT) ; GET DEVICE/UNIT
AND $0F ; ISOLATE UNIT NUM
LD A,(IY+RF_DEV) ; GET DEVICE NUM
OR A ; SET FLAGS
JR NZ,RF_SETIO1
LD A,RF_U0IO
JR RF_SETIO3
@ -246,7 +251,7 @@ RF_SETIO1:
LD A,RF_U1IO
JR RF_SETIO3
RF_SETIO2:
CALL PANIC ; INVALID UNIT
CALL PANIC ; INVALID UNIT
RF_SETIO3:
LD (RF_IO),A
RET
@ -257,9 +262,9 @@ RF_SETADR:
LD A,(RF_IO)
OR RF_AL
LD C,A
LD A,(HSTLBALO)
LD A,(IY+RF_LBA+0)
OUT (C),A
LD A,(HSTLBALO+1)
LD A,(IY+RF_LBA+1)
INC C
OUT (C),A
RET
@ -280,5 +285,4 @@ RF_CHKWP:
RF_IO .DB 0
RF_RWFNADR .DW 0
;
RF_UNIT .DB 0
RF_DSKBUF .DW 0

387
Source/HBIOS/sd.asm

@ -54,33 +54,33 @@
; === R1 RESPONSE ===
; ALL COMMAND RESPONSES START WITH R1
;
; 7 6 5 4 3 2 1 0
; 7 6 5 4 3 2 1 0
; +---+---+---+---+---+---+---+---+
; | 0 | X | X | X | X | X | X | X |
; +---+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | | | | | | |
; | | | | | | +--- IDLE
; | | | | | +------- ERASE RESET
; | | | | +----------- ILLEGAL COMMAND
; | | | +--------------- COM CRC ERROR
; | | +------------------- ERASE SEQUENCE ERROR
; | +----------------------- ADDRESS ERROR
; | | | | | | |
; | | | | | | +--- IDLE
; | | | | | +------- ERASE RESET
; | | | | +----------- ILLEGAL COMMAND
; | | | +--------------- COM CRC ERROR
; | | +------------------- ERASE SEQUENCE ERROR
; | +----------------------- ADDRESS ERROR
; +--------------------------- PARAMETER ERROR
;
; === DATA ERROR TOKEN ===
;
; 7 6 5 4 3 2 1 0
; 7 6 5 4 3 2 1 0
; +---+---+---+---+---+---+---+---+
; | 0 | 0 | 0 | 0 | X | X | X | X |
; +---+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | | | |
; | | | +--- ERROR - GENERAL OR UNKNOWN ERROR
; | | +------- CC ERROR - INTERNAL CARD CONTROLER ERROR
; | +----------- CARD ECC FAILED - CARD INTERNAL ECC FAILED TO CORRECT DATA
; +--------------- OUT OF RANGE - PARAMAETER OUT OF RANGE ALLOWED FOR CARD
; | | | |
; | | | +--- ERROR - GENERAL OR UNKNOWN ERROR
; | | +------- CC ERROR - INTERNAL CARD CONTROLER ERROR
; | +----------- CARD ECC FAILED - CARD INTERNAL ECC FAILED TO CORRECT DATA
; +--------------- OUT OF RANGE - PARAMAETER OUT OF RANGE ALLOWED FOR CARD
;
#IF (SDMODE == SDMODE_JUHA) ; JUHA MINI-BOARD
SD_UNITCNT .EQU 1 ; NUMBER OF PHYSICAL UNITS (SOCKETS)
SD_DEVCNT .EQU 1 ; NUMBER OF PHYSICAL UNITS (SOCKETS)
SD_OPRREG .EQU RTC ; USES RTC LATCHES FOR OPERATION
SD_OPRDEF .EQU %00000001 ; QUIESCENT STATE???
SD_INPREG .EQU RTC ; INPUT REGISTER IS RTC
@ -91,7 +91,7 @@ SD_DO .EQU %10000000 ; RTC:7 IS DATA OUT (CARD -> CPU)
#ENDIF
;
#IF (SDMODE == SDMODE_N8) ; UNMODIFIED N8-2511
SD_UNITCNT .EQU 1 ; NUMBER OF PHYSICAL UNITS (SOCKETS)
SD_DEVCNT .EQU 1 ; NUMBER OF PHYSICAL UNITS (SOCKETS)
SD_OPRREG .EQU RTC ; USES RTC LATCHES FOR OPERATION
SD_OPRDEF .EQU %00000001 ; QUIESCENT STATE???
SD_INPREG .EQU RTC ; INPUT REGISTER IS RTC
@ -102,7 +102,7 @@ SD_DO .EQU %01000000 ; RTC:6 IS DATA OUT (CARD -> CPU)
#ENDIF
;
#IF (SDMODE == SDMODE_CSIO) ; N8-2312
SD_UNITCNT .EQU 1 ; NUMBER OF PHYSICAL UNITS (SOCKETS)
SD_DEVCNT .EQU 1 ; NUMBER OF PHYSICAL UNITS (SOCKETS)
SD_OPRREG .EQU RTC ; USES RTC LATCHES FOR OPERATION
SD_OPRDEF .EQU %00000000 ; QUIESCENT STATE
SD_CS .EQU %00000100 ; RTC:2 IS SELECT
@ -111,7 +111,7 @@ SD_TRDR .EQU Z180_TRDR
#ENDIF
;
#IF (SDMODE == SDMODE_PPI) ; PPISD
SD_UNITCNT .EQU 1 ; NUMBER OF PHYSICAL UNITS (SOCKETS)
SD_DEVCNT .EQU 1 ; NUMBER OF PHYSICAL UNITS (SOCKETS)
SD_PPIBASE .EQU PPIBASE ; BASE IO PORT FOR PPI
SD_PPIB .EQU PPIBASE + 1 ; PPI PORT B (INPUT: DOUT)
SD_PPIC .EQU PPIBASE + 2 ; PPI PORT C (OUTPUT: CS, CLK, DIN)
@ -126,7 +126,7 @@ SD_DO .EQU %10000000 ; PPIB:7 IS DATA OUT (CARD -> CPU)
#ENDIF
;
#IF (SDMODE == SDMODE_UART)
SD_UNITCNT .EQU 1 ; NUMBER OF PHYSICAL UNITS (SOCKETS)
SD_DEVCNT .EQU 1 ; NUMBER OF PHYSICAL UNITS (SOCKETS)
SD_OPRREG .EQU SIO_MCR ; UART MCR PORT (OUTPUT: CS, CLK, DIN)
SD_OPRDEF .EQU %00001100 ; QUIESCENT STATE
SD_INPREG .EQU SIO_MSR ; INPUT REGISTER IS MSR
@ -137,7 +137,7 @@ SD_DO .EQU %00100000 ; UART MSR:5 IS DATA OUT (CARD -> CPU)
#ENDIF
;
#IF (SDMODE == SDMODE_DSD) ; DUAL SD
SD_UNITCNT .EQU 2 ; NUMBER OF PHYSICAL UNITS (SOCKETS)
SD_DEVCNT .EQU 2 ; NUMBER OF PHYSICAL UNITS (SOCKETS)
SD_OPRREG .EQU $08 ; DEDICATED OPERATIONS REGISTER
SD_OPRDEF .EQU %00000001 ; QUIESCENT STATE
SD_INPREG .EQU SD_OPRREG ; INPUT REGISTER IS OPRREG
@ -150,7 +150,7 @@ SD_DO .EQU %00000001 ; RTC:0 IS DATA OUT (CARD -> CPU)
#ENDIF
;
#IF (SDMODE == SDMODE_MK4) ; MARK IV (CSIO STYLE INTERFACE)
SD_UNITCNT .EQU 1 ; NUMBER OF PHYSICAL UNITS (SOCKETS)
SD_DEVCNT .EQU 1 ; NUMBER OF PHYSICAL UNITS (SOCKETS)
SD_OPRREG .EQU MK4_SD ; DEDICATED MK4 SDCARD REGISTER
SD_OPRDEF .EQU %00000000 ; QUIESCENT STATE
SD_CS .EQU %00000100 ; SELECT ACTIVE
@ -198,16 +198,42 @@ SD_STCRCERR .EQU -8 ; CRC ERROR ON RECEIVED DATA PACKET
SD_STNOMEDIA .EQU -9 ; NO MEDIA IN CONNECTOR
SD_STWRTPROT .EQU -10 ; ATTEMPT TO WRITE TO WRITE PROTECTED MEDIA
;
; PER UNIT DATA OFFSETS (CAREFUL NOT TO EXCEED PER UNIT SPACE IN SD_UNITDATA)
; SEE SD_UNITDATA IN DATA STORAGE BELOW
;
SD_STAT .EQU 0 ; LAST STATUS (1 BYTE)
SD_TYPE .EQU 1 ; CARD TYPE (1 BYTE)
SD_CAPACITY .EQU 2 ; CARD CAPACITY (1 DWORD/4 BYTES)
; IDE DEVICE CONFIGURATION
;
SD_CFGSIZ .EQU 12 ; SIZE OF CFG TBL ENTRIES
;
; PER DEVICE DATA OFFSETS
;
SD_DEV .EQU 0 ; OFFSET OF DEVICE NUMBER (BYTE)
SD_STAT .EQU 1 ; LAST STATUS (BYTE)
SD_TYPE .EQU 2 ; DEVICE TYPE (BYTE)
SD_FLAGS .EQU 3 ; FLAG BITS (BYTE)
SD_MEDCAP .EQU 4 ; MEDIA CAPACITY (DWORD)
SD_LBA .EQU 8 ; OFFSET OF LBA (DWORD)
;
SD_CFGTBL:
; DEVICE 0, PRIMARY MASTER
.DB 0 ; DRIVER DEVICE NUMBER
.DB 0 ; DEVICE STATUS
.DB 0 ; DEVICE TYPE
.DB 0 ; FLAGS BYTE
.DW 0,0 ; DEVICE CAPACITY
.DW 0,0 ; CURRENT LBA
#IF (SD_DEVCNT >= 2)
; DEVICE 1, PRIMARY SLAVE
.DB 1 ; DRIVER DEVICE NUMBER
.DB 0 ; DEVICE STATUS
.DB 0 ; DEVICE TYPE
.DB 0 ; FLAGS BYTE
.DW 0,0 ; DEVICE CAPACITY
.DW 0,0 ; CURRENT LBA
#ENDIF
;
; MACRO TO RETURN POINTER TO FIELD WITHIN UNIT DATA
#IF ($ - SD_CFGTBL) != (SD_DEVCNT * SD_CFGSIZ)
.ECHO "*** INVALID SD CONFIG TABLE ***\n"
#ENDIF
;
#DEFINE SD_DPTR(FIELD) CALL SD_DPTRIMP \ .DB FIELD
.DB $FF ; END MARKER
;
;=============================================================================
; INITIALIZATION ENTRY POINT
@ -216,29 +242,6 @@ SD_CAPACITY .EQU 2 ; CARD CAPACITY (1 DWORD/4 BYTES)
SD_INIT:
CALL NEWLINE ; FORMATTING
PRTS("SD:$")
CALL SD_PROBE ; CHECK FOR HARDWARE
JR Z,SD_INIT00 ; CONTINUE IF PRESENT
;
; HARDWARE NOT PRESENT
PRTS(" NOT PRESENT$")
OR $FF ; SIGNAL FAILURE
RET
;
SD_INIT00:
;
; SETUP THE DISPATCH TABLE ENTRIES
;
LD B,SD_UNITCNT ; LOOP CONTROL
LD C,0 ; PHYSICAL UNIT INDEX
SD_INIT0:
PUSH BC ; SAVE LOOP CONTROL
LD B,C ; PHYSICAL UNIT
LD C,DIODEV_SD ; DEVICE TYPE
LD DE,0 ; UNIT DATA BLOB ADDRESS
CALL DIO_ADDENT ; ADD ENTRY, BC IS NOT DESTROYED
POP BC ; RESTORE LOOP CONTROL
INC C ; NEXT PHYSICAL UNIT
DJNZ SD_INIT0 ; LOOP UNTIL DONE
;
#IF (SDMODE == SDMODE_JUHA)
PRTS(" MODE=JUHA$")
@ -313,32 +316,53 @@ SD_INIT0:
CALL PRTHEXBYTE
#ENDIF
;
PRTS(" UNITS=$")
LD A,SD_UNITCNT
CALL SD_PROBE ; CHECK FOR HARDWARE
JR Z,SD_INIT00 ; CONTINUE IF PRESENT
;
; HARDWARE NOT PRESENT
PRTS(" NOT PRESENT$")
OR $FF ; SIGNAL FAILURE
RET
;
SD_INIT00:
;
; SETUP THE DISPATCH TABLE ENTRIES
;
PRTS(" DEVICES=$")
LD A,SD_DEVCNT
CALL PRTDECB
;
; SETUP THE DISPATCH TABLE ENTRIES
;
LD B,SD_DEVCNT ; LOOP CONTROL
LD IY,SD_CFGTBL ; START OF CFG TABLE
SD_INIT0:
PUSH BC ; SAVE LOOP CONTROL
LD BC,SD_FNTBL ; BC := FUNC TABLE ADR
PUSH IY ; CFG ENTRY POINTER
POP DE ; COPY TO DE
CALL DIO_ADDENT ; ADD ENTRY, BC IS NOT DESTROYED
LD BC,SD_CFGSIZ ; SIZE OF CFG ENTRY
ADD IY,BC ; BUMP IY TO NEXT ENTRY
POP BC ; RESTORE BC
DJNZ SD_INIT0 ; LOOP AS NEEDED
;
; INITIALIZE THE SD INTERFACE NOW
CALL SD_SETUP ; DO HARDWARE SETUP/INIT
RET NZ ; ABORT ON ERROR
;
; CLEAR OUT ALL DATA (FOR ALL UNITS)
LD HL,SD_UNITDATA
LD BC,SD_DATALEN
XOR A
CALL FILL
;
; INITIALIZE INDIVIDUAL UNIT(S)
LD B,SD_UNITCNT ; INIT LOOP COUNTER TO UNIT COUNT
LD C,0 ; INIT UNIT INDEX TO ZERO
; INITIALIZE INDIVIDUAL UNIT(S) AND DISPLAY DEVICE INVENTORY
LD B,SD_DEVCNT ; INIT LOOP COUNTER TO DEVICE COUNT
LD IY,SD_CFGTBL ; START OF CFG TABLE
SD_INIT1:
PUSH BC ; SAVE LOOP COUNTER/INDEX
LD A,C ; UNIT ID TO A
CALL SD_INITUNIT ; INITIALIZE IT
#IF (SDTRACE < 2)
CALL NZ,SD_PRTSTAT ; IF ERROR, SHOW IT
#ENDIF
POP BC ; RESTORE LOOP COUNTER/INDEX
INC C ; INCREMENT UNIT INDEX
LD BC,SD_CFGSIZ ; SIZE OF CFG ENTRY
ADD IY,BC ; BUMP IY TO NEXT ENTRY
POP BC ; RESTORE LOOP CONTROL
DJNZ SD_INIT1 ; DECREMENT LOOP COUNTER AND LOOP AS NEEDED
;
RET ; DONE
@ -346,8 +370,6 @@ SD_INIT1:
; INITIALIZE UNIT DESIGNATED IN ACCUM
;
SD_INITUNIT
LD (SD_UNIT),A ; SET CURRENT UNIT
;
CALL SD_SELUNIT ; SELECT UNIT
RET NZ ; ABORT ON ERROR
;
@ -357,9 +379,7 @@ SD_INITUNIT
CALL SD_PRTPREFIX
;
; PRINT CARD TYPE
PRTS(" TYPE=$")
SD_DPTR(SD_TYPE) ; SET HL TO ADR OF CARD TYPE, TRASHES AF
LD A,(HL)
LD A,(IY+SD_TYPE) ; GET CARD TYPE VALUE TO A
LD DE,SD_STR_TYPEMMC
CP SD_TYPEMMC
JR Z,SD_INITUNIT1
@ -406,23 +426,25 @@ SD_INITUNIT2:
INC HL ; POINT TO NEXT BYTE
DJNZ SD_INITUNIT2 ; LOOP FOR ALL 5 BYTES
;
PRTS(" BLOCKS=0x$") ; LABEL
SD_DPTR(SD_CAPACITY) ; SET HL TO ADR OF CARD CAPACITY, TRASHES AF
CALL LD32 ; GET THE VALUE
CALL PRTHEX32 ; PRINT IT
;
; CONVERT VALUE TO MEGABYTES AND PRINT IT
LD B,11 ; SHIFT 11 BITS TO CONVERT FROM
CALL SRL32 ; ... 512 BYTE BLOCKS TO MEGABYTES
;
PRTS(" SIZE=$") ; PRINT LABEL
CALL PRTDEC ; PRINT VALUE
; PRINT STORAGE CAPACITY (BLOCK COUNT)
PRTS(" BLOCKS=0x$") ; PRINT FIELD LABEL
LD A,SD_MEDCAP ; OFFSET TO CAPACITY FIELD
CALL LDHLIYA ; HL := IY + A, REG A TRASHED
CALL LD32 ; GET THE CAPACITY VALUE
CALL PRTHEX32 ; PRINT HEX VALUE
;
; PRINT STORAGE SIZE IN MB
PRTS(" SIZE=$") ; PRINT FIELD LABEL
LD B,11 ; 11 BIT SHIFT TO CONVERT BLOCKS --> MB
CALL SRL32 ; RIGHT SHIFT
CALL PRTDEC ; PRINT LOW WORD IN DECIMAL (HIGH WORD DISCARDED)
PRTS("MB$") ; PRINT SUFFIX
;
; CHECK FOR WRITE PROTECT AND NOTIFY USER IF SO
CALL SD_CHKWP ; WRITE PROTECTED?
RET Z ; IF NOT, DONE
PRTS(" WP$") ; NOTIFY USER
;
RET ; DONE
;
;----------------------------------------------------------------------
@ -457,48 +479,30 @@ SD_PROBE:
RET ; AND RETURN
;
;=============================================================================
; FUNCTION DISPATCH ENTRY POINT
; DRIVER FUNCTION TABLE
;=============================================================================
;
SD_DISPATCH:
; VERIFY AND SAVE THE TARGET DEVICE/UNIT LOCALLY IN DRIVER
LD A,C ; DEVICE/UNIT FROM C
AND $0F ; ISOLATE UNIT NUM
CP SD_UNITCNT
CALL NC,PANIC ; PANIC IF TOO HIGH
LD (SD_UNIT),A ; SAVE IT
;
; DISPATCH ACCORDING TO DISK SUB-FUNCTION
LD A,B ; GET REQUESTED FUNCTION
AND $0F ; ISOLATE SUB-FUNCTION
JP Z,SD_STATUS ; SUB-FUNC 0: STATUS
DEC A
JP Z,SD_RESET ; SUB-FUNC 1: RESET
DEC A
JP Z,SD_SEEK ; SUB-FUNC 2: SEEK
DEC A
JP Z,SD_READ ; SUB-FUNC 3: READ SECTORS
DEC A
JP Z,SD_WRITE ; SUB-FUNC 4: WRITE SECTORS
DEC A
JP Z,SD_VERIFY ; SUB-FUNC 5: VERIFY SECTORS
DEC A
JP Z,SD_FORMAT ; SUB-FUNC 6: FORMAT TRACK
DEC A
JP Z,SD_DEVICE ; SUB-FUNC 7: DEVICE REPORT
DEC A
JP Z,SD_MEDIA ; SUB-FUNC 8: MEDIA REPORT
DEC A
JP Z,SD_DEFMED ; SUB-FUNC 9: DEFINE MEDIA
DEC A
JP Z,SD_CAP ; SUB-FUNC 10: REPORT CAPACITY
DEC A
JP Z,SD_GEOM ; SUB-FUNC 11: REPORT GEOMETRY
SD_FNTBL:
.DW SD_STATUS
.DW SD_RESET
.DW SD_SEEK
.DW SD_READ
.DW SD_WRITE
.DW SD_VERIFY
.DW SD_FORMAT
.DW SD_DEVICE
.DW SD_MEDIA
.DW SD_DEFMED
.DW SD_CAP
.DW SD_GEOM
#IF (($ - SD_FNTBL) != (DIO_FNCNT * 2))
.ECHO "*** INVALID IDE FUNCTION TABLE ***\n"
#ENDIF
;
SD_VERIFY:
SD_FORMAT:
SD_DEFMED:
CALL PANIC ; INVALID SUB-FUNCTION
CALL PANIC ; INVALID SUB-FUNCTION
;
;
;
@ -516,9 +520,11 @@ SD_WRITE:
;
SD_IO:
LD (SD_CMDVAL),A ; SAVE THE SD CARD COMMAND
LD (SD_DSKBUF),HL ; SAVE DISK BUFFER ADDRESS
LD A,E ; GET BLOCK COUNT REQUESTED
LD (SD_BLKCNT),A ; ... AND SAVE IT
LD (SD_DSKBUF),HL ; SAVE DISK BUFFER ADDRESS
OR A ; SET FLAGS
RET Z ; ZERO SECTOR I/O, RETURN W/ E=0 & A=0
#IF (IDETRACE == 1)
LD HL,SD_PRTERR ; SET UP SD_PRTERR
PUSH HL ; ... TO FILTER ALL EXITS
@ -541,12 +547,11 @@ SD_IO1:
LD C,A ; ... AND PUT IN C
CALL SD_SECTIO ; DO SECTOR I/O
JR NZ,SD_IO2 ; IF ERROR, SKIP INCREMENT
LD HL,HSTLBA ; POINT TO 32-BIT CURRENT LBA
PUSH HL ; SAVE POINTER
CALL LD32 ; LOAD 32-BIT LBA INTO DE:HL
CALL INC32 ; INCREMENT LBA FOR NEXT I/O
POP BC ; RECOVER LBA POINTER INTO BC
CALL ST32 ; AND SAVE IT
; INCREMENT LBA
LD A,SD_LBA ; LBA OFFSET
CALL LDHLIYA ; HL := IY + A, REG A TRASHED
CALL INC32HL ; INCREMENT THE VALUE
; INCREMENT DMA
LD HL,SD_DSKBUF+1 ; POINT TO MSB OF BUFFER ADR
INC (HL) ; BUMP DMA BY
INC (HL) ; ... 512 BYTES
@ -565,9 +570,8 @@ SD_IO3:
;
;
SD_STATUS:
; RETURN UNIT STATUS
SD_DPTR(SD_STAT) ; HL := ADR OF STATUS, AF TRASHED
LD A,(HL) ; GET STATUS OF SELECTED UNIT
; RETURN DEVICE STATUS
LD A,(IY+SD_STAT) ; GET STATUS OF SELECTED DEVICE
OR A ; SET FLAGS
RET ; AND RETURN
;
@ -586,10 +590,10 @@ SD_RESET:
;
;
SD_DEVICE:
LD D,DIODEV_SD ; D := DEVICE TYPE
LD E,C ; E := PHYSICAL UNIT
LD C,%01010000 ; C := ATTRIBUTES, REMOVABLE, SD CARD
XOR A ; SIGNAL SUCCESS
LD D,DIODEV_SD ; D := DEVICE TYPE
LD E,(IY+SD_DEV) ; E := PHYSICAL DEVICE NUMBER
LD C,%01010000 ; C := ATTRIBUTES, REMOVABLE, SD CARD
XOR A ; SIGNAL SUCCESS
RET
;
;
@ -599,10 +603,10 @@ SD_MEDIA:
OR A ; SET FLAGS
JR Z,SD_MEDIA2 ; JUST REPORT CURRENT STATUS AND MEDIA
;
SD_DPTR(SD_STAT) ; POINT TO UNIT STATUS
LD A,(HL) ; GET STATUS
; GET CURRENT STATUS
LD A,(IY+SD_STAT) ; GET STATUS
OR A ; SET FLAGS
JR NZ,SD_MEDIA1 ; ERROR ACTIVE, TO RIGHT TO RESET
JR NZ,SD_MEDIA1 ; ERROR ACTIVE, GO RIGHT TO RESET
;
; USE SEND_CSD TO CHECK CARD
CALL SD_SELUNIT ; SET CUR UNIT
@ -620,8 +624,7 @@ SD_MEDIA1:
CALL SD_RESET ; RESET CARD
;
SD_MEDIA2:
SD_DPTR(SD_STAT) ; HL := ADR OF STATUS, AF TRASHED
LD A,(HL) ; GET STATUS OF SELECTED UNIT
LD A,(IY+SD_STAT) ; GET STATUS
OR A ; SET FLAGS
LD D,0 ; NO MEDIA CHANGE DETECTED
LD E,MID_HD ; ASSUME WE ARE OK
@ -636,19 +639,21 @@ SD_SEEK:
BIT 7,D ; CHECK FOR LBA FLAG
CALL Z,HB_CHS2LBA ; CLEAR MEANS CHS, CONVERT TO LBA
RES 7,D ; CLEAR FLAG REGARDLESS (DOES NO HARM IF ALREADY LBA)
LD BC,HSTLBA ; POINT TO LBA STORAGE
CALL ST32 ; SAVE LBA ADDRESS
LD (IY+SD_LBA+0),L ; SAVE NEW LBA
LD (IY+SD_LBA+1),H ; ...
LD (IY+SD_LBA+2),E ; ...
LD (IY+SD_LBA+3),D ; ...
XOR A ; SIGNAL SUCCESS
RET ; AND RETURN
;
;
;
SD_CAP:
SD_DPTR(SD_STAT) ; POINT TO UNIT STATUS
LD A,(HL) ; GET STATUS
LD A,(IY+SD_STAT) ; GET STATUS
PUSH AF ; SAVE IT
SD_DPTR(SD_CAPACITY) ; POINT HL TO CAPACITY OF CUR UNIT
CALL LD32 ; GET THE CURRENT CAPACITY DO DE:HL
LD A,SD_MEDCAP ; OFFSET TO CAPACITY FIELD
CALL LDHLIYA ; HL := IY + A, REG A TRASHED
CALL LD32 ; GET THE CURRENT CAPACITY INTO DE:HL
LD BC,512 ; 512 BYTES PER BLOCK
POP AF ; RECOVER STATUS
OR A ; SET FLAGS
@ -674,11 +679,11 @@ SD_GEOM:
;
SD_INITCARD:
;
; CLEAR OUT UNIT SPECIFIC DATA
SD_DPTR(0) ; SET HL TO START OF UNIT DATA
LD BC,SD_UNITDATALEN
XOR A
CALL FILL
;; CLEAR OUT UNIT SPECIFIC DATA
;SD_DPTR(0) ; SET HL TO START OF UNIT DATA
;LD BC,SD_UNITDATALEN
;XOR A
;CALL FILL
;
CALL SD_CHKCD ; CHECK CARD DETECT
JP Z,SD_NOMEDIA ; Z=NO MEDIA, HANDLE IF SO
@ -697,9 +702,7 @@ SD_INITCARD1:
RET NZ ; ABORT IF FAILED
;
SD_INITCARD2:
SD_DPTR(SD_TYPE) ; SET HL TO ADR OF CARD TYPE, TRASHES AF
LD A,SD_TYPESDSC ; ASSUME SDSC CARD TYPE
LD (HL),A ; SAVE IT
LD (IY+SD_TYPE),SD_TYPESDSC ; ASSUME SDSC CARD TYPE
;
; CMD8 IS REQUIRED FOR V2 CARDS. FAILURE HERE IS OK AND
; JUST MEANS THAT IT IS A V1 CARD
@ -822,8 +825,7 @@ SD_INITCARD4A:
LD C,SD_TYPESDXC ; OTHERWISE, THIS IS SDXC CARD
;
SD_INITCARD5:
SD_DPTR(SD_TYPE) ; SET HL TO ADR OF CARD TYPE, TRASHES AF
LD (HL),C ; SAVE IT
LD (IY+SD_TYPE),C ; SAVE CARD TYPE
#IF (SDTRACE >= 3)
CALL SD_PRTPREFIX
@ -832,7 +834,7 @@ SD_INITCARD5:
LD A,C
CALL PRTHEXBYTE
#ENDIF
;
; SET OUR DESIRED BLOCK LENGTH (512 BYTES)
LD A,SD_CMD_SET_BLOCKLEN ; SET_BLOCKLEN
CALL SD_INITCMD ; SETUP COMMAND BUFFER
@ -874,8 +876,7 @@ SD_INITCARD5:
#ENDIF
;
; GET SIZE OF DEVICE IN BLOCKS
SD_DPTR(SD_TYPE) ; SET HL TO ADR OF CARD TYPE, TRASHES AF
LD A,(HL) ; GET CARD TYPE
LD A,(IY+SD_TYPE) ; GET CARD TYPE
OR A ; SET FLAGS
CALL Z,PANIC ; PANIC IF CARD TYPE UNKNOWN
CP SD_TYPESDHC ; COMPARE TO SDHC (V2)
@ -949,19 +950,19 @@ SD_INITCARD8: ; GET SIZE FOR V2 CARD
CALL SLA32 ; SHIFT THE 32 BIT VALUE
JR SD_INITCARD9 ; CONTINUE
;
SD_INITCARD9: ; COMMON CODE TO RECORD RESULTANT SIZE (IN DE:HL)
; SAVE DERIVED CAPACITY VALUE
SD_INITCARD9:
; SAVE DERIVED CAPACITY VALUE IN DE:HL
PUSH HL ; SAVE HL
SD_DPTR(SD_CAPACITY) ; SET HL TO ADR OF CARD CAPACITY, TRASHES AF
LD A,SD_MEDCAP ; OFFSET TO CAPACITY FIELD
CALL LDHLIYA ; HL := IY + A, REG A TRASHED
PUSH HL ; MOVE ADDRESS
POP BC ; ... TO BC
POP HL ; RECOVER HL
CALL ST32 ; SAVE THE CAPACITY VALUE (DWORD)
;
; RESET CARD STATUS TO 0 (OK)
SD_DPTR(SD_STAT) ; HL := ADR OF STATUS, AF TRASHED
XOR A ; A := 0 (STATUS = OK)
LD (HL),A ; SAVE IT
LD (IY+SD_STAT),A ; SAVE IT
;
RET ; RETURN, A=0, Z SET
@ -1004,23 +1005,22 @@ SD_SECTIO3:
; CHECK THE SD CARD, ATTEMPT TO REINITIALIZE IF NEEDED
;
SD_CHKCARD:
; FIX: NEED TO CHECK FOR CARD DETECT HERE AND
; FIX: NEED TO CHECK CARD DETECT HERE AND
; HANDLE AS ERROR.
;
SD_DPTR(SD_STAT) ; HL = ADR OF STATUS, AF TRASHED
LD A,(HL) ; GET CURRENT STATUS
LD A,(IY+SD_STAT) ; GET CURRENT STATUS
OR A ; SET FLAGS
RET Z ; RETURN WITH A=0 AND Z SET
JP SD_INITCARD ; OTHERWISE INIT CARD
;
; CONVERT LBA ADDRESS IN HSTLBA TO CARD SPECIFIC ADDRESS IN CMD PARMS
; CONVERT LBA ADDRESS TO CARD SPECIFIC ADDRESS IN CMD PARMS
; V1 CARDS REQUIRE BYTE ADDRESSING, SO A TRANSLATION IS DONE IN THAT CASE
;
SD_SETADDR:
SD_DPTR(SD_TYPE) ; SET HL TO ADR OF CARD TYPE, TRASHES AF
LD A,(HL) ; GET CARD TYPE
LD A,(IY+SD_TYPE) ; GET CARD TYPE
PUSH AF ; SAVE IT
LD HL,HSTLBA ; POINT TO INCOMING LBA VALUE
LD A,SD_LBA ; OFFSET OF LBA VALUE
CALL LDHLIYA ; HL := IY + A, REG A TRASHED
CALL LD32 ; LOAD IT TO DE:HL, AF IS TRASHED
POP AF ; GET CARD TYPE BACK
CP SD_TYPESDHC ; IS IT V2 OR BETTER?
@ -1334,10 +1334,7 @@ SD_OPRMSK .EQU (SD_CS | SD_CLK | SD_DI)
; UNIT IS SPECIFIED IN A
;
SD_SELUNIT:
LD A,(SD_UNIT)
;
CP SD_UNITCNT ; CHECK VALIDITY (EXCEED UNIT COUNT?)
JP NC,SD_INVUNIT ; HANDLE INVALID UNIT
LD A,(IY+SD_DEV) ; GET CURRENT DEVICE
;
#IF (SDMODE == SDMODE_DSD)
; SELECT REQUESTED UNIT
@ -1538,12 +1535,7 @@ SD_WRTPROT:
JR SD_ERR2 ; DO NOT UPDATE UNIT STATUS!
;
SD_ERR:
PUSH HL ; IS THIS NEEDED?
PUSH AF ; SAVE INCOMING STATUS
SD_DPTR(SD_STAT) ; GET STATUS ADR IN HL, AF TRASHED
POP AF ; RESTORE INCOMING STATUS
LD (HL),A ; UPDATE STATUS
POP HL ; IS THIS NEEDED?
LD (IY+SD_STAT),A ; SAVE NEW STATUS
SD_ERR2:
#IF (SDTRACE >= 2)
CALL SD_PRTSTAT
@ -1659,14 +1651,14 @@ SD_REGDUMP1:
; PRINT DIAGNONSTIC PREFIX
;
SD_PRTPREFIX:
PUSH AF
CALL NEWLINE
PRTS("SD$")
PUSH AF
LD A,(SD_UNIT)
LD A,(IY+SD_DEV) ; GET CURRENT DEVICE NUM
ADD A,'0'
CALL COUT
POP AF
CALL PC_COLON
POP AF
RET
;
; DISPLAY COMMAND, LOW ORDER WORD OF PARMS, AND RC
@ -1710,11 +1702,11 @@ SD_STR_STRDYTO .TEXT "READY TIMEOUT$"
SD_STR_STINITTO .TEXT "INITIALIZATION TIMEOUT$"
SD_STR_STCMDTO .TEXT "COMMAND TIMEOUT$"
SD_STR_STCMDERR .TEXT "COMMAND ERROR$"
SD_STR_STDATAERR .TEXT "DATA ERROR$"
SD_STR_STDATAERR .TEXT "DATA ERROR$"
SD_STR_STDATATO .TEXT "DATA TIMEOUT$"
SD_STR_STCRCERR .TEXT "CRC ERROR$"
SD_STR_STNOMEDIA .TEXT "NO MEDIA$"
SD_STR_STWRTPROT .TEXT "WRITE PROTECTED$"
SD_STR_STNOMEDIA .TEXT "NO MEDIA$"
SD_STR_STWRTPROT .TEXT "WRITE PROTECTED$"
SD_STR_STUNK .TEXT "UNKNOWN$"
SD_STR_TYPEUNK .TEXT "UNK$"
SD_STR_TYPEMMC .TEXT "MMC$"
@ -1744,37 +1736,12 @@ SD_CMDCRC .DB 0 ; CRC
SD_RC .DB 0 ; RETURN CODE FROM CMD
SD_TOK .DB 0 ; TOKEN FROM DATA XFR
;
SD_UNIT .DB 0 ; ACTIVE UNIT, DEFAULT TO ZERO
SD_DSKBUF .DW 0 ; ACTIVE DISK BUFFER
;
; UNIT SPECIFIC DATA STORAGE
;
SD_UNITDATA .FILL SD_UNITCNT * 8, 0 ; PER UNIT DATA, 8 BYTES
SD_DATALEN .EQU $ - SD_UNITDATA ; LENGTH OF ENTIRE DATA STORAGE FOR ALL UNITS
SD_UNITDATALEN .EQU SD_DATALEN / SD_UNITCNT ; LENGTH OF PER UNIT DATA
SD_DSKBUF .DW 0 ; ADR OF ACTIVE DISK BUFFER
;
;=============================================================================
; HELPER ROUTINES
;=============================================================================
;
; IMPLEMENTATION FOR MACRO SD_DPTR
; SET HL TO ADDRESS OF FIELD WITHIN PER UNIT DATA
; HL := ADR OF SD_UNITDATA[(SD_UNIT)][(SP)]
; ENTER WITH TOP-OF-STACK = ADDRESS OF FIELD OFFSET
; AF IS TRASHED
;
SD_DPTRIMP:
LD HL,SD_UNITDATA ; POINT TO START OF UNIT DATA ARRAY
LD A,(SD_UNIT) ; GET CURRENT UNIT NUM
RLCA ; MULTIPLY BY
RLCA ; ... SIZE OF PER UNIT DATA
RLCA ; ... (8 BYTES)
EX (SP),HL ; GET PTR TO FIELD OFFSET VALUE FROM TOS
ADD A,(HL) ; ADD IT TO START OF UNIT DATA IN ACCUM
INC HL ; BUMP HL TO NEXT REAL INSTRUCTION
EX (SP),HL ; AND PUT IT BACK ON STACK, HL GETS ADR OF START OF DATA
JP ADDHLA ; CALC FINAL ADR IN HL AND RETURN
;
; MSB<-->LSB MIRROR BITS IN A, RESULT IN C
;
MIRROR:

5
Source/HBIOS/std.asm

@ -35,6 +35,11 @@ PLT_MK4 .EQU 5 ; MARK IV
PLT_UNA .EQU 6 ; UNA BIOS
PLT_RC .EQU 7 ; RC2014
;
; FOUNCTION GROUP FUNCTION COUNTS
;
CIO_FNCNT .EQU 7
DIO_FNCNT .EQU 12
;
#IF (PLATFORM != PLT_UNA)
#INCLUDE "hbios.inc"
#ENDIF

10
Source/HBIOS/util.asm

@ -385,6 +385,16 @@ _REGDMP:
CALL PC_COLON
LD BC,(REGDMP_SP)
CALL PRTHEXWORD ; SP
CALL PC_COLON
PUSH IX
POP BC
CALL PRTHEXWORD ; IX
CALL PC_COLON
PUSH IY
POP BC
CALL PRTHEXWORD ; IY
CALL PC_RBKT
CALL PC_SPACE

773
Source/HBIOS/vga_old.asm

@ -1,773 +0,0 @@
;======================================================================
; VGA DRIVER FOR RBC PROJECT
;
; WRITTEN BY: WAYNE WARTHEN -- 5/29/2017
;======================================================================
;
; TODO:
;
;======================================================================
; VGA DRIVER - CONSTANTS
;======================================================================
;
VGA_BASE .EQU $E0
;
VGA_KBDDATA .EQU VGA_BASE + $00 ; KBD CTLR DATA PORT
VGA_KBDST .EQU VGA_BASE + $01 ; KBD CTLR STATUS/CMD PORT
VGA_REG .EQU VGA_BASE + $02 ; SELECT CRTC REGISTER
VGA_DATA .EQU VGA_BASE + $03 ; READ/WRITE CRTC DATA
VGA_CFG .EQU VGA_BASE + $04 ; VGA3 BOARD CFG REGISTER
VGA_HI .EQU VGA_BASE + $05 ; BOARD RAM HI ADDRESS
VGA_LO .EQU VGA_BASE + $06 ; BOARD RAM LO ADDRESS
VGA_DAT .EQU VGA_BASE + $07 ; BOARD RAM BYTE R/W
;
VGA_ROWS .EQU 25
VGA_COLS .EQU 80
;
#DEFINE DEFREGS REGS_VGA
;
TERMENABLE .SET TRUE ; INCLUDE TERMINAL PSEUDODEVICE DRIVER
;
;======================================================================
; VGA DRIVER - INITIALIZATION
;======================================================================
;
VGA_INIT:
LD IY,VGA_IDAT ; POINTER TO INSTANCE DATA
;
CALL NEWLINE ; FORMATTING
PRTS("VGA: IO=0x$")
LD A,VGA_REG
CALL PRTHEXBYTE
CALL VGA_PROBE ; CHECK FOR HW PRESENCE
JR Z,VGA_INIT1 ; CONTINUE IF HW PRESENT
;
; HARDWARE NOT PRESENT
PRTS(" NOT PRESENT$")
OR $FF ; SIGNAL FAILURE
RET
;
VGA_INIT1:
; DISPLAY CONSOLE DIMENSIONS
LD A,VGA_COLS
CALL PC_SPACE
CALL PRTDECB
LD A,'X'
CALL COUT
LD A,VGA_ROWS
CALL PRTDECB
PRTS(" TEXT$")
; HARDWARE INITIALIZATION
CALL VGA_CRTINIT ; SETUP THE VGA CHIP REGISTERS
CALL VGA_LOADFONT ; LOAD FONT DATA FROM ROM TO VGA STRORAGE
CALL VGA_VDARES
CALL KBD_INIT ; INITIALIZE KEYBOARD DRIVER
; ADD OURSELVES TO VDA DISPATCH TABLE
LD BC,VGA_DISPATCH ; BC := DISPATCH ADDRESS
LD DE,VGA_IDAT ; DE := VGA INSTANCE DATA PTR
CALL VDA_ADDENT ; ADD ENTRY, A := UNIT ASSIGNED
; INITIALIZE EMULATION
LD C,A ; C := ASSIGNED VIDEO DEVICE NUM
LD DE,VGA_DISPATCH ; DE := DISPATCH ADDRESS
LD HL,VGA_IDAT ; HL := VGA INSTANCE DATA PTR
CALL TERM_ATTACH ; DO IT
XOR A ; SIGNAL SUCCESS
RET
;
;======================================================================
; VGA DRIVER - VIDEO DISPLAY ADAPTER (VDA) DISPATCHER AND FUNCTIONS
;======================================================================
;
VGA_DISPATCH:
LD A,B ; GET REQUESTED FUNCTION
AND $0F ; ISOLATE SUB-FUNCTION
JP Z,VGA_VDAINI ; $40
DEC A
JP Z,VGA_VDAQRY ; $41
DEC A
JP Z,VGA_VDARES ; $42
DEC A
JP Z,VGA_VDADEV ; $43
DEC A
JP Z,VGA_VDASCS ; $44
DEC A
JP Z,VGA_VDASCP ; $45
DEC A
JP Z,VGA_VDASAT ; $46
DEC A
JP Z,VGA_VDASCO ; $47
DEC A
JP Z,VGA_VDAWRC ; $48
DEC A
JP Z,VGA_VDAFIL ; $49
DEC A
JP Z,VGA_VDACPY ; $4A
DEC A
JP Z,VGA_VDASCR ; $4B
DEC A
JP Z,KBD_STAT ; $4C
DEC A
JP Z,KBD_FLUSH ; $4D
DEC A
JP Z,KBD_READ ; $4E
CALL PANIC
VGA_VDAINI:
; RESET VDA
; CURRENTLY IGNORES VIDEO MODE AND BITMAP DATA
CALL VGA_VDARES ; RESET VDA
XOR A ; SIGNAL SUCCESS
RET
VGA_VDAQRY:
LD C,$00 ; MODE ZERO IS ALL WE KNOW
LD D,VGA_ROWS ; ROWS
LD E,VGA_COLS ; COLS
LD HL,0 ; EXTRACTION OF CURRENT BITMAP DATA NOT SUPPORTED YET
XOR A ; SIGNAL SUCCESS
RET
VGA_VDARES:
LD A,$07 ; ATTRIBUTE IS STANDARD WHITE ON BLACK
LD (VGA_ATTR),A ; SAVE IT
XOR A ; ZERO (REVEVERSE, UNDERLINE, BLINK)
LD (VGA_RUB),A ; SAVE IT
LD DE,0 ; ROW = 0, COL = 0
CALL VGA_XY ; SEND CURSOR TO TOP LEFT
LD A,' ' ; BLANK THE SCREEN
LD DE,$800 ; FILL ENTIRE BUFFER
CALL VGA_FILL ; DO IT
LD DE,0 ; ROW = 0, COL = 0
CALL VGA_XY ; SEND CURSOR TO TOP LEFT
LD HL,$0404 ; SET VIDEO ENABLE BIT
CALL VGA_SETCFG ; DO IT
XOR A
RET
VGA_VDADEV:
LD D,VDADEV_VGA ; D := DEVICE TYPE
LD E,0 ; E := PHYSICAL UNIT IS ALWAYS ZERO
XOR A ; SIGNAL SUCCESS
RET
VGA_VDASCS:
CALL PANIC ; NOT IMPLEMENTED (YET)
VGA_VDASCP:
CALL VGA_XY ; SET CURSOR POSITION
XOR A ; SIGNAL SUCCESS
RET
VGA_VDASAT:
; INCOMING IS: -----RUB (R=REVERSE, U=UNDERLINE, B=BLINK)
;
; JUST SAVE THE VALUE AND FALL THROUGH. ONLY REVERSE IS
; SUPPORTED WHICH IS IMPLEMENTED BELOW.
LD A,E
LD (VGA_RUB),A ; SAVE IT
JR VGA_VDASCO2 ; IMPLEMENT SETTING
VGA_VDASCO:
; INCOMING IS: IBGRIBGR (I=INTENSITY, B=BLUE, G=GREEN, R=RED)
; TRANSFORM TO: -RGBIRGB (DISCARD INTENSITY BIT IN HIGH NIBBLE)
;
; A := INVERTED E, SO A IS RGBIRGBI (F/B)
LD B,8 ; DO 8 BITS
VGA_VDASCO1:
RRC E ; LOW BIT OF E ROTATED RIGHT INTO CF
RLA ; CF ROTATED LEFT INTO LOW BIT OF A
DJNZ VGA_VDASCO1 ; DO FOR ALL 8 BITS
; LS A X 3 TO SWAP F/B BITS, SO A IS IRGBIRGB (B/F)
RLCA
RLCA
RLCA
; MASK FOR RELEVANT BITS, SO A IS 0R0B0R0B
AND %01010101
; SAVE A IN C AND SET A = E
LD C,A
LD A,E
; MASK FOR RELEVANT BITS, SO A IS 00G0I0G0
AND %00101010
; COMBINE WITH SAVED
OR E
; SAVE NEW ATTR VALUE
LD (VGA_ATTR),A ; AND SAVE THE RESULT
VGA_VDASCO2:
; CHECK FOR REVERSE VIDEO
LD A,(VGA_RUB) ; GET RUB SETTING
BIT 2,A ; REVERSE IS BIT 2
JR Z,VGA_VDASCO3 ; DONE IF REVERSE VID NOT SET
; IMPLEMENT REVERSE VIDEO
LD A,(VGA_ATTR) ; GET ATTRIBUTE
PUSH AF ; SAVE IT
AND %00001000 ; ISOLATE INTENSITY BIT
LD E,A ; SAVE IN E
POP AF ; GOT ATTR BACK
RLCA ; SWAP FG/BG COLORS
RLCA
RLCA
RLCA
AND %01110111 ; REMOVE HIGH BITS
OR E ; COMBINE WITH PREVIOUS INTENSITY BIT
LD (VGA_ATTR),A ; SAVE NEW VALUE
VGA_VDASCO3:
XOR A ; SIGNAL SUCCESS
RET
VGA_VDAWRC:
LD A,E ; CHARACTER TO WRITE GOES IN A
CALL VGA_PUTCHAR ; PUT IT ON THE SCREEN
XOR A ; SIGNAL SUCCESS
RET
VGA_VDAFIL:
LD A,E ; FILL CHARACTER GOES IN A
EX DE,HL ; FILL LENGTH GOES IN DE
CALL VGA_FILL ; DO THE FILL
XOR A ; SIGNAL SUCCESS
RET
VGA_VDACPY:
; LENGTH IN HL, SOURCE ROW/COL IN DE, DEST IS VGA_POS
; BLKCPY USES: HL=SOURCE, DE=DEST, BC=COUNT
PUSH HL ; SAVE LENGTH
CALL VGA_XY2IDX ; ROW/COL IN DE -> SOURCE ADR IN HL
POP BC ; RECOVER LENGTH IN BC
LD DE,(VGA_POS) ; PUT DEST IN DE
JP VGA_BLKCPY ; DO A BLOCK COPY
VGA_VDASCR:
LD A,E ; LOAD E INTO A
OR A ; SET FLAGS
RET Z ; IF ZERO, WE ARE DONE
PUSH DE ; SAVE E
JP M,VGA_VDASCR1 ; E IS NEGATIVE, REVERSE SCROLL
CALL VGA_SCROLL ; SCROLL FORWARD ONE LINE
POP DE ; RECOVER E
DEC E ; DECREMENT IT
JR VGA_VDASCR ; LOOP
VGA_VDASCR1:
CALL VGA_RSCROLL ; SCROLL REVERSE ONE LINE
POP DE ; RECOVER E
INC E ; INCREMENT IT
JR VGA_VDASCR ; LOOP
;
;======================================================================
; VGA DRIVER - PRIVATE DRIVER FUNCTIONS
;======================================================================
;
;----------------------------------------------------------------------
; SET BOARD CONFIGURATON REGISTER
; MASK IN H, VALUE IN L
;----------------------------------------------------------------------
;
VGA_SETCFG:
PUSH AF ; PRESERVE AF
LD A,H ; MASK IN ACCUM
CPL ; INVERT IT
LD H,A ; BACK TO H
LD A,(VGA_CFGV) ; GET CURRENT CONFIG VALUE
AND H ; RESET ALL TARGET BITS
OR L ; SET TARGET BITS
LD (VGA_CFGV),A ; SAVE NEW VALUE
OUT (VGA_CFG),A ; AND WRITE IT TO REGISTER
POP AF ; RESTORE AF
RET
;
;----------------------------------------------------------------------
; UPDATE CRTC REGISTERS
; VGA_REGWR WRITES VALUE IN A TO VDU REGISTER SPECIFIED IN C
;----------------------------------------------------------------------
;
VGA_REGWR:
PUSH AF ; SAVE VALUE TO WRITE
LD A,C ; SET A TO VGA REGISTER TO SELECT
OUT (VGA_REG),A ; WRITE IT TO SELECT THE REGISTER
POP AF ; RESTORE VALUE TO WRITE
OUT (VGA_DATA),A ; WRITE IT
RET
;
VGA_REGWRX:
LD A,H ; SETUP MSB TO WRITE
CALL VGA_REGWR ; DO IT
INC C ; NEXT CVDU REGISTER
LD A,L ; SETUP LSB TO WRITE
JR VGA_REGWR ; DO IT & RETURN
;
;----------------------------------------------------------------------
; READ CRTC REGISTERS
; VGA_REGRD READS VDU REGISTER SPECIFIED IN C AND RETURNS VALUE IN A
;----------------------------------------------------------------------
;
VGA_REGRD:
LD A,C ; SET A TO VGA REGISTER TO SELECT
OUT (VGA_REG),A ; WRITE IT TO SELECT THE REGISTER
IN A,(VGA_DATA) ; READ IT
RET
;
VGA_REGRDX:
CALL VGA_REGRD ; GET VALUE FROM REGISTER IN C
LD H,A ; SAVE IN H
INC C ; BUMP TO NEXT REGISTER OF PAIR
CALL VGA_REGRD ; READ THE VALUE
LD L,A ; SAVE IT IN L
RET
;
;----------------------------------------------------------------------
; WRITE VIDEO RAM
; VGA_MEMWR WRITES VALUE IN A TO ADDRESS IN DE
; VGA_MEMWRX WRITES VALUE IN HL TO ADDRESS IN DE
;----------------------------------------------------------------------
;
VGA_MEMWR:
LD C,VGA_HI
OUT (C),D
INC C
OUT (C),E
INC C
OUT (C),A
RET
;
VGA_MEMWRX:
LD C,VGA_HI
OUT (C),D
INC C
OUT (C),E
INC C
OUT (C),H
INC E
DEC C
OUT (C),E
INC C
OUT (C),L
DEC E
RET
;
;----------------------------------------------------------------------
; READ VIDEO RAM
; VGA_MEMRD READS VALUE IN DE TO A
; VGA_MEMRDX READS VALUE IN DE TO HL
;----------------------------------------------------------------------
;
VGA_MEMRD:
LD C,VGA_HI
OUT (C),D
INC C
OUT (C),E
INC C
IN A,(C)
RET
;
VGA_MEMRDX:
LD C,VGA_HI
OUT (C),D
INC C
OUT (C),E
INC C
IN H,(C)
INC E
DEC C
OUT (C),E
INC C
IN L,(C)
DEC E
RET
;
;----------------------------------------------------------------------
; PROBE FOR VGA HARDWARE
;----------------------------------------------------------------------
;
; ON RETURN, ZF SET INDICATES HARDWARE FOUND
;
VGA_PROBE:
LD DE,0 ; POINT TO FIRST BYTE OF VRAM
LD A,$A5 ; INITIAL TEST VALUE
LD B,A ; SAVE IN B
CALL VGA_MEMWR ; WRITE IT
INC E ; NEXT BYTE OF VRAM
CPL ; INVERT TEST VALUE
CALL VGA_MEMWR ; WRITE IT
DEC E ; BACK TO FIRST BYTE OF VRAM
CALL VGA_MEMRD ; READ IT
CP B ; CHECK FOR TEST VALUE
RET NZ ; RETURN NZ IF FAILURE
INC E ; SECOND VRAM BYTE
CALL VGA_MEMRD ; READ IT
CPL ; INVERT IT
CP B ; CHECK FOR INVERTED TEST VALUE
RET ; RETURN WITH ZF SET BASED ON CP
;
;----------------------------------------------------------------------
; CRTC DISPLAY CONTROLLER CHIP INITIALIZATION
;----------------------------------------------------------------------
;
VGA_CRTINIT:
LD HL,$FF00 ; ZERO ALL CFG BITS
CALL VGA_SETCFG ; DO IT
CALL VGA_RES ; RESET CRTC (ALL REGS TO ZERO)
LD HL,DEFREGS ; HL = POINTER TO TABLE OF REG VALUES
VGA_CRTINIT1:
LD A,(HL) ; FIRST BYTE IS REG ADR
LD C,A ; PUT IN C FOR LATER
INC A ; TEST FOR END MARKER ($FF)
RET Z ; IF EQUAL, DONE
INC HL ; NEXT BYTE
LD A,(HL) ; SECOND BYTE IS REG VAL
INC HL ; HL TO NEXT ENTRY
CALL VGA_REGWR ; WRITE REGISTER VALUE
JR VGA_CRTINIT1 ; LOOP
;
VGA_RES:
LD C,0 ; START WITH REG ZERO
LD B,40 ; CLEAR 40 REGISTERS
VGA_RES1:
XOR A ; VALUE IS ZERO
CALL VGA_REGWR ; SET VALUE
INC C ; NEXT REGISTER
DJNZ VGA_RES1 ; LOOP TILL DONE
RET ; DONE
;
VGA_CRTCDUMP:
LD C,0 ; START WITH REG ZERO
LD B,40 ; CLEAR 40 REGISTERS
VGA_CRTCDUMP1:
CALL VGA_REGRD ; SET VALUE
CALL PRTHEXBYTE
CALL PC_SPACE
INC C ; NEXT REGISTER
DJNZ VGA_CRTCDUMP1 ; LOOP TILL DONE
RET ; DONE
;
;----------------------------------------------------------------------
; LOAD FONT DATA
;----------------------------------------------------------------------
;
VGA_LOADFONT:
LD HL,$7000 ; CLEAR FONT PAGE NUM
CALL VGA_SETCFG
LD DE,$7000 ; PAGE 7 OF VIDEO RAM
LD HL,FONT_HI ; START OF FONT DATA
VGA_LOADFONT1:
LD A,(HL) ; GET NEXT BYTE
CALL VGA_MEMWR ; MEM(DE) := A
INC HL ; NEXT FONT BYTE
INC DE ; NEXT MEM BYTE
LD A,D
CP $80 ; CHECK FOR END
JR NZ,VGA_LOADFONT1 ; LOOP
LD HL,$7070 ; SET FONT PAGE NUM TO 7
CALL VGA_SETCFG
RET ; DONE
;
;----------------------------------------------------------------------
; SET CURSOR POSITION TO ROW IN D AND COLUMN IN E
;----------------------------------------------------------------------
;
VGA_XY:
CALL VGA_XY2IDX ; CONVERT ROW/COL TO BUF IDX
LD (VGA_POS),HL ; SAVE THE RESULT (DISPLAY POSITION)
LD C,14 ; CURSOR POSITION REGISTER PAIR
JP VGA_REGWRX ; DO IT AND RETURN
;
;----------------------------------------------------------------------
; CONVERT XY COORDINATES IN DE INTO LINEAR INDEX IN HL
; D=ROW, E=COL
;----------------------------------------------------------------------
;
VGA_XY2IDX:
LD A,E ; SAVE COLUMN NUMBER IN A
LD H,D ; SET H TO ROW NUMBER
LD E,VGA_COLS ; SET E TO ROW LENGTH
CALL MULT8 ; MULTIPLY TO GET ROW OFFSET
LD E,A ; GET COLUMN BACK
ADD HL,DE ; ADD IT IN
RET ; RETURN
;
;----------------------------------------------------------------------
; WRITE VALUE IN A TO CURRENT VDU BUFFER POSTION, ADVANCE CURSOR
;----------------------------------------------------------------------
;
VGA_PUTCHAR:
; SETUP DE WITH BUFFER ADDRESS
LD DE,(VGA_POS) ; GET CURRENT POSITION
RL E ; MULTIPLY BY 2
RL D ; ... 2 BYTES PER CHAR
; SETUP CHAR/ATTR IN HL
LD H,A ; CHARACTER
LD A,(VGA_ATTR) ; ATTRIBUTE
LD L,A ; ... TO L
; WRITE CHAR & ATTR
CALL VGA_MEMWRX
; UPDATE CURRENT POSITION
LD HL,(VGA_POS) ; GET CURSOR POSITION
INC HL ; INCREMENT
LD (VGA_POS),HL ; SAVE NEW POSITION
LD C,14 ; CURSOR POSITION REGISTER PAIR
JP VGA_REGWRX ; DO IT AND RETURN
;
;----------------------------------------------------------------------
; FILL AREA IN BUFFER WITH SPECIFIED CHARACTER AND CURRENT COLOR/ATTRIBUTE
; STARTING AT THE CURRENT FRAME BUFFER POSITION
; A: FILL CHARACTER
; DE: NUMBER OF CHARACTERS TO FILL
;----------------------------------------------------------------------
;
VGA_FILL:
PUSH DE ; COUNT ON STACK
LD H,A ; H = CHAR
LD A,(VGA_ATTR) ; GET CUR ATTR
LD L,A ; PUT INT L
; SETUP DE WITH INITIAL BUFFER ADDRESS
LD DE,(VGA_POS) ; GET CURRENT POSITION
RL E ; MULTIPLY BY 2
RL D ; ... 2 BYTES PER CHAR
LD C,VGA_HI
VGA_FILL1:
OUT (C),D ; SET HI ADDR
INC C ; POINT TO LO ADDR REG
VGA_FILL2:
EX (SP),HL ; HL = COUNT, SAVE CHAR/ATTR
LD A,H ; CHECK FOR
OR L ; ... ZERO
JR Z,VGA_FILL3 ; ALL DONE
DEC HL ; DEC COUNT
EX (SP),HL ; HL = CHAR/ATTR, COUNT ON STACK
OUT (C),E ; SET LO ADDR
INC C ; POINT TO DATA REG
OUT (C),H ; OUTPUT CHAR
INC E ; INC ADDR
DEC C ; POINT TO LO ADDR REG
OUT (C),E ; UPDATE LO ADDR
INC C ; POINT TO DATA REG
OUT (C),L ; OUTPUT ATTR
DEC C ; POINT TO LO ADDR REG
INC E ; INC ADDR LO
JR NZ,VGA_FILL2 ; IF NO CF, SHORT LOOP
DEC C ; POINT TO HI ADDR REG
INC D ; INC ADDR HI
JR VGA_FILL1 ; FULL LOOP
VGA_FILL3:
POP DE ; CLEAR STACK
RET
;
;----------------------------------------------------------------------
; SCROLL ENTIRE SCREEN FORWARD BY ONE LINE (CURSOR POSITION UNCHANGED)
;----------------------------------------------------------------------
;
VGA_SCROLL:
; CLEAR LINE ABOUT TO BE EXPOSED
LD DE,(VGA_POS)
PUSH DE
LD DE,0 + (VGA_ROWS * VGA_COLS)
LD (VGA_POS),DE
LD DE,VGA_COLS
LD A,' '
CALL VGA_FILL
POP DE
LD (VGA_POS),DE
; USE BLOCK COPY TO SCROLL UP ONE LINE
LD HL,VGA_COLS
LD DE,0
LD BC,0 + ((VGA_ROWS) * VGA_COLS)
CALL VGA_BLKCPY
RET
;
;----------------------------------------------------------------------
; REVERSE SCROLL ENTIRE SCREEN BY ONE LINE (CURSOR POSITION UNCHANGED)
;----------------------------------------------------------------------
;
VGA_RSCROLL:
; USE BLOCK COPY TO SCROLL DOWN ONE LINE
LD HL,0 + ((VGA_ROWS - 1) * VGA_COLS) - 1 ; SRC IS EOS - 1 LINE
LD DE,0 + ((VGA_ROWS) * VGA_COLS) - 1 ; DEST IS EOS
LD BC,0 + ((VGA_ROWS - 1) * VGA_COLS) ; LENGTH IS ROWS - 1
CALL VGA_RBLKCPY
; CLEAR TOP LINE
LD DE,(VGA_POS)
PUSH DE
LD DE,0
LD (VGA_POS),DE
LD DE,VGA_COLS
LD A,' '
CALL VGA_FILL
POP DE
LD (VGA_POS),DE
RET
;
;----------------------------------------------------------------------
; BLOCK COPY BC BYTES FROM HL TO DE
;----------------------------------------------------------------------
;
VGA_BLKCPY:
; ADJUST POINTERS FOR 2 BYTE WIDTH (CHAR & ATTR)
RL E
RL D
RL L
RL H
VGA_BLKCPY1:
PUSH BC ; SAVE COUNT
; BA = (HL), HL INCREMENTED
LD C,VGA_HI ; C := VGA_HI
OUT (C),H ; VGA_HI := SOURCE HI (H)
INC C ; C := VGA_LO
OUT (C),L ; VGA_LO := SOURCE LO (L)
INC C ; C := VGA_DATA
IN B,(C) ; B := EVEN DATA BYTE (CHAR)
INC HL ; INC SOURCE PTR
DEC C ; C := VGA_LO
OUT (C),L ; VGA_LO := SOURCE LO (L), VGA_HI IS UNCHANGED!
INC C ; C := VGA_DATA
IN A,(C) ; A := ODD DATA BYTE (ATTR)
INC HL ; INC SOURCE PTR
; (DE) = BA, DE INCREMENTED
LD C,VGA_HI ; C := VGA_HI
OUT (C),D ; VGA_HI := DEST HI (D)
INC C ; C := VGA_LO
OUT (C),E ; VGA_LO := DEST LO (E)
INC C ; C := VGA_DATA
OUT (C),B ; EVEN DATA BYTE (CHAR) := B
INC DE ; INC DEST PTR
DEC C ; C := VGA_LO
OUT (C),E ; VGA_LO := DEST LO (E), VGA_HI IS UNCHANGED
INC C ; C := VGA_DATA
OUT (C),A ; ODD DATA BYTE (ATTR) := A
INC DE ; INC DEST PTR
; CHECK COUNT AND LOOP TILL DONE
POP BC ; RECOVER COUNT
DEC BC ; DEC COUNT
LD A,B ; CHECK COUNT
OR C ; ... FOR ZERO
JR NZ,VGA_BLKCPY1 ; LOOP TILL DONE
RET ; DONE
;
VGA_RBLKCPY:
; ADJUST POINTERS FOR 2 BYTE WIDTH (CHAR & ATTR)
RL E
RL D
RL L
RL H
; ADJUST TO POINT TO SECOND BYTE OF PAIR (ATTR)
INC E
INC L
VGA_RBLKCPY1:
PUSH BC ; SAVE COUNT
; BA = (HL), HL INCREMENTED
LD C,VGA_HI ; C := VGA_HI
OUT (C),H ; VGA_HI := SOURCE HI (H)
INC C ; C := VGA_LO
OUT (C),L ; VGA_LO := SOURCE LO (L)
INC C ; C := VGA_DATA
IN A,(C) ; A := ODD DATA BYTE (ATTR)
DEC HL ; DEC SOURCE PTR
DEC C ; C := VGA_LO
OUT (C),L ; VGA_LO := SOURCE LO (L), VGA_HI IS UNCHANGED!
INC C ; C := VGA_DATA
IN B,(C) ; B := EVEN DATA BYTE (CHAR)
DEC HL ; DEC SOURCE PTR
; (DE) = BA, DE INCREMENTED
LD C,VGA_HI ; C := VGA_HI
OUT (C),D ; VGA_HI := DEST HI (D)
INC C ; C := VGA_LO
OUT (C),E ; VGA_LO := DEST LO (E)
INC C ; C := VGA_DATA
OUT (C),A ; ODD DATA BYTE (ATTR) := A
DEC DE ; DEC DEST PTR
DEC C ; C := VGA_LO
OUT (C),E ; VGA_LO := DEST LO (E), VGA_HI IS UNCHANGED
INC C ; C := VGA_DATA
OUT (C),B ; EVEN DATA BYTE (CHAR) := B
DEC DE ; DEC DEST PTR
; CHECK COUNT AND LOOP TILL DONE
POP BC ; RECOVER COUNT
DEC BC ; DEC COUNT
LD A,B ; CHECK COUNT
OR C ; ... FOR ZERO
JR NZ,VGA_RBLKCPY1 ; LOOP TILL DONE
RET ; DONE
;
;==================================================================================================
; VGA DRIVER - DATA
;==================================================================================================
;
VGA_ATTR .DB 0 ; CURRENT COLOR
VGA_POS .DW 0 ; CURRENT DISPLAY POSITION
VGA_CFGV .DB 0 ; CURRENT BOARD CONFIG VALUE
VGA_RUB .DB 0 ; REVERSE/UNDERLINE/BLINK (-----RUB)
;
; ATTRIBUTE ENCODING:
; BIT 7: ALT FONT
; BIT 6: BG REG
; BIT 5: BG GREEN
; BIT 4: BG BLUE
; BIT 3: FG INTENSITY
; BIT 2: FG RED
; BIT 1: FG GREEN
; BIT 0: FG BLUE
;
;===============================================================================
; DEFAULT REGISTER VALUES
;===============================================================================
;
REGS_VGA:
.DB 0,100 - 1 ; HORZ TOT - 1
.DB 1,80 ; HORZ DISP
.DB 2,80 + 2 ; HORZ DISP + HORZ FP
.DB 3,(2 << 4) | (12 & $0F) ; VERT SW, HORZ SW
.DB 4,28 - 1 ; VERT TOT - 1
.DB 5,1 ; VERT TOT ADJ
.DB 6,25 ; VERT DISP
.DB 7,25 + 1 ; VERT DISP + VERT FP
.DB 9,16 - 1 ; CHAR HEIGHT - 1
.DB 10,(13 | $60) ; CURSOR START & CURSOR BLINK
.DB 11,14 ; CURSOR END
.DB 12,($0000 >> 8) & $FF ; SCRN 1 START (HI)
.DB 13,($0000 & $FF) ; SCRN 1 START (LO)
.DB 30,0 ; CONTROL 1
.DB 31,0 ; CONTROL 2
.DB 33,0 ; CONTROL 3
.DB $FF ; END MARKER
;
;==================================================================================================
; VGA DRIVER - INSTANCE DATA
;==================================================================================================
;
VGA_IDAT:
.DB VGA_KBDST
.DB VGA_KBDDATA
Loading…
Cancel
Save