A boxed Synertek VIM-1

A boxed VIM-1 acquired in August 2026. More SYM-1 photos here.


SYM-2 prototype

In August 2026 I acquired an boxed engineering SYM-2 prototype. It comes with two large circuit diagrams illustrating the design.


Next photos by Paul Schroeter.




Jolt with 4K images

With thanks to Jonathan Chapman of Glitchworks who found a Jolt system, here images of a Jolt with 4K memory, an experimenters board and the power supply.

Here the images

post

Jolt with 4K and power supply

With thanks to Jonathan Chapman of Glitchworks who found a Jolt system, here images of a Jolt with 4K memory, an experimenters board and the power supply.

As received

Memory

Power supply

Parts unused

Packaging

KB-9, MOS TECH BASIC for the 6502

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.

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


How to build and adapt KB-9 and KB-6

Sources of KB-9 Microsoft Basic v1.1

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)

  1. Download and unpack the archive of pagetable in a folder on your PC.
  2. Download and unpack the CC65 package, a C compiler, from which only the assembler and linker is used. I used the Windows binaries.
  3. 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:

  1. To save you the work I have collected the adaptations described above in this archive for your convenience here.
  2. 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.
  3. 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
  • Repeat step 4 and 5 until you are satisfied with the adaptations. The articles listed are a good source of inspiration.
  • 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+1
      

      Change 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

    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.

    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)

    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)