In Circuit EPROM emulator and debugger

Using, learning, programming and modding the Gigatron and anything related.
Forum rules
Be nice.
Post Reply
gesari
Posts: 29
Joined: 11 Apr 2019, 07:15
Location: Valladolid, Spain
Contact:

In Circuit EPROM emulator and debugger

Post by gesari » 17 Apr 2019, 13:25

I'm planing to use the Gigatron as a teaching tool for computer science because I think it fills very well the link between simple digital circuits, like decoders or counters, and microprocessors. The main problem for this is the EPROM. Its erasing time is too long and you have to remove it every time you want to test an student code. So, I think the first thing I'm going to do after ordering a gigatron is to design a ROM emulator to overcome the burden of EPROM erasing and programming.
ISDebug.gif
ISDebug.gif (15.57 KiB) Viewed 216 times
The block diagram of such a circuit is that of the figure. Here the EPROM role is played by an equivalent SRAM, whose contents have been previously loaded by a microcontroller.

Notice that the address lines of the RAM can't be generated by the microcontroller because that would create an electrical contention with the Gigatron's PC. Address lines are always inputs to the microcontroller. The main idea here is to use the PC as an address counter and, in order to do this, the clock signal of the Gigatron is also generated by the microcontroller. It is not necessary to remove the crystal, the low impedance output of the microcontroller is going to override the clock signal.

Program ROM emulation
The PC reset is not connected here, therefore the first thing we have to do to load a ROM image into the RAM is to reset the PC by means of these operations:

1 - Put a 'LD $00,Y' opcode in the data bus.
2 - Pulse CLK.
3 - Put a 'JMP Y,$00' opcode in the data bus.
4 - Pulse CLK.
5 - put a 'NOP' opcode in the data bus.
6 - Pulse CLK.

Using a similar trick we can load any address into the PC. After reset the RAM loading is going to be done this way:

1 - Put memory content in the data bus.
2 - Pulse /WE. This stores the data in the RAM.
3 - Put a 'NOP' opcode in the data bus.
4 - Pulse CLK. This increments the PC.

After loading another reset sequence will put the PC pointing at zero. Then we can change the data lines as inputs to the microcontroller, lower the /OE signal, and start to pulse the CLK signal at maximum speed to execute the newly loaded code.

Debugger

This circuit can also do a lot of interesting things. In fact, it can debug programs step by step. This means the microcontroller has to:

1 - Stop execution. No problem because we are controlling the clock.
2 - Load and save the Gigatron state. This means reading the values of the Gigatron's registers and also possibly some of the data RAM.
3 - Show the state to the user and wait for it's command.

A resume execution command will need to:

4 - Restore the Gigatron state by writing the modified registers with their original values.
5 - Continuing applying clock pulses.

Reading state

Lets see how to read the Gigatron state:

1 - The PC value can be read directly from the EPROM address bus.
2 - Executing a 'JMP Y,xx, NOP' we can get the value of the Y register in the high address lines.
3 - Executing a 'LD AC,Y, JMP Y,xx, NOP' sequence we can read the accumulator value.
4 - Executing a 'LD IN,Y, JMP Y,xx, NOP' sequence we can read the input register.
5 - The X register is more difficult to read, but not impossible. One possible way would be:

5.1 - Read the page zero data. This data is also of interest, so this step was going to be taken anyway. This is achieved by executing 256 'LD [nn],Y, JMP Y,xx, NOP' sequences.
5.2 - Write all the zero page bytes with zeros by executing a 'LD $0,AC' followed by 256 'ST AC,[nn]' instructions.
5.3 - Execute a 'LD $1,AC, ST AC,[X]' sequence.
5.4 - Read the zero page data and stop when the value read is one. The count gives us the value of the X register.

The OUT and XOUT registers can't be read, but as they are used for video/audio generation their particular value is of little interest. And the LED value can be read by just looking at the Gigatron.

Restoring state

This is going to be easier. Let see:

1- X, OUT, and XOUT registers were unchanged.
2- The page zero data has to be written with its original values. This can be done with 256 sequences of 'LD dd,AC, ST AC,[nn]'
3- The AC value is restored with a single 'LD dd,AC'
4- Then follows the PC. First compute PC-1, and then execute 'LD hh,Y, JMP Y,ll',where hh and ll are the high and low bytes of PC-1.
5- Finally we restore the Y register by executing 'LD nn,Y'. This also increments the PC, which now points to the same address it has when the execution was stopped.

More features

The contents of the program memory and data memory can be read, allowing for disassembling and memory dumps.

The first one requires to change the data pins to input in the microcontroller and to enable the /OE line of the program RAM for read. Then disable /OE, put the data pins as outputs, place a NOP in the data pins, and pulse clock for the next address.

