******************************************************************************
*                                                                            *
*                       6805R3 KEYBOARD ENCODER                              *
*                                                                            *
*       Modified from 6805U2 keyboard encoder.                               *
*                                                                            *
*       Features:                                                            *
*                                                                            *
*        Full ASCII parallel output                                          *
*               7 bits, generates all 128 codes                              *
*        Full ASCII serial output                                            *
*               7 bits, generates all 128 codes                              *
*        Control keys on separate keys:                                      *
*               shift,control,repeat,alpha lock                              *
*        Low parts count:                                                    *
*               MC6805R3, 1 capacitor, (12 pullup resistors)                 *
*        Negative edge keyboard strobe                                       *
*        2-Key rollover (N-key rollover with diodes)                         *
*        Easy P.C. board layout                                              *
*        Single 5 Volt supply operation                                      *
*                                                                            *
******************************************************************************
*
*       Important constants
*
NKEYS   equ     64      using an 8 by 8 matrix
row     equ     portb   keyboard row driver port
column  equ     portd   keyboard column inputs
data    equ     porta   encoder parallel output data lines
strobe  equ     7        porta bit7 = strobe
junk    equ     portc   multiple use I/O port
*
*       Bits of junk I/O port C
*
ctrl    equ     7       control key
funct   equ     6       function: `1' selects keyboard encoder
serout  equ     5       serial output bit
shift   equ     4       shift key
repeat  equ     3       repeat key
lock    equ     2       alpha lock (upper case only)
*  baud rate select by bits `1' &`0'
*
*        C1  C0
*         0   0   300 baud
*         0   1  1200 baud
*         1   0  4800 baud
*         1   1  9600 baud
*
*       Character constants
*
BS      equ     $08     backspace (ctrl-H)
TAB     equ     $09     tab (ctrl-I)
ESC     equ     $1B     escape character (ctrl-[)
CAN     equ     $18     cancel (ctrl-X)
SP	equ	BL	ascii blank
RUB     equ     $7F     rubout
BREAK   equ     $FE     break key code
NOKEY   equ     $FF     invalid key code
STOP    equ     $13     (ctrl s)
GO      equ     $11     (ctrl q)
*
*       RAM variables
*
damper  equ     RAM     count register for debounce delay
coltmp  equ     RAM+1   saved column mask
*
*       kbd --- 6805 keyboard encoder
*
kbd
*
*       Setup I/O port (port a )
*
	clr     data            initialize data outputs
	lda     #$80            set strobe=1
	sta     data            .
	lda     #$FF            .
	sta     data+ddr        turn on data outputs (initially zero)
*
*       initialize keyboard matrix ports ( ports b & d )
*
	sta     row             next do the row drivers
	sta     row+ddr         all ones to begin with
	clr     column+ddr      establish kbd column input
*
	clr     junk+ddr        init option port
	lda     #$20            serout ddr
	sta     junk            .
	sta     junk+ddr        .
*
	ldx     #NKEYS-1        make it look like a scan just finished
	clra
	bra     next            skip to next key test
*
*       Main loop, check for any key down
*
scan_loop
	bit     column          this key down?
	bne     next            no, try next one
	bsr     debounce        see if it was a fluke
	bsr     debounce        more delay (total is about 5ms)
	bit     column          check it again
	bne     next            was just noise
	bsr     output          the real thing, send it out
next
	incx                    move index
	lsra                    move mask to next row
	bne     scan_loop       still more keys in this row
	lda     #%10000000      reinitialize row mask
	sec                     shift the zero to the next row
	ror     row
	cmpx    #NKEYS          have we checked all keys?
	bne     scan_loop       no, more keys this time around
	ldx     #$7F            move zero to first row again
	stx     row
	clrx                    reset key index
	bra     scan_loop       continue scanning
*
*       debounce --- Delay while keyboard bounces (approx 2.5ms)
*
debounce
	clr     damper
deb2
	inc     damper
	bne     deb2
	rts
*
*       output --- Send current key out on port A
*
*       Key code to output is in X.  A  has  the  current  column
*       that the key was found on.  Output will return with A and
*       X  unchanged  so that the main loop can continue scanning
*       where  it  left  off.   This  is   the   2-key   rollover
*       algorithm. The serial output routine is in the monitor.
*
output
	sta     coltmp          save current column
*
*       Interpret key code as per ASCII tables
*
	lda     down,x          pickup unshifted character
	cmp     #BREAK          break key ?
	bne     arnbk           no,continue
	bclr    serout,junk     set ser line =`0'
	jsr     delay250        wait 250 ms
wtbrk
	lda     coltmp          restore last column checked
	bit     column          wait till key is lifted
	beq     wtbrk           .
	bset    serout,junk     .
	rts                     & exit
arnbk
	brset   shift,junk,okdown check shift key
	lda     up,x            pickup shifted character
okdown
	cmp     #NOKEY          invalid key combination?
	bne     doit            will output some character
	lda     coltmp          restore column last checked
nkd
	bit     column          still down?
	beq     nkd             wait
	rts
*
*       check if alpha lock is on
*
doit
	brset   lock,junk,nomap clear means map lower to upper
	cmp     #'a             is character between a and z?
	blo     nomap
	cmp     #'z
	bhi     nomap
	sub     #$20            map to upper case
*
*       check if control key is pressed
*
nomap
	brset   ctrl,junk,sendit
	cmp     #'@             control codes only valid for `sticks' 4-7
	blo     sendit          can't control this character
	and     #$1F            clear high order bits and make it a control
sendit
	ora     #$80            set msb for strobe
	sta     data            update the data lines
	bclr    strobe,data     signal new data valid
	and     #$7f            clear strobe bit
	jsr     putc            send char serially
waitup
	brset   repeat,junk,norpt
	bsr     delay25         25ms delay
	bset    strobe,data     reset strobe
	bsr     delay25         25ms delay
	bclr    strobe,data     returns low
	lda     data            restore char
	and     #$7f            clear msb
	jsr     putc            send serially agian
norpt
	lda     coltmp          restore column mask
	bit     column          is the key still down?
	beq     waitup          yes, check other stuff again
	bset    strobe,data     signal key going up (data still valid)
	rts                     wazu
*
*       delay routines
*
*       delay250 --- 250 ms delay
delay250
	lda     #100
	bra     d50more
*       delay25 --- 25ms delay
delay25
	lda     #10             20*2.5=50
d50more
	bsr     debounce        delay 2.5ms
	deca
	bne     d50more
	rts
*
*
*       Keyboard encoder mapping tables.  Converts the matrix
*       position of the key to whatever you like.  In this case,
*       the mapping is to good ol' ASCII.
*
*       down --- The unshifted characters
down
 fcb     TAB,    '1,     '2,     '3,     '4,     '5,     '6,     '7
 fcb     ESC,    'q,     'w,     'e,     'r,     't,     'y,     'u
 fcb     CAN,    'a,     's,     'd,     'f,     'g,     'h,     'j
 fcb     SP,     'z,     'x,     'c,     'v,     'b,     'n,     'm
 fcb     '8,     '9,     '0,     '-,     '^,     '\,     '_,     STOP
 fcb     'i,     'o,     'p,     '@,     '[,     '],     BS,     GO
 fcb     'k,     'l,     ';,     ':,     RUB,    CR,     NOKEY,  NOKEY
 fcb     ',,     '.,     '/,     SP,     NOKEY,  LF,     NOKEY,  BREAK
*
*       up --- The corresponding shifted characters
up
 fcb     TAB,    '!,     '",     '#,     '$,     '%,     '&,     ''
 fcb     ESC,    'Q,     'W,     'E,     'R,     'T,     'Y,     'U
 fcb     CAN,    'A,     'S,     'D,     'F,     'G,     'H,     'J
 fcb     SP,     'Z,     'X,     'C,     'V,     'B,     'N,     'M
 fcb     '(,     '),     '0,     '=,     '~,     '|,     RUB,    STOP
 fcb     'I,     'O,     'P,     '`,     '{,     '},     BS,     GO
 fcb     'K,     'L,     '+,     '*,     RUB,    CR,     NOKEY,  NOKEY
 fcb     '<,     '>,     '?,     SP,     NOKEY,  LF,     NOKEY,  BREAK
*
*       end of keyboard encoder
*
******************************************************************************
