1

Topic: How do I start porting?

Hi,
I implemented ZX Spectrum on an Altera DE1 board and would like to add esxdos to it. How do you suggest I start with it?
I could not find the esxdos sources (are they public?) which could show the exact hardware requirements in terms of the pins, memory map etc. I would just like to map SD Card to it for the moment.

Can you help me get started?
Thanks!

2

Re: How do I start porting?

gdevic wrote:

Hi,
I implemented ZX Spectrum on an Altera DE1 board and would like to add esxdos to it. How do you suggest I start with it?
I could not find the esxdos sources (are they public?) which could show the exact hardware requirements in terms of the pins, memory map etc. I would just like to map SD Card to it for the moment.

Can you help me get started?
Thanks!

Hi,

You need to implement the "DivMMC" hardware specification, which is a DivIDE with SD/MMC instead of IDE ports, and 128k up to 512k instead of 32k. More info about the DivIDE:

http://baze.au.com/divide/files/pgm_model.txt

Info about SD/MMC ports:

SPI_PORT       equ $EB
OUT_PORT      equ $E7         ; port for CS control (D1:D0)

3

Re: How do I start porting?

Thank you for the link! That document seems to contain what is needed.

I will post result when it's done. I am adding it to the new Z80 model I wrote, described at www.baltazarstudios.com

Thanks!

4

Re: How do I start porting?

gdevic wrote:

I will post result when it's done. I am adding it to the new Z80 model I wrote, described at www.baltazarstudios.com

That's most interesting, specially the A-Z80!

5

Re: How do I start porting?

You may want to check the sources of the ZX Spectrum core inside the ZX-Uno clone. It already implements a complete DivMMC interface.
Tech wiki: http://www.zxuno.com
SVN repo: http://guest:zxuno@www.atc.us.es/svn/zxuno

I'd like to add your A-Z80 to the ZX-Uno but my design flow doesn't support SystemVerilog. Is A-Z80 ported to either VHDL or plain Verilog? The T80 core is fine, but differs at some timmings.

6

Re: How do I start porting?

McLeod, I've seen ZX-Uno that you did - congratulations, it s a *very* neat project!

About 90% of all A-Z80 source files are already Verilog (pre-compiled from the schematic files): all *.v files from folders (alu,bus,registers,control). It is those few exceptions for which I am not sure how difficult it would be to port them from SystemVerilog:
bus/bus_switch.sv - probably very easy
control/execute.sv (+ exec_module.i) ?
control/pla_decode.sv - this one is generated by the z80_pla_checker tool; likely easy
toplevel/z80_top_direct_n.sv (+ core.i) - this is the main module; ?

The rest of the *.sv files in directories are mostly tests and not needed. So, there are not too many files! One would just have to go ahead and start removing sv specifics and tokens and see where the road bumps are. I suspect there would be no hard show-stoppers since I did not use sv in its full potential but mostly to improve readability.

I am not familiar with the Xilinx toolchain, but I am very surprised that they don't support sv!?

7

Re: How do I start porting?

I have updated the project and copied all CPU files into a separate folder called "deploy" so it's easier to pick them up and synthesize the CPU. I will also look into porting those few remaining SystemVerilog files to Verilog, so hopefully you can use it in zxuno and others might benefit. Just need to find some time..

8

Re: How do I start porting?

lordcoxis wrote:

Hi,

You need to implement the "DivMMC" hardware specification, which is a DivIDE with SD/MMC instead of IDE ports, and 128k up to 512k instead of 32k. More info about the DivIDE:

http://baze.au.com/divide/files/pgm_model.txt

Info about SD/MMC ports:

SPI_PORT       equ $EB
OUT_PORT      equ $E7         ; port for CS control (D1:D0)

Hi,

I am planning to build a Spectrum compatible too and would like to implement EsxDOS in it
Unfortunately, it seems to be that the link to the programming model is broken. Is it possible to post it again? I am having some difficult to find technical info on how DivMMC and EsxDOS works, like ports, memory model, ROM switching and API works.
What about usage licences? Is it ok to make a compatible hardware to run it?
My idea is to build a 128 clone with dual AY, ULA plus and some extra tricks in the sleeve too, running on a real Z80, without FPGAs
Right now it is just an idea and I am gathering information to start thinking about the technical points. Any info an EsxDOS will be very welcome.

Thanks a lot,

                     Marcelo

9 (edited by Luzie 2020-10-14 16:58:12)

Re: How do I start porting?

Aeroman66 wrote:
lordcoxis wrote:

Hi,

You need to implement the "DivMMC" hardware specification, which is a DivIDE with SD/MMC instead of IDE ports, and 128k up to 512k instead of 32k. More info about the DivIDE:

