* Filename      : LAB7A.ASM
* Programmer    : Michael Hattermann
* Date          : November 5, 2001 Fall 2001
* Version       : 1.0
* Description   : This program will record key pressed from an infrared
*                   remote control and record them.  It will then compare
*                   new key pressed to the record, if the match, data will
*                   be displayed on the LCD panel.
*
************************************************************
* Constant Definitions
************************************************************
*
BASE        EQU     $1000           ; Base address of register stack
BAUD        EQU     $2B             ; Baud-rate control register to set the baud rate
SCCR1       EQU     $2C             ; Serial Communication Control Register-1
SCCR2       EQU     $2D             ; Serial Communication Control Register-2
SCSR        EQU     $2E             ; Serial Communication Status Register
SCDR        EQU     $2F             ; Serial Communication Data Register

TMSK1       EQU     $22             ; Timer Interrupt Mask-1
TMSK2       EQU     $24             ; Timer Interrupt Mask-2
TFLG1       EQU     $23             ; Timer Interrupt Flag-1
TCTL1       EQU     $20             ; Timer Control Register-1
TCTL2       EQU     $21             ; Timer Control Register-2
TOC2        EQU     $18             ; Output Compare-2
TCNT        EQU     $0E             ; Timer Count
TIC3        EQU     $14             ; Timer Input Capture-3

OC2PVECT    EQU     $00DC           ; Timer output compare 2 interrupt pseudovector
IC3PVECT    EQU     $00E2           ; Timer input capture 3 interrupt pseudovector
SCIPVECT    EQU     $00C4           ; SCI system interrupt pseudovector

VARSTART    EQU     $4001           ; start of ram - variables/constants
PROGSTART   EQU     $6000           ; start of program
STKSTART    EQU     $0041           ; start of stack

INP1        EQU     $2000           ; address of input port
OUT1        EQU     $2000           ; address of output port 1
OUT2        EQU     $3000           ; address of output port 2

LCDCMD      EQU     $B5F0           ; LCD Command register
LCDDATA     EQU     $B5F1           ; LCD Data register

EOS         EQU     $04             ; User-defined End Of String (EOS) character
CR          EQU     $0D             ; Carriage Return Character
LF          EQU     $0A             ; Line Feed Character
ESC         EQU     $1B             ; ESC character

BIT0        EQU     %00000001       ; bit 0
INV0        EQU     %11111110       ; inverse of bit 0
BIT5        EQU     %00100000       ; bit 5
INV5        EQU     %11011111       ; inverse of bit 5
BIT6        EQU     %01000000       ; bit 6
INV6        EQU     %10111111       ; inverse of bit 6
BIT06       EQU     %01000001       ; bits 0,6
INV06       EQU     %10111110       ; inverse of bits 0,6

ENDDELAY    EQU     20000           ; 10 ms delay to timeout
NOMATCH     EQU     $EE             ; no match flag
*
************************************************************
* Interrupt Pseudovector Declarations
************************************************************
*
            ORG     OC2PVECT        ; OC2
            JMP     OC2_ISR         ;

            ORG     IC3PVECT        ; IC3
            JMP     IC3_ISR         ;

            ORG     SCIPVECT        ; SCI
            JMP     SCI_ISR         ;
*
************************************************************
* Constant Declarations
************************************************************
*
            ORG     VARSTART
MAINMENU    FCB     ESC,$5B,$32,$4A,ESC,$5B,$3B,$48
            FCC     @Select option:@
            FCB     CR,LF
            FCB     CR,LF
            FCC     @1) Record keys@
            FCB     CR,LF
            FCC     @2) Recognize keys@
            FCB     CR,LF
            FCC     @3) Quit@
NEWLINE     FCB     CR,LF
            FCB     EOS

RECORDMENU  FCB     ESC,$5B,$32,$4A,ESC,$5B,$3B,$48
            FCC     @Select key to record (ESC to quit to main menu):@
            FCB     CR,LF
            FCB     CR,LF
            FCC     @0) Record key 0@
            FCB     CR,LF
            FCC     @1) Record key 1@
            FCB     CR,LF
            FCC     @2) Record key 2@
            FCB     CR,LF
            FCC     @3) Record key 3@
            FCB     CR,LF
            FCC     @4) Record key 4@
            FCB     CR,LF
            FCC     @5) Record key 5@
            FCB     CR,LF
            FCC     @6) Record key 6@
            FCB     CR,LF
            FCC     @7) Record key 7@
            FCB     CR,LF
            FCC     @8) Record key 8@
            FCB     CR,LF
            FCC     @9) Record key 9@
            FCB     CR,LF
            FCB     EOS

