KIM-1 monitor data storage

The 6530-002 and 6530-003 software use these data areas:

0069 00EF .ORG $00EF
0070 00EF ; MPU REG. SAVX AREA IN PAGE 0
0071 00EF ;
0072 00EF PCL .BLOCK 1 ; PROGRAM CNT LOW
0073 00F0 PCH .BLOCK 1 ; PROGRAM CNT HI
0074 00F1 PREG .BLOCK 1 ; CURRENT STATUS REG.
0075 00F2 SPUSER .BLOCK 1 ; CURRENT STACK POINT
0076 00F3 ACC .BLOCK 1 ; ACCUMULATOR
0077 00F4 YREG .BLOCK 1 ; Y INDEX
0078 00F5 XREG .BLOCK 1 ; X INDEX
0079 00F6 ;
0080 00F6 ; KIM FIXED AREA IN PAGE 0
0081 00F6 ;
0082 00F6 CHKHI .BLOCK 1
0083 00F7 CHKSUM .BLOCK 1
0084 00F8 INL .BLOCK 1 ; INPUT BUFFER
0085 00F9 INH .BLOCK 1 ; INPUT BUFFER
0086 00FA POINTL .BLOCK 1 ; LSB OF OPEN CELL
0087 00FB POINTH .BLOCK 1 ; MSB OF OPEN CELL
0088 00FC TEMP .BLOCK 1
0089 00FD TMPX .BLOCK 1
0090 00FE CHAR .BLOCK 1
0091 00FF MODE .BLOCK 1
0092 0100 ;
0093 0100 ; KIM FIXED AREA IN PAGE 23 (in 6530-002 RAM)
0095 17E7 .ORG $17E7
0096 17E7 CHKL .BLOCK 1
0097 17E8 CHKH .BLOCK 1 ; CHKSUM
0098 17E9 SAVX .BLOCK 3
0099 17EC VEB .BLOCK 6 ; VOLATILE EXEC BLOCK (6-B)
0100 17F2 CNTL30 .BLOCK 1 ; TTY DELAY
0101 17F3 CNTH30 .BLOCK 1 ; TTY DELAY
0102 17F4 TIMH .BLOCK 1
0103 17F5 SAL .BLOCK 1 ; LOW STARTING ADDRESS
0104 17F6 SAH .BLOCK 1 ; HI STARTING ADDRESS
0105 17F7 EAL .BLOCK 1 ; LOW ENDING ADDRESS
0106 17F8 EAH .BLOCK 1 ; HI ENDING ADDRESS
0107 17F9 ID .BLOCK 1 ;
0108 17FA ;
0109 17FA ; INTERRUPT VECTORS
0110 17FA ;
0111 17FA NMIV .BLOCK 2 ; STOP VECTOR (STOP=1C00)
0112 17FC RSTV .BLOCK 2 ; RST VECTOR
0113 17FE IRQV .BLOCK 2 ; IRQ VECTOR (BRK=1C00)

RAMpager: a 1MB banked RAM expansion for the KIM-1

An exapnsion for the MTU bus: RAMpager: a 1MB banked RAM expansion for the KIM-1

On this location you can find the open hardware source of a RAM card made for the MTU bus

he RAMpager is a MTU banked RAM expansion for the KIM-1: the board supports up to 1MB (that’s three orders of magnitude above more than the original 1152 bytes!) of memory and maps it to a 4KB window placed between 2000h and FFFFh. The window can be mapped to different banks for read and write operations via two control ports.

It supports an optional internal/external backup battery to keep the data in the SRAMs valid across power cycles.

Kempac documents added

The Kempac system now is fully documented!

Proton PIM-1 hex monitor source added

Thanks to Gerben Voort the source of the PIM-1 has been added to the PIM-1 page

Subroutines DUMP to tape