http://baze.au.com/divide/files/pgm_model.txt

Info about SD/MMC ports:

SPI_PORT       equ $EB
OUT_PORT      equ $E7         ; port for CS control (D1:D0)

Hi,

I am planning to build a Spectrum compatible too and would like to implement EsxDOS in it
Unfortunately, it seems to be that the link to the programming model is broken. Is it possible to post it again?

Hi Marcelo,

WaybackMachine holds a copy of this .txt-File, you can access it via: https://web.archive.org/web/20141221142 … _model.txt

and I post the content here:

DivIDE programming model (v1.03)
--------------------------------

Pavel "Zilog" Cimbal (xcimbal@quick.cz)
English rewritten by J. G. Harston
Further corrections by Milos "baze" Bazelides


The DivIDE interacts with the ZX Spectrum using I/O accesses or automatically
by paging in external memory over the internal ROM when there is a CPU fetch
from certain entry points. This automatic paging can be enabled and disabled.

DivIDE contains 8 KB ROM/EPROM/EEPROM paged in at 0000h-1FFFh and 32 KB RAM
paged in in 8 KB banks at 2000h-3FFFh. DivIDE can use the 3rd 8 KB bank of RAM
for its system. Accidental writes to EEPROM can be disabled with an on-board
link (E). If the current lower 8 KB is EEPROM and the link is removed, it can
be reprogrammed in situ.

The other link (A) should be always linked on Amstrad Spectrum models +2A/+3.

All ports are decoded using low address lines A0..A7 only, so short I/O
instructions (INI/INIR and OUTI/OTIR) can be used. All eight ATA command block
registers are at addresses xxxx xxxx  101r rr11. Other DivIDE features are
controlled with the DivIDE Control Register at address xxxx xxxx 1110 0011.


ATA command block registers
---------------------------

xxxx xxxx  1010 0011, 0A3h, 163 - DATA REGISTER (R/W)

This register is used to read and write data. It is 16 bits wide, so divIDE
joins pairs of 8-bit writes into words and splits read words into bytes.

When reading from this register each ODD access will return low byte of 
read word, latching the high byte. Each EVEN access will return the latched
high byte.

When writing, each ODD access latches the byte as the low byte of the word
to be written. Each EVEN access writes the peviously latched low byte with
the byte written as the high byte.

After any access to any other ATA register, or to the divIDE control
register, any following data register access will be an ODD access. Accesses
outside the divIDE ports do not change the ODD/EVEN state. After reset or
power-on the ODD/EVEN state is undefined.

xxxx xxxx  1010 0111, 0a7h, 167 - ERROR REGISTER (R) / FEATURES REGISTER (W)
xxxx xxxx  1010 1011, 0abh, 171 - SECTOR COUNT (R/W)
xxxx xxxx  1010 1111, 0afh, 175 - SECTOR NUMBER or LBA bits 0..7 (R/W)
xxxx xxxx  1011 0011, 0b3h, 179 - CYLINDER LOW or LBA bits 8..15 (R/W)
xxxx xxxx  1011 0111, 0b7h, 183 - CYLINDER HIGH or LBA bits 16..23 (R/W)
xxxx xxxx  1011 1011, 0bbh, 187 - DRIVE/HEAD or LBA bits 24..28 (R/W)
xxxx xxxx  1011 1111, 0bfh, 191 - STATUS REGISTER (R) / COMMAND REGISTER (W)

For detailed desription of ATA command registers, see http://www.t13.org .


DivIDE control register
-----------------------

xxxx xxxx 1110 0011, 0E3h, 227 - divIDE Control Register (Write Only)

This register is write only. All bits are reset to '0' after each power-on.
Unimplemented bits, marked 'X', should be written as zero for future
compatibility divIDEs with more than 32K RAM.

    7        6     5  4  3  2   1       0
[ CONMEM , MAPRAM, X, X, X, X, BANK1, BANK0 ]

BANK1 and BANK0 select which 8 KB bank is paged in at 2000h-3FFFh when divIDE
memory is paged in. Bits 2 to 5 are reserved for accessing up to 512 KB of
memory.

Setting MAPRAM to '1' write protects RAM bank 3 and enables it to act as ROM.
Bank 3 is paged in at 0000h-1FFFh either automatically upon reaching ROM entry
point or instantly if the divIDE memory is already mapped. Once set to '1',
MAPRAM can only be reset again with a power-on. RESET leaves it unchanged.
MAPRAM can be overridden by setting CONMEM. That is, ROM/EPROM/EEPROM will be
mapped to 0000h-1FFFh instead of bank 3.

