If anyone wants to look over my start to some 4004 emulation, I've attached a zip of what I've been working on the last few nights. I've tested most of the opcodes, but not all of them yet. One thing I'm still considering changing about it is that I am storing a lot of nibbles in unsigned char which is a bit wasteful, but I'm trying to balance that against the performance loss of extracting and packing nibbles into bytes. I may try that and see how it does.
Where I want this project to go is first I plan on making a console application for it (WIN32), but I should be easily able to adapt it to DOS and CP/M as well. I've been wanting to make a control panel type CPU emulation project for awhile, but it is always the input side of things (switches, keys, etc.) that makes the UI unwieldy on a hardware board and just not quite what I'm looking for. Then I had the idea of what about making a smaller mini hardware board that has blinky lights for output, but not a real control panel. Instead it will be controlled through a serial port that has a monitor/debug type interface. Maybe that would be the best of both worlds. So, my first plan is console applications, then my second plan is to migrate them to an AVR based board with some LED's. The control/monitor is external to the emulation, not running inside the emulated CPU.
Here is what I have so far for the monitor interface:
The assemble function won't be a real assembler, but like how DOS DEBUG does it where you can assemble instructions on the fly, but there won't be any labels. I'd really like to be able to make it an environment where, like BASIC, one could sit there with it and assemble instructions to build a test program and step them to see how they work. The registers command would show during those steps like this:
R0=F R1=0 R2=F R3=0 R4=F R5=0 R6=F R7=0 R8=F R9=0 RA=F RB=0
RC=F RD=0 RE=F RF=0 S1=000 S2=000 S3=000 ACC=F DCL=7 SRC=FF NC
PC=000 1234 JUN 123
Not all commands would be present, Q/LF would be for a console program (WIN32/DOS/CPM) only, and LX would be for AVR only. Everything would be in hex except the T/throttle command.
One of the challenges with the 4004 was that it has different address spaces, so if you use the dump command for example, you can let it pick the last one, or you could specify one like "d pgm:0" to dump program memory starting at address 0. I'm thinking about these address spaces so far. This is 16x 4001 ROM's and 32x 4002 RAM's.
pgm: 0-FFF bytes program memory
pgmi: 0-F nibbles program memory input port
pgmo: 0-F nibbles program memory output port
data: 0-7FF nibbles data memory
datao: 0-1F nibbles data memory output port
stat: 0-1FF nibbles status memory
I'm probably biting off more than I can chew; I tend to do that with projects, but ultimately my test application for this would be to see if I can write an Enigma M4 machine emulator that runs on it. One thing I need for that is a serial interface accessible inside the 4004 emulation layer, and my plan so far on that is to use I/O ports. One 4 bit output port, one 4 bit input port, and then two control lines (1 bit input, 1 bit output). Using this the 4004 can communicate outside of its emulation to the AVR which can then handle the UART, etc. Theoretically an AVR could be also made to be an I/O processor for a real 4004 that works the same way.
Where I want this project to go is first I plan on making a console application for it (WIN32), but I should be easily able to adapt it to DOS and CP/M as well. I've been wanting to make a control panel type CPU emulation project for awhile, but it is always the input side of things (switches, keys, etc.) that makes the UI unwieldy on a hardware board and just not quite what I'm looking for. Then I had the idea of what about making a smaller mini hardware board that has blinky lights for output, but not a real control panel. Instead it will be controlled through a serial port that has a monitor/debug type interface. Maybe that would be the best of both worlds. So, my first plan is console applications, then my second plan is to migrate them to an AVR based board with some LED's. The control/monitor is external to the emulation, not running inside the emulated CPU.
Here is what I have so far for the monitor interface:
Code:
A [address] Assemble
B [breakpoint] [-breakpoint] Breakpoints
C range target Copy
D [address] Dump
E [address] Enter
F range data Fill
G [address] Go
I [=address] [qty] Step into
K range target Compare
LI <range> Load intel hex
LX <range> Load xmodem
LF <range> <file> Load file
M [key] Monitor break key
O [=address] qty Step over
P [on|off] Performance update (displayed every 10 seconds)
Q Quit
R [assignment] [assignment] Registers
SI <range> Save intel hex
SX <range> Save xmodem
SF <range> <file> Save file
T [speed|off] Throttle (speed is decimal cycles per second)
U [address] Unassemble
X Address spaces
Z range data Search
The assemble function won't be a real assembler, but like how DOS DEBUG does it where you can assemble instructions on the fly, but there won't be any labels. I'd really like to be able to make it an environment where, like BASIC, one could sit there with it and assemble instructions to build a test program and step them to see how they work. The registers command would show during those steps like this:
R0=F R1=0 R2=F R3=0 R4=F R5=0 R6=F R7=0 R8=F R9=0 RA=F RB=0
RC=F RD=0 RE=F RF=0 S1=000 S2=000 S3=000 ACC=F DCL=7 SRC=FF NC
PC=000 1234 JUN 123
Not all commands would be present, Q/LF would be for a console program (WIN32/DOS/CPM) only, and LX would be for AVR only. Everything would be in hex except the T/throttle command.
One of the challenges with the 4004 was that it has different address spaces, so if you use the dump command for example, you can let it pick the last one, or you could specify one like "d pgm:0" to dump program memory starting at address 0. I'm thinking about these address spaces so far. This is 16x 4001 ROM's and 32x 4002 RAM's.
pgm: 0-FFF bytes program memory
pgmi: 0-F nibbles program memory input port
pgmo: 0-F nibbles program memory output port
data: 0-7FF nibbles data memory
datao: 0-1F nibbles data memory output port
stat: 0-1FF nibbles status memory
I'm probably biting off more than I can chew; I tend to do that with projects, but ultimately my test application for this would be to see if I can write an Enigma M4 machine emulator that runs on it. One thing I need for that is a serial interface accessible inside the 4004 emulation layer, and my plan so far on that is to use I/O ports. One 4 bit output port, one 4 bit input port, and then two control lines (1 bit input, 1 bit output). Using this the 4004 can communicate outside of its emulation to the AVR which can then handle the UART, etc. Theoretically an AVR could be also made to be an I/O processor for a real 4004 that works the same way.