From 4a9d3c654f3d7b5561145f63c00bc231573ab0ee Mon Sep 17 00:00:00 2001 From: Wayne Warthen Date: Wed, 29 Nov 2017 18:39:49 -0800 Subject: [PATCH] Modify RTC.COM to dynamically adjust to hardware RTC.COM is now one application instead of one per hardware platform. It adjusts to the running platform by querying HBIOS for the active platform. --- Source/Apps/Build.cmd | 1 + Source/Apps/RTC.asm | 1702 +++++++++++++++++++++++++++++++++++ Source/RomDsk/MK4/RTC.COM | Bin 2048 -> 0 bytes Source/RomDsk/N8/RTC.COM | Bin 2048 -> 0 bytes Source/RomDsk/SBC/RTC.COM | Bin 2048 -> 0 bytes Source/RomDsk/ZETA/RTC.COM | Bin 2048 -> 0 bytes Source/RomDsk/ZETA2/RTC.COM | Bin 2048 -> 0 bytes 7 files changed, 1703 insertions(+) create mode 100644 Source/Apps/RTC.asm delete mode 100644 Source/RomDsk/MK4/RTC.COM delete mode 100644 Source/RomDsk/N8/RTC.COM delete mode 100644 Source/RomDsk/SBC/RTC.COM delete mode 100644 Source/RomDsk/ZETA/RTC.COM delete mode 100644 Source/RomDsk/ZETA2/RTC.COM diff --git a/Source/Apps/Build.cmd b/Source/Apps/Build.cmd index be60f023..c308521a 100644 --- a/Source/Apps/Build.cmd +++ b/Source/Apps/Build.cmd @@ -17,6 +17,7 @@ call :asm Format || goto :eof call :asm Talk || goto :eof call :asm OSLdr || goto :eof call :asm Mode || goto :eof +call :asm RTC || goto :eof zx Z80ASM -SYSGEN/F diff --git a/Source/Apps/RTC.asm b/Source/Apps/RTC.asm new file mode 100644 index 00000000..4f2b1e03 --- /dev/null +++ b/Source/Apps/RTC.asm @@ -0,0 +1,1702 @@ + .Title "RTC" +; +; Program: rtc.asm +; Author: Andrew Lynch +; Date: 22 Feb 2007 +; Enviroment: TASM MS-DOS Z80 Cross Assembler source for CP/M +; +;[2011/8/11] VK5DG modified for N8 +; Changed base address to $88 +; Changed trickle charger value to 2k+2 diodes for DS1210s +; +;[2012/2/7] WBW modified to build for either +; traditional N8VEM/Zeta or N8 via conditionals +; +;[2013/12/29] WBW modified to build for MK4 +; +;[2017/11/29] WBW modified to adjust to RTC in use dynamically +; using HBIOS platform detection +; +; Constants +; + +mask_data .EQU %10000000 ; RTC data line +mask_clk .EQU %01000000 ; RTC Serial Clock line +mask_rd .EQU %00100000 ; Enable data read from RTC +mask_rst .EQU %00010000 ; De-activate RTC reset line + +PORT_SBC .EQU $70 ; RTC port for SBC/ZETA +PORT_N8 .EQU $88 ; RTC port for N8 +PORT_MK4 .EQU $8A ; RTC port for MK4 + +BDOS .EQU 5 ; BDOS invocation vector +; +; Program +; + .ORG 0100H + +LOOP: + LD DE,MSG + LD C,09H ; CP/M write string to console call + CALL 0005H + +; program starts here + + CALL RTC_INIT ; Program initialization + + CALL RTC_TOP_LOOP + + LD C,00H ; CP/M system reset call - shut down + CALL 0005H + + HALT ; This code is never reached + + +; function HEXSTR +; input number in A +; output upper nibble of number in ASCII in H +; output lower nibble of number in ASCII in L +; uses BC +; +; based on following algorithm: +: +; const +; hextab : string = ('0','1','2','3','4','5','6','7','8', +; '9','A','B','C','D','E','F'); +; +; PROCEDURE hexstr(n: int): ^string; +; BEGIN +; n := n and 255; +; tmpstr[1] := hextab[n / 16]; +; tmpstr[2] := hextab[n and 15]; +; tmpstr[0] := #2; +; return @tmpstr; +; END; + + +HEXSTR: + PUSH BC ;SAVE BC + LD B,A + RLC A ;DO HIGH NIBBLE FIRST + RLC A + RLC A + RLC A + AND 0FH ;ONLY THIS NOW + ADD A,30H ;TRY A NUMBER + CP 3AH ;TEST IT + JR C,HEXSTR1 ;IF CY SET SAVE 'NUMBER' in H + ADD A,07H ;MAKE IT AN ALPHA +HEXSTR1: + LD H,A ;SAVE 'ALPHA' in H + LD A,B ;NEXT NIBBLE + AND 0FH ;JUST THIS + ADD A,30H ;TRY A NUMBER + CP 3AH ;TEST IT + JR C,HEXSTR2 ;IF CY SET SAVE 'NUMBER' in L + ADD A,07H ;MAKE IT ALPHA + +HEXSTR2: + LD L,A ;SAVE 'ALPHA' in L + POP BC ;RESTORE BC + RET + + +;***************************************************** +;* GET K.B. DATA & MAKE IT 'HEX' +;***************************************************** + +HEXIN: + PUSH BC ;SAVE BC REGS. + CALL NIBL ;DO A NIBBLE + RLC A ;MOVE FIRST BYTE UPPER NIBBLE + RLC A + RLC A + RLC A + LD B,A ;SAVE ROTATED BYTE + PUSH BC + + CALL NIBL ;DO NEXT NIBBLE + POP BC + ADD A,B ;COMBINE NIBBLES IN ACC. + POP BC ;RESTORE BC + RET ;DONE +NIBL: + LD C,01H ; CP/M console input call + CALL 0005H ;GET K.B. DATA + CP 40H ;TEST FOR ALPHA + JR NC,ALPH + AND 0FH ;GET THE BITS + RET +ALPH: + AND 0FH ;GET THE BITS + ADD A,09H ;MAKE IT HEX A-F + RET + +; function RTC_IN +; +; read a byte from RTC port, return in A +; NOTE: port address is dynamically set in RTC_INIT + +RTC_IN: +INP .EQU $ + 1 + IN A,($FF) + RET + +; function RTC_OUT +; +; write a byte to RTC port, value in A +; NOTE: port address is dynamically set in RTC_INIT + +RTC_OUT: +OUTP .EQU $ + 1 + OUT ($FF),A + RET + +; function RTC_BIT_DELAY +; +; based on following algorithm: +; +; { Make a short delay } +; PROCEDURE rtc_bit_delay; +; var +; x : int; +; BEGIN +; x := 3; +; END; + +RTC_BIT_DELAY: ; purpose is to delay ~36 uS or 144 t-states at 4MHz + PUSH AF ; 11 t-states + LD A,07H ; 7 t-states ADJUST THE TIME 13h IS FOR 4 MHZ +RTC_BIT_DELAY1: + DEC A ; 4 t-states DEC COUNTER. 4 T-states = 1 uS. + JP NZ,RTC_BIT_DELAY1 ; 10 t-states JUMP TO PAUSELOOP2 IF A <> 0. + + NOP ; 4 t-states + NOP ; 4 t-states + POP AF ; 10 t-states + RET ; 10 t-states (144 t-states total) + + +; function RTC_RESET +; +; based on following algorithm: +; +; { Output a RTC reset signal } +; PROCEDURE rtc_reset; +; BEGIN +; out(rtc_base,mask_data + mask_rd); +; rtc_bit_delay(); +; rtc_bit_delay(); +; out(rtc_base,mask_data + mask_rd + mask_rst); +; rtc_bit_delay(); +; rtc_bit_delay(); +; END; +; +RTC_RESET: + LD A,mask_data + mask_rd + ;OUT (RTC),A + CALL RTC_OUT + CALL RTC_BIT_DELAY + CALL RTC_BIT_DELAY + LD A,mask_data + mask_rd + mask_rst + ;OUT (RTC),A + CALL RTC_OUT + CALL RTC_BIT_DELAY + CALL RTC_BIT_DELAY + RET + + +; function RTC_RESET_ON +; +; based on following algorithm: +; +; { Assert RTC reset signal } +; PROCEDURE rtc_reset_on; +; BEGIN +; out(rtc_base,mask_data + mask_rd); +; rtc_bit_delay(); +; rtc_bit_delay(); +; END; + +RTC_RESET_ON: + LD A,mask_data + mask_rd + ;OUT (RTC),A + CALL RTC_OUT + CALL RTC_BIT_DELAY + CALL RTC_BIT_DELAY + RET + +; function RTC_RESET_OFF +; +; based on following algorithm: +; +; { De-assert RTC reset signal } +; PROCEDURE rtc_reset_off; +; BEGIN +; out(rtc_base,mask_data + mask_rd + mask_rst); +; rtc_bit_delay(); +; rtc_bit_delay(); +; END; + +RTC_RESET_OFF: + LD A,mask_data + mask_rd + mask_rst + ;OUT (RTC),A + CALL RTC_OUT + CALL RTC_BIT_DELAY + CALL RTC_BIT_DELAY + RET + +; function RTC_WR +; input value in C +; uses A +; +; PROCEDURE rtc_wr(n : int); +; var +; i : int; +; BEGIN +; for i := 0 while i < 8 do inc(i) loop +; if (n and 1) <> 0 then +; out(rtc_base,mask_rst + mask_data); +; rtc_bit_delay(); +; out(rtc_base,mask_rst + mask_clk + mask_data); +; else +; out(rtc_base,mask_rst); +; rtc_bit_delay(); +; out(rtc_base,mask_rst + mask_clk); +; end; +; rtc_bit_delay(); +; n := shr(n,1); +; end loop; +; END; + +RTC_WR: + XOR A ; set A=0 index counter of FOR loop + +RTC_WR1: + PUSH AF ; save accumulator as it is the index counter in FOR loop + LD A,C ; get the value to be written in A from C (passed value to write in C) + BIT 0,A ; is LSB a 0 or 1? + JP Z,RTC_WR2 ; if it’s a 0, handle it at RTC_WR2. + ; LSB is a 1, handle it below + ; setup RTC latch with RST and DATA high, SCLK low + LD A,mask_rst + mask_data + ;OUT (RTC),A ; output to RTC latch + CALL RTC_OUT + CALL RTC_BIT_DELAY ; let it settle a while + ; setup RTC with RST, DATA, and SCLK high + LD A,mask_rst + mask_clk + mask_data + ;OUT (RTC),A ; output to RTC latch + CALL RTC_OUT + JP RTC_WR3 ; exit FOR loop + +RTC_WR2: + ; LSB is a 0, handle it below + LD A,mask_rst ; setup RTC latch with RST high, SCLK and DATA low + ;OUT (RTC),A ; output to RTC latch + CALL RTC_OUT + CALL RTC_BIT_DELAY ; let it settle a while + ; setup RTC with RST and SCLK high, DATA low + LD A,mask_rst + mask_clk + ;OUT (RTC),A ; output to RTC latch + CALL RTC_OUT + +RTC_WR3: + CALL RTC_BIT_DELAY ; let it settle a while + RRC C ; move next bit into LSB position for processing to RTC + POP AF ; recover accumulator as it is the index counter in FOR loop + INC A ; increment A in FOR loop (A=A+1) + CP $08 ; is A < $08 ? + JP NZ,RTC_WR1 ; No, do FOR loop again + RET ; Yes, end function and return + + +; function RTC_RD +; output value in C +; uses A +; +; function RTC_RD +; +; PROCEDURE rtc_rd(): int ; +; var +; i,n,mask : int; +; BEGIN +; n := 0; +; mask := 1; +; for i := 0 while i < 8 do inc(i) loop +; out(rtc_base,mask_rst + mask_rd); +; rtc_bit_delay(); +; if (in(rtc_base) and #1) <> #0 then +; { Data = 1 } +; n := n + mask; +; else +; { Data = 0 } +; end; +; mask := shl(mask,1); +; out(rtc_base,mask_rst + mask_clk + mask_rd); +; rtc_bit_delay(); +; end loop; +; return n; +; END; + +RTC_RD: + XOR A ; set A=0 index counter of FOR loop + LD C,$00 ; set C=0 output of RTC_RD is passed in C + LD B,$01 ; B is mask value + +RTC_RD1: + PUSH AF ; save accumulator as it is the index counter in FOR loop + ; setup RTC with RST and RD high, SCLK low + LD A,mask_rst + mask_rd + ;OUT (RTC),A ; output to RTC latch + CALL RTC_OUT + CALL RTC_BIT_DELAY ; let it settle a while + ;IN A,(RTC) ; input from RTC latch + CALL RTC_IN ; input from RTC latch + BIT 0,A ; is LSB a 0 or 1? + JP Z,RTC_RD2 ; if LSB is a 1, handle it below + LD A,C + ADD A,B + LD C,A +; INC C + ; if LSB is a 0, skip it (C=C+0) +RTC_RD2: + RLC B ; move input bit out of LSB position to save it in C + ; setup RTC with RST, SCLK high, and RD high + LD A,mask_rst + mask_clk + mask_rd + ;OUT (RTC),A ; output to RTC latch + CALL RTC_OUT + CALL RTC_BIT_DELAY ; let it settle + POP AF ; recover accumulator as it is the index counter in FOR loop + INC A ; increment A in FOR loop (A=A+1) + CP $08 ; is A < $08 ? + JP NZ,RTC_RD1 ; No, do FOR loop again + RET ; Yes, end function and return. Read RTC value is in C + +; function RTC_WRITE +; input address in D +; input value in E +; uses A +; +; based on following algorithm: +; +; PROCEDURE rtc_write(address, value: int); +; BEGIN +; lock(); +; rtc_reset_off(); +; { Write command } +; rtc_wr(128 + shl(address and $3f,1)); +; { Write data } +; rtc_wr(value and $ff); +; rtc_reset_on(); +; unlock(); +; END; + +RTC_WRITE: + DI ; disable interrupts during critical section + CALL RTC_RESET_OFF ; turn off RTC reset + LD A,D ; bring into A the address from D +; AND $3F ; keep only bits 6 LSBs, discard 2 MSBs + AND %00111111 ; keep only bits 6 LSBs, discard 2 MSBs + RLC A ; rotate address bits to the left +; ADD A,$80 ; set MSB to one for DS1302 COMMAND BYTE (WRITE) + ADD A,%10000000 ; set MSB to one for DS1302 COMMAND BYTE (WRITE) + LD C,A ; RTC_WR expects write data (address) in reg C + CALL RTC_WR ; write address to DS1302 + LD A,E ; start processing value + AND $FF ; seems unnecessary, probably delete since all values are 8-bit + LD C,A ; RTC_WR expects write data (value) in reg C + CALL RTC_WR ; write address to DS1302 + CALL RTC_RESET_ON ; turn on RTC reset + EI + RET + + +; function RTC_READ +; input address in D +; output value in C +; uses A +; +; based on following algorithm +; +; PROCEDURE rtc_read(address: int): int; +; var +; n : int; +; BEGIN +; lock(); +; rtc_reset_off(); +; { Write command } +; rtc_wr(128 + shl(address and $3f,1) + 1); +; { Read data } +; n := rtc_rd(); +; rtc_reset_on(); +; unlock(); +; return n; +; END; + +RTC_READ: + DI ; disable interrupts during critical section + CALL RTC_RESET_OFF ; turn off RTC reset + LD A,D ; bring into A the address from D + AND $3F ; keep only bits 6 LSBs, discard 2 MSBs + RLC A ; rotate address bits to the left + ADD A,$81 ; set MSB to one for DS1302 COMMAND BYTE (READ) + LD C,A ; RTC_WR expects write data (address) in reg C + CALL RTC_WR ; write address to DS1302 + CALL RTC_RD ; read value from DS1302 (value is in reg C) + CALL RTC_RESET_ON ; turn on RTC reset + EI + RET + + +; function RTC_WR_PROTECT +; input D (address) $07 +; input E (value) $80 +; uses A +; +; based on following algorithm +; +; PROCEDURE rtc_wr_protect; +; BEGIN +; rtc_write(7,128); +; END; + +RTC_WR_PROTECT: +; LD D,$07 + LD D,%00000111 +; LD E,$80 + LD E,%10000000 + CALL RTC_WRITE + RET + + +; function RTC_WR_UNPROTECT +; input D (address) $07 +; input E (value) $00 +; uses A +; +; based on following algorithm +; +; PROCEDURE rtc_wr_unprotect; +; BEGIN +; rtc_write(7,0); +; END; + +RTC_WR_UNPROTECT: +; LD D,$07 + LD D,%00000111 +; LD E,$00 + LD E,%00000000 + CALL RTC_WRITE + RET + + +; function RTC_GET_TIME +; input HL (memory address of buffer) +; uses A,C,D,E +; +; based on following algorithm +; +; PROCEDURE rtc_get_time(var buf: string); +; var +; n : int; +; BEGIN +; lock(); +; rtc_reset_off(); +; { Write command, burst read } +; rtc_wr(255 - 64); +; { Read seconds } +; n := rtc_rd(); 0 +; buf[16] := char(((n / 16) and $07)) + '0'; +; buf[17] := char((n and $0f)) + '0'; +; { Read minutes } +; n := rtc_rd(); 1 +; buf[13] := char(((n / 16) and $07)) + '0'; +; buf[14] := char((n and $0f)) + '0'; +; buf[15] := ':'; +; { Read hours } +; n := rtc_rd(); 2 +; buf[10] := char(((n / 16) and $03)) + '0'; +; buf[11] := char((n and $0f)) + '0'; +; buf[12] := ':'; +; { Read date } +; n := rtc_rd(); 3 +; buf[7] := char(((n / 16) and $03)) + '0'; +; buf[8] := char((n and $0f)) + '0'; +; buf[9] := ' '; +; { Read month } +; n := rtc_rd(); 4 +; buf[4] := char(((n / 16) and $03)) + '0'; +; buf[5] := char((n and $0f)) + '0'; +; buf[6] := '-'; +; { Read day } +; n := rtc_rd(); 5 +; { +; buf[4] := char(((n / 16) and $03)) + '0'; +; buf[4] := char((n and $0f)) + '0'; +; } +; { Read year } +; n := rtc_rd(); 6 +; buf[1] := char(((n / 16) and $0f)) + '0'; +; buf[2] := char((n and $0f)) + '0'; +; buf[3] := '-'; +; length(buf) := 17; +; rtc_reset_on(); +; unlock(); +; END rtc_get_time; + +RTC_GET_TIME: + DI ; disable interrupts during DS1302 read + CALL RTC_RESET_OFF ; turn of RTC reset + ; { Write command, burst read } + LD C,%10111111 ; (255 - 64) + CALL RTC_WR ; send COMMAND BYTE (BURST READ) to DS1302 + +; { Read seconds } + + CALL RTC_RD ; read value from DS1302, value is in Reg C + + ; digit 16 + LD A,C ; put value output in Reg C into accumulator + RLC A + RLC A + RLC A + RLC A + AND $07 + ADD A,'0' + LD (RTC_PRINT_BUFFER+15),A + + ; digit 17 + LD A,C ; put value output in Reg C into accumulator + AND $0F + ADD A,'0' + LD (RTC_PRINT_BUFFER+16),A + +; { Read minutes } + + CALL RTC_RD ; read value from DS1302, value is in Reg C + + ; digit 13 + LD A,C ; put value output in Reg C into accumulator + RLC A + RLC A + RLC A + RLC A + AND $07 + ADD A,'0' + LD (RTC_PRINT_BUFFER+12),A + + ; digit 14 + LD A,C ; put value output in Reg C into accumulator + AND $0F + ADD A,'0' + LD (RTC_PRINT_BUFFER+13),A + + ; digit 15 + LD A,':' + LD (RTC_PRINT_BUFFER+14),A + +; { Read hours } + + CALL RTC_RD ; read value from DS1302, value is in Reg C + + ; digit 10 + LD A,C ; put value output in Reg C into accumulator + RLC A + RLC A + RLC A + RLC A + AND $03 + ADD A,'0' + LD (RTC_PRINT_BUFFER+09),A + + ; digit 11 + LD A,C ; put value output in Reg C into accumulator + AND $0F + ADD A,'0' + LD (RTC_PRINT_BUFFER+10),A + + ; digit 12 + LD A,':' + LD (RTC_PRINT_BUFFER+11),A + +; { Read date } + + CALL RTC_RD ; read value from DS1302, value is in Reg C + + ; digit 07 + LD A,C ; put value output in Reg C into accumulator + RLC A + RLC A + RLC A + RLC A + AND $03 + ADD A,'0' + LD (RTC_PRINT_BUFFER+06),A + + ; digit 08 + LD A,C ; put value output in Reg C into accumulator + AND $0F + ADD A,'0' + LD (RTC_PRINT_BUFFER+07),A + + ; digit 09 + LD A,' ' + LD (RTC_PRINT_BUFFER+08),A + +; { Read month } + + CALL RTC_RD ; read value from DS1302, value is in Reg C + + ; digit 04 + LD A,C ; put value output in Reg C into accumulator + RLC A + RLC A + RLC A + RLC A + AND $03 + ADD A,'0' + LD (RTC_PRINT_BUFFER+03),A + + ; digit 05 + LD A,C ; put value output in Reg C into accumulator + AND $0F + ADD A,'0' + LD (RTC_PRINT_BUFFER+04),A + + ; digit 06 + LD A,'-' + LD (RTC_PRINT_BUFFER+05),A + +; { Read day } + + CALL RTC_RD ; read value from DS1302, value is in Reg C + + ; digit 04 +; LD A,C ; put value output in Reg C into accumulator +; RLC A +; RLC A +; RLC A +; RLC A +; AND $03 +; ADD A,'0' +; LD (RTC_PRINT_BUFFER+03),A + + ; digit 04 +; LD A,C ; put value output in Reg C into accumulator +; AND $0F +; ADD A,'0' +; LD (RTC_PRINT_BUFFER+03),A + +; add special code to put "DAY" value at end of string until better solution known + + ; digit 18 + LD A,'-' + LD (RTC_PRINT_BUFFER+17),A + + ; digit 19 + LD A,C ; put value output in Reg C into accumulator + RLC A + RLC A + RLC A + RLC A + AND $0F + ADD A,'0' + LD (RTC_PRINT_BUFFER+18),A + + ; digit 20 + LD A,C ; put value output in Reg C into accumulator + AND $0F + ADD A,'0' + LD (RTC_PRINT_BUFFER+19),A + + + + +; { Read year } + + CALL RTC_RD ; read value from DS1302, value is in Reg C + + ; digit 01 + LD A,C ; put value output in Reg C into accumulator + RLC A + RLC A + RLC A + RLC A + AND $0F + ADD A,'0' + LD (RTC_PRINT_BUFFER+00),A + + ; digit 02 + LD A,C ; put value output in Reg C into accumulator + AND $0F + ADD A,'0' + LD (RTC_PRINT_BUFFER+01),A + + ; digit 03 + LD A,'-' + LD (RTC_PRINT_BUFFER+02),A + + CALL RTC_RESET_ON ; turn RTC reset back on + EI ; re-enable interrupts + + RET ; Yes, end function and return + + +; function RTC_SET_NOW +; uses A, D, E +; +; based on following algorithm +; +; { Set time to 96-02-18 19:43:00 } +; PROCEDURE rtc_set_now; +; BEGIN +; rtc_wr_unprotect(); +; { Set seconds } +; rtc_write(0,0); +; { Set minutes } +; rtc_write(1,$43); +; { Set hours } +; rtc_write(2,$19); +; { Set date } +; rtc_write(3,$18); +; { Set month } +; rtc_write(4,$02); +; { Set day } +; rtc_write(5,$07); +; { Set year } +; rtc_write(6,$96); +; rtc_wr_protect(); +; END; + +RTC_SET_NOW: +; set time to 07-02-23 19:45:00-05 <-Friday + CALL RTC_WR_UNPROTECT +; seconds + LD D,$00 + LD A,(SECONDS) + LD E,A + CALL RTC_WRITE + +; minutes + LD D,$01 + LD A,(MINUTES) + LD E,A + CALL RTC_WRITE + +; hours + LD D,$02 + LD A,(HOURS) + LD E,A + CALL RTC_WRITE + +; date + LD D,$03 + LD A,(DATE) + LD E,A + CALL RTC_WRITE + +; month + LD D,$04 + LD A,(MONTH) + LD E,A + CALL RTC_WRITE + +; day + LD D,$05 + LD A,(DAY) + LD E,A + CALL RTC_WRITE + +; year + LD D,$06 + LD A,(YEAR) + LD E,A + CALL RTC_WRITE + + CALL RTC_WR_PROTECT + RET + +RTC_INIT_NOW: +; set time to Current Time + +; year + LD DE,RTC_TOP_LOOP1_INIT_YEAR + LD C,09H ; CP/M write string to console call + CALL 0005H + CALL HEXIN + LD (YEAR),A + +; month + LD DE,RTC_TOP_LOOP1_INIT_MONTH + LD C,09H ; CP/M write string to console call + CALL 0005H + CALL HEXIN + LD (MONTH),A + +; date + LD DE,RTC_TOP_LOOP1_INIT_DATE + LD C,09H ; CP/M write string to console call + CALL 0005H + CALL HEXIN + LD (DATE),A + +; hours + LD DE,RTC_TOP_LOOP1_INIT_HOURS + LD C,09H ; CP/M write string to console call + CALL 0005H + CALL HEXIN + LD (HOURS),A + +; minutes + LD DE,RTC_TOP_LOOP1_INIT_MINUTES + LD C,09H ; CP/M write string to console call + CALL 0005H + CALL HEXIN + LD (MINUTES),A + +; seconds + LD DE,RTC_TOP_LOOP1_INIT_SECONDS + LD C,09H ; CP/M write string to console call + CALL 0005H + CALL HEXIN + LD (SECONDS),A + +; day + LD DE,RTC_TOP_LOOP1_INIT_DAY + LD C,09H ; CP/M write string to console call + CALL 0005H + CALL HEXIN + LD (DAY),A + + RET + + +; function RTC_RESTART +; +; uses A, D, E, +; +; based on the following algorithm +; +; { Restart clock, set seconds to 00 } +; PROCEDURE rtc_restart; +; BEGIN +; rtc_wr_unprotect(); +; { Set seconds } +; rtc_write(0,0); +; rtc_wr_protect(); +; END; + +RTC_RESTART: + CALL RTC_WR_UNPROTECT + LD D,$00 + LD E,$00 + CALL RTC_WRITE + CALL RTC_WR_PROTECT + RET + + +; function RTC_CHARGE_ENABLE +; +; uses A, D, E +; +; based on following algorithm +; +; PROCEDURE rtc_charge_enable; +; BEGIN +; rtc_wr_unprotect(); +; { Enable trickle charger, 2kohm, 1 diode } +; rtc_write(8,$A5); +; rtc_wr_protect(); +; END; +; +; Trickle Charge Current: +; +; Imax = (5.0V - (0.7 * Ndiode)) / R +; (5.0 - (0.7 * 1)) / 2000 = .00215A = 2.15 milliamps +; (5.0 - (0.7 * 1)) / 8000 = 0.0005375A = .537 milliamps +; + +RTC_CHARGE_ENABLE + CALL RTC_WR_UNPROTECT + LD D,$08 + LD E,$A5 + CALL RTC_WRITE + CALL RTC_WR_PROTECT + RET + + +; function RTC_CHARGE_DISABLE +; +; uses A, D, E +; +; based on following algorithm +; +; PROCEDURE rtc_charge_disable; +; BEGIN +; rtc_wr_unprotect(); +; { Disable trickle charger} +; rtc_write(8,$00); +; rtc_wr_protect(); +; END; + +RTC_CHARGE_DISABLE + CALL RTC_WR_UNPROTECT + LD D,$08 + LD E,$00 + CALL RTC_WRITE + CALL RTC_WR_PROTECT + RET + + +; function TEST_BIT_DELAY +; +; based on the following algorithm +; +; +; PROCEDURE test_bit_delay(); +; var +; i,t0,t1 : int; +; BEGIN +; putln("Testing bit delay..."); +; t0 := sys_time(); +; for i := 0 while i < 1000 do inc(i) loop +; rtc_bit_delay(); +; end loop; +; t1 := sys_time(); +; putln(i," rtc_bit_delay calls took ",t1-t0," ms."); +; END; + +RTC_TEST_BIT_DELAY + LD DE,TESTING_BIT_DELAY_MSG + LD C,09H ; CP/M write string to console call + CALL 0005H + LD C,01H ; CP/M console input call + CALL 0005H + + ; test should take approximately 43 seconds based on the following code analysis + ; of Z80 T-states on a 4 MHz processor + ; =(4+15*(7+255*(7+255*(17+144+4+10)+4+10)+10)+7)/4/1000000 + + LD B,$0F +PAUSE: + LD C,$FF +PAUSE1: + LD A,$FF ; ADJUST THE TIME 13h IS FOR 4 MHZ +PAUSE2: + CALL RTC_BIT_DELAY ; CAUSE 36uS DELAY + DEC A ; DEC COUNTER. + JP NZ,PAUSE2 ; JUMP TO PAUSE2 IF A <> 0. + DEC C ; DEC COUNTER + JP NZ,PAUSE1 ; JUMP TO PAUSE1 IF C <> 0. + DJNZ PAUSE ; JUMP TO PAUSE IF B <> 0. + + LD DE,TESTING_BIT_DELAY_OVER + LD C,09H ; CP/M write string to console call + CALL 0005H + RET + + +; function RTC_HELP +; +; based on following algorithm +; +; PROCEDURE help(); +; BEGIN +; putln(); +; putln("rtc: ",version); +; putln("rtc: Commands: (E)xit (T)ime st(A)rt (S)et (R)aw (L)oop (C)harge (N)ocharge (H)elp"); +; END; + +RTC_HELP + LD DE,RTC_HELP_MSG + LD C,09H ; CP/M write string to console call + CALL 0005H + RET + +; function RTC_INIT +; +; Determine RTC port based on hardware platform +; and record it dynamically in code (see RTC_IN and RTC_OUT). +; + +RTC_INIT: + CALL IDBIO ; Id BIOS, 1=HBIOS, 2=UBIOS + DEC A ; Test for HBIOS + JR Z,HINIT ; Do HBIOS setup + DEC A ; Test for UBIOS + JR Z,UINIT ; Do UBIOS setup +; + ; Neither UNA nor RomWBW + LD DE,BIOERR ; BIOS error message + LD C,9 ; BDOS string display function + CALL BDOS ; Do it + JP 0 ; Bail out! +; +HINIT: +; + ; Display RomWBW notification string + LD DE,HBTAG ; BIOS notification string + LD C,9 ; BDOS string display function + CALL BDOS ; Do it +; + ; Get platform id from RomWBW HBIOS + LD B,0F1H ; HBIOS VER function 0xF1 + LD C,0 ; Required reserved value + RST 08 ; Do it, L := Platform ID + LD A,L ; Move to A +; + ; Assign correct port to C + LD C,PORT_SBC + LD DE,PLT_SBC + CP $01 ; SBC + JR Z,RTC_INIT2 + CP $02 ; ZETA + JR Z,RTC_INIT2 + CP $03 ; ZETA 2 + JR Z,RTC_INIT2 + LD C,PORT_N8 + LD DE,PLT_N8 + CP $04 ; N8 + JR Z,RTC_INIT2 + LD C,PORT_MK4 + LD DE,PLT_MK4 + CP $05 ; Mark IV + JR Z,RTC_INIT2 +; + ; Unknown platform + LD DE,PLTERR ; BIOS error message + LD C,9 ; BDOS string display function + CALL BDOS ; Do it + JP 0 ; Bail out! +; +UINIT: + ;; Display UNA notification string + ;LD DE,UBTAG ; BIOS notification string + ;LD C,9 ; BDOS string display function + ;CALL BDOS ; Do it +; + ; Notify UNA not supported at present + LD DE,UBERR ; BIOS not support message + LD C,9 ; BDOS string display function + CALL BDOS ; Do it + JP 0 ; Bail out! + +RTC_INIT2: + ; Record port number in code routines + LD A,C + LD (INP),A + LD (OUTP),A +; + ; Display platform + LD C,9 ; BDOS string display function + CALL BDOS ; Do it + RET + +; +; Identify active BIOS. RomWBW HBIOS=1, UNA UBIOS=2, else 0 +; +IDBIO: +; + ; Check for UNA (UBIOS) + LD A,(0FFFDH) ; fixed location of UNA API vector + CP 0C3H ; jp instruction? + JR NZ,IDBIO1 ; if not, not UNA + LD HL,(0FFFEH) ; get jp address + LD A,(HL) ; get byte at target address + CP 0FDH ; first byte of UNA push ix instruction + JR NZ,IDBIO1 ; if not, not UNA + INC HL ; point to next byte + LD A,(HL) ; get next byte + CP 0E5H ; second byte of UNA push ix instruction + JR NZ,IDBIO1 ; if not, not UNA, check others + LD A,2 ; UNA BIOS id = 2 + RET ; and done +; +IDBIO1: + ; Check for RomWBW (HBIOS) + LD HL,(0FFFEH) ; HL := HBIOS ident location + LD A,'W' ; First byte of ident + CP (HL) ; Compare + JR NZ,IDBIO2 ; Not HBIOS + INC HL ; Next byte of ident + LD A,~'W' ; Second byte of ident + CP (HL) ; Compare + JR NZ,IDBIO2 ; Not HBIOS + LD A,1 ; HBIOS BIOS id = 1 + RET ; and done +; +IDBIO2: + ; No idea what this is + XOR A ; Setup return value of 0 + RET ; and done + + +; function RTC_TOP_LOOP +; +; based on following algorithm +; +; PROCEDURE toploop(); +; var +; err,i,n,fd : int; +; BEGIN +; putln(); +; help(); +; rtc_reset_on(); +; hold(100); +; test_bit_delay(); +; rtc_charge_disable(); +; putln("rtc: trickle charger disabled."); +; loop +; put("rtc>"); +; gets(line); +; if line = "exit" then +; putln("Bye."); +; exit(0); +; elsif line = "charge" then +; putln("Trickle charger enabled."); +; rtc_charge_enable(); +; elsif line = "nocharge" then +; putln("Trickle charger disabled."); +; rtc_charge_disable(); +; elsif line = "start" then +; rtc_restart(); +; putln("Restarting RTC"); +; elsif line = "t" then +; rtc_get_time(line); +; putln("Current time: ",line); +; elsif line = "raw" then +; putln(); +; putln("Raw read loop, hit any key to stop..."); +; while read(0,@n,1 + RD_NOWAIT) = 0 loop +; put(#13,"sec=",hexstr(rtc_read(0))^); +; put(" min=",hexstr(rtc_read(1))^); +; hold(500); +; end loop; +; elsif line = "loop" then +; putln(); +; putln("Clock loop, hit any key to stop..."); +; while read(0,@n,1 + RD_NOWAIT) = 0 loop +; rtc_get_time(line); +; put(#13,line); +; hold(200); +; end loop; +; elsif line = "set" then +; putln("Setting RTC time to 96-02-18 19:43:00"); +; rtc_set_now(); +; elsif (line = "help") or (line = "?") then +; help(); +; elsif length(line) <> 0 then +; putln("You typed: """,line,""""); +; end; +; end loop; +; END toploop; + +RTC_TOP_LOOP: + LD DE,CRLF_MSG + LD C,09H ; CP/M write string to console call + CALL 0005H + + CALL RTC_HELP + + CALL RTC_RESET_ON + + CALL RTC_BIT_DELAY + CALL RTC_BIT_DELAY + CALL RTC_BIT_DELAY + +; CALL RTC_TEST_BIT_DELAY + +; CALL RTC_CHARGE_DISABLE ; *vk5dg* using supercap so leave on + +; LD DE,RTC_TOP_LOOP1_MSG +; LD C,09H ; CP/M write string to console call +; CALL 0005H + +RTC_TOP_LOOP_1: + LD DE,RTC_TOP_LOOP1_PROMPT + LD C,09H ; CP/M write string to console call + CALL 0005H + + LD C,01H ; CP/M console input call + CALL 0005H + + AND %01011111 ; handle lower case responses to menu + + CP 'E' + JP Z,RTC_TOP_LOOP_EXIT + + CP 'C' + JP Z,RTC_TOP_LOOP_CHARGE + + CP 'N' + JP Z,RTC_TOP_LOOP_NOCHARGE + + CP 'A' + JP Z,RTC_TOP_LOOP_START + + CP 'T' + JP Z,RTC_TOP_LOOP_TIME + + CP 'R' + JP Z,RTC_TOP_LOOP_RAW + + CP 'L' + JP Z,RTC_TOP_LOOP_LOOP + + CP 'H' + JP Z,RTC_TOP_LOOP_HELP + + CP 'D' + JP Z,RTC_TOP_LOOP_DELAY + + CP 'S' + JP Z,RTC_TOP_LOOP_SET + + CP 'I' + JP Z,RTC_TOP_LOOP_INIT + + CP 'G' + JP Z,RTC_TOP_LOOP_GET + + CP 'P' + JP Z,RTC_TOP_LOOP_PUT + + LD DE,RTC_TOP_LOOP1_OTHER1 + LD C,09H ; CP/M write string to console call + CALL 0005H + + LD E,A + LD C,02H ; CP/M Console output call + CALL 0005H + + LD DE,RTC_TOP_LOOP1_OTHER2 + LD C,09H ; CP/M write string to console call + CALL 0005H + + JP RTC_TOP_LOOP_1 + +RTC_TOP_LOOP_EXIT: + RET + +RTC_TOP_LOOP_CHARGE: + LD DE,RTC_TOP_LOOP1_CHARGE + LD C,09H ; CP/M write string to console call + CALL 0005H + CALL RTC_CHARGE_ENABLE + JP RTC_TOP_LOOP_1 + +RTC_TOP_LOOP_NOCHARGE: + LD DE,RTC_TOP_LOOP1_NOCHARGE + LD C,09H ; CP/M write string to console call + CALL 0005H + CALL RTC_CHARGE_DISABLE + JP RTC_TOP_LOOP_1 + +RTC_TOP_LOOP_START: + LD DE,RTC_TOP_LOOP1_START + LD C,09H ; CP/M write string to console call + CALL 0005H + CALL RTC_RESTART + JP RTC_TOP_LOOP_1 + +RTC_TOP_LOOP_TIME: + LD DE,RTC_TOP_LOOP1_TIME + LD C,09H ; CP/M write string to console call + CALL 0005H + CALL RTC_GET_TIME + LD DE,RTC_PRINT_BUFFER + LD C,09H ; CP/M write string to console call + CALL 0005H + JP RTC_TOP_LOOP_1 + +RTC_TOP_LOOP_RAW: + LD DE,RTC_TOP_LOOP1_RAW + LD C,09H ; CP/M write string to console call + CALL 0005H +RTC_TOP_LOOP_RAW1: + +; { Read seconds } + LD D,$00 ; seconds register in DS1302 + CALL RTC_READ ; read value from DS1302, value is in Reg C + + ; digit 16 + LD A,C ; put value output in Reg C into accumulator + RLC A + RLC A + RLC A + RLC A + AND $07 + ADD A,'0' + LD (RTC_PRINT_BUFFER+15),A + + ; digit 17 + LD A,C ; put value output in Reg C into accumulator + AND $0F + ADD A,'0' + LD (RTC_PRINT_BUFFER+16),A + +; { Read minutes } + + LD D,$01 ; minutes register in DS1302 + CALL RTC_READ ; read value from DS1302, value is in Reg C + + ; digit 13 + LD A,C ; put value output in Reg C into accumulator + RLC A + RLC A + RLC A + RLC A + AND $07 + ADD A,'0' + LD (RTC_PRINT_BUFFER+12),A + + ; digit 14 + LD A,C ; put value output in Reg C into accumulator + AND $0F + ADD A,'0' + LD (RTC_PRINT_BUFFER+13),A + + ; digit 15 + LD A,':' + LD (RTC_PRINT_BUFFER+14),A + + ; digits 1-12 and 18-20 are spaces + LD A,' ' ; space + LD (RTC_PRINT_BUFFER+19),A + LD (RTC_PRINT_BUFFER+18),A + LD (RTC_PRINT_BUFFER+17),A + LD (RTC_PRINT_BUFFER+11),A + LD (RTC_PRINT_BUFFER+10),A + LD (RTC_PRINT_BUFFER+09),A + LD (RTC_PRINT_BUFFER+08),A + LD (RTC_PRINT_BUFFER+07),A + LD (RTC_PRINT_BUFFER+06),A + LD (RTC_PRINT_BUFFER+05),A + LD (RTC_PRINT_BUFFER+04),A + LD (RTC_PRINT_BUFFER+03),A + LD (RTC_PRINT_BUFFER+02),A + LD (RTC_PRINT_BUFFER+01),A + LD (RTC_PRINT_BUFFER+00),A + + LD DE,RTC_PRINT_BUFFER + LD C,09H ; CP/M write string to console call + CALL 0005H + + LD C,01H ; CP/M console input call + CALL 0005H + + CP ' ' ; space + JP Z,RTC_TOP_LOOP_RAW1 + + JP RTC_TOP_LOOP_1 + +RTC_TOP_LOOP_LOOP: + LD DE,RTC_TOP_LOOP1_LOOP + LD C,09H ; CP/M write string to console call + CALL 0005H + +RTC_TOP_LOOP_LOOP1: + CALL RTC_GET_TIME + + LD DE,RTC_PRINT_BUFFER + LD C,09H ; CP/M write string to console call + CALL 0005H + + LD C,01H ; CP/M console input call + CALL 0005H + + CP ' ' + JP Z,RTC_TOP_LOOP_LOOP1 + + JP RTC_TOP_LOOP_1 + +RTC_TOP_LOOP_SET: + LD DE,RTC_TOP_LOOP1_SET + LD C,09H ; CP/M write string to console call + CALL 0005H + CALL RTC_SET_NOW + JP RTC_TOP_LOOP_1 + +RTC_TOP_LOOP_INIT: + LD DE,RTC_TOP_LOOP1_INIT + LD C,09H ; CP/M write string to console call + CALL 0005H + CALL RTC_INIT_NOW + JP RTC_TOP_LOOP_1 + +RTC_TOP_LOOP_DELAY: + CALL RTC_TEST_BIT_DELAY + JP RTC_TOP_LOOP_1 + +RTC_TOP_LOOP_HELP: + CALL RTC_HELP + JP RTC_TOP_LOOP_1 + +RTC_TOP_LOOP_PUT: + LD A,$01 ; set PUT as true + LD (GET_PUT),A +RTC_TOP_LOOP_GET: + LD DE,RTC_TOP_LOOP1_GET + LD C,09H ; CP/M write string to console call + CALL 0005H + + CALL HEXIN ; read NVRAM address + LD (PUT_ADR),A ; store for possible PUT later + +; { Read NVRAM address } + LD D,A ; seconds register in DS1302 + CALL RTC_READ ; read value from DS1302, value is in Reg C + + ; first digit + LD A,C ; put value output in Reg C into accumulator + RLC A + RLC A + RLC A + RLC A + AND $0F + CP 0AH ;TEST FOR NUMERIC & convert to ASCII + JR C,NUM1 ;if not ALPHA, its numeric and skip + ADD A,$07 + +NUM1: ADD A,'0' + LD (RTC_GET_BUFFER),A + + ; second digit + LD A,C ; put value output in Reg C into accumulator + AND $0F + CP 0AH ;TEST FOR NUMERIC & convert to ASCII + JR C,NUM2 ;if not ALPHA, its numeric and skip + ADD A,$07 + +NUM2: ADD A,'0' + LD (RTC_GET_BUFFER+1),A + + LD DE,RTC_TOP_LOOP1_OTHER2 + LD C,09H ; CP/M write string to console call + CALL 0005H + + LD DE,RTC_GET_BUFFER + LD C,09H ; CP/M write string to console call + CALL 0005H + + LD A,(GET_PUT) ; check if GET or PUT mode + CP $00 + JP Z,RTC_GET_PUT_EXIT ; if GET mode, exit + + LD DE,RTC_TOP_LOOP1_PUT + LD C,09H ; CP/M write string to console call + CALL 0005H + +; { Write NVRAM address } + + CALL RTC_WR_UNPROTECT + + CALL HEXIN ; read NVRAM address + LD E,A ; new data for NVRAM register in DS1302 + LD A,(PUT_ADR) + LD D,A ; load address from before + + CALL RTC_WRITE ; read value from DS1302, value is in Reg C + + CALL RTC_WR_PROTECT + +RTC_GET_PUT_EXIT: + LD A,$00 ; reset GET mode + LD (GET_PUT),A + JP RTC_TOP_LOOP_1 + + + + +; +; Text Strings +; + +MSG: + .TEXT "Start RTC Program" + .DB 0Ah, 0Dh ; line feed and carriage return + .DB "$" ; Line terminator + +CRLF_MSG: + .DB 0Ah, 0Dh ; line feed and carriage return + .DB "$" ; Line terminator + +TESTING_BIT_DELAY_MSG: + .DB 0Ah, 0Dh ; line feed and carriage return + .TEXT "Testing bit delay. Successful test is ~43 sec." + .DB 0Ah, 0Dh ; line feed and carriage return + .TEXT "Start clock and press space bar." + .DB 0Ah, 0Dh ; line feed and carriage return + .DB "$" ; Line terminator + +TESTING_BIT_DELAY_OVER: + .DB 0Ah, 0Dh ; line feed and carriage return + .TEXT "Test complete. Stop clock." + .DB 0Ah, 0Dh ; line feed and carriage return + .DB "$" ; Line terminator + +RTC_HELP_MSG: + .DB 0Ah, 0Dh ; line feed and carriage return + .TEXT "RTC: Version 1.1" + .DB 0Ah, 0Dh ; line feed and carriage return + .TEXT "RTC: Commands: E)xit T)ime st(A)rt S)et R)aw L)oop C)harge N)ocharge D)elay I)nit G)et P)ut H)elp" + .DB 0Ah, 0Dh ; line feed and carriage return + .DB "$" ; Line terminator + +RTC_TOP_LOOP1_MSG: + .DB 0Ah, 0Dh ; line feed and carriage return + .TEXT "RTC: trickle charger disabled." + .DB 0Ah, 0Dh ; line feed and carriage return + .DB "$" ; Line terminator + +RTC_TOP_LOOP1_PROMPT: + .DB 0Ah, 0Dh ; line feed and carriage return + .TEXT "RTC>" + .DB "$" ; Line terminator + +RTC_TOP_LOOP1_CHARGE: + .DB 0Ah, 0Dh ; line feed and carriage return + .TEXT "Trickle charger enabled." + .DB 0Ah, 0Dh ; line feed and carriage return + .DB "$" ; Line terminator + +RTC_TOP_LOOP1_NOCHARGE: + .DB 0Ah, 0Dh ; line feed and carriage return + .TEXT "Trickle charger disabled." + .DB 0Ah, 0Dh ; line feed and carriage return + .DB "$" ; Line terminator + +RTC_TOP_LOOP1_START: + .DB 0Ah, 0Dh ; line feed and carriage return + .TEXT "Restart RTC." + .DB 0Ah, 0Dh ; line feed and carriage return + .DB "$" ; Line terminator + +RTC_TOP_LOOP1_TIME: + .DB 0Ah, 0Dh ; line feed and carriage return + .TEXT "Current time: " + .DB "$" ; Line terminator + +RTC_TOP_LOOP1_RAW: + .DB 0Ah, 0Dh ; line feed and carriage return + .TEXT "Raw read Loop. Press SPACE BAR for next." + .DB 0Ah, 0Dh ; line feed and carriage return + .DB "$" ; Line terminator + +RTC_TOP_LOOP1_LOOP: + .DB 0Ah, 0Dh ; line feed and carriage return + .TEXT "Clock Loop. Press SPACE BAR for next." + .DB 0Ah, 0Dh ; line feed and carriage return + .DB "$" ; Line terminator + +RTC_TOP_LOOP1_SET: + .DB 0Ah, 0Dh ; line feed and carriage return + .TEXT "Set RTC time." + .DB 0Ah, 0Dh ; line feed and carriage return + .DB "$" ; Line terminator + +RTC_TOP_LOOP1_INIT: + .DB 0Ah, 0Dh ; line feed and carriage return + .TEXT "Init date/time." + .DB 0Ah, 0Dh ; line feed and carriage return + .DB "$" ; Line terminator + +RTC_TOP_LOOP1_GET: + .DB 0Ah, 0Dh ; line feed and carriage return + .TEXT "Get NVRAM addr:" + .DB "$" ; Line terminator + +RTC_TOP_LOOP1_PUT: + .DB 0Ah, 0Dh ; line feed and carriage return + .TEXT "NVRAM data:" + .DB "$" ; Line terminator + +RTC_TOP_LOOP1_INIT_SECONDS: + .DB 0Ah, 0Dh ; line feed and carriage return + .TEXT "SECONDS:" + .DB "$" ; Line terminator + +RTC_TOP_LOOP1_INIT_MINUTES: + .DB 0Ah, 0Dh ; line feed and carriage return + .TEXT "MINUTES:" + .DB "$" ; Line terminator + +RTC_TOP_LOOP1_INIT_HOURS: + .DB 0Ah, 0Dh ; line feed and carriage return + .TEXT "HOURS:" + .DB "$" ; Line terminator + +RTC_TOP_LOOP1_INIT_DATE: + .DB 0Ah, 0Dh ; line feed and carriage return + .TEXT "DATE:" + .DB "$" ; Line terminator + +RTC_TOP_LOOP1_INIT_MONTH: + .DB 0Ah, 0Dh ; line feed and carriage return + .TEXT "MONTH:" + .DB "$" ; Line terminator + +RTC_TOP_LOOP1_INIT_DAY: + .DB 0Ah, 0Dh ; line feed and carriage return + .TEXT "DAY:" + .DB "$" ; Line terminator + +RTC_TOP_LOOP1_INIT_YEAR: + .DB 0Ah, 0Dh ; line feed and carriage return + .TEXT "YEAR:" + .DB "$" ; Line terminator + +RTC_TOP_LOOP1_OTHER1: + .DB 0Ah, 0Dh ; line feed and carriage return + .TEXT "YOU TYPED: " + .DB "$" ; Line terminator + +RTC_TOP_LOOP1_OTHER2: + .DB 0Ah, 0Dh ; line feed and carriage return + .DB "$" ; Line terminator + +RTC_PRINT_BUFFER: + .FILL 20,0 ; Buffer for formatted date & time to print + .DB 0Ah, 0Dh ; line feed and carriage return + .DB "$" ; line terminator + +RTC_GET_BUFFER: + .FILL 2,0 ; Buffer for formatted NVRAM data to print + .DB 0Ah, 0Dh ; line feed and carriage return + .DB "$" ; line terminator + +BIOERR .TEXT "Unknown BIOS, aborting...\r\n$" +PLTERR .TEXT "Unknown hardware platform, aborting...\r\n$" +UBERR .TEXT "UNA UBIOS is not currently supported, aborting...\r\n$" +HBTAG .TEXT "RomWBW HBIOS$" +UBTAG .TEXT "UNA UBIOS" +PLT_SBC .TEXT ", RTC Latch Port 0x70\r\n$" +PLT_N8 .TEXT ", RTC Latch Port 0x88\r\n$" +PLT_MK4 .TEXT ", RTC Latch Port 0x8A\r\n$" + +; +; Generic FOR-NEXT loop algorithm +; +; LD A,$00 ; set A=0 index counter of FOR loop +;FOR_LOOP: +; PUSH AF ; save accumulator as it is the index counter in FOR loop +; { contents of FOR loop here } ; setup RTC with RST and RD high, SCLK low +; POP AF ; recover accumulator as it is the index counter in FOR loop +; INC A ; increment A in FOR loop (A=A+1) +; CP $08 ; is A < $08 ? +; JP NZ,FOR_LOOP ; No, do FOR loop again +; RET ; Yes, end function and return. Read RTC value is in C + +YEAR .DB $17 +MONTH .DB $11 +DATE .DB $29 +HOURS .DB $00 +MINUTES .DB $00 +SECONDS .DB $00 +DAY .DB $04 +GET_PUT .DB $00 + +PUT_ADR .DB 0 + + .END + diff --git a/Source/RomDsk/MK4/RTC.COM b/Source/RomDsk/MK4/RTC.COM deleted file mode 100644 index 64788f53289c448a166a926e440b2147a8a2247f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2048 zcma)6O>7%Q6y9~#@gyQn_Y#Q%Wh8oFg$QAx60FElV;ehCY8%^W6;u>$>}{~>*zS4* z2_Oha2q~wkCys!Ggpg1paVeKpaT>R~?v|2NqE*%W7E6c&R46CJhBq_oI6pmLTRZQ2 z-+OP~oB6ydCvPG(DsLe5NqHTq&&X>?^~tM94ag6W>X)~W%E=Fr_-1FY%kguLDg-%L z-&=|`0_@xDtq-`$E53SQV!CaY7px`cJl_h65wI}3UQ^gs&SyOQ)cKaR$7${HUfP~%#OzzVdVvP2w^!yC@A2vphEjBCbUk{_MYW%J z>r#;Gb^e*ng8-Lv&jahR;Y`{{lQy*J3sIrG+%E7>a$7bGXG(7hb+!F{6BlB zPpPlT+adP2yWQED!2*T5!{e{ zUvRVb?}D4QcLaCXp7XnL`=;NG*mb{~vA_4bL-u9A8?%4)yD59wFV3@x#-L9>CthJ_ zaYV4hDYldIR|i1xqK90H<~_7Y(SnCkK5=2UfVj-OeVilt+IrZp*FOFbc|frsyE_OJ z1fl|c$_)gP1tH2ekbE71;^ZYHUqc`rxrRVZtp?b;0NVjSX`b`0t=(XYzexG#JpNTW z&Y*`rA;@_`AkX9Esq*A?^_EA2u6{$O_x0cFc9WMC==v_v^)9-HS|=;sW!cI@vvaX&M^JN`*-sSIuWb z5_F%DbQnR>-p9jI8R~_lcQs=|#|f#NV^%~W6W}4K1j#WHo|2|a90zxW_Cy<}n&rcp2yPs0p`uI2GC z%mK%fqGy;%g~Cz%MktNXmJM9er%f-Np7s9<&5#p+zCPK-!slq{psP@1mE a5u6=OMI&_9W87mta2Xs&ACDpTyZ!^A>#V{6 diff --git a/Source/RomDsk/N8/RTC.COM b/Source/RomDsk/N8/RTC.COM deleted file mode 100644 index c644663afee67a8249a89e462e7b5d17159ef46d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2048 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 ZGdMq-iO1-y$GC@l;4(OlJ|03c*MII)ukio? diff --git a/Source/RomDsk/ZETA/RTC.COM b/Source/RomDsk/ZETA/RTC.COM deleted file mode 100644 index b36725f379bb1113467be09629c472e3b3314ca1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2048 zcma)6O>7%Q6y9~#@gyQn_Y#Q%Wh8oFg$QAx60FElV;ehCY8%@r3Mz^=_BL2`YO`sFR8a`FQtzTO?|ar~U43PBFm zcb8(#0QaeJ;Avv2b1c^atRTB$7F<<%n$rRdV^dH9Np>Ob+; z#UR(sZ>vMpeXjzU|MGM5$tI^(sEfw^!CQYjKk)CjUTp>%^GW9t|3PbqEY3IlKYOT8 zsISG`1A(LSPS9t;%8`{+2wovcEq<;&d@Ilxl5e3oays%a=n&<2)J>!+^3VJEE=aLG zzDf8ShxuzBe;uhu%kisN7HyPX4%v_(bo5(jx`W8Y(PrLe8mAKN?ho#$J0Qj3 z`jbLm{R!d7pW=^`Q((X8-DUQ}(i7TwoJTK%ah2yv)$z zm|%%BY$xZhE`Z_%54jXAcxaQNnuk(8v9?=4TxQ+@&XIf_J?z)(0Dp))pjeRIZ3GGe zQGq_?CIZQV5asJgzJ@??@)DA-B9M+;N13MFRZ?SP*&&w1C@X|T;-p!_o)|1uqC z*h3!^dGfk?!=pi0zo9qx_22LIl9v_e`VP_cF1m}_CoA4z*~$ata<^XMH+53cELSkiVLUXV;8VI$EtE_6`N5&yKI#dVr>CK2Rl!kd78=S*g=rmE&8I^W zbf1xQ7(vqB!=q9e>V>6uG-FD~38|c8RzxBb;1Q_=$uSb1l4eXC2X}?`MRzfcLhfu) z$1KUf`9f8jEb95))>JaVfgruKC*~k|paKlmQ4P4S^O)s6E_5TXZkQ0JSCOfg@5pooH&D5Xk_+k*1IF$~a z#9BUYD9{i?5T+57iH4JjNQRgvM-pS%C^h5Bu{1Rzp=^|L$wW3zj7VslEaTBony$$) ZoE=X^BXrhd+#^1485~C+k0AHE{sWO0tE2z` diff --git a/Source/RomDsk/ZETA2/RTC.COM b/Source/RomDsk/ZETA2/RTC.COM deleted file mode 100644 index b36725f379bb1113467be09629c472e3b3314ca1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2048 zcma)6O>7%Q6y9~#@gyQn_Y#Q%Wh8oFg$QAx60FElV;ehCY8%@r3Mz^=_BL2`YO`sFR8a`FQtzTO?|ar~U43PBFm zcb8(#0QaeJ;Avv2b1c^atRTB$7F<<%n$rRdV^dH9Np>Ob+; z#UR(sZ>vMpeXjzU|MGM5$tI^(sEfw^!CQYjKk)CjUTp>%^GW9t|3PbqEY3IlKYOT8 zsISG`1A(LSPS9t;%8`{+2wovcEq<;&d@Ilxl5e3oays%a=n&<2)J>!+^3VJEE=aLG zzDf8ShxuzBe;uhu%kisN7HyPX4%v_(bo5(jx`W8Y(PrLe8mAKN?ho#$J0Qj3 z`jbLm{R!d7pW=^`Q((X8-DUQ}(i7TwoJTK%ah2yv)$z zm|%%BY$xZhE`Z_%54jXAcxaQNnuk(8v9?=4TxQ+@&XIf_J?z)(0Dp))pjeRIZ3GGe zQGq_?CIZQV5asJgzJ@??@)DA-B9M+;N13MFRZ?SP*&&w1C@X|T;-p!_o)|1uqC z*h3!^dGfk?!=pi0zo9qx_22LIl9v_e`VP_cF1m}_CoA4z*~$ata<^XMH+53cELSkiVLUXV;8VI$EtE_6`N5&yKI#dVr>CK2Rl!kd78=S*g=rmE&8I^W zbf1xQ7(vqB!=q9e>V>6uG-FD~38|c8RzxBb;1Q_=$uSb1l4eXC2X}?`MRzfcLhfu) z$1KUf`9f8jEb95))>JaVfgruKC*~k|paKlmQ4P4S^O)s6E_5TXZkQ0JSCOfg@5pooH&D5Xk_+k*1IF$~a z#9BUYD9{i?5T+57iH4JjNQRgvM-pS%C^h5Bu{1Rzp=^|L$wW3zj7VslEaTBony$$) ZoE=X^BXrhd+#^1485~C+k0AHE{sWO0tE2z`