RECORDSTR1  FCB     ESC,$5B,$32,$4A,ESC,$5B,$3B,$48
            FCC     @Press any key to begin recording key @
            FCB     EOS

RECORDSTR2  FCC     @ from remote.@
            FCB     CR,LF
            FCB     EOS

RECORDSTR3  FCB     CR,LF
            FCC     @Recording...@
            FCB     CR,LF
            FCB     EOS

RECORDSTR4  FCB     CR,LF
            FCB     CR,LF
            FCC     @Successfully recorded key @
            FCB     EOS

RECORDSTR5  FCC     @. Press any key to continue.@
            FCB     EOS

RECOGSTR1   FCB     ESC,$5B,$32,$4A,ESC,$5B,$3B,$48
            FCC     @Awaiting input from remote. Press @
            FCC     @any key to return to main menu.@
            FCB     CR,LF
            FCB     EOS

LCDSTR0     FCC     @0: Lights@
            FCB     EOS

LCDSTR1     FCC     @1: Toaster Oven@
            FCB     EOS

LCDSTR2     FCC     @2: Stove@
            FCB     EOS

LCDSTR3     FCC     @3: Microwave@
            FCB     EOS

LCDSTR4     FCC     @4: Computer@
            FCB     EOS

LCDSTR5     FCC     @5: Coffee Maker@
            FCB     EOS

LCDSTR6     FCC     @6: Dish Washer@
            FCB     EOS

LCDSTR7     FCC     @7: Blender@
            FCB     EOS

LCDSTR8     FCC     @8: A/C@
            FCB     EOS

LCDSTR9     FCC     @9: Toaster@
            FCB     EOS

SAVEJMPTBL  FDB     KEY0SIZ,KEY1SIZ,KEY2SIZ,KEY3SIZ
            FDB     KEY4SIZ,KEY5SIZ,KEY6SIZ,KEY7SIZ
            FDB     KEY8SIZ,KEY9SIZ

LCDPTBL     FDB     LCDSTR0,LCDSTR1,LCDSTR2,LCDSTR3
            FDB     LCDSTR4,LCDSTR5,LCDSTR6,LCDSTR7
            FDB     LCDSTR8,LCDSTR9

YESSTR      FCC     @MATCH KEY @
            FCB     EOS

*
************************************************************
* Variable Declarations
************************************************************
*
KEY0SIZ     RMB     1                   ; # of pulse widths in key 0
KEYTBL0     RMB     $200                ; Saved key 0
KEY1SIZ     RMB     1                   ; # of pulse widths in key 1
KEYTBL1     RMB     $200                ; Saved key 1
KEY2SIZ     RMB     1                   ; # of pulse widths in key 2
KEYTBL2     RMB     $200                ; Saved key 2
KEY3SIZ     RMB     1                   ; # of pulse widths in key 3
KEYTBL3     RMB     $200                ; Saved key 3
KEY4SIZ     RMB     1                   ; # of pulse widths in key 4
KEYTBL4     RMB     $200                ; Saved key 4
KEY5SIZ     RMB     1                   ; # of pulse widths in key 5
KEYTBL5     RMB     $200                ; Saved key 5
KEY6SIZ     RMB     1                   ; # of pulse widths in key 6
KEYTBL6     RMB     $200                ; Saved key 6
KEY7SIZ     RMB     1                   ; # of pulse widths in key 7
KEYTBL7     RMB     $200                ; Saved key 7
KEY8SIZ     RMB     1                   ; # of pulse widths in key 8
KEYTBL8     RMB     $200                ; Saved key 8
KEY9SIZ     RMB     1                   ; # of pulse widths in key 9
KEYTBL9     RMB     $200                ; Saved key 9
CMPKEYSIZ   RMB     1                   ;
CMPKEY      RMB     $200                ; Saved key for compare

DONEREC     RMB     1                   ; flag to indicate done recording
ESCFLAG     RMB     1                   ; flag to indicate quit matching

TEMPSIZ     RMB     1                   ; Number of pulses recorded
TBLADDR     RMB     2                   ; Current address to store data

