title 'I/O Drivers for Core Board' ;---------------------------------------------------------------- ; Core Board I/O Drivers ; ; Written By Richard Holmes 12-05-86 ; Last Update By Richard Holmes 23-01-87 ; ; Changed Dart setup for DTR set on 08-06-86 ; Modified clock routine to save year in 58167 ram 08-06-86 ; Modified clock routine to use DE as buffer address 30-06-86 ; Use WDT$FLG in the clrwdt routine 23-11-86 ; Added LED drivers 18-01-87 ; Removed AUX drivers 19-01-87 ;---------------------------------------------------------------- ; maclib z80 maclib core ; public cie,coe,cst public con$inp,con$out,con$ist public clkrd,clkwr,schrd public init,clrwdt ; Led Drivers public ini$led,tog$led ; Initialize led drivers public clr$led,set$led ; Led number on/off public ori$led,ani$led ; OR and AND led bit mask public xri$led ; XOR led image ; Bell driver public set$bel,clr$bel ; Set/Clear bell public tog$bel ; Toggle bell bit on/off ; ;================================================================ ; LED Drivers ; ;================================================================ ; Initialize the LED drivers by clearing the data byte and hence ; the led port ;---------------------------------------------------------------- ; ini$led: mvi a,wr$en ; Memory enable only sta led$byt ; Save for masks later out @ledd ; Send to driver ret ; ;---------------------------------------------------------------- ; Set the specified bit in A LED on. Leave others alone. ; ; On Entry ; A = 1..6 for the led number ; On Exit ; Led number turned on. Others preserved. ;---------------------------------------------------------------- ; set$led: ora a rz ; Exit if = 0 cpi 7 rnc ; NC and > 6 hence in error push b call led$msk lda led$byt ; Load old data ora c ; OR in the new bit mask led$com: sta led$byt out @ledd ; Write out again pop b ret ; ;---------------------------------------------------------------- ; Clear the specified bit in A. Leave others alone. ; ; On Entry ; A = 1..6 for the led number ; On Exit ; Led number cleared. Others preserved. ;---------------------------------------------------------------- ; clr$led: ora a rz ; Exit if = 0 cpi 7 rnc ; NC and > 6 hence in error push b call led$msk cma mov c,a ; Invert and save led mask lda led$byt ; Load old data ana c ; And OFF the selected bit ori wr$en ; Mask in the memory enable bit jr led$com ; ;---------------------------------------------------------------- ; Or the specified bit mask in A into the LED Outputs. ; ; On Entry ; A = led mask ; ; On Exit ; Set bit leds turned on. Others preserved. ;---------------------------------------------------------------- ; ori$led: push b ani 0011$1111b ; Mask off any top bits mov c,a ; Save lda led$byt ; Load old data ora c ; OR in the bit mask ; Maskin ram enable ori 1100$0000b ; Turns ram on. jr led$com ; ;---------------------------------------------------------------- ; AND the specified bit mask in A into the LED Outputs. ; ; On Entry ; A = led mask ; ; On Exit ; Set bit leds turned on. Others turned off. ;---------------------------------------------------------------- ; ani$led: push b mov c,a ; Save lda led$byt ; Load old data ana c ; AND the bit image of previous leds ori wr$en ; OR in memory enable jr led$com ; ;---------------------------------------------------------------- ; Exclusive OR the bit in A with the current LED port mask. ; ; On Entry ; A = bit mask to XOR into led image ; ; On Exit ; LED image updated ;---------------------------------------------------------------- ; xri$led: push b mov c,a lda led$byt xra c jr led$com ; ;---------------------------------------------------------------- ; Toggle the passed in LED ; ;---------------------------------------------------------------- ; tog$led: ora a rz cpi 8 rnc ; push b call led$msk lda led$byt xra c ori wr$en jmp led$com ; ; --------------------------------------------- ; -- Convert a bit number into an actual Bit -- ; --------------------------------------------- ; led$msk: mov b,a ; load counter mvi a,080h ; Seed. Must rotate at least once. led$rot: rlc ; Shift left djnz led$rot mov c,a ; Save data into C for later ret ; ;---------------------------------------------------------------- ; Turn on the system bell ;---------------------------------------------------------------- ; set$bel: push psw mvi a,1 sta bel$byt out @buz ; To bell / buzzer pop psw ret ; ;---------------------------------------------------------------- ; Turn off the system bell ;---------------------------------------------------------------- ; clr$bel: push psw xra a ; Send a 0 sta bel$byt out @buz ; To bell / buzzer pop psw ret ; ;---------------------------------------------------------------- ; Toggle the system bell bit ON/OFF ;---------------------------------------------------------------- ; tog$bel: push psw lda bel$byt xri 1 sta bel$byt out @buz ; To bell / buzzer pop psw ret ; ;---------------------------------------------------------------- ; Clear the watchdog timer by writing a 1 then 0 to toggle ; the port. ;---------------------------------------------------------------- ; clrwdt: push psw lda wdt$flg out @wdt xri 1 ; Toggle bit 1 sta wdt$flg pop psw ret ; ;---------------------------------------------------------------- ; Read the dip switch into A for the user ;---------------------------------------------------------------- ; schrd: in @sch ret ; ;---------------------------------------------------------------- ; Read real time clock to ram at DE ; ; Memory is laid out in the following format: ; ; seconds ; minutes ; hours ; day of week ; day of month ; month ; Year. Saved in ram in the clock chip at port 01fh ; ; Note the bit of code that stops the clock from being read ; constantly if the chip is faulty. This is the count value ; in B. ;---------------------------------------------------------------- ; clkrd: push h push b ; Save sded ?time mvi b,5 ; 5 times maximum read count ; ; ; read$clock: ; Repeat here if a rollover lhld ?time in @clk + 2 ; Seconds mov m,a inx h ; in @clk + 3 ; Minutes mov m,a inx h ; in @clk + 4 ; hours mov m,a inx h ; in @clk + 5 ; Day of week mov m,a inx h ; in @clk + 6 ; Day of month mov m,a inx h ; in @clk + 7 ; Month mov m,a inx h ; -> year register in system ram in @clk + 0fh ; Year ram in clock mov m,a ; ; Check rollover status port. Bitset = an internal ripple, re-read required. ; in @clk+20 ; Status port ani 1 ; Status bit is in D0 jz read$kend ; if 00, a good read djnz read$clock ; Read till a 0 bit. ; ; Else the time is valid ; read$kend: pop b ; Restore all pop h ret ; ;---------------------------------------------------------------- ; ; Write the real time clock from a ram store. This is expected ; to be in the same format as that for clock read. ; ; On entry ; DE -> time buffer ;---------------------------------------------------------------- ; clkwr: push h ; Reset clock counters mvi a,0ffh ; All 1's for a reset counter command out @clk + 18 ; Resets all the counters ; ldax d mov a,m out @clk + 2 inx d ; ldax d out @clk + 3 ; Minutes inx d ; ldax d out @clk + 4 ; hours inx d ; ldax d out @clk + 5 ; Day of week inx d ; ldax d out @clk + 6 ; Day of month inx d ; ldax d out @clk + 7 ; Month inx d ; ldax d ; Write year to clock ram out @clk + 0fh ; Write to year register ram ; pop h ret ; ;---------------------------------------------------------------- ; Initialize the hardware on the board ; ; Initialize the SIO for channel A and channel B 8 bit, 1 stop ; no parity and 9600 baud each. ; CTC channels 0 and 1 are for SIO baud rates ; CTC channel 2 for external interrupts......... (see monitor) ; CTC channel 3 for real time clock interrupts.. (see monitor) ;---------------------------------------------------------------- ; init: lxi h,initbl initlp: mov b,m ; get counter inx h mov c,m ; get port mov a,b ora a ; check for zero jz inictc ; exit if count=0 inx h outir ; send all out jr initlp ; inictc: mvi a,02h ; Reset channel out @ctc0 ; nop nop ; ; mvi a,045h ; Time constant follows out @ctc0 mvi a,13 out @ctc0 ; ; Initialize the watchdog timer clear routine that toggles the ; low order bit each time called. ; xra a sta wdt$flg sta bel$byt ; ret ; ;---------------------------------------------------------------- ; Console output ;---------------------------------------------------------------- ; con$out: coe: push psw coe$wait: in @stat0 ani txmsk ; See if transmitter empty. jrz coe$wait ; Ok, send the data out. pop psw out @data0 ret ; ;---------------------------------------------------------------- ; Console input ;---------------------------------------------------------------- ; con$inp: cie: call clrwdt in @stat0 ani rxmsk jz cie in @data0 ret ; Done ; ;---------------------------------------------------------------- ; Console status ;---------------------------------------------------------------- ; con$ist: cst: call clrwdt ; Clear the dog in @stat0 ani rxmsk rz mvi a,0ffh ret ; ;---------------------------------------------------------------- ; Hardware setups for the system chips. ;---------------------------------------------------------------- ; initbl: ; Setup the dart A channel db 01,@stat0,018h ; Channel reset db 02,@stat0,04,044h ; X1 clock, 1 stop bit, parity OFF db 02,@stat0,01,000h ; Clear internal status db 02,@stat0,03,0c1h ; Rx 8 bit. Rx enable, auto enables OFF db 02,@stat0,05,0eah ; DTR, Tx 8 bit, Tx enable, RTS, DTR of db 00 ; ; NOTE that the B channel is initialized in the AUX driver module used ; by the system. This makes sense as different system software may ; need different AUX drivers. ; dseg ; bel$byt db 00 ; Last bell port write led$byt db 00 ; Last LED output byte wdt$flg db 00 ; Dog flag bit 0 ?time: ds 8 ; Time buffer address end ;