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: 6502
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
The KIM-1, TIM and Jolt explained
During the hot summer days, locked up in house because of the heat, I made a deep dive into the KIM-1 and the TIM/Jolt software and hardware.
50 years of working with a KIM-1:
The KIM-1 Explained
The Jolt, one of the first 6502 SBC’s, so nicely reproduced now:
The TIM/Jolt explained.
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.
Jolt manuals and documents
Documents
|
Jolt Replica User manual |
|
Jolt User Newsletter |
![]() |
DEMON software manual (this manual has an alternative listing of the TIM 6530-004 monitor) |
See also:
TERC KIM-1 Interface set
6502 tester NMOS CMOS 1-8MHz
680x/650x Test system
Backbit Chip Tester PRO V2
Alter memory or registers
Sample session
* 7052 B0 00 FF 00 FF .M 0200 00 00 00 00 00 00 00 00 .: 0200 33 44 55 .M 0200 33 44 55 00 00 00 00 00 .R 7052 B0 00 FF 00 FF .: 3455 55 55 55 55 55 .R 3455 55 55 55 55 55 .M 00F6 55 34 55 55 55 55 55 02 .M 7000 85 F9 A9 23 D0 55 A9 16 .: 7000 77? .? .
The ‘:’ command reacts different upon previous actions:
- if the previous command was M, the current address types in with M is printed and bytes can be typed in that will be placed at the current PC. The current address is incremented and the next byte can be entered, till maximum 8 are entered 85
- if the previous command was R the program counter has to be typed and the 5 registers PS A X Y Z (or less by pressing ENTER).
- after a ‘:’ command, the next ‘:’ will behave the same as following the M command
Note the current address and the Program Counter are not the same. The GO command requires the Program Counter to be set to the desired address.
0282 70E0 ; 0283 70E0 ; READ AND STORE BYTE. NO STORE IF SPACE OR RCNT=0. 0284 70E0 ; 0285 70E0 20 B3 73 BYTE JSR RDOB ; CHAR IN A, CY=0 IF SP 0286 70E3 90 10 BCC BY3 ; SPACE 0287 70E5 ; 0288 70E5 A2 00 LDX #0 ; STORE BYTE 0289 70E7 81 EE STA (TMP0,X) 0290 70E9 ; 0291 70E9 C1 EE CMP (TMP0,X) ; TEST FOR VALID WRITE (RAM) 0292 70EB F0 05 BEQ BY2 0293 70ED 68 PLA ; ERR, CLEAR JSR ADR IN STACK 0294 70EE 68 PLA 0295 70EF 4C BA 70 JMP ERROPR 0296 70F2 ; 0297 70F2 20 7C 72 BY2 JSR CADD ; INCR CKSUM 0298 70F5 20 97 73 BY3 JSR INCTMP ; GO INCR TMPO ADR 0299 70F8 C6 FE DEC RCNT 0300 70FA 60 RTS
BYTE
What is happening here?
- Read a byte (two hex characters) (285)
- if space skip writing databyte (286, 289)
- store as binary in current address and increment current address (289)
- if databyte read back is not equal databyte then error out of caller also (291-295)
- add to checksum (checksum is part of L command) (297)
- increment address to store into (298)
- decrement number of bytes to write (299)
0272 70D0 A5 EE PUTP LDA TMP0 ; MOVE TMP0 TO PCH,PCL 0273 70D2 85 F6 STA PCL 0274 70D4 A5 EF LDA TMP0+1 0275 70D6 85 F7 STA PCH 0276 70D8 60 RTS 0302 70FB A9 F8 SETR LDA #FLGS ; SET TO ACCESS REGS 0303 70FD 85 EE STA TMP0 0304 70FF A9 00 LDA #0 0305 7101 85 EF STA TMP0+1 0306 7103 A9 05 LDA #5 0307 7105 60 RTS
PUTP
Move current address in TMP0 to Program Counter PCL
SETR
- The address of the saved registers is loaded in TMP0, TMP0+1
- A is laoded with 5, to let DSPLYM show the registers SP A X Y Z
0349 713A ; ALTER LAST DISPLAYED ITEM (ADR IN TMPC) 0350 713A ; 0351 713A C6 E9 ALTER DEC PREVC ; R INDEX = 1 0352 713C D0 0D BNE A3 0353 713E ; 0354 713E 20 A4 73 JSR RDOA ; CY=0 IF SP 0355 7141 90 03 BCC A2 ; SPACE 0356 7143 20 D0 70 JSR PUTP ; ALTER PC 0357 7146 20 FB 70 A2 JSR SETR ; ALTER R*S 0358 7149 D0 05 BNE A4 ; JMP A4 (SETR RETURNS ACC = 5) 0359 714B 20 9A 72 A3 JSR WROA ; ALTER M, TYPE ADR 0360 714E A9 08 LDA #8 ; SET CNT=8 0361 7150 ; 0362 7150 85 FE A4 STA RCNT 0363 7152 20 77 73 A5 JSR SPACE ; PRESERVES Y 0364 7155 20 E0 70 JSR BYTE 0365 7158 D0 F8 BNE A5 0366 715A F0 D8 A9 BEQ BEQS1 0345 7134 4C 86 70 BEQS1 JMP START
What is happening here?
- decrement previous command index(set in START) :=1 R=2 M=3 (351-352)
- if > 0 then M command, also resets R command mode (358)
- else previous was R command: read address and put in Program counter (354-358, 362)
- set current address to registers (FLGS) and 5 bytes to write (357)
- M command: show address, 8 bytes to write (360-361
- loop bytes to write
- print space (363)
- read and store byte (if not space) (364)
- if error entering byte then error out via BYTE
- until all bytes to write are done(365)
- back to START for next command 366, 345)
See also:
TERC KIM-1 Interface set
6502 tester NMOS CMOS 1-8MHz
680x/650x Test system
Backbit Chip Tester PRO V2
ASCII Conversion Routine
A very compact and obscure looking routine. But a clever use of the Carry flag underneath!
0673 7358 18 ASCII CLC 0674 7359 69 06 ADC #6 0675 735B 69 F0 ADC #$F0 0676 735D 90 02 BCC ASC1 0677 735F 69 06 ADC #$06 0678 7361 ; 0679 7361 69 3A ASC1 ADC #$3A 0680 7363 48 PHA ; TEST FOR LETTER B IN ADR DURING WBNPF 0681 7364 C9 42 CMP 'B' ; 0682 7366 D0 0A BNE ASCX 0683 7368 A5 FD LDA SAVX 0684 736A C9 07 CMP #NCMDS 0685 736C D0 04 BNE ASCX ; NOT WB CMD 0686 736E 68 PLA 0687 736F A9 20 LDA ' ' ; FOR WB, BLANK 0'S IN ADR 0688 7371 48 PHA 0689 7372 68 ASCX PLA 0690 7373 60 RTS
ASCII
Convert the low nibble in A to ASCII hex. Call it with the upper nibble containing 0.
A returned has the ASCII equivalent of the byte value.
What is happening here?
- clear the Carry flag (673)
- A is shifted into a range that later allows the Carry flag to distinguish between numeric digits (0–9) and alphabetic digits (A–F) (674)
- Adding $F0 causes only values A–F to generate a carry.(675)
Input Accumulator Carry 0–9 $F6–$FF 0 A–F $00–$05 1 - Carry is clear, the value was 0–9. Otherwise an extra ADC $06 is executed before the final addition.(677)
- Add $3A to make it ASCII ((679)
- if the character is ‘B” and the current command is WH BNPF repalce with ‘ ‘
to suppress illegal characters in the BNPF format
Note that suppressing ‘F’ is also part of the BNPF format definition. It is not done on the TIM for unknown reasons.
Examples
Input = 5
5 + 6 = 11 11 + $F0 = $FB Carry=0 $FB + $3A = $35 ASCII '5'
Input = A (10)
10 + 6 = 16 16 + $F0 = $00 Carry=1 00 + 6 + C = $07 07 + $3A = $41 ASCII 'A'
See also:
TERC KIM-1 Interface set
6502 tester NMOS CMOS 1-8MHz
680x/650x Test system
Backbit Chip Tester PRO V2
Write hex routines
These routines are called from the command handlers to display data.
0537 729A ; WRITE ADR FROM TMP0 STORES 0538 729A ; 0539 729A A2 01 WROA LDX #1 0540 729C D0 0A BNE WROA1 0541 729E A2 05 WROA4 LDX #5 0542 72A0 D0 06 BNE WROA1 0543 72A2 A2 07 WROA6 LDX #7 0544 72A4 D0 02 BNE WROA1 0545 72A6 A2 09 WRPC LDX #9 0546 72A8 B5 ED WROA1 LDA TMP0-1,X 0547 72AA 48 PHA 0548 72AB B5 EE LDA TMP0,X 0549 72AD 20 B1 72 JSR WROB 0550 72B0 68 PLA
[/code]
0551 72B1 ;
0552 72B1 ; WRITE BYTE – A = BYTE
0553 72B1 ; UNPACK BYTE DATA INTO TWO ASCII CHARS: A=BYTE; X,A=CHARS
0554 72B1 ;
0555 72B1 48 WROB PHA
0556 72B2 4A LSR A
0557 72B3 4A LSR A
0558 72B4 4A LSR A
0559 72B5 4A LSR A
0560 72B6 20 58 73 JSR ASCII ; CONVERT TO ASCII
0561 72B9 AA TAX
0562 72BA 68 PLA
0563 72BB 29 0F AND #$0F
0564 72BD 20 58 73 JSR ASCII
[/code]
0565 72C0 ; 0566 72C0 ; WRITE 2 CHARS - X,A = CHARS 0567 72C0 ; 0568 72C0 48 WRTWO PHA 0569 72C1 8A TXA 0570 72C2 20 C6 72 JSR WRT 0571 72C5 68 PLA
See also:
TERC KIM-1 Interface set
6502 tester NMOS CMOS 1-8MHz
680x/650x Test system
Backbit Chip Tester PRO V2
Additions to the EMMA system documentation
Additions to the EMMA system documentation, thanks Keith Norman
![]() |
Emma Hardware Manual |
![]() |
Eprom Programmer |
![]() |
Mac User Manual |

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.
CRLF to serial
0104 0000 CRDLY =227 $E3 ;DELAY FOR CR IN BIT-TIMES 0162 701E A0 01 LDY #1 ; SET TO MEASURE 2 BITS 0163 7020 84 E3 STY CRDLY ;INIT OR DELAY TIME PARAMETER 0565 72C0 ; 0566 72C0 ; WRITE 2 CHARS - X,A = CHARS 0567 72C0 ; 0568 72C0 48 WRTWO PHA 0569 72C1 8A TXA 0570 72C2 20 C6 72 JSR WRT 0571 72C5 68 PLA 0572 72C6 ; 0573 72C6 ; WRITE SERIAL OUTPUT 0574 72C6 ; A = CHAR TO BE OUTPUT 0575 72C6 ; 0576 72C6 20 1D 73 WRT JSR DLY2 ... 0528 728A A2 0D CRLF LDX #$0D 0529 728C A9 0A LDA #$0A 0530 728E 20 C0 72 JSR WRTWO 0531 7291 A6 E3 LDX CRDLY ;BIT-TIME COUNT FOR DELAY 0532 7293 20 1D 73 CR1 JSR DLY2 ;DELAY OF ONE BIT-TIME 0533 7296 CA DEX 0534 7297 D0 FA BNE CR1 0535 7299 60 RTS
WRTWO
– print characters in X and A, A first via WRT
– fall through in WRT.
CRLF
– print CR and LF via WRTWO
– wait (CRDLY * serial bit time)
The wait can be extended by increasing the default of CRDLY of 1, obviously to give a slow teletype a chance to perform a CRLF.