LOOPCNT     RMB     1
*
************************************************************************
*                       MAIN PROGRAM
* Description: This program prompts the user for a function - record or
*               recognize, then jumps to the approprite routine
* Calls: INITSCI,INCHAR,OUTSTR,RECORDKEY,RECOGKEY
************************************************************************
*
            ORG     PROGSTART
MAIN        LDS     #STKSTART           ; initialize stack pointer
            JSR     INITSCI             ; init SCI system
            JSR     INITLCD             ; init the LCD
            CLI                         ; turn on all interrupts

MAIN1       LDX     #MAINMENU           ; print the main menu
            JSR     OUTSTR              ;
MAIN2       JSR     INCHAR              ; wait for user to enter choice
            CMPB    #$31                ; do we need to record keys?
            BNE     MAIN3               ; no, move on
            JSR     RECORDKEY           ; yes go record keys
            BRA     MAIN1               ; continue
MAIN3       CMPB    #$32                ; do we need to recognize keys?
            BNE     MAIN4               ; no, move on
            JSR     RECOGKEY            ; yes go record keys
            BRA     MAIN1               ; continue
MAIN4       CMPB    #$33                ; do we need to quit?
            BEQ     MAIN5               ; yes so get out
            BRA     MAIN2               ; didnt recognize character, reinput
MAIN5
END         SWI                         ; return to buffalo
*
************************************************************************
*                       SUBROUTINE - INITSCI
* Description: This subroutine initializes the BAUD rate to 9600 and
*              sets up the SCI port for 1 start bit, 8 data bits and
*              1 stop bit.  It also enables the transmitter and receiver.
*              Effected registers are BAUD, SCCR1, and SCCR2.
* Input         : None.
* Output        : Initializes SCI.
* Destroys      : None.
* Calls         : None.
************************************************************************
*
INITSCI     PSHA                    ; save reg A
            PSHX                    ; save reg X
            LDX     #BASE           ; load reg stack address
            LDAA    #$30            ; SCP1:SCP0=ll  SCR2:SCR1:SCR0=011
            STAA    BAUD,X          ; set baud rate to 9600
            LDAA    #$00            ; 1 start/stop bit, 8 data bits ;
            STAA    SCCR1,X         ;   no wakeup
            LDAA    #%00001100      ; enable Tx and Rx;
            STAA    SCCR2,X         ; all interrupts off
            PULX                    ; restore reg X
            PULA                    ; restore reg A
            RTS                     ; Return from subtoutine
*
************************************************************************
*                       SUBROUTINE -  OUTCHAR
* Description: Outputs the character in register B to the screen after
*              checking if the Transmitter Data Register is Empty
* Input         : Data to be transmitted in register B.
* Output        : Transmit the data.
* Destroys      : None.
* Calls         : None.
************************************************************************
*
OUTCHAR     PSHA                    ; save reg A
            PSHX                    ; save reg X
            LDX     #BASE           ; load reg stack address
OUTCHAR1    LDAA    SCSR,X          ; check status reg (TDRE in bit 7)
            ANDA    #$80            ; check if transmit buffer is empty
            BEQ     OUTCHAR1        ; Wait until empty

            STAB    SCDR,X          ; output character
            PULX                    ; restore reg X
            PULA                    ; restore reg A
            RTS                     ; Return from subtoutine
*
************************************************************************
*                       SUBROUTINE -  OUTSTR
* Description: Outputs the string terminated by EOS. The starting location
*              of the string is pointed by X register. Calls the OutChar
*              subroutine to display a character on the screen and
*              exit once EOS has been reached.
* Input         : Starting location of the string to be transmitted
*               : (passed in X register)
* Output        : Prints the string.
* Destroys      : Contents of X register.
* Calls         : OUTCHAR.
************************************************************************
*
OUTSTR      PSHB
OUTSTR1     LDAB    0,X             ; Get a character (put in A register)
            CMPB    #EOS            ; Check if it's EOS
            BEQ     OUTSTR2         ; Branch to Done if it's EOS
            BSR     OUTCHAR         ; Print the character by calling OutChar
            INX
            BRA     OUTSTR1
OUTSTR2     PULB
            RTS                     ; Return from subtoutine
*
************************************************************************
*                SUBROUTINE  -  INCHAR
* Description: Waits for a character to be pressed
* Input         : None
* Output        : Character pressed in reg. B
* Destroys      : B.
* Calls         : None
************************************************************************
*
INCHAR      PSHX                    ; save reg X
            LDX     #BASE           ; load reg stack address