0277   1932             ;        SUBROUTINES BELOW   
0278   1932             ;
0279   1932             ;        SUB TO MOVE SA TO VEB+1,2
0280   1932             ;
0281   1932 AD F5 17    INTVEB  LDA   SAL        
0282   1935 8D ED 17            STA   VEB+1       
0283   1938 AD F6 17            LDA   SAH         
0284   193B 8D EE 17            STA   VEB+2       
0285   193E A9 60               LDA   #$60        ; RTS INST
0286   1940 8D EF 17            STA   VEB+3       
0287   1943 A9 00               LDA   #$00        ; CLEAR CHKSUM AREA
0288   1945 8D E7 17            STA   CHKL
0289   1948 8D E8 17            STA   CHKH
0290   194B 60                  RTS
0291   194C             ;
0292   194C             ;       COMPUTE CHKSUM FOR TAPE LOAD   
0293   194C             ;       RTN USES Y TO SAVEX A   
0294   194C             ;
0295   194C A8          CHKT    TAY                     
0296   194D 18                  CLC
0297   194E 6D E7 17            ADC   CHKL
0298   1951 8D E7 17            STA   CHKL
0299   1954 AD E8 17            LDA   CHKH
0300   1957 69 00               ADC   #$00
0301   1959 8D E8 17            STA   CHKH
0302   195C 98                  TYA
0303   195D 60                  RTS
0304   195E             ;		
0305   195E             ;       OUTPUT ONE BYTE USE Y
0306   195E             ;       TO SAVX BYTE
0307   195E             ;  
0308   195E 20 4C 19    OUTBTC  JSR   CHKT        ; COMP CHKSUM 
0309   1961 A8          OUTBT   TAY               ; SAVX DATA BYTE
0310   1962 4A                  LSR   A           ; SHIFT OFF LSD
0311   1963 4A                  LSR   A       
0312   1964 4A                  LSR   A       
0313   1965 4A                  LSR   A       
0314   1966 20 6F 19            JSR   HEXOUT      ; OUT PUT MSD
0315   1969 98                  TYA           
0316   196A 20 6F 19            JSR   HEXOUT      ; OUT PUT LSD
0317   196D 98           	    TYA           
0318   196E 60                  RTS
0319   196F             ;		
0320   196F             ;       CONVERT LSD OF A TO ASCII
0321   196F             ; 	    AND OUTPUT TO TAPE   
0322   196F             ;
0323   196F 29 0F       HEXOUT  AND   #$0F                               
0324   1971 C9 0A               CMP   #$0A
0325   1973 18                  CLC  
0326   1974 30 02               BMI   HEX1
0327   1976 69 07               ADC   #$07
0328   1978 69 30       HEX1    ADC  #$30
0329   197A             ;
0330   197A             ;       OUTPUT TO TAPE ONE ASCII  
0331   197A             ;       CHAR  USE SUB'S ONE + ZRO   
0332   197A             ;
0333   197A 8E E9 17    OUTCHT  STX   SAVX                                
0334   197D 8C EA 17            STY   SAVX+1
0335   1980 A0 08               LDY   #$08        ; START BIT
0336   1982 20 9E 19    CHT1    JSR   ONE         
0337   1985 4A                  LSR   A           ; GET DATA BIT
0338   1986 B0 06               BCS   CHT2        
0339   1988 20 9E 19            JSR   ONE         ; DATA BIT=1
0340   198B 4C 91 19            JMP   CHT3        
0341   198E 20 C4 19    CHT2    JSR   ZRO         ; DATA BIT=0
0342   1991 20 C4 19    CHT3    JSR   ZRO         
0343   1994 88                  DEY   
0344   1995 D0 EB               BNE   CHT1
0345   1997 AE E9 17            LDX   SAVX
0346   199A AC EA 17            LDY   SAVX+1
0347   199D 60                  RTS
0348   199E             ;
0349   199E             ;		
0350   199E             ;          OUTPUT 1 TO TAPE 
0351   199E             ;          9 PULSES 138 MICROSEC EACH
0352   199E             ;   
0353   199E A2 09       ONE     LDX   #$09        ; 
0354   19A0 48                  PHA               ; SAVX A
0355   19A1 2C 47 17    ONE1    BIT   CLKRDI      ; WAIT FOR TIME OUT 
0356   19A4 10 FB               BPL   ONE1
0357   19A6 A9 7E               LDA   #126
0358   19A8 8D 44 17            STA   CLK1T
0359   19AB A9 A7               LDA   #$A7
0360   19AD 8D 42 17            STA   SBD         ; SET PB7=1
0361   19B0 2C 47 17    ONE2    BIT   CLKRDI      ; 
0362   19B3 10 FB               BPL   ONE2
0363   19B5 A9 7E               LDA   #126
0364   19B7 8D 44 17            STA   CLK1T
0365   19BA A9 27               LDA   #$27
0366   19BC 8D 42 17            STA   SBD         ; RESET PB7=0
0367   19BF CA                  DEX   
0368   19C0 D0 DF               BNE   ONE1
0369   19C2 68                  PLA
0370   19C3 60                  RTS
0371   19C4             ;
0372   19C4             ;
0373   19C4             ;        OUTPUT 0 TO TAPE
0374   19C4             ;        6 PULSES 207 MICROSEC EACH   
0375   19C4             ;
0376   19C4 A2 06       ZRO     LDX   #$06        
0377   19C6 48                  PHA               ; SAVX A
0378   19C7 2C 47 17    ZRO1    BIT   CLKRDI                              
0379   19CA 10 FB               BPL   ZRO1
0380   19CC A9 C3               LDA #$C3
0380   19CC A9 C3       
0381   19CE 8D 44 17            STA   CLK1T
0382   19D1 A9 A7               LDA   #$A7
0383   19D3 8D 42 17            STA   SBD         ; SET PB7=1
0384   19D6 2C 47 17    ZRO2    BIT   CLKRDI
0385   19D9 10 FB               BPL   ZRO2
0386   19DB A9 C3               LDA   #195
0387   19DD 8D 44 17            STA   CLK1T
0388   19E0 A9 27               LDA   #$27
0389   19E2 8D 42 17            STA   SBD         ; RESET PB7=0
0390   19E5 CA                  DEX   
0391   19E6 D0 DF               BNE   ZRO1
0392   19E8 68                  PLA               ; RESTORE A
0393   19E9 60                  RTS
0394   19EA             ;
0395   19EA             ;          SUB TO INC VEB+1,2   
0396   19EA             ;
0397   19EA EE ED 17    INCVEB  INC   VEB+1                   
0398   19ED D0 03               BNE   INCVE1
0399   19EF EE EE 17            INC   VEB+2
0400   19F2 60          INCVE1  RTS

