home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
cpm
/
utils
/
asmutl
/
hd64180a.lbr
/
IO.AZM
/
IO.ASM
Wrap
Assembly Source File
|
1991-08-04
|
11KB
|
465 lines
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
;