socz80: A Z80 retro microcomputer for the Papilio Pro

Will Sowerbutts

Recommended Posts

Thanks - that's useful to see for things like the pipelining which I've managed to avoid so far for most of it although I think as I've got buffers on the syncs my pixels are probably one pixel clock out at the moment.


I've attached 32K of video RAM (leaves only 2 RAM16BWERs free) which is almost enough to be ideal but not quite.


In the end I deleted most of the original, split it into more processes and turned it into a trivial machine which executes a series of 16 2bit wide codes in a loop. The codes being

               - Load the next byte of video RAM for the next pixel

               - Hold the current pixel

               - Rotate to the next pixel in the byte

               - Spare


Video modes supported at this point are 640/320/160 rows at 1/2/4 bpp. Depth is currently always 480 because I want to improve the driver to read scan bases from a list each scan line. That will allow for scrolling sensibly but also ensure that 640x480 text mode is useful (all the blank lines between text can point to the same scan without which it won't fit in 32K). Since that gives you x 240 modes I didn't see the point in adding a hardware scan doubler.


Also need to work out how to do arrays of registers so I can d a 256 entry colour table, which will make it possible to do full colour mode (but with quite chunky pixels) and colour chaining mode (where the colour of a pixel is used as the top bits of the colour of the next pixel)


That, vblank and hblank interrupts and a pixel level soft scroll register ought to keep me occupied for quite a while 8)


But it works.. and it's currently showing a very bad retro mono picture of a Papilio Logic Wing 8)



Link to comment
Share on other sites

Had a chance to play a bit more with this. I have a feeling the timing violation that you get even with the base build is actually mattering now. When I try and put all the bitmap video bits together with SocZ80 I get a lot of strangeness including things like corruption on the uart, cases where the Z80 executes code but if I swap a single fetch from video ram in the video code for a constant it doesn't etc.


I guess it's struggling to route all the block RAMs.


If I give it 4K of video RAM and run a text mode state machine with your font ROM and my VGA clock generators a bit of debugging all seems to be working ok. For the moment people will have to live with 128 text characters with configurable foreground/background/bright colours or inverse video. Both 80x30 and a nice retro 40x30 are supported so you can run 40x30 with white chunky writing in white on blue.


Need to tidy a few of the other bits up some more and go through the Intel paperwork formalities to release this as an own time project but then I'll make it available for everyone to laugh at my VHDL. I know there are some definite design mistakes in the video, in particular I should have clocked the video engine at twice the pixel clock. On the other hand given it works at the pixel clock and accesses the RAMs one after another it ought to be able to do 1080i ;-) with some tweaking.


VHDL does seem to be somewhere half way between programming and sticking your head in a blender. Its the first language I've dealt with where the result is the answer to the question you asked last time (or frequently the time before that...).



Link to comment
Share on other sites

Sounds great. :) I got a good chuckle out of that last bit. I put the order in for the Classic Computing Shield in today, should get verification soon and boards in a week and a half. Oh, and I did add a Grove connector to the board for RTC clocks... Anyway, if the board tests out correctly I will try to get a prototype of the DUO and the CC shield to you.



Link to comment
Share on other sites

Much strangeness going on.


I tried dropping it to 64MHz but then the DRAM or cache breaks somewhere (eg rread 200 fails part way with a random address change). I set the clock divider 0 to 8 (from 4) and also  adjusted clk_freq_mhz. If I remember correctly Will you said you'd run it at a lower clock when trying to make SMP work. Were there any other bits of magic needed that aren't in the base source ?


I'm not sure its overclocking problems but I'd like to run it in a state where the tools at least agree it should work to eliminate that cause.

Link to comment
Share on other sites



I agree running it in a state where the synthesiser says "yes, I'm confident that can work!" would be preferable :) I'd love to really understand why the timing error exists at 128MHz and what I can do to change the design to meet timing.


