diff --git a/ReadMe.md b/ReadMe.md
index 3727f082..1af8654c 100644
--- a/ReadMe.md
+++ b/ReadMe.md
@@ -3,7 +3,7 @@
**RomWBW ReadMe** \
Version 3.3 \
Wayne Warthen ([wwarthen@gmail.com](mailto:wwarthen@gmail.com)) \
-02 Jun 2023
+06 Jun 2023
# Overview
diff --git a/ReadMe.txt b/ReadMe.txt
index fa0649e6..47d25c02 100644
--- a/ReadMe.txt
+++ b/ReadMe.txt
@@ -1,6 +1,6 @@
RomWBW ReadMe
Wayne Warthen (wwarthen@gmail.com)
-02 Jun 2023
+06 Jun 2023
diff --git a/Source/Doc/Applications.md b/Source/Doc/Applications.md
index 49aab8ff..36b813db 100644
--- a/Source/Doc/Applications.md
+++ b/Source/Doc/Applications.md
@@ -51,6 +51,7 @@ found:
| INTTEST | No | Yes | Yes |
| FAT | No | Yes | Yes |
| TUNE | No | Yes | Yes |
+| WDATE | No | Yes | Yes |
`\clearpage`{=latex}
@@ -1128,3 +1129,85 @@ can be used to reduce your processor speed.
VGMPLAY is still under development. The source code is provided in the
RomWBW distribution.
+
+`\clearpage`{=latex}
+
+# WDATE
+
+`wdate` is a utility for CP/M systems that have Wayne Warthen's
+ROMWBW firmware. It reads or sets the real-time clock, using function
+calls in the BIOS. It should work on any RTC device that is supported by
+ROMWBW, including the internal interrupt-driven timer that is is available
+on some systems.
+
+`wdate` differs from the `rtc.com` utility that is provided with the
+ROMWBW version of CP/M in that it only gets and sets the date/time.
+`rtc.com` can also manipulate the nonvolatile RAM in certain clock
+devices, and modify the charge controller. However, `wdate` is (I would
+argue) easier to use, as it takes its input from the command line, which
+can be edited, and it's less fussy about the format. It doesn't require
+the date to be set if you only want to change the time, for example.
+ In addition, `wdate` has at least some error checking.
+
+`wdate` displays the day-of-week and month as English text, not
+numbers. It calculates the day-of-week from the year, month, and day.
+RTC chips usually store a day-of-week value, but it's useless in this
+application for two reasons: first, the BIOS does not expose it. Second,
+there is no universally-accepted way to interpret it (which day does
+the week start on? Is '0' a valid day of the week?)
+
+## Syntax
+
+| `WDATE`
+| `WDATE ` *`
`*
+| `WDATE ` *`
`*
+| `WDATE ` *`
`*
+
+## Usage
+
+ A> wdate
+ Saturday 27 May 13:14:39 2023
+
+With no arguments, displays the current date and time.
+
+ A> wdate hr min
+
+With two arguments, sets the time in hours and minutes, without changing date
+or seconds
+
+ A> wdate hr min sec
+
+With three arguments, sets the time in hours, minutes, and seconds, without
+changing date
+
+ A> wdate year month day hr min sec
+
+With six arguments, sets date and time. All numbers are one or two digits. The
+two-digit year starts at 2000.
+
+ A> wdate /?
+
+Show a summary of the command-line usage.
+
+## Notes
+
+I've tested this utility with the DS1302 clock board designed by Ed
+Brindly, and on the interrupt-driven timer built into my Z180 board.
+However, it does not interact with hardware, only BIOS; I would expect
+it to work with other hardware.
+
+wdate checks for the non-existence of ROMWBW, and also for failing
+operations on the RTC. It will display the terse "No RTC" message in
+both cases.
+
+The ROMWBW functions that manipulate the date and time operate on BCD
+numbers, as RTC chips themselves usually do. wdate works in decimal, so
+that it can check that the user input makes sense. A substantial part of
+the program's code is taken up by number format conversion and range
+checking.
+
+## Etymology
+
+The `WDATE` application was written and contributed by Kevin Boone.
+The source code is available on GitHub at
+[https://github.com/kevinboone/wdate-cpm/blob/main/README.md](https://github.com/kevinboone/wdate-cpm/blob/main/README.md).
diff --git a/Source/HBIOS/imm.asm b/Source/HBIOS/imm.asm
index a579c6ec..c104b66a 100644
--- a/Source/HBIOS/imm.asm
+++ b/Source/HBIOS/imm.asm
@@ -81,13 +81,11 @@
; THERE DOES NOT SEEM TO BE A WAY TO VISUALLY DETERMINE IF A ZIP
; 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
-; 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.
+; - THIS DRIVER OPERATES USES NIBBLE READ MODE. ALTHOUGH THE 8255
+; (MG014) CAN READ OR WRITE TO PORT A (DATA), IT "GLITCHES" WHEN
+; THE MODE IS CHANGED CAUSING THE CONTROL LINES TO CHANGE AND
+; BREAKS THE PROTOCOL. I SUSPECT THE MBC SPP CAN SUPPORT 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
@@ -197,7 +195,7 @@ IMM_INIT4:
;
CALL IMM_RESET ; RESET/INIT THE INTERFACE
#IF (IMMTRACE <= 1)
- CALL IMM_PRTSTAT
+ CALL NZ,IMM_PRTSTAT
#ENDIF
JR NZ,IMM_INIT6
;
@@ -344,6 +342,13 @@ IMM_IO:
JR NZ,IMM_IO3 ; BAIL OUT ON ERROR
;
LD (IMM_DSKBUF),HL ; SAVE DISK BUFFER ADDRESS
+;
+#IF (DSKYENABLE)
+ LD A,IMM_LBA
+ CALL LDHLIYA
+ CALL HB_DSKACT ; SHOW ACTIVITY
+#ENDIF
+;
; SETUP LBA
; 3 BYTES, LITTLE ENDIAN -> BIG ENDIAN
LD HL,IMM_CMD_RW+1 ; START OF LBA FIELD IN CDB (MSB)
@@ -356,7 +361,6 @@ IMM_IO:
LD A,(IY+IMM_LBA+0)
LD (HL),A
INC HL
-;
; DO SCSI IO
LD DE,(IMM_DSKBUF) ; DISK BUFFER TO DE
LD A,1 ; BLOCK I/O, ONE SECTOR
@@ -756,10 +760,13 @@ IMM_WAIT:
AND $B8
RET ; RETURN W/ RESULT IN A
;
-; MAX OBSERVED IMM_WAITLOOP ITERATIONS IS $0116B3
+; MAX OBSERVED WAITLOOP ITERATIONS IS $0116B3 @ 7.3728 MHZ ON MG014
+; MAX OBSERVED WAITLOOP ITERATIONS IS $028EFE @ 8.000 MHZ ON MBC SPP
;
IMM_LONGWAIT:
- LD B,3 ; VALUE???
+ LD A,(CB_CPUMHZ) ; LOAD CPU SPEED IN MHZ
+ SRL A ; DIVIDE BY 2, GOOD ENOUGH
+ LD B,A ; USE FOR OUTER LOOP COUNT
IMM_WCTL($0C)
IMM_LONGWAIT1:
LD HL,0
@@ -888,7 +895,7 @@ IMM_GETDATA1:
LD (DE),A ; AND SAVE THE FULL BYTE VALUE
INC DE ; NEXT BUFFER POS
INC HL ; INCREMENT BYTES COUNTER
- ;IMM_WCTL($04)
+ IMM_WCTL($04)
JR IMM_GETDATA1 ; LOOP TILL DONE
;
IMM_GETDATA2:
@@ -924,17 +931,18 @@ IMM_GETBLOCK:
LD (IMM_GETBLOCK_B),A ; ... DYNAMIC BITS OF CODE
INC A ; CONTROL PORT
LD C,A ; ... TO C
- ; DE: CLOCK VALUES
#IF (IMMMODE == IMMMODE_MG014)
+ ; DE: CLOCK VALUES
LD D,$06 ^ ($0B | $80)
LD E,$05 ^ ($0B | $80)
+ ; HL: STATMAP
+ LD H,MG014_STATMAPLO >> 8
#ENDIF
#IF (IMMMODE == IMMMODE_SPP)
+ ; DE: CLOCK VALUES
LD D,$06
LD E,$05
#ENDIF
- ; HL: STATMAP
- LD H,MG014_STATMAPLO >> 8
EXX ; SWITCH TO PRI REGS
EX AF,AF' ; SWITCH TO PRI AF
CALL IMM_GETBLOCK1 ; LOOP TWICE
diff --git a/Source/HBIOS/ppa.asm b/Source/HBIOS/ppa.asm
index af4bb390..5b7c370e 100644
--- a/Source/HBIOS/ppa.asm
+++ b/Source/HBIOS/ppa.asm
@@ -81,13 +81,11 @@
; THERE DOES NOT SEEM TO BE A WAY TO VISUALLY DETERMINE IF A ZIP
; 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
-; 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.
+; - THIS DRIVER OPERATES USES NIBBLE READ MODE. ALTHOUGH THE 8255
+; (MG014) CAN READ OR WRITE TO PORT A (DATA), IT "GLITCHES" WHEN
+; THE MODE IS CHANGED CAUSING THE CONTROL LINES TO CHANGE AND
+; BREAKS THE PROTOCOL. I SUSPECT THE MBC SPP CAN SUPPORT 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
@@ -201,7 +199,7 @@ PPA_INIT4:
;
CALL PPA_RESET ; RESET/INIT THE INTERFACE
#IF (PPATRACE <= 1)
- CALL PPA_PRTSTAT
+ CALL NZ,PPA_PRTSTAT
#ENDIF
JR NZ,PPA_INIT6
;
@@ -340,6 +338,13 @@ PPA_IO:
JR NZ,PPA_IO3 ; BAIL OUT ON ERROR
;
LD (PPA_DSKBUF),HL ; SAVE DISK BUFFER ADDRESS
+;
+#IF (DSKYENABLE)
+ LD A,PPA_LBA
+ CALL LDHLIYA
+ CALL HB_DSKACT ; SHOW ACTIVITY
+#ENDIF
+;
; SETUP LBA
; 3 BYTES, LITTLE ENDIAN -> BIG ENDIAN
LD HL,PPA_CMD_RW+1 ; START OF LBA FIELD IN CDB (MSB)
@@ -665,8 +670,6 @@ PPA_SENDCMD1:
RET
;
;
-;
-;
; WAIT FOR SCSI BUS TO BECOME READY WITH A TIMEOUT.
;
PPA_WAITLOOP:
@@ -684,13 +687,19 @@ PPA_WAIT:
PPA_WCTL($0C)
CALL PPA_WAITLOOP
JP Z,PPA_CMD_TIMEOUT ; HANDLE TIMEOUT
+ ;PUSH AF
+ ;IMM_WCTL($04)
+ ;POP AF
AND $F0
RET ; RETURN W/ RESULT IN A
;
-; MAX OBSERVED PPA_WAITLOOP ITERATIONS IS $0116B3
+; MAX OBSERVED WAITLOOP ITERATIONS IS $0116B3 @ 7.372 MHZ ON MG014
+; MAX OBSERVED WAITLOOP ITERATIONS IS $028EFE @ 8.000 MHZ ON MBC SPP
;
PPA_LONGWAIT:
- LD B,3 ; VALUE???
+ LD A,(CB_CPUMHZ) ; LOAD CPU SPEED IN MHZ
+ SRL A ; DIVIDE BY 2, GOOD ENOUGH
+ LD B,A ; USE FOR OUTER LOOP COUNT
PPA_WCTL($0C)
PPA_LONGWAIT1:
LD HL,0
@@ -713,6 +722,7 @@ PPA_LONGWAIT2:
POP AF
#ENDIF
;
+ ;POP AF
AND $F0
RET ; RETURN W/ RESULT IN A
;
@@ -814,17 +824,18 @@ PPA_GETBLOCK:
LD (PPA_GETBLOCK_B),A ; ... DYNAMIC BITS OF CODE
INC A ; CONTROL PORT
LD C,A ; ... TO C
- ; DE: CLOCK VALUES
#IF (PPAMODE == PPAMODE_MG014)
+ ; DE: CLOCK VALUES
LD D,$04 ^ ($0B | $80)
LD E,$06 ^ ($0B | $80)
+ ; HL: STATMAP
+ LD H,MG014_STATMAPLO >> 8
#ENDIF
#IF (PPAMODE == PPAMODE_SPP)
+ ; DE: CLOCK VALUES
LD D,$04
LD E,$06
#ENDIF
- ; HL: STATMAP
- LD H,MG014_STATMAPLO >> 8
EXX ; SWITCH TO PRI
CALL PPA_GETBLOCK1 ; LOOP TWICE
CALL PPA_GETBLOCK1 ; ... FOR 512 BYTES
diff --git a/Source/HBIOS/syq.asm b/Source/HBIOS/syq.asm
index ca31255f..8fd81a79 100644
--- a/Source/HBIOS/syq.asm
+++ b/Source/HBIOS/syq.asm
@@ -72,23 +72,15 @@
;
; TODO:
;
-; - STRAIGHTEN OUT TIMEOUTS
-;
-; - REVIEW/ADD CODE COMMENTS
-;
-; - CODE NEEDS TO BE REORGANIZED
-;
; 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.
+; - THIS DRIVER OPERATES USES NIBBLE READ MODE. ALTHOUGH THE 8255
+; (MG014) CAN READ OR WRITE TO PORT A (DATA), IT "GLITCHES" WHEN
+; THE MODE IS CHANGED CAUSING THE CONTROL LINES TO CHANGE AND
+; BREAKS THE PROTOCOL. I SUSPECT THE MBC SPP CAN SUPPORT 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
@@ -181,12 +173,9 @@ SYQ_LBA .EQU 8 ; OFFSET OF LBA (DWORD)
; 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)
+SYQ_TOSLOW .EQU 120 ; SLOW TIMEOUT IS 30 SECS (30 / .25)
+SYQ_TONORM .EQU 4 ; NORMAL TIMEOUT IS 1 SEC (1 / .25)
;
; MACROS
;
@@ -208,6 +197,17 @@ SYQ_TOPICO .EQU 50 ; RC2014 SD PICO (5 SECONDS)
;=============================================================================
;
SYQ_INIT:
+ ; COMPUTE CPU SPEED COMPENSATED TIMEOUT SCALER
+ ; ONE INTERNAL LOOP IN WAITBSY IS 489TS. ON A 1 MHZ CPU, 1 TS
+ ; TAKES 1NS. SO 1/4 SECOND IS 250000 TS ON A 1 MHZ CPU.
+ ; SINCE 1 INTERNAL LOOP IS 489 TS, IT TAKES 250000 / 489 = 511
+ ; INTERNAL LOOPS FOR 1/10 SECOND. SO, WE WANT TO USE
+ ; 511 * CPU MHZ FOR INTERNAL LOOP COUNT.
+ LD DE,511 ; LOAD SCALER FOR 1MHZ
+ LD A,(CB_CPUMHZ) ; LOAD CPU SPEED IN MHZ
+ CALL MULT8X16 ; HL := DE * A
+ LD (SYQ_TOSCALER),HL ; SAVE IT
+;
LD IY,SYQ_CFG ; POINT TO START OF CONFIG TABLE
;
SYQ_INIT1:
@@ -417,6 +417,9 @@ SYQ_IO:
LD (SYQ_DSKBUF),HL ; SAVE DISK BUFFER ADDRESS
LD A,SYQ_LBA ; LBA OFFSET IN CONFIG
CALL LDHLIYA ; POINT TO LBA DWORD
+#IF (DSKYENABLE)
+ CALL HB_DSKACT ; SHOW ACTIVITY
+#ENDIF
CALL LD32 ; SET DE:HL TO LBA
;
CALL SYQ_CMDSETUP ; SETUP ATA COMMAND BUF
@@ -526,364 +529,168 @@ SYQ_GEOM:
; 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
+SYQ_IDENTIFY:
+#IF (SYQTRACE >= 3)
+ CALL SYQ_PRTPREFIX
+ PRTS(" IDDEV$")
#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.
+ LD C,SYQ_CMD_IDDEV
+ LD DE,0
+ LD HL,0
+ CALL SYQ_CMDSETUP
;
-; MG014 IBM PC (SPP)
-; -------- --------
-; 0: /ACK 6: /ACK
-; 1: BUSY 7: /BUSY
-; 2: POUT 5: POUT
-; 3: SEL 4: SEL
-; 4: /ERR 3: /ERR
+ LD HL,HB_WRKBUF
+ LD (SYQ_DSKBUF),HL
+ LD A,SYQ_XFR_READ
+ LD (SYQ_XFRMODE),A
;
-SYQ_READSTATUS:
- LD C,(IY+SYQ_IOBASE) ; IOBASE TO C
- INC C ; BUMP TO STATUS PORT
- IN A,(C) ; READ IT
+ JP SYQ_RUNCMD
;
-#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
;
+SYQ_MEDIASTATUS:
+#IF (SYQTRACE >= 3)
+ CALL SYQ_PRTPREFIX
+ PRTS(" MEDIASTATUS$")
#ENDIF
;
- RET
-;
-; SIGNAL SEQUENCE TO CONNECT/DISCONNECT
-; VALUE IN A IS WRITTEN TO DATA PORT DURING SEQUENCE
+ LD C,SYQ_CMD_MEDIASTATUS
+ LD DE,0
+ LD HL,0
+ CALL SYQ_CMDSETUP
;
-SYQ_CPP:
- PUSH AF
- SYQ_W2(4)
- SYQ_W0($22)
- SYQ_W0($AA)
- SYQ_W0($55)
- SYQ_W0(0)
- SYQ_W0($FF)
+ LD HL,0
+ LD (SYQ_DSKBUF),HL
+ LD A,SYQ_XFR_NONE
+ LD (SYQ_XFRMODE),A
;
- CALL SYQ_READSTATUS
- AND $B8
- LD (SYQ_S1),A
+ JP SYQ_RUNCMD
;
- SYQ_W0($87)
+; DE:HL LBA
+; C: COMMAND
;
- CALL SYQ_READSTATUS
- AND $B8
- LD (SYQ_S2),A
+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
;
- SYQ_W0($78)
+;=============================================================================
+; COMMAND PROCESSING
+;=============================================================================
;
- CALL SYQ_READSTATUS
- AND $38
- LD (SYQ_S3),A
+; 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.
;
- POP AF
- CALL SYQ_WRITEDATA
- SYQ_W2(4)
- SYQ_W2(5)
- SYQ_W2(4)
- SYQ_W0($FF)
+SYQ_RUNCMD:
;
- ; 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
+#IF (SYQTRACE >= 3)
+ PRTS(" RUNCMD:$")
#ENDIF
;
- XOR A ; ASSUME SUCCESS FOR NOW
- RET
-;
-SYQ_S1 .DB 0
-SYQ_S2 .DB 0
-SYQ_S3 .DB 0
+ CALL SYQ_CONNECT ; CONNECT TO DEVICE
;
-; SEQUENCE TO CONNECT TO DEVICE ON PARALLEL PORT BUS.
+ 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
;
-SYQ_CONNECT:
+ 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(" CONNECT:$")
+ PRTS(" -->$")
#ENDIF
;
- LD A,$00 ; INITIALIZE THE CHIP
- CALL SYQ_CPP
+
+ LD A,SYQ_TOSLOW
+ LD (SYQ_TIMEOUT),A
+
+
+ LD A,(SYQ_TIMEOUT)
+ PUSH AF
+ LD A,SYQ_TOSLOW
+ CALL SYQ_WAITBSY ; WAIT FOR DRIVE READY (COMMAND DONE)
+ POP AF
+ LD (SYQ_TIMEOUT),A
+ CALL SYQ_GETRES
;
- LD A,$E0 ; CONNECT TO THE CHIP
- CALL SYQ_CPP
+ 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_W0(0)
- SYQ_W2(1)
- SYQ_W2(4)
+SYQ_CMD_CMDERR:
+ LD A,SYQ_STCMDERR ; SIGNAL COMMAND ERROR
+ JR SYQ_CMD_EXIT ; AND EXIT
;
- SYQ_WR($08,$10)
- SYQ_WR($0C,$14)
- SYQ_WR($0A,$38)
- SYQ_WR($12,$10)
+SYQ_CMD_IOERR:
+ LD A,SYQ_STIOERR ; SIGNAL IO ERROR
+ JR SYQ_CMD_EXIT ; AND EXIT
;
- RET
+SYQ_CMD_TIMEOUT:
+ LD A,SYQ_STTO ; SIGNAL TIMEOUT ERROR
+ JR SYQ_CMD_EXIT ; AND EXIT
;
-; SEQUENCE TO DISCONNECT FROM DEVICE ON PARALLEL PORT BUS.
-; THE FINAL SYQ_WRITECTRL IS ONLY TO TURN OFF THE MG014 STATUS LED.
+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_DISCONNECT:
;
+;
+SYQ_GETRES:
+ SYQ_RR(SYQ_REG_STAT)
#IF (SYQTRACE >= 3)
- PRTS(" DISCON:$")
+ CALL PC_SPACE
+ CALL PRTHEXBYTE
#ENDIF
+ AND %00000001 ; ERROR BIT SET?
+ RET Z ; NOPE, RETURN WITH ZF
;
- 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_RR(SYQ_REG_ERR)
+#IF (SYQTRACE >= 3)
+ CALL PC_SPACE
+ CALL PRTHEXBYTE
+#ENDIF
+ JP SYQ_CMD_CMDERR
;
-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
-;
-;
-;
-SYQ_GETBUF:
- SYQ_W0(7)
+SYQ_GETBUF:
+ SYQ_W0(7)
SYQ_W2(1)
SYQ_W2(3)
SYQ_W0($FF)
@@ -906,8 +713,10 @@ SYQ_GETBUF:
LD (SYQ_GETBUF_D),A ;
INC A ; CONTROL PORT
LD C,A ; ... TO C
+#IF (SYQMODE == SYQMODE_MG014)
; HL: STATMAP
LD H,MG014_STATMAPLO >> 8
+#ENDIF
EXX ; SWITCH TO PRI REGS
EX AF,AF' ; SWITCH TO PRI AF
CALL SYQ_GETBUF1 ; 256 WORDS
@@ -941,6 +750,7 @@ SYQ_GETBUF1:
LD E,$04
#ENDIF
OUT (C),D ; FIRST CLOCK
+ NOP ; SMALL DELAY SEEMS TO BE NEEDED
SYQ_GETBUF_A .EQU $+1
IN A,($FF) ; GET LOW NIBBLE
#IF (SYQMODE == SYQMODE_MG014)
@@ -959,6 +769,7 @@ SYQ_GETBUF_A .EQU $+1
LD L,A ; SAVE NIBBLE IN L
#ENDIF
OUT (C),E ; SECOND CLOCK
+ NOP ; SMALL DELAY SEEMS TO BE NEEDED
SYQ_GETBUF_B .EQU $+1
IN A,($FF) ; GET HIGH NIBBLE
#IF (SYQMODE == SYQMODE_MG014)
@@ -976,6 +787,14 @@ SYQ_GETBUF_B .EQU $+1
LD (DE),A ; SAVE BYTE
INC DE ; BUMP BUF PTR
;
+ ; SPECIAL HANDLING FOR LAST BYTE
+ LD A,B ; GET ITERATION COUNTER
+ DEC A ; SET ZF IF ON LAST ITERATION
+ JR NZ,SYQ_GETBUF2 ; IF NOT SET, SKIP OVER
+ LD A,$FF ; VALUE TO WRITE
+ CALL SYQ_WRITEDATA ; PUT VALUE ON DATA BUS
+;
+SYQ_GETBUF2:
; SECOND BYTE
EXX ; ALT REGS
;
@@ -989,6 +808,7 @@ SYQ_GETBUF_B .EQU $+1
LD E,$05
#ENDIF
OUT (C),D ; FIRST CLOCK
+ NOP ; SMALL DELAY SEEMS TO BE NEEDED
SYQ_GETBUF_C .EQU $+1
IN A,($FF) ; GET LOW NIBBLE
#IF (SYQMODE == SYQMODE_MG014)
@@ -1007,6 +827,7 @@ SYQ_GETBUF_C .EQU $+1
LD L,A ; SAVE NIBBLE IN L
#ENDIF
OUT (C),E ; SECOND CLOCK
+ NOP ; SMALL DELAY SEEMS TO BE NEEDED
SYQ_GETBUF_D .EQU $+1
IN A,($FF) ; GET HIGH NIBBLE
#IF (SYQMODE == SYQMODE_MG014)
@@ -1072,15 +893,6 @@ SYQ_PUTBUF_B .EQU $+1
DJNZ SYQ_PUTBUF1 ; LOOP
RET ; DONE
;
-; 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:
@@ -1171,62 +983,285 @@ SYQ_INITDEV2:
;
RET ; RETURN, A=0, Z SET
;
+;=============================================================================
+; INTERFACE SUPPORT ROUTINES
+;=============================================================================
;
+; OUTPUT BYTE IN A TO THE DATA PORT
+;
+SYQ_WRITEDATA: ; 17 (CALL)
+ LD C,(IY+SYQ_IOBASE) ; DATA PORT IS AT IOBASE ; 19
+ OUT (C),A ; WRITE THE BYTE ; 12
+ ;CALL DELAY ; IS THIS NEEDED???
+ RET ; DONE ; 10
+; ; --> 58
+;
+;
+SYQ_WRITECTRL: ; 17 (CALL)
+ ; 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 ; 19
+ INC C ; BUMP TO CONTROL PORT ; 4
+ INC C ; 4
+ OUT (C),A ; WRITE TO CONTROL PORT ; 12
+ ;CALL DELAY ; IS THIS NEEDED?
+ RET ; DONE ; 10
+; ; --> 49
+; 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: ; 17 (CALL)
+ LD C,(IY+SYQ_IOBASE) ; IOBASE TO C ; 19
+ INC C ; BUMP TO STATUS PORT ; 4
+ IN A,(C) ; READ IT ; 12
+;
+#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 ; 10
+; ; --> 62
+; 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:
;
-SYQ_IDENTIFY:
#IF (SYQTRACE >= 3)
- CALL SYQ_PRTPREFIX
- PRTS(" IDDEV$")
+ PRTS(" CONNECT:$")
#ENDIF
;
- LD C,SYQ_CMD_IDDEV
- LD DE,0
- LD HL,0
- CALL SYQ_CMDSETUP
+ LD A,$00 ; INITIALIZE THE CHIP
+ CALL SYQ_CPP
;
- LD HL,HB_WRKBUF
- LD (SYQ_DSKBUF),HL
- LD A,SYQ_XFR_READ
- LD (SYQ_XFRMODE),A
+ LD A,$E0 ; CONNECT TO THE CHIP
+ CALL SYQ_CPP
;
- JP SYQ_RUNCMD
+ 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:
;
-SYQ_MEDIASTATUS:
#IF (SYQTRACE >= 3)
- CALL SYQ_PRTPREFIX
- PRTS(" MEDIASTATUS$")
+ PRTS(" DISCON:$")
#ENDIF
;
- LD C,SYQ_CMD_MEDIASTATUS
- LD DE,0
- LD HL,0
- CALL SYQ_CMDSETUP
+ LD A,$30 ; DISCONNECT FROM THE CHIP
+ CALL SYQ_CPP
;
- LD HL,0
- LD (SYQ_DSKBUF),HL
- LD A,SYQ_XFR_NONE
- LD (SYQ_XFRMODE),A
+ ; TURNS OFF MG014 LED
+ SYQ_W2($8C)
;
- JP SYQ_RUNCMD
+ RET
;
-; DE:HL LBA
-; C: COMMAND
+; WRITE VALUE IN A TO ATA REGISTER IN C
;
-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
+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: ; 17 (CALL)
+ LD A,C ; 4
+ CALL SYQ_WRITEDATA ; 58
+ SYQ_W2(1) ; 49 + 7
+ SYQ_W2(3) ; 49 + 7
+ CALL SYQ_READSTATUS ; 62
+ AND $F0 ; 7
+ RRCA ; 4
+ RRCA ; 4
+ RRCA ; 4
+ RRCA ; 4
+ LD C,A ; 4
+ PUSH BC ; 11
+ SYQ_W2(4) ; 49 + 7
+ CALL SYQ_READSTATUS ; 62
+ AND $F0 ; 7
+ POP BC ; 10
+ OR C ; 4
+ RET ; 10
+; ; --> 440
+; 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
+;
+;
+;
+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) ; 440 + 7
+ 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 ; 489
+;
;=============================================================================
; ERROR HANDLING AND DIAGNOSTICS
;=============================================================================
@@ -1394,7 +1429,7 @@ 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_TOSCALER .DW CPUMHZ * 511 ; WAIT FUNCS SCALER FOR CPU SPEED
;
; SYQ DEVICE CONFIGURATION TABLE
;
diff --git a/Source/Images/Common/All/WDATE.COM b/Source/Images/Common/All/WDATE.COM
new file mode 100644
index 00000000..c7ab78e3
Binary files /dev/null and b/Source/Images/Common/All/WDATE.COM differ
diff --git a/Source/ver.inc b/Source/ver.inc
index 189b5f35..afd6ca53 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.21"
+#DEFINE BIOSVER "3.3.0-dev.22"
#define rmj RMJ
#define rmn RMN
#define rup RUP
diff --git a/Source/ver.lib b/Source/ver.lib
index 698bc076..02bbe41d 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.21"
+ db "3.3.0-dev.22"
endm