INCHAR1     LDAB    SCSR,X          ; check status reg (RDRF in bit 5)
            ANDB    #$20            ; check if receive buffer is empty
            BEQ     INCHAR1         ; Wait until not empty

            LDAB    SCDR,X          ; input character
            PULX                    ; restore reg X
            RTS                     ; Return from subroutine
*
************************************************************************
*                SUBROUTINE  -  RECORDKEY
* Description: Prints record key menu - when key is selected, it sets up
*               variable for the correct key to be recorded and turns on
*               interrupts - quit from this menu returns to main menu
* Input         : None
* Output        : None
* Destroys      : None
* Calls         : None
************************************************************************
*
RECORDKEY   PSHX                    ; save reg X
            PSHB                    ; save reg B
RECORDKEY1  LDX     #RECORDMENU     ; print the record menu
            JSR     OUTSTR          ;
RECORDKEY2  JSR     INCHAR          ; get the users choice
            CMPB    #$30            ; was the choice valid?
            BLT     RECORDKEY3      ; no, so move on
            CMPB    #$39            ; was the choice valid?
            BGT     RECORDKEY3      ; no, so move on
            JSR     RECORD          ; go record the key
            BRA     RECORDKEY1      ; do it again

RECORDKEY3  CMPB    #ESC            ; did we want to quit?
            BNE     RECORDKEY2      ; no, so continue
            PULB                    ; restore reg B
            PULX                    ; restore reg X
            RTS                     ; return to caller
*
************************************************************************
*                SUBROUTINE  -  RECORD
* Description: Prints prompt to begin recording.  Sets up variables to
*               record key pressed.  Records the key press.  Prints
*               confirmation message.  Returns to Record menu.
* Input         : B - ASCII of key pressed
* Output        : None
* Destroys      : B
* Calls         : None
************************************************************************
*
RECORD      PSHX                    ; save reg X
            PSHB                    ; save reg B

*           Print prompt to begin recording
            LDX     #RECORDSTR1     ; print the press key message
            JSR     OUTSTR          ;
            JSR     OUTCHAR         ; print the key we are recording
            LDX     #RECORDSTR2     ; print rest of prompt
            JSR     OUTSTR          ;
            JSR     INCHAR          ; wait for key press
            LDX     #RECORDSTR3     ; print recording message
            JSR     OUTSTR          ;

*           Calc address of table to store data
            PULB                    ; restore key pressed
            PSHB                    ; save key pressed
            SUBB    #$30            ; convert from ASCII
            LSLB                    ; scale to double bytes
            LDX     #SAVEJMPTBL     ; get address of jump table
            ABX                     ; calc address of our new table
            LDX     0,X             ; get address of table

*           Record the key
            JSR     CAPTUREKEY      ; save the new key

*           Print success message
            LDX     #RECORDSTR4     ; print confirmation
            JSR     OUTSTR          ;
            PULB                    ; restore key pressed
            JSR     OUTCHAR         ; print the key we are recording
            LDX     #RECORDSTR5     ; print rest of confirmation
            JSR     OUTSTR          ;
            PSHB                    ; save key pressed
            JSR     INCHAR          ; wait for key press

            PULB                    ; restore reg B
            PULX                    ; restore reg X
            RTS                     ; return to caller
*
************************************************************************
*                SUBROUTINE  -  RECOGKEY
* Description: Prints prompt to user.  Inputs keys and displays the data
*               on the LCD screen.
* Input         : None
* Output        : None
* Destroys      : None
* Calls         : None
************************************************************************
*
RECOGKEY    PSHX                        ; save reg X
            PSHB                        ; save reg B

            LDX     #RECOGSTR1          ; print awaiting message
            JSR     OUTSTR              ;

            CLR     ESCFLAG             ; clear the escape flag

*           Initialize SCI interrupts
            LDX     #BASE               ;
            LDAB    SCCR2,X             ; turn on SCI interrupts
            ORAB    #BIT5,X             ;
            STAB    SCCR2,X             ;

