|
DataMuseum.dkPresents historical artifacts from the history of: CP/M |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about CP/M Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - download
Length: 8192 (0x2000) Types: TextFile Names: »TIME10.ASM«
└─⟦09ad82a35⟧ Bits:30002863 PolyPascal-80 V3.10 for JET80 CP/M └─ ⟦this⟧ »TIME10.ASM«
; ; TIME PROGRAM FOR THE LEGACY COMPUTER SYSTEMS REAL TIME CLOCK ; This program modified 4 Jan 84 to work with the Kaypro 10 by ; P.J. Lenk ; BASE EQU 078H ; base address of pio BDATA EQU BASE+1 ; port B data BCMND EQU BASE+3 ; port B command HOLD EQU 16 ; Hold 5832 to set up read/write WR EQU 64 ; Read 5832 RD EQU 32 ; Write 5832 REF EQU 15 ; Timing references (not used yet) MODE0 EQU 0FH ; pio output mode MODE3 EQU 0CFH ; Pio control mode BDOS EQU 5 ; CP/M entry point CONO EQU 2 ; Console output function CPRT EQU 9 ; Print string to console function RCONS EQU 10 ; Read console buffer function FCB EQU 5CH ; Default file control block CBUF EQU 80H ; console buffer TPA EQU 100H ; Transient Program Area CR EQU 13 ; Carriage return code LF EQU 10 ; Line feed code ORG TPA ; Transient Program Area START: LXI H,0 ; clear it DAD SP ; put stack ptr in it SHLD STACK ; save it for exit LXI SP,STACK ; set local stack ; set port to output mode ; BEGIN: MVI A,MODE0 ; output mode OUT BCMND ; command port MVI A,3 ; disable interrupts OUT BCMND ; command port ; ; main program ; ; CALL TELTIM ; tell present time LXI H,TIME MVI C,13 MVI A,1 CL1: MOV M,A INX H DCR C JNZ CL1 LDA FCB+1 ; see if we should set time ANI 5FH ; force upper case CPI 'S' ; is it s<et>? JNZ TIM ; i suppose not, bye CALL SETTIM ; ask the time, and set it CALL ILPRT ; print following in-line string DB CR,LF,0 TIM: CALL TELTIM ; tell new time JMP EXIT ; bye ; ; new trial routine ; TELTIM: CALL RDMOD ; set chb to read mode LXI H,TIME ; clock buffer MVI C,13 ; # bytes to read TTLP: MOV A,L ANI 0FH ; mask off high nybble CALL RDCLK MOV M,A ; store it in clock buffer INX H ; bump buffer ptr DCR C ; finished? JNZ TTLP ; guess not ; ; output clock buffer to screen ; ; hour,minute,second ; LHLD HOUR ; hours MOV A,H ; 10's digit ANI 3 ; mask hi bits CALL ASCII ; to screen MOV A,L ; 1's digit CALL ASCII ; to screen LHLD MIN ; minutes MOV A,H ; 10's digit CALL ASCII ; to screen MOV A,L ; 1's digit CALL ASCII ; to screen MVI A,':' ; separator CALL TYPE ; to screen LHLD SEC ; seconds MOV A,H ; 10's digit CALL ASCII ; to screen MOV A,L ; 1's digit CALL ASCII ; to screen MVI A,' ' ; space CALL TYPE ; to screen ; day of the week LDA DAY ; varies from 0 - 6 ANI 7 ; mask hi bits MOV L,A ; preset hl MVI H,0 DAD H ; day * 2 for table offset LXI D,DAYS ; point to days table DAD D ; point to day of week MOV E,M ; move pointer to de INX H MOV D,M MVI C,CPRT ; print string CALL BDOS ; print day of week ; date of the month LHLD DATE ; date of month MOV A,H ; 10's digit ORA A ; is it zero? JZ DATL ; if so CALL ASCII ; to screen if not DATL: MOV A,L ; 1's digit CALL ASCII ; to screen MVI A,' ' ; space CALL TYPE ; to screen ; month of the year (varies from 1 to 12) LDA MONTH+1 ; 10's digit ANI 1 ; is it October or later? JZ MONT ; guess not MVI A,10 MONT: MOV L,A ; A = 0 or 10 MVI H,0 LDA MONTH ; 1's digit ANI 0FH ; mask hi bits ADD L MOV L,A ; month in hl DCX H ; rel zero for months table DAD H ; times 2 for offset LXI D,MONTHS ; point to table DAD D ; point to month MOV E,M ; move pointer to de INX H MOV D,M MVI C,CPRT CALL BDOS ; month to console ; print year to console CALL ILPRT DB '19',0 ; print century LDA YEAR+1 ; 10's digit CALL ASCII ; to screen LDA YEAR ; 1's digit CALL ASCII ; to screen RET SETTIM: ; ; Ask 'What time is it?' ; MVI A,80H ; max console buffer length STA CBUF ; init buffer length CALL ILPRT ; print setting message db cr,lf,lf,'Set Clock. Type <ctl-C> to Exit.' DB CR,LF,lf,'What year is this? (e.g. 83) ',0 LXI D,CBUF ; console buffer MVI C,RCONS ; read console buffer CALL BDOS LDA CBUF+1 ; length ORA A ; no entry? JZ SMONTH ; next LXI H,CBUF+2 ; first digit MOV A,M ANI 0FH ; strip ascii STA YEAR+1 ; store it INX H ; next digit MOV A,M ANI 0FH ; strip ascii STA YEAR ; store it SMONTH: CALL ILPRT DB CR,LF,'Month? (Jan = 01, Feb = 02, etc.) ',0 LXI D,CBUF MVI C,RCONS CALL BDOS LDA CBUF+1 ORA A JZ SDATE ; no month specified LDA CBUF+2 ANI 0FH STA MONTH+1 LDA CBUF+3 ANI 0FH STA MONTH SDATE: CALL ILPRT ; in-line print DB CR,LF,'Today''s date? (i.e. 01 to 31) ',0 LXI D,CBUF ; console buffer MVI C,RCONS CALL BDOS LDA CBUF+1 ORA A JZ SDAY LDA CBUF+2 ; 10's digit ANI 0FH ; mask hi nybble STA DATE+1 LDA CBUF+3 ANI 0FH STA DATE SDAY: CALL ILPRT DB CR,LF,'What day is it? (ie. Sunday = 1, Monday = 2, etc.) ',0 LXI D,CBUF MVI C,RCONS CALL BDOS LDA CBUF+1 ORA A JZ STIME ; no day specified LDA CBUF+2 ANI 0FH DCR A ; rel 0 STA DAY STIME: CALL ILPRT DB CR,LF,'What time is it? (ie. 1545) ',0 LXI D,CBUF MVI C,RCONS CALL BDOS LDA CBUF+1 ORA A JZ SETCLK ; no time specified LDA CBUF+2 ANI 0FH ORI 8 ; 24 hour format STA HOUR+1 LDA CBUF+3 ANI 0FH STA HOUR LDA CBUF+4 ANI 0FH STA MIN+1 LDA CBUF+5 ANI 0FH STA MIN SETCLK: ; ; write the time buffer to the clock ; CALL WRMOD LXI H,TIME MVI C,13 STCLK1: MOV E,M MOV A,L ANI 0FH CALL WRCLK INX H DCR C JNZ STCLK1 RET ILPRT: POP H ; hl points to string ILP1: MOV A,M ; get the character INX H ; point to next character ORA A ; is this the zero terminator? JZ ILEX ; yep. we'RE DONE CALL TYPE ; to screen JMP ILP1 ; do it again ILEX: PCHL ; jump to instruction following string ASCII: ADI 30H ; binary to ascii TYPE: PUSH PSW ; out to screen, saving all registers PUSH H PUSH D PUSH B MOV E,A MVI C,CONO ; console output CALL BDOS POP B POP D POP H POP PSW RET RDCLK: ; FOR KCLOCK push psw ; save address call wrmod ; setup pio pop psw ori hold+80h ; add hold and address gate bit out bdata ; set address and gate ani 7fh ; reset gate bit out bdata ; address is now latched call wait ; 150 usec to establish hold call rdmod ; setup to read lo nybble mvi a,hold+rd ; add read command to hold out bdata call wait1 ; wait 6 usec in bdata ; read clock ani 0fh ; mask hi nybble push psw ; save it xra a ; clear a out bdata ; release hold pop psw ; restore clock data ret wrclk: ; for KClock push psw ; save address call wrmod pop psw ori hold+80h ; hold plus address gate bit out bdata ANI 7FH ; reset gate bit out bdata call wait ; wait 150 usec to establish hold mvi a,hold+wr ; add write command to hold ORA e ; data to write out bdata PUSH PSW call wait1 ; wait 6 usec POP PSW XRI WR ; turn off write command OUT BDATA xra a ; clear a out bdata ; release hold ret ; set port b to write the clock WRMOD: MVI A,MODE3 ; control mode OUT BCMND MVI A,0 ; write to clock OUT BCMND RET ; set port b to read the clock RDMOD: MVI A,MODE3 ; control mode OUT BCMND MVI A,0FH ; to read clock OUT BCMND RET wait: ; 150 usec timing loop mvi a,54 ; loop control w0: dcr a jnz w0 ret wait1: ; 6 usec timing loop mvi a,3 jmp w0 EXIT: LHLD STACK SPHL RET TIME: EQU $+15 AND 0FFF0H ; 16-byte boundary ORG TIME SEC: DS 2 ; seconds MIN: DS 2 ; minutes HOUR: DS 2 DAY: DS 1 ; day of week DATE: DS 2 MONTH: DS 2 YEAR: DS 2 DAYS: DW SUN DW MON DW TUE DW WED DW THU DW FRI DW SAT SUN DB 'Sunday, $' MON DB 'Monday, $' TUE DB 'Tuesday, $' WED DB 'Wednesday, $' THU DB 'Thursday, $' FRI DB 'Friday, $' SAT DB 'Saturday, $' MONTHS: DW JAN DW FEB DW MAR DW APR DW MAY DW JUN DW JUL DW AUG DW SEP DW OCT DW NOV DW DEC JAN DB 'January $' FEB DB 'February $' MAR DB 'March $' APR DB 'April $' MAY DB 'May $' JUN DB 'June $' JUL DB 'July $' AUG DB 'August $' SEP DB 'September $' OCT DB 'October $' NOV DB 'November $' DEC DB 'December $' DS 32 STACK: END START «eof»