;------------------------------------------------------
;   THIS IS AN EXAMPLE FOR THE TMS370 MICROCONTROLLER
; FAMILY.  IT BEGINS ON PAGE 13-29 OF THE 1988 TMS370
; FAMILY DATA MANUAL FROM TEXAS INSTRUMENTS, AND
; AFTER ONLY FORMAT MODIFICATIONS,
; IT IS PASSED ON AS AN EXAMPLE, FREE OF CHARGE,
; BY UNIVERSAL CROSS-ASSEMBLERS.
;
         CPU     "TMS370.TBL"     ; CPU TABLE
         HOF     "INT8"           ; HEX OUTPUT FORMAT
;
;   The TMS370 table provided with the assembler is for
; a TMS370CX50 operating in single-chip mode, with a
; register file space of 0000H to 00FFh, a peripheral
; file of 1000h to 10BFh and a Program ROM of 7000h
; to 7FFFh.  The table may be configured for any
; specific controller and mode by changing the file
; ranges in TMS370.TBL
;
;   The assembler with the supplied TMS370 table, does
; not implicitly recognize register (Rnn) or peripheral
; (Pnn) labels.  These should be defined at the
; beginning of the source file, using their real
; address values, as shown in the following example.
;
;   The assembler constructed instructions CMPBIT,
; JBIT0, JBIT1, SBIT0, and SBIT1 are not supported.
; The corresponding TMS370 instructions
; should be used to replace these, as explained in the
; 1988 TMS370 Family Data Manual.
;
;------------------------------------------------------
;   This routine reads a 16 key keyboard, returns the
; hex digit of the key and debounces the key to avoid
; noise.  A 'valid key' flag is set when a new key is
; found.
;                      AFTER     AFTER
; REGISTER  BEFORE    NO KEY    NEW KEY  FUNCTION
; --------  ------    ------    -------  --------
;     A       XX         0       COLUMN  Temporary
;     B       XX         0         ROW   Temporary
;    R2       XX        16        KEY #  Temp store for Key value
;    R3     OLD KEY    0FFh       KEY #  Hold key pressed now
;    R4    DEBOUNCED     0          0    Debounce counter, old key
;                                        or new
;    R5     GENERAL ?xxxxxxx0 ?xxxxxxx1  One bit of register is 1
;             BITS                       if new key
;
        ORG     7000H
R2:     EQU     0002H
R3:     EQU     0003H
R4:     EQU     0004H
R5:     EQU     0005H
FLAG:   EQU     R2           ;"swap has been made" flag
DDIR:   EQU     102FH        ;Port D data direction register
DDATA:  EQU     102EH        ;Port D data register
                             ;THESE ASSIGNMENTS NEED TO BE
                             ;DONE IN THE MAIN INITIALIZATION
                             ;
START:  MOV     #00,DDATA    ;clear these registers
        MOV     #0,R5        ;clear register that say key found
        MOV     #0F0h,DDIR   ;set data direction register 4
                             ;output,
                             ;4 input
                             ;THIS IS THE BEGINNING OF THE
                             ;KEYBOARD SCAN ROUTINE
                             ;
GETKEY: MOV     #8,B         ;initialize row pointer
        CLR     R2           ;
LOOP:   RLC     B            ;select next row
        JC      NOKEY        ;last row? if so no key was found.
        ADD     #4,R2        ;add number of keys/row to key
                             ;accumulator
        MOV     B,DDATA      ;activate row
        MOV     DDATA,A      ;read columns
        MOV     #0,DDATA     ;clear row
        AND     #0Fh,A       ;isolate column data
        JZ      LOOP         ;if no keys found then check next
                             ;row
KEYLSB: DEC     R2           ;decrement column offset
        RRC     A            ;find column
        JNC     KEYLSB       ;if not column then, try again
                             ;
NEWKEY: CMP     R2,R3        ;is the new key the same as the old
                             ;key
        JEQ     DEBONS       ;if it is then debounce it
        MOV     R2,R3        ;brand new key, move it to current
                             ;key value
        MOV     #07,R4       ;set up debounce count, debounce 7
                             ;times
DEBONS: CMP     #2,R4        ;is the debounce count 1 or 0?
        JL      GOODKY       ;
        DJNZ    R4,GETKEY    ;if greater than 1 then debounce is
                             ;not finished, go read key again
GOODKY: BTJZ    #01,R4,NONEW ;if debounce count = 0 then key
                             ;was here last time
        DEC     R4           ;if it was one this is a new valid
                             ;key, make old key
        OR      #1,R5        ;set new key flag in BIT register,
                             ;the
        RTS                  ;found new key so return to main
                             ;calling routine uses this flag
NOKEY:  MOV     #0FFh,R3     ;no key was found, set key value to
                             ;unique
                             ;value
NONEW:  RTS                  ;if jumped to NONEW it is still the
                             ;same key
                             ;held down do nothing
        END
