home *** CD-ROM | disk | FTP | other *** search
- ;----------------------------------------------------------------
- ; This program reads 4 digital input lines on an SBC-800 board
- ; parallel port lines and uses them to count external events.
- ; It is assumed that the lines will be low, going high, then low
- ; again. The leading edge is detected and when the falling edge is
- ; found then a counter is incermented.
- ;
- ; Written R.C.H. 23/10/83
- ; Last Update R.C.H. 08/12/83
- ;----------------------------------------------------------------
- ;
- extrn prolog,inline,cie,coe,cst,cursor,clkrd,bell
- extrn bell,setxy,pmenu,quit,clear,caps,crlf
- extrn nolzb,lzb,blzb,phacc,pdde,phde,dispatch,hexbcd
- extrn curon,curoff,clkrd,xyinline
- ;
- data equ 080h ; data port to read for the 4 switches
- stat equ data+3 ; status port for the data port
- cntmax equ 030 ; loops between time check & print
- timx equ 22 ; time x column screen address
- timy equ 22 ; time y row address
- ;
- call prolog
- call clear
- lxi d,display ; display a message
- call pmenu
- call curoff ; disable the cursor
- call blzb ; nice blanking is required
- ; Clear all the counts next
- call clear0
- call clear1
- call clear2
- call clear3 ; all set to 00, status also
- ; Now we set up a default status of the on / off switches by setting them on
- mvi c,0ffh ; all switches on
- call check4
- call check5
- call check6
- call check7
- ;
- ; Set up the 8255 to be an input device on channel A
- mvi a,090h ; a inputs, b&c outputs
- out stat
- ;
- mvi a,1 ; display time soonest possible
- sta counts ; save a loop counter
- ;
- ; Now go straight into the loop.
- ; Read the input port PA0 and detect which switches are on and off
- ; Use this to detect switch transitions.
- ;
- loop:
- in data
- mov c,a ; save the data byte
- call check0 ; bits 0--7 are counters
- call check1
- call check2
- call check3
- call check4 ; bits 4--7 are on / off switches
- call check5
- call check6
- call check7
- call chk$counts ; check the loop counter
- call do$bell ; ring bell only if a changed counter
- call cst ; character typed ?
- jz loop
- call cie
- call caps
- cpi 'Q'
- jz finish
- lxi h,loop
- push h ; put a return address on stack
- cpi '0'
- jz clear0
- cpi '1'
- jz clear1
- cpi '2'
- jz clear2
- cpi '3'
- jz clear3
- cpi 'T'
- jz tog$bell ; toggle the bell
- jmp bell ; all else was an illegal character
- ;
- finish:
- lxi d,21 ; line 22
- call cursor
- call crlf
- call curon ; restore the cursor
- jmp quit
- ;
- ;----------------------------------------------------------------
- ; This routine must get the count of the number of times the
- ; program has looped and when it is 00 it prints the time
- ; on the screen where it is set up for.
- ;----------------------------------------------------------------
- ;
- chk$counts:
- lda counts
- dcr a
- sta counts
- ora a
- rnz ; exit if not end of loop
- ;
- mvi a,cntmax ; get maximum count value
- sta counts
- ; Now get the time
- lxi d,tbuff ; point to time buffer
- call clkrd ; read the clock into it
- ; Now check the validity of the time
-
-
- ; Now we check if the seconds has changed since the last time we were here
- lda old$secs
- mov c,a ; save
- lda secs ; get current seconds value
- cmp c ; same ??
- rz ; return now if the same
- sta old$secs ; save the seconds
- ;
- ; Since time is ok, print it after x,y addressing
- prnt$time:
- mvi d,timx + 7
- mvi e,timy
- call cursor ; do the set up
- ;
- call nolzb
- lda hrs
- call phacc ; display it
- mvi a,':'
- call dispatch
- lda mins
- call phacc
- mvi a,':'
- call dispatch
- lda secs
- call phacc
- call blzb ; back to blank filled lzb again
- ;
- ; Now print the loops counter. This = the number of seconds we have run.
- lhld loops
- inx h
- shld loops
- xchg ; load into DE
- call inline
- db ' $'
- call pdde
- ret
- ;
- ;----------------------------------------------------------------
- ; The following four routines use the byte passed in and use
- ; it to detect a switch transition. A switch transition occurrs
- ; when an input goes high then low.
- ;----------------------------------------------------------------
- ;
- check0:
- mov a,c ; fetch input byte
- ani 1 ; make it a 1 or a 0 only
- mov e,a ; put into e
- lda status0
- cmp e ; is the previous value the same ??
- rz ; exit if so
- ; We have gone high-> low or low-> high if here
- jnc c0fall ; no carry means a falling edge
- ; Here and there is a rising edge.
- mvi a,1
- sta status0 ; save it
- ret
- ; Here and a falling edge detected.
- c0fall:
- xra a
- sta status0
- lhld s0 ; load the count value
- inx h
- shld s0
- ; set up cursor and display
- dsp0: ; The entry to display hl on the screen
- lxi d,0a06h
- call cursor
- xchg
- call pdde
- mvi a,0ffh
- sta ring ; flag a change in a counter
- ret
- ;
- ; Second counter exactly the same way
- ;
- check1:
- mov a,c ; fetch input byte
- ani 2 ; make it a 1 or a 0 only
- mov e,a ; put into e
- lda status1
- cmp e ; is the previous value the same ??
- rz ; exit if so
- ; We have gone high-> low or low-> high if here
- jnc c1fall ; no carry means a falling edge
- ; Here and there is a rising edge.
- mvi a,2 ; save the bit number
- sta status1 ; save it
- ret
- ; Here and a falling edge detected.
- c1fall:
- xra a
- sta status1
- lhld s1 ; load the count value
- inx h
- shld s1
- ; set up cursor and display
- dsp1: ; The entry to display hl on the screen
- lxi d,0a08h
- call cursor
- xchg
- call pdde
- mvi a,0ffh
- sta ring
- ret
- ;
- ; Third counter
- ;
- check2:
- mov a,c ; fetch input byte
- ani 4 ; make it a 1 or a 0 only
- mov e,a ; put into e
- lda status2
- cmp e ; is the previous value the same ??
- rz ; exit if so
- ; We have gone high-> low or low-> high if here
- jnc c2fall ; no carry means a falling edge
- ; Here and there is a rising edge.
- mvi a,4
- sta status2 ; save it
- ret
- ; Here and a falling edge detected.
- c2fall:
- xra a
- sta status2
- lhld s2 ; load the count value
- inx h
- shld s2
- ; set up cursor and display
- dsp2: ; The entry to display hl on the screen
- lxi d,0a0ah
- call cursor
- xchg
- call pdde
- mvi a,0ffh
- sta ring
- ret
- ;
- ; Fourth and last counter
- ;
- check3:
- mov a,c ; fetch input byte
- ani 8 ; make it a 1 or a 0 only
- mov e,a ; put into e
- lda status3
- cmp e ; is the previous value the same ??
- rz ; exit if so
- ; We have gone high-> low or low-> high if here
- jnc c3fall ; no carry means a falling edge
- ; Here and there is a rising edge.
- mvi a,8
- sta status3 ; save it
- ret
- ; Here and a falling edge detected.
- c3fall:
- xra a
- sta status3
- lhld s3 ; load the count value
- inx h
- shld s3
- ; set up cursor and display
- dsp3: ; The entry to display hl on the screen
- lxi d,0a0ch
- call cursor
- xchg
- call pdde
- mvi a,0ffh
- sta ring
- ret
- ;
- ;----------------------------------------------------------------
- ; These routines display the status of the on / off switches
- ; connected to bits 4 to 7 inclusive.
- ; The only time the switch has its message changed is when there is a
- ; transition from one state to another. All else causes a return.
- ; On entry register C = the input byte. Each routine checks its bit
- ; to see if there is a change from the bit saved in memory. If a
- ; difference then the message is changed and the bit saved.
- ;----------------------------------------------------------------
- ;
- check4:
- mov a,c ; fetch the bit
- ani 010h ; test bit 4
- mov e,a ; save it back
- lda s4
- cmp e ; is the original equal to the new ?
- rz ; This is the immediate exit if no change
- ;
- ; Here we do a conditional bell.
- ; Now write the new bit back to memory then test is the message should be
- ; an on or off message, print it then return.
- mov a,e ; restore masked / tested bit
- sta s4
- ora a
- jz c4off ; display check 4 off message
- ; Here display the on message
- lxi d,0c0eh
- call cursor
- call inline
- db ' ON$'
- ret
- c4off:
- lxi d,0c0eh
- call cursor
- call inline
- db 'OFF$'
- ret
- ;
- ; Check the second switch status
- ;
- check5:
- mov a,c ; fetch the bit
- ani 020h ; test bit 5
- mov e,a ; save it back
- lda s5
- cmp e ; is the original equal to the new ?
- rz ; This is the immediate exit if no change
- ;
- ; Here we do a conditional bell.
- ; Now write the new bit back to memory then test is the message should be
- ; an on or off message, print it then return.
- mov a,e ; restore masked / tested bit
- sta s5
- ora a
- jz c5off ; display check 4 off message
- ; Here display the on message
- lxi d,0c10h
- call cursor
- call inline
- db ' ON$'
- ret
- c5off:
- lxi d,0c10h
- call cursor
- call inline
- db 'OFF$'
- ret
- ;
- ; Check the tried switch
- ;
- check6:
- mov a,c ; fetch the bit
- ani 040h ; test bit 6
- mov e,a ; save it back
- lda s6
- cmp e ; is the original equal to the new ?
- rz ; This is the immediate exit if no change
- ;
- ; Here we do a conditional bell.
- ; Now write the new bit back to memory then test is the message should be
- ; an on or off message, print it then return.
- mov a,e ; restore masked / tested bit
- sta s6
- ora a
- jz c6off ; display check 4 off message
- ; Here display the on message
- lxi d,0c12h
- call cursor
- call inline
- db ' ON$'
- ret
- c6off:
- lxi d,0c12h
- call cursor
- call inline
- db 'OFF$'
- ret
- ;
- ; Check the last (bottom) switch
- ;
- check7:
- mov a,c ; fetch the bit
- ani 080h ; test bit 4
- mov e,a ; save it back
- lda s7
- cmp e ; is the original equal to the new ?
- rz ; This is the immediate exit if no change
- ;
- ; Here we do a conditional bell.
- ; Now write the new bit back to memory then test is the message should be
- ; an on or off message, print it then return.
- mov a,e ; restore masked / tested bit
- sta s7
- ora a
- jz c7off ; display check 4 off message
- ; Here display the on message
- lxi d,0c14h
- call cursor
- call inline
- db ' ON$'
- ret
- c7off:
- lxi d,0c14h
- call cursor
- call inline
- db 'OFF$'
- ret
- ;
- ; Clear the counters. This is called at program start and when
- ; keystroke options are entered
- ;
- clear0:
- xra a
- lxi h,0
- shld s0
- sta status0
- jmp dsp0 ; display this new value
- ;
- clear1:
- xra a
- lxi h,0
- shld s1
- sta status1
- jmp dsp1
- ;
- clear2:
- xra a
- lxi h,0
- shld s2
- sta status2
- jmp dsp2
- ;
- clear3:
- xra a
- lxi h,0
- shld s3
- sta status3
- jmp dsp3
- ;
- ; This is the conditional bell ringer. If the bell status flag is
- ; 00 then the bell is not sounded else if non zero then it is rung.
- ;
- do$bell:
- lda bell$stat
- ora a
- rz
- ; Now we check the bell code in ring. If this is not 00 then we clear it
- ; then ring the bell. This byte really only is used to indicate
- ; a changed counter.
- lda ring
- ora a
- rz ; exit since no counters tripped
- xra a
- sta ring ; clear the byte if it is set
- jmp bell ; return after ringing the bell
- ;
- ; This simple routine toggles the bell in and out. The bell is
- ; in when the bell stat byte is not 00.
- ;
- tog$bell:
- lxi d,0340ah ; col 53, lin 10
- call cursor
- ;
- lda bell$stat
- xri 0ffh ; toggle it
- sta bell$stat
- ;
- ora a ; 00 and bell off
- jz tog$bell2
- ; here and the bell is on, next time we toggle off
- call inline
- db 'OFF$'
- ret
- ; here and the bell is disabled so we toggle it on next time
- tog$bell2:
- call inline
- db 'ON $'
- ret
- ;
- ; Message display area next
- ;
- display:
- db 12,00,'SBC-800 Switch Transition Counter V1.0$'
- db 00,06,' Count 0$'
- db 00,08,' Count 1$'
- db 00,10,' Count 2$'
- db 00,12,' Count 3$'
- db 00,14,'Switch 0 $'
- db 00,16,'Switch 1 $'
- db 00,18,'Switch 2 $'
- db 00,20,'Switch 3 $'
- db 36,04,'------Options----$'
- db 36,06,'0 = Clear Count 0$'
- db 36,07,'1 = Clear Count 1$'
- db 36,08,'2 = Clear Count 2$'
- db 36,09,'3 = Clear Count 3$'
- db 36,10,'T = Toggle bell ON$'
- db 36,12,'Q = Quit$'
- db timx,timy,'Time$'
- db timx+24,timy,'Total Seconds$'
- db 0ffh
- ;
- dseg
- ;
- ; The next 8 sections are used to detect leading edges and to
- ; count switch transitions.
- ;
- s0 db 00,00
- status0 db 00
- s1 db 00,00
- status1 db 00
- s2 db 00,00
- status2 db 00
- s3 db 00,00
- status3 db 00
- ;
- ; The next 4 locations are for the switches
- ;
- s4 db 00
- s5 db 00
- s6 db 00
- s7 db 00
- ;
- ; Status flags
- ;
- bell$stat:
- db 00 ; 00 = bell off, else bell on
- ring db 00 ; 00 = no ring, 0ffh = change so ring
- ;
- ; A buffer to read the time into
- ;
- loops db 00,00 ; loop counter = total seconds run
- counts db 00 ; count program loops
- old$secs
- db 00 ; Save to check time against
- ;
- tbuff: db 00,00,00,00 ; year, month, day, dow
- hrs db 00
- mins db 00
- secs db 00
- ;
- end