For the data RAM any position can be read with the instruction sequence 'LD hh,Y, LD [Y,ll],AC, LD AC,Y, JMP Y,xx, NOP', where hh and ll are the high and low bytes of the address.

Breakpoints can also be implemented in two different ways:

- Address breakpoint: The PC value is read in each clock cycle, compared to the breakpoint, and if a matching is found the clock is stopped. This will slow down the clock generation, and should be restricted to a single breakpoint.

- Instruction breakpoint: First we need an unused op-code, like 'LD IN,[Y,X++],OUT' to be used as a breakpoint. Then we replace with this op-code the places of the program memory where the execution is going to stop. For each clock cycle we read the op-code at the output of the program memory and if it is a BREAK the clock is stopped. Then the original content of the program memory can be restored before resuming execution.

Clock generation

In order to run code real time a fast microcontroller will be needed. I'm thinking about using an LPC1114 (ARM cortex-M0) running at 48MHz for this project. Also, the clock signal can be mapped to a PWM output, obtaining up to 24MHz. Unfortunately, the 6.25MHz is not obtainable, but 6MHz is and I hope a -4% error in the frequency is going to be tolerated by most VGA monitors.

If the clock is generated by program its frequency is going to be lower, but still the MHz range can be achieved. We'll probably have to generate the clock while checking the address or data for breakpoints. This will require about 14 cycles of the ARM CPU per one Gigatron cycle, lowering the frequency to around 3MHz.

User avatar
marcelk
Posts: 252
Joined: 13 May 2018, 08:26

Re: In Circuit EPROM emulator and debugger

Post by marcelk » 17 Apr 2019, 17:39

Thanks, this is a promising, cool and useful project! I remember at67 built a ROM switcher one year ago, but this takes it a whole lot further...

gesari
Posts: 29
Joined: 11 Apr 2019, 07:15
Location: Valladolid, Spain
Contact:

Re: In Circuit EPROM emulator and debugger

Post by gesari » 19 Apr 2019, 10:23

A first schematic is attached.
Attachments
gt2_ISD_schematic.pdf
Schematic
(57.6 KiB) Downloaded 25 times

gesari
Posts: 29
Joined: 11 Apr 2019, 07:15
Location: Valladolid, Spain
Contact:

Re: In Circuit EPROM emulator and debugger

Post by gesari » 25 Apr 2019, 19:10

Hi,

I completed the layout of the board. Finally I included a 10MHz crystal to get the micro running at 50MHz, so the 6.25MHz can be obtained dividing the clock by 8.
lay_top_corner.gif
lay_top_corner.gif (87.57 KiB) Viewed 153 times
Here you can see how the emulator gets placed on the EPROM socket of the Gigagtron. I had to make room at one corner to avoid colliding with the Gigatron's crystal. In any case long pins for the socked would be a good idea.

More figures and gerber files can be downloaded from here:

https://www.ele.uva.es/~jesus/gigatron/ISRD/

gesari
Posts: 29
Joined: 11 Apr 2019, 07:15
Location: Valladolid, Spain
Contact:

Re: In Circuit EPROM emulator and debugger

Post by gesari » 14 May 2019, 20:56

Hi,
Today I received the PCBs for the ROM emulator.
idrd1.jpg
idrd1.jpg (238.02 KiB) Viewed 91 times
And I assembled one board...
isrd2.jpg
isrd2.jpg (289.4 KiB) Viewed 91 times
isrd3.jpg
isrd3.jpg (260.02 KiB) Viewed 91 times
And after plugging it into the Gigatron, and of course some software tweaking, I was able to load a ROMv3 image from an SD card and to run it
isrd4.jpg
isrd4.jpg (391.02 KiB) Viewed 91 times
isrd5.jpg
isrd5.jpg (379.46 KiB) Viewed 91 times
There is still a lot of software to be done before getting a full featured debugger, but the basic functionality seems to be working.

gesari
Posts: 29
Joined: 11 Apr 2019, 07:15
Location: Valladolid, Spain
Contact:

Re: In Circuit EPROM emulator and debugger

Post by gesari » Yesterday, 07:40

It was hard to achieve, but I finally can run the ROM emulator at full speed (6.25MHz) with breakpoints enabled.
I had to use a NOP op-code for breakpoints because these instructions are executed before stopping the clock. This gives me an extra 8 ARM cycles to disable the PWM wave of clock, and the timing is still tight...
I choose the op-code 0x4E (OR AC,AC with [Y,X] in MAU) for the breakpoint. I hope nobody is planning to use this instruction for program ROMs...

Post Reply