RECOGKEY1   LDX     #CMPKEYSIZ          ; load address of compare table
            JSR     CAPTUREKEY          ; go get a key press

            JSR     FINDMATCH           ; go try and find a match
            CMPB    #NOMATCH            ; did we get a match?
            BEQ     RECOGKEY2

            LSLB                        ; scale to double bytes
            LDX     #LCDPTBL            ; get address of LCD print table
            ABX                         ; calc address of string to print
            LDX     0,X                 ; get address of string

            JSR     LCDOUTSTR           ; print LCD string

RECOGKEY2   TST     ESCFLAG             ; are we done yet?
            BEQ     RECOGKEY1           ; no, keep going

*           Turn off SCI interrupts
            LDX     #BASE               ;
            LDAB    SCCR2,X             ; turn off SCI interrupts
            ANDB    #INV5               ;
            STAB    SCCR2,X             ;

            PULB                        ; restore reg B
            PULX                        ; restore reg X
            RTS                         ; return to caller
*
************************************************************************
*                SUBROUTINE  -  FINDMATCH
* Description: Compares the compare key to all recorded keys.  if there
*               is a match, it returns the match key # in reg B
* Input         : None
* Output        : Matched key number in reg B
* Destroys      : None
* Calls         : None
************************************************************************
*
FINDMATCH   PSHA                        ; save reg A

            CLRA                        ; clear counter

FINDMATCH1  TAB                         ; load in table to compare
            JSR     COMPAREKEY          ; compare the current key
            CMPB    #NOMATCH            ; did we get a match?
            BNE     FINDMATCHX          ; yes, get out

            INCA                        ; move to next table
            CMPA    #10                 ; are we done?
            BLT     FINDMATCH1          ; no, continue

FINDMATCHX  PULA                        ; restore reg A
            RTS                         ; return to caller

*
************************************************************************
*                SUBROUTINE  -  COMPAREKEY
* Description: Compares the key number in reg B to the compare. Returns
*               key number in reg B if match otherwise returns no match
*               flag.
* Input         : None
* Output        : Match flag in reg B
* Destroys      : None
* Calls         : None
************************************************************************
*
COMPAREKEY  PSHY                    ; save reg Y
            PSHX                    ; save reg X
            PSHA                    ; save reg A
            PSHB                    ; save reg B

*           Find address of table to compare to
            LSLB                    ; scale to double bytes
            LDX     #SAVEJMPTBL     ; get address of jump table
            ABX                     ; calc address of our new table
            LDX     0,X             ; get address of table
            LDY     #CMPKEYSIZ      ; get compare key table

*           Compare table sizes
            LDAA    0,X             ; get first table size
            LDAB    0,Y             ; get second table size
            CBA                     ; do we have the same number of entries
            BNE     CMPKEYNO        ; no, no match exit
            STAB    LOOPCNT         ; save loop count
            INX                     ; move to data table
            INY                     ; move to data table

CMPKEY1     LDD     0,Y             ; get compare pulse time
            CMPD    #100            ; if < 100, dont test it
            BHS     CMPKEY2         ; we need to check it
            LDD     0,X             ; get key pulse time
            CMPD    #100            ; is it < 100
            BLO     CMPKEY3         ; yes, skip check


CMPKEY2     LDD     0,X             ; get key pulse time
            LSRD                    ; calc 25%
            LSRD                    ;
            ADDD    0,X             ; this is 25% greater
            CPD     0,Y             ; is the compare less than this
            BLO     CMPKEYNO        ; no, get out

            LDD     0,X             ; get key pulse time
            LSRD                    ; calc 25%
            LSRD                    ;
            SUBD    0,X             ; this is 25% less
            COMA                    ;
            COMB                    ;
            ADDD    #1              ;
            CPD     0,Y             ; is the compare less than this
            BHI     CMPKEYNO        ; no, get out

*           This value matched, go to next one
CMPKEY3     INX                     ; increment key table pointer
            INX                     ;
            INY                     ; increment compare table pointer
            INY                     ;
            DEC     LOOPCNT         ; decrement loop cnt
            BNE     CMPKEY1         ; more to do, do it

*           We found a match, return success
            BRA     CMPKEYYES       ; return success


CMPKEYNO    PULB                    ; remove table num from stack
            LDAB    #NOMATCH        ; return no match flag
            BRA     CMPKEYX         ; continue exit...
CMPKEYYES   PULB                    ; restore reg B
CMPKEYX     PULA                    ; restore reg A
            PULX                    ; restore reg X
            PULY                    ; restore reg Y
            RTS                     ; return to caller