The breakage is almost certainly in the DRAM. At a slower clock speed the data from the DRAM arrives at the input pins in fewer clock cycles.


I think that you can just tinker with the length of the "data_ready_delay" vector in SDRAM_Controller.vhd to adjust when the data is read. You need to reduce its length from 5 down to 2 or 3 bits, I expect.


To test in the monitor: Write a value to RAM, then read a value from another address that aliases to the same cache line (eg addr+16K), then read back the first address you wrote to.



Link to comment
Share on other sites

Thanks I'll give that a go.


I did start reading some of the guidance on fixing timing delays but its mostly over my head at this point. That said if the CPU and cache can be clocked at 128MHz I doubt clocking the rest at a lower speed would be noticable in performance ?


On the bright side a minimal video console is now working (only 80x25 chars, almost no control codes). That's enough to make the I/O handling that slight bit slower and enough to break sendmany with an overrun. Meh


I've mapped the video into bank 1 0x7000-0x7FFF and told CP/M the bank space available is 0100-6FFF (with CP/M 3 banked

itself running above that again). That means a bank switch on console I/O to the monitor but it also means the entire terminal emulation can live in banked RAM so won't intrude on the TPA.


Some interesting oddities left to deal with - 'trapdoor' and then rboot 200 makes a nasty mess as rboot doesn't force the MMU back sane, and due to the banking "uzi" and "mpmldr" both fail because they are somewhat surprised when they bank switch to discover that they were not in bank 0 and just entered hyperspace. uzi also dies because the SPI is now connected to the ADC and that upsets it greatly 8)


I have been trying to work out some kind of concept for actual platform so I don't have 500 CP/M BIOSen to field at the moment I've added the following to the memory and I/O map


0x201xxxx    => Video RAM


0xE0 => Feature bits (uart 0, uart 1, sd card on 0x30, joystick 0, 1, 2, vga out, ps/2 in)

0xE1 => Feature bits2 (audio out)


0xEC => Joystick 0

0xED => Joystick 1

0xEE => Joystick 2

(These will be mappable as AUX input in CP/M 3)


0xD8-0xDF => Video (with 0xDF identifying the device present if any)


0x80-0x87 => Wing #0  (and  I guess we'll need some for mixed setups)


Right now it just consists of identifier 0xFF (none), 0x01 (Logic WIng), in which case the I/O ports drive the seven segments


For the logic wing the switches are mapped to the GPIOs (and switch 0 is reset), and the LEDS to the GPIO outputs (with LED 4 hardwired to cpu wait at the moment as before).


Need to have a look at the clock divider some day too, although I'm thinking it may well be sufficient for many uses to tell the BIOS that if switch 2 is set it should spin each character output as if it were at 9600 baud. That'll probably make many games work ok!



Link to comment
Share on other sites

Hi Etched,


The controller for the memory has two timing components, one that is related to number of cycles to access data in the SDRAM, the other is related to the time-of-flight of data from the logic in the FPGA out to the SDRAM, and then the SDRAM's response time, and then the delay to get the data back into the FPGA. This second component adds up to about 13 ns or so regardless of the speed that the design is running at.


With clocks between 80 MHz through 120 MHz the delay takes the data into the next cycle. With clocks below about 65 MHz the data is available one cycle earlier. In between the two the data signals are not stable and the data can't be reliably captured.


This could be addressed by using a PLL or DCM to introduce the desired/required amount of phase shift between the SDRAM clock signal and the main logic, but the added complexity is well, awful.

Link to comment
Share on other sites

Not had time to play with the slower clock yet as a mix of real work and packing keeps getting in the way.


Text mode video is now working and I have a VT52 console on SocZ80 with a few small extensions for 40/80 columns etc. Still need my boss to return to get the paperwork done. It's alarming how well you remember processors you learned when about 12. I can still sit down and churn out Z80 without thinking !



Link to comment
Share on other sites