Dump to tape

DUMPT dumps via bitbanging a KIM-1 audio tape file.

Very straight forward well commented source.
See also the user manual, which explains the technique quite well.

0119   1800             ;       DUMP MEMORY TO TAPE 
0120   1800               
0121   1800 A9 AD       DUMPT   LDA   #$AD         ; LOAD ABSOLUTE INST
0122   1802 8D EC 17            STA   VEB
0123   1805 20 32 19            JSR   INTVEB
0124   1808             ;             
0125   1808 A9 27               LDA   #$27         ; TURN OFF DATAIN PB5
0126   180A 8D 42 17            STA   SBD          
0127   180D A9 BF               LDA   #$BF         ; CONVERT PB7 TO OUTPUT
0128   180F 8D 43 17            STA   PBDD         
0129   1812             ;                          
0130   1812 A2 64               LDX   #$64         ; 100 CHARS
0131   1814 A9 16       DUMPT1 LDA    #$16         ; SYNC CHAR'S
0132   1816 20 7A 19            JSR   OUTCHT       
0133   1819 CA                  DEX                
0134   181A D0 F8               BNE   DUMPT1       
0135   181C             ;                         
0136   181C             
0137   181C A9 2A       	LDA   #$2A         ; START CHAR
0138   181E 20 7A 19            JSR   OUTCHT        
0139   1821             ;
0140   1821 AD F9 17            LDA   ID           ; OUTPUT ID
0141   1824 20 61 19            JSR   OUTBT         
0142   1827             ;
0143   1827 AD F5 17            LDA   SAL          ; OUTPUT STARTING
0144   182A 20 5E 19            JSR   OUTBTC       ; ADDRESS
0145   182D AD F6 17            LDA   SAH           
0146   1830 20 5E 19            JSR   OUTBTC        
0147   1833             ;
0148   1833 AD ED 17    DUMPT2  LDA   VEB+1        ; CHECK FOR LAST
0149   1836 CD F7 17            CMP   EAL          ; DATA BYTE
0150   1839 AD EE 17            LDA   VEB+2         
0151   183C ED F8 17            SBC   EAH           
0152   183F 90 24               BCC   DUMPT4        
0153   1841             ;
0154   1841 A9 2F               LDA   #'/'         ; OUTPUT END OF DATA CHAR
0155   1843 20 7A 19            JSR   OUTCHT        
0156   1846 AD E7 17            LDA   CHKL         ; LAST BYTE HAS BEEN
0157   1849 20 61 19            JSR   OUTBT        ; OUT PUT    NOW OUTPUT
0158   184C AD E8 17            LDA   CHKH         ; CHKSUM
0159   184F 20 61 19            JSR   OUTBT         
0160   1852             ;
0161   1852             ;
0162   1852 A2 02               LDX   #$02         ; 2 CHAR'S
0163   1854 A9 04       DUMPT3  LDA   #$04         ; EOT CHAR
0164   1856 20 7A 19            JSR   OUTCHT        
0165   1859 CA                  DEX                 
0166   185A D0 F8               BNE   DUMPT3   
0167   185C             		
0168   185C A9 00               LDA   #$00 ; DISPLAY 0000
0169   185E 85 FA               STA   POINTL       ; FOR NORMAL EXIT
0170   1860 85 FB               STA   POINTH        
0171   1862 4C 4F 1C            JMP   START         
0172   1865             ;
0173   1865 20 EC 17    DUMPT4  JSR   VEB          ; DATA BYTE OUTPUT
0174   1868 20 5E 19            JSR   OUTBTC  
0175   186B             ;		
0176   186B 20 EA 19            JSR   INCVEB
0177   186E 4C 33 18            JMP   DUMPT2