*
************************************************************************
*                SUBROUTINE  -  INITREC
* Description: Turns on interrupts.  Saves TCNT times to temp buffer.
*               Then converts into absolute times and save to key buffer
*               address passed in reg X
* Input         : X - Address of permanent buffer to save to
* Output        : None
* Destroys      : None
* Calls         : None
************************************************************************
*
INITREC     PSHB                    ; save reg B
            PSHX                    ; save reg X

            INX                     ; move to start of table
            STX     TBLADDR         ; save start address of table
            CLR     DONEREC         ; clear finished recording flag
            CLR     TEMPSIZ         ; clear index to temp table
            LDX     #BASE           ; load base address of register stack
            LDAB    #$03            ; enable triggering on any edge for IC3
            STAB    TCTL2,X         ;   all others disables
            BCLR    TFLG1,X INV0    ; clear IC3 interrupt flag
            BSET    TMSK1,X BIT0    ; turn on IC3,OC2 interrupts

            PULX                    ; restore reg X
            PULB                    ; restore reg B
            RTS                     ; return to caller
*
************************************************************************
*                SUBROUTINE  -  CAPTUREKEY
* Description: Captures a key and saves it to the table address in reg X
* Input         : X - Address of permanent buffer to save to
* Output        : None
* Destroys      : None
* Calls         : None
************************************************************************
*
CAPTUREKEY  PSHA                    ; save reg A
            PSHB                    ; save reg B
            PSHX                    ; save reg X

*           Record the key
            JSR     INITREC         ; start saving the key
CAPTUREKEY1 TST     DONEREC         ; have we finished recording?
            BEQ     CAPTUREKEY1     ; no, keep waiting

*           Save size of new table
            LDAA    TEMPSIZ         ; get temp size
            DECA                    ; adjust
            STAA    0,X             ; save new size of the table
            INX

*           Convert key to absolute times
            STAA    LOOPCNT         ; init loop count
CAPTUREKEY2 LDD     2,X             ; get later time
            SUBD    0,X             ; calc absolute time
            STD     0,X             ; save absolute time
            INX                     ; increment table pointer
            INX                     ; increment table pointer
            DEC     LOOPCNT         ; increment loop counter
            BNE     CAPTUREKEY2     ; no, continue

            PULX                    ; restore reg X
            PULB                    ; restore reg B
            PULA                    ; restore reg A
            RTS                     ; return to caller
*
************************************************************************
*                SUBROUTINE  -  INITLCD
* Description: Initializes the LCD screen for output
* Input         : None
* Output        : None
* Destroys      : None
* Calls         : None
************************************************************************
*
INITLCD     PSHA                    ; save reg A

            LDAA    #$3C            ; set 2x40 Display
            STAA    LCDCMD
            JSR     DELAY
            LDAA    #$01            ; Clear & Home
            STAA    LCDCMD
            JSR     DELAY
            LDAA    #$0C            ; Display on
            STAA    LCDCMD
            JSR     DELAY
            LDAA    #$06            ; Cursor shift on
            STAA    LCDCMD
            LDAA    #$14            ; Shift right
            STAA    LCDCMD
            LDAA    #$02            ; Cursor to Home
            STAA    LCDCMD
            JSR     DELAY
            PULA                    ; restore reg A
            RTS
*
************************************************************************
*                SUBROUTINE  -  LCDOUTCHAR
* Description: Prints 1 character to LCD screen
* Input         : Character to print in reg B
* Output        : None
* Destroys      : None
* Calls         : None
************************************************************************
*
LCDOUTCHAR  PSHA                    ; save reg A
            LDAA    LCDCMD          ; get current address
            CMPA    #$10            ; at end of first row
            BNE     LCDOUT1         ; yes, so adjust address

            LDAA    #$C0            ; set correct address
            STAA    LCDCMD          ; make address fix
            JSR     DELAY1
LCDOUT1     STAB    LCDDATA         ; write data to lcd output port
            JSR     DELAY1
            PULA                    ; restore reg A
            RTS                     ; return to caller
*
************************************************************************
*                SUBROUTINE  -  LCDOUTSTR
* Description: Prints a string to LCD screen
* Input         : Address of string to print in reg X
* Output        : None
* Destroys      : None
* Calls         : None
************************************************************************
*
LCDOUTSTR   PSHB
            LDAB    #$01            ; clear display, cursor home
            STAB    LCDCMD          ;
            JSR     DELAY           ;