CONMEM instantly pages ROM/EPROM/EEPROM in at 0000h-1FFFh and RAM set with
BANK 1..0 at 2000h-3FFFh, regardless of any automatic paging. Memory at
2000h-3FFFh is always writable - even bank 3 if MAPRAM is active. Memory at
0000h-1FFFh is writable if the write protect (E) link is removed and EEPROM
is installed.

To load a replacement ROM image you must do the following:

 * Disable interrupts
 * CALL 1FFBh ('RET') to reset automatic memory mapper
 * Set CONMEM to override write protect
 * load new code to 0000h-3FFFh
 * Clear CONMEM, Set MAPRAM
 * Enable interupts

The values written to the control register can be summarised as follows:

 * 00h-03h: When divIDE is activated the specified RAM bank will be paged in
            at 2000h-3FFFh. Depending on MAPRAM state, either ROM/EPROM/EEPROM
            or bank 3 will be mapped to 0000h-1FFFh.
 * 40h-43h: When divIDE is activated, write protected bank 3 will be paged
            in at 0000h-1FFFh, and the specified RAM bank will be paged in at
            2000h-3FFFh (bank 3 is not writable).
 * 80h-83h: Immediately page divIDE ROM/EPROM/EEPROM in at 0000h-1FFFh and the
            specified RAM bank at 2000h-3FFFh (which is always writable).

Note: While it is perfectly possible to set both CONMEM and MAPRAM by single
instruction, firmware developers are advised not to use this combination
as it may be used in future hardware revisions of divIDE to expand the function
of the control register.


Memory mapping
--------------

DivIDE memory can be mapped in instantly by setting CONMEM or automatically
when the CPU fetches an opcode from an entry point. Automatic mapping only
happens if EPROM/EEPROM is present, indicated with the the 'E' link being
present, or if MAPRAM is set in the Control Register.

Automatic mapping occurs at the begining of refresh cycle after fetching an
opcode (after the M1 cycle) from 0000h, 0008h, 0038h, 0066h, 04C6h and 0562h.
Mapping also occurs instantly when executing an opcode at 3D00h-3DFFh, 100 ns
after the /MREQ falling edge.

DivIDE memory is paged out in the refresh cycle of any instruction fetch
from 1FF8h-1FFFh, referred to as the 'off-area'.

The one-instruction delay can be used to distinguish between nested calls to
the same place. To do this you should place different instructions at the
entry point address than is in the original ROM. The first call will execute
the original instruction, but any subsequent call will execute the
instruction in the paged-in memory.

This is particularly useful for avoiding nested NMI calls, which can not be
easily implemented using hardware. It also allows the divIDE to use INTs for
timing. When divIDE code is excuted, external calls will map divIDE out and
continue at the original code at 0038h, but nested INTs can jump to
different code.

When automatic memory paging occurs, if MAPRAM is set, the write-protected
RAM bank 3 is paged in at 2000h-3FFFh.

Memory at 0000h-3FFFh is as follows:

CONMEN set:

0000h-1FFFh - EEPROM/EPROM/NOTHING (if empty socket), writable if 'E' link
              absent
2000h-3FFFh - 8K RAM selected by BANK bits, always writable.

CONMEM clear, MAPRAM set, entrypoint executed:

0000h-1FFFh - Bank 3, read-only
2000h-3FFFh - 8K RAM selected by BANK bits. Writable, unless bank 3.

CONMEM clear, MAPRAM clear, entrypoint executed:

0000h-1FFFh - EEPROM/EPROM/NOTHING (if empty socket), read-only.
2000h-3FFFh - 8K RAM selected by BANK bits, always writable.

Otherwise there is normal Spectrum memory layout.


Final words
-----------

It might sound complex but it's actually not if you try reading it again.
Feel free to ask me (Zilog) at xcimbal@quick.cz. I hope you will enjoy this
piece of hardware, I have spent months optimising it.

Zilog

Cheers,

Luzie

10

Re: How do I start porting?

Thanks a lot!!
One more question: If use the same E3/EB/E7 ports on my hardware do I need to configure EsxDOS somehow to recognize it as a DivMMC, or is it just a matter of flashing the binary file on the EEPROM?
Will it automatically detect if it is running on a DivMMC or a DivIDE?

11 (edited by Luzie 2020-10-16 14:18:45)

Re: How do I start porting?

Aeroman66 wrote:

Thanks a lot!!
One more question: If use the same E3/EB/E7 ports on my hardware do I need to configure EsxDOS somehow to recognize it as a DivMMC, or is it just a matter of flashing the binary file on the EEPROM?
Will it automatically detect if it is running on a DivMMC or a DivIDE?

Hi,

I not sure, but as there are two different esxDOS-Binaries to flash, I think you should take the matching one for DivMMC called (on esxDOS 0.8.8): ESXMMC.BIN/ESXMMC.TAP