With a scan of manuals by Gerben Voort, and a third photo of a cassette with KB-9, time to refresh the KB-9 pages. Thanks Gerben Voort
Category Archives: kim-1
MOS TECH BASIC versions
Despite all the versions you see on the download page, there is only one official and original binary known of the MOS TECH BASIC for the 6502 KIM and that is my V1.1 (ID 01) loaded from my original tape. There is another tape known recently, owned by my friend Gerben Voort, and we hope to be able to read that tape.
Every other version is a derivate, in the 80ties or in the past years.
There are also sources of Microsoft Basic for the 6502. The official source, in PDP-11 MACRO source format has been declared open not so long ago.
The title is ‘M6502 8K VER 1.1 BY MICRO-SOFT’. Yes the name of the company was originally MICRO-SOFT!
Many years before the official source, Michael Steyl of pagetable.com reconstructed the source, based upon my binary dump. A perfect start to create derivate versions!
Versions known in the 80ties
- KB-9
Created by Microsoft, only distributed by Johnson Computers (afaik). Binary available.
On the tape label: 2000-4260 ID #01 St 4065
Oldest known documentation available, scanned. - KB-6
Mentioned in the documentation of ID #01. Not available.
6 digit precision floating point, smaller in size. - KB-9 ID #101
Distributed by Johnson Computers
On the tape label: 2000-437D ID #101 St 4065 S/N 217 and 233. Binary not available (yet).
Mentioned in the documentation of the versions distributed by Johnson Computer with ID #101. Binary not available. Two versions of the documentation known and scanned.
This version seems to be the V1.1 KB-9 with added Hypertape and BLOCKMOVE routines at the end of the binary. With the alternative start addresses the hypertape routine can be moved to $0200 or $0300 and the SAVE command patched to the hypertape routine. Or with the standard start at $4065 hypertape can be skipped.
All KB-9 internal addresses are the same. - KB-9P
Mentioned in the documentation of the versions distributed by Johnson Computer with ID #101, Binary not available.
KB-9P is a stripped version of KB-9 fit for burning into a ROM. SIN-COS-ATN is not available.

My MSBasic for the KIM-1 cassette

Another MOS TECH BASIC for KIM-1, lower serial number

