Appendix D
68HC711 Assembly Code
*******************************************************************************
*******************************************************************************
* PAWS (Printer Quota Access With Speed) HC11 assembly code *
* North Carolina State University *
* Written by: Kent Voorhees and Sean Korb *
* For Senior Design ECE 480/481. *
* Spring 1996 *
* Modified by: *
* *
*******************************************************************************
******************************** Flow Diagram *********************************
*******************************************************************************
*
* TOP
* -------------->-------------.---------------<---------------|
* | | |
* | | |
* | -------------------------- |
* | | Initialize + Scrolling | |
* | -------------------------- |
* | | Keyhit |
* | | |
* | | |
* | Timeout --------------------------- /|\
* |<-------------| Read ID # | |
* | --------------------------- |
* | | |
* | | |
* | | |
* | |--------| Timeout /=\ Fail |----------| |
* |/___|Message,|__________/ Ser \ ____________|MessageID#|___|
* |\ | resync | \ ial / |not found |
* | |--------| \=/ |----------|
* | | Pass
* | |
* | |
* | ------------------------
* | | ID# XXX-XX-XXXX |
* | | account verified |
* | ------------------------
* | |
* | .---------------------->|<------------------------------,
* | | | |
* | | --------------------------- |
* | | | Quota= +/-XXX.XX on/off | |
* | | | Enter $5.00 bills... | |
* | | --------------------------- |
* | | | | | |
* | | Timeout | | Keyhit | $5 entered |
* | | | | | |
* | |Keyhit -------- | | |
* | `--------| more | | | |
* | | time | | | |
* | -------- | | |
* | Timeout | | | |
* |<--------------' | | |
* | --------- --------------- |
* | | Thank | | quota up $5 | |
* | | You | |Bill Accepted| |
* | --------- --------------- |
* | | | |
* |<-----------------------' | |
* | | |
* | | |
* | ------------ Timeout /=\ Pass |
* |_______| Message, |_____________ / Ser \___________________|
* | | resync | \ ial /
* | ------------ \=/
* | | Fail
* | |
* | --------------
* | | Message of |
* | | $5 stolen |
* | --------------
* | |
* `---------------<--------------------'
*
*
****************************************************************************
***************************** Global Definitions ***************************
****************************************************************************
RAMBS equ $0000 * start of ram
KEYPADMEM equ RAMBS+$00 * keypad storage area
TIMECNT1 equ RAMBS+$06 * counter for timeouts
TIMECNT2 equ RAMBS+$08 * counter for timeouts
TIMEUP equ RAMBS+$0A * timeup flag
MSGFRONT equ RAMBS+$0C * location of beginning of message for wrap
MSGWINDOW equ RAMBS+$0E * location of message to LCD scrolling
BUTTON equ RAMBS+$10 * button hit flag
SCRATCH equ RAMBS+$12 * scratch space
SSNCOUNT equ RAMBS+$1E * counter for ID number
SSNMSG equ RAMBS+$20 * storage of the ID number
SSN equ RAMBS+$20 * storage of the ID number
MESSAGE equ RAMBS+$30 * message storage received from serial communication
BAUD_BAK equ RAMBS+$48 * sci storage
SCCR1_BAK equ RAMBS+$4A * sci storage
SCCR2_BAK equ RAMBS+$4C * sci storage
SCRLSTYLE equ RAMBS+$4E * scrolling style variable
REGBS equ $1000 * start of registers
KPDROW equ REGBS+$03 * location of the keypad row select output (port C 0-3)
LED equ REGBS+$03 * location of the status LED (port C 4-5)
BILLENB equ REGBS+$03 * location of the bill enable output (port C 6)
LCDDATA equ REGBS+$04 * location of the LCD's data bus (port B)
DDRC equ REGBS+$07 * location of port C control register
LCDCTRL equ REGBS+$08 * location of the LCD's enable and reg. select (port D)
DDRD equ REGBS+$09 * location of port D control register
PORTE equ REGBS+$0A * port e
KPDCOL equ REGBS+$0A * location of the keypad column detect input (port E 0-3)
BILLACK equ REGBS+$0A * location of the bill acknowledgement input (port E 4)
BAUD equ REGBS+$2B * sci baud reg
SCCR1 equ REGBS+$2C * sci control1 reg
SCCR2 equ REGBS+$2D * sci control2 reg
SCSR equ REGBS+$2E * sci status reg
SCDAT equ REGBS+$2F * sci data reg
BPROT equ REGBS+$35 * block protect reg
OPTION equ REGBS+$39 * option reg
COPRST equ REGBS+$3A * cop reset reg
PPROG equ REGBS+$3B * ee prog reg
HPRIO equ REGBS+$3C * hprio reg
CONFIG equ REGBS+$3F * config register
ROMBS equ $E000 * start of rom
STREE equ $B600 * start of eeprom
ENDEE equ $B7FF * end of eeprom
************************* BEGINING OF EXECUTION****************************
org $fffe *** vector for 68hc11 reset, fetches and
fcb $b6 *** puts in pc at reset. $b600 is the location
fcb $00 *** of eeprom where we want to jump to.
org $b600 *** EEPROM location
nop ***
nop ***
jmp MAININIT *** at the eeprom location we can jump to the
jmp MAININIT *** program in EPROM $d000
org $d000 *** location of the program
BEGIN: equ * *** current location... EE $b600 E $d000
MAININIT:
lds #$01E0 *** load stack pointer first
ldaa #$ff *** load accumulator A
staa DDRC *** store reg A, enable port C for output
staa DDRD *** store reg A, enable port D for output
jsr BILLINIT *** set billreader off, LED red
jsr PAUSEMED *** pause so to allow LCD to power up
MAINTOP:
jsr LCDRESET ***
jsr LCDCLEAR ***
jsr SCROLLMGR *** output messages until someone hits a key
MAINSTART: lds #$01E0 *** load stack pointer for jumps to this spot
jsr LCDRESET ***
PROMPT: jsr PROMPTSSN ***
READ: jsr READSSN *** read ID number from keypad
jsr SSNSERIAL *** send it serially and get message back
jsr VERIFY *** check it for pass fail
jsr QUOTAPRN *** show user quota status
BILLS: jsr READBILLS *** verify the collection of a bills
jsr THANKYOU *** Thank you! message
jmp MAINTOP *** loop to the top always
************************************************************************
* SCROLLMGR() coordinates all the scolling activity while the device *
* is in standby mode. It can output many different predefined messages *
* to the LCD screen. Exits on a keyhit. *
************************************************************************
SCROLLMGR: psha
pshx
clr BUTTON ***
MGRTOP: ldx #SCRLMSG1 *** First message
ldaa #$00 ***
staa SCRLSTYLE *** Single line style
ldaa #$03 *** repeat 2 times
jsr SCROLL ***
tst BUTTON *** if button hit quit
bne MGROUT ***
ldx #SCRLMSG2 *** message 2
ldaa #$01 ***
staa SCRLSTYLE *** 2 line wrapped style
ldaa #$02 *** repeat once
jsr SCROLL ***
tst BUTTON *** if button hit quit
bne MGROUT ***
ldx #SCRLMSG3 *** message 3
ldaa #$02 ***
staa SCRLSTYLE *** 2 line double print style
ldaa #$02 *** repeat once
jsr SCROLL ***
tst BUTTON *** if button hit quit
bne MGROUT ***
ldx #SCRLMSG4 *** message 4
ldaa #$03 ***
staa SCRLSTYLE *** 2nd line only style
ldaa #$02 *** repeat once
jsr SCROLL ***
tst BUTTON *** if button hit quit
bne MGROUT ***
ldx #SCRLMSG5 *** message 5
ldaa #$01 ***
staa SCRLSTYLE *** 2 line wrapped style
ldaa #$02 *** repeat once
jsr SCROLL ***
tst BUTTON *** if button hit quit
beq MGRTOP ***
MGROUT: clr BUTTON *** clear that button hit for exit condition
pulx
pula
rts
************************* SCROLLING MESSAGE PRINTER **************************
* Takes an address in register X and begins reading data from that location, *
* outputs characters until end of message flag. Then it repeats that message *
* the number of times that are passed in the A accumulator, or until a key *
* is struck on the keypad. Four scrolling styles are currently supported: *
* One line top(0), Two lines wrapped(1), Double lines(2), and Single line *
* bottom(3). These style are selected by storing the numbe listed above in *
* the variable SCRLSTYLE. *
* $FE is the end of message delimiter. *
******************************************************************************
SCROLL: pshb *** stack up registers a,b
psha ***
clr BUTTON *** set button low
stx MSGFRONT *** beginning of the message marked
FIRSTSCREEN: pula ***
deca ***
psha ***
ble SCROLLOUT ***
ldx MSGFRONT *** load character from memory
stx MSGWINDOW *** current screen location the first screen
NEXTSCREEN: ldx MSGWINDOW *** load the screen location
jsr LCDCLEAR *** clear for next screen
ldaa SCRLSTYLE ***
cmpa #$03 ***
bge SCROLL1 ***
ldab #$10 *** output a total of 16 characters
NEXT1ST: ldaa 0,x *** First line
jsr DATAOUT *** output one character
inx *** move over one
decb ***
bne NEXT1ST ***
SCROLL1: ldaa SCRLSTYLE ***
cmpa #$01 ***
bne SCROLL2 ***
jsr LINE2 ***
ldab #$10 ***
NEXT2ND: ldaa 0,x *** Second line extention of the first, wrapped.
jsr DATAOUT *** output one character
inx *** move over one
decb ***
bne NEXT2ND ***
SCROLL2: ldaa SCRLSTYLE ***
cmpa #$02 ***
blt SCROLL3 ***
cmpa #$03 ***
bgt SCROLL3 ***
ldx MSGWINDOW ***
jsr LINE2 ***
ldab #$10 ***
NEXTDBL: ldaa 0,x *** Double print, both lines same message
jsr DATAOUT ***
inx ***
decb ***
bne NEXTDBL ***
SCROLL3: ldaa 0,x ***
cmpa #$fe *** end of message marker
beq FIRSTSCREEN ***
ldx #$01cf *** finished with x so use for loop delay
SCROLLDELAY: jsr KEYHIT *** check to see if someone
tst BUTTON *** has pushed a button to
bne SCROLLOUT *** start the quota action-->out
dex
bne SCROLLDELAY
ldx MSGWINDOW *** Shift the window over one place
inx ***
stx MSGWINDOW *** if the last one draw new screen one over
bra NEXTSCREEN *** if not draw next screen
SCROLLOUT:
pula *** do not clear button on exit
pulb ***
rts *** return
nop ***
****************************** LCDOUT ************************************
* Takes an address in register X and reads one piece of data from that *
* location, and outputs 1 character or instruction if not the end of *
* message flag. $FE is the end of message delimiter $AO indicates that *
* the next byte is an instruction. Also COUT allow single ctrl code *
* output to the LCD. *
**************************************************************************
LCDOUT: cmpa #$FE *** check for end of message which is $FE
beq LCDEXIT ***
cmpa #$A0 *** check for an instruction (otherwise character data)
bne DATAOUT *** if character skip down...
inx
CTRLOUT: psha *** Control codes only
pshb ***
ldaa 0,x *** load instruction from index x register
bra COUT1
COUT: psha *** Used to blast out single ctrl codes
pshb *** outside the context of a message.
ldab #$10 ***
stab LCDCTRL ***
staa LCDDATA ***
ldab #$00 ***
stab LCDCTRL ***
jsr PAUSESHORT ***
bra LCDEND ***
COUT1: ldab #$10 *** mask for control code
stab LCDCTRL *** blast out the control code for the LCD
staa LCDDATA *** write character to display's data bus
ldab #$00 *** lower the enable on the control mask
stab LCDCTRL *** blast out the code with enable lowered
jsr PAUSEMED *** call routine for delay between characters
bra LCDEND *** skip the rest
DATAOUT: psha *** Data only output here
pshb ***
ldab #$18 ***
stab LCDCTRL *** blast out the control code for the LCD
staa LCDDATA *** write character to display's data bus
ldab #$08 *** lower the enable on the control mask
stab LCDCTRL *** blast out the code with enable lowered
jsr PAUSESHORT *** call routine for delay between characters
LCDEND: pulb *** unstack registers y,b,a
pula ***
LCDEXIT: rts *** all done return from subroutine
nop ***
**************************** KEYHIT **************************************
* Detects a keystrike on the keyboard and sets the memorylocation BUTTON *
* to a non zero number. That non zero number is the value of the key *
* that was hit. Except for zero, a one is stored for zero. Tha 'A' key *
* is for Abort. It turns off the bill reader, jumps to the top of main. *
**************************************************************************
KEYHIT: psha *** stack up register b
pshb ***
pshx ***
jsr KEY2NUM *** get a key press value
cmpb #$10 ***
beq OUTNOHIT *** no hit go back, hit proceed
tba ***
WAITKEYOFF: jsr KEY2NUM ***
cmpb #$10 *** wait for key to go back low
bne WAITKEYOFF ***
tab *** retrieve value
cmpb #$03 *** if 'A' is not hit
bne KEYDOWN *** skip the following
jsr BILLSROFF *** turn off bill machine if on
jmp MAINSTART *** Abort and return to the top main loop
KEYDOWN:
cmpb #$00 *** check for zero
bne KEYHITOUT ***
incb *** for zero add one so we can see it as a hit
KEYHITOUT: stab BUTTON *** number stored for hit
OUTNOHIT: pulx ***
pulb *** unstack register b
pula ***
rts *** all done return from subroutine
nop ***
**************************** TIMEOUT ********************************
* Time out when called decrements a pair of nested values which are *
* preloaded. When these values both reach zero the timeout has *
* finished and the timeup flag is set high. Used for preventing the *
* program from being hung in any one loaction. *
*********************************************************************
TIMEOUT: pshy *** stack up register a
LEVEL1:
ldy TIMECNT1 *** check first counter
dey
beq LEVEL2 *** if zero check second counter
sty TIMECNT1
jmp EXITTIMEOUT *** return
LEVEL2: ldy #$0fff ***
sty TIMECNT1 *** reload first counter
ldy TIMECNT2
dey *** check second counter
beq TIMEDONE *** test to see if done
sty TIMECNT2
jmp EXITTIMEOUT ***
TIMEDONE: ldy #$ffff *** if done
sty TIMEUP *** set the timeup flag to nonzero
EXITTIMEOUT: puly *** unstack register a
rts *** all done return from subroutine
nop ***
************************* SETTIMEOUT **********************************
* Sets the timeout values in timecnt1 and timecnt2 to three possible *
* values. A short medium and long length time out are provided. *
***********************************************************************
SETTIMEOUT1: pshy *** stack up register a
ldy #$0024 *** 45 secs
jmp SETTIMEOUT ***
SETTIMEOUT2: pshy *** stack up register a
ldy #$000f *** 15 secs
jmp SETTIMEOUT ***
SETTIMEOUT3: pshy *** stack up register a
ldy #$009f *** for sci timeouts
SETTIMEOUT: sty TIMECNT2 *** load second counter
ldy #$0fff ***
sty TIMECNT1 *** load first counter
ldy #$0000 ***
sty TIMEUP *** reset timeup flag
puly ***
rts
*********************** MESSAGE PRINTER ******************************
* Takes an address in register X and begins reading data from that *
* location, outputs characters or instructions until end of message *
* flag. $FE is the end of message delimiter $AO indicates that the *
* next byte is an instruction. *
**********************************************************************
MESGPRN: psha *** stack up register a
MESGTOP: ldaa 0,x *** load character from memory
cmpa #$FE *** check for end of message which is $FE
beq MESGEND *** is so exit
nop ***
jsr LCDOUT *** output information (data or control)
inx *** next character in message
bra MESGTOP *** repeat...
MESGEND: pula *** unstack register a
rts *** all done return from subroutine
nop ***
*********************** QUOTA PRINTER ******************************
* Outputs the screen for showing the users Quota amount and tells *
* the user to enter $5 bills. *
********************************************************************
QUOTAPRN: psha ***
jsr LCDCLEAR *** clear screen then print following
ldx #MSGQUO1 *** quota=
jsr MESGPRN ***
nop
ldx #MESSAGE+#$01 *** Info about quota from host
ldaa 0,x ***
cmpa #$50 *** 'P'
bne QUOTE1 ***
inx
QUOTE1: jsr MESGPRN *** -XXX.XX on or +XXX.XX off
ldx #MSGQUO2 *** Insert $5 bills
jsr MESGPRN ***
pula ***
rts
*************************** THANKYOU *********************************
* Outputs the screen for thanking the user for using PAWS. It first *
* clears the screen *
**********************************************************************
THANKYOU: pshx
jsr LCDCLEAR
ldx #MSG5
jsr MESGPRN
jsr PAUSE3SEC
pulx
rts
************************ KEY PAD SCANNER *****************************
* Scans the entire keypad once storing the results by row in the low *
* order nibble of the 4 memory addresses beginning at $0000 *
**********************************************************************
READKEY: psha *** stack up registers a,b,x
pshb ***
pshx ***
SCAN: ldaa #1 *** initialize to first row of keypad
ldx #0 *** load 0 into index register x
ROW: ldab KPDROW ***
andb #$f0 ***
aba ***
staa KPDROW *** scan a row by poking it with a 1,2,4 or 8
anda #$0f ***
ldab KPDCOL *** returns which keys in that row were pushed, by column #
stab 0,x *** store that number in memory (x) ??? for later decode
inx *** increment index register x
lsla *** shift (increment) the row number (1->2->4->8)
cmpa #8 ***
ble ROW *** continue until scanned all 4 rows
pulx ***
pulb ***
pula *** stack off registers x,b,a
rts ***
nop ***
nop ***
**************** KEYGRID TO KEY NUMBER CONVERSION ********************
* Calls READKEY above, and then parses the output, leaving a number *
* for the key pressed in register B. *
**********************************************************************
KEY2NUM: psha *** stack up registers a,x
pshx ***
jsr READKEY *** call subroutine for row/column reading.
ldx #0 *** load index register x with 0
ldab #0 *** load accum b with 0
ldaa #1 *** load accum a with 1
CONVROW: bita 0,x *** set condition codes ANDing accum a with (00x)
bne DONENUM *** if found set bit exit with current value of b
incb *** if not found increment b (0->1->2->...->15)
lsla *** shift accum a left (1->2->4->8->16)
cmpa #16 *** if in first 4 columns come down and -------.
bne SKIPINX *** stop after reach the end of row and --. |
inx *** increment index register x <----' |
ldaa #1 *** reload accum a with 1 |
SKIPINX: cpx #4 *** compare x with last row <--------'
bne CONVROW *** if not last row jump back to top
DONENUM: pulx ***
pula *** stack off the registers x,a
rts ***
nop ***
nop ***
************************* KEY PAD READER *********************************
* READSSN() Reads the input from the keypad until 9 numbers have been *
* entered or until a 45 second timeout has expired(return to beginning) *
* READ calls KEY2NUM(translation to numbers) which calls READKEY(raw get *
* keypad bytes). READSSN() checks for non number keyhits (command keys) *
* and executes the cooresponding action. Allows only a 9 digit number to *
* be entered(automatically exits). Calls SSNSTORPRN() which stores and *
* prints each digit of the number. *
**************************************************************************
READSSN: psha ***
pshb ***
pshx ***
clr SSNCOUNT *** Start counting over
jsr SETTIMEOUT3 *** 45 sec time limit
READ1: jsr TIMEOUT *** decrement that limit
tst TIMEUP *** check if time is up
beq READ2 *** if not skip the next jump
jmp MAINTOP *** if done jump to main
READ2: jsr KEY2NUM *** check for a keypress
cmpb #$10 *** returns a no key pressed
beq READ1 *** keep reading keypad until a key is read
tba *** transfer accum b to accum a for storage
READ3: jsr KEY2NUM *** go look until keypress is done
cmpb #$10 *** compare with a nopress
bne READ3 *** loop until character is over
tab *** transfer accum a back into accum b
cmpb #$03 *** key 'A' done was pressed. Abort key.
bne READSKIP1 ***
jmp MAINTOP ***
READSKIP1: cmpb #$07 *** key 'B' done was pressed. Backspace key.
bne READSKIP2 ***
jsr BACKSPACE *** so move back 1
READSKIP2: cmpb #$0B *** key 'C' done was pressed. Clear key.
bne READSKIP3 ***
jmp MAINSTART *** Distance problem for branching
READSKIP3: cmpb #$0C *** key '*'
beq READ1 ***
cmpb #$0E *** key '#'
beq READ1 ***
cmpb #$0F *** key 'D' done was pressed. Enter key.
beq CHECK10 *** so confirm SSN is 10 numbers long
jsr SSNSTORPRN ***
CHECK10: ldaa SSNCOUNT ***
cmpa #$09 ***
beq EXITREAD ***
bra READ1 *** jump back up to top (need a 'D' to exit)
nop
EXITREAD:
pulx ***
pulb ***
pula ***
rts ***
*************************** PROMPT FOR SSN ******************************
* Outputs the screen that prompts the user to enter the Social Security *
* Number. *
**************************************************************************
PROMPTSSN: pshx ***
jsr LCDCLEAR *** Clear the screen
ldx #MSG1 *** Enter ID#
jsr MESGPRN *** >
pulx ***
rts
nop
nop
****************************** Verify ***********************************
* Clears the screen outputs the SSN as entered by the user. Then if the *
* hostapproved show accepted and proceed, else tell of failure and quit *
* the transaction. *
*************************************************************************
VERIFY: pshb ***
pshx ***
jsr LCDCLEAR *** clear screen
VERIFY1: ldx #IDNUM *** ID#
jsr MESGPRN ***
ldaa #$fe *** append a end of message marker to SSN
staa SSN+$0a *** at the end of the number
ldx #SSN+$01 *** load location of SSN
jsr MESGPRN *** output the SSN
ldx #MESSAGE ***
ldaa 0,x *** check first letter of message
cmpa #$50 *** "P" for Pass, all else fails
beq PASS ***
inx ***
ldaa 0,x ***
cmpa #$50 ***
bne FAIL ***
PASS: ldx #FOUND *** success, show 'em then continue
jsr MESGPRN ***
jsr PAUSELONG ***
VEROUT: pulx ***
pulb ***
rts *** return to main loop...
nop
FAIL: ldx #NOTFOUND *** Fail the lookup so tell 'em so
jsr MESGPRN ***
jsr PAUSE3SEC *** pause then start scrolling again
VEROUT2: jmp MAINTOP ***
nop
****************************************************************
* FAILCOMM() Outputs stuff out the serial port until it hears *
* a response from the host. If we get a message back we know *
* all is well. PAWS gets hung here if host or cable is down. * *
****************************************************************
FAILCOMM: jsr LCDCLEAR ***
ldx #TROUBLE1 *** serial communication fault
jsr MESGPRN *** out to screen
jsr PAUSE3SEC ***
jsr LCDCLEAR ***
ldx #TROUBLE2 *** second message 'more details'
jsr MESGPRN ***
jsr ONSCI ***
jsr INSCI *** Clear anything in there
FAILCOMM1: jsr SETTIMEOUT2 *** SCI timeout
ldaa #$30 ***
jsr OUTSCI *** blast out zeros until we get a message back
FAILCOMM2: jsr TIMEOUT ***
tst TIMEUP ***
beq FAILCOMM3 *** timeout means host needs more characters
jsr OFFSCI ***
bra FAILCOMM ***
FAILCOMM3: ldaa #$00
jsr INSCI *** try to get a character
cmpa #$00 ***
beq FAILCOMM2 *** if we don't have first character of a message
jsr PAUSEMED2 ***
ldaa #$00 ***
jsr INSCI ***
cmpa #$00 ***
beq FAILCOMM2 *** try again if no message
jsr PAUSELONG *** let message go streaming by
jsr INSCI *** clear last character
jsr OFFSCI ***
jmp MAINTOP *** restart
********************** SSN STORE AND PRINT ****************************
* Stores the input SSN in ASCII form in a stack. It also outputs it to *
* the LCD for viewing. Allows a max of 9 numbers in the SSN storage. *
* Checks for nonnumber button hits and ignores then. * *
************************************************************************
SSNSTORPRN: psha ***
pshb ***
pshx ***
ldaa #$30 *** add for 0 to convert to ascii
cmpb #$0D *** Equals zero
beq ZERO ***
ldaa #$31 *** add for 1->3 to convert to ascii
cmpb #$03 *** because of the A B C D # * keys
blo SSNDOWN ***
beq SSNOUT ***
ldaa #$30 *** add for 4->6
cmpb #$07 ***
blo SSNDOWN ***
beq SSNOUT ***
ldaa #$2f *** add for 7->9
cmpb #$0B ***
blo SSNDOWN ***
bra SSNOUT *** fails to be a number
ZERO: ldab #$00 *** add to $30 => 0 ascii
SSNDOWN: aba ***
jsr DATAOUT *** Print the number to the screen
ldab SSNCOUNT *** check the count of the SSN
cmpb #$09 ***
bge SSNOUT *** if more than 9 numbers
ldx #SSN *** load the location of the SSN
abx *** add it to the SSN count
inx *** put it in the next open spot
staa 0,x *** store number from A into that spot
inc SSNCOUNT *** up the count
SSNOUT: pulx ***
pulb ***
pula ***
rts ***
nop ***
nop ***
******************************* SSN SERIAL *******************************
* Outputs message to the PAWS workstation host. Used to verify that the *
* person is a real user and can have their quota increased. Receives the *
* users quota information in a message from the host. *
**************************************************************************
SSNSERIAL: psha ***
jsr ONSCI *** turn on the serial port
nop ***
ldaa #$fe *** append a stop character for serial out
staa SSN+$0a *** at the end of the SSN
ldx #SSN+$01 *** lock and load
jsr OUTSTRG *** output the number entered by the user
nop ***
ldx #LOOKUP *** load the lookup command 'll' after #
jsr OUTSTRG ***
nop ***
jsr MESSAGEIN *** Now get the return message
ldx #MESSAGE+$0c *** append a end of message byte to the
ldaa #$fe *** message from the host for LCD.
staa 0,x ***
nop ***
jsr OFFSCI *** Turn off the sci til next time
pula ***
rts ***
nop
***************************************************************
* OFFSCI() ONSCI() Turn off and on the sci port. *
***************************************************************
ONSCI: psha *** Store the current values
ldaa BAUD *** in memory until later
staa BAUD_BAK *** when we move them back.
ldaa SCCR1 ***
staa SCCR1_BAK ***
ldaa SCCR2 ***
staa SCCR2_BAK ***
ldaa #$30 *** Load the communication
staa BAUD *** registers with the #'s
ldaa #$00 *** that make it go:
staa SCCR1 *** 9600 Bps
ldaa #$0c *** enable the pins
staa SCCR2 ***
pula ***
rts
OFFSCI: psha ***
ldaa BAUD_BAK *** Put the original values
staa BAUD *** back in the registers.
ldaa SCCR1_BAK ***
staa SCCR1 ***
ldaa SCCR2_BAK ***
staa SCCR2 ***
pula ***
rts ***
******************************************************************
* MESSAGEIN() Accepts a serial message through the serial port *
* until a 'Q' has been entered signaling the end of the message *
* or until 16 bytes have been entered. Timeouts are used and the *
* the resyncing subroutine is called in event of a failure. *
******************************************************************
MESSAGEIN: psha ***
jsr SETTIMEOUT3 *** SCI timeout length
ldx #MESSAGE *** location of the storage of the message
ldaa #$00 *** clear accumulator a
MESSAGE1: jsr TIMEOUT ***
tst TIMEUP *** Timed out yet?
bne MESSAGE3 *** Timeout so try to fix the problem.
jsr INSCI ***
cmpa #$00 ***
beq MESSAGE1 *** if no character try again
staa 0,x ***
inx ***
cmpa #$51 *** stop at Q or also
beq MESSAGE2 ***
cpx #MESSAGE+#$0010 *** stop after 16 chars input
blt MESSAGE1 ***
MESSAGE2: pula ***
rts ***
MESSAGE3: jmp FAILCOMM *** Failed communications try resyncing
**********************************************************************
* INSCI(), OUTSCI(), and OUTSTRG(x) were from the Buffalo 32 monitor *
* program for the 68HC11. We borrowed and modified this code. *
**********************************************************************
**********
* INSCI() - Read from SCI. Return a=char or 0.
**********
INSCI LDAA SCSR read status reg
ANDA #$20 check rdrf
BEQ INSCI1 jump if no data
LDAA SCDAT read data
ANDA #$7F mask parity
INSCI1 RTS
**********
* OUTSCI() - Output A to sci.
**********
OUTSCI pshb
cmpa #$fe
BEQ OUTSCI2 jump if end=0
OUTSCI1 LDAB SCSR read status
BITB #$80
BEQ OUTSCI1 loop until tdre=1
ANDA #$7F mask parity
STAA SCDAT send character
OUTSCI2 pulb
RTS
**********
* OUTSTRG(x) - Output string of ASCII bytes
* starting at x until end of text ($fe). Can
**********
OUTSTRG
OUTSTRG0 PSHA
OUTSTRG1 LDAA 0,X read char into a
CMPA #$fe *EOT
BEQ OUTSTRG3 jump if eot
JSR OUTSCI output character
INX
BRA OUTSTRG1
OUTSTRG3 PULA
jsr PAUSEMED
RTS
******************************* BILL SERIAL ******************************
* Outputs a serial message to the PAWS workstation host to increase the *
* quota value for the SSN transmitted. Receives a message back from the *
* host that tells the new quota level. Checks for a serial timeout *
* violation and calls a routine to resync communications. Checks for a *
* faulty message or a message of failure. *
**************************************************************************
SERIALBILL: psha ***
jsr ONSCI *** turn on the serial port
nop ***
ldx #SSN+$01 *** Send ID number
jsr OUTSTRG ***
ldx #INCREASE *** send the increase command 'ii'
jsr OUTSTRG ***
nop ***
jsr MESSAGEIN *** Now catch the return message from host
ldx #MESSAGE+$0c ***
ldaa #$fe *** append a end-of-message marker
staa 0,x *** to the message so it can be output
nop *** by LCD routine
jsr OFFSCI ***
tst TIMEUP *** Failure in the MESSAGEIN routine?
beq SB1 ***
jsr FAILCOMM *** if so then fix the problem
SB1: ldx #MESSAGE ***
ldaa 0,x ***
cmpa #$50 *** 'P' for pass required in message[0] or
beq SBPASS ***
inx ***
ldaa 0,x ***
cmpa #$50 *** 'P' for pass required in message[1].
beq SBPASS *** If we fail this we may have stolen money
jsr LCDCLEAR ***
ldx #SERBILLFAIL1 *** tell user we stole his money
jsr MESGPRN ***
jsr PAUSE3SEC ***
jsr LCDCLEAR ***
ldx #SERBILLFAIL2 *** tell user what to do about t
jsr PAUSE3SEC ***
jmp MAINTOP *** start over
SBPASS: pula ***
rts ***
nop
******************************* BILL READER ********************************
* Enables the bill reader and waits for a bill to be put into the machine. *
* When a bill is accepted, disable the reader and return from subroutine. *
* Allows bill to be entered for 45 seconds, if this time expires then it *
* asks the user if they would like more time. If the user does not hit a *
* key in 15 seconds the subroutine is exited. If a key is hit the user *
* another 45 seconds to enter a bill. This can repeat indefinetly. *
****************************************************************************
READBILLS: pshb ***
pshx ***
BILLTOP:
jsr SETTIMEOUT1 *** 45second timeout for bill entering
jsr BILLSRON *** turn bill reader on
clr BUTTON ***
nop
BILLWAIT: jsr KEYHIT *** check for abort
tst BUTTON ***
bne BILLOUT ***
jsr TIMEOUT ***
tst TIMEUP *** test for time up
bne MORETIME *** watchout, if timed out ask user if need more time
ldaa BILLACK *** scan the accept line
anda #$10 *** check for a bill
beq BILLWAIT *** try again
jsr BILLSROFF *** bill entered shut off bill reader
jsr LCDCLEAR ***
ldx #MSGACCPT *** show accepted
jsr MESGPRN ***
jsr SERIALBILL *** send SSN and lookup, receive quota info
jsr PAUSELONG ***
jsr QUOTAPRN *** display that new info
jmp BILLTOP *** try for another bill
nop ***
MORETIME: jsr BILLSROFF *** timeout occured, shut off bill reader
jsr LCDCLEAR ***
ldx #MSGTIME *** ask if they want more time
jsr MESGPRN ***
jsr SETTIMEOUT2 *** 15 sec timeout this time
nop
MT_TOP: jsr TIMEOUT ***
jsr KEYHIT *** a keyhit will get you back to bill entering again
tst BUTTON ***
beq MT_1 ***
jsr QUOTAPRN ***
jmp BILLTOP ***
MT_1: tst TIMEUP ***
beq MT_TOP *** if timeout occurs exit bill reading entirely
nop
BILLOUT: jsr BILLSROFF ***
pulx ***
pulb ***
rts ***
nop ***
nop ***
*********************** BILLREADER OFF/ON/INIT ************************
* Turns the bill reader on and off, also the LED indicator. Green is *
* operational, taking bills. Red is on, but not for bills. *
***********************************************************************
BILLSROFF: pshb ***
ldab BILLENB ***
andb #$9f ***
orab #$10 ***
bra BILL1 ***
BILLSRON: pshb ***
ldab BILLENB ***
andb #$ef ***
orab #$60 ***
bra BILL1 ***
BILLINIT: pshb ***
ldab #$10 ***
BILL1: stab BILLENB ***
pulb ***
rts ***
***************** STANDARD DELAY LOOP ********************
* Runs through a tight loop decrementing register Y *
* until zero is reached, for a number of iterations *
* equal to register B. *
**********************************************************
DELAY: dey *** dec y until
bne DELAY *** it equals zero
ldy #$ffff *** reload y with $ffff and
decb *** repeat until b is dec to zero
bne DELAY *** are we done yet
rts *** all done
nop ***
************************ LCD DELAY ***********************
* Loads register Y and register B and then calls DELAY *
**********************************************************
PAUSESHORT: pshb *** stack up registers b,y^M
pshy ***^M
ldy #$003f *** load up y with delay factor^M
ldab #$01 *** load up b with delay factor^M
bra PAUSE
PAUSEMED: pshb *** stack up registers b,y
pshy ***
ldy #$0900 *** load up y with delay factor
ldab #$01 *** load up b with delay factor
bra PAUSE
PAUSEMED2: pshb ***
pshy ***
ldy #8000 ***
ldab #$01 ***
bra PAUSE
PAUSELONG: pshb *** stack up registers b,y^M
pshy ***^M
ldy #$ffff *** load up y with delay factor^M
ldab #$0c *** load up b with delay factor^M
bra PAUSE
PAUSE3SEC: pshb
pshy
ldy #$ffff
ldab #$16
PAUSE: jsr DELAY *** delay is (Y*B) loops
puly ***
pulb *** stack off registers y,b
rts *** all done
nop ***
**************************************************************************
* LCD Backspace backs the cursor for inputing the SSN. It does not allow *
* the cursor to be backed up more than the number of digits entered *
**************************************************************************
BACKSPACE: pshx ***
tst SSNCOUNT *** if SSNCOUNT > 0 then we can backspace
beq BACKOUT *** else it will foul up the display.
dec SSNCOUNT ***
ldx #BACKLCD *** backspace message...
jsr MESGPRN ***
BACKOUT: pulx ***
rts ***
nop ***
******************************** LCD RESET **********************************
* Resets the LCD from cold or hot start. Clears the screen, cursor at front *
*****************************************************************************
LCDRESET: pshx ***
ldx #RESETLCD ***
jsr MESGPRN ***
pulx ***
rts ***
nop ***
*****************************************************************************
* LCD clear subroutine clears the screen and places the cursor at home. *
*****************************************************************************
LCDCLEAR: pshx ***
ldx #CLEARLCD ***
jsr MESGPRN ***
jsr PAUSEMED ***
pulx ***
rts ***
nop ***
****************************************************************************
* Moves LCD to the secound line. *
****************************************************************************
LINE2: psha ***
ldaa #$c0c0 ***
jsr COUT ***
pula ***
rts ***
nop ***
**************************************************************************
* moves LCD cursor to first location, home. *
**************************************************************************
HOME: psha ***
ldaa #$0202 ***
jsr COUT ***
pula ***
rts ***
nop ***
**************************************************************************
* moves LCD cursor to any location passed in accumulator B. The home *
* position is 0 , the second line is 40. Include error range check. *
**************************************************************************
CURSOR: psha ***
tstb ***
blt CURSOROUT *** only accept numbers between 0-80
cmpb #$80 ***
bgt CURSOROUT ***
ldaa #$80 *** then scale it to the display (+$80)
aba ***
jsr COUT ***
CURSOROUT:
pula ***
rts ***
nop ***
*** BEGIN MESSAGE DEFS ***
* Messages can be referenced from anywhere using their labels.
* All messages end with $FE and instructions can be embedded by preceding
* them with $AO.
SCRLMSG1: fcc ' '
fcc 'Welcome to PAWS... Add '
fcc 'money to your Printer Quota '
fcc '24 hours a day with Paws... '
fcc 'PAWS is Printer Quota Access '
fcc 'With Speed !!! Get printing '
fcc 'again fast with PAWS...'
fcc 'HIT ANY KEY TO START !!!'
fcc ' '
fcb $fe
SCRLMSG2: fcc ' '
fcc 'Run out '
fcc 'of Printer Quota at 2am in the morning ??? '
fcc 'No problem... A $5 bill and PAWS '
fcc 'can get you back up and printing '
fcc 'so you can make your early morning '
fcc 'deadline... '
fcb $fe
SCRLMSG3: fcc ' '
fcc 'Directions: Hit any key to Start '
fcc 'At the Prompt enter your student'
fcc ' ID number. The keys are as follows '
fcc 'A) Abort B) Backspace C) Clear '
fcc ' D) Done. Enter $5 bills when told '
fcc 'to do so and your Printer Quota '
fcc 'will be increased in $5 increments! '
fcc ' '
fcb $fe
SCRLMSG4: fcc ' '
fcc 'PAWS is a result of the Senior Design '
fcc 'Project Class for Electrical and '
fcc 'Computer Engineering at NC State... '
fcc 'ECE 480/481. '
fcc 'PAWS was built by Derek Creech '
fcc 'Sean Korb, Kent Voorhees and Ryan '
fcc 'Wigley... '
fcc ' '
fcb $fe
SCRLMSG5: fcc ' '
fcc 'N.C.S.U. WOLFPACK '
fcc ' Go!!! State!!! '
fcc ' '
fcb $fe
RESETLCD: fcb $a0
fcb $3f * data length = 8 bits; lines = 2; font = 1
fcb $a0
fcb $0e * display = on; cursor = on; cursor blink = off;
fcb $a0
fcb $01 * go to home position (upper left corner)
fcb $fe
CLEARLCD: fcb $a0
fcb $01 * go to home position (upper left corner)
fcb $a0
fcb $80 * go to home position (upper left corner)
fcb $fe
BACKLCD: fcb $a0
fcb $10 * back one space
fcb $20 * space overwrite
fcb $a0 * back up one again
fcb $10
fcb $fe
MSG1: fcc 'Enter ID Number '
fcb $a0
fcb $c0
fcc '> '
fcb $fe
IDNUM: fcc 'ID# '
fcb $fe
TROUBLE1: fcc 'Check PAWS host '
fcb $a0
fcb $c0
fcc 'and our cable...'
fcb $fe
TROUBLE2: fcc 'PAWS communicati'
fcb $a0
fcb $c0
fcc 'on is down... '
fcb $fe
FOUND: fcb $a0
fcb $c0
fcc 'account verified'
fcb $fe
NOTFOUND: fcb $a0
fcb $c0
fcc 'Failed lookup!!!'
fcb $fe
MSGQUO1: fcc 'Quota='
fcb $fe
MSGQUO2: fcb $a0
fcb $c0
fcc 'Insert $5 bills '
fcb $fe
MSGTIME: fcc 'Need more time ?'
fcb $a0
fcb $c0
fcc ' D=Yes / A=No '
fcb $fe
MSGACCPT: fcc 'Bill accepted. '
fcb $a0
fcb $c0
fcc 'Quota up $5.00 '
fcb $fe
SERBILLFAIL1:
fcc 'PAWS failed ??? '
fcb $a0
fcb $c0
fcc 'Check quota !!! '
fcb $fe
SERBILLFAIL2:
fcc 'Go to WOLF COPY '
fcb $a0
fcb $c0
fcc 'if so, clear up'
fcb $fe
MSG5: fcc 'Thank you! :-)'
fcb $a0
fcb $c0
fcc 'Come again soon.'
fcb $fe
LOOKUP: fcc 'll' *** control code
fcb $0d *** carige return
fcb $fe
INCREASE: fcc 'ii' *** control code
fcb $0d *** carrige return
fcb $fe
fcb $fe