diff --git a/Source/Apps/assign.asm b/Source/Apps/assign.asm index fcc677ea..728ed868 100644 --- a/Source/Apps/assign.asm +++ b/Source/Apps/assign.asm @@ -1920,7 +1920,7 @@ dev08 .db "PPPSD",0 dev09 .db "HDSK",0 dev10 .db "PPA",0 dev11 .db "IMM",0 -dev12 .equ devunk +dev12 .db "SYQ",0 dev13 .equ devunk dev14 .equ devunk dev15 .equ devunk diff --git a/Source/CBIOS/cbios.asm b/Source/CBIOS/cbios.asm index 0b06d19c..9d5f395f 100644 --- a/Source/CBIOS/cbios.asm +++ b/Source/CBIOS/cbios.asm @@ -2934,6 +2934,8 @@ DRV_INIT3A: JR Z,DRV_INIT3B ; IF SO, SKIP MEDIA CHECK CP DIODEV_IMM ; IMM (ZIP DRIVE) IS REMOVABLE JR Z,DRV_INIT3B ; IF SO, SKIP MEDIA CHECK + CP DIODEV_SYQ ; IMM (ZIP DRIVE) IS REMOVABLE + JR Z,DRV_INIT3B ; IF SO, SKIP MEDIA CHECK ; CHECK FOR ACTIVE AND RETURN IF NOT PUSH DE ; SAVE DE (HARD DISK VOLUME COUNTER) @@ -3401,7 +3403,7 @@ DEV08 .DB "PPPSD$" DEV09 .DB "HDSK$" DEV10 .DB "PPA$" DEV11 .DB "IMM$" -DEV12 .EQU DEVUNK +DEV12 .DB "SYQ$" DEV13 .EQU DEVUNK DEV14 .EQU DEVUNK DEV15 .EQU DEVUNK diff --git a/Source/CPM3/boot.z80 b/Source/CPM3/boot.z80 index 05dcb4f6..fdb86aa3 100644 --- a/Source/CPM3/boot.z80 +++ b/Source/CPM3/boot.z80 @@ -186,6 +186,8 @@ dinit3a: jr z,dinit3b ; if so, skip media check cp 0B0h ; imm (zip drive) is removable jr z,dinit3b ; if so, skip media check + cp 0C0h ; syq (syquest drive) is removable + jr z,dinit3b ; if so, skip media check ; check for active and return if not push de ; save de (hard disk volume counter) diff --git a/Source/HBIOS/cfg_dyno.asm b/Source/HBIOS/cfg_dyno.asm index 92a781e3..1ef3f852 100644 --- a/Source/HBIOS/cfg_dyno.asm +++ b/Source/HBIOS/cfg_dyno.asm @@ -256,6 +256,8 @@ PPAENABLE .EQU FALSE ; PPA: ENABLE PPA DISK DRIVER (PPA.ASM) ; IMMENABLE .EQU FALSE ; IMM: ENABLE IMM DISK DRIVER (IMM.ASM) ; +SYQENABLE .EQU FALSE ; SYQ: ENABLE IMM DISK DRIVER (SYQ.ASM) +; PIO_4P .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB 4P BOARD PIO_ZP .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB ZILOG PERIPHERALS BOARD (PIO.ASM) PIO_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP diff --git a/Source/HBIOS/cfg_master.asm b/Source/HBIOS/cfg_master.asm index fb0b79c9..2528e4d4 100644 --- a/Source/HBIOS/cfg_master.asm +++ b/Source/HBIOS/cfg_master.asm @@ -320,17 +320,24 @@ LPT1BASE .EQU $EC ; LPT 1: REGISTERS BASE ADR PPAENABLE .EQU FALSE ; PPA: ENABLE PPA DISK DRIVER (PPA.ASM) PPACNT .EQU 1 ; PPA: NUMBER OF PPA DEVICES (1-2) PPATRACE .EQU 1 ; PPA: TRACE LEVEL (0=NO,1=ERRORS,2=ALL) -PPAMODE .EQU PPAMODE_MG014 ; PPA: DRIVER MODE: PPAMODE_[NONE|SPP|MG014] +PPAMODE .EQU PPAMODE_SPP ; PPA: DRIVER MODE: PPAMODE_[NONE|SPP|MG014] PPA0BASE .EQU LPT0BASE ; PPA 0: BASE I/O ADDRESS OF PPI FOR PPA PPA1BASE .EQU LPT1BASE ; PPA 1: BASE I/O ADDRESS OF PPI FOR PPA ; IMMENABLE .EQU FALSE ; IMM: ENABLE IMM DISK DRIVER (IMM.ASM) IMMCNT .EQU 1 ; IMM: NUMBER OF IMM DEVICES (1-2) IMMTRACE .EQU 1 ; IMM: TRACE LEVEL (0=NO,1=ERRORS,2=ALL) -IMMMODE .EQU IMMMODE_MG014 ; IMM: DRIVER MODE: IMMMODE_[NONE|SPP|MG014] +IMMMODE .EQU IMMMODE_SPP ; IMM: DRIVER MODE: IMMMODE_[NONE|SPP|MG014] IMM0BASE .EQU LPT0BASE ; IMM 0: BASE I/O ADDRESS OF PPI FOR IMM IMM1BASE .EQU LPT1BASE ; IMM 1: BASE I/O ADDRESS OF PPI FOR IMM ; +SYQENABLE .EQU FALSE ; SYQ: ENABLE IMM DISK DRIVER (SYQ.ASM) +SYQCNT .EQU 1 ; SYQ: NUMBER OF SYQ DEVICES (1-2) +SYQTRACE .EQU 1 ; SYQ: TRACE LEVEL (0=NO,1=ERRORS,2=ALL) +SYQMODE .EQU IMMMODE_SPP ; SYQ: DRIVER MODE: SYQMODE_[NONE|SPP|MG014] +SYQ0BASE .EQU LPT0BASE ; SYQ 0: BASE I/O ADDRESS OF PPI FOR SYQ +SYQ1BASE .EQU LPT1BASE ; SYQ 1: BASE I/O ADDRESS OF PPI FOR SYQ +; PIO_4P .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB 4P BOARD PIO4BASE .EQU $90 ; PIO: PIO REGISTERS BASE ADR FOR ECB 4P BOARD PIO_ZP .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB ZILOG PERIPHERALS BOARD (PIO.ASM) diff --git a/Source/HBIOS/cfg_mbc.asm b/Source/HBIOS/cfg_mbc.asm index 5c283fe0..8d670220 100644 --- a/Source/HBIOS/cfg_mbc.asm +++ b/Source/HBIOS/cfg_mbc.asm @@ -255,6 +255,13 @@ IMMMODE .EQU IMMMODE_SPP ; IMM: DRIVER MODE: IMMMODE_[NONE|SPP|MG014] IMM0BASE .EQU LPT0BASE ; IMM 0: BASE I/O ADDRESS OF PPI FOR IMM IMM1BASE .EQU LPT1BASE ; IMM 1: BASE I/O ADDRESS OF PPI FOR IMM ; +SYQENABLE .EQU FALSE ; SYQ: ENABLE IMM DISK DRIVER (SYQ.ASM) +SYQCNT .EQU 1 ; SYQ: NUMBER OF SYQ DEVICES (1-2) +SYQTRACE .EQU 1 ; SYQ: TRACE LEVEL (0=NO,1=ERRORS,2=ALL) +SYQMODE .EQU IMMMODE_SPP ; SYQ: DRIVER MODE: SYQMODE_[NONE|SPP|MG014] +SYQ0BASE .EQU LPT0BASE ; SYQ 0: BASE I/O ADDRESS OF PPI FOR SYQ +SYQ1BASE .EQU LPT1BASE ; SYQ 1: BASE I/O ADDRESS OF PPI FOR SYQ +; PIO_4P .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB 4P BOARD PIO4BASE .EQU $90 ; PIO: PIO REGISTERS BASE ADR FOR ECB 4P BOARD PIO_ZP .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB ZILOG PERIPHERALS BOARD (PIO.ASM) diff --git a/Source/HBIOS/cfg_mk4.asm b/Source/HBIOS/cfg_mk4.asm index 895b5ef2..3582161d 100644 --- a/Source/HBIOS/cfg_mk4.asm +++ b/Source/HBIOS/cfg_mk4.asm @@ -258,6 +258,8 @@ PPAENABLE .EQU FALSE ; PPA: ENABLE PPA DISK DRIVER (PPA.ASM) ; IMMENABLE .EQU FALSE ; IMM: ENABLE IMM DISK DRIVER (IMM.ASM) ; +SYQENABLE .EQU FALSE ; SYQ: ENABLE IMM DISK DRIVER (SYQ.ASM) +; PIO_4P .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB 4P BOARD PIO4BASE .EQU $90 ; PIO: PIO REGISTERS BASE ADR FOR ECB 4P BOARD PIO_ZP .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB ZILOG PERIPHERALS BOARD (PIO.ASM) diff --git a/Source/HBIOS/cfg_n8.asm b/Source/HBIOS/cfg_n8.asm index 8a441056..f65b6f92 100644 --- a/Source/HBIOS/cfg_n8.asm +++ b/Source/HBIOS/cfg_n8.asm @@ -251,6 +251,8 @@ PPAENABLE .EQU FALSE ; PPA: ENABLE PPA DISK DRIVER (PPA.ASM) ; IMMENABLE .EQU FALSE ; IMM: ENABLE IMM DISK DRIVER (IMM.ASM) ; +SYQENABLE .EQU FALSE ; SYQ: ENABLE IMM DISK DRIVER (SYQ.ASM) +; PIO_4P .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB 4P BOARD PIO4BASE .EQU $90 ; PIO: PIO REGISTERS BASE ADR FOR ECB 4P BOARD PIO_ZP .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB ZILOG PERIPHERALS BOARD (PIO.ASM) diff --git a/Source/HBIOS/cfg_rcz180.asm b/Source/HBIOS/cfg_rcz180.asm index ecccf85f..bf458086 100644 --- a/Source/HBIOS/cfg_rcz180.asm +++ b/Source/HBIOS/cfg_rcz180.asm @@ -277,6 +277,13 @@ IMMMODE .EQU IMMMODE_MG014 ; IMM: DRIVER MODE: IMMMODE_[NONE|SPP|MG014] IMM0BASE .EQU LPT0BASE ; IMM 0: BASE I/O ADDRESS OF PPI FOR IMM IMM1BASE .EQU LPT1BASE ; IMM 1: BASE I/O ADDRESS OF PPI FOR IMM ; +SYQENABLE .EQU FALSE ; SYQ: ENABLE IMM DISK DRIVER (SYQ.ASM) +SYQCNT .EQU 1 ; SYQ: NUMBER OF SYQ DEVICES (1-2) +SYQTRACE .EQU 1 ; SYQ: TRACE LEVEL (0=NO,1=ERRORS,2=ALL) +SYQMODE .EQU IMMMODE_MG014 ; SYQ: DRIVER MODE: SYQMODE_[NONE|SPP|MG014] +SYQ0BASE .EQU LPT0BASE ; SYQ 0: BASE I/O ADDRESS OF PPI FOR SYQ +SYQ1BASE .EQU LPT1BASE ; SYQ 1: BASE I/O ADDRESS OF PPI FOR SYQ +; PIO_4P .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB 4P BOARD PIO_ZP .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB ZILOG PERIPHERALS BOARD (PIO.ASM) PIO_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP diff --git a/Source/HBIOS/cfg_rcz280.asm b/Source/HBIOS/cfg_rcz280.asm index f9a444d7..df8f2162 100644 --- a/Source/HBIOS/cfg_rcz280.asm +++ b/Source/HBIOS/cfg_rcz280.asm @@ -281,6 +281,13 @@ IMMMODE .EQU IMMMODE_MG014 ; IMM: DRIVER MODE: IMMMODE_[NONE|SPP|MG014] IMM0BASE .EQU LPT0BASE ; IMM 0: BASE I/O ADDRESS OF PPI FOR IMM IMM1BASE .EQU LPT1BASE ; IMM 1: BASE I/O ADDRESS OF PPI FOR IMM ; +SYQENABLE .EQU FALSE ; SYQ: ENABLE IMM DISK DRIVER (SYQ.ASM) +SYQCNT .EQU 1 ; SYQ: NUMBER OF SYQ DEVICES (1-2) +SYQTRACE .EQU 1 ; SYQ: TRACE LEVEL (0=NO,1=ERRORS,2=ALL) +SYQMODE .EQU IMMMODE_MG014 ; SYQ: DRIVER MODE: SYQMODE_[NONE|SPP|MG014] +SYQ0BASE .EQU LPT0BASE ; SYQ 0: BASE I/O ADDRESS OF PPI FOR SYQ +SYQ1BASE .EQU LPT1BASE ; SYQ 1: BASE I/O ADDRESS OF PPI FOR SYQ +; PIO_4P .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB 4P BOARD PIO_ZP .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB ZILOG PERIPHERALS BOARD (PIO.ASM) PIO_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP diff --git a/Source/HBIOS/cfg_rcz80.asm b/Source/HBIOS/cfg_rcz80.asm index 1071dab6..6fd84124 100644 --- a/Source/HBIOS/cfg_rcz80.asm +++ b/Source/HBIOS/cfg_rcz80.asm @@ -275,6 +275,13 @@ IMMMODE .EQU IMMMODE_MG014 ; IMM: DRIVER MODE: IMMMODE_[NONE|SPP|MG014] IMM0BASE .EQU LPT0BASE ; IMM 0: BASE I/O ADDRESS OF PPI FOR IMM IMM1BASE .EQU LPT1BASE ; IMM 1: BASE I/O ADDRESS OF PPI FOR IMM ; +SYQENABLE .EQU FALSE ; SYQ: ENABLE IMM DISK DRIVER (SYQ.ASM) +SYQCNT .EQU 1 ; SYQ: NUMBER OF SYQ DEVICES (1-2) +SYQTRACE .EQU 1 ; SYQ: TRACE LEVEL (0=NO,1=ERRORS,2=ALL) +SYQMODE .EQU IMMMODE_MG014 ; SYQ: DRIVER MODE: SYQMODE_[NONE|SPP|MG014] +SYQ0BASE .EQU LPT0BASE ; SYQ 0: BASE I/O ADDRESS OF PPI FOR SYQ +SYQ1BASE .EQU LPT1BASE ; SYQ 1: BASE I/O ADDRESS OF PPI FOR SYQ +; PIO_4P .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB 4P BOARD PIO_ZP .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB ZILOG PERIPHERALS BOARD (PIO.ASM) PIO_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP diff --git a/Source/HBIOS/cfg_rph.asm b/Source/HBIOS/cfg_rph.asm index f1d46a3f..09d330cc 100644 --- a/Source/HBIOS/cfg_rph.asm +++ b/Source/HBIOS/cfg_rph.asm @@ -240,6 +240,8 @@ PPAENABLE .EQU FALSE ; PPA: ENABLE PPA DISK DRIVER (PPA.ASM) ; IMMENABLE .EQU FALSE ; IMM: ENABLE IMM DISK DRIVER (IMM.ASM) ; +SYQENABLE .EQU FALSE ; SYQ: ENABLE IMM DISK DRIVER (SYQ.ASM) +; PIO_4P .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB 4P BOARD PIO4BASE .EQU $90 ; PIO: PIO REGISTERS BASE ADR FOR ECB 4P BOARD PIO_ZP .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB ZILOG PERIPHERALS BOARD (PIO.ASM) diff --git a/Source/HBIOS/cfg_sbc.asm b/Source/HBIOS/cfg_sbc.asm index 5177e829..36158a10 100644 --- a/Source/HBIOS/cfg_sbc.asm +++ b/Source/HBIOS/cfg_sbc.asm @@ -239,6 +239,8 @@ PPAENABLE .EQU FALSE ; PPA: ENABLE PPA DISK DRIVER (PPA.ASM) ; IMMENABLE .EQU FALSE ; IMM: ENABLE IMM DISK DRIVER (IMM.ASM) ; +SYQENABLE .EQU FALSE ; SYQ: ENABLE IMM DISK DRIVER (SYQ.ASM) +; PIO_4P .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB 4P BOARD PIO4BASE .EQU $90 ; PIO: PIO REGISTERS BASE ADR FOR ECB 4P BOARD PIO_ZP .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB ZILOG PERIPHERALS BOARD (PIO.ASM) diff --git a/Source/HBIOS/cfg_scz180.asm b/Source/HBIOS/cfg_scz180.asm index f3f711db..197a676a 100644 --- a/Source/HBIOS/cfg_scz180.asm +++ b/Source/HBIOS/cfg_scz180.asm @@ -271,6 +271,13 @@ IMMMODE .EQU IMMMODE_MG014 ; IMM: DRIVER MODE: IMMMODE_[NONE|SPP|MG014] IMM0BASE .EQU LPT0BASE ; IMM 0: BASE I/O ADDRESS OF PPI FOR IMM IMM1BASE .EQU LPT1BASE ; IMM 1: BASE I/O ADDRESS OF PPI FOR IMM ; +SYQENABLE .EQU FALSE ; SYQ: ENABLE IMM DISK DRIVER (SYQ.ASM) +SYQCNT .EQU 1 ; SYQ: NUMBER OF SYQ DEVICES (1-2) +SYQTRACE .EQU 1 ; SYQ: TRACE LEVEL (0=NO,1=ERRORS,2=ALL) +SYQMODE .EQU IMMMODE_MG014 ; SYQ: DRIVER MODE: SYQMODE_[NONE|SPP|MG014] +SYQ0BASE .EQU LPT0BASE ; SYQ 0: BASE I/O ADDRESS OF PPI FOR SYQ +SYQ1BASE .EQU LPT1BASE ; SYQ 1: BASE I/O ADDRESS OF PPI FOR SYQ +; PIO_4P .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB 4P BOARD PIO_ZP .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB ZILOG PERIPHERALS BOARD (PIO.ASM) PIO_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP diff --git a/Source/HBIOS/cfg_z80retro.asm b/Source/HBIOS/cfg_z80retro.asm index 1a92ce7b..dae8f9b2 100644 --- a/Source/HBIOS/cfg_z80retro.asm +++ b/Source/HBIOS/cfg_z80retro.asm @@ -210,6 +210,8 @@ PPAENABLE .EQU FALSE ; PPA: ENABLE PPA DISK DRIVER (PPA.ASM) ; IMMENABLE .EQU FALSE ; IMM: ENABLE IMM DISK DRIVER (IMM.ASM) ; +SYQENABLE .EQU FALSE ; SYQ: ENABLE IMM DISK DRIVER (SYQ.ASM) +; PIO_4P .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB 4P BOARD PIO_ZP .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB ZILOG PERIPHERALS BOARD (PIO.ASM) PIO_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP diff --git a/Source/HBIOS/cfg_zeta.asm b/Source/HBIOS/cfg_zeta.asm index f2a2e508..635ffc88 100644 --- a/Source/HBIOS/cfg_zeta.asm +++ b/Source/HBIOS/cfg_zeta.asm @@ -181,6 +181,8 @@ PPAENABLE .EQU FALSE ; PPA: ENABLE PPA DISK DRIVER (PPA.ASM) ; IMMENABLE .EQU FALSE ; IMM: ENABLE IMM DISK DRIVER (IMM.ASM) ; +SYQENABLE .EQU FALSE ; SYQ: ENABLE IMM DISK DRIVER (SYQ.ASM) +; PIO_4P .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB 4P BOARD PIO_ZP .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB ZILOG PERIPHERALS BOARD (PIO.ASM) PIO_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP diff --git a/Source/HBIOS/cfg_zeta2.asm b/Source/HBIOS/cfg_zeta2.asm index 1d937a05..5a224502 100644 --- a/Source/HBIOS/cfg_zeta2.asm +++ b/Source/HBIOS/cfg_zeta2.asm @@ -192,6 +192,8 @@ PPAENABLE .EQU FALSE ; PPA: ENABLE PPA DISK DRIVER (PPA.ASM) ; IMMENABLE .EQU FALSE ; IMM: ENABLE IMM DISK DRIVER (IMM.ASM) ; +SYQENABLE .EQU FALSE ; SYQ: ENABLE IMM DISK DRIVER (SYQ.ASM) +; PIO_4P .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB 4P BOARD PIO_ZP .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR ECB ZILOG PERIPHERALS BOARD (PIO.ASM) PIO_SBC .EQU FALSE ; PIO: ENABLE PARALLEL PORT DRIVER FOR 8255 CHIP diff --git a/Source/HBIOS/hbios.asm b/Source/HBIOS/hbios.asm index 4af09d42..5c29e50a 100644 --- a/Source/HBIOS/hbios.asm +++ b/Source/HBIOS/hbios.asm @@ -3245,6 +3245,9 @@ HB_INITTBL: #IF (IMMENABLE) .DW IMM_INIT #ENDIF +#IF (SYQENABLE) + .DW SYQ_INIT +#ENDIF #IF (PRPENABLE) .DW PRP_INIT #ENDIF @@ -6372,6 +6375,15 @@ SIZ_IMM .EQU $ - ORG_IMM .ECHO " bytes.\n" #ENDIF ; +#IF (SYQENABLE) +ORG_SYQ .EQU $ + #INCLUDE "syq.asm" +SIZ_SYQ .EQU $ - ORG_SYQ + .ECHO "SYQ occupies " + .ECHO SIZ_SYQ + .ECHO " bytes.\n" +#ENDIF +; #IF (TERMENABLE) ORG_TERM .EQU $ #INCLUDE "term.asm" @@ -7158,6 +7170,7 @@ PS_DDPPPSD .TEXT "PPPSD$" PS_DDHDSK .TEXT "HDSK$" PS_DDPPA .TEXT "PPA$" PS_DDIMM .TEXT "IMM$" +PS_DDSYQ .TEXT "SYQ$" ; ; DISK TYPE STRINGS ; diff --git a/Source/HBIOS/hbios.inc b/Source/HBIOS/hbios.inc index 9d4c65d7..628ccb6e 100644 --- a/Source/HBIOS/hbios.inc +++ b/Source/HBIOS/hbios.inc @@ -323,6 +323,7 @@ DIODEV_PPPSD .EQU $80 DIODEV_HDSK .EQU $90 DIODEV_PPA .EQU $A0 DIODEV_IMM .EQU $B0 +DIODEV_SYQ .EQU $C0 ; ; RTC DEVICE IDS ; diff --git a/Source/HBIOS/imm.asm b/Source/HBIOS/imm.asm index 25ecbb54..079bf9af 100644 --- a/Source/HBIOS/imm.asm +++ b/Source/HBIOS/imm.asm @@ -78,7 +78,7 @@ ; - THIS DRIVER IS FOR THE ZIP DRIVE IMM INTERFACE. IT WILL SIMPLY ; FAIL TO EVEN RECOGNIZE A ZIP DRIVE WITH THE OLDER PPA INTERFACE. ; THERE DOES NOT SEEM TO BE A WAY TO VISUALLY DETERMINE IF A ZIP -; DRIVE IS IMM OR PPA. SIGH. +; DRIVE IS PPA OR IMM. SIGH. ; ; - THERE ARE SOME HARD CODED TIMEOUT LOOPS IN THE CODE. THEY ARE ; WORKING OK ON A 7 MHZ Z80. THEY ARE LIKELY TO NEED TWEAKING ON @@ -130,6 +130,11 @@ IMM_IOBASE .EQU 3 ; IO BASE ADDRESS (BYTE) IMM_MEDCAP .EQU 4 ; MEDIA CAPACITY (DWORD) IMM_LBA .EQU 8 ; OFFSET OF LBA (DWORD) ; +; MACROS +; +#DEFINE IMM_WCTL(VAL) LD A,VAL \ CALL IMM_WRITECTRL +#DEFINE IMM_WDATA(VAL) LD A,VAL \ CALL IMM_WRITEDATA +; ;============================================================================= ; INITIALIZATION ENTRY POINT ;============================================================================= @@ -289,7 +294,7 @@ IMM_READ: ; ; IMM_WRITE: - CALL HB_DSKREAD ; HOOK DISK WRITE CONTROLLER + CALL HB_DSKWRITE ; HOOK DISK WRITE CONTROLLER LD A,SCSI_CMD_WRITE ; SETUP SCSI WRITE LD (IMM_CMD_RW),A ; AND SAVE IT IN SCSI CMD JP IMM_IO ; DO THE I/O @@ -445,6 +450,10 @@ IMM_WRITECTRL: #IF (IMMMODE == IMMMODE_MG014 XOR $0B | $80 ; HIGH BIT IS MG014 LED #ENDIF +;#IF (IMMMODE == IMMMODE_SPP +; AND %00001111 +; OR %11000000 +;#ENDIF LD C,(IY+IMM_IOBASE) ; GET BASE IO ADDRESS INC C ; BUMP TO CONTROL PORT INC C @@ -503,28 +512,28 @@ IMM_READSTATUS5: ; IMM_CPP: PUSH AF - LD A,$0C \ CALL IMM_WRITECTRL - LD A,$AA \ CALL IMM_WRITEDATA - LD A,$55 \ CALL IMM_WRITEDATA - LD A,$00 \ CALL IMM_WRITEDATA - LD A,$FF \ CALL IMM_WRITEDATA + IMM_WCTL($0C) + IMM_WDATA($AA) + IMM_WDATA($55) + IMM_WDATA($00) + IMM_WDATA($FF) CALL IMM_READSTATUS AND $B8 LD (IMM_S1),A - LD A,$87 \ CALL IMM_WRITEDATA + IMM_WDATA($87) CALL IMM_READSTATUS AND $B8 LD (IMM_S2),A - LD A,$78 \ CALL IMM_WRITEDATA + IMM_WDATA($78) CALL IMM_READSTATUS AND $38 LD (IMM_S3),A POP AF CALL IMM_WRITEDATA - LD A,$0C \ CALL IMM_WRITECTRL - LD A,$0D \ CALL IMM_WRITECTRL - LD A,$0C \ CALL IMM_WRITECTRL - LD A,$FF \ CALL IMM_WRITEDATA + IMM_WCTL($0C) + IMM_WCTL($0D) + IMM_WCTL($0C) + IMM_WDATA($FF) ; ; CONNECT: S1=$B8 S2=$18 S3=$30 ; DISCONNECT: S1=$B8 S2=$18 S3=$38 @@ -567,23 +576,23 @@ IMM_DISCONNECT: CALL IMM_CPP ; ; TURNS OFF MG014 LED - LD A,$8C \ CALL IMM_WRITECTRL + IMM_WCTL($8C) ; RET ; ; INITIATE A SCSI BUS RESET. ; IMM_RESETPULSE: - LD A,$04 \ CALL IMM_WRITECTRL - LD A,$40 \ CALL IMM_WRITEDATA + IMM_WCTL($04) + IMM_WDATA($40) CALL DELAY ; 16 US, IDEALLY, 1 US - LD A,$0C \ CALL IMM_WRITECTRL - LD A,$0D \ CALL IMM_WRITECTRL + IMM_WCTL($0C) + IMM_WCTL($0D) CALL DELAY ; 48 US, IDEALLY, 50 US CALL DELAY CALL DELAY - LD A,$0C \ CALL IMM_WRITECTRL - LD A,$04 \ CALL IMM_WRITECTRL + IMM_WCTL($0C) + IMM_WCTL($04) RET ; ; SCSI SELECT PROCESS @@ -592,7 +601,7 @@ IMM_SELECT: #IF (IMMTRACE >= 3) PRTS("\r\nSELECT: $") #ENDIF - LD A,$0C \ CALL IMM_WRITECTRL + IMM_WCTL($0C) ; LD HL,500 ; TIMEOUT COUNTER ; @@ -607,12 +616,12 @@ IMM_SELECT1: JR IMM_SELECT1 ; IMM_SELECT2: - LD A,$04 \ CALL IMM_WRITECTRL + IMM_WCTL($04) ; PLACE HOST AND TARGET BIT ON DATA BUS LD A,$80 | (1 << IMM_TGT) CALL IMM_WRITEDATA CALL DELAY ; CONFIRM DELAY TIME? - LD A,$0C \ CALL IMM_WRITECTRL + IMM_WCTL($0C) ; #IF (IMMTRACE >= 3) CALL IMM_READSTATUS @@ -620,7 +629,7 @@ IMM_SELECT2: CALL PRTHEXBYTE #ENDIF ; - LD A,$0D \ CALL IMM_WRITECTRL + IMM_WCTL($0D) ; #IF (IMMTRACE >= 3) CALL IMM_READSTATUS @@ -645,7 +654,7 @@ IMM_SELECT3: JR IMM_SELECT3 ; IMM_SELECT4: - LD A,$0C \ CALL IMM_WRITECTRL + IMM_WCTL($0C) ; XOR A RET @@ -675,7 +684,7 @@ IMM_SENDCMD: ; INC HL ; BACK TO FIRST CMD BYTE IMM_SENDCMD1: - LD A,$04 \ CALL IMM_WRITECTRL + IMM_WCTL($04) LD A,(HL) ; LOAD CMD BYTE ; #IF (IMMTRACE >= 3) @@ -686,8 +695,8 @@ IMM_SENDCMD1: CALL IMM_WRITEDATA ; PUT IT ON THE BUS INC HL ; BUMP TO NEXT BYTE DEC B ; DEC LOOP COUNTER - LD A,$05 - CALL IMM_WRITECTRL \ LD A,(HL) ; LOAD CMD BYTE + IMM_WCTL($05) + LD A,(HL) ; LOAD CMD BYTE ; #IF (IMMTRACE >= 3) CALL PC_SPACE @@ -696,11 +705,11 @@ IMM_SENDCMD1: ; CALL IMM_WRITEDATA ; PUT IT ON THE BUS INC HL ; BUMP TO NEXT BYTE - LD A,$00 \ CALL IMM_WRITECTRL + IMM_WCTL($00) DJNZ IMM_SENDCMD1 ; LOOP TILL DONE ; IMM_SENDCMD2: - LD A,$04 \ CALL IMM_WRITECTRL + IMM_WCTL($04) ; RET ; @@ -718,11 +727,11 @@ IMM_WAITLOOP: ; IMM_WAIT: LD HL,500 ; GOOD VALUE??? - LD A,$0C \ CALL IMM_WRITECTRL + IMM_WCTL($0C) CALL IMM_WAITLOOP JP Z,IMM_CMD_TIMEOUT ; HANDLE TIMEOUT PUSH AF - LD A,$04 \ CALL IMM_WRITECTRL + IMM_WCTL($04) POP AF AND $B8 RET ; RETURN W/ RESULT IN A @@ -731,7 +740,7 @@ IMM_WAIT: ; IMM_LONGWAIT: LD B,3 ; VALUE??? - LD A,$0C \ CALL IMM_WRITECTRL + IMM_WCTL($0C) IMM_LONGWAIT1: LD HL,0 CALL IMM_WAITLOOP @@ -741,7 +750,7 @@ IMM_LONGWAIT1: ; IMM_LONGWAIT2: PUSH AF - LD A,$04 \ CALL IMM_WRITECTRL + IMM_WCTL($04) ; #IF 0 CALL PC_GT @@ -761,19 +770,19 @@ IMM_NEGOTIATE: #IF (IMMTRACE >= 3) PRTS("\r\nNEGO: $") #ENDIF - LD A,$04 \ CALL IMM_WRITECTRL + IMM_WCTL($04) CALL DELAY ; 16 US, IDEALLY 5 US - LD A,$00 \ CALL IMM_WRITEDATA + IMM_WDATA($00) LD DE,7 ; 112 US, IDEALLY 100 US CALL VDELAY - LD A,$06 \ CALL IMM_WRITECTRL + IMM_WCTL($06) CALL DELAY ; 16 US, IDEALLY 5 US CALL IMM_READSTATUS PUSH AF ; SAVE RESULT CALL DELAY ; 16 US, IDEALLY 5 US - LD A,$07 \ CALL IMM_WRITECTRL + IMM_WCTL($07) CALL DELAY ; 16 US, IDEALLY 5 US - LD A,$06 \ CALL IMM_WRITECTRL + IMM_WCTL($06) ; POP AF ; @@ -799,7 +808,7 @@ IMM_NEGOTIATE: ; IMM_GETBYTE: CALL IMM_WAIT - LD A,$06 \ CALL IMM_WRITECTRL + IMM_WCTL($06) CALL IMM_READSTATUS AND $F0 RRCA @@ -807,13 +816,13 @@ IMM_GETBYTE: RRCA RRCA PUSH AF - LD A,$05 \ CALL IMM_WRITECTRL + IMM_WCTL($05) CALL IMM_READSTATUS AND $F0 POP HL OR H PUSH AF - LD A,$04 \ CALL IMM_WRITECTRL + IMM_WCTL($04) POP AF RET ; @@ -844,8 +853,8 @@ IMM_GETDATA1: POP HL ; RESTORE BYTE COUNTER CP $98 ; CHECK FOR READ PHASE JR NZ,IMM_GETDATA2 ; IF NOT, ASSUME WE ARE DONE - LD A,$04 \ CALL IMM_WRITECTRL - LD A,$06 \ CALL IMM_WRITECTRL + IMM_WCTL($04) + IMM_WCTL($06) CALL IMM_READSTATUS ; GET FIRST NIBBLE AND $F0 ; ISOLATE BITS RRCA ; AND SHIFT TO LOW NIBBLE @@ -853,7 +862,7 @@ IMM_GETDATA1: RRCA RRCA PUSH AF ; SAVE WORKING VALUE - LD A,$05 \ CALL IMM_WRITECTRL + IMM_WCTL($05) CALL IMM_READSTATUS ; GET SECOND NIBBLE AND $F0 ; ISOLATE BITS POP BC ; RECOVER LOW NIBBLE @@ -861,8 +870,8 @@ IMM_GETDATA1: LD (DE),A ; AND SAVE THE FULL BYTE VALUE INC DE ; NEXT BUFFER POS INC HL ; INCREMENT BYTES COUNTER - LD A,$04 \ CALL IMM_WRITECTRL - LD A,$0C \ CALL IMM_WRITECTRL + IMM_WCTL($04) + IMM_WCTL($0C) JR IMM_GETDATA1 ; LOOP TILL DONE ; IMM_GETDATA2: @@ -884,9 +893,9 @@ IMM_GETDATALEN: PRTS(" BYTES$") #ENDIF ; - LD A,$04 \ CALL IMM_WRITECTRL + IMM_WCTL($04) IMM_GETDATALEN1: - LD A,$06 \ CALL IMM_WRITECTRL + IMM_WCTL($06) CALL IMM_READSTATUS ; GET FIRST NIBBLE AND $F0 ; ISOLATE BITS RRCA ; MOVE TO LOW NIBBLE @@ -894,7 +903,7 @@ IMM_GETDATALEN1: RRCA RRCA PUSH AF ; SAVE WORKING VALUE - LD A,$05 \ CALL IMM_WRITECTRL + IMM_WCTL($05) CALL IMM_READSTATUS ; GET SECOND NIBBLE AND $F0 ; ISOLATE BITS POP BC ; RECOVER FIRST NIBBLE @@ -902,11 +911,11 @@ IMM_GETDATALEN1: LD (DE),A ; SAVE FINAL BYTE VALUE INC DE ; NEXT BUFFER POS DEC HL ; DEC LOOP COUNTER - LD A,$04 \ CALL IMM_WRITECTRL + IMM_WCTL($04) LD A,H ; CHECK LOOP COUNTER OR L JR NZ,IMM_GETDATALEN1 ; LOOP IF NOT DONE - LD A,$0C \ CALL IMM_WRITECTRL + IMM_WCTL($0C) RET ; ; PUT A CHUNK OF DATA TO THE SCSI BUS. THIS IS SPECIFICALLY FOR @@ -935,21 +944,21 @@ IMM_PUTDATA1: POP HL ; RESTORE BYTE COUNTER CP $88 ; CHECK FOR WRITE PHASE JR NZ,IMM_PUTDATA2 ; IF NOT, ASSUME WE ARE DONE - LD A,$04 \ CALL IMM_WRITECTRL + IMM_WCTL($04) LD A,(DE) ; GET NEXT BYTE TO WRITE (FIRST OF PAIR) CALL IMM_WRITEDATA ; PUT ON BUS INC DE ; BUMP TO NEXT BUF POS INC HL ; INCREMENT COUNTER - LD A,$05 \ CALL IMM_WRITECTRL + IMM_WCTL($05) LD A,(DE) ; GET NEXT BYTE TO WRITE (SECOND OF PAIR) CALL IMM_WRITEDATA ; PUT ON BUS INC DE ; BUMP TO NEXT BUF POS INC HL ; INCREMENT COUNTER - LD A,$00 \ CALL IMM_WRITECTRL + IMM_WCTL($00) JR IMM_PUTDATA1 ; LOOP TILL DONE ; IMM_PUTDATA2: - LD A,$04 \ CALL IMM_WRITECTRL + IMM_WCTL($04) ; #IF (IMMTRACE >= 3) CALL PC_SPACE @@ -968,22 +977,22 @@ IMM_PUTDATALEN: PRTS(" BYTES$") #ENDIF ; - LD A,$04 \ CALL IMM_WRITECTRL + IMM_WCTL($04) IMM_PUTDATALEN1: LD A,(DE) ; GET NEXT BYTE (FIRST OF PAIR) CALL IMM_WRITEDATA ; PUT ON BUS INC DE ; INCREMENT BUF POS DEC HL ; DEC LOOP COUNTER - LD A,$05 \ CALL IMM_WRITECTRL + IMM_WCTL($05) LD A,(DE) ; GET NEXT BYTE (SECOND OF PAIR) CALL IMM_WRITEDATA ; PUT ON BUS INC DE ; INCREMENT BUF POS DEC HL ; DEC LOOP COUNTER - LD A,$00 \ CALL IMM_WRITECTRL + IMM_WCTL($00) LD A,H ; CHECK LOOP COUNTER OR L JR NZ,IMM_PUTDATALEN1 ; LOOP TILL DONE - LD A,$04 \ CALL IMM_WRITECTRL + IMM_WCTL($04) RET ; ; READ SCSI COMMAND STATUS @@ -1018,10 +1027,10 @@ IMM_GETSTATUS: ; TERMINATE A BULD READ OPERATION ; IMM_ENDREAD: - LD A,$04 \ CALL IMM_WRITECTRL - LD A,$0C \ CALL IMM_WRITECTRL - LD A,$0E \ CALL IMM_WRITECTRL - LD A,$04 \ CALL IMM_WRITECTRL + IMM_WCTL($04) + IMM_WCTL($0C) + IMM_WCTL($0E) + IMM_WCTL($04) RET ; ; THIS IS THE MAIN SCSI ENGINE. BASICALLY, IT SELECTS THE DEVICE diff --git a/Source/HBIOS/ppa.asm b/Source/HBIOS/ppa.asm index 8522738c..d10b88ab 100644 --- a/Source/HBIOS/ppa.asm +++ b/Source/HBIOS/ppa.asm @@ -71,14 +71,16 @@ ; ; TODO: ; +; - CURRENTLY HAS ONLY DETECTION LOGIC. NEED TO WRITE THE REST!!! +; ; - OPTIMIZE READ/WRITE LOOPS ; ; NOTES: ; ; - THIS DRIVER IS FOR THE ZIP DRIVE PPA INTERFACE. IT WILL SIMPLY -; FAIL TO EVEN RECOGNIZE A ZIP DRIVE WITH THE OLDER PPA INTERFACE. +; FAIL TO EVEN RECOGNIZE A ZIP DRIVE WITH THE NEWER IMM INTERFACE. ; THERE DOES NOT SEEM TO BE A WAY TO VISUALLY DETERMINE IF A ZIP -; DRIVE IS PPA OR PPA. SIGH. +; DRIVE IS PPA OR IMM. SIGH. ; ; - THERE ARE SOME HARD CODED TIMEOUT LOOPS IN THE CODE. THEY ARE ; WORKING OK ON A 7 MHZ Z80. THEY ARE LIKELY TO NEED TWEAKING ON @@ -130,6 +132,11 @@ PPA_IOBASE .EQU 3 ; IO BASE ADDRESS (BYTE) PPA_MEDCAP .EQU 4 ; MEDIA CAPACITY (DWORD) PPA_LBA .EQU 8 ; OFFSET OF LBA (DWORD) ; +; MACROS +; +#DEFINE PPA_WCTL(VAL) LD A,VAL \ CALL PPA_WRITECTRL +#DEFINE PPA_WDATA(VAL) LD A,VAL \ CALL PPA_WRITEDATA +; ;============================================================================= ; INITIALIZATION ENTRY POINT ;============================================================================= @@ -303,7 +310,7 @@ PPA_READ: ; ; PPA_WRITE: - CALL HB_DSKREAD ; HOOK DISK WRITE CONTROLLER + CALL HB_DSKWRITE ; HOOK DISK WRITE CONTROLLER LD A,SCSI_CMD_WRITE ; SETUP SCSI WRITE LD (PPA_CMD_RW),A ; AND SAVE IT IN SCSI CMD JP PPA_IO ; DO THE I/O @@ -463,7 +470,7 @@ PPA_WAITDONE1: DEC HL LD A,H OR L - JP Z,IMM_CMD_TIMEOUT ; TIMEOUT + ;JP Z,PPA_CMD_TIMEOUT ; TIMEOUT JR PPA_WAITDONE1 ; ; OUTPUT BYTE IN A TO THE DATA PORT @@ -772,7 +779,7 @@ PPA_PRTPREFIX: PUSH AF CALL NEWLINE PRTS("PPA$") - LD A,(IY+IMM_DEV) ; GET CURRENT DEVICE NUM + LD A,(IY+PPA_DEV) ; GET CURRENT DEVICE NUM CALL PRTDECB CALL PC_COLON POP AF diff --git a/Source/HBIOS/std.asm b/Source/HBIOS/std.asm index f101ea8d..fe0c4a3f 100644 --- a/Source/HBIOS/std.asm +++ b/Source/HBIOS/std.asm @@ -260,6 +260,12 @@ IMMMODE_NONE .EQU 0 ; NONE IMMMODE_SPP .EQU 1 ; IBM PC STANDARD PAR PORT (SPP) IMMMODE_MG014 .EQU 2 ; RCBUS MG014 STYLE INTERFACE ; +; SYQ DRIVER MODE SELECTIONS +; +SYQMODE_NONE .EQU 0 ; NONE +SYQMODE_SPP .EQU 1 ; IBM PC STANDARD PAR PORT (SPP) +SYQMODE_MG014 .EQU 2 ; RCBUS MG014 STYLE INTERFACE +; ; GDC MONITOR SELECTIONS ; GDCMON_NONE .EQU 0 diff --git a/Source/HBIOS/syq.asm b/Source/HBIOS/syq.asm new file mode 100644 index 00000000..737c4fbf --- /dev/null +++ b/Source/HBIOS/syq.asm @@ -0,0 +1,1327 @@ +; +;============================================================================= +; SYQ DISK DRIVER +;============================================================================= +; +; PARALLEL PORT INTERFACE FOR ATA DISK DEVICES USING A PARALLEL PORT +; ADAPTER. PRIMARILY TARGETS PARALLEL PORT SYQUEST DRIVES. +; +; INTENDED TO CO-EXIST WITH LPT DRIVER. +; +; CREATED BY WAYNE WARTHEN FOR ROMWBW HBIOS. +; MUCH OF THE CODE IS DERIVED FROM FUZIX (ALAN COX). +; +; 5/29/2023 WBW - INITIAL RELEASE +; +;============================================================================= +; +; IBM PC STANDARD PARALLEL PORT (SPP): +; - NHYODYNE PRINT MODULE +; +; PORT 0 (OUTPUT): +; +; D7 D6 D5 D4 D3 D2 D1 D0 +; +-------+-------+-------+-------+-------+-------+-------+-------+ +; | PD7 | PD6 | PD5 | PD4 | PD3 | PD2 | PD1 | PD0 | +; +-------+-------+-------+-------+-------+-------+-------+-------+ +; +; PORT 1 (INPUT): +; +; D7 D6 D5 D4 D3 D2 D1 D0 +; +-------+-------+-------+-------+-------+-------+-------+-------+ +; | /BUSY | /ACK | POUT | SEL | /ERR | 0 | 0 | 0 | +; +-------+-------+-------+-------+-------+-------+-------+-------+ +; +; PORT 2 (OUTPUT): +; +; D7 D6 D5 D4 D3 D2 D1 D0 +; +-------+-------+-------+-------+-------+-------+-------+-------+ +; | STAT1 | STAT0 | ENBL | PINT | SEL | RES | LF | STB | +; +-------+-------+-------+-------+-------+-------+-------+-------+ +; +;============================================================================= +; +; MG014 STYLE INTERFACE: +; - RCBUS MG014 MODULE +; +; PORT 0 (OUTPUT): +; +; D7 D6 D5 D4 D3 D2 D1 D0 +; +-------+-------+-------+-------+-------+-------+-------+-------+ +; | PD7 | PD6 | PD5 | PD4 | PD3 | PD2 | PD1 | PD0 | +; +-------+-------+-------+-------+-------+-------+-------+-------+ +; +; PORT 1 (INPUT): +; +; D7 D6 D5 D4 D3 D2 D1 D0 +; +-------+-------+-------+-------+-------+-------+-------+-------+ +; | | | | /ERR | SEL | POUT | BUSY | /ACK | +; +-------+-------+-------+-------+-------+-------+-------+-------+ +; +; PORT 2 (OUTPUT): +; +; D7 D6 D5 D4 D3 D2 D1 D0 +; +-------+-------+-------+-------+-------+-------+-------+-------+ +; | LED | | | | /SEL | /RES | /LF | /STB | +; +-------+-------+-------+-------+-------+-------+-------+-------+ +; +;============================================================================= +; +; TODO: +; +; - STRAIGHTEN OUT TIMEOUTS +; +; - CODE NEEDS TO BE REORGANIZED +; +; - OPTIMIZE READ/WRITE LOOPS +; +; NOTES: +; +; - TESTED ON THE SYQUEST SPARQ ONLY. +; +; - THERE ARE SOME HARD CODED TIMEOUT LOOPS IN THE CODE. THEY ARE +; WORKING OK ON A 7 MHZ Z80. THEY ARE LIKELY TO NEED TWEAKING ON +; FASTER CPUS. +; +; - THIS DRIVER OPERATES PURELY IN NIBBLE MODE. I SUSPECT IT IS +; POSSIBLE TO USE FULL BYTE MODE (PS2 STYLE), BUT I HAVE NOT +; ATTEMPTED IT. +; +; - RELATIVE TO ABOVE, THIS BEAST IS SLOW. IN ADDITION TO THE +; NIBBLE MODE READS, THE MG014 ASSIGNS SIGNALS DIFFERENTLY THAN +; THE STANDARD IBM PARALLEL PORT WHICH NECESSITATES A BUNCH OF EXTRA +; BIT FIDDLING ON EVERY READ. +; +; - SOME OF THE DATA TRANSFERS HAVE NO BUFFER OVERRUN CHECKS. IT IS +; ASSUMED SCSI DEVICES WILL SEND/REQUEST THE EXPECTED NUMBER OF BYTES. +; +; SYQ PORT OFFSETS +; +SYQ_IODATA .EQU 0 ; PORT A, DATA, OUT +SYQ_IOSTAT .EQU 1 ; PORT B, STATUS, IN +SYQ_IOCTRL .EQU 2 ; PORT C, CTRL, OUT +SYQ_IOSETUP .EQU 3 ; PPI SETUP +; +; THIS INTERFACE TRANSLATES BETWEEN PPI AND ATA. THE ATA REGSITERS +; CAN BE ACCESSED THROUGH THE INTERFACE. THE INTERFACE ALSO HAS +; REGISTERS OF ITS OWN. +; +SYQ_REG_NAT .EQU 0 ; START OF NATIVE INTERFACE REGISTERS +SYQ_REG_PRI .EQU $18 ; START OF PRIMARY ATA REGISTERS +SYQ_REG_ALT .EQU $10 ; START OF ALTERNATE ATA REGISTERS +; +SYQ_REG_DATA .EQU SYQ_REG_PRI + $00 ; DATA /OUTPUT (R/W) +SYQ_REG_ERR .EQU SYQ_REG_PRI + $01 ; ERROR REGISTER (R) +SYQ_REG_FEAT .EQU SYQ_REG_PRI + $01 ; FEATURES REGISTER (W) +SYQ_REG_COUNT .EQU SYQ_REG_PRI + $02 ; SECTOR COUNT REGISTER (R/W) +SYQ_REG_SECT .EQU SYQ_REG_PRI + $03 ; SECTOR NUMBER REGISTER (R/W) +SYQ_REG_CYLLO .EQU SYQ_REG_PRI + $04 ; CYLINDER NUM REGISTER (LSB) (R/W) +SYQ_REG_CYLHI .EQU SYQ_REG_PRI + $05 ; CYLINDER NUM REGISTER (MSB) (R/W) +SYQ_REG_DRVHD .EQU SYQ_REG_PRI + $06 ; DRIVE/HEAD REGISTER (R/W) +SYQ_REG_LBA0 .EQU SYQ_REG_PRI + $03 ; LBA BYTE 0 (BITS 0-7) (R/W) +SYQ_REG_LBA1 .EQU SYQ_REG_PRI + $04 ; LBA BYTE 1 (BITS 8-15) (R/W) +SYQ_REG_LBA2 .EQU SYQ_REG_PRI + $05 ; LBA BYTE 2 (BITS 16-23) (R/W) +SYQ_REG_LBA3 .EQU SYQ_REG_PRI + $06 ; LBA BYTE 3 (BITS 24-27) (R/W) +SYQ_REG_STAT .EQU SYQ_REG_PRI + $07 ; STATUS REGISTER (R) +SYQ_REG_CMD .EQU SYQ_REG_PRI + $07 ; COMMAND REGISTER (EXECUTE) (W) +SYQ_REG_XAR .EQU SYQ_REG_ALT + $00 ; ECB DIDE EXTERNAL ADDRESS REGISTER (W) +SYQ_REG_ALTSTAT .EQU SYQ_REG_ALT + $06 ; ALTERNATE STATUS REGISTER (R) +SYQ_REG_CTRL .EQU SYQ_REG_ALT + $06 ; DEVICE CONTROL REGISTER (W) +SYQ_REG_DRVADR .EQU SYQ_REG_ALT + $07 ; DRIVE ADDRESS REGISTER (R) +; +; ATA COMMAND BYTES +; +SYQ_CMD_NOP .EQU $00 +SYQ_CMD_DEVRES .EQU $08 +SYQ_CMD_RECAL .EQU $10 +SYQ_CMD_READ .EQU $20 +SYQ_CMD_WRITE .EQU $30 +SYQ_CMD_DEVDIAG .EQU $90 +SYQ_CMD_IDPKTDEV .EQU $A1 +SYQ_CMD_MEDIASTATUS .EQU $DA +SYQ_CMD_IDDEV .EQU $EC +SYQ_CMD_SETFEAT .EQU $EF +; +; POST-COMMAND DATA TRANSFER OPTIONS +; +SYQ_XFR_NONE .EQU 0 ; NO DATA TRANSFER FOR CMD +SYQ_XFR_READ .EQU 1 ; CMD IS A READ OPERATION +SYQ_XFR_WRITE .EQU 2 ; CMD IS A WRITE OPERATION +; +; SYQ DEVICE STATUS +; +SYQ_STOK .EQU 0 +SYQ_STNOMEDIA .EQU -1 +SYQ_STCMDERR .EQU -2 +SYQ_STIOERR .EQU -3 +SYQ_STTO .EQU -4 +SYQ_STNOTSUP .EQU -5 +; +; SYQ DEVICE CONFIGURATION +; +SYQ_CFGSIZ .EQU 12 ; SIZE OF CFG TBL ENTRIES +; +; PER DEVICE DATA OFFSETS IN CONFIG TABLE ENTRIES +; +SYQ_DEV .EQU 0 ; OFFSET OF DEVICE NUMBER (BYTE) +SYQ_MODE .EQU 1 ; OPERATION MODE: SYQ MODE (BYTE) +SYQ_STAT .EQU 2 ; LAST STATUS (BYTE) +SYQ_IOBASE .EQU 3 ; IO BASE ADDRESS (BYTE) +SYQ_MEDCAP .EQU 4 ; MEDIA CAPACITY (DWORD) +SYQ_LBA .EQU 8 ; OFFSET OF LBA (DWORD) +; +; THE SYQ_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. THE SLOW TIMEOUT IS USED TO WAIT FOR A DEVICE TO +; BECOME READY AFTER A HARD RESET (SPIN UP, ETC.). THE NORMAL TIMEOUT +; IS USED DURING NORMAL OPERATION FOR ALL I/O OPERATIONS WHICH SHOULD +; OCCUR PRETTY FAST. NOTE THAT THE ATA SPEC ALLOWS UP TO 30 SECONDS +; FOR DEVICES TO RESPOND. WE ARE USING MUCH MORE AGGRESSIVE VALUES +; BASED ON REAL WORLD EXPERIENCE. +; THE PICO TIMEOUT (TOPICO) IS A SPECIAL TIMEOUT FOR THE RC2014 SD +; PICO TO WAIT FOR THE PICO DEVICE TO INITIALIZE. +; +SYQ_TOSLOW .EQU 200 ; SLOW TIMEOUT IS 20 SECS +SYQ_TONORM .EQU 5 ; NORMAL TIMEOUT IS 0.55 SECS +SYQ_TOPICO .EQU 50 ; RC2014 SD PICO (5 SECONDS) +; +; MACROS +; +#DEFINE SYQ_W0(VAL) LD A,VAL \ CALL SYQ_WRITEDATA +#DEFINE SYQ_R1 CALL SYQ_READSTATUS +#DEFINE SYQ_W2(VAL) LD A,VAL \ CALL SYQ_WRITECTRL +; +#DEFINE SYQ_WR(REG,VAL) LD C,REG \ LD A,VAL \ CALL SYQ_WRITEREG +#DEFINE SYQ_RR(REG) LD C,REG \ CALL SYQ_READREG +; +;============================================================================= +; INITIALIZATION ENTRY POINT +;============================================================================= +; +SYQ_INIT: + LD IY,SYQ_CFG ; POINT TO START OF CONFIG TABLE +; +SYQ_INIT1: + LD A,(IY) ; LOAD FIRST BYTE TO CHECK FOR END + CP $FF ; CHECK FOR END OF TABLE VALUE + JR NZ,SYQ_INIT2 ; IF NOT END OF TABLE, CONTINUE + XOR A ; SIGNAL SUCCESS + RET ; AND RETURN +; +SYQ_INIT2: + CALL NEWLINE ; FORMATTING + PRTS("SYQ:$") ; DRIVER LABEL +; + PRTS(" IO=0x$") ; LABEL FOR IO ADDRESS + LD A,(IY+SYQ_IOBASE) ; GET IO BASE ADDRES + CALL PRTHEXBYTE ; DISPLAY IT +; + PRTS(" MODE=$") ; LABEL FOR MODE + LD A,(IY+SYQ_MODE) ; GET MODE BITS + LD HL,SYQ_STR_MODE_MAP + ADD A,A + CALL ADDHLA + LD E,(HL) + INC HL + LD D,(HL) + CALL WRITESTR +; + ; CHECK FOR HARDWARE PRESENCE + CALL SYQ_DETECT ; PROBE FOR INTERFACE + JR Z,SYQ_INIT4 ; IF FOUND, CONTINUE + CALL PC_SPACE ; FORMATTING + LD DE,SYQ_STR_NOHW ; NO SYQ MESSAGE + CALL WRITESTR ; DISPLAY IT + JR SYQ_INIT6 ; SKIP CFG ENTRY +; +SYQ_INIT4: + ; UPDATE DRIVER RELATIVE UNIT NUMBER IN CONFIG TABLE + LD A,(SYQ_DEVNUM) ; GET NEXT UNIT NUM TO ASSIGN + LD (IY+SYQ_DEV),A ; UPDATE IT + INC A ; BUMP TO NEXT UNIT NUM TO ASSIGN + LD (SYQ_DEVNUM),A ; SAVE IT +; + ; ADD UNIT TO GLOBAL DISK UNIT TABLE + LD BC,SYQ_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 +; + CALL SYQ_RESET ; RESET/INIT THE INTERFACE +#IF (SYQTRACE <= 1) + CALL NZ,SYQ_PRTSTAT +#ENDIF + JR NZ,SYQ_INIT6 +; + ; START PRINTING DEVICE INFO + CALL SYQ_PRTPREFIX ; PRINT DEVICE PREFIX +; +SYQ_INIT5: + ; PRINT STORAGE CAPACITY (BLOCK COUNT) + PRTS(" BLOCKS=0x$") ; PRINT FIELD LABEL + LD A,SYQ_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 PRTDEC32 ; PRINT DWORD IN DECIMAL + PRTS("MB$") ; PRINT SUFFIX +; +SYQ_INIT6: + LD DE,SYQ_CFGSIZ ; SIZE OF CFG TABLE ENTRY + ADD IY,DE ; BUMP POINTER + JP SYQ_INIT1 ; AND LOOP +; +;---------------------------------------------------------------------- +; PROBE FOR SYQ HARDWARE +;---------------------------------------------------------------------- +; +; ON RETURN, ZF SET INDICATES HARDWARE FOUND +; +SYQ_DETECT: +; +#IF (SYQTRACE >= 3) + PRTS("\r\nDETECT:$") +#ENDIF +; + ; INITIALIZE 8255 + LD A,(IY+SYQ_IOBASE) ; BASE PORT + ADD A,SYQ_IOSETUP ; BUMP TO SETUP PORT + LD C,A ; MOVE TO C FOR I/O + LD A,$82 ; CONFIG A OUT, B IN, C OUT + OUT (C),A ; DO IT + CALL DELAY ; BRIEF DELAY FOR GOOD MEASURE +; + ; WE USE THIS SEQUENCE TO DETECT AN ACTUAL SYQ DEVICE ON THE + ; PARALLEL PORT. THE VALUES RECORDED IN THE FINAL CALL TO + ; SYQ_DISCONNECT ARE USED TO CONFIRM DEVICE PRESENCE. + ; NO ACTUAL ATA COMMANDS ARE USED. + CALL SYQ_DISCONNECT + CALL SYQ_CONNECT + CALL SYQ_DISCONNECT +; + ; THE SYQ_SN VALUES ARE RECORDED IN THE CPP ROUTINE USED BY + ; SYQ_CONNECT/DISCONNECT. + ; EXPECTING S1=$B8, S2=$18, S3=$38 + LD A,(SYQ_S1) + CP $B8 + RET NZ + LD A,(SYQ_S2) + CP $18 + RET NZ + LD A,(SYQ_S3) + CP $38 + RET NZ +; + ; PRESENCE CHECK + CALL SYQ_CONNECT +; +#IF (SYQTRACE >= 3) + PRTS(" CHK:$") +#ENDIF +; + SYQ_WR($18+2,$AA) + SYQ_WR($18+3,$55) + SYQ_RR($18+2) +#IF (SYQTRACE >= 3) + CALL PC_SPACE + CALL PRTHEXBYTE +#ENDIF + LD H,A + SYQ_RR($18+3) +#IF (SYQTRACE >= 3) + CALL PC_SPACE + CALL PRTHEXBYTE +#ENDIF + LD L,A + CALL SYQ_DISCONNECT +; + LD A,H + CP $AA + RET NZ + LD A,L + CP $55 + RET +; +;============================================================================= +; DRIVER FUNCTION TABLE +;============================================================================= +; +SYQ_FNTBL: + .DW SYQ_STATUS + .DW SYQ_RESET + .DW SYQ_SEEK + .DW SYQ_READ + .DW SYQ_WRITE + .DW SYQ_VERIFY + .DW SYQ_FORMAT + .DW SYQ_DEVICE + .DW SYQ_MEDIA + .DW SYQ_DEFMED + .DW SYQ_CAP + .DW SYQ_GEOM +#IF (($ - SYQ_FNTBL) != (DIO_FNCNT * 2)) + .ECHO "*** INVALID SYQ FUNCTION TABLE ***\n" +#ENDIF +; +SYQ_VERIFY: +SYQ_FORMAT: +SYQ_DEFMED: + SYSCHKERR(ERR_NOTIMPL) ; NOT IMPLEMENTED + RET +; +; +; +SYQ_READ: + CALL HB_DSKREAD ; HOOK DISK READ CONTROLLER + LD B,SYQ_XFR_READ ; READ TRANSFER MODE + LD C,SYQ_CMD_READ ; READ COMMAND BYTE + JP SYQ_IO ; DO THE I/O +; +; +; +SYQ_WRITE: + CALL HB_DSKWRITE ; HOOK DISK WRITE CONTROLLER + LD B,SYQ_XFR_WRITE ; WRITE TRANSFER MODE + LD C,SYQ_CMD_WRITE ; WRITE COMMAND BYTE + JP SYQ_IO ; DO THE I/O +; +; +; +SYQ_IO: + LD (SYQ_DSKBUF),HL ; SAVE DISK BUFFER ADDRESS + LD A,B ; XFR MODE TO ACCUM + LD (SYQ_XFRMODE),A ; AND SAVE IT FOR CMD +; + PUSH BC ; SAVE MODE/COMMAND + CALL SYQ_CHKERR ; CHECK FOR ERR STATUS AND RESET IF SO + POP BC ; RECOVER MODE/COMMAND + JR NZ,SYQ_IO1 ; BAIL OUT ON ERROR +; + LD A,SYQ_LBA ; LBA OFFSET IN CONFIG + CALL LDHLIYA ; POINT TO LBA DWORD + CALL LD32 ; SET DE:HL TO LBA +; + CALL SYQ_CMDSETUP ; SETUP ATA COMMAND BUF + CALL SYQ_RUNCMD ; RUN COMMAND + JR NZ,SYQ_IO1 ; IF ERR, SKIP INCREMENT +; + ; INCREMENT LBA + LD A,SYQ_LBA ; LBA OFFSET + CALL LDHLIYA ; HL := IY + A, REG A TRASHED + CALL INC32HL ; INCREMENT THE VALUE +; + ; INCREMENT DMA + LD HL,SYQ_DSKBUF+1 ; POINT TO MSB OF BUFFER ADR + INC (HL) ; BUMP DMA BY + INC (HL) ; ... 512 BYTES +; + XOR A ; SIGNAL SUCCESS +; +SYQ_IO1: + LD HL,(SYQ_DSKBUF) ; CURRENT DMA TO HL + OR A ; SET FLAGS + RET ; AND DONE +; +; +; +SYQ_STATUS: + ; RETURN UNIT STATUS + LD A,(IY+SYQ_STAT) ; GET STATUS OF SELECTED DEVICE + OR A ; SET FLAGS + RET ; AND RETURN +; +; +; +SYQ_RESET: + JP SYQ_INITDEV ; JUST (RE)INIT DEVICE +; +; +; +SYQ_DEVICE: + LD D,DIODEV_SYQ ; D := DEVICE TYPE + LD E,(IY+SYQ_DEV) ; E := PHYSICAL DEVICE NUMBER + LD C,%01000000 ; C := REMOVABLE HARD DISK + LD H,(IY+SYQ_MODE) ; H := MODE + LD L,(IY+SYQ_IOBASE) ; L := BASE I/O ADDRESS + XOR A ; SIGNAL SUCCESS + RET +; +; SYQ_GETMED +; +SYQ_MEDIA: + LD A,E ; GET FLAGS + OR A ; SET FLAGS + JR Z,SYQ_MEDIA1 ; JUST REPORT CURRENT STATUS AND MEDIA +; + CALL SYQ_RESET ; RESET INCLUDES MEDIA CHECK +; +SYQ_MEDIA1: + LD A,(IY+SYQ_STAT) ; GET STATUS + OR A ; SET FLAGS + LD D,0 ; NO MEDIA CHANGE DETECTED + LD E,MID_HD ; ASSUME WE ARE OK + RET Z ; RETURN IF GOOD INIT + LD E,MID_NONE ; SIGNAL NO MEDIA + LD A,ERR_NOMEDIA ; NO MEDIA ERROR + OR A ; SET FLAGS + RET ; AND RETURN +; +; +; +SYQ_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 (IY+SYQ_LBA+0),L ; SAVE NEW LBA + LD (IY+SYQ_LBA+1),H ; ... + LD (IY+SYQ_LBA+2),E ; ... + LD (IY+SYQ_LBA+3),D ; ... + XOR A ; SIGNAL SUCCESS + RET ; AND RETURN +; +; +; +SYQ_CAP: + LD A,(IY+SYQ_STAT) ; GET STATUS + PUSH AF ; SAVE IT + LD A,SYQ_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 + RET +; +; +; +SYQ_GEOM: + ; FOR LBA, WE SIMULATE CHS ACCESS USING 16 HEADS AND 16 SECTORS + ; RETURN HS:CC -> DE:HL, SET HIGH BIT OF D TO INDICATE LBA CAPABLE + CALL SYQ_CAP ; GET TOTAL BLOCKS IN DE:HL, BLOCK SIZE TO BC + LD L,H ; DIVIDE BY 256 FOR # TRACKS + 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 + RET ; DONE, A STILL HAS SYQ_CAP STATUS +; +;============================================================================= +; FUNCTION SUPPORT ROUTINES +;============================================================================= +; +; OUTPUT BYTE IN A TO THE DATA PORT +; +SYQ_WRITEDATA: + LD C,(IY+SYQ_IOBASE) ; DATA PORT IS AT IOBASE + OUT (C),A ; WRITE THE BYTE + ;CALL DELAY ; IS THIS NEEDED??? + RET ; DONE +; +; +; +SYQ_WRITECTRL: + ; IBM PC INVERTS ALL BUT C2 ON THE BUS, MG014 DOES NOT. + ; BELOW TRANSLATES FROM IBM -> MG014. IT ALSO INVERTS THE + ; MG014 LED SIMPLY TO MAKE IT EASY TO KEEP LED ON DURING + ; ALL ACTIVITY. +; +#IF (SYQMODE == SYQMODE_MG014 + XOR $0B | $80 ; HIGH BIT IS MG014 LED +#ENDIF + LD C,(IY+SYQ_IOBASE) ; GET BASE IO ADDRESS + INC C ; BUMP TO CONTROL PORT + INC C + OUT (C),A ; WRITE TO CONTROL PORT + ;CALL DELAY ; IS THIS NEEDED? + RET ; DONE +; +; READ THE PARALLEL PORT INPUT LINES (STATUS) AND MAP SIGNALS FROM +; MG014 TO IBM STANDARD. NOTE POLARITY CHANGE REQUIRED FOR BUSY. +; +; MG014 IBM PC (SPP) +; -------- -------- +; 0: /ACK 6: /ACK +; 1: BUSY 7: /BUSY +; 2: POUT 5: POUT +; 3: SEL 4: SEL +; 4: /ERR 3: /ERR +; +SYQ_READSTATUS: + LD C,(IY+SYQ_IOBASE) ; IOBASE TO C + INC C ; BUMP TO STATUS PORT + IN A,(C) ; READ IT +; +#IF (SYQMODE == SYQMODE_MG014) +; + ; SHUFFLE BITS ON MG014 + LD C,0 ; INIT RESULT + BIT 0,A ; 0: /ACK + JR Z,SYQ_READSTATUS1 + SET 6,C ; 6: /ACK +SYQ_READSTATUS1: + BIT 1,A ; 1: BUSY + JR NZ,SYQ_READSTATUS2 ; POLARITY CHANGE! + SET 7,C ; 7: /BUSY +SYQ_READSTATUS2: + BIT 2,A ; 2: POUT + JR Z,SYQ_READSTATUS3 + SET 5,C ; 5: POUT +SYQ_READSTATUS3: + BIT 3,A ; 3: SEL + JR Z,SYQ_READSTATUS4 + SET 4,C ; 4: SEL +SYQ_READSTATUS4: + BIT 4,A ; 4: /ERR + JR Z,SYQ_READSTATUS5 + SET 3,C ; 3: /ERR +SYQ_READSTATUS5: + LD A,C ; RESULT TO A +; +#ENDIF +; + RET +; +; SIGNAL SEQUENCE TO CONNECT/DISCONNECT +; VALUE IN A IS WRITTEN TO DATA PORT DURING SEQUENCE +; +SYQ_CPP: + PUSH AF + SYQ_W2(4) + SYQ_W0($22) + SYQ_W0($AA) + SYQ_W0($55) + SYQ_W0(0) + SYQ_W0($FF) +; + CALL SYQ_READSTATUS + AND $B8 + LD (SYQ_S1),A +; + SYQ_W0($87) +; + CALL SYQ_READSTATUS + AND $B8 + LD (SYQ_S2),A +; + SYQ_W0($78) +; + CALL SYQ_READSTATUS + AND $38 + LD (SYQ_S3),A +; + POP AF + CALL SYQ_WRITEDATA + SYQ_W2(4) + SYQ_W2(5) + SYQ_W2(4) + SYQ_W0($FF) +; + ; CONNECT: S1=$B8 S2=$18 S3=$30 + ; DISCONNECT: S1=$B8 S2=$18 S3=$38 + +#IF (SYQTRACE >= 4) + PRTS(" CPP: S1=$") + LD A,(SYQ_S1) + CALL PRTHEXBYTE + PRTS(" S2=$") + LD A,(SYQ_S2) + CALL PRTHEXBYTE + PRTS(" S3=$") + LD A,(SYQ_S3) + CALL PRTHEXBYTE +#ENDIF +; + XOR A ; ASSUME SUCCESS FOR NOW + RET +; +SYQ_S1 .DB 0 +SYQ_S2 .DB 0 +SYQ_S3 .DB 0 +; +; SEQUENCE TO CONNECT TO DEVICE ON PARALLEL PORT BUS. +; +SYQ_CONNECT: +; +#IF (SYQTRACE >= 3) + PRTS(" CONNECT:$") +#ENDIF +; + LD A,$00 ; INITIALIZE THE CHIP + CALL SYQ_CPP +; + LD A,$E0 ; CONNECT TO THE CHIP + CALL SYQ_CPP +; + SYQ_W0(0) + SYQ_W2(1) + SYQ_W2(4) +; + SYQ_WR($08,$10) + SYQ_WR($0C,$14) + SYQ_WR($0A,$38) + SYQ_WR($12,$10) +; + RET +; +; SEQUENCE TO DISCONNECT FROM DEVICE ON PARALLEL PORT BUS. +; THE FINAL SYQ_WRITECTRL IS ONLY TO TURN OFF THE MG014 STATUS LED. +; +SYQ_DISCONNECT: +; +#IF (SYQTRACE >= 3) + PRTS(" DISCON:$") +#ENDIF +; + LD A,$30 ; DISCONNECT FROM THE CHIP + CALL SYQ_CPP +; + ; TURNS OFF MG014 LED + SYQ_W2($8C) +; + RET +; +; WRITE VALUE IN A TO ATA REGISTER IN C +; +SYQ_WRITEREG: + PUSH AF + LD A,$60 + ADD A,C + CALL SYQ_WRITEDATA + SYQ_W2(1) + POP AF + CALL SYQ_WRITEDATA + SYQ_W2(4) + RET +; +; READ VALUE FROM ATA REGISTER IN C +; +SYQ_READREG: + LD A,C + CALL SYQ_WRITEDATA + SYQ_W2(1) + SYQ_W2(3) + CALL SYQ_READSTATUS + AND $F0 + RRCA + RRCA + RRCA + RRCA + LD C,A + PUSH BC + SYQ_W2(4) + CALL SYQ_READSTATUS + AND $F0 + POP BC + OR C + RET +; +; +; +SYQ_WAITRDY: + LD A,(SYQ_TIMEOUT) ; GET TIMEOUT IN 0.05 SECS + LD B,A ; PUT IN OUTER LOOP VAR +SYQ_WAITRDY1: + LD A,B + LD DE,(SYQ_TOSCALER) ; CPU SPPED SCALER TO INNER LOOP VAR +SYQ_WAITRDY2: + SYQ_RR(SYQ_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,SYQ_WAITRDY2 ; INNER LOOP RETURN + DJNZ SYQ_WAITRDY1 ; OUTER LOOP RETURN + JP SYQ_CMD_TIMEOUT ; EXIT WITH RDYTO ERR +; +; +; +SYQ_WAITDRQ: + LD A,(SYQ_TIMEOUT) ; GET TIMEOUT IN 0.1 SECS + LD B,A ; PUT IN OUTER LOOP VAR +SYQ_WAITDRQ1: + LD DE,(SYQ_TOSCALER) ; CPU SPPED SCALER TO INNER LOOP VAR +SYQ_WAITDRQ2: + SYQ_RR(SYQ_REG_STAT) + LD C,A ; SAVE IT??? + AND %10001000 ; TO FILL (OR READY TO FILL) + XOR %00001000 + RET Z + DEC DE + LD A,D + OR E + JR NZ,SYQ_WAITDRQ2 + DJNZ SYQ_WAITDRQ1 + JP SYQ_CMD_TIMEOUT ; EXIT WITH BUFTO ERR +; +; +; +SYQ_WAITBSY: + LD A,(SYQ_TIMEOUT) ; GET TIMEOUT IN 0.1 SECS + LD B,A ; PUT IN OUTER LOOP VAR +SYQ_WAITBSY1: + LD DE,(SYQ_TOSCALER) ; CPU SPPED SCALER TO INNER LOOP VAR +SYQ_WAITBSY2: + SYQ_RR(SYQ_REG_STAT) + 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,SYQ_WAITBSY2 ; 12TS + DJNZ SYQ_WAITBSY1 ; ----- + JP SYQ_CMD_TIMEOUT ; EXIT WITH BSYTO ERR ; 180 +; +; RUN AN ATA COMMAND USING CMD BUFFER IN SYQ_CMDBUF. +; DATA TRANSFER MODE IN SYQ_XFRMODE: SYQ_XFR_[NONE|READ|WRITE] +; DATA TRANSFER BUFFER PTR IN SYQ_DSKBUF. +; +SYQ_RUNCMD: +; +#IF (SYQTRACE >= 3) + PRTS(" RUNCMD:$") +#ENDIF +; + CALL SYQ_CONNECT ; CONNECT TO DEVICE +; + LD (SYQ_CMD_STKSAV),SP ; SAVE STACK FOR ERR EXITS + LD HL,SYQ_CMD_EXIT ; SETUP NORMAL RETURN VIA + PUSH HL ; ... SYQ_CMDEXIT + CALL SYQ_WAITRDY ; WAIT FOR DRIVE READY +; + LD B,7 + LD C,SYQ_REG_PRI + 1 + LD HL,SYQ_CMDBUF + 1 +SYQ_RUNCMD1: + LD A,(HL) +#IF (SYQTRACE >= 3) + CALL PC_SPACE + CALL PRTHEXBYTE +#ENDIF + PUSH BC + CALL SYQ_WRITEREG + POP BC + INC HL + INC C + DJNZ SYQ_RUNCMD1 +; +#IF (SYQTRACE >= 3) + PRTS(" -->$") +#ENDIF +; + CALL SYQ_WAITBSY ; WAIT FOR DRIVE READY (COMMAND DONE) + CALL SYQ_GETRES +; + LD A,(SYQ_XFRMODE) ; DATA TRANSFER? + OR A ; SET FLAGS + JR Z,SYQ_CMD_EXIT ; IF NONE, EXIT, A IS ZERO + CP SYQ_XFR_READ ; READ? + JP Z,SYQ_GETBUF ; READ DATA TO BUFFER + CP SYQ_XFR_WRITE ; WRITE? + JP Z,SYQ_PUTBUF ; WRITE DATA FROM BUFFER + JR SYQ_CMD_CMDERR ; INVALID VALUE FOR XFR +; +SYQ_CMD_CMDERR: + LD A,SYQ_STCMDERR ; SIGNAL COMMAND ERROR + JR SYQ_CMD_EXIT ; AND EXIT +; +SYQ_CMD_IOERR: + LD A,SYQ_STIOERR ; SIGNAL IO ERROR + JR SYQ_CMD_EXIT ; AND EXIT +; +SYQ_CMD_TIMEOUT: + LD A,SYQ_STTO ; SIGNAL TIMEOUT ERROR + JR SYQ_CMD_EXIT ; AND EXIT +; +SYQ_CMD_EXIT: + LD SP,(SYQ_CMD_STKSAV) ; UNWIND STACK + PUSH AF ; SAVE RESULT + CALL SYQ_DISCONNECT ; DISCONNECT + POP AF ; RESTORE RESULT + OR A ; ERROR? + JP NZ,SYQ_ERR ; IF SO, HANDLE IT + RET ; NORMAL RETURN +; +; +; +SYQ_GETRES: + SYQ_RR(SYQ_REG_STAT) +#IF (SYQTRACE >= 3) + CALL PC_SPACE + CALL PRTHEXBYTE +#ENDIF + AND %00000001 ; ERROR BIT SET? + RET Z ; NOPE, RETURN WITH ZF +; + SYQ_RR(SYQ_REG_ERR) +#IF (SYQTRACE >= 3) + CALL PC_SPACE + CALL PRTHEXBYTE +#ENDIF + JP SYQ_CMD_CMDERR +; +; HL= BUFFER +; +SYQ_GETBUF: + SYQ_W0(7) + SYQ_W2(1) + SYQ_W2(3) + SYQ_W0($FF) +; + LD HL,(SYQ_DSKBUF) ; INIT BUFFER PTR + LD B,0 ; READ 256 WORDS +SYQ_GETBUF1: +; + ; FIRST BYTE + SYQ_W2(6) + SYQ_R1 ; GET LOW NIBBLE + PUSH AF ; SAVE NIBBLE +; BIT 3,A ; IF BIT SET +; JR NZ,SYQ_GETBUF2 ; USE SAVE VALUE FOR NEXT NIBBLE + SYQ_W2(4) + SYQ_R1 ; GET HIGH NIBBLE +;SYQ_GETBUF2: + AND $F0 ; TOP BITS FOR SECOND NIBBLE + LD C,A ; SAVE IN C + POP AF ; RECOVER FIRST NIBBLE + RRCA ; MOVE TO LOW BITS + RRCA + RRCA + RRCA + AND $0F ; ONLY LOW BITS + OR C ; COMBINE + LD (HL),A ; SAVE IT + INC HL ; BUMP BUF PTR + ;CALL PC_SPACE + ;CALL PRTHEXBYTE +; + ; SPECIAL HANDLING FOR LAST BYTE + LD A,B ; GET ITERATION COUNTER + CP 1 ; LAST ITERATION? + JR NZ,SYQ_GETBUF3 ; IF NOT, BYPASS + SYQ_W0($FD) ; LAST BYTE ACTION +SYQ_GETBUF3: +; + ; SECOND BYTE + SYQ_W2(7) + SYQ_R1 ; GET LOW NIBBLE + PUSH AF ; SAVE NIBBLE +; BIT 3,A ; IF BIT SET +; JR NZ,SYQ_GETBUF4 ; USE SAVE VALUE FOR NEXT NIBBLE + SYQ_W2(5) + SYQ_R1 ; GET HIGH NIBBLE +;SYQ_GETBUF4: + AND $F0 ; TOP BITS FOR SECOND NIBBLE + LD C,A ; SAVE IN C + POP AF ; RECOVER FIRST NIBBLE + RRCA ; MOVE TO LOW BITS + RRCA + RRCA + RRCA + AND $0F ; ONLY LOW BITS + OR C ; COMBINE + LD (HL),A ; SAVE IT + INC HL ; BUMP BUF PTR + ;CALL PC_SPACE + ;CALL PRTHEXBYTE +; + DJNZ SYQ_GETBUF1 ; LOOP TILL DONE +; + SYQ_W0(0) + SYQ_W2(4) +; + XOR A ; SIGNAL SUCCESS + RET +; +; HL= BUFFER +; +SYQ_PUTBUF: + SYQ_W0($67) + SYQ_W2(1) + SYQ_W2(5) +; + LD HL,(SYQ_DSKBUF) ; INIT BUFFER PTR + LD B,0 ; READ 256 WORDS +SYQ_PUTBUF1: +; + ; FIRST BYTE + LD A,(HL) + INC HL + CALL SYQ_WRITEDATA + SYQ_W2(4) +; + ; SECOND BYTE + LD A,(HL) + INC HL + CALL SYQ_WRITEDATA + SYQ_W2(5) +; + DJNZ SYQ_PUTBUF1 +; + SYQ_W2(7) + SYQ_W2(4) +; + XOR A + RET + +; +; CHECK CURRENT DEVICE FOR ERROR STATUS AND ATTEMPT TO RECOVER +; VIA RESET IF DEVICE IS IN ERROR. +; +SYQ_CHKERR: + LD A,(IY+SYQ_STAT) ; GET STATUS + OR A ; SET FLAGS + CALL NZ,SYQ_RESET ; IF ERROR STATUS, RESET BUS + RET +; +; (RE)INITIALIZE DEVICE +; +SYQ_INITDEV: +; +#IF (SYQTRACE >= 3) + PRTS("\r\nINITDEV:$") +#ENDIF +; + ; INITIALIZE 8255 + LD A,(IY+SYQ_IOBASE) ; BASE PORT + ADD A,SYQ_IOSETUP ; BUMP TO SETUP PORT + LD C,A ; MOVE TO C FOR I/O + LD A,$82 ; CONFIG A OUT, B IN, C OUT + OUT (C),A ; DO IT + CALL DELAY ; SHORT DELAY FOR BUS SETTLE +; + CALL SYQ_CONNECT ; NOW CONNECT TO BUS + CALL SYQ_DISCONNECT ; DISCONNECT FIRST JUST IN CASE + CALL SYQ_CONNECT ; NOW CONNECT TO BUS +; + ; ATA SOFT RESET + LD C,SYQ_REG_CTRL + LD A,%00001010 + CALL SYQ_WRITEREG + CALL DELAY + LD C,SYQ_REG_CTRL + LD A,%00001110 + CALL SYQ_WRITEREG + CALL DELAY + LD C,SYQ_REG_CTRL + LD A,%00001010 + CALL SYQ_WRITEREG + CALL DELAY + +#IF (SYQTRACE >= 3) + ; SELECT PRIMARY IDE DRIVE + LD C,SYQ_REG_DRVHD + LD A,$A0 + CALL SYQ_WRITEREG +; + PRTS(" ATA REGS:$") + CALL SYQ_REGDUMP ; DUMP ATA PRIMARY REGISTERS +#ENDIF +; + CALL SYQ_DISCONNECT +; + ; ISSUE DEVICE IDENTIFY COMMAND TO READ AND RECORD + ; DEVICE CAPACITY. + CALL SYQ_IDENTIFY ; RUN IDENTIFY COMMAND + RET NZ ; BAIL OUT ON ERROR +; + LD DE,HB_WRKBUF ; POINT TO BUFFER +#IF (SYQTRACE >= 4) + CALL DUMP_BUFFER ; DUMP IT IF DEBUGGING +#ENDIF +; + ; GET DEVICE CAPACITY AND SAVE IT + LD A,SYQ_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 + CALL ADDHLA ; POINT TO ADDRESS OF SECTOR COUNT + CALL LD32 ; LOAD IT TO DE:HL + POP BC ; RECOVER POINTER TO CAPACITY ENTRY + CALL ST32 ; SAVE CAPACITY +; + ; ISSUE MEDIA STATUS A FEW TIMES TO CLEAR ANY PENDING ERRORS + ; (LIKE MEDIA CHANGE) AND DETERMINE IF MEDIA IS LOADED. IF + ; AN ERROR IS STILL OCCURRING AFTER MULTIPLE ATTEMPTS, WE + ; ASSUME MEDIA IS NOT LOADED IN DEVICE. + LD B,4 ; 4 TRIES +SYQ_INITDEV1: + PUSH BC + CALL SYQ_MEDIASTATUS + POP BC + JR Z,SYQ_INITDEV2 ; MOVE ON IF NO ERROR + DJNZ SYQ_INITDEV1 ; LOOP AS NEEDED + JP SYQ_NOMEDIA ; EXIT W/ NO MEDIA STATUS +; +SYQ_INITDEV2: +; + ; RECORD STATUS OK + XOR A ; A := 0 (STATUS = OK) + LD (IY+SYQ_STAT),A ; SAVE IT +; + RET ; RETURN, A=0, Z SET +; +; +; +SYQ_IDENTIFY: +#IF (SYQTRACE >= 3) + CALL SYQ_PRTPREFIX + PRTS(" IDDEV$") +#ENDIF +; + LD C,SYQ_CMD_IDDEV + LD DE,0 + LD HL,0 + CALL SYQ_CMDSETUP +; + LD HL,HB_WRKBUF + LD (SYQ_DSKBUF),HL + LD A,SYQ_XFR_READ + LD (SYQ_XFRMODE),A +; + JP SYQ_RUNCMD +; +; +; +SYQ_MEDIASTATUS: +#IF (SYQTRACE >= 3) + CALL SYQ_PRTPREFIX + PRTS(" MEDIASTATUS$") +#ENDIF +; + LD C,SYQ_CMD_MEDIASTATUS + LD DE,0 + LD HL,0 + CALL SYQ_CMDSETUP +; + LD HL,0 + LD (SYQ_DSKBUF),HL + LD A,SYQ_XFR_NONE + LD (SYQ_XFRMODE),A +; + JP SYQ_RUNCMD +; +; DE:HL LBA +; C: COMMAND +; +SYQ_CMDSETUP: + XOR A + LD (SYQ_CMD_FEAT),A + INC A + LD (SYQ_CMD_COUNT),A + LD (SYQ_CMD_LBA0),HL + LD (SYQ_CMD_LBA2),DE + LD A,$E0 + LD (SYQ_CMD_DRV),A + LD A,C + LD (SYQ_CMD_OP),A + RET +; +;============================================================================= +; ERROR HANDLING AND DIAGNOSTICS +;============================================================================= +; +; ERROR HANDLERS +; +SYQ_NOMEDIA: + LD A,SYQ_STNOMEDIA + JR SYQ_ERR +; +SYQ_CMDERR: + LD A,SYQ_STCMDERR + JR SYQ_ERR +; +SYQ_IOERR: + LD A,SYQ_STIOERR + JR SYQ_ERR +; +SYQ_TO: + LD A,SYQ_STTO + JR SYQ_ERR +; +SYQ_NOTSUP: + LD A,SYQ_STNOTSUP + JR SYQ_ERR +; +SYQ_ERR: + LD (IY+SYQ_STAT),A ; SAVE NEW STATUS +; +SYQ_ERR2: +#IF (SYQTRACE >= 2) + CALL SYQ_PRTSTAT +#ENDIF + OR A ; SET FLAGS + RET +; +; +; +SYQ_PRTERR: + RET Z ; DONE IF NO ERRORS + ; FALL THRU TO SYQ_PRTSTAT +; +; PRINT FULL DEVICE STATUS LINE +; +SYQ_PRTSTAT: + PUSH AF + PUSH DE + PUSH HL + LD A,(IY+SYQ_STAT) + CALL SYQ_PRTPREFIX ; PRINT UNIT PREFIX + CALL PC_SPACE ; FORMATTING + CALL SYQ_PRTSTATSTR + POP HL + POP DE + POP AF + RET +; +; PRINT STATUS STRING +; +SYQ_PRTSTATSTR: + PUSH AF + PUSH DE + PUSH HL + LD A,(IY+SYQ_STAT) + NEG + LD HL,SYQ_STR_ST_MAP + ADD A,A + CALL ADDHLA + LD E,(HL) + INC HL + LD D,(HL) + CALL WRITESTR + POP HL + POP DE + POP AF + RET +; +; PRINT ALL REGISTERS DIRECTLY FROM DEVICE +; DEVICE MUST BE CONNECTED AND SELECTED PRIOR TO CALL +; +SYQ_REGDUMP: + PUSH AF + PUSH BC + CALL PC_SPACE + CALL PC_LBKT + LD B,8 + LD C,SYQ_REG_PRI +SYQ_REGDUMP1: + PUSH BC + CALL SYQ_READREG + POP BC + CALL PRTHEXBYTE + INC C + DEC B + CALL NZ,PC_SPACE + JR NZ,SYQ_REGDUMP1 + CALL PC_RBKT + POP BC + POP AF + RET +; +; PRINT DEVICE/UNIT PREFIX +; +SYQ_PRTPREFIX: + PUSH AF + CALL NEWLINE + PRTS("SYQ$") + LD A,(IY+SYQ_DEV) ; GET CURRENT DEVICE NUM + CALL PRTDECB + CALL PC_COLON + POP AF + RET +; +;============================================================================= +; STRING DATA +;============================================================================= +; +SYQ_STR_ST_MAP: + .DW SYQ_STR_ST_OK + .DW SYQ_STR_ST_NOMEDIA + .DW SYQ_STR_ST_CMDERR + .DW SYQ_STR_ST_IOERR + .DW SYQ_STR_ST_TO + .DW SYQ_STR_ST_NOTSUP +; +SYQ_STR_ST_OK .TEXT "OK$" +SYQ_STR_ST_NOMEDIA .TEXT "NO MEDIA$" +SYQ_STR_ST_CMDERR .TEXT "COMMAND ERROR$" +SYQ_STR_ST_IOERR .TEXT "IO ERROR$" +SYQ_STR_ST_TO .TEXT "TIMEOUT$" +SYQ_STR_ST_NOTSUP .TEXT "NOT SUPPORTED$" +SYQ_STR_ST_UNK .TEXT "UNKNOWN ERROR$" +; +SYQ_STR_MODE_MAP: + .DW SYQ_STR_MODE_NONE + .DW SYQ_STR_MODE_SPP + .DW SYQ_STR_MODE_MG014 +; +SYQ_STR_MODE_NONE .TEXT "NONE$" +SYQ_STR_MODE_SPP .TEXT "SPP$" +SYQ_STR_MODE_MG014 .TEXT "MG014$" +; +SYQ_STR_NOHW .TEXT "NOT PRESENT$" +; +;============================================================================= +; DATA STORAGE +;============================================================================= +; +SYQ_DEVNUM .DB 0 ; TEMP DEVICE NUM USED DURING INIT +SYQ_CMDSTK .DW 0 ; STACK PTR FOR CMD ABORTING +SYQ_DSKBUF .DW 0 ; WORKING DISK BUFFER POINTER +SYQ_XFRLEN .DW 0 ; WORKING TRANSFER LENGTH +SYQ_CMD .DB 0 ; CURRENT ATA COMMAND +SYQ_XFRMODE .DB 0 ; COMMAND DATA TRANSFER MODE +SYQ_CMD_STKSAV .DW 0 ; STACK FOR CMD ERROR EXIT +; +SYQ_CMDBUF: +SYQ_CMD_DATA .DB 0 +SYQ_CMD_FEAT .DB 0 +SYQ_CMD_COUNT .DB 0 +SYQ_CMD_LBA0 .DB 0 +SYQ_CMD_LBA1 .DB 0 +SYQ_CMD_LBA2 .DB 0 +SYQ_CMD_DRV .DB 0 +SYQ_CMD_OP .DB 0 +; +SYQ_TIMEOUT .DB SYQ_TONORM ; WAIT FUNCS TIMEOUT IN TENTHS OF SEC +SYQ_TOSCALER .DW CPUMHZ * 556 ; WAIT FUNCS SCALER FOR CPU SPEED +; +; SYQ DEVICE CONFIGURATION TABLE +; +SYQ_CFG: +; +#IF (SYQCNT >= 1) +; +SYQ0_CFG: ; DEVICE 0 + .DB 0 ; DRIVER DEVICE NUMBER (FILLED DYNAMICALLY) + .DB SYQMODE ; DRIVER DEVICE MODE + .DB 0 ; DEVICE STATUS + .DB SYQ0BASE ; IO BASE ADDRESS + .DW 0,0 ; DEVICE CAPACITY + .DW 0,0 ; CURRENT LBA +#ENDIF +; +#IF (SYQCNT >= 2) +; +SYQ1_CFG: ; DEVICE 1 + .DB 0 ; DRIVER DEVICE NUMBER (FILLED DYNAMICALLY) + .DB SYQMODE ; DRIVER DEVICE MODE + .DB 0 ; DEVICE STATUS + .DB SYQ1BASE ; IO BASE ADDRESS + .DW 0,0 ; DEVICE CAPACITY + .DW 0,0 ; CURRENT LBA +#ENDIF +; +#IF ($ - SYQ_CFG) != (SYQCNT * SYQ_CFGSIZ) + .ECHO "*** INVALID SYQ CONFIG TABLE ***\n" +#ENDIF +; + .DB $FF ; END MARKER diff --git a/Source/ver.inc b/Source/ver.inc index 52fa8fb2..70dd66c9 100644 --- a/Source/ver.inc +++ b/Source/ver.inc @@ -2,7 +2,7 @@ #DEFINE RMN 3 #DEFINE RUP 0 #DEFINE RTP 0 -#DEFINE BIOSVER "3.3.0-dev.17" +#DEFINE BIOSVER "3.3.0-dev.18" #define rmj RMJ #define rmn RMN #define rup RUP diff --git a/Source/ver.lib b/Source/ver.lib index 651ebd13..70d1d5ed 100644 --- a/Source/ver.lib +++ b/Source/ver.lib @@ -3,5 +3,5 @@ rmn equ 3 rup equ 0 rtp equ 0 biosver macro - db "3.3.0-dev.17" + db "3.3.0-dev.18" endm