It has just come to my attention that in some cases back-to-back reads are broken in my SDRAM controller.


If the controller performs a back-to-back read to the same page it may end up stuck reading data until a refresh or another transaction interrupts it. The problem is that "got_transaction" is not reset to '0' during back-to-back reads, 


I'm just working on a test bench that exposes the flaw so I can verify the fix - the fix passes initial testing so if you think you may be experiencing this issue I can send you a patch ASAP.



Link to comment
Share on other sites

Thats a rather odd American quirk.. and not one I can rely upon. Plus quite frankly I don't want to use a font without proper credit and the intent of its author because that's just bad manners...


has the bits except for the font rom


(yeah some of the video driver is quite gross.. I'm still learning ok 8))



Link to comment
Share on other sites

  • 1 month later...
  • 1 year later...

Hi all, 

last November I received my Papillio Pro. One of the projects I immediatly tried out was  Will Sowerbutts SOCZ80. I really liked it, especially I started my computing experience with real CP/M computers in the beginning of the 80s. This included writing an own BIOS, etc. My old CP/M computer exists, but is not usable anymore because over the years all floppy disks get lost.

So working with SOCZ80 was a exactly what I searched for. In the meantime I did a lot of extension to it:

- Integration of a text mode video controller from open cores,interface_vga80x40
- PS/2 keyboard
- Adapted to use the Arcade Megawing for PS/2, VGA, GPIO LEDs, reset button
- Extended CP/M 2.2 BIOS and MPM XIOS to support PS/2 and VGA.
- ROM Monitor and boot loaders that can be used with VGA/PS/2 - so my extended version can be used as real stand-alone Computer when connected to power suplly, monitor and keyboard
- The simulated terminal supports ADM3A/TVI950 escape sequences instead of VT100. They are easier/smaller to implement and many CP/M programs have difficulty to generate VT100 seqeunces. The disadvantage is that the local console is incompatible with the serial console, because I'm not aware of any Windows Terminal Emulator supporting ADM3A
- The keyboard supports Wordstar compaitble Control characters for cursor keys. 
- For MP/M Console 0 is the Serial UART and Console 1 PS/2 / VGA. 

Other hardware / Software extensions:

- Added support to Interrupt Mode 2 to the hardware and adapted MP/M XIOS to it (this allows the use of normal CP/M debuggers under MP/M without crashing the systems because the XIOS is no longer using RST7 for interrupts)
- Fixed a bug in BIOS/XIOS with not taking into account that a CP/M DMA buffer can cross a 4K boundary. This occaisonally lead to data corruption e.g. when copying a file with CP/M PIP.COM


I also wrote a xmodem receive program in Turbo Pascal which makes transfering files a bit more easier.
I collected a lot of old Software like Wordstar, Mutiplan, CBASIC, MBASIC, Turbo Pascal, Microsoft Fortran etc. and configured it to run with the Video Terminal. 
I created some example programs in Turbo Pascal, MBASIC, CBASIC and even Fortran (it was the first Fortran program in my life -really fun :-) ).
I also collected things like Eliza and Startrek. I also adpated the MBASIC Startrek to compiled CBASIC. 

I sill plan to do more. E.g a improved video controller supporting higher resolutions, virtual console support  for MP/M.

My focus is currently on the MP/M implementation, because MP/M was beyond my reach in the 80s and I'm really fascinated by the elegance and power of this little multi-user/multi-tasking system. I support CP/M as bootloader and "maintenance mode" for MP/M, but currently have no plan to support CP/M 3.0

I'm currently in preparation to publish my extended SOCZ80 also with some disk images. Biggest limitation of the current implementation maybe that I only adapted it to German Keyboard Layout. This can be easily changed.
My pre-anouncment here is mostly intended to find out if there is anybody out there interested in my work and also I'm searching for someone acting as tester to check if my distribution files (FPGA bitstream and disk images) are ok. 

