On the Utilities page I have two programs to convert to MOS Technology papertape format: KIMpaper, a command line utility, and ConvertHexFormat, a GUI app.
All in Freepascal/Lazarus source format, and tested on Linux (Raspberry PI OS) and Windows 10 64 bit. So the programs will run everywhere Lazarus is available (MS DOS, WIndows, Linux Mac OS).
KIMPAPER is written at the time the Micro-KIM appeared. CLI utility. Supports Binary to/from Papertape. Still runs fine on all platforms supported by Freepascal (Windows, MS DOS, Linux etc) after a recompilation, source available.
ConvertHexFormat is a more recent GUI utilitilty with many more 8 bit hex formats as input and output.
There were some bugs of course in older versions. V2 added the ability for multipart hex formats, records having a non-consecutive load address. That seems to wok fine since V2.1
In 2.2 a bug in MOS Papertape format for bigger files is fixed, the end-of-file record (record type 00, total line count) had a bug in the checksum calculation. KIMPAPER is and was correct in the calculation.
But in ConvertHexFormat it was wrong (as it still is in the well known srec utility in the Unix world!).
Programs to manipulate the binary and hex formatted files of interest for SBC owners. Intel hex, MOS papertape, Motorola S-record, binary, hex conversion fort eh 8 bit world.
Runs on Windows, Linux, Mac due to Lazarus and Freepascal. Source included.
The KIM-1 has two methods of loading programs:
– from audio files on the audio interface
– from papertape from a papertape reader connected to the teletype terminal
(Photos by Dave Wiliams with the MOS KIM-1 Reproduction)
The papertape method is the preferred way available for KIM-1 clone owners, since audio input input hardware is either not present or quite inconvenient and using terminal emulators is already the way we use these computers.
Now papertape format is a special MOS Technology format, already used in the TIM-1. See the KIM-1 user manual for a technical description.
This is for example the papertape output captured with the KIM-1 S command for the memory test program in the Fist Book of KIM
Load address, data and checksums are in the records.
What the dump above does not show that the KIM-1 inserts in front of every record a series of NULL characters (a character with value 0), to give the papertape device time to do its mechnica work and also helps the slow KIM-1 load routine to do its work after a line end of a record.
A part of a real dump:
Papertape format is therefore a readable text file, but when captured from a KIM-1 output contains NULL characters.
So if we could send the papertape formatted test file to the KIM, we can load programs.
This requires solutions for the following:
Make a papertape file The PC utilities section has programs to produce MOS papertape from binaries or other common 8 bit hex formats produced by assembler such as Intel hex, Motorola S-Record
Send a text file
Many terminal emulators that have support for serial allow to capture the serial output to a text file or send a text file to the serial input.
Good examples are nowadays Teraterm for Windows or Minicom for Linux.
Compensate for timing
The KIM-1 character routines are quite primitive and not rebust : bit-banged, not interrupt driven, no hardware ,handshake so no buffering and it is CPU intensive.
When you sent characters quite fast to the KIM-1 (and that means any baud rate from 1200 to 9600, and the KIM-1 also has to do some processing like processsing the record just received, it is to be expected the KIM-1 will be too late reading the next record, skip a record and sync at the next and leave the program received in chaso.
So we need to give time to the poor KIM-1.
1200 baud, 20 ms character delay, 200 ms line delay is conservative but reliable for me. It is slow ..
An example for Teraterm is shown here:
Decimal mode
The 6502 NMOS version is in unknown state after reset regarding decimal mode.
Most programs start with the CLD D8 instruction, but not all. Microsoft KIM-1 Basic v1.1 is one of those.
A section from the KIM Hints:
A number of KIM-1 customers have reported difficulty in achieving correct results for the sample problem shown in Sec. 2.4 of the KIM-1 User Manual. In addition, some customers have experienced problems in recording or playback of audio cassettes. (Sec. 2.5 of the KIM-1 User Manual). In all cases, the problems have been traced to a single cause: the inadvertent setting of the DECIMAL MODE.
The 6502 Microprocessor Array used in the KIM-1 system is capable of operating in either binary or decimal arithmetic mode. The programmer must be certain that the mode is selected correctly for the program to be executed. Since the system may be in either mode after initial power-on, a specific action is required to insure the selection of the correct mode. Specifically, the results predicted for the sample problem (Sec. 2.4) are based on the assumption that the system is operating in the binary arithmetic mode. To insure that this is the case, insert the following key sequence prior to the key operations shown at the bottom of Page 11 of the KIM-1 User Manual.
[AD]
[0] [0] [F] [1]
[DA] [0] [0]
This sequence resets the decimal mode flag in the Status Register prior to the execution of the sample program.
The same key sequence may be inserted prior to the key operations shown on pages 14 and 15 for audio cassette recording and playback. These operations will not be performed correctly if the decimal mode is in effect.
In general, whenever a program is to be executed in response to the [GO] key, the programmer should insure that the correct arithmetic mode has been set in the status register (00F1) prior to program execution.
Michael Kowalski created the 6502 Simulator many years ago. It simulated the MOS 6502, CMOS 65C02, and the 6501. Daryl Rictor took the sources and updated with 65816 assembler and emulator support to 16MB memory. He also translated the Polish help to English in CHM format. It is a Windows 32 bit program and runs fine on Windows 10 64 bit.
The debugger/simulator is still only 65(C)02.
You can write code, assemble it, and run it with a debugger with breakpoints, step by step etcetera.
How to use
Entering the source code
Open a blank source file by clicking on (File / New)
Type in your assembly language program
Save it by doing (File / Save as). Use the suggested extension of .65s for your filename.
Assembling the source code
Assemble the source code by clicking on (Simulator / Assemble).
If there are any errors in your code, an error message should come up at this point.
Using the debugger
Turn on the debugger by clicking on (Simulator / Debugger), or press F6.
Go to the View menu and make the following windows visible:
– 6502 Registers
– 6502 Memory
– Identifiers
Find the assembled machine code in the Memory window. It should match up with the codes on the handout.
A better way of looking at the code is to open the Disassembler window ( View / Disassembler ) which shows you clearly which instructions produced which machine code bytes.
The identifiers window tells you which memory locations have been set aside for the variables that you declared at the bottom of your program. That is all it is for really, so once you have seen that, you can close it.
Running the program
To run the program you have various options, all listed on the Simulator menu. The most useful one from a teaching point of view is ( Simulator / Step Into) or F11.
Arrange your windows so that you can see the source code, the memory window, and the registers window ( and the Dissassembler window if you want) and use F11 to start to step through the code.
After each instruction, look at the state of the registers, and satisfy yourself that the instruction has done what you expected it to. Also, when you do a Store to Memory instruction, you should see the value pop up in the appropriate place in the memory window.
When you have finished running the program, click on (Simulator / Restart Program) before trying to run it again.
Undocumented directives
In the file parse6502.cpp in the subfolder CrystalEdit you can read some assemble directives and I/O ports not documented in the Help.
Some are not documented in the Help but are in the sourcefile crytaledit/Parse6502.cpp
.ASCII
Directives defining values of single bytes using passed arguments.
Description
.BYTE (.DB, .ASCII) directives generates and defines single byte values. Input data might be entered in numerical or string form. Numerical expressions are also accepted.
.ROM_AREA
Directive establishing memory protection area
Syntax
.ROM_AREA addr_from_expr, addr_to_expr
Example
.ROM_AREA $a000, $afff
.ROM_AREA Start, * ; from ‘Start’ to here
Description
.ROM_AREA turns on memory protection for a given range of addresses. Any attempt to write to this area will stop program execution. Write attempts to the EPROM usually indicate a bug and memory protection can facilitate locating such bugs. Specifying same start and end address turns protection off
.IO_WND
Directive setting terminal window size.
Syntax
.IO_WND cols_expr, rows_expr
Example
.IO_WND 40, 20; 40 columns, 20 rows
Description
.IO_WND directive sets size of terminal window. It requires two parameters: number of columns and rows.
Both columns and rows are limited to 1..255 range.
IO_AREA
Label representing beginning of simulator I/O area.
Syntax
IO_AREA = addr_expr ; set I/O area IO_AREA ; use I/O area, default $E000
Example
IO_CLS = IO_AREA + 0 ; clear window port
STA IO_AREA+1 ; put char
Description
IO_AREA label represents beginning of simulator I/O area. Simulator can detect read and write attempts
from/to its I/O area.
Starting from IO_AREA address consecutive bytes are treated as virtual ports.”
(w) means write only port, (r) read only, (r/w) read/write.
TERMINAL_CLS – clear terminal window, set cursor at (0,0) position
TERMINAL_OUT – output single character interpreting control characters.
Terminal can only recognize those characters:
– $d char (caret) moving cursor to the beginning of line,
– $a char (line feed) moving cursor to the next line and scrolling window if necessary,
– 8 char (backspace) moving one position to the left and erasing char below cursor.
TERMINAL_OUT_CHR – outputs single character; control chars are being output just like regular characters.
TERMINAL_OUT_HEX – outputs single byte as a two-digit hexadecimal number.
TERMINAL_IN – input single byte, returns 0 if there’s no characters available in terminal’s buffer
– when I/O terminal window is active it can accept keyboard input;
– press Ins key to paste clipboard’s contents into terminal.
TERMINAL_X_POS – cursor X position (column).
TERMINAL_Y_POS – cursor Y position (row).
The Kowalski simulator includes a primitive I/O console, which is memory-mapped at a location declared with the IO_AREA pseudo-op. For example, IO_AREA=$D000 will map the console in at $D000.
; Wait for input test
; IO area of the simulator has to be set at the address $e000
; (Option/Simulator/InOut memory area)
; In/Out Window will only accept input when it has focus (is active)
*= $0600
io_area = $e000
io_cls = io_area + 0 ; clear terminal window
io_putc = io_area + 1 ; put char
io_putr = io_area + 2 ; put raw char (doesn't interpret CR/LF)
io_puth = io_area + 3 ; put as hex number
io_getc = io_area + 4 ; get char
LDA #$a
STA io_putc ; this will move cursor to the next line
STA io_putr ; this will print character
LDA #'>'
STA io_putc
.wait
LDA io_getc
BEQ .wait
STA io_puth
JMP .wait
BRK
Simulator
Compared to 6502 and 65C02 microprocessors, the simulator is characterized by the following different components:
There is no relationship between the speed of different opcodes.
Illegal codes in 6502 mode are not executed, but cause the program to stop.
Illegal codes in 65C02 mode are treated as NOP statements and do not cause the program to stop.
BRK, RTS, and $DB are privileged because one of them, depending on the settings, ends the program.
Reserved bits in the Status register (P) are always set to 1 (as in 65C02, but not in 6502).
With the simulator you can run a program assembled from the built-in editor. Or you can load an Intel Hex file, a Motorola S-record file or a binary file. The type is determined by the extension, so you may have to rename your hex files. The simulator makes all memory available, only the IO_AREA is special.
Several Windows Can be opened during a debug session: Processor Status and registers, Memory, Disassembly, Text Input/output, Stack, ZeroPage, Identifiers (from assembled symbol table)
Example code
A good example of a Kowalski program is the source of Lee Davison’a EhBasic Minimal Monitor
; minimal monitor for EhBASIC and 6502 simulator V1.05
; To run EhBASIC on the simulator load and assemble [F7] this file, start the simulator
; running [F6] then start the code with the RESET [CTRL][SHIFT]R. Just selecting RUN
; will do nothing, you'll still have to do a reset to run the code.
.include "basic.asm"
; put the IRQ and MNI code in RAM so that it can be changed
IRQ_vec = VEC_SV+2 ; IRQ code vector
NMI_vec = IRQ_vec+$0A ; NMI code vector
; setup for the 6502 simulator environment
IO_AREA = $F000 ; set I/O area for this monitor
ACIAsimwr = IO_AREA+$01 ; simulated ACIA write port
ACIAsimrd = IO_AREA+$04 ; simulated ACIA read port
; now the code. all this does is set up the vectors and interrupt code
; and wait for the user to select [C]old or [W]arm start. nothing else
; fits in less than 128 bytes
*= $FF80 ; pretend this is in a 1/8K ROM
; reset vector points here
RES_vec
CLD ; clear decimal mode
LDX #$FF ; empty stack
TXS ; set the stack
; set up vectors and interrupt code, copy them to page 2
LDY #END_CODE-LAB_vec ; set index/count
LAB_stlp
LDA LAB_vec-1,Y ; get byte from interrupt code
STA VEC_IN-1,Y ; save to RAM
DEY ; decrement index/count
BNE LAB_stlp ; loop if more to do
; now do the signon message, Y = $00 here
LAB_signon
LDA LAB_mess,Y ; get byte from sign on message
BEQ LAB_nokey ; exit loop if done
JSR V_OUTP ; output character
INY ; increment index
BNE LAB_signon ; loop, branch always
LAB_nokey
JSR V_INPT ; call scan input device
BCC LAB_nokey ; loop if no key
AND #$DF ; mask xx0x xxxx, ensure upper case
CMP #'W' ; compare with [W]arm start
BEQ LAB_dowarm ; branch if [W]arm start
CMP #'C' ; compare with [C]old start
BNE RES_vec ; loop if not [C]old start
JMP LAB_COLD ; do EhBASIC cold start
LAB_dowarm
JMP LAB_WARM ; do EhBASIC warm start
; byte out to simulated ACIA
ACIAout
STA ACIAsimwr ; save byte to simulated ACIA
RTS
; byte in from simulated ACIA
ACIAin
LDA ACIAsimrd ; get byte from simulated ACIA
BEQ LAB_nobyw ; branch if no byte waiting
SEC ; flag byte received
RTS
LAB_nobyw
CLC ; flag no byte received
no_load ; empty load vector for EhBASIC
no_save ; empty save vector for EhBASIC
RTS
; vector tables
LAB_vec
.word ACIAin ; byte in from simulated ACIA
.word ACIAout ; byte out to simulated ACIA
.word no_load ; null load vector for EhBASIC
.word no_save ; null save vector for EhBASIC
; EhBASIC IRQ support
IRQ_CODE
PHA ; save A
LDA IrqBase ; get the IRQ flag byte
LSR ; shift the set b7 to b6, and on down ...
ORA IrqBase ; OR the original back in
STA IrqBase ; save the new IRQ flag byte
PLA ; restore A
RTI
; EhBASIC NMI support
NMI_CODE
PHA ; save A
LDA NmiBase ; get the NMI flag byte
LSR ; shift the set b7 to b6, and on down ...
ORA NmiBase ; OR the original back in
STA NmiBase ; save the new NMI flag byte
PLA ; restore A
RTI
END_CODE
LAB_mess
.byte $0D,$0A,"6502 EhBASIC [C]old/[W]arm ?",$00
; sign on string
; system vectors
*= $FFFA
.word NMI_vec ; NMI vector
.word RES_vec ; RESET vector
.word IRQ_vec ; IRQ vector
Written in 1976, Microsoft BASIC for the 8 bit MOS 6502 has been available for virtually every 6502-based computer. Also for the SBC’s on this site: KIM-1, SYM-1, AIM 65 and as a port of Applesoft on the Apple 1.
Binary versions and manuals are on the pages dedicated to these machines:
Build binaries from source on a Linux system (Raspberry PI OS)
First install CC65 package, the assembler and linker are required.
You need the CC65 package, a C and Macro assembler and linker for the 6502.
https://github.com/cc65/wiki/wiki is broken, https://cc65.github.io/getting-started.html is fine.
git clone https://github.com/cc65/cc65.git
cd cc65
make
sudo make avail
Now get the MS Basic source and assemble the binaries
https://github.com/mist64/msbasic
git clone https://github.com/mist64/msbasic
cd msbasic
./make.sh
cd tmp
ls
and you will see a directory of binaries (.bin), symbol table (.lbl) and object files (.o)
Compare the binary files with the binary files in the msbasic/orig folder and you will see hopefullyy they are identical!
It is not only nice to see the source, now you are able to customize a Microsoft Basic to your likings.
Steps as advised in the pagetable description:
1. Create a .cfg file by copying an existing one.
2. Adapt the make file for the new target.
3. Change the platform specific source files
An example is this post by Gordon Henderson who made a serial interfaced Commodore Basic by creating a new variant and tweaking some conditionals, replacing the screen editor with the line editing interface of older versions.
and perhaps other Replica’s with the Propeller IC. Report by Didier.
Didier has 2 replica, the Red one Ten, the older one green, both With a propelle which had the same problem but it occurred rarely
in fact apparently all the Replica 1 with the Propeller IC ten are affected more or less by this problem.
Issue
Users have reported every few seconds a “/” appears on their screen followed by a linefeed. This renders any data entry impossible.
The Replica 1 seems to act like an antenna, moving hands above the Replica can trigger it.
The problem is reported by Reactive Micro as Screen Noise Issue.
Try adding a 100k resistor to the USB module as pictured below. And if there is still noise then add a .1uF cap (100nF) to Pin28 of the Propelelr to either Ground or +5v.
As little as 10k can be used for +3.3v pullup, but anything smaller risks damage to the FTDI module. 100k is much safer in all regards. This helps hold the data line high. It seems the RX line is held high by default. And both lines are held high when connected to a USB data port, which is why the noise issue is not seen when connected to a PC. You can connect the resistor most simply to the USB module. Or to the rear of the PCB to pin 39 (Tx) and pin 12 or 32 (+3.3v) of the Propeller.
Fix by Didier
The Reactive Micro fix dows only reduce the noise but does not stop it completely.
But adding two 2 resistors definitively fix the problem.
The real problem is the floating lines STROBE and DA of the Propeller.
To really understand this noise bug you need to check at the same time:
the circuit diagram, the Wozmon initialization, and the Propeller code
the other modification are for a change from a PIA to a PIAT for my 6502 monitor
PIAT (6524) = PIA 6250 + TIMER (as it is mounted with my patch the PIAT replace totally the PIA
without any software change)
2 lines CA and STROBE are input at the same time…
they are acting like an antenna and capturing noise
for example, if I pass my hand 5 cm above the propeller
I start to see:
/
/
as if the replica was resetting.
In fact, when the replica received a full buffer of junk it jumps to reset code…
The problem comes from the propeller code…
STROBE is programmed sometimes as input and sometimes as output to permit both the PS/2 and ASCII keyboard
it is possible to fix the propeller code to avoid the parasite but in that case, you lose the ASCII keyboard
To fix that on the back of the board add a resistor of 10K between the STROBE PIN and GND
The same problem occurs for the DA line but it only happens during the time the machine was powered up but not yet reset… the same way a 10K resistor between DA PIN and GND fix the problem
The fix for STROBE and DA is therefore two resistors added on the back of the PIA.
Willem Aandewiel designed a tape device for the (micro)KIM. With a Wemos D1, ES8266 and ATTiny and some clever software to make the KIM believe a audio cassette recorder is connected.
All details here on Willem’s website.
The device in action:
https://youtu.be/R_zD5T_khKs
Willem has now published the next generation, together with a 32K RAM card, of this device.
Demonstrates his design for a cassette interface for the Micro-KIM single board computer from Briel Computers (a replica of the 1970’s KIM-1 SBC). The original KIM-1 has a built-in cassette interface, but the Micro-KIM replica does not, so I designed and built his own. The design uses a single PIC micro-controller, is very reliable, supports all HyperTAPE speeds, and has the ability to save and play back recorded data into the KIM-1.