diff --git a/Doc/ChangeLog.txt b/Doc/ChangeLog.txt index ce47499a..81279518 100644 --- a/Doc/ChangeLog.txt +++ b/Doc/ChangeLog.txt @@ -1,3 +1,7 @@ +Version 2.6.2 +------------- +- WBW: DS1302 clock driver modified to observe proper delays + Version 2.6.2 ------------- - WBW: ASSIGN.COM substantially improved to map all drive types diff --git a/ReadMe.txt b/ReadMe.txt index 81ea5609..5718c7db 100644 --- a/ReadMe.txt +++ b/ReadMe.txt @@ -8,8 +8,8 @@ Builders: Wayne Warthen (wwarthen@gmail.com) Douglas Goodall (douglas_goodall@mac.com) David Giles (vk5dg@internode.on.net) -Updated: 2014-09-19 -Version: 2.6.2 +Updated: 2014-10-13 +Version: 2.6.3 This is an adaptation of CP/M-80 2.2 and ZSDOS/ZCPR targeting ROMs for all N8VEM Z80 hardware variations diff --git a/Source/BIOS/dsrtc.asm b/Source/BIOS/dsrtc.asm index 09edef00..94b37d73 100644 --- a/Source/BIOS/dsrtc.asm +++ b/Source/BIOS/dsrtc.asm @@ -3,6 +3,64 @@ ; DALLAS SEMICONDUCTOR DS1302 RTC DRIVER ;================================================================================================== ; +; PROGRAMMING NOTES: +; - ALL SIGNALS ARE ACTIVE HIGH +; - DATA OUTPUT (HOST -> RTC) ON RISING EDGE +; - DATA INPUT (RTC -> HOST) ON FALLING EDGE +; - SIMPLIFIED TIMING CONSTRAINTS: +; @ 50MHZ, 1 TSTATE IS WORTH 20NS, 1 NOP IS WORTH 80NS, 1 EX (SP), IX IS WORTH 23 460NS +; 1) AFTER CHANGING CE, WAIT 1US (2 X EX (SP), IX) +; 2) AFTER CHANGING CLOCK, WAIT 250NS (3 X NOP) +; 3) AFTER SETTING A DATA BIT, WAIT 50NS (1 X NOP) +; 4) PRIOR TO READING A DATA BIT, WAIT 200NS (3 X NOP) +; +; COMMAND BYTE: +; +; 7 6 5 4 3 2 1 0 +; +-----+-----+-----+-----+-----+-----+-----+-----+ +; | 1 | RAM | A4 | A3 | A2 | A1 | A0 | RD | +; | | ~CK | | | | | | ~WR | +; +-----+-----+-----+-----+-----+-----+-----+-----+ +; +; REGISTER ADDRESSES (HEX / BCD): +; +; RD WR D7 D6 D5 D4 D3 D2 D1 D0 RANGE +; +----+----+----+----+----+----+----+----+----+----+-----------+ +; | 81 | 80 | CH | 10 SECS | SEC | 00-59 | +; +----+----+----+----+----+----+----+----+----+----+-----------+ +; | 83 | 82 | | 10 MINS | MIN | 00-59 | +; +----+----+----+----+----+----+----+----+----+----+-----------+ +; | 85 | 84 | TF | 00 | PM | 10 | HOURS | 1-12/0-23 | +; +----+----+----+----+----+----+----+----+----+----+-----------+ +; | 87 | 86 | 00 | 00 | 10 DATE | DATE | 1-31 | +; +----+----+----+----+----+----+----+----+----+----+-----------+ +; | 89 | 88 | 00 | 10 MONTHS | MONTH | 1-12 | +; +----+----+----+----+----+----+----+----+----+----+-----------+ +; | 8B | 8A | 00 | 00 | 00 | 00 | DAY | 1-7 | +; +----+----+----+----+----+----+----+----+----+----+-----------+ +; | 8D | 8C | 10 YEARS | YEAR | 0-99 | +; +----+----+----+----+----+----+----+----+----+----+-----------+ +; | 8F | 8E | WP | 00 | 00 | 00 | 00 | 00 | 00 | 00 | | +; +----+----+----+----+----+----+----+----+----+----+-----------+ +; | 91 | 90 | TCS | DS | RS | | +; +----+----+----+----+----+----+----+----+----+----+-----------+ +; | BF | BE | *CLOCK BURST* | +; +----+----+----+----+----+----+----+----+----+----+-----------+ +; | C1 | C0 | | | +; | .. | .. | *RAM* | | +; | FD | FC | | | +; +----+----+----+----+----+----+----+----+----+----+-----------+ +; | FF | FE | *RAM BURST* | | +; +----+----+----+----+----+----+----+----+----+----+-----------+ +; +; CH=CLOCK HALT (1=CLOCK HALTED & OSC STOPPED) +; TF=12 HOUR (1) OR 24 HOUR (0) +; PM=IF 24 HOURS, 0=AM, 1=PM, ELSE 10 HOURS +; WP=WRITE PROTECT (1=PROTECTED) +; TCS=TRICKLE CHARGE ENABLE (1010 TO ENABLE) +; DS=TRICKLE CHARGE DIODE SELECT +; RS=TRICKLE CHARGE RESISTOR SELECT +; ; CONSTANTS ; DSRTC_BASE .EQU RTC ; RTC PORT ON ALL N8VEM SERIES Z80 PLATFORMS @@ -24,14 +82,17 @@ DSRTC_INIT: JR Z,DSRTC_INIT1 PRTS("INIT CLOCK $") LD HL,DSRTC_TIMDEF - CALL DSRTC_SETTIM + CALL DSRTC_TIM2CLK + LD HL,DSRTC_BUF + CALL DSRTC_WRCLK ; DSRTC_INIT1: ; DISPLAY CURRENT TIME + LD HL,DSRTC_BUF + CALL DSRTC_RDCLK + LD HL,DSRTC_TIMBUF + CALL DSRTC_CLK2TIM LD HL,DSRTC_TIMBUF - PUSH HL - CALL DSRTC_GETTIM - POP HL CALL PRTDT ; XOR A ; SIGNAL SUCCESS @@ -73,13 +134,77 @@ DSRTC_SETBLK: ; DSRTC_GETTIM: ; - ; READ THE CLOCK PUSH HL ; SAVE ADR OF OUTPUT BUF - LD HL,DSRTC_BUF ; USE WORK BUF TO READ CLOCK +; + ; READ THE CLOCK + LD HL,DSRTC_BUF ; POINT TO CLOCK BUFFER CALL DSRTC_RDCLK ; READ THE CLOCK + LD HL,DSRTC_TIMBUF ; POINT TO TIME BUFFER + CALL DSRTC_CLK2TIM ; CONVERT CLOCK TO TIME +;; +; ; NOW COPY TO REAL DESTINATION (INTERBANK SAFE) +; LD C,BID_BIOS ; SOURCE BANK IS HBIOS +; LD A,(HBX_CURBNK) ; GET CURRENT BANK +; LD B,A ; .. AND USE AS DEST BANK +; LD (HBX_SRCBNK),BC ; SET COPY BANKS +; LD HL,DSRTC_TIMBUF ; SOURCE ADR +; POP DE ; DEST ADR +; LD BC,6 ; LENGTH IS 6 BYTES +; LD A,BID_BIOS ; RET BANK IS HBIOS +; CALL HB_COPY ; COPY THE CLOCK DATA +; + LD C,BID_HB ; SOURCE BANK IS OUR BANK + CALL HBXX_GETBNK ; GET USER BANK + LD B,A ; PUT IN B AS DEST BANK + CALL HBXX_XCOPY ; SETUP COPY BANKS + LD HL,DSRTC_TIMBUF ; SOURCE IS TIMBUF + POP DE ; DESTINATION IS PASSED IN + LD BC,6 ; 6 BYTES + CALL HBXX_COPY ; DO IT +; + ; CLEAN UP AND RETURN + XOR A ; SIGNAL SUCCESS + RET ; AND RETURN +; +; RTC SET TIME +; A: RESULT (OUT), 0=OK, Z=OK, NZ=ERR +; HL: DATE/TIME BUFFER (IN) +; BUFFER FORMAT IS BCD: YYMMDDHHMMSS +; 24 HOUR TIME FORMAT IS ASSUMED ; - ; TRANSLATE FROM TEMP BUF TO OUTPUT BUF - POP HL ; RESTORE THE OUTPUT BUF ADR +DSRTC_SETTIM: +; +; ; COPY INCOMING TIME DATA TO OUR TIME BUFFER +; LD A,(HBX_CURBNK) ; GET CURRENT BANK +; LD C,A ; .. AND USE AS SOURCE BANK +; LD B,BID_BIOS ; DESTINATION BANK IS HBIOS +; LD (HBX_SRCBNK),BC ; SET COPY BANKS +; LD DE,DSRTC_TIMBUF ; DEST ADR +; LD BC,6 ; LENGTH IS 6 BYTES +; LD A,BID_BIOS ; RET BANK IS HBIOS +; CALL HB_COPY ; COPY THE CLOCK DATA +; + CALL HBXX_GETBNK + LD C,A + LD B,BID_HB + CALL HBXX_XCOPY + LD DE,DSRTC_TIMBUF + LD BC,6 + CALL HBXX_COPY +; + ; WRITE TO CLOCK + LD HL,DSRTC_TIMBUF ; POINT TO TIME BUFFER + CALL DSRTC_TIM2CLK ; CONVERT TO CLOCK FORMAT + LD HL,DSRTC_BUF ; POINT TO CLOCK BUFFER + CALL DSRTC_WRCLK ; WRITE TO THE CLOCK +; + ; CLEAN UP AND RETURN + XOR A ; SIGNAL SUCCESS + RET ; AND RETURN +; +; CONVERT DATA IN CLOCK BUFFER TO TIME BUFFER AT HL +; +DSRTC_CLK2TIM: LD A,(DSRTC_YR) LD (HL),A INC HL @@ -96,21 +221,13 @@ DSRTC_GETTIM: LD (HL),A INC HL LD A,(DSRTC_SEC) - LD (HL),A -; - ; CLEAN UP AND RETURN - XOR A ; SIGNAL SUCCESS - RET ; AND RETURN -; -; RTC SET TIME -; A: RESULT (OUT), 0=OK, Z=OK, NZ=ERR -; HL: DATE/TIME BUFFER (IN) -; BUFFER FORMAT IS BCD: YYMMDDHHMMSS -; 24 HOUR TIME FORMAT IS ASSUMED + LD (HL),A + RET ; -DSRTC_SETTIM: +; CONVERT DATA IN TIME BUFFER AT HL TO CLOCK BUFFER ; - ; TRANSLATE FROM INPUT BUF TO WORK BUF +DSRTC_TIM2CLK: + PUSH HL LD A,(HL) LD (DSRTC_YR),A INC HL @@ -128,16 +245,10 @@ DSRTC_SETTIM: INC HL LD A,(HL) LD (DSRTC_SEC),A - XOR A ; FIX: DERIVE DAY OF WEEK!!! + POP HL + XOR A LD (DSRTC_DAY),A -; - ; WRITE TO CLOCK - LD HL,DSRTC_BUF ; POINT TO WORK BUF - CALL DSRTC_WRCLK ; SEND IT TO RTC -; - ; CLEAN UP AND RETURN - XOR A ; SIGNAL SUCCESS - RET ; AND RETURN + RET ; ; TEST CLOCK FOR VALID DATA ; READ CLOCK HALT BIT AND RETURN ZF BASED ON BIT VALUE @@ -148,6 +259,7 @@ DSRTC_TSTCLK: LD C,$81 ; SECONDS REGISTER HAS CLOCK HALT FLAG CALL DSRTC_CMD ; SEND THE COMMAND CALL DSRTC_GET ; READ THE REGISTER + CALL DSRTC_END ; FINISH IT AND %10000000 ; HIGH ORDER BIT IS CLOCK HALT RET ; @@ -164,9 +276,7 @@ DSRTC_RDCLK1: INC HL ; INC BUF POINTER POP BC ; RESTORE BC DJNZ DSRTC_RDCLK1 ; LOOP IF NOT DONE - XOR A ; ALL LINES OFF TO CLEAN UP - OUT (DSRTC_BASE),A ; WRITE TO RTC PORT - RET + JR DSRTC_END ; FINISH IT ; ; BURST WRITE CLOCK DATA FROM BUFFER AT HL ; @@ -175,6 +285,7 @@ DSRTC_WRCLK: CALL DSRTC_CMD ; SEND COMMAND XOR A ; $00 = UNPROTECT CALL DSRTC_PUT ; SEND VALUE TO CONTROL REGISTER + CALL DSRTC_END ; FINISH IT ; LD C,$BE ; COMMAND = $BE TO BURST WRITE CLOCK CALL DSRTC_CMD ; SEND COMMAND TO RTC @@ -188,54 +299,112 @@ DSRTC_WRCLK1: DJNZ DSRTC_WRCLK1 ; LOOP IF NOT DONE LD A,$80 ; ADD CONTROL REG BYTE, $80 = PROTECT ON CALL DSRTC_PUT ; WRITE REQUIRED 8TH BYTE - XOR A ; ALL LINES OFF TO CLEAN UP - OUT (DSRTC_BASE),A ; WRITE TO RTC PORT - RET + JR DSRTC_END ; FINISH IT ; ; SEND COMMAND IN C TO RTC +; ALL RTC SEQUENCES MUST CALL THIS FIRST TO SEND THE RTC COMMAND. +; THE COMMAND IS SENT VIA A PUT. CE AND CLK ARE LEFT HIGH! THIS +; IS INTENTIONAL BECAUSE WHEN THE CLOCK IS LOWERED, THE FIRST BIT +; WILL BE PRESENTED TO READ (IN THE CASE OF A READ CMD). +; +; 0) ASSUME ALL LINES UNDEFINED AT ENTRY +; 1) DEASSERT ALL LINES (CE, RD, CLOCK, & DATA) +; 2) WAIT 1US +; 3) ASSERT CE +; 4) WAIT 1US +; 5) PUT COMMAND ; DSRTC_CMD: - LD A,DSRTC_RD ; CE LOW TO RESET RTC - OUT (DSRTC_BASE),A ; WRITE IT + XOR A ; ALL LINES OFF TO CLEAN UP + OUT (DSRTC_BASE),A ; WRITE TO RTC PORT + EX (SP), IX \ EX (SP), IX ; WAIT 1US + XOR DSRTC_CE ; RUN ON CE + OUT (DSRTC_BASE),A ; WRITE TO RTC PORT + EX (SP), IX \ EX (SP), IX ; WAIT 1US LD A,C ; LOAD COMMAND CALL DSRTC_PUT ; WRITE IT RET ; ; WRITE BYTE IN A TO THE RTC +; WRITE BYTE IN A TO THE RTC. CE IS IMPLICITY ASSERTED AT +; THE START. CE AND CLK ARE LEFT HIGH AT THE END. CLOCK +; *MUST* BE LEFT HIGH FROM DSRTC_CMD! +; +; 0) ASSUME ENTRY WITH CE & CLK ASSERTED, RD DEASSERTED, DATA UNKNOWN +; 1) WAIT 250NS (COMPLETE ANY PENDING WRITE) +; 2) DEASSERT CLOCK (LOW) +; 3) WAIT 250NS +; 4) (DE)ASSERT DATA (ACCORDING TO BIT VALUE) +; 5) ASSERT CLOCK (HIGH) +; 6) LOOP FOR 8 DATA BITS ; DSRTC_PUT: LD B,8 ; LOOP FOR 8 BITS DSRTC_PUT1: + NOP \ NOP \ NOP ; WAIT 250NS RRCA ; ROTATE NEXT BIT TO SEND INTO BIT 7 LD C,A ; SAVE WORKING VALUE AND %10000000 ; ISOLATE THE DATA BIT - OR DSRTC_CE ; ADD CHIP ENABLE, CLOCK HIGH - OUT (DSRTC_BASE),A ; WRITE TO PORT WITH CLOCK LOW - XOR DSRTC_CLK ; TURN CLOCK BACK ON - OUT (DSRTC_BASE),A ; WRITE TO PORT WITH CLOCK HIGH + OR DSRTC_CE ; SET CHIP ENABLE BIT + OUT (DSRTC_BASE),A ; WRITE TO PORT (CLOCK IS LOW) + NOP \ NOP \ NOP ; WAIT 250NS + XOR DSRTC_CLK ; TURN CLOCK ON + OUT (DSRTC_BASE),A ; WRITE TO PORT TO SET CLOCK HIGH LD A,C ; RECOVER WORKING VALUE DJNZ DSRTC_PUT1 ; LOOP IF NOT DONE RET ; ; READ BYTE FROM RTC, RETURN VALUE IN A +; READ THE NEXT BYTE FROM THE RTC INTO A. CE IS IMPLICITLY +; ASSERTED AT THE START. CE AND CLK ARE LEFT HIGH AT +; THE END. CLOCK *MUST* BE LEFT HIGH FROM DSRTC_CMD! +; +; 0) ASSUME ENTRY WITH CE & CLK ASSERTED, RD DEASSERTED, DATA UNKNOWN +; 1) WAIT 250NS (COMPLETE ANY PENDING WRITE) +; 2) ASSERT RD AND DEASSERT DATA +; 3) DEASSERT CLOCK (LOW) +; 4) WAIT 250NS +; 5) READ DATA BIT +; 5) ASSERT CLOCK (HIGH) +; 6) LOOP FOR 8 DATA BITS ; DSRTC_GET: + NOP \ NOP \ NOP ; WAIT 250NS LD C,0 ; INITIALIZE WORKING VALUE TO 0 LD B,8 ; LOOP FOR 8 BITS DSRTC_GET1: - LD A,DSRTC_RD+DSRTC_CE ; LOWER CLOCK, CE STAYS HI, READ IS ON + LD A,DSRTC_RD | DSRTC_CE | DSRTC_CLK ; ASSERT RD, DEASSERT DATA + OUT (DSRTC_BASE),A ; WRITE TO RTC PORT + XOR DSRTC_CLK ; DEASSERT CLOCK OUT (DSRTC_BASE),A ; WRITE TO RTC PORT - NOP ; SETTLE + NOP \ NOP \ NOP ; WAIT 250NS IN A,(DSRTC_BASE) ; READ THE RTC PORT AND %00000001 ; ISOLATE THE DATA BIT OR C ; COMBINE WITH WORKING VALUE RRCA ; ROTATE FOR NEXT BIT LD C,A ; SAVE WORKING VALUE - LD A,DSRTC_CLK+DSRTC_RD+DSRTC_CE ; CLOCK BACK TO HIGH NOW + LD A,DSRTC_CLK | DSRTC_RD | DSRTC_CE ; CLOCK BACK TO HIGH NOW OUT (DSRTC_BASE),A ; WRITE TO RTC PORT DJNZ DSRTC_GET1 ; LOOP IF NOT DONE LD A,C ; GET RESULT INTO A RET +; +; COMPLETE A COMMAND SEQUENCE +; FINISHES UP A COMMAND SEQUENCE. +; DOES NOT DESTROY ANY REGISTERS. +; +; 1) WAIT 250NS (COMPLETE ANY PENDING WRITE) +; 2) DEASSERT ALL LINES (CE, RD, CLOCK, & DATA) +; +DSRTC_END: + NOP \ NOP \ NOP ; WAIT 250NS + PUSH AF ; SAVE AF + XOR A ; ALL LINES OFF TO CLEAN UP + OUT (DSRTC_BASE),A ; WRITE TO RTC PORT + POP AF ; RESTORE AF + RET + + ; ; WORKING VARIABLES ; diff --git a/Source/BIOS/ver.inc b/Source/BIOS/ver.inc index 25e497e0..abf0ef21 100644 --- a/Source/BIOS/ver.inc +++ b/Source/BIOS/ver.inc @@ -1,7 +1,7 @@ #DEFINE RMJ 2 #DEFINE RMN 6 -#DEFINE RUP 2 +#DEFINE RUP 3 #DEFINE RTP 14 -#DEFINE BIOSVER "2.6.2" -#DEFINE BIOSBLD "Build 14" +#DEFINE BIOSVER "2.6.3" +#DEFINE BIOSBLD "Build 15" #DEFINE REVISION 500