This is the memory map after RESET.



About small SBC systems
This is the memory map after RESET.



Bill Mensch wrote:
I would be happy to contribute some commentary concerning the creation of the 6530 at MOS.
What are you interested in other than it was the second chip for the combination of the 6502 for use in control systems.
The KIM-1 was a reference design/use case for bothe the 6502 and the 6530, actually two of them.
One 6530 was for the “Teletype Input Monitor (TIM)” and the other one was for the “Keypad Input Monitor (KIM)”.
It was first demonstrated along with the 6501/6502 at the WESCON ’75.
The 6502 and 6530 were ment to compete with the $29 Intel 4040 two chip controller combo.
The actual design was important for the introduction of the 6502.
I and a team of three mask designers Harry Bawcom, Mike Jaynes and Sid Holdt created the 6530.
The timer design was patented and used on the 6530, 6531 and 6532 chips.
Chuck Peddle and Wil Mathys contributed the system level applications concepts and requested the features.
We were a small team. I was the semiconductor design and architect engineer.
The 6530 followed many of the design concepts of the 6820/6520/6821/6520 concepts for IO and interrupt features.
The 6522 followed the 6520/6530/6532 designs at MOS.
Ray Hirt was the project lead on the 6532.
The 6532 RIOT design was basically to remove the ROM and add another 64 bytes of RAM for a total of 128 bytes.
I was the microprocessor design manager at this time replacing Rod Orgill who had left MOS to work at NCR in Colorado Springs, CO.
Rod didn’t work on any of the IO chips, just the 6501/6502.
Ray, Rod, sometimes Wil and I shared many a pitcher of beer at many lunches after the 6502 and 6530/32 were completed before Rod left for Colorado.
These are fond memories of my time at MOS.
Let me know if you have any questions.
Best,
-Bill
The RESET of a system with a 6530-004 TIM is a bit special. The RESET code comes from the OTIM ROM, after the RESET the memory map is restored to the documented one.
0084 0000 MDBK =%00010110 ; X,X,X,PCR,DATA-AVAIL,GOT-DATA,SERIAL-OUT,IN 0095 0000 UINT =$FFF8 0793 73F8 00 70 INTVEC .WORD NMINT ; DEFAULT USER INTRO TO NMINT 0794 73FA 00 70 .WORD NMINT 0795 73FC 06 70 .WORD RESET 0796 73FE 52 70 .WORD INTRQ 0144 7006 A9 16 RESET LDA #MDBK ; INIT DIR REG, PCR TO 1 RELOCATES 0145 7008 ; 0146 7008 8D 03 6E STA MDB 0147 700B ; 0148 700B A2 08 LDX #8 ; X=0 0149 700D BD F7 73 R1 LDA INTVEC-1,X ; INITALIZE INT VECTORS 0150 7010 9D F7 FF STA UINT-1,X 0151 7013 CA DEX 0152 7014 D0 F7 BNE R1 0153 7016 ; 0154 7016 86 EA STX MAJORT ; INIT MAJOR T COUNT TO ZERO 0155 7018 86 E7 STX HSPTR ; CLEAR HSPTR FLAGS 0156 701A 86 E8 STX HSROP 0157 701C CA DEX ; X=FF 0158 701D 9A TXS ; SP=FF

The Chip Select equations for the 6530-004
What is happening here?
The address decoding is a bit course, the ROM of the 6530-004 is not only at $7000, but also mirrored at $7400, $7800 and $7C00. So $73FF is also $7FFF.

The PB4 circuit from the TIM manual

