***************************************************************** * AMPRO Computers Inc. * * Date.asm * * * * Adapted from DATE.MAC * * by Don Delwood, * * with mods by Roger Warren * * * * Additional modifications were made to allow update from * * the Calendar/Clock board by Kenmore Computer Technologies * * * * by Ernest J. Levesque * * * * (changes are in lower case, ending with ******) * * * * Implementation is competed ajusting the equate "cbase" to the* * base port of the clock board. Date functions as usual but * * adding S after the command causes the date and time to be * * taken from clock board. Note that the time is also set. * * Note that the posibility exists that if call to the clock * * occurs during an update of the clock the wrong time could be * * set. This could cured by looping through the clock update * * routine until two passes match. I may get around to that * * implementation but current is satisfactory for my needs * ***************************************************************** ; ; Version date by History ; ------- -------- ------ -------- ; 1.0 4 mar 86 fsw Version 1.0 for use with bios 3.6 ; *---------------------------------------------------------------* VER EQU 10 ; version 1.0 CR EQU 13 LF EQU 10 LDIR EQU 0B0EDH ; z80 ldir ORG 100H JMP BEGIN ; jump over logo HELP: CALL PRINT DB CR,LF,LF DB 'DATE ' DB 'Version ',VER/10+'0','.',VER MOD 10+'0',CR,LF DB 'AMPRO Computers Inc.' DB CR,LF,'To change the date, enter change ' DB 'on the command line as follows:',cr,lf,lf DB 'du>DATE mm-dd-yy',cr,lf DB 0 JMP EXIT BEGIN: DW 73EDH,OLDSTK ; save old stack pointer LXI SP,LOCSTK ; set new stack ; LXI D,WBOOT ; build bios entry table LHLD 1 ; get bios start LXI B,51 ; bytes to move DW LDIR ; move it ; CALL GETTBL ; get address of next jmp tbl CPI 36 ; must be bios ver 3.6 or higher JC BADVER ; give message and exit LXI D,NXTTBL ; 'hl' has bios nxttbl address LXI B,15 ; DW LDIR ; move the table LXI H,0 ; make sure that clock is enabled CALL TOD ; get clock base address MOV A,L ; see if address of tick was returned ORA H JZ NOCLK ; exit clock not enabled ; 'hl' has addres of clock LXI D,SEC ; move time LXI B,6 DW LDIR ; save time ; Everthing needed has been moved into program area now. ; parse command tail to see if time was entered on command line. ; LXI H,80H ; point to command tail MOV A,M ; get character count ANA A ; if zero nothing on cmd line STA UPDATE ; save possible entry on cmd line JZ SHDATE ; skip no char on command line LOOP: INX H ; point to first char on command line MOV A,M CPI ' ' JZ LOOP ; filter leading spaces ;******* ****** cpi 'S' ;******* See if set command is requested ****** jz kendate ;******* Jump off to get date from clock port ****** ;******* ****** PUSH H CALL VALID ; test for valid numeric ascii POP H CALL EVAL10 CPI 12+1 ; see if more than december JNC NVALMS STA TMONTH ; set temp month MOV C,A ; save month INX H CALL EVAL10 PUSH H LXI H,MTHS-1 ; MVI B,0 DAD B ; point to number of days in month CMP M ; see if valid entry for the month POP H JZ CONT JNC NVALMS CONT: STA TDAY ; set temp month INX H CALL EVAL10 STA YEAR ; set year CALL MD2J ; convert the month/day to julian SHDATE: CALL J2MD ; convert julian date to month/day LDA TMONTH DCR A ; adjust MOV E,A ; ADD A ; times 2 ADD E ; times 3 MOV E,A MVI D,0 LXI H,AMONTHS ; find month in string DAD D LXI D,MON LXI B,3 ; move 3 bytes DW LDIR LDA TDAY CALL BINASC DW 43EDH,DAY LDA YEAR CALL BINASC DW 43EDH,YR CALL PRINT ; print message CURDAT: DB 'Current date is ' MON: DB ' ' DAY: DB ' , 19' YR: DB ' ' DB 0 ; ; if time was not changed from the command line, do not place ; the time prameters back into the bios clock area. ; LDA UPDATE ANA A ; if zero time was only displayed JZ EXIT ; ; move the newly set time prameters to bios clock area ; lda kenflag ; Load the Kenmorre clock flag ***** cpi 0ffh ; See if we set the flag for Kenmore ***** jnz oldexit ; exit through former method if not ***** call tod ; get address of time counters ***** xchg ; bios time counter addresss to 'de' ***** lxi h,sec ; ***** lxi b,6 ; date only, not time ***** dw ldir ; move it to bios memory ***** jmp exit ; ***** oldexit: CALL TOD ; get address of time counters ***** LXI D,3 ; offset to date DAD D ; add offset to 'hl' XCHG ; bios time counter addresss to 'de' LXI H,JDAY ; LXI B,3 ; date only, not time DW LDIR ; move it to bios memory JMP EXIT ; ; Get the seconds, minutes, hours, day, and month from Kenmore Clock board ; kenflag: ds 1 ; Flag for Set from Kenmore clock ****** cbase equ 0e0H ; Port address of millisecond clock ****** kendate: mvi a,0ffh ; Set Clock flag for exit update ****** sta kenflag ; Store flag ****** in cbase+7 ; Port address of month ****** call fix ; change BCD from clock to binary ****** sta tmonth ; Store the month temporary ****** in cbase+6 ; Port address of day ****** call fix ; change BCD from clock to binary ****** sta tday ; Store the day temporary ****** in cbase+4 ; Port address of hour ****** call fix ; change BCD from clock to binary ****** sta hour ; Store hours ****** in cbase+3 ; Port address of minutes ****** call fix ; change BCD from clock to binary ****** sta min ; Store minutes ****** in cbase+2 ; Port address of second ****** call fix ; change BCD from clock to binary ****** sta sec ; Store seconds ****** call md2j ; Convert temp day month to julian ****** mvi a,86 ; Load the year ****** sta year ; Store ****** jmp shdate ; Show the date and exit ****** ; ****** ; FIX - Fix converts BCD from the Kenmorre clock to binary through ****** ; existing routines ****** ; ****** fix: mov c,a ; place character in c for later ****** ani 0f0h ; strip tens digit ****** rrc ; rotate to units ****** rrc ; ****** rrc ; ****** rrc ; ****** adi 030h ; make into character ****** sta clockchr ; store in two character string ****** mov a,c ; get back the character ****** ani 0fh ; strip units digit ****** adi 030h ; make into character ****** sta clockchr+1 ; store in string ****** lxi h,clockchr ; point to clock string ****** jmp eval10 ; jmp to eval. let eval return ****** clockchr: db ' ',0 ; this is the string that allows the ****** ; the use of eval10 to make binary ****** ; ; Test the command for valid time entry. Scan the command tail ; for along its legnth for the pattern hh:mm:ss. test for ; valid numeric characters. it has already been determined that ; somthing was entered on the command line ; VALID: LXI H,80H ; character count MOV B,M ; get number of characters typed INX H DCR B JZ NVALMS ; exit only spaces or one char on line MOV A,M ; get first char CPI ' ' JZ VALID+4 ; filter the spaces VAL1: MOV A,M INX H ; point to next char ANA A ; 00h is terminator or zero count RZ CPI '/' JZ HELP ; show instructions CPI '?' JZ HELP ; show insturctions CPI '-' JZ VAL1 ; delimeter ok CPI '0' JC NVALMS ; less than ascii 0 CPI '9'+1 JNC NVALMS ; more than ascii 9 JMP VAL1 ; NVALMS: CALL PRINT DB 'Invalid date',cr,lf,0 JMP EXIT ; ; time of day TOD jmp was not in bios ; NOCLK: CALL PRINT DB 'Clock not installed',cr,lf,0 JMP EXIT ; ; wrong version bios ; BADVER: CALL PRINT DB 'Requires Bios 3.6 or higher.',cr,lf,0 ; fall through to exit ; ; Normal program exit. Restores system stack and returns ; EXIT: DW 7BEDH,OLDSTK ; recover old stack pointer RET ; ; Print string of characters terminated with zero '0'. ; PRINT: POP H MOV A,M ; get byte ANA A JZ PRNEND PUSH H ; MOV C,A CALL CONOUT ; call bios routine POP H INX H ; next byte JMP PRINT+1 PRNEND: XTHL ; hl has return RET ;*************************************************************** ; convert binary to ascii ; in: a - binary value ; out: bc - ascii character (low high) (mod. after Rich Conn) ;*************************************************************** BINASC: MVI C,0 ; init count MVI B,10 BIN1: SUB B JC BINEXT INR C JMP BIN1 binext: ADD B ; A = ones digit C = tens digit ADI '0' MOV B,A MOV A,C ADI '0' MOV C,A RET ;*************************************************************** ; eval10 - convert ascii string to decimal value ; in: hl - points to beginning of string ; out: a - e ; de - value ; hl - points to delimiter (error character) ; (mod. after Rich Conn) ;*************************************************************** EVAL10: PUSH B LXI D,0 ; init de to zero E10L: MOV A,M ; next digit, check range '0'-'9' CPI '0' JC EVLOUT ; less than ascii 0 CPI '9'+1 JNC EVLOUT ; more than ascii 9 SUI '0' MUL10: PUSH H ; multiply DE by 10 MOV H,D MOV L,E DAD H ; *2 DAD H ; *4 DAD D ; *5 DAD H ; *10 MOV E,A ; add in latest digit MVI D,0 DAD D XCHG POP H INX H JMP E10L EVLOUT: MOV A,E POP B RET ;**************************************************************** ; convert month/day to julian ;**************************************************************** MD2J: LXI D,MTHS-1 ; init month pointer LXI H,0 LDA TMONTH ; get binary month MOV B,A ; set count MD2J1: LDAX D ; get number of days in month ADD L MOV L,A ; update 'l' CC MD2J3 ; adjust 'h' if carry DCR B INX D ; next month JNZ MD2J1 MD2J2: LDA TDAY ; get binary day MOV E,A ; MVI D,0 DAD D ; add the day DCX H ; adjust for ordinal 0 SHLD JDAY RET MD2J3: MVI A,1 ; if carry add 1 to 'h' ADD H MOV H,A RET ;**************************************************************** ; convert julian to month/day ;**************************************************************** J2MD: LXI D,MTHS ; int month pointer LHLD JDAY ; julian day in 'hl' INX H ; adjust for ordinal 0 XRA A MOV B,A ; init high byte of sub with 0 INR A STA TMONTH ; init month to 1 J2MD1: LDAX D ORA A ; clear carry MOV C,A MOV A,L ; may be day DW 42EDH ; sbc hl,bc JC J2MD2 JZ J2MD2 LDA TMONTH INR A ; update month STA TMONTH INX D JMP J2MD1 J2MD2: STA TDAY ; set day RET DB 0 MTHS: DB 31,29,31,30,31,30,31,31,30,31,30,31 AMONTHS: DB 'JanFebMarAprMayJunJulAugSepOctNovDec' ; local stack area ; DS 32 ; 16 level stack LOCSTK: DW EXIT ; exit point on top of stack OLDSTK: DS 2 ; save for old stack UPDATE DS 1 ; flag for command entry ; ; bios jmp table, moved from the bios during init. ; WBOOT: DS 3 ; Warm start CONST: DS 3 ; Console status CONIN: DS 3 ; Console character in CONOUT: DS 3 ; Console character out LIST: DS 3 ; List character out PUNCH: DS 3 ; Punch character out READER: DS 3 ; Reader character in HOME: DS 3 ; Seek to home position SELDSK: DS 3 ; Select disk SETTRK: DS 3 ; Set track number SETSEC: DS 3 ; Set sector number SETDMA: DS 3 ; Set DMA address READ: DS 3 ; Read disk WRITE: DS 3 ; Write disk LISTST: DS 3 ; Return list status SECTRAN:DS 3 ; Sector translate GETTBL: DS 3 ; Point to more jumps, returns bioss ; version in 'a'. NXTTBL: SWAP: DS 3 ; jmp swap HD$INF: DS 3 ; get hd table info PHTBAC: DS 3 ; get/set phytab acces PAGET: DS 3 ; get phytab entry address TOD: DS 3 ; get base address of clock tick ; time/date counters from bios SEC: DS 1 MIN: DS 1 HOUR: DS 1 JDAY: DS 2 ; julian day 0-366 for leap year YEAR: DS 1 ; PRESET YEAR TMONTH: DS 1 ; temp storage for month TDAY: DS 1 ; temp storage for day TYEAR: DS 1 ; temp storage for year END