Looking foward to any reply.




Link to comment
Share on other sites

  • 2 weeks later...

Hi Alan,
I have already downloaded your fork a while ago to look into it. SD Card is one of the things on my list.  I'm struggling a bit with the fact, that there are not enough free I/O pins anymore when using the Arcade MegaWing. There is exaclty one pin missing, I'm considering of just cutting one of the joystick pins - I'm personally not interested in Games :)

CP/M 3.0 is much newer than MP/M II and one advantage is indeed that it can do the blocking/deblocking and there is no need for doing it in the BIOS.  


BTW I also did some closer look in the timing violations of SOCZ80, I think you mentioned it a while ago in this thread.  With the Timing analysis tools in the ISE "PlanAhead" tool it is not that hard. I'm afraid the reason is a 14 level deep logic path in the T80 CPU which cannot be changed without completly redesigning the core. On the LX9 the T80 core simply cannot run faster then ~85 Mhz. That it works with 128Mhz simply shows that the Xilinx device seem to have a lot of overclocking margin. 
85Mhz on the other hand is close to the clock range where Hamsters DRAM controller becomes unreliable. 

A "clean" design of SOCZ80 would need to work with DRAM clock separated from CPU clock. I have already take a look into the design of the cache, it should be not to difficult to separte the clock domains in the cache controller.






Link to comment
Share on other sites

  • 3 weeks later...

Hi all,

finally I managed to finalize my work in a way that I can upload it.

The bit files are my extended version of SOCZ80 (I named my variant "RETRO80").

The "Serialboot" bitfile contains the orginal ROM Monitor from Will which interacts with the serial console (the baud rate is 115200 bit/sec fixed). The video RAM is initalized with a test pattern (with initalizing the Block RAM by VHDL code), so it is easy to check if VGA is working.

The "consoleboot" bitfile contains a ROM Monitor which uses the VGA Port and the PS/2 "A" port of the arcade megawing as conole. Unfortunately the keyboard layout is german at the moment...

Having a boot image is much more usefull. To get the boot image onto the system you can either use the method described in Wills readme.txt, or as fast alternative merge it at address 0x200000 to the bitfile and upload it.

For merging bitfiles there are different tools, I used papillo-prog.

The command is

papilio-prog.exe -v  -f retro80Serialboot20160604.bit -b ..\bscan_spi_xc6slx9.bit -a 200000:retro80_200.image

Of course you must adjust the pathes to the structure on your system. My example was from a start directly in the directory where papilio-prog resides after intallationof the Papilio tools.

When everything is loaded to the Papillio Pros flash chip and you restart the board (best with power cycling) you should see the boot monitor prompt either on your terminal emulator or the VGA display.

Then you enter

rread 200 200

rboot 200

Now CP/M is booted, the provided image will always boot CP/M on the serial console. On this console you can enter "MPMLDR", this will fire up MP/M II running console 0 on PS/2 / VGA, console 1 on serial port.

The disk image contains a lot, e.g. Turbo Pascal and Wordstar. Please note that all this programs are patched for using the ADM3A screen sequences of the VGA console. So they will not work with the usual VT100 emulation of e.g. putty or TerraTerm. There is a which can be used with VT100.

On user 6 there is an adapted versio of the startrek game.

You can start it with:

user 6


If you want also the CP/M part work in VGA/PS/2 you can patch the disk image:

First reset the SOC with the reset button on the Arcade MegaWing (this will only reset the CPU/board not reload the bitfile and will therefore not harm the DRAM contents)

Boot CP/M


sysload bootvga.bin a:

press "C" to continue (the sysload program is missing a message saying this ....)

Reset the system again. rboot 200 should now boot to the VGA PS/2 console.

To make the change permnent you need to enter 

rwrite 200 200 

in the ROM Monitor.

I will post a link to my bitbucket Repository soon.










Link to comment
Share on other sites

  • 1 month later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.