* REAL-TIME CLOCK UTILITY BY S. K. WEBB * RTCV23 -> Source re-created by Z80DIS 2.2 * Z80DIS was written by Kenneth Gielow * Palo Alto, CA XTEXT ASCII XTEXT HOSEQU XTEXT ESVAL XTEXT ECDEF XTEXT COMP XTEXT DADA XTEXT DADA2 XTEXT DU66 XTEXT UDD XTEXT HOSDEF XTEXT TYPTX XTEXT HLIHL XTEXT MU10 XTEXT MOVE CLOCK EQU 240Q Clock base port S1 EQU 0 Seconds register S10 EQU 1 Tens of Seconds MI1 EQU 2 Minutes register MI10 EQU 3 Tens of Minutes H1 EQU 4 Hours register H10 EQU 5 Tens of Hours D1 EQU 6 Days register D10 EQU 7 Tens of Days MO1 EQU 8 Months register MO10 EQU 9 Tens of Months Y1 EQU 10 Years register Y10 EQU 11 Tens of Years W EQU 12 Day of week reg. REGD EQU 13 Control Register D REGE EQU 14 Control Register E REGF EQU 15 Control Register F * * Epson 7242 RTC register masks * * Control Register D * RDHOLD EQU 00000001B Hold RDBUSY EQU 00000010B Busy RDIRQ EQU 00000100B IRQ Flag RD30S EQU 00001000B 30 Second correction * * Control Register E * REMASK EQU 00000001B Mask REITR EQU 00000010B ITRPT/STND RET0 EQU 00000100B t0 RET1 EQU 00001000B t1 * * Control Register F * REFRST EQU 00000001B Reset REFSTOP EQU 00000010B Stop REF24 EQU 00000100B 1=24 hr. mode; 0=12 hr. REFTEST EQU 00001000B Test must be 0 ORG USERFWA WELCOM DB 'H8 RTC Support Utility v2.3 (08-APR-13 VERSION) ' DB 'by Stanley K. Webb',ENL USAGE DB 'Usage=>RTC HELP',NL DB 'or =>RTC SETUP',NL DB 'or =>RTC',TAB,TAB DB '(for TIME and DATE update)',ENL * * Execution starts here * ENTRY LXI H,WELCOM print signon message SCALL .PRINT LXI H,CKDVD Load CK: device driver SCALL .LOADD LXI H,MEMTOP Set RAM top SCALL .SETTP MVI A,EC.NEM Not enough memory JC ERROR SCALL .VERS HDOS Version PUSH PSW MVI A,EC.NCV Not correct verson of HDOS JC ERROR POP PSW CPI VERS JNC VEROK MVI A,EC.NCV Not correct version of HDOS JMP ERROR * * Past initial error checking * VEROK LXI H,0 DAD SP HL = SP (points to cmd line parameters) MVI A,200Q Subtract offset SUB L Look at low byte (L) LXI D,CMDLINE Destination MOV C,A String length CALL STRCPY Make a copy * * Welcome user * LXI SP,WELCOM LXI D,CMDLINE Examine command line CALL DOCMD Process command line * * HELP command * DB 'HELP',0 LXI H,USAGE JNC PREXIT Print message and exit LDAX D ANA A JZ J$23A0 CALL DOCMD * * SETUP command * DB 'SETUP',0 JNC J.238B CALL DOCMD * * SET command * DB 'SET',0 JNC J.238B * * No match, print error message * MVI A,BELL Ring the bell SCALL .SCOUT LXI H,USAGE And print usage reminder SCALL .PRINT * * Exit to HDOS * EXIT MVI A,0 SCALL .CLOSE XRA A SCALL .EXIT * * Print message in (HL) and then exit * PREXIT SCALL .PRINT JMP EXIT * * Process error and then exit * ERROR MVI H,EC.ILR Illegal Request SCALL .ERROR JMP EXIT J.238B CALL CHKRTC Check for the RTC CNC READDOW If have RTC get the DOW * * Even if no RTC found proceed with date/time set * CALL INDATE Prompt user for date CALL INTIME Prompt user for time CALL SETCLK Set clock device CALL WRRTC Write date, time and DOW to RTC JMP J$2411 J$23A0 CALL CHKRTC JC NORTC CALL RDRTC Read and store RTC data CALL GETTIM Fetch S.TIME working copy CALL SETCLK * * Display the time * CALL $TYPTX DB 'RTC Time is',' '+200Q CALL PRSTIM * * Compute and store coded (HDOS) date * CALL CODEDT Compute coded date SHLD S.DATC Store in RAM XCHG DE = coded date LXI H,S.DATE Address of ASCII date CALL $DAD Decode Augustan Date * * Display the day of week, and date * CALL $TYPTX DB NL,'RTC Date is',' '+200Q CALL PRNDAY Print day of week CALL $TYPTX DB ',',' '+200Q CALL PRSDAT Print system date CALL $TYPTX DB ' (System Updated)',ENL JMP EXIT NORTC CALL $TYPTX DB 'NO RTC Found',ENL J$2411 CALL $TYPTX DB 'System Time is',' '+200Q CALL PRSTIM Print system time CALL $TYPTX DB ' System Date is',' '+200Q CALL PRSDAT Print system date CALL $TYPTX DB ENL JMP EXIT * ============================================== * * PRSDAT - Print System Date stored in S.DATE * * ============================================== PRSDAT MVI C,9 Print 9 ASCII characters LXI H,S.DATE from System date PRSD1 MOV A,M fetch byte INX H point to next SCALL .SCOUT print it DCR C count down JNZ PRSD1 repeat 'til done... RET * ============================================== * * PRNDAY - print day of week * * ============================================== PRNDAY LDA DOW Fetch day of week ANI 7 low 3 bits ADD A *2 (word offset) LXI H,DTAB Table of day messages CALL $DADA point to entry CALL $HLIHL (HL) = entry CALL $TYPTX. type it! RET DTAB DW MSUN DW MMON DW MTUE DW MWED DW MTHU DW MFRI DW MSAT DW MERR MSUN DB 'Sunda','y'+200Q MMON DB 'Monda','y'+200Q MTUE DB 'Tuesda','y'+200Q MWED DB 'Wednesda','y'+200Q MTHU DB 'Thursda','y'+200Q MFRI DB 'Frida','y'+200Q MSAT DB 'Saturda','y'+200Q MERR DB 'PROGRAM ERR',200Q MYMO DB 6 MYDD DB 15H MYYY DB 48H YY DOW DB 0 Day of week * * Our copy of S.TIME * MYTIME EQU * MYHH DB 0 Hours MYMM DB 0 Minutes MYSS DB 0 Seconds * ============================================== * * PRSTIM - Print System Date stored in S.TIME * * ============================================== PRSTIM MVI C,3 3 bytes (hh, mm, ss) LXI H,S.TIME (HL) = S.TIME LXI D,HMSLC (DE) = ASCII time PUSH D Save address PRST1 MOV A,M Fetch byte (hh, mm or ss) ANI 0F0H High nibble RRC Move to low RRC RRC RRC ADI '0' make ASCII STAX D and store INX D next output byte MOV A,M fetch byte again ANI 0FH low nibble now ADI '0' make ASCII STAX D and store INX D skip ':' INX D next output byte INX H next input byte DCR C count down JNZ PRST1 loop 'til done POP H Pop string address CALL $TYPTX. and print it RET HMSLC DB 'hh:mm:ss',200Q HMSUC DB 'HH:MM:SS',NL,200Q XTEXT DDD XTEXT MCU XTEXT MLU * * READLU - Read line and map to upper case * READLU CALL READLN RC JMP $MLU * * READLN - Read a line of text * * ENTRY: (HL) = buffer for storing line * READLN PUSH H Save HL READLN1 CALL GETCH Get a character CPI CTLD CTL-D -> exit with 'C' set JZ READLN2 MOV M,A Store character INX H point to next CPI NL Was ENTER hit? JNZ READLN1 No, keep readin DCX H Enter was hit, go back one MVI M,0 Replace NL with NUL INX H and point past it XCHG XTHL MOV A,E SUB L ANA A POP D RET READLN2 POP H STC RET XTEXT SOB * ============================================== * * GETCH - Wait for a single character from the * console and read/return it * * ============================================== GETCH SCALL .SCIN JC GETCH RET * ============================================== * * PUTCH - Output a single character to the * console. * * ============================================== PUTCH SCALL .SCOUT RET SPACE 4,10 ** $CADY2K - CODE AUGUSTAN DATE IN HDOS Y2K FORMAT ** Modifications to $CAD by Stanley K. Webb ** More stringent checking of days in month by Stanley K. Webb ** ** $CADY2K IS CALLED TO CODE AN AUGUSTAN DATE INTO A 16 BIT WORD: ** ** 7BITS 4BIT 5BITS ** YYYYYYY MMMM DDDDD ** 1111110 0000 00000 ** 5432109 8765 43210 ** 00-99 1-12 1-31 ** ** FROM THE INPUT FORMAT: 'DD-MMM-YY' ** ** ENTRY HL POINTS TO STRING ** EXIT 'C' CLEAR IF OK ** (DE) = 16 BIT VALUE ** (HL) ADVANCED PAST '-YY' $CAD PUSH H MVI C,CADBL LXI D,CADB CALL $COMP JNZ CAD0 POP D LXI D,0 0 => NO-DATE ANA A RET CAD0 POP H CALL $DDD DECODE DECIMAL DIGITS RC MOV A,D ANA A STC RNZ TOO LARGE MOV A,E ANA A STC RZ TOO SMALL FOR DD CPI 32 CMC RC TOO BIG STA CAD.DD SKW- SAVE DAY XCHG MVI A,100000B COUNT FIRST MONTH ADD L MOV L,A XCHG PUSH D MOV A,M INX H CPI '-' JNE CAD2 FORMAT ERROR LXI D,CADA CAD1 LXI B,3 PUSH H PUSH D CALL $COMP POP D JE CAD3 POP H INX D INX D INX D XTHL MVI A,100000B CALL $DADA. XTHL LDAX D TEST FOR END OF STRING ANA A JNZ CAD1 CAD2 POP H STC RET CAD3 POP B MOV A,M CPI '-' JNE CAD2 INX H CALL $DDD DECODE DECIMAL DIGITS JC CAD2 ERROR MOV A,D ANA A JNZ CAD2 TOO BIG MOV A,E JC CAD2 CPI 100 SKW- Y2K FIX JNC CAD2 POP D STA CAD.YY SKW-SAVE YEAR ADD A SHIFT 1 BIT ADD D MOV D,A MERGE DATA ** CRACK OUT MONTH SKW ** PUSH H PUSH D XCHG DAD H DAD H DAD H MOV A,H ANI 00001111B ISOLATE MONTH STA CAD.MON SKW- SAVE MONTH ** AND TEST DAYS IN MONTH ** CALL DAYCHK SKW- CODED THIS SUBROUTINE POP D POP H RET CADA DS 0 DB 'JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC',0 CADB DB ' No-Date ' CADBL EQU *-CADB CAD.DD DB 0 CAD.MON DB 0 CAD.YY DB 0 DAYCHK LDA CAD.YY LXI HL,MNTHDNY ;NORMAL YEAR TABLE ANI 3H JNZ DAYCHK1 LXI HL,MNTHDLY ;HAVE LEAP YEAR DAYCHK1 LDA CAD.MON DCR A CALL $DADA ;HL POINTS TO MAX DAYS IN MONTH LDA CAD.DD DCR A CMP M CMC FLAG AS TOO MANY DAYS RET MNTHDNY DB 31,28,31,30,31,30,31,31,30,31,30,31 MNTHDLY DB 31,29,31,30,31,30,31,31,30,31,30,31 SPACE 4,10 ** $DADY2K - DECODE AUGUSTAN DATE WORD IN HDOSY2K FORMAT ** ** A MODIFIED VERSION OF $DAD BY STANLEY K. WEBB ** DECODES A 16 BIT DATE ENCODED IN THE FOLLOWING FORMAT: ** ** 7BITS 4BIT 5BITS ** YYYYYYY MMMM DDDDD ** 1111110 0000 00000 ** 5432109 8765 43210 ** 00-99 1-12 1-31 ** ** TO THE FORM 'DD-MMM-YY' ** ** ENTRY (DE)= 16 BIT PACKED DATE ** (HL)= ADDRESS FOR DECODE $DAD MOV A,D ORA E JZ DAD2 NO DATE MOV B,D MOV C,E LXI D,32 PUSH H SAVE ADDRESS CALL $DU66 (DE)=DAY, (HL) YEAR & MONTH XTHL HL=ADDRESS MOV B,D MOV C,E MOV A,E ANA A BAD VALUE? JZ DAD1 YES IF ZERO MVI A,2 CALL $UDD UNPACK DAY MVI M,'-' INX H POP B (BC)=YEAR & MONTH LXI D,16 PUSH H SAVE ADDRESS CALL $DU66 XTHL (HL)= ADDRESS ((SP))= YEAR MOV A,E ADD A ADD E A=3*MONTH JZ DAD1 ZERO IS BAD VALUE CPI 13*3 JNC DAD1 TOO BIG, BAD VALUE XCHG LXI H,DADB-3 GET MONTH CALL $DADA. LXI B,3 XCHG CALL $MOVE MOVE INTO PLACE MVI M,'-' INX H POP B MOV A,C ADI 0 CPI 100 TOO BIG? CMC RC MOV C,A MVI A,2 CALL $UDD UNPACK YEAR ANA A RET DAD1 POP H STC RET DAD2 LXI B,DADCL LXI D,DADC JMP $MOVE DADB DB 'JanFebMarAprMayJunJulAugSepOctNovDec' DADC DB ' No-Date ' DADCL EQU *-DADC * ============================================== * * READDOW - Prompt for Day Of Week, read and validate * answer and store it locally. * * ============================================== READDOW CALL $TYPTX DB NL,'Input Day of Week index (1-7)',NL,NL DB '1 = Sunday',NL DB '2 = Monday',NL DB '3 = Tuesday',NL DB '4 = Wednesday',NL DB '5 = Thursday',NL DB '6 = Friday',NL DB '7 = Saturday',ENL LXI H,CMDLINE CALL READLU Read line (map to upper case) JC EXIT exit if CTL-D hit CALL $SOB Skip over ' ' and TAB ANA A MVI A,0 Default to Sunday STA DOW RZ CALL $DDD Decode digits into DE MOV A,D Top byte must be 0 ANA A JNZ BADDOW MOV A,E Bottom byte must be DCR A 0-6 (entered as 1-7) CPI 7 JNC BADDOW STA DOW Valid DOW - save it! ANA A RET BADDOW CALL $TYPTX DB 'INVALID WEEK DAY INDEX ENTERED',BELL,ENL JMP READDOW Prompt for and read DOW * ============================================== * * INDATE - Input date as DD-MMM-YY * * ============================================== INDATE CALL $TYPTX DB NL,'Input DATE as DD-MMM-YY ?',' '+200Q LXI H,CMDLINE CALL READLU Read line (map to upper case) JC EXIT CALL $SOB ANA A JZ INDATE Try again CALL $CAD Code Augustan DAte JC BADDATE XCHG SHLD S.DATC XCHG LXI H,S.DATE CALL $DAD Decode Augustan Date JC ERROR1 LDA CAD.DD STA MYDD LDA CAD.MON STA MYMO LDA CAD.YY STA MYYY MVI A,3 LXI H,MYMO CALL CODEVAL RET BADDATE CALL $TYPTX DB 'INVALID DATE ENTERED',BELL,ENL JMP INDATE ERROR1 CALL $TYPTX DB BELL,'PROGRAM ERROR 1',ENL JMP EXIT * ============================================== * * Input time in 24 hour format * * ============================================== INTIME CALL $TYPTX Prompt to enter time DB NL,'Military Time ','('+200Q CALL PRSTIM Print current time CALL $TYPTX DB ')?',' '+200Q LXI H,CMDLINE CALL READLU Read line (map to upper case) JC EXIT CALL $SOB Skip white space (HL) ANA A JZ INTIME CALL $DDD MOV A,D ANA A JNZ INVTIM Invalid Time MOV A,E CPI 24 JNC INVTIM Invalid Time STA MYHH Hours good - save it! * * Validate minutes * MVI A,':' expecting ":" CMP M got it? JNZ INVTIM No! - invalid Time INX H next char CALL $DDD MOV A,D ANA A JNZ INVTIM Invalid Time MOV A,E CPI 60 Minutes must be < 60 JNC INVTIM Invalid Time STA MYMM Minutes good - save it! XRA A STA MYSS Zero our seconds value MVI A,':' expecting ":" CMP M got it? JNZ CODETM No! - done INX H next char CALL $DDD MOV A,D ANA A JNZ INVTIM Invalid Time MOV A,E CPI 60 Seconds must be < 60 JNC INVTIM Invalid Time STA MYSS Seconds good - save it! * * Now convert these decimal time values * into BCD coded ones * CODETM MVI A,3 Count 3 bytes (hh, mm, ss) LXI H,MYTIME Time location is here * * Code each value * CODEVAL PUSH PSW PUSH H MOV C,M (BC) = Value (hh, mm or ss) MVI B,0 LXI D,10 (DE) = 10 CALL $DU66 (HL) = value/10 MOV A,L Get tens value RLC put it in high nibble RLC RLC RLC ORA E Put ones in low nibble POP H restore memory pointer MOV M,A save the value INX H point to next POP PSW restore count DCR A decrement JNZ CODEVAL and loop 'til done GETTIM LXI H,S.TIME LXI D,MYTIME LXI B,3 DI CALL $MOVE EI RET INVTIM CALL $TYPTX DB ' INVALID TIME ENTERED',BELL,ENL JMP INTIME * * Set the clock device (even if none loaded) * SETCLK CALL WRITECK Write time to CK: ANA A RET * ============================================== * * WRITECK - Write time to CK: device * * ============================================== WRITECK MVI A,0 Channel 0 LXI D,DEFALT LXI H,CKDVD CK: device SCALL .OPENW Open for write RC LXI H,HMSLC 'hh:mm:ss' LDA MYHH our copy of hours CALL DTOBCD Convert and store ASCII MVI M,':' INX H LDA MYMM our copy of minutes CALL DTOBCD Convert and store ASCII MVI M,':' INX H LDA MYSS our copy of seconds CALL DTOBCD Convert and store ASCII MVI A,0 Console channel LXI B,9 9 bytes LXI D,HMSLC 'hh:mm:ss' (now current) SCALL .WRITE Write it RC MVI A,0 SCALL .CLOSE RC CALL $TYPTX DB NL,'CLOCK SET TO: ',200Q LXI H,HMSLC CALL $TYPTX. MVI A,0 LXI D,DEFALT LXI H,CKDVD SCALL .OPENR RC MVI A,0 Console I/O LXI B,9 9 bytes LXI D,HMSUC HH:MM:SS SCALL .READ Read it RC MVI A,0 SCALL .CLOSE RC CALL $TYPTX DB NL,'CLOCK READS: ',200Q LXI H,HMSUC SCALL .PRINT ANA A RET * ============================================== * * DTOBCD - convert decimal value into * two ASCII bytes, high nibble first, then * low. Store these in (HL) while incrementing * location. * * ============================================== DTOBCD CALL BTOBCD Once for each nibble BTOBCD RRC Rotate nibble RRC RRC RRC PUSH PSW ANI 0FH mask nibble ADI '0' Convert to ASCII MOV M,A Store it INX H and point to next POP PSW RET * ============================================== * * WRRTC - Write time, date and DOW to the Real * time clock chip * * EXIT: 'C' set if no RTC found * * ============================================== WRRTC CALL CHKRTC Do we have the chip? RC no, return with 'C' set CALL CSETUP Set up the RTC chip CALL WREADY Make sure it's ready for I/O MVI A,REFRST+REFSTOP+REF24 OUT CLOCK+REGF CALL WREADY * * Write time, date and DOW to the clock chip * LDA MYSS get Seconds ANI 0FH low nibble (ones) OUT CLOCK+S1 send to RTC CALL WREADY LDA MYSS get Seconds RRC high nibble (tens) RRC RRC RRC ANI 0FH OUT CLOCK+S10 send to RTC CALL WREADY LDA MYMM get Minutes ANI 0FH low nibble (ones) OUT CLOCK+MI1 send to RTC CALL WREADY LDA MYMM get Minutes RRC high nibble (tens) RRC RRC RRC ANI 0FH OUT CLOCK+MI10 send to RTC CALL WREADY LDA MYHH Get Hours ANI 0FH low nibble (ones) OUT CLOCK+H1 send to RTC CALL WREADY LDA MYHH Get Hours RRC high nibble (tens) RRC RRC RRC ANI 0FH OUT CLOCK+H10 send to RTC CALL WREADY LDA MYDD Get Day ANI 0FH low nibble (ones) OUT CLOCK+D1 send to RTC CALL WREADY LDA MYDD Get Day RRC high ibble (tens) RRC RRC RRC ANI 0FH OUT CLOCK+D10 send to RTC CALL WREADY LDA DOW Get Day of Week ANI 0FH OUT CLOCK+W send to RTC CALL WREADY LDA MYMO Get Month ANI 0FH low nibble (ones) OUT CLOCK+MO1 send to RTC CALL WREADY LDA MYMO Get Month RRC high nibble (tens) RRC RRC RRC ANI 0FH OUT CLOCK+MO10 send to RTC CALL WREADY LDA MYYY Get Year ANI 0FH low nibble ones) OUT CLOCK+Y1 send to RTC CALL WREADY LDA MYYY get Year RRC high nibble (tens) RRC RRC RRC ANI 0FH OUT CLOCK+Y10 send to RTC CALL WREADY CALL CSETUP RET * ============================================== * * CHKRTC - Test for real time clock available * * Returns: * 'Z' if OK * 'C' if no RTC * * ============================================== CHKRTC MVI A,REF24 24 hour clock mode MOV C,A OUT CLOCK+REGF IN CLOCK+REGF ANI 0FH CMP C RZ CALL $TYPTX DB NL,'CHIPTST: NO RTC CHIP?',ENL STC RET * ============================================== * * CSETUP - set up clock register info * * ============================================== CSETUP MVI A,REF24 24 hour clock mode MOV C,A OUT CLOCK+REGF MVI A,RET1+REITR+REMASK MOV C,A OUT CLOCK+REGE MVI A,RDIRQ OUT CLOCK+REGD ANA A RET * ============================================== * * WREADY - wait 'til clock is ready for next I/O * * ============================================== WREADY IN CLOCK+REGD Control reg D ORI RDHOLD HOLD bit OUT CLOCK+REGD set it IN CLOCK+REGD read control reg again ANI RDBUSY BUSY? RZ no, done IN CLOCK+REGD Read control reg again ANI 0FFH-RDHOLD !HOLD OUT CLOCK+REGD set it JMP WREADY retry... * ============================================== * * RDRTC - Read from the real time clock and * store year, month, day and day of week in * corresponding local variables. * * EXIT: 'C' set if no RTC found * * ============================================== RDRTC CALL CSETUP Set up the clock chip RC return with 'C' set if none CALL RDYEAR Read and store Year CALL RDMONTH Read and store Month CALL RDDOW Read and store Day of Week CALL RDDAY Read and store Day of Month CALL RDHMS RET RDTBAD CALL $TYPTX DB 'IN RDTIM1-2: ',200Q BADDATA CALL $TYPTX DB 'RDDATA: READING BAD DATA FROM RTC AT 240Q ',ENL STC RET * * RDYEAR - Read Year 10's then 1's * RDYEAR EQU * * * Read Year 10's position * RDY10 IN CLOCK+Y10 Read Year 10's ANI 0FH MOV B,A save it IN CLOCK+Y10 read again ANI 0FH CMP B same? JNZ RDY10 repeat 'til not changing CPI 10 must be < 10 JNC BADDATA RRC rotate to high bits RRC RRC RRC MOV B,A save it * * Read Year 1's position * RDY1 IN CLOCK+Y1 Read Year 1's ANI 0FH MOV C,A save it in C IN CLOCK+Y1 read again ANI 0FH CMP C same? JNZ RDY1 repeat 'til not changing CPI 10 must be < 10 JNC BADDATA ORA B A = YY STA MYYY RET * * RDMONTH - Read Month 10's and then 1's * RDMONTH EQU * RDMO10 IN CLOCK+MO10 Read Month 10's ANI 0FH MOV B,A save it IN CLOCK+MO10 read again ANI 0FH CMP B same? JNZ RDMO10 repeat 'til not changing CPI 2 Must be 0 or 1 JNC BADDATA RRC rotate high bits RRC RRC RRC MOV B,A and save * * Read month Ones * RDMO1 IN CLOCK+MO1 Read Month 1's ANI 0FH MOV C,A save it IN CLOCK+MO1 read again ANI 0FH CMP C same? JNZ RDMO1 repeat 'til not changing CPI 10 Must be < 10 JNC BADDATA ORA B combine 10's and 1's CPI 13H (typo? < 13 decimal not hex?) JNC BADDATA CPI 0 JZ BADDATA must be > 0 STA MYMO Save it! RET * * RDDAY - Read day (10's and 1's) * RDDAY EQU * RDD10 IN CLOCK+D10 Read Day 10's ANI 0FH MOV B,A save IN CLOCK+D10 read again ANI 0FH CMP B same? JNZ RDD10 repeat 'til not changing CPI 4 must be < 4 JNC BADDATA RRC rotate to high bits RRC RRC RRC MOV B,A and save * * Read Day one's * RDD1 IN CLOCK+D1 Read day 1's ANI 0FH MOV C,A save IN CLOCK+D1 read again ANI 0FH CMP C same? JNZ RDD1 repeat 'til not changing CPI 10 must be < 10 JNC BADDATA ORA B Combine 10's and 1's CPI 32H (typo? <32 decimal not hex?) JNC BADDATA ANA A can't be zero either JZ BADDATA STA MYDD Save it! RET * * RDDOW - Read Day of the week * RDDOW IN CLOCK+W Read DOW ANI 0FH MOV C,A save IN CLOCK+W read again ANI 0FH CMP C same? JNZ RDDOW repeat 'til not changing CPI 7 Must be 0-6 JNC BADDATA STA DOW save it! ANA A RET * * Read Hours, Minutes and Seconds * RDHMS EQU * * * Read Hours 10's * RDH10 IN CLOCK+H10 Read Hours 10's ANI 0FH MOV B,A save IN CLOCK+H10 read again ANI 0FH CMP B same? JNZ RDH10 repeat 'til not changing ANI 11111011B CPI 3 JNC RDTBAD RLC rotate to high bits RLC RLC RLC MOV B,A and save * * Read Hours 1's * RDH1 IN CLOCK+H1 Read hour ones digit ANI 0FH MOV C,A save IN CLOCK+H1 read again ANI 0FH CMP C same? JNZ RDH1 repeat 'til not changing CPI 10 must be < 10 JNC RDTBAD ORA B Get full hours value CPI 24H (typo? should be < 24 decimal?) JNC RDTBAD STA MYHH Save it! * * Read Minutes * RDM10 IN CLOCK+MI10 Read Minutes tens ANI 0FH MOV B,A save IN CLOCK+MI10 read again ANI 0FH CMP B same? JNZ RDM10 repeat 'til not changing CPI 7 must be 0-6 JNC BADDATA RLC rotate to high nibble RLC RLC RLC MOV B,A save * * Read Minutes (1's digit) * RDM1 IN CLOCK+MI1 Read minute one's ANI 0FH MOV C,A save IN CLOCK+MI1 read again ANI 0FH CMP C same? JNZ RDM1 repeat 'til not changing CPI 10 must be < 10 JNC BADDATA ORA B combine 10's and 1's STA MYMM save it! * * Read Seconds * RDS10 IN CLOCK+S10 Read seconds 10's digit ANI 0FH MOV B,A save IN CLOCK+S10 read again ANI 0FH CMP B same? JNZ RDS10 repeat 'til not changing CPI 7 must be 0-6 JNC BADDATA RLC move to high nibble RLC RLC RLC MOV B,A save * * Read Seconds one digit * RDS1 IN CLOCK+S1 Read seconds 1 digit ANI 0FH MOV C,A save IN CLOCK+S1 read again ANI 0FH CMP C same? JNZ RDS1 repeat 'til not changing CPI 10 must be < 10 JNC BADDATA ORA B Combine 10's and 1's STA MYSS save it! RET * ============================================== * * CODEDT - Convert Date to coded date (HDOS internal * format used in S.DATC * * ============================================== CODEDT LDA MYYY Year LXI H,0 HL = 0 CALL BCDTOD decimal CALL $DADA. (HL) = Year DAD H *2 DAD H *4 DAD H *8 DAD H *16 (shift left 4 bits) LDA MYMO Month CALL BCDTOD decimal CALL $DADA. (HL) = Year <<4 + Month DAD H *2 DAD H *4 DAD H *8 DAD H *16 DAD H *32 (shift left 5 bits) LDA MYDD Day CALL BCDTOD decimal CALL $DADA. YYMMDD as decimal value RET * ============================================== * * BCDTOD - A has 10's digit in top nibble * and 1's digit in bottom nibble. Convert * to decimal * * ============================================== BCDTOD MOV B,A save the value ANI 0F0H high nibble RRC a/2 MOV C,A save a/2 RRC a/4 RRC a/8 ADD C a/8 + a/2 MOV C,A MOV A,B ANI 0FH ; 15 ADD C RET * ============================================== * * DOCMD - process option supplied on the * command line (e.g. HELP, SET, SETUP, etc.) * * ============================================== DOCMD CALL SKIPWS Skip blanks and tabs XTHL (HL) = return address * Save HL on the stack PUSH D (DE) = command item DOCMD1 LDAX D Fetch char from command CMP M match? JNZ DOCMD2 No, fixup and continue... * * So far we have a match, keep scanning * INX D next char from command INX H next code byte XRA A NUL CMP M == NUL? JNZ DOCMD1 no, keep going... * * We have a match! * INX SP fix the stack pointer INX SP XTHL (SP) = code block to execute LDAX D ANA A RET * * No match yet DOCMD2 POP D Undo PUSH D DOCMD3 XRA A A=0 CMP M == NUL? INX H next JNZ DOCMD3 no, searching... XTHL LDAX D ANA A STC RET * ============================================== * * STRCPY - Copy string and null-terminate * * Entry: C = string length * DE = destination * HL = source * * ============================================== STRCPY XRA A Zero CMP C Check for done? STAX D Store byte RZ leave if done DCR C else, count down MOV A,M fetch byte STAX D store it INX D next destination INX H next source JMP STRCPY loop * ============================================== * * SKIPWS - Skip over white space (blanks * and tabs. (similar to $SOB) * * ENTRY: (DE) = string * EXIT: (DE) updated * ============================================== SKIPW1 INX D SKIPWS LDAX D A = (DE) CPI ' ' Blank? JZ SKIPW1 Yes, next... CPI TAB or Tab? JZ SKIPW1 Yes, next... RET * ============================================== * * Storage * * ============================================== CKDVD DB 'CK:',0 DEFALT DB 0,0,0,0,0,0 Default block CMDLINE EQU * * * Working space * MEMTOP EQU CMDLINE+101 END ENTRY