LCDOUTSTR1  LDAB    0,X             ; Get a character
            CMPB    #EOS            ; Check if it's EOS
            BEQ     LCDOUTSTR2      ; Branch to Done if it's EOS
            BSR     LCDOUTCHAR      ; Print the character
            INX
            BRA     LCDOUTSTR1
LCDOUTSTR2  PULB
            RTS                     ; Return from subtoutine
*
************************************************************************
*                SUBROUTINE  -  DELAY
* Description: Delay loop for LCD display
* Input         : None
* Output        : None
* Destroys      : None
* Calls         : None
************************************************************************
*
DELAY       PSHX                    ; save x
            LDX     #548            ; load count
DELAY1      DEX                     ; decriment x
            BNE     DELAY1          ; loop if not 0
            PULX                    ; restore x
            RTS
*
************************************************************************
*                SUBROUTINE  -  DELAY1
* Description: Delay loop for 40 us for LCD display
* Input         : None
* Output        : None
* Destroys      : None
* Calls         : None
************************************************************************
*
DELAY1      PSHX                    ; save x
            LDX     #11             ; load count
DELLP       DEX                     ; decriment x
            BNE     DELLP           ; loop if not 0
            PULX                    ; restore x
            RTS
*
************************************************************************
*                INTERRUPT SERVICE ROUTINE - OC2_ISR
* Description: Handles all OC2 interrupts - handles timing for end of
*               signal - then turns off IC3 interrupts and sets
*               completion flag
* Input         : None
* Output        : None
* Destroys      : TFLG1
* Calls         : None
************************************************************************
*
OC2_ISR     LDX     #BASE                   ; check for an illegal interrupt
            BRCLR   TFLG1,X BIT6 OC2DONE    ; illegal - get out

            BCLR    TMSK1,X BIT06           ; disable IC3,OC2 interrupts
            INC     DONEREC                 ; set flag to indicate we are done recording

            BCLR    TFLG1,X INV06           ; clear OC2,IC3 interrupt flags

OC2DONE     RTI                             ; return from interrupt
*
************************************************************************
*                INTERRUPT SERVICE ROUTINE - IC3_ISR
* Description: Handles all IC3 interrupts - handles recording of a key
*               from a remote.  Save key into table specified by CURRKEY
* Input         : None
* Output        : None
* Destroys      : TFLG1,KEYTBL
* Calls         : None
************************************************************************
*
IC3_ISR     LDX     #BASE                   ; check for an illegal interrupt
            BRCLR   TFLG1,X BIT0 IC3DONE    ; illegal - get out

            BCLR    TFLG1,X INV0            ; clear IC3 interrupt flag

            CLRA                            ; clear upper byte
            LDAB    TEMPSIZ                 ; get index into temp key table
            LSLB                            ; convert index to double bytes
            ADDD    TBLADDR                 ; calc address to store data
            XGDY                            ; save off address

            LDD     TIC3,X                  ; get the time of the last edge
            STD     0,Y                     ; save the last time

            ADDD    #ENDDELAY               ; calc new timeout time
            STD     TOC2,X                  ; save new timeout time
            BCLR    TFLG1,X INV6            ; clear OC2 interrupt flag
            BSET    TMSK1,X BIT6            ; turn on OC2 interrupts

            INC     TEMPSIZ                 ; increment pulse counter
            BVC     IC3DONE                 ; if we reached max, get out

            BCLR    TMSK1,X BIT06           ; disable IC3,OC2 interrupts
            INC     DONEREC                 ; set flag to indicate we are done recording

IC3DONE     RTI                             ; return from interrupt
*
************************************************************************
*                INTERRUPT SERVICE ROUTINE - SCI_ISR
* Description: Handles all SCI interrupts - Handles escape of program
* Input         : None
* Output        : None
* Destroys      : None
* Calls         : None
************************************************************************
*
SCI_ISR     LDX     #BASE               ; load base address of reg stack
            LDAA    SCSR,X              ; get SCI control reg
            ANDA    #BIT5               ; check if flag is set
            BEQ     SCIDONE             ; illegal interrupt - get out

            LDAA    SCDR,X              ; get input character - clear interrupt flag

SCIQUIT     LDAA    #1                  ; get out of program
            STAA    ESCFLAG             ;

SCIDONE     RTI