Thanks Gerben Voort
See also:
TERC KIM-1 Interface set
6502 tester NMOS CMOS 1-8MHz
680x/650x Test system
Backbit Chip Tester PRO V2
How to build and adapt KB-9 and KB-6
Sources of KB-9 Microsoft Basic v1.1
- Microsoft BASIC for 6502 Original Source Code [1978], article on Pagetable, local copy
- Original source in MAC format
- Create your own Version of Microsoft BASIC for 6502, article on Pagetable, local copy, sources in CC65 (CA65 assembler)
- Version 2 sources at the github site of Eduardo Casino, master branch (there is also the KIMIEC branch, with Save and Load to a 1541 floopy drive)
Adapt KB-9, first step make it faster and smaller
In the previous section the pagetable article was shown, with resources to recreate from source many 6502 Basic’s, like KB-9.
Here an example how I, quick and dirty, used this to create a KB-9 named V1.2 which is smaller and faster than the original.
This is how to prepare for it (Windows, can be done also on Linux)
- Download and unpack the archive of pagetable in a folder on your PC.
- Download and unpack the CC65 package, a C compiler, from which only the assembler and linker is used. I used the Windows binaries.
- Copy CA65.EXE, LD65.EXE and longbranch.mac from the CC65 package to the folder where you unpacked the MS Basic source.
Do the adaptations as described below or your own:
- To save you the work I have collected the adaptations described above in this archive for your convenience here.
- Change whatever you like in the source. It is quite a complicated construction, with macros for every variant, so look carefully at the listing file what really is produced.
Start with no adaptations and then go on studying the listing file and testing. The KIM-1 Simulator is a good tool for testing! Load the symbol table file to see what is where. - Assemble and link with this simple batch file makekb9v2.bat, resulting in an object, a binary, a listing file and a symbol label file.
ca65 -D kb9 msbasic.s -o tmp/kb9v2.o -l tmp/kb9v2.lst ld65 -C kb9.cfg tmp/kb9v2.o -o tmp/kb9v2.bin -Ln tmp/kb9v2.lbl
These are the adaptations done in V1.2 use the ROR instruction and suppress nulls sent to the terminal and Clear decimal and fix GET
I changed this:
-
- In define_kim.s make a comment of the following two lines:
;CONFIG_NULL := 1 ;CONFIG_ROR_WORKAROUND := 1 ; patch HO 2021
- In init.s add this line at label COLD_START
COLD_START: .ifdef SYM1 jsr ACCESS .endif .ifdef KBD . . . .else .ifndef CBM2 cld ; patch for KIM-1 HO 2021 ldx #$FF stx CURLIN+1Change line 493 init.s
.ifdef KIM .byte "MOS TECH 6502 BASIC V1.2" - do the fix in the “GET handling (see below)
- Add backspace handling to correct typing errors
- Change the version number in inline.s line 493 to “MOS TECH 6502 BASIC V1.2
Assemble and link with the batch file makekb9v2.bat, this will deliver in the folder tmp
– kb9v2.bin file : load as usual at $20001
– kb9v12.lbl text file
– kb9v12lst textfile
Start KB9 V2 now at location $3FB1, label COLD_START (used to be $4065, so we gained some RAM), see the lbl file for other addresses.
KB-6
I know KB-6 existed. The ‘6’ stands for the precision in digits of the floating point number. In the documentation KB-6 is described.
Never seen a version in the wild. So the reconstruction here is not checked with the original, addresses in the reconstruction from the linker differ from the documentation.
Perhaps the ROR workaround or the insertion of CLD in the init.s caused this.
KB-6 can be ‘reconstructed’ since other versions of 6 digit Microsoft Basic are in the ‘pagetable sources’.
It takes one define added in define_kim.s, changes on the original file are now:
; CONFIG_NULL := 1 ; patch HO 2021 ;CONFIG_ROR_WORKAROUND := 1 ; patch HO 2021 CONFIG_SMALL := 1 ; patch H0 2021
Assemble and link as above, replace kb9v12 with kb6v12 in the batch file. See the archive for a working batch file.
COLD_START moves to $3D50, size shrinks to 8K.
As you can see in the following screenshots it works! Note the number of digits is less, as expected. It should be faster also.

Microsoft Basic for the KIM-1 KB-9

Microsoft Basic for the KIM-1 KB-6, less precision, smaller program size
The GET bug
The bug was described and fixed first by an article in the KIM User notes 17
From the pagetable sources:
BUG: The beq/bne L2AF8 below is supposed to be always taken. For this to happen, the last load must be a 0 for beq and != 0 for bne.
The original Microsoft code had ldx/ldy/bne here, which was only correct for a non-ZP INPUTBUFFER. Commodore fixed it in CBMBASIC V1 by swapping the ldx and the ldy. It was broken on KIM, but okay on APPLE and CBM2, because these used a non-ZP INPUTBUFFER. Microsoft fixed this somewhere after KIM and before MICROTAN, by using beq instead of bne in the ZP case.
.ifdef CBM1
ldy >(INPUTBUFFER-1)
ldx <(INPUTBUFFER-1)
.else
ldx >(INPUTBUFFER-1)
ldy <(INPUTBUFFER-1)
..
beq 08
You can easily fix this in KB9 by changing the branch in $2AEE from $D0 (bne) to $F0 (beq).
I have fixed this in the source of KB9V2 (KB6 does not have the GET statement) .
Use the backspace key to correct typing errors
Correcting typing errors can be done with the _ key ($5F). On a video terminal, like we use nowadays it can be done with backspace.
The way characters are handled by the input routine do not allow to just replace the compare with _ (C9 5F) with 08 for backspace.
A trick by Jim W4JBM can be used to reuse the BELL handling (07) to a backspace.
Replace in inline.s
INLINAIM:
.endif
.ifndef CONFIG_NO_LINE_EDITING
cmp #$07
beq L2443
with
INLINAIM:
.ifndef CONFIG_NO_LINE_EDITING
cmp #$08
beq L2420
In the original KB9.BIN you can do that with
poke 9260,8
poke 9262,241

