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