Routines to light LED display and checking for a key pressed by multiplexing the seven segment LED and checking if a key is pressed. Must be called in a loop, since the lighting is only for a short time.

This complex looking circuit is the magic that makes the LED Display and keyboard work.
Actually this is made up of two circuits: the multiplexed LED display and the keyboard matrix.
The multiplexed LED display

By multiplexing the lighting of the seven segment LED displays not much special hardware is required to have a hex keypad and 6 digit serviced.
All LED displays have the segment inputs connected to each other and Port A PA0-PA6 as output are connected to the led segments a-g, PA0 = a .. PA6 = g.
The 74145 outputs O4..)9 are connected to the cathodes of the corresponding LED display.
So by setting the PB1..PB4 inputs of the 74145 one LED display is lighted, the others are off. By lighting this for a small delay and then stepping to the next display all LEDs are lighted after each other. If this is done fast enough the slow human eyes will not see this as a flickering light.
This is what is happening in the SCAND(1) routine.


Reading the keyboard matrix

The keyboard matrix is also read out by multiplexing rows and columns checking for a short circuit if a key is pressed, via
PA0..6 as inputs and the outputs of the 74145 00-03.
By selecting row 0 to 3 (output 00 to 03 of the 74145) and reading PA0 to PA6 a pressed key is detected.
In the GETKEY routine a key is detected this way, debounced and converted to a key number 00.14.
PB1-4 to 74145 decoder
The 74145 serves the multiplexing. From the RRIOT Port B PB1 .. PB4 to A..D inputs decodes to 10 outputs 00..09.
00 – 03 Keyboard KB Row 0-3
04 – O9 outputs switch LED display 1..6 on/off one by one.
Also available on the Application connector!
Part of the keypad is the TTY/KB switch, connected via Application connector 21-V = PA0 to O3 KB Row 3 connected via switch/jumper
1030 1EFE ;
1031 1EFE ; SUB TO DETERMINE IF KEY IS
1032 1EFE ; DEPRESSED OR CONDITION OF SSW
1033 1EFE ; KEY NOT DEP OR TTY MODE A=0
1034 1EFE ; KEY DEP OR KB MODE A NOT ZERO
1035 1EFE ;
1036 1EFE ;
1037 1EFE A0 03 AK LDY #$03 ; 3 ROWS
1038 1F00 A2 01 LDX #$01 ; DIGIT 0
1039 1F02 ;
1040 1F02 A9 FF ONEKEY LDA #$FF
1041 1F04 8E 42 17 AK1 STX SBD ; OUTPUT DIGIT
1042 1F07 E8 INX ; GET NEXT DIGIT
1043 1F08 E8 INX
1044 1F09 2D 40 17 AND SAD ; INPUT SEGMENTS
1045 1F0C 88 DEY
1046 1F0D D0 F5 BNE AK1
1047 1F0F
1048 1F0F A0 07 LDY #$07
1049 1F11 8C 42 17 STY SBD
1050 1F14 ;
1051 1F14 09 80 ORA #$80
1052 1F16 49 FF EOR #$FF
1053 1F18 60 RTS
What is happening here?
- Three rows, start with first digit 0 (1037-1040)
- Select digit by setting 74145 to O(X) via PB1-4 (1041)
- Check if key pressed, A <> 0 (1044)
- next row until all rows done (1045-1046
- restore default PB1 and PB2 1, PB3, PB4 0: Os low
- return
A=0 if key not depressed or TTY mode
A<>0 if key depressed or KB mod
SCAND
show digits for a short time form current cell address and contents
1054 1F19 ;
1055 1F19 ; SUB OUTPUT TO 7-SEGMENT DISPLAY **
1056 1F19 ;
1057 1F19 A0 00 SCAND LDY #$00 ; GET DATA SPECIFIED
1058 1F1B B1 FA LDA (POINTL),Y ; BY POINT
1059 1F1D 85 F9 STA INH ; SET UP DISPLAY BUFFER
1060 1F1F A9 7F LDA #$7F ; CHANGE SEG
1061 1F21 8D 41 17 STA PADD ; TO OUTPUT
1062 1F24 ;
1063 1F24 A2 09 LDX #$09 ; INIT DIGIT NUMBER
1064 1F26 A0 03 LDY #$03 ; OUTPUT 3 BYTES
1065 1F28 ;
1066 1F28 B9 F8 00 SCAND1 LDA INL,Y ; GET BYTE
1067 1F2B 4A LSR A ; GET MSD
1068 1F2C 4A LSR A
1069 1F2D 4A LSR A
1070 1F2E 4A LSR A
1071 1F2F 20 48 1F JSR CONVD ; OUTPUT CHAR
1072 1F32 B9 F8 00 LDA INL,Y ; GET BYTE AGAIN
1073 1F35 29 0F AND #$0F ; GET LSD
1074 1F37 20 48 1F JSR CONVD ; OUTPUT CHAR
1075 1F3A 88 DEY ; SET UP FOR NEXT BYTE
1076 1F3B D0 EB BNE SCAND1
1077 1F3D 8E 42 17 STX SBD ; ALL DIGITS OFF
1078 1F40 A9 00 LDA #$00 ; CHANGE SEGMENT
1079 1F42 8D 41 17 STA PADD ; TO INPUTS
1080 1F45 4C FE 1E JMP AK ; GET ANY KEY
SCAND display four digits of address and two digits of content.
3 bytes from F9..FA are converted to hex on the six digits.
What is happening here?
- load current cell FA, FB to display buffer INH (1057..1058)
- X = 9 is selection of digit number PB1..PB4 (04..09 of 74145)
- Y = 3, number of bytes
- load low part of byte (1066..1070)
- display via CONVD (1071)
- load high part of bye
- display via CONVD (1074)
- do next byte (1075..1076)
- set all displays off PB1..PB4= 0 (1077)
- PA0..PA6 to inputs (1078..1079)
- return via AK (1080)
CONVD
Lights segment of current select digit for a short time.
Segments output via PA0..PA6.
Hex to segment conversion via TABLE lookup
Digit value in Y
X is digit number in PB1..PB4 format
1081 1F48 ;
1082 1F48 ; CONVERT AND DISPLAY HEX
1083 1F48 ; USED BY SCAND ONLY
1084 1F48 ;
1085 1F48 84 FC CONVD STY TEMP ; SAVE Y
1086 1F4A A8 TAY ; USE CHAR AS INDEX
1087 1F4B B9 E7 1F LDA TABLE,Y ; LOOKUP CONVERSION
1088 1F4E A0 00 LDY #$00 ; TURN OFF SEGMENTS
1089 1F50 8C 40 17 STY SAD
1090 1F53 8E 42 17 STX SBD ; OUTPUT DIGIT ENABLE
1091 1F56 8D 40 17 STA SAD ; OUT PUT SEGMENTS
1092 1F59
1093 1F59 A0 7F LDY #$7F ; DELAY 500 CYCLES APPROX.
1094 1F5B 88 CONVD1 DEY
1095 1F5C D0 FD BNE CONVD1
1096 1F5E ;
1097 1F5E E8 INX ; GET NEXT DIGIT NUM
1098 1F5F E8 INX ; ADD 2
1099 1F60 A4 FC LDY TEMP ; RESTORE Y
1100 1F62 60 RTS
What is happening here?
- convert hex to segment via TABLE lookup (1086 .. 1087)
- turn off all segments PA0..PA6 (1088..1089)
- enable digit via SBD = X (1090)
- light segment via SAD = A, keep PA7 to 1 (1091)
- delay some time (1093..1095
- X = next display 2 hex per hex byte (1097)
[/code]
GETKEY
Get key pressed:
– Key pressed: A is key number
– No key: A = 15
Key values are:
0..9 = $00 ..$09
AD = $10 address mode
DA = $11 data mode
+ = $12 step
GO = $13 GO execute
PC = $14 PC mode
1108 1F6A ;
1109 1F6A ; GET KEY FROM KEY BOARD
1110 1F6A ; RETURN WITH A=KEY VALUE
1111 1F6A ; A GT. 15 TEHN ILLEGAL OR NO KEY
1112 1F6A ;
1113 1F6A ;
1114 1F6A A2 21 GETKEY LDX #$21 ; START AT DIGIT 0
1115 1F6C A0 01 GETKE5 LDY #$01 ; GET 1 ROW
1116 1F6E 20 02 1F JSR ONEKEY
1117 1F71 D0 07 BNE KEYIN ; A=0 NO KEY
1118 1F73 E0 27 CPX #$27 ; TEST FOR DIGIT 2
1119 1F75 D0 F5 BNE GETKE5
1120 1F77 A9 15 LDA #$15 ; 15=NOKEY
1121 1F79 60 RTS
; key pressed
1122 1F7A A0 FF KEYIN LDY #$FF
1123 1F7C 0A KEYIN1 ASL A ; SHIFT LEFT
1124 1F7D B0 03 BCS KEYIN2 ; UNTIL Y=KEY NUM
1125 1F7F C8 INY
1126 1F80 10 FA BPL KEYIN1
1127 1F82 8A KEYIN2 TXA
1128 1F83 29 0F AND #$0F ; MASK MSD
1129 1F85 4A LSR A ; DIVIDE BY 2
1130 1F86 AA TAX
1131 1F87 98 TYA
1132 1F88 10 03 BPL KEYIN4
1133 1F8A 18 KEYIN3 CLC
1134 1F8B 69 07 ADC #$07 ; MULT (X-1) TIMES A
1135 1F8D CA KEYIN4 DEX
1136 1F8E D0 FA BNE KEYIN3
1137 1F90 60 RTS
1138 1F91 ;
What is happening here?
- check if key pressed (1114..1119)
- return with $15 if none (1120)
- calculate key number 00..14 from position in matrix (1122..1136)
TABLE
HEX to 7 segment lookup table, HEX number 0..F to segment a..g
bit 0 = a
bit 1 = b
bit 2 = c
bit 3 = d
bit 4 = e
bit 5 = f
bit 6 = g
bit 7 = 1 to keep PA7, the TTY output to 1
Seven segment layout
a
---
f| g | b
---
e| | c
---
d
Examples
hex 0 is all 1 except g: 1011 1111 = $BF
hex A is all 1 except d: 1111 0111 = $F7
hex F is all 1 except b,c,d 1111 0001 = $F1
1200 1FE7 ; TABLE HEX TO 7 SEGMENT
1201 1FE7 ; 0 1 2 3 4 5 6 7
1202 1FE7 BF 86 DB CF TABLE .BYTE $BF,$86,$DB,$CF,$E6,$ED,$FD,$87
1202 1FEB E6 ED FD 87
1203 1FEF ; 8 9 A B C D E F
1204 1FEF FF EF F7 FC .BYTE $FF,$EF,$F7,$FC,$B9,$DE,$F9,$F1
1204 1FF3 B9 DE F9 F1
1205 1FF7 ;
The following two pages from the First Book of KIM are also interesting to see what is happening here and how to expand the routine with a larger amount of characters to show on the display.

