******************************************************************************* ******************************************************************************* * 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