The PB4 circuit in the Jolt, note the pullup resistor.
After power PB4 is an input, the default for a 6530 port. So the inverter input is seen as high (on the Jolt a pullup resistor makes that certain) , so the output of the inverter is low. This blocks the 7400 port input, the other input is A15. So the ROM address $7FFF is mirrored to $FFFF. And so the RESET vector of the 6502 is read from the ROM the 6530-004, and the program counter is set to $7006, the RESET code in the ROM.
The Data Direction register or Port B is loaded with MDBK =%00010110
By making PB4 an output, PB4 becomes low, the output of the 7400 high, and A15 reaches the 6530, so the ROM is not seen at FFFF. Teh default memory map is now active.
The 8 vector bytes from the ROM are now loaded into the RAM of the 6430-004 at upper memory (location UINT) in a loop with X as down counter to zero (148-152)
Some counters and flags are now initialized to zero with X (High speed reader, serial T count) (154 to 156)
As last the stack pointer is set to $FF (157-158)
The Jolt and SuperJolt computers use the 6530-004 RRIOT TIM IC. The Jolt is in fact just a board with a 6502 with a TIM RRIOT + some RAM and a PIA 6520 and some decoding logic.
The program in the TIM is called DEMON by Micro Associates (Ray Holt and Manny Lemas).
So understanding how the Jolt works starts with understanding how the TIM RRIOT hard- and software works.