Audio tape hardware and ROM

The second RRIOT, named 6530-003, in the KIM-1 is nearly free to use by the user. The two parallel ports, the timer, the RAM, not used by the software.

But the ROM is used, it contains two routines to dump and load data on audio cassette tape. The hardware for this is connected to the 6530-002.

The hardware for audio out is simple, the software does all the work of producing audio tones at PB7, with some pulse shaping with a capacitor/resistor and a ‘low’
or ‘high’ amplitude output.

Audio in is a bit more complicated. The PLL LM565 Phase Locked Loop detects the frequency of incoming audio signals, the output of the PLL is converted to TTL level by the comparator LM311. This is is the only part of the KIM-1 hardware requiring 12V.
See here the datasheet of the LM565.

On pin7 a TTL signal is seen if there is a KIM-1 compatible audio signal is coming in.
Read Appendix E of the User manual to see how all this works.

The two routines, LOADT and DUMPT, are described on the next pages. The style of the programming is a different from the main ROM. It is better structured and easily readable.

Where the 6530-002 papertape routines use indexed zeropage addressing to load/save bytes in memory, the 6530-003 uses a so called Volatile Execution Block VEB in page 23.
A small routine is constructed there during the dump and load.

For DUMPT
AD yy xx 60 LDA xxyy RTS

for LOADT
8D yy xx 4C TAP STA xxyy XX JMP LOADT12

The address xxyy is incremented during the load or dump.

DUMPT and LOADT are completely independent of the monitor in the KIM 6530-002. So you have to start the routines via the GO command or key. The routines end with a call to START in the main routine, where an error condition is indicated with the current address: 0000 is succes, FFFF is error.

It would have been nice to integrate DUMPT and LOADT with command in the TTY loop for example and return via the normal exit routine, displaying ERR KIM as the papertape routines do.
Also making it callable as subroutine might have nice for programs like the KB9 MOS Technology Basic for the KIM or Focal instead of falling back to the KIM monitor.

Expanding the KIM-1

