;IMPLEMENTATION MODULE ClockIO; ; ;PROCEDURE InitClk; ; ;PROCEDURE ReadClk( VAR Time : ARRAY OF CHAR; ; VAR Date : ARRAY OF CHAR ); ; ;PROCEDURE RdClk0( VAR Time : ARRAY OF CHAR; ; VAR Date : ARRAY OF CHAR ); ; ;PROCEDURE ClkEI; ; ;PROCEDURE ClkDI; ; ;PROCEDURE ClkClr; ; ;PROCEDURE Z80M0; ; ;PROCEDURE Z80M1; ; ;PROCEDURE Z80EI; ; ;PROCEDURE Z80DI; ; ; ; PIO equates: ; ; ORA EQU 0 DDRA EQU ORA ORB EQU 2 DDRB EQU ORB CRA EQU 1 CRB EQU 3 ; ; BDOS EQU 5 ; ; ; 'initclk' is the module body, if you will... ; ; INITCLK:: LD HL,0E800h ; start at slot '8' SEARCH: DEC H ; slot := slot - 1 LD A,H AND 0Fh ; done all slots? JR Z,NOFIND ; error, no clock ; LD L,0 ; offset zero LD A,(HL) ; get a byte CP 08 JR NZ,SEARCH ; not it.. ; INC L ; next byte LD A,(HL) CP 78h JR NZ,SEARCH ; LD L,0FEh LD A,(HL) CP 0B2h JR NZ,SEARCH ; INC L LD A,(HL) CP 03 ; in TimeMaster mode? JR Z,GOTIT ; NOFIND: LD A,(0EFFFh) ; turn off all expansion ROM LD DE,ERRMSG LD C,09 CALL BDOS ; print error message JP 0 ; and warm-boot out! ; GOTIT: LD A,(0EFFFh) ; expansion ROM off LD A,H ; slot page to 'A' SLA A SLA A SLA A SLA A ; 'En' --> 'n0' ADD 80h ; normal to 80h LD (IOBASE),A ; set up hardware base address ; LD IY,(IOBASE) XOR A ; 'A' := 0 LD (IY+CRA),A LD (IY+CRB),A ; let's talk to PIO DDRA's ; LD (IY+DDRA),A ; port 'A' to all input LD A,0FFH LD (IY+DDRB),A ; port 'B' to all output ; JP CLKDI1 ; setup PIO's and return.. ; ; IOBASE: DW 0E080h ; base of hardware I/O area ; ; ERRMSG: DB 0Dh,0Ah DB 'Unable to locate clock, exiting program!' DB 0Dh,0Ah,'$' ; ; ; ; RDCLK0:: CALL COMMON CALL RC0 JR OUT ; leave w/o restarting interrupts ; ; READCLK:: CALL COMMON CALL RC0 ; do the read.. ; LD A,2FH LD (IY+ORB),A ; re-start clock interrupts ; OUT: INC HL ; index to clear stack!! POP DE ; return address to 'DE' LD SP,HL ; setup new stack EX DE,HL JP (HL) ; ret ; ; ; RC0: LD DE,6 ADD HL,DE ; point at address of date string LD E,(HL) INC HL LD D,(HL) ; 'DE' points to date string PUSH HL ; save stack index ; LD HL,DATECODES LD B,8 CALL READ ; POP HL ; get stack index LD DE,3 ADD HL,DE ; index to time string LD E,(HL) INC HL LD D,(HL) PUSH HL ; LD HL,TIMECODES LD B,5 CALL READ ; POP HL ; recover stack index RET ; ; ; ; ; ; READ: LD A,(HL) ; get code BIT 7,A ; is it a puctuation char? RES 7,A ; clear it in case it was JR NZ,PUTCHAR ; it was.. ; LD (IY+ORB),A ; set the latch for desired data CP 56 JR Z,SHORTMSK ; if it's day of week 'tens' digit CP 53 JR Z,SHORTMSK ; or hour 'tens', use alt mask. ; LD A,0Fh ; clear hi nibble JR GETTIME ; SHORTMSK: LD A,03 ; clear bits 2-7 GETTIME: AND (IY+ORA) ; read the clock (with mask) ADD 30h ; make it ascii PUTCHAR: LD (DE),A ; put char in caller's string ; INC DE INC HL ; next byte DJNZ READ ; RET ; ; DATECODES: DB 58,57, '/'+80h, 56,55, '/'+80h, 60,59 ; TIMECODES: DB 53,52, ':'+80h, 51,50 ; ; ; ; CLKEI:: CALL COMMON ; LD A,12 LD (IY+CRA),A LD A,4 LD (IY+CRB),A ; interrupt every sec. & set to OR's ; JR CLKCLR1 ; ; ; ; ; CLKDI:: CALL COMMON ; CLKDI1: LD A,4 LD (IY+CRA),A LD (IY+CRB),A ; disable PIO interrupts, and talk to ; output registers.. ; JR CLKCLR2 ; ; ; CLKCLR:: CALL COMMON ; CLKCLR1: LD A,2FH LD (IY+ORB),A ; enable clock interrupt latch ; CLKCLR2: LD A,(IY+ORA) LD A,(IY+ORB) ; clear any existing interrupt ; RET ; ; ; Z80M0:: IM 0 RET ; ; ; ; Z80M1:: IM 1 RET ; ; ; ; Z80EI:: EI RET ; ; ; ; Z80DI:: DI RET ; ; ; COMMON: LD HL,0 ADD HL,SP ; get stack pointer in 'HL' ; LD IY,(IOBASE) ; 'IY' points at clock-base RET ; ; ; ; ; ; END