The TIM RRIOT, 6530-004,contains the ROM (1K), timers, 128 byte RAM, 16 I/O) and 64 bytes RAM.
|
MOS TIM folder with pricelist |
|
MOS TIM manual Rev 6500-20 |
![]() |
Jolt DeMon software manual, the same as TIM (this manual has an alternative listing of the TIM 6530-004 monitor), only the first page is different. |
|
Jolt Replica User manual |
Here the machine readable and ready to assemble source, listing and binary of TIM (Thanks Martin Hoffmann-Vetter)
Note that this contains a corrected version, version 2026! While testing the TIM Simulator I found an error in the papertape loader LH command, the ‘;’ start of a record seems to be OCR’ed to ‘:’ . In 2026, during the deep dive into explaining the TIM, many OCR errors in the comments were corrected.
The resulting binary is identical to the ROM dumped from a real 6530-004.
The source listing is used on the next pages to explain the software.
The KIM-1 monitor surprises me every time I dive into it.
The KIM-1 Explained is nearing completion. The KIM-1 explained
There is a bug in the TTY CLI, it accepts characters as ‘;’ and ‘:’ as valid hex and translates to A..F.
KIM 0200 A9 ;; 00BB 00 :: 00AA 00 ???? FFFF 1C
More about this innocent feature here: PRTBYT, GETBYT and PACK
PRTBYT takes a byte and sends it to the serial TY as two hex ascii characters
The byte is entered in A, two characters are printed and A is saved.
0914 1E3B ; 0915 1E3B ; PRINT 1 HEX BYTE AS 2 ASCII CHAR'S 0916 1E3B ; 0917 1E3B 85 FC PRTBYT STA TEMP 0918 1E3D 4A LSR A ; SHIFT CHAR RIGHT 4 BITS 0919 1E3E 4A LSR A 0920 1E3F 4A LSR A 0921 1E40 4A LSR A 0922 1E41 20 4C 1E JSR HEXTA ; CONVERT TO HEX AND PRINT 0923 1E44 A5 FC LDA TEMP ; GET OTHER HALF 0924 1E46 20 4C 1E JSR HEXTA ; CONVERT TO HEX AND PRINT 0925 1E49 A5 FC LDA TEMP ; RESTORE BYTE IN A AND RETURN 0926 1E4B 60 RTS 0927 1E4C ; 0928 1E4C 29 0F HEXTA AND #$0F ; MASK HI 4 BITS 0929 1E4E C9 0A CMP #$0A 0930 1E50 18 CLC 0931 1E51 30 02 BMI HEXTA1 0932 1E53 69 07 ADC #$07 ; ALPHA HEX 0933 1E55 69 30 HEXTA1 ADC #$30 ; DEC HEX 0934 1E57 4C A0 1E JMP OUTCH ; PRINT CHAR
What is happening here?
GETBYT and PACK
1148 1F9D ; 1149 1F9D ; GET 2 HEX CHAR'S AND PACK 1150 1F9D ; INTO INL AND INH 1151 1F9D ; X PRESERVED Y RETURNED = 0 1152 1F9D ; NON-HEX WILL BE LOADED AS NEAREST HEX EQU 1153 1F9D ; 1154 1F9D 20 5A 1E GETBYT JSR GETCH 1155 1FA0 20 AC 1F JSR PACK 1156 1FA3 20 5A 1E JSR GETCH 1157 1FA6 20 AC 1F JSR PACK 1158 1FA9 A5 F8 LDA INL 1159 1FAB 60 RTS 1160 1FAC ; 1161 1FAC ; SHIFT CHAR IN A INTO 1162 1FAC ; INL AND INH 1163 1FAC ; 1164 1FAC C9 30 PACK CMP #$30 ; CHECK FOR HEX 1165 1FAE 30 1B BMI UPDAT2 1166 1FB0 C9 47 CMP #$47 ; NOT HEX EXIT 1167 1FB2 10 17 BPL UPDAT2 1168 1FB4 C9 40 CMP #$40 ; CONVERT TO HEX 1169 1FB6 30 03 BMI UPDATE 1170 1FB8 18 CLC 1171 1FB9 69 09 ADC #$09 1172 1FBB 2A UPDATE ROL A 1173 1FBC 2A ROL A 1174 1FBD 2A ROL A 1175 1FBE 2A ROL A 1176 1FBF A0 04 LDY #$04 ; SHIFT INTO I/O BUFFER 1177 1FC1 2A UPDAT1 ROL A 1178 1FC2 26 F8 ROL INL 1179 1FC4 26 F9 ROL INH 1180 1FC6 88 DEY 1181 1FC7 D0 F8 BNE UPDAT1 1182 1FC9 A9 00 LDA #$00 ; A=0 IF HEX NUM 1183 1FCB 60 UPDAT2 RTS
What is happening here?
GETBYT
The GETBYT routine is used in the TTY part of the KIM-1 monitor to enter two hex characters (0..9 and A..F) and pack it into one byte.
PACK
Note that the range between ‘9’ and ‘A’ is not checked, so those are taken as valid hex characters.
The PACK routine accepts ‘:’– ‘?’, $3A .. $3F as valid hex characters A ..F.
KIM 0200 A9 ;; 00BB 00 :: 00AA 00 ???? FFFF 1C
The ASCII encoding is arranged so that adding 9 to ‘A’–’F’ aligns them perfectly with the desired hexadecimal nibble after four left rotates. This avoids a separate subtraction of ‘A’ and addition of 10.
The following demo with PRTBYT and GETBYT illustrates how this could be done in a user program.
0001 0000 ; 0002 0000 ; GETBYTC with error checking 0003 0000 ; illustrates shortcomings in PACK 0004 0000 ; - G and ; and possibly more accepted without error 0005 0000 ; 0006 0000 ; 0007 0000 ; KIM 0008 0000 ; 0000 00 200 0009 0000 ; 0200 A9 G 0010 0000 ; >12=12 0011 0000 ; >33=33 0012 0000 ; >H? 0013 0000 ; >G? 0014 0000 ; >::=AA 0015 0000 ; >;;=BB 0016 0000 ; >AB=AB 0017 0000 ; >CD=CD 0018 0000 ; >EE=EE 0019 0000 ; > 0020 0000 0021 0000 ; KIM-1 defines 0022 0000 ; 0023 0000 PACK = $1FAC ; pack hex character into INL, shift in 0024 0000 PRTBYT = $1E3B ; print byte as 2 hex characters 0025 0000 GETCH = $1E5A ; receive character from TTY serial 0026 0000 OUTCH = $1EA0 ; send character via TTY serial 0027 0000 INL = $F8 0028 0000 INH = $F9 0029 0000 ; 0030 0200 .org $0200 0031 0200 0032 0200 ; demo code 0033 0200 ; 0034 0200 A9 00 LOOP LDA #$00 0035 0202 85 F8 STA INL ; zero hex byte 0036 0204 85 F9 STA INH 0037 0206 20 42 02 JSR CRLF 0038 0209 A9 3E LDA #'>' ; prompt 0039 020B 20 A0 1E JSR OUTCH 0040 020E 20 28 02 JSR GETBYTC 0041 0211 90 08 BCC OK 0042 0213 A9 3F LDA #'?' ; error 0043 0215 20 A0 1E JSR OUTCH 0044 0218 4C 00 02 JMP LOOP 0045 021B ; 0046 021B 48 OK PHA 0047 021C A9 3D LDA #'=' 0048 021E 20 A0 1E JSR OUTCH 0049 0221 68 PLA 0050 0222 20 3B 1E JSR PRTBYT 0051 0225 4C 00 02 JMP LOOP ; repeat 0052 0228 ; 0053 0228 ; subroutine GETBYTC 0054 0228 ; read 2 hex characters from TTY input 0055 0228 ; pack into one byte 0056 0228 ; Returns: carry clear if hex OK, A == hex byte 0057 0228 ; clobbers X and Y 0058 0228 ; 0059 0228 0060 0228 0061 0228 20 5A 1E GETBYTC JSR GETCH ; read character 0062 022B 20 AC 1F JSR PACK ; pack into INL 0063 022E C9 00 CMP #$00 ; restore z flag 0064 0230 D0 0E BNE EGETB ; A = 0 if hex number 0065 0232 20 5A 1E JSR GETCH ; read second character 0066 0235 20 AC 1F JSR PACK ; pack into INL 0067 0238 C9 00 CMP #$00 ; restore z flag 0068 023A D0 04 BNE EGETB ; A = 0 if hex number 0069 023C A5 F8 LDA INL 0070 023E 18 CLC 0071 023F 60 RTS 0072 0240 38 EGETB SEC 0073 0241 60 RTS 0074 0242 0075 0242 A9 0D CRLF LDA #$0D 0076 0244 20 A0 1E JSR OUTCH 0077 0247 A9 0A LDA #$0A 0078 0249 20 A0 1E JSR OUTCH 0079 024C 60 RTS 0080 024D 0081 024D .END 0082 024D 0083 024D tasm: Number of errors = 0
Some tips that I learned programming for the KIM-1 and the 6502.
ALWAYS CHECK YOU DO NOT FORGET IMMEDIATE ACCESS SYNTAX!
It so easy an common to forget the ‘#’ in your assembler code. Assemblers will not complain and make it absolute or zeropage addressing and you will search for hours!
This routine sends the CR and LF to the TTY output vai OUTCH. Nice, you will need that often in a console program.
But if you read the page on printing a string you see this routine also sends out 6 Null ($00) characters, this takes a lot of wasted time!
Just make your own subroutine
LDA #$0D ; CR JSR OUTCH LDA #$0A ; LF JSR OUTCH RTS
Note that this destroys A and Y!
GETCH gets a character to serial TTY.
Blocking, it waits indefinitely for a character to arrive and A will have the value.
The routine also kills the Y register, returns with Y = $FF.
Also, in LED Display and Keyboard mode, it returns with A = $01 and X = 8.
Save Y before calling GETCH, and restore Y when it returns.
OUTCH sends a character to serial TTY
No handshaking, no hardware flow control, it just spits out the character.
A destroyed, Y=FF, X preserved.
Save at least Y, and saving A is recommended.
This just calls OUTCH with A = $20, so read OUTCH for the side effects.
Uses OUTCH, so Y is lost. A is preserved.
X saved, Y = 0, A is hex character
Reads two hex characters (0..9 A..F) and tries to pack them in A.
See the page on PRTBYT,GETBYT and PACK for an error checking alternative GETBYTC to GETBYT.
Note that due to an incomplete check ‘:’– ‘?’, $3A .. $3F are accepted as valid hex characters A ..F.
KIM 0200 A9 ;; 00BB 00 :: 00AA 00 ???? FFFF 1C
The DUMPT and LOADT routines are OK to call interactively to dump and load KIM-1 files on tape.
The cannot be called as subroutines. when finished they return to the KIM-1 monitor.
DUMPT return with $0000 as current address pointer in the KIM-1 monitor.
LOADT returns it status via the current address pointer in the KIM-1 monitor, $0000 is success, $FFFF is a loading error.
What you can do is:
– Have code at $0000 to return to your program (Warm start entry), so the user just has to press G
– instruct the user what to do if DUMPT returns $FFFF
The better solution is to incorporate Hypertape as callable subroutine.
The preferred location to call to enter the KIM-1 monitor form a user program is START at $1C4F
Fill F9, FA, FB with the values to show on the LED displays
Call SCAND
Call SCAND to debounce
CaLl GETKEY
Now check the key in A:
– above $14 : no key
– 14 = PC
– 13 = GO
– 12 = +
– 11 = DA
– 10 = AD
– 0 ..9 A – F keys
Handle key and loop back to the begin
KIM-1 TTY command summary
– Connect the application connector with a TTY switch
– Serial port in your terminal emulator settings 9600 bps (or less, 4800 or 2400 work best), 8N1
– Add character and line delay in your terminal emulator, see the TTY problems page
– Press Enter (or any key with odd ASCII value after Reset to initialize serial bit rate.
After startup give the NMI and IRQ/BRK vector a known value
NMI Initialization for Single Step and Stop
17FA 00
17FB 1C
IRQ Initialization for BRK
17FE 00
17FF 1C
Make sure you are not in decimal mode:
00F1 00
Machine Context saved/restored by ST/GO
00EF PC low
00F0 PC high
00F1 Status Register (flags)
00F2 Stack Pointer
00F3 A
00F4 Y
00F5 X
Breakpoints
– Write BRK instruction ($00) at desired address, program will be stopped here.
– ST button: Pressing will invoke NMI interrupt.
– Single Step: Set SST switch to on, type G to step one instruction from current location.
Cassette Load and Save
12 Volt power source is only required when reading tapes
Save to tape
– Store $00 in $00F1 (to ensure CPU is in binary mode).
– Save start address (low/high) in $17F5, $17F6.
– Save end address+1 (low/high) in $17F7, $17F8.
– Write tape ID ($01-$FE) in $17F9.
– Start tape in record mode.
– Run address $1800 (DUMPT) to save.
Load from tape
– Store $00 in $00F1 (to ensure CPU is in binary mode).
– Write tape ID ($01-$FE, $00 loads any ID, $FF loads using start address values (low/high) in $17F5, $17F6) to $17F9.
– Run address $1873 (LOADT) to load.
– success of load: current address is 0000, error is FFFF
TTY commands
<hex address> Show data at current address
(hex characters shifted in to the left)
<hex data&>. Write to current address
<Return> Next address
<Line Feed> Move to previous address (CTRL/J)
L Load program from paper (error if ERR KIM is displayed)
Q Save memory to paper tape, saves from current address
to end address stored at $17F7 (low), $17F8 (high)
G Start program at current address
(note: set F1 00 if not in SST mode)
RUB OUT restart the KIM-1 monitor
Note that pressing RUB OUT in current terminal emulators is not a standard key. I have done it with some customization in Teraterm for Windows.
In the KIM-1 Simulator the RUBOUT is patched to CTRL-G.
To use a HEathkit H14 matrix printer in 1980 I have written a serial send character routine, inspired by OUTCH on Port B pin 0.
The first version was simple, like OUTCH, at low speed to let the printer have time to do its work.
The second version added RTS/CTS handshaking via a second Port B pin as input.
Both were published in the Dutch KIM Club magazine in 1980 and 1981, together with a parallel keyboard routine and integration into the MICO ADE Editor/Assembler.
Here I present the drivers, in a more general format to have a second serial output on the KIM-1 optionally with handshake.
The hardware to adapt the KIM-1 to the RS232C levels can be kept simple. Here some examples:


You can find the sources in TASM32 format here.
0001 0000 ; 0002 0000 ; Serial output for example to drive a printer connected to a KIM-1 0003 0000 ; 1980 Original by Hans Otten 0004 0000 ; 2026 Cleaned of MICRO ADE artefacts and converted to TASM 0005 0000 ; 0006 0000 ; Original in MICRO ADE syntax, curent version TASM32 Hans Otten, 2026 0007 0000 ; 0008 0000 ; Serial output routine (inspired by OUTCH in KIM-1 monitor) 0009 0000 ; 0010 0000 ; Send a byte in RS232C format via a PIA bit 0011 0000 ; 0012 0000 ; Choose MASK0 and MASK1 so any pin of a PIA can be ued 0013 0000 ; Choose OUT for any PIA 6520/6521/6522/6530/6820/21. A 6522 VIA needs other initialization 0014 0000 ; 0015 0000 ; The baud rate is determined by using the following table for calling delay routine 0016 0000 ; BAUD A Y 0017 0000 ; 75 189 10 0018 0000 ; 110 80 0A 0019 0000 ; 300 9C 03 0020 0000 ; 600 D8 01 0021 0000 ; 1200 71 01 0022 0000 ; 2400 4C 0023 0000 ; 4800 22 0024 0000 ; 9600 14 0025 0000 ; 0026 0000 ; Use the second delay routine if only one value is given, w.o.w. above 1200 baud. 0027 0000 ; 0028 0000 ; In the following driver pin PB0 of the KIM-1 is chosen as output, and a baudrate of 4800. 0029 0000 ; Adapt OUT, TI, TII, MSKO, MASKI and choose the applicable delay routine 0030 0000 ; 0031 0000 ; Serial driver without handshake via PB0 KIM-1 0032 0000 ; Original Hans Otten KIM Kenner 12 0033 0000 ; 0034 0000 ; 0035 0000 ; Zeropage used, only during sending character 0036 0000 ; 0037 0000 CHAR = $FE 0038 0000 TEMP = $FD 0039 0000 TMPX = $FC 0040 0000 ; 0041 0000 MASKI = $01 ; set PB0 bit 0 of port for serial OUT 0042 0000 MASKO = $FE ; clear PB 0043 0000 ; 0044 0000 ; Port PBO address 0045 0000 ; 0046 0000 OUT = $1702 ; PBDD data Port B 0047 0000 OUTD = $1703 ; PBD data direction Port B 0048 0000 0049 0000 ; 0050 0200 .ORG $0200 0051 0200 ; 0052 0200 48 OUTPR PHA ; save character 0053 0201 84 FD STY TEMP ; save Y 0054 0203 86 FC STX TMPX ; save X 0055 0205 85 FE STA CHAR ; save character to send 0056 0207 AD 03 17 LDA OUTD ; 0057 020A 09 01 ORA #MASKI ; 0058 020C 8D 03 17 STA OUTD ; set Port B PB0 as output 0059 020F AD 02 17 LDA OUT ; 0060 0212 09 01 ORA #MASKI ; 0061 0214 8D 02 17 STA OUT ; 0062 0217 20 51 02 JSR TDELAY ; send out startbit 1 0063 021A A2 08 LDX #$08 ; 8N1 8 databits 0064 021C AD 02 17 NEXTB LDA OUT 0065 021F 46 FE LSR CHAR ; lsb in carry 0066 0221 B0 04 BCS ONE ; bit is 1? 0067 0223 09 01 ORA #MASKI ; 0068 0225 90 02 BCC BOUT ; set bit 0069 0227 29 FE ONE AND #MASKO ; bit is 0 0070 0229 8D 02 17 BOUT STA OUT ; set bit 0071 022C 20 51 02 JSR TDELAY ; wait bit time 0072 022F CA DEX ; next bit 0073 0230 D0 EA BNE NEXTB ; 0074 0232 AD 02 17 LDA OUT ; stop bit 0075 0235 29 FE AND #MASKO ; is zero 0076 0237 8D 02 17 STA OUT 0077 023A 20 51 02 JSR TDELAY 0078 023D ; JSR TDELAY ; if you want 2 stop bits 0079 023D A6 FC LDX TMPX ; resatore X, Y, A 0080 023F A4 FD LDY TEMP 0081 0241 68 PLA 0082 0242 60 RTS 0083 0243 0084 0243 ; 0085 0243 ; Delay for 110 baud A, Y from table 0086 0243 ; 0087 0243 A0 0A DELAY LDY #$0A 0088 0245 A9 80 OLOOP LDA #$80 0089 0247 38 ILOOP SEC 0090 0248 E9 01 SBC #$01 ; inner loop A*7 -1 0091 024A D0 FB BNE ILOOP 0092 024C EA NOP 0093 024D 88 DEY 0094 024E D0 F5 BNE OLOOP ; 0095 0250 60 RTS 0096 0251 0097 0251 A0 0E TDELAY LDY #14 ; time = Y+5 -1 0098 0253 88 TDLOOP DEY 0099 0254 D0 FD BNE TDLOOP 0100 0256 60 RTS 0101 0257 0102 0257 .END Label Value Label Value Label Value ------------------ ------------------ ------------------ BOUT 0229 CHAR 00FE DELAY 0243 ILOOP 0247 MASKI 0001 MASKO 00FE NEXTB 021C OUT 1702 OUTD 1703 OUTPR 0200 ONE 0227 OLOOP 0245 TEMP 00FD TMPX 00FC TDELAY 0251 TDLOOP 0253 tasm: Number of errors = 0 0001 0000 ; 0002 0000 ; Serial output for example to drive e.g. a serial interface printer connected to a KIM-1 0003 0000 ; 1980 Original by Hans Otten 0004 0000 ; 1981 adapted to RTS CTS handshaking 0005 0000 ; 2026 Cleaned of MICRO ADE artefacts and converted to TASM 0006 0000 ; 0007 0000 ; Original in MICRO ADE syntax, curent version TASM32 Hans Otten, 2026 0008 0000 ; 0009 0000 ; Serial output routine (inspired by OUTCH in KIM-1 monitor) 0010 0000 ; 0011 0000 ; Send a byte in RS232C format via a PIA bit 0012 0000 ; 0013 0000 ; Choose MASK0 and MASK1 so any pin of a Port can be used for serial output 0014 0000 ; Chsooe MSKCTS to select a pin for input of the RTS/CTA handshake line. 0015 0000 ; Assumed both pins are on the same port. 0016 0000 ; Choose OUT for any PIA 6520/6521/6522/6530/6820/21. A 6522 VIA needs other initialization 0017 0000 ; 0018 0000 ; The baud rate is determined by using the following table for calling delay routine 0019 0000 ; BAUD A Y 0020 0000 ; 75 189 10 0021 0000 ; 110 80 0A 0022 0000 ; 300 9C 03 0023 0000 ; 600 D8 01 0024 0000 ; 1200 71 01 0025 0000 ; 2400 4C 0026 0000 ; 4800 22 0027 0000 ; 9600 14 0028 0000 ; 0029 0000 ; Use the second delay routine if only one value is given, w.ow above 1200 baud. 0030 0000 ; 0031 0000 ; In the following driver pin PB0 of the KIM-1 is chosen as output, and a baudrate of 4800 0032 0000 ; For RTS/CTS handling pin PB1 is used as input 0033 0000 ; Adapt OUT, TI, TII, MASKO, MASKI and MSKCTS and choose the applicable delay routine 0034 0000 ; 0035 0000 ; Serial driver with via PB0 KIM-1 0036 0000 ; Original Hans Otten PGJ de Beer KIM Kenner 19 0037 0000 ; 0038 0000 ; Zeropage used, only during sending character 0039 0000 ; 0040 0000 CHAR = $FE 0041 0000 TEMP = $FD 0042 0000 TMPX = $FC 0043 0000 ; 0044 0000 MASKI = $01 ; set PB0 bit 0 of port for serial OUT 0045 0000 MASKO = $FE ; clear PB 0046 0000 MSKCTS = $02 ; isolate RTS CTS pin, here PB1 0047 0000 MSKCTI = $FD 0048 0000 ; 0049 0000 ; Port PBO, PB1 addresses 0050 0000 ; 0051 0000 OUT = $1702 ; PBDD data Port B 0052 0000 OUTD = $1703 ; PBD data direction Port B 0053 0000 0054 0000 ; 0055 0300 .ORG $0300 0056 0300 ; 0057 0300 08 OUTPR PHP 0058 0301 48 PHA ; save character 0059 0302 84 FD STY TEMP ; save Y 0060 0304 86 FC STX TMPX ; save X 0061 0306 85 FE STA CHAR ; save character to send 0062 0308 AD 03 17 LDA OUTD ; 0063 030B 09 01 ORA #MASKI ; output pin serial 0064 030D 29 FD AND #MSKCTI ; input pin RTS 0065 030F 8D 03 17 STA OUTD ; set Port B PB0 as output, PB1 as input 0066 0312 AD 02 17 BUFF LDA OUT 0067 0315 29 02 AND #MSKCTS ; is RTS active? 0068 0317 F0 F9 BEQ BUFF ; wait 0069 0319 AD 02 17 LDA OUT ; 0070 031C 09 01 ORA #MASKI ; 0071 031E 8D 02 17 STA OUT ; 0072 0321 20 5B 03 JSR TDELAY ; send out startbit 1 0073 0324 A2 08 LDX #$08 ; 8N1 8 databits 0074 0326 AD 02 17 NEXTB LDA OUT 0075 0329 46 FE LSR CHAR ; lsb in carry 0076 032B B0 04 BCS ONE ; bit is 1? 0077 032D 09 01 ORA #MASKI ; 0078 032F 90 02 BCC BOUT ; set bit 0079 0331 29 FE ONE AND #MASKO ; bit is 0 0080 0333 8D 02 17 BOUT STA OUT ; set bit 0081 0336 20 5B 03 JSR TDELAY ; wait bit time 0082 0339 CA DEX ; next bit 0083 033A D0 EA BNE NEXTB ; 0084 033C AD 02 17 LDA OUT ; stop bit 0085 033F 29 FE AND #MASKO ; is zero 0086 0341 8D 02 17 STA OUT 0087 0344 20 5B 03 JSR TDELAY 0088 0347 ; JSR TDELAY ; if you want 2 stop bits 0089 0347 A6 FC LDX TMPX ; resatore X, Y, A 0090 0349 A4 FD LDY TEMP 0091 034B 68 PLA 0092 034C 60 RTS 0093 034D 0094 034D ; 0095 034D ; Delay for 110 baud A, Y from table 0096 034D ; 0097 034D A0 0A DELAY LDY #$0A 0098 034F A9 80 OLOOP LDA #$80 0099 0351 38 ILOOP SEC 0100 0352 E9 01 SBC #$01 ; inner loop A*7 -1 0101 0354 D0 FB BNE ILOOP 0102 0356 EA NOP 0103 0357 88 DEY 0104 0358 D0 F5 BNE OLOOP ; 0105 035A 60 RTS 0106 035B 0107 035B A0 0E TDELAY LDY #14 ; time = Y+5 -1 0108 035D 88 TDLOOP DEY 0109 035E D0 FD BNE TDLOOP 0110 0360 60 RTS 0111 0361 0112 0361 .END Label Value Label Value Label Value ------------------ ------------------ ------------------ BUFF 0312 BOUT 0333 CHAR 00FE DELAY 034D ILOOP 0351 MASKI 0001 MASKO 00FE MSKCTS 0002 MSKCTI 00FD NEXTB 0326 OUT 1702 OUTD 1703 OUTPR 0300 ONE 0331 OLOOP 034F TEMP 00FD TMPX 00FC TDELAY 035B TDLOOP 035D tasm: Number of errors = 0
The 6530-002 and 6530-003 software use these data areas.
When your program wants to sue these locations, be aware they can be altered by the monitor or you can make the monitor misbehave.
Reading is OK, writing there requires you know what the monitor does there.
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)