On the page KIM-1 Memory layout you can see the KIM-1 in its basic form of address decoding is limited to 8K address space, repeated 8 times in the 64K address space.
So the KIM-1 can boot from the KIM-1 ROM since address 17FA is the same as FFFA.

The basic memory decoder in the KIM-1

Simple expansion
A first memory expansion often used in the KIM-1 is to use K1, K2, K3 and K4. When you place RAM there, location 0400-13FF become available. The KIM-1 still sees 8K repeated in the 64K
My first expansion was made this way, four 1K SRAM cards made 4K RAM extra available. Great for Tiny Basic.
This is described in the Radio Bulletin article with the 1K B.E.M. static RAM card.

Chapter 6 of the User manual has good advice on the memory decoding.

If we want to expand the access of the 6502 to more than *K , we need to involve address lines A13, A14 and A15 and use DECODE ENABLE to limit K0-K7 to the first 8K of the address space..

This was my second expansion, as described in this article.
With 4K RAM cards, 2114 SRAM based.

You see here A13, A14, A15 connected to a 74145 used as 3 to 8 decoder. Again the 74145 is used for its open collector outputs.
This delivers signals 8K0 to 8K7, where 8K0 selects 0000-1FFF, 8K1 2000-3FFF and so on, 8K7 selects E000-EFFF.
By tying signal 8K0 to 8K7 we repeat 0000-1FFF to E000-FFFF and the KIM-1 ROM vector is mapped in for a RESET. So we gain access to 2000-DFFF for expansion.
The second and third 74145 is an example to deliver Kx signals for 4KB memory parts. I added 32K SRAM this way with 8 4K RAM cards.

If you want access to address space E000-FFFF, you have to provide ROM at FFFA-FFFF, or map this address space to 17FA-17FF.

The same principles are used in the Micro-KIM and PAL-1 RAM card. and the PAL-2 full decode.

PAL-1 and Micro-KIM RAM board

PAL-2 decoder

KIM-1 memory layout

The 6502 has an 16 bit address bus, so it can access 64KB of memory, made up of RAM, ROM and I/O devices.
Address decoding is the hardware that enables the devices in that memory space at the desired address.

The basic address decoding is made up of a 74145, a TTL IC that decodes 4 bit to 10 bits, here used as 3 to 8 decoder. Te 74145 has open collector outputs, so outputs can be tied together.

74145 function table

Memory decoder in the KIM-1

According the User manual this leads to the memory layout as shown above. Note the K0-K7 signals that are connected to the hardware devices such a RAM, and the RRIOTs.
The Kx signal covers a 1KB block of memory, a ‘Page’ is 256 bytes, 4 pages in a Kx block. So K0 addresses pages 0..3, K5 has page 23 which you will see mentioned in the source as the RAM locations in use by the monitor.

Incomplete memory decoding
The picture from the user manual above is a bit misleading. Since address A13, A14 and A15 are not included in the decoder, they are effectively ignored. The KIM-1 sees a maximum of 8K memory this way 0000-1FFF. Why still using 16 bit addresses? In fact since the higher address lines are ignored, address 0000 is also address 2000, 4000 etc with 8K steps to E000.
And the vectors at address 1FFA in the KIM ROM are also found at FFFA, so the RESET vector works. Simple and effective.
The KIM-1 in its basic form of address decoding is limited to 8K address space, repeated 8 times in the 64K address space.

DE Decode enable
The fourth input D of the 74145 is connected to pin A-K of the Application connector. For the basic address decoding as 3 to 8 decoder pin D of the 74145 has to be connected to ground.
This is the essential wire on the Application connector to let a KIM-1 function.
DE is essential for external devices to take over the 6502 address space and allow expansion utilizing the full address space.

Conclusion
The KIM-1 has access to a 8K memory space. Any address is truncated to 13 bits in hardware, so if you use an address 2000 and up it is mapped into 0000-1FFF.

Further reading
Chapter 6 of the User manual has good advice on the memory decoding.

On the next page, Expand the KIM-1, you will see how to add RAM, ROM and I/O to the KIM-1 and use the full address space, with full decode and using Decode Enable.

LED Display and keyboard

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.