V2 adaptations to V1.2 by Eduardo Casino
(after applying all above)
The start address is moved to $2000 by changing this in header.s
.segment "HEADER"
.ifdef KBD
jmp LE68C
.byte $00,$13,$56
.endif
.ifdef KIM
jmp COLD_START
.endif
.ifdef AIM65
jmp COLD_START
jmp RESTART
.word AYINT,GIVAYF
.endif
.ifdef SYM1
jmp PR_WRITTEN_BY
.endif
Change line 493 init.s
.ifdef KIM
.byte "MOS TECH 6502 BASIC V2.0"
Assemble and link with
ca65 -D kb9 msbasic.s -o tmp/kb9v2.o -l tmp/kb9v2.lst ld65 -C kb9.cfg tmp/kb9v2.o -o tmp/kb9v2.bin -Ln tmp/kb9v2.lbl
KB6 V2
Change this in defines_kim.s (after applying all above)
CONFIG_SMALL := 1
Assemble and link with
ca65 -D kb9 msbasic.s -o tmp/kb6v2.o -l tmp/kb6v2.lst ld65 -C kb9.cfg tmp/kb6v2.o -o tmp/kb6v2.bin -Ln tmp/kb6v2.lbl
See the downloads for the binary files.

Another MOS TECH BASIC for KIM-1, lower serial number

Thanks Gerben Voort
See also:
TERC KIM-1 Interface set
6502 tester NMOS CMOS 1-8MHz
680x/650x Test system
Backbit Chip Tester PRO V2
Bug in the TTY KIM-1 monitor?
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
See also:
A demo of the new facilities in the KIM-1 Simulator 2.2.1
KIM-1 connectors: beware the Chinese cheap variants!
Magazines: Compute! and Compute II
All documents in the MTU pages are now clean and higher quality, about 50 new PDFs.
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?
- The byte in A is saved (917)
- the high nibble is shifted to the lower nibble (918-921)
- the nibble is converted to hex (922, calls hexta)
- the byte is restored and the low nibble converted to hex
- A is restored
- hexta masks off low nibble (928)
- convert A..F to ascii (929-932)
- convert hex to ascii and print(933-934)
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.
- read the first character (1154)
- pack it into INL lower nibble (1155)
- read the second character (1156)
- pack it into INL, shifting the lower nibble to high and shifting in the second nibble (1157)
- return byte from INL to A
PACK
- check if < '0' and error out with A > 0 (1164-1165)
- check if > ‘F’ and error out with A > 0 (1166-1167)
- if A..F add $09 (1168-1171)
- shift in nibble via INH and INL
- return zero if valid hex but with invalid Z flag
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
See also:
TERC KIM-1 Interface set
6502 tester NMOS CMOS 1-8MHz
680x/650x Test system
Backbit Chip Tester PRO V2
Programming tips
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!
TTY routines
Do not use the CRLF routine at $1E2F in the monitor
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.
SPACE print a blank
This just calls OUTCH with A = $20, so read OUTCH for the side effects.
PRTBYT Print A as two hex characters
Uses OUTCH, so Y is lost. A is preserved.
GETBYT and GETBYTC
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 audio tape routines
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.
Return to the KIM-1 monitor
The preferred location to call to enter the KIM-1 monitor form a user program is START at $1C4F
Reading the keyboard and lighting the display
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
See also:
TERC KIM-1 Interface set
6502 tester NMOS CMOS 1-8MHz
680x/650x Test system
Backbit Chip Tester PRO V2
TTY operation summary
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.
See also:
TERC KIM-1 Interface set
6502 tester NMOS CMOS 1-8MHz
680x/650x Test system
Backbit Chip Tester PRO V2
Serial interface with RTS CTS handshake
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
See also:
TERC KIM-1 Interface set
6502 tester NMOS CMOS 1-8MHz
680x/650x Test system
Backbit Chip Tester PRO V2
KIM-1 monitor data storage
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)
See also:
TERC KIM-1 Interface set
6502 tester NMOS CMOS 1-8MHz
680x/650x Test system
Backbit Chip Tester PRO V2
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 #$2F; ; 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