z88dk for rc2014

1,766 views
Skip to first unread message

phillip.stevens

unread,
Nov 14, 2016, 8:03:22 AM11/14/16
to RC2014-Z80
Well it has taken quite a bit of time and posts on another thread, but I think that the rc2014 is now ready for "prime time" in the z88dk.

The z88dk is a fully featured development environment for z80 processor based machines.

The repository is a snapshot of the z88dk (from November 14th, as of writing) is called z88dk-rc2014.
After cloning this repo from Github, the instructions on my blog and on the z88dk wiki can be interpreted to build and use the z88dk.

Note that the SDCC is updated to #9801 from November 14th, too. Linux AMD64 binaries are in the ~/bin directory zsdcc and zsdcpp.
So there is no need to build SDCC separately, unless you want to.

Testing using the attached test.c file shows that both the low level driver functions and the high level stdio.h functions work as expected.
The simple test.c uses and additional 1800 bytes to have the full stdio function set available.

Note that because of an odd thing with the z80-machine emulator, the Tx interrupt only fires twice, outputting two characters.
Just hit a key to continue serial output. This effect doesn't happen with real rc2014 hardware.

Both serial ACIA input and output are buffered with 128 bytes, and are interrupt driven.
Once the transmit buffer is full, the output call is blocking until the Tx buffer has space available.

Once we've done a bit of testing, I'm sure that the very helpful z88dk team (particularly aralbrec, who essentially wrote this port) will want to pull the rc2014 platform into their mainline code. So this repository should be treated as transitory.

There are a couple of improvements to make straight away, but now it is in a place where it can be tested.
Please use Github for registering issues.

Enjoy.

feilipu (and aralbrec)




test.c

phillip.stevens

unread,
Nov 14, 2016, 8:13:27 AM11/14/16
to RC2014-Z80
Testing using the attached test.c file shows that both the low level driver functions and the high level stdio.h functions work as expected.
The simple test.c uses and additional 1800 bytes to have the full stdio function set available.

# to use the ROM version. Compressed ROM also available with -subtype=rom_zx7 
zcc +rc2014 -subtype=rom -v -m -SO3 --max-allocs-per-node200000 --c-code-in-asm --list test.c  -o test -create-app

# to generate ROM for the z80machine.
genroms test.roms test.ihx

# to disassemble your code to ensure you're not dreaming.
z80dasm --origin=0 --address --labels --zilog test.bin -o test.dasm

Filippo Bergamasco

unread,
Nov 14, 2016, 8:16:29 AM11/14/16
to rc201...@googlegroups.com
Great job! I'll definitely give it a try as soon as I have some free time :)

Filippo


--
You received this message because you are subscribed to the Google Groups "RC2014-Z80" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rc2014-z80+unsubscribe@googlegroups.com.
To post to this group, send email to rc201...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/rc2014-z80/9ae4c54b-3fdd-45e6-bbb1-409ce987a7c5%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

A A

unread,
Nov 15, 2016, 12:54:10 AM11/15/16
to RC2014-Z80


I've committed the current wip source code into z88dk and it is available with the Nov 15 build (ie now).  This is mainly of use to windows and osx users as the nightly build will contain compiled binaries for those platforms.  Install instructions are here ( http://www.z88dk.org/wiki/doku.php?id=temp:front#installation ).  The z88dk commits will lag Philip's repo so if you want to contribute or use the latest his repo is the way to go. I think most changes will be confined to z88dk/libsrc/_DEVELOPMENT/target/rc2014 so windows and osx users could keep up to date by copying that directory from the repo.

For the moment there are only rom and compressed rom builds for address 0 (ie a standalone rom).  More crts and a ram build will have to be added to suit other compile scenarios.

With stdin and stdout in place I compiled a few test programs to try.  If you've got some spare roms lying around let us know if they work:

https://drive.google.com/file/d/0B6XhJJ33xpOWUVd5d0FQcElSMms/view?usp=sharing

clisp.c : "zcc +rc2014 -vn -subtype=rom_zx7 -SO3 --max-allocs-per-node200000 --opt-code-size clisp.c -o clisp --fsigned-char -create-app"
A simple lisp interpretter without file i/o (which limits its usefulness).  You can find some lisp type-ins here:  http://z88dk.cvs.sourceforge.net/viewvc/z88dk/z88dk/examples/clisp/ "minimalistic.l" contains some short examples.

eliza.c : "zcc +rc2014 -vn -subtype=rom_zx7 -SO3 --max-allocs-per-node200000 eliza.c -o eliza -create-app"
Simple psychologist program popular in the 1970s.

startrek.c : "zcc +rc2014 -vn -subtype=rom_zx7 -SO3 --max-allocs-per-node200000 --opt-code-size startrek.c -o startrek -lm -create-app"
Star trek program also from the 1970s.  Unfortunately, the randomize method used in this program is not yet available for the rc2014 so the first game played will always be the same one at power up.  This one is also interesting because it makes use of the float library.

sudoku.c : "zcc +rc2014 -vn -subtype=rom -SO3 --max-allocs-per-node200000 sudoku.c -o sudoku -create-app"
Solves sudoku puzzles.  Puzzles are entered like this with zeroes used to indicate blanks:
024100600
050040008
000000000
510008300
030905080
006300097
000000000
900050070
001007430

umchess.c : "zcc +rc2014 -vn -subtype=rom_zx7 -SO3 --max-allocs-per-node200000 umchess.c -o umchess -lm --fsigned-char -create-app"
One of the world's smallest chess programs.  Entering a blank line gets the computer to make a move.  Human moves are entered in the form "e2 e4" IIRC.

phillip.stevens

unread,
Nov 16, 2016, 7:25:30 AM11/16/16
to RC2014-Z80


On Tuesday, 15 November 2016 16:54:10 UTC+11, A A wrote:

With stdin and stdout in place I compiled a few test programs to try.  If you've got some spare roms lying around let us know if they work:

https://drive.google.com/file/d/0B6XhJJ33xpOWUVd5d0FQcElSMms/view?usp=sharing

Thanks downloaded...

But, unfortunately they're all too large for the 8kB ROM of the rc2014... Would be good to have a 32k/32k memory split version... perhaps?
 
umchess.c : "zcc +rc2014 -vn -subtype=rom_zx7 -SO3 --max-allocs-per-node200000 umchess.c -o umchess -lm --fsigned-char -create-app"
One of the world's smallest chess programs.  Entering a blank line gets the computer to make a move.  Human moves are entered in the form "e2 e4" IIRC.

The only file that I could test was the umchess program.

And... from C code... compiled on my own tool chain and machine... IT WORKS!

Evidence below.


Very _very_ happy with this outcome.

That's a real C compiler and full standard C library working with the rc2014!

A A

unread,
Nov 17, 2016, 12:12:43 AM11/17/16
to RC2014-Z80


On Wednesday, November 16, 2016 at 5:25:30 AM UTC-7, phillip.stevens wrote:



But, unfortunately they're all too large for the 8kB ROM of the rc2014... Would be good to have a 32k/32k memory split version... perhaps?
 

Bit of a brainfart there.  I'm not sure how I had it in my mind it was 32k/32k.  Three programs should fit:  umchess, sudoku and eliza.

Eliza.c I got to fit by adding a few pragmas:

#pragma output CLIB_OPT_PRINTF      = 0x200    // %s only
#pragma output CLIB_STDIO_HEAP_SIZE = 0        // cannot open files

The first disables all printf converters except %s and the second gets rid of any extra memory set aside for opening files.  The bin shrank by 1k and that's almost all due to the printf pragma.

The small standard rom is probably a good reason to create a ram model compile too.  It would be possible to have a monitor rom in the bottom 8k and then have a ram model compile make use of the stored routines in the rom (the interrupt driver is there, maybe printf and scanf are there, etc) or a ram model compile could use the basic rom and find a way to use the existing basic i.o for text printing and scanning.

phillip.stevens

unread,
Nov 17, 2016, 6:22:15 AM11/17/16
to RC2014-Z80

But, unfortunately they're all too large for the 8kB ROM of the rc2014... Would be good to have a 32k/32k rc2014 memory split version... perhaps?
 
Bit of a brainfart there.  I'm not sure how I had it in my mind it was 32k/32k. 

Well there IS the option for the 64k RAM board, that can be configured for 56k RAM / 8k ROM (on the ROM board).

That makes a good option to consider, I think.

The small standard rom is probably a good reason to create a ram model compile too.  It would be possible to have a monitor rom in the bottom 8k and then have a ram model compile make use of the stored routines in the rom (the interrupt driver is there, maybe printf and scanf are there, etc) or a ram model compile could use the basic rom and find a way to use the existing basic i.o for text printing and scanning.

IIRC there's a ROM decompression to RAM model for z88dk too, isn't there?

Depending on how effective the zx7 compression routine is, it should be possible to decompress the functions (except for the compression routine) and into RAM from 0x2000 to 0x7FFF memory addresses, and still retain 32kB of RAM available from 0x8000.  That would allow a maximum of 24kB of program space, or more if the zx7 compression routine was more effective, and some uncompressed functions could remain in the 0x0100 to 0x1FFF ROM addresses.

Spencer Owen

unread,
Nov 18, 2016, 1:42:59 PM11/18/16
to rc201...@googlegroups.com

Firstly, thanks for converting these programs to run on the RC2014! Awesome work!

So, I've tested out umchess, Eliza and Super Star Trek on real RC2014 hardware and pretty much good news :-)

The actual set up was with 64k RAM, SD Memory Dump Module and Pi Zero Terminal (plus Z80, clock, serial IO obviously)

All 3 worked on first try, although initially I thought it wasn't reading serial input... then noticed that just the return key did things. Eventually I worked out that serial input is working fine, but it just doesn't echo anything on the screen. 

Although I've not tried it yet, I'm sure they'd would work perfectly via FTDI and serial software with local echo turned on.

Cheers

Spencer


--
You received this message because you are subscribed to the Google Groups "RC2014-Z80" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rc2014-z80+unsubscribe@googlegroups.com.
To post to this group, send email to rc201...@googlegroups.com.

phillip.stevens

unread,
Jun 22, 2017, 12:51:16 AM6/22/17
to RC2014-Z80
Well its been some time since visiting this thread, but I think now there's some substantial improvements that make it worth updating.

Over the past few days aralbrec and pauloscustodio have been working on getting the build process for the rc2014 improved to the point that it is now possible to replace the TASM (or other) assembler with `z80asm` and `appmake` (through z88dk) and get an identical outcome, and soon to allow a C program to built to use the existing serial I/O RST jumps provided by the Nascom BASIC initialisation code.

Initially (rather than pulling in the z88dk C libraries), it is possible to build raw assembly code with any origin, and create an Intel HEX file which can be loaded into the rc2014. As an example of how to do this, I've converted the Nascom BASIC int32k.asm code (formerly for TASM) into z88dk format in the RC2014 HexLoadr repository.

As the z88dk platform is much more modern (read complex) than TASM, there are some extra configurations needed to get everything right.

A .lst file (for example the nascom32k.lst file) if referenced by the @ symbol, contains the list of files to be compiled. This saves noting them all on the command line.

The first file referenced on the command line, or through the .lst file is a map file, which allows sections of code to be located at specific origins. Within z88dk this is used to control the location of code into ROM areas, RAM areas (including banks of RAM), as needed. In this example rc2014_map.asm is simply used to locate the functions initialising the hardware for BASIC.

A new feature in appmake was written specifically for us, which enable a number of binary sections to be properly located and glued into a single Intel HEX file. So the incantation to get (effectively) the same output as is generated by TASM is below.

zcc +rc2014 --no-crt @nascom32k.lst -o int32k -create-app -subtype=none -Cz"+glue --ihex --clean"
  • --no-crt stops linking in the rest of the z88dk libraries
  • -create-app -subtype=none continues the prevention of library linking, and stops default options being passed to appmake
  • +glue --ihex --clean glues multiple binaries generated by z80asm into IHEX, according to the section map, and then cleans away the binaries.
Next step is to provide an additional startup option to integrate with the serial RST jumps provided by Nascom BASIC. This will allow arbitrary C code to be compiled, then just loaded into free RAM by a HexLoadr, and be called by the Nascom BASIC USR(x) function, and also use the existing serial routines. This will allow C programs to be written and used from RAM by the simplest RC2014 device (without needing optional hardware). More on this soon.

For further reading, the Github conversation in z88dk #247

Enjoy
feilipu


On Tuesday, 15 November 2016 00:03:22 UTC+11, phillip.stevens wrote:
Well it has taken quite a bit of time and posts on another thread, but I think that the rc2014 is now ready for "prime time" in the z88dk.

The z88dk is a fully featured development environment for z80 processor based machines.

Jay Cotton

unread,
Jun 23, 2017, 1:45:50 PM6/23/17
to RC2014-Z80

So I was able to get this to compile on Solaris no problems.  On cygwin it was a problem.  I did manage to cob it together but I will be back to it again
and see if I can fix the makefiles so they work on cygwin.  When done, maybe we can integrate these fixes and add one more platform.

I have not tried it on win32 (no interest). 

Cool and thanks for doing all the hard work.

jc

phillip.stevens

unread,
Jun 26, 2017, 8:00:18 AM6/26/17
to RC2014-Z80
Over the past few days aralbrec and pauloscustodio have been working on getting the build process for the rc2014 improved to the point that it is now possible to replace the TASM (or other) assembler with `z80asm` and `appmake` (through z88dk) and get an identical outcome, and soon to allow a C program to built to use the existing serial I/O RST jumps provided by the Nascom BASIC initialisation code.

Next step is to provide an additional startup option to integrate with the serial RST jumps provided by Nascom BASIC. This will allow arbitrary C code to be compiled, then just loaded into free RAM by a HexLoadr, and be called by the Nascom BASIC USR(x) function, and also use the existing serial routines. This will allow C programs to be written and used from RAM by the simplest RC2014 device (without needing optional hardware). More on this soon.

For further reading, the Github conversation in z88dk #247
 
Well, this is very exciting !!!

Over the past few days aralbrec has finished off the final piece of the z88dk RC2014 jigsaw to enable users of standard FULL MONTY or MINI RC2014 devices access to programming in C with the z88dk.

Tonight (my timezone) he's made the -subtype=basic option available from the z88dk command line. The basic subtype uses the standard ROM ACIA routines and the standard ACIA interrupt so that it supports standard off-the-shelf RC2014 devices.

For example for sudoku.c : 
zcc +rc2014 -subtype=basic -SO3 --max-allocs-per-node200000 sudoku.c -o sudoku -create-app

Or for umchess.c :
zcc +rc2014 -subtype=basic -SO3 --max-allocs-per-node200000 umchess.c -o umchess -lm --fsigned-char -create-app

will create an IHEX file with the origin at 0x9000, which can be loaded into the RAM of the RC2014 using a HexLoad Basic program using the standard RC2014 ROM, or the HexLoadr ROM.

The memory model for this implementation has the C heap will follow immediately after the C program loaded at 0x9000, and the C stack will be located at 0xFFFF and grow down.

To ensure there is no conflict with basic, the initial Memory top? question should be answered with 36863 (0x8FFF) or lower.

More on this work at the Github conversation in z88dk #256.

Enjoy.

phillip.stevens

unread,
Jun 26, 2017, 9:13:11 AM6/26/17
to RC2014-Z80
Over the past few days aralbrec and pauloscustodio have been working on getting the build process for the rc2014 improved to the point that it is now possible to replace the TASM (or other) assembler with `z80asm` and `appmake` (through z88dk) and get an identical outcome, and soon to allow a C program to built to use the existing serial I/O RST jumps provided by the Nascom BASIC initialisation code.

Next step is to provide an additional startup option to integrate with the serial RST jumps provided by Nascom BASIC. This will allow arbitrary C code to be compiled, then just loaded into free RAM by a HexLoadr, and be called by the Nascom BASIC USR(x) function, and also use the existing serial routines. This will allow C programs to be written and used from RAM by the simplest RC2014 device (without needing optional hardware). More on this soon.

For further reading, the Github conversation in z88dk #247
 
Over the past few days aralbrec has finished off the final piece of the z88dk RC2014 jigsaw to enable users of standard FULL MONTY or MINI RC2014 devices access to programming in C with the z88dk.

Tonight (my timezone) he's made the -subtype=basic option available from the z88dk command line. The basic subtype uses the standard ROM ACIA routines and the standard ACIA interrupt so that it supports standard off-the-shelf RC2014 devices.

The memory model for this implementation has the C heap will follow immediately after the C program loaded at 0x9000, and the C stack will be located at 0xFFFF and grow down.

To ensure there is no conflict with basic, the initial Memory top? question should be answered with 36863 (0x8FFF) or lower.

More on this work at the Github conversation in z88dk #256.


A question for Spencer, or anyone who's got an opinion.

Are any "8kB ROM 56kB RAM - ROM versions distributed with the 64kB RAM modules, or otherwise?

The answer to this question would help define the preferred (default) memory map for using 64kB RAM modules with C.

a) Lots of 56kB RAM - ROMs distributed.
Then -subtype=basic56 : BASIC > 0x3000 > CODE > DATA > BSS > HEAP --- STACK < 0xFFFF.

b) Only 32kB RAM - ROMs distributed.
Then -subtype=basic56 : 0x2000 > DATA > BSS > HEAP --- STACK < 0x7FFF | BASIC > 0x9000 > CODE.


Scott Lawrence

unread,
Jun 26, 2017, 9:48:11 AM6/26/17
to rc201...@googlegroups.com
Question;

Why does this need to be compiled in?  You could fairly accurately detect the memory size at runtime and adjust stack, work space, etc at runtime....

By writing at 1 kbyte boundaries with known values, walking-ones, or somesuch, and then reading them back, and subsequently restoring values if need be.  I've done such a thing and have accurately detected RAM/ROM in a system. (detecting lack of both is not reliable in my tests.)  Read back the computed walking-ones value, and it's RAM...  Read back an unchanged value, it's probably ROM... Read back FF or 00 when it wasn't FF or 00 before, it's probably unpopulated.

I have a routine that does this in my git repo if anyone's interested.

I've often considered modifying the NASCOM BASIC ROM to remove all startup questions about memory size, so it goes into BASIC like the C64, etc.  Autodetecting everything where possible...

-s

--
You received this message because you are subscribed to the Google Groups "RC2014-Z80" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rc2014-z80+unsubscribe@googlegroups.com.
To post to this group, send email to rc201...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
Scott Lawrence
yor...@gmail.com

Spencer Owen

unread,
Jun 26, 2017, 9:57:22 AM6/26/17
to rc201...@googlegroups.com
On 26 Jun 2017 14:13, "phillip.stevens" <phillip...@gmail.com> wrote:

A question for Spencer, or anyone who's got an opinion.

Are any "8kB ROM 56kB RAM - ROM versions distributed with the 64kB RAM modules, or otherwise?

At a guess, I'd say I've shipped around 50 ROMs with 56k BASIC on. Possibly more. (Would be nice and poetic if I'd shipped exactly 56!)

Cheers

Spencer 

phillip.stevens

unread,
Jun 26, 2017, 10:05:57 AM6/26/17
to RC2014-Z80
Why does this need to be compiled in?  You could fairly accurately detect the memory size at runtime and adjust stack, work space, etc at runtime.

Because the whole program needs to be linked together before it is loaded into RAM. The locations of variables stored in DATA and BSS sections need to be known so they can be referenced from with the CODE section.

What you're describing is essentially a just-in-time linked language, which is something other than C, as far as I understand it.

There is an option (though I've never used it) to make the code relocatable, but I think that option implies that data and bss sections are also known in advance and typically follow directly behind the code section.

phillip.stevens

unread,
Jun 26, 2017, 10:10:59 AM6/26/17
to RC2014-Z80

A question for Spencer, or anyone who's got an opinion.

Are any "8kB ROM 56kB RAM - ROM versions distributed with the 64kB RAM modules, or otherwise?

At a guess, I'd say I've shipped around 50 ROMs with 56k BASIC on. Possibly more. (Would be nice and poetic if I'd shipped exactly 56!)

Sorry, forgot to add the follow up question.

Is there a large base of 64kB RAM modules in the wild too?
Or is it also about 10% of your 32kB RAM base?

I don't want to cause the z88dk team unreasonable workload.  So, I'm just wondering whether it is reasonable to make an additional z88dk subtype for the 64kB RAM module, or whether using the currently existing #pragma options are sufficient.

Cheers.

Spencer Owen

unread,
Jun 26, 2017, 10:51:11 AM6/26/17
to rc201...@googlegroups.com
There's been 183 of the 64k RAM Module sold to date, which us roughly 25% of the overall RC2014 numbers. However, the vast majority of those sold were along with a compact flash and CP/M ROM.

My expectation us that 64k will become the norm at some point.

Spencer 

--
You received this message because you are subscribed to the Google Groups "RC2014-Z80" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rc2014-z80+unsubscribe@googlegroups.com.
To post to this group, send email to rc201...@googlegroups.com.

phillip.stevens

unread,
Jun 27, 2017, 7:18:44 AM6/27/17
to RC2014-Z80
There's been 183 of the 64k RAM Module sold to date, which us roughly 25% of the overall RC2014 numbers. However, the vast majority of those sold were along with a compact flash and CP/M ROM.

Thanks. Based on this input I've suggested that z88dk keeps to 32kB as the default for Basic ROM users.
If you want to suggest otherwise, I'm sure your voice will resonate strongly.

My expectation is that 64kB will become the norm at some point.

On that topic, I was disappointed that Startrek wouldn't fit into 32kB, so I added the HexLoadr to my 56kB NASCOM Basic build.

It is straight forward to configure the zcc +rc2014 -subtype=basic to use a #pragma CRT_ORG_CODE = 0x3000 to move the code origin to 0x3000, which also takes the data, bss, and heap origins along for the ride.  This enables Startrek to fit into the rc2014 with 64kB RAM module.

Uploading the 82kB HEX file generating 31kB of code (0x3000 through to 0xA820) takes only a few seconds, as HexLoadr runs at line rate.


I've attached the HEX for the reference.

Enjoy.

startrek.ihx

phillip.stevens

unread,
Jun 28, 2017, 11:10:29 AM6/28/17
to RC2014-Z80
Over the past few days aralbrec and pauloscustodio have been working on getting the build process for the rc2014 improved to the point that it is now possible to replace the TASM (or other) assembler with `z80asm` and `appmake` (through z88dk) and get an identical outcome, and soon to allow a C program to built to use the existing serial I/O RST jumps provided by the Nascom BASIC initialisation code.
For further reading, the Github conversation in z88dk #247
 
Over the past few days aralbrec has finished off the final piece of the z88dk RC2014 jigsaw to enable users of standard FULL MONTY or MINI RC2014 devices access to programming in C with the z88dk.
Tonight (my timezone) he's made the -subtype=basic option available from the z88dk command line. The basic subtype uses the standard ROM ACIA routines and the standard ACIA interrupt so that it supports standard off-the-shelf RC2014 devices.
The memory model for this implementation has the C heap will follow immediately after the C program loaded at 0x9000, and the C stack will be located at 0xFFFF and grow down.
To ensure there is no conflict with basic, the initial Memory top? question should be answered with 36863 (0x8FFF) or lower.
More on this work at the Github conversation in z88dk #256.

Ok, I promise this nearly the end of this work. The last link between the z88dk development environment, and the standard RC2014 Full Monty or Mini Kit. And that is adapting the hexload program, written by Filippo Bergamasco, to be assembled by z88dk, and then to load itself into the RC2014 using slowprint.py, and then automatically start a C program which it has loaded into the default location for the z88dk +rc2014 -subtype=basic.

Cold Start the RC2014, and set the Memory top? to be 35071 (0x88FF).

The hexload.bas file is then "typed" into the RC2014 either by hand (ahhgh noooo),
or by using python slowprint.py > /dev/ttyUSB0 < hexload.bas

That will automatically start the hexload program running, and it will wait for a z88dk HEX encoded program (asm or C) to be cat'ed to the RC2014.
cat > /dev/ttyUSB0 < eliza.ihx
You could also use slowprint.py for this job, but who has time for that?

The default origin for the rc2014 basic subtype for z88dk is 0x9000, but this can be flexibly changed as desired.
The hexload program origin is 0x8900, and this leaves some free space before the z88dk default origin.

Then, Eliza should start automatically.
I've attached both example files (renamed with .txt) for experimentation.

Enjoy.
feilipu & aralbrec
eliza.ihx.txt
hexload.bas.txt

phillip.stevens

unread,
Jul 3, 2017, 6:19:52 AM7/3/17
to RC2014-Z80
Over the past few days aralbrec has finished off the final piece of the z88dk RC2014 jigsaw to enable users of standard FULL MONTY or MINI RC2014 devices access to programming in C with the z88dk.
Tonight (my timezone) he's made the -subtype=basic option available from the z88dk command line. The basic subtype uses the standard ROM ACIA routines and the standard ACIA interrupt so that it supports standard off-the-shelf RC2014 devices.
The memory model for this implementation has the C heap will follow immediately after the C program loaded at 0x9000, and the C stack will be located at 0xFFFF and grow down.
To ensure there is no conflict with Basic, the initial Memory top? question should be answered with 35071 (0x88FF) or lower.

More on this work at the Github conversation in z88dk #256.

Ok, I promise this nearly the end of this work. The last link between the z88dk development environment, and the standard RC2014 Full Monty or Mini Kit. And that is adapting the hexload program, written by Filippo Bergamasco, to be assembled by z88dk, and then to load itself into the RC2014 using slowprint.py, and then automatically start a C program which it has loaded into the default location for the z88dk +rc2014 -subtype=basic.

Cold Start the RC2014, and set the Memory top? to be 35071 (0x88FF).

The hexload.bas file is then "typed" into the RC2014 either by hand (ahhgh noooo), or by using 
python slowprint.py > /dev/ttyUSB0 < hexload.bas

That will automatically start the hexload program running from origin at 0x8900, and it will wait for a z88dk HEX encoded program (asm or C) to be cat'ed to the RC2014.
cat > /dev/ttyUSB0 < eliza.ihx

You could also use slowprint.py for this job, but who has time for that?

The default origin for the rc2014 basic subtype for z88dk is 0x9000, but this can be flexibly changed as desired.
The hexload program origin is 0x8900, and this leaves some free space before the z88dk default origin.

Now, the (really) final z88dk piece is in place. Previously the -subtype=basic did very simple handling of the command line, and did not permit interactive line editing or such like.

But... now... aralbrec has prepared an additional option -subtype=basic_dcio which supports interactive command line editing.

# in a directory with the source files

:~$ zcc +rc2014 -v -subtype=basic_dcio -SO3 -clib=sdcc_iy --max-allocs-per-node200000 password.c -o password -create-app
:~$ zcc +rc2014 -v -subtype=basic_dcio -SO3 -clib=sdcc_iy --max-allocs-per-node200000 eliza.c -o eliza -create-app

# with your RC2014 connected

:~$ python slowprint.py > /dev/ttyUSB0 < hexload.bas
:~$ cat > /dev/ttyUSB0 < password.ihx # or
:~$ cat > /dev/ttyUSB0 < eliza.ihx

I've attached compiled versions of two programs (eliza, password), which can be checked by using the hexload.bas.
Note again the starting point for this is the standard "Full Monty" or "Mini" RC2014, with 32kB of RAM, and the standard ROM.

Any input at Github z88dk Issue #256, welcome.
Enjoy.

hexload.bas.txt
eliza.ihx.txt
password.ihx.txt

phillip.stevens

unread,
Jul 3, 2017, 6:30:02 AM7/3/17
to RC2014-Z80

# in a directory with the source files

:~$ zcc +rc2014 -v -subtype=basic_dcio -SO3 -clib=sdcc_iy --max-allocs-per-node200000 password.c -o password -create-app
:~$ zcc +rc2014 -v -subtype=basic_dcio -SO3 -clib=sdcc_iy --max-allocs-per-node200000 eliza.c -o eliza -create-app

# with your RC2014 connected

:~$ python slowprint.py > /dev/ttyUSB0 < hexload.bas
:~$ cat > /dev/ttyUSB0 < password.ihx # or
:~$ cat > /dev/ttyUSB0 < eliza.ihx

I've attached compiled versions of two programs (eliza, password), which can be checked by using the hexload.bas.
Note again the starting point for this is the standard "Full Monty" or "Mini" RC2014, with 32kB of RAM, and the standard ROM.

A gratuitous screenshot, of username and password editing. 

phillip.stevens

unread,
Mar 1, 2018, 8:40:47 AM3/1/18
to RC2014-Z80
I'd like to note that the serial interface drivers for the RC2014 within z88dk have been completely revamped. They are now "terminal" drivers by default, rather than "character" drivers.

Also the subtype options for the +rc2014 target have been simplified. There remain now just two options:
-subtype=acia which can be used when you want to create a complete ROM with no existing MSBASIC.
-subtype=basic which can be used where a HexLoadr program can be used together with a version of MSBASIC.

Both subtypes default to the Classic or Mini RC2014 configuration of 8kB of ROM, and 32kB of RAM from 0x8000. But also both can easily be configured to work with 56kB of RAM if desired.

For more discussion on the conversion, see this github issue #588.

Also please note that the +cpm target can be used without restriction where CP/M is being used on a RC2014.

Thanks again to AA for his generous support of this community.


# in a directory with the source files

:~$ zcc +rc2014 -v -subtype=basic -SO3 -clib=sdcc_iy --max-allocs-per-node200000 password.c -o password -create-app
:~$ zcc +rc2014 -v -subtype=basic -SO3 -clib=sdcc_iy --max-allocs-per-node200000 eliza.c -o eliza -create-app

# with your RC2014 connected

:~$ python slowprint.py > /dev/ttyUSB0 < hexload.bas
:~$ cat > /dev/ttyUSB0 < password.ihx # or
:~$ cat > /dev/ttyUSB0 < eliza.ihx

I've attached compiled versions of two programs (eliza, password), which can be checked by using the hexload.bas.
Note again the starting point for this is the standard "Full Monty" or "Mini" RC2014, with 32kB of RAM, and the standard ROM.

Phillip Stevens

unread,
Jan 22, 2019, 3:28:00 AM1/22/19
to RC2014-Z80
It has been a while since I updated this thread, but over the past year there have been constant updates and improvements.

Not that z88dk is now at Release 1.99C, perhaps it is time to add some more updates about RC2014 support.
Note that the CP/M subtype was committed after the 1.99C release, and so daily builds (the normal way) after 1.99C are required.

On Friday, 2 March 2018 00:40:47 UTC+11, Phillip Stevens wrote:
I'd like to note that the serial interface drivers for the RC2014 within z88dk have been completely revamped. They are now "terminal" drivers by default, rather than "character" drivers.
 
Also the subtype options for the +rc2014 target have been expanded. There are now four options:
  • -subtype=acia which can be used when you want to create a complete standalone ROM, with the ACIA UART hardware.
  • -subtype=sio which can be used when you want to create a complete standalone ROM, with the SIO/2 UART hardware.
  • -subtype=basic which can be used where a HexLoad program can be used together with a version of MSBASIC.
  • -subtype=cpm which can be used where the RC2014 is running any version of CP/M.
All of the subtypes (except CP/M) default to the Classic or Mini RC2014 configuration of 8kB of ROM, and 32kB of RAM from 0x8000.
But they can also can easily be configured to work with 56kB of RAM if desired, using #pragma to drive the configuration.

So why is there an additional zcc +rc2014 -subtype=cpm option, when the zcc +cpm platform already exists and works perfectly with the RC2014?
Having CP/M as a subtype will allow RC2014 specific libraries (think AY/YM sound library, and graphics library) to be easily linked into programs to be used within a CP/M environment.
This wouldn't be possible with the default CP/M environment, which is correctly limited to using BDOS calls.

In a related topic, the z88dk customisation of sdcc will be updated to r10892 (v3.8.5) as a precursor to moving to the to-be-announced stable v3.9.0 release later this year.
Any issues can be reported at z88dk, or perhaps better directly at sdcc.

J.B. Langston

unread,
Jan 26, 2019, 9:26:25 PM1/26/19
to RC2014-Z80
I got the latest nightly for z88dk compiled and I was able to compile a basic hello world using the rc2014 cpm subtype and run it successfully under the Altair 8800 CP/M disk image using z80ctrl.  I wasn't able to get any graphical programs to compile using the rc2014 platform though. I get a message that graphics.h can't be found.  But since I have my TMS9918A card configured to use the ColecoVision ports, I tried compiling them for Coleco Adam, and it works. I got the chess board, marilyn monroe, and spirograph working to run under CP/M.  Here's an example invocation that I used.

zcc +cpm -subtype=adam -lm /opt/z88dk/examples/graphics/spirograph.c -create-app -ospiro.com

After that, I just xmodemed the com file over to my Altair 8800 CP/M image running on z80ctrl and ran it.  I assume it would work with my TMS9918A board under RomWBW too but I'm not going to switch out all the boards to test it right now.  The ColecoVision ports aren't compatible with the 64K pageable rom module, so to get it to work there, I'd probably have to compile for MSX instead.

Phillip Stevens

unread,
Jan 27, 2019, 7:11:01 AM1/27/19
to RC2014-Z80
On Sunday, 27 January 2019 13:26:25 UTC+11, J.B. Langston wrote:
I got the latest nightly for z88dk compiled and I was able to compile a basic hello world using the rc2014 cpm subtype and run it successfully under the Altair 8800 CP/M disk image using z80ctrl.

Glad to hear that it worked for you. AFAIK, you're the second person to try it. So it is nice to hear a positive result.

I think the CP/M subtype on the RC2014 is also the first time that a "cross-target" subtype has been created. So it is doubly good that it actually worked. 
 
I wasn't able to get any graphical programs to compile using the rc2014 platform though. I get a message that graphics.h can't be found.

Yes, the RC2014 target only has the 82C55, ACIA and SIO devices, and IDE and Terminal drivers presently integrated into the libraries.
The intention is to add support for additional hardware, but that depends on someone having both hardware (to test) and time to do it.

My intention is (was) to do the AY/YM sound card driver too, but a combination of bad hardware and going down a compiler rabbit hole has delayed that outcome.
Coming soon, all things being equal.

Adding video support to the RC2014 target depends on someone having interest to do the driver, and of course a card to base the work on.

If you want to do a driver, then z88dk has a third-party library capability z88dk-lib, which allows you to test something without digging through all the development kit.
Or, if later you want to maintain the library yourself (without waiting on others to commit your PRs), then it is a good solution.

I use the third party library to link in FATFS support for the RC2014, so that the CP/M-IDE can access a FAT32 file system. I'll be doing the AY/YM library in the same way (at least initially).
 
But since I have my TMS9918A card configured to use the ColecoVision ports, I tried compiling them for Coleco Adam, and it works. I got the chess board, marilyn monroe, and spirograph working to run under CP/M.  Here's an example invocation that I used.

zcc +cpm -subtype=adam -lm /opt/z88dk/examples/graphics/spirograph.c -create-app -ospiro.com

What you've found is that the CP/M target is actually much more full featured than the RC2014 target, as the CPM target has many subtypes relating to different machines, with a range of video and audio capabilities. The CP/M target subtypes may (potentially) also rely on ROM entrance points relevant to their own hardware. CP/M should be pretty safe though, using BDOS calls only.

If your TMS9918A card replicates an established machine, then you'll be (as you discovered) much better served by target CP/M and selecting a subtype matching the machine you're configured for, provided the machine doesn't require the use of specific ROM entrance points for other things.

The other good thing about the CP/M target is that it can access either the classic library or the new library.
The classic library has support for many more machines using the CP/M target
  • SUBTYPE none 
  • SUBTYPE default  -Cz+newext -Cz-e -Cz.com
  • SUBTYPE px       -Cz+px -lpx8 -Ca-IDESTDIR/lib/target/px8/def
  • SUBTYPE px32k    -Cz+px -lpx8 -Cz--32k -Ca-IDESTDIR/lib/target/px8/def
  • SUBTYPE px4      -Cz+px -lpx4 -Cz--32k 
  • SUBTYPE px4ansi  -Cz+px -lpx4 -Cz--32k -pragma-need=ansiterminal -D__CONIO_VT100 -pragma-define:ansipixels=240 -pragma-define:ansirows=8 
  • SUBTYPE einstein -Cz+cpmdisk -Cz-f -Czeinstein -leinstein -pragma-define:CONSOLE_COLUMNS=40 -pragma-define:CONSOLE_ROWS=24 -D__EINSTEIN__
  • SUBTYPE attache  -Cz+cpmdisk -Cz-f -Czattache -lgfxattache -D__ATTACHE__
  • SUBTYPE osborne1 -Cz+cpmdisk -Cz-f -Czosborne1 -lgfxosborne1 -D__OSBORNE1__
  • SUBTYPE kayproii -Cz+cpmdisk -Cz-f -Czkayproii -D__KAYPROII__
  • SUBTYPE mz2500   -Cz+cpmdisk -Cz-f -Czmz2500cpm -D__MZ2500__
  • SUBTYPE microbee -Cz+cpmdisk -Cz-f -Czmicrobee-ds80 -pragma-define:CONSOLE_COLUMNS=80 -pragma-define:CONSOLE_ROWS=24 -lmicrobee -D__BEE__
  • SUBTYPE qc10 -Cz+cpmdisk -Cz-f -Czqc10 -D__QC10__ -D__QX10__
  • SUBTYPE nascom   -Cz+cpmdisk -Cz-f -Cznascomcpm -Cz--container=raw -D__NASCOM__
  • SUBTYPE tiki100 -Cz+cpmdisk -Cz-f -Cztiki100-40t -D__TIKI100__ -ltiki100 -pragma-define:CRT_ORG_GRAPHICS=48000 -pragma-define:REGISTER_SP=48000 -pragma-define:CONSOLE_ROWS=32 -pragma-define:CONSOLE_COLUMNS=128
  • SUBTYPE svi -Cz+cpmdisk -Cz-f -Czsvi-40ss -D__SVI__ 
  • SUBTYPE dmv -Cz+cpmdisk -Cz-f -Czdmv -D__DMV__
  • SUBTYPE adam -Cz+cpmdisk -Cz-f -Czcol1 -Cz--container=raw -D__COLECOADAM__ -D__COLECO__ -ladam -pragma-define:CONSOLE_COLUMNS=32 -pragma-define:CONSOLE_ROWS=24
  • SUBTYPE smc70 -Cz+cpmdisk -Cz-f -Czsmc777 -D__SMC70__ -lsmc777 -pragma-define:CONSOLE_COLUMNS=80 -pragma-define:CONSOLE_ROWS=25
  • SUBTYPE smc777 -Cz+cpmdisk -Cz-f -Czsmc777 -D__SMC777__ -lsmc777 -pragma-define:CONSOLE_COLUMNS=80 -pragma-define:CONSOLE_ROWS=25

The new library supports only these targets
  • generic Z80 and Z180 targets
  • RC2014
  • YAZ180
  • CP/M
  • SMS
  • VGL
  • ZX Spectrum
  • ZXN Spectrum Next
If you swing the library usage over to the new library using the -clib=sdcc_iy or -clib=new option, then you'd lose access to these machine types, AFAIK, and only be able to access BDOS calls. Also, AFAIK, the CP/M file system I/O is not finished in the new library, but it is when using the classic library.

After that, I just xmodemed the com file over to my Altair 8800 CP/M image running on z80ctrl and ran it.  I assume it would work with my TMS9918A board under RomWBW too but I'm not going to switch out all the boards to test it right now.  The ColecoVision ports aren't compatible with the 64K pageable rom module, so to get it to work there, I'd probably have to compile for MSX instead.

Looking forward to hearing if it works, or not.

Phillip

J.B. Langston

unread,
Jan 27, 2019, 9:57:36 AM1/27/19
to RC2014-Z80
Yes, the RC2014 target only has the 82C55, ACIA and SIO devices, and IDE and Terminal drivers presently integrated into the libraries.
The intention is to add support for additional hardware, but that depends on someone having both hardware (to test) and time to do it.

Ah, I misunderstood your last email to mean that audio and video support was already done. 

Adding video support to the RC2014 target depends on someone having interest to do the driver, and of course a card to base the work on.

If you want to do a driver, then z88dk has a third-party library capability z88dk-lib, which allows you to test something without digging through all the development kit.

I don't really think there's any driver work to be done.  The existing TMS driver for the Adam just needs to be enabled for the RC2014. I poked around a bit in the z88dk source code but I don't fully understand how the target configuration works well enough to do that without some guidance.  Hopefully it's possible to configure the driver to use either port 98/99 from the MSX or BE/BF from the ColecoVision so that it would be compatible with either.  
 
Or, if later you want to maintain the library yourself (without waiting on others to commit your PRs), then it is a good solution.

I already have an assembly language library for my card here: https://github.com/jblang/TMS9918A/blob/master/examples/tms.asm.  I could potentially write a z88dk wrapper for that.  It's pretty low-level though and just provides support for things like setting video modes and writing bytes to VRAM.  I don't have any of the drawing primitives like those in the z88dk library.
 
The CP/M target subtypes may (potentially) also rely on ROM entrance points relevant to their own hardware. CP/M should be pretty safe though, using BDOS calls only.

I also tried the psgtest sound demo, since I've also made a ColecoVision-compatible SN76489 sound card.  It compiled but wouldn't play anything when I ran it. I am wondering now if maybe it's relying on the play routines in the Coleco BIOS.  I will dig into it some more.
 
If your TMS9918A card replicates an established machine, then you'll be (as you discovered) much better served by target CP/M and selecting a subtype matching the machine you're configured for, provided the machine doesn't require the use of specific ROM entrance points for other things.

My card is a stock TMS9918A chip with configuration jumpers to select different ports and route the interrupts to either INT (for MSX) or NMI (for Coleco).  I've successfully run both MSX-BASIC and ColecoVision games on it without any modification.  

With z80ctrl, I can actually load the CV BIOS in RAM to play the games, but it can't be loaded at the same time as CP/M.  I'm not sure how the Adam runs CP/M, maybe some bank switching scheme (I am not nearly as familiar with the Adam as the CV).  I actually tried compiling some of the z88dk graphics demos as CV roms and they didn't work when I loaded them along with the CV BIOS.  When I figured out that CP/M programs for the Adam worked, I didn't bother to dig into why the CV ROMs weren't working.  I will probably poke at it some more today.
 
If you swing the library usage over to the new library using the -clib=sdcc_iy or -clib=new option, then you'd lose access to these machine types, AFAIK, and only be able to access BDOS calls. Also, AFAIK, the CP/M file system I/O is not finished in the new library, but it is when using the classic library.

I haven't played with the new library at all yet.
 
I'd probably have to compile for MSX instead.

Looking forward to hearing if it works, or not.

It didn't.  Maybe the MSX driver may relies on the MSX BIOS being there, or maybe MSX-DOS binaries aren't fully compatible with CP/M.  I didn't dig into it.  The ColecoVision and Adam are much simpler machines than the MSX, so it would probably be easier to just modify those drivers to use a different port instead of trying to get the MSX target to work.

Alan Cox

unread,
Jan 27, 2019, 3:59:40 PM1/27/19
to rc201...@googlegroups.com
> It didn't. Maybe the MSX driver may relies on the MSX BIOS being there, or maybe MSX-DOS binaries aren't fully compatible with CP/M. I didn't dig into it. The ColecoVision and Adam are much simpler machines than the MSX, so it would probably be easier to just modify those drivers to use a different port instead of trying to get the MSX target to work.

MSXDOS provides CP/M compatibility for the most part but has a lot of
its own calls.

Alan

Phillip Stevens

unread,
Jan 27, 2019, 6:54:59 PM1/27/19
to RC2014-Z80


On Monday, 28 January 2019 01:57:36 UTC+11, J.B. Langston wrote:
Yes, the RC2014 target only has the 82C55, ACIA and SIO devices, and IDE and Terminal drivers presently integrated into the libraries.
The intention is to add support for additional hardware, but that depends on someone having both hardware (to test) and time to do it.

Ah, I misunderstood your last email to mean that audio and video support was already done. 
 
Adding video support to the RC2014 target depends on someone having interest to do the driver, and of course a card to base the work on.
If you want to do a driver, then z88dk has a third-party library capability z88dk-lib, which allows you to test something without digging through all the development kit.

I don't really think there's any driver work to be done.  The existing TMS driver for the Adam just needs to be enabled for the RC2014. I poked around a bit in the z88dk source code but I don't fully understand how the target configuration works well enough to do that without some guidance.  Hopefully it's possible to configure the driver to use either port 98/99 from the MSX or BE/BF from the ColecoVision so that it would be compatible with either.

That is good information. Hopefully, just copying the Coleco Adam code over to RC2014 will work. From just reading the Makefile, it seems that the Adam is only a subtype on CP/M, related to the Coleco, which means that it probably be relatively easy to copy over to the RC2014 in the new library. And, most of the calls will be via BDOS, except the video specific ones that you've already proven to work.

The Coleco has its own target, so there's probably more variation (including ROM calls) present there.
Would be interesting to read into how the two targets (CP/M & Coleco) differ and are similar.
 
My card is a stock TMS9918A chip with configuration jumpers to select different ports and route the interrupts to either INT (for MSX) or NMI (for Coleco).  I've successfully run both MSX-BASIC and ColecoVision games on it without any modification.

I'm not sure how to configure the ACIA or SIO to chain the INT, so for the purposes of a simple RC2014 (with minimum hardware), it is probably better to rely on the NMI option which is otherwise unused.

 I'd probably have to compile for MSX instead.
Looking forward to hearing if it works, or not.
It didn't. 
 
The ColecoVision and Adam are much simpler machines than the MSX, so it would probably be easier to just modify those drivers to use a different port instead of trying to get the MSX target to work.

I like simple. So IMHO, the shortest simplest path is to make the Coleco Adam graphics (which are those of the classic lib anyway, and common to all targets) work with the RC2014 with its CP/M subtarget. Scratch that into the to-do list if you like. ;-)

Cheers, Phillip 

Alan Cox

unread,
Jan 27, 2019, 7:20:46 PM1/27/19
to rc201...@googlegroups.com
> I'm not sure how to configure the ACIA or SIO to chain the INT, so for the purposes of a simple RC2014 (with minimum hardware), it is probably better to rely on the NMI option which is otherwise unused.

That assumes nothing else on the machine ever leaves the stack
invalid. Dangerous assumption for portability 8)

You can't easily chain the TMS9918A interrupt into an ACIA or SIO. You
can do hack things like wiring it to a modem line but it's a bit
weird. The CTC cards can be used this way but are not I think that
common in RC2014 land.

In addition INT mode doesn't appear to be usable with other cards on
the current TMS9918A. I'm trying to work out if I can just add a diode
to mine somewhere to fix that ?

Lots of other systems used the TMS9918A (from the Memotech MTX which
also had a CP/M option, to some third party TRS80 cards)

Alan

J.B. Langston

unread,
Jan 27, 2019, 11:47:53 PM1/27/19
to RC2014-Z80
I added a diode to the latest REV of my TMS9918A card to make the INT line behave like an open collector.  https://github.com/jblang/TMS9918A/blob/master/TMS9918.pdf

Then you can use interrupt mode 1 and when you get an interrupt, poll the status register on the TMS9918 or other potential interrupt sources to see what triggered it. This is how the MSX did it.

There is a problem with using NMI in CP/M since the NMI vector is in the middle of the FCB.  It works OK if you don't need to do any file operations, or do all your file operations up front before you enable interrupts on the TMS9918A.  In theory, I guess you could copy the FCB somewhere else, replace it with the NMI vector before enabling interrupts, and if you needed to do a file operation, disable interrupts and copy the FCB back before hand, then rinse and repeat as necessary.

I am not sure if the z88dk graphics libraries even use interrupts. Certainly none of the examples seemed to.

Regarding other systems, my card has pretty flexible address configuration, so it should be possible to configure it to work with software from those as well.  You might not be able to get the address decoding as tight as you like, but it can at least be configured to respond to a superset of the ports used on a particular system.  https://github.com/jblang/TMS9918A#jumper-descriptions

Phillip Stevens

unread,
Jan 28, 2019, 12:10:28 AM1/28/19
to RC2014-Z80
On Monday, 28 January 2019 15:47:53 UTC+11, J.B. Langston wrote:
I added a diode to the latest REV of my TMS9918A card to make the INT line behave like an open collector.  https://github.com/jblang/TMS9918A/blob/master/TMS9918.pdf

Then you can use interrupt mode 1 and when you get an interrupt, poll the status register on the TMS9918 or other potential interrupt sources to see what triggered it. This is how the MSX did it.

Yes that's ok, except that the SIO driver expects to be in IM2. The ACIA will be ok in IM1.
 
There is a problem with using NMI in CP/M since the NMI vector is in the middle of the FCB.

Yes. I forgot, about a week of hand wringing trying to think around this problem of NMI and CP/M.
In the end, I decided for my purposes it was too much of a problem, and just gave up and tied up the NMI.

I am not sure if the z88dk graphics libraries even use interrupts. Certainly none of the examples seemed to.

If the  TMS9918A can work without an interrupt, then easier / better.
The whole interrupt question becomes unimportant.

There may be an easy way to fix this, so I'll raise an issue on Z88DK.
Some help would make it easier.

Cheers, Phillip

J.B. Langston

unread,
Jan 28, 2019, 12:44:52 AM1/28/19
to RC2014-Z80
Yes. I forgot, about a week of hand wringing trying to think around this problem of NMI and CP/M.
In the end, I decided for my purposes it was too much of a problem, and just gave up and tied up the NMI.

It's manageable, especially if you only need file access at the beginning. I wrote a loader program for CP/M that loads in a game ROM using standard CP/M file handling, then it disables interrupts, loads the ColecoVision BIOS and game data to the expected location, and jumps to the ColecoVision BIOS. At that point, the ColecoVision code has the whole system to itself and can enable interrupts on TMS9918, which is tied to NMI.  The games have no way of exiting since they were designed to run on a dedicated system, so you have to reset to get back to CP/M.

J.B. Langston

unread,
Jan 28, 2019, 12:45:17 AM1/28/19
to RC2014-Z80

Phillip Stevens

unread,
Jan 28, 2019, 1:07:05 AM1/28/19
to RC2014-Z80
I raised an issue asking for help. Perhaps there’s an easy answer, leaning on the Coleco Adam solution? Let’s see.

For me it was too hard to resolve the NMI stuff because the bank management and stack management in the presence of a RTOS was messy, and or very slow. There was an easier solution, simply not using it.

Phillip Stevens

unread,
Jul 2, 2019, 4:43:51 AM7/2/19
to RC2014-Z80
You'd think that in a year quite a bit would have happened with z88dk... well there have been a few developments, but perhaps the most interesting is the release of the new zsdcc customisation of sdcc.

On Tuesday, 22 January 2019 19:28:00 UTC+11, Phillip Stevens wrote:
It has been a while since I updated this thread, but over the past year there have been constant updates and improvements.

On Friday, 2 March 2018 00:40:47 UTC+11, Phillip Stevens wrote:
I'd like to note that the serial interface drivers for the RC2014 within z88dk have been completely revamped. They are now "terminal" drivers by default, rather than "character" drivers.
 
Also the subtype options for the +rc2014 target have been expanded. There are now four options:
  • -subtype=acia which can be used when you want to create a complete standalone ROM, with the ACIA UART hardware.
  • -subtype=sio which can be used when you want to create a complete standalone ROM, with the SIO/2 UART hardware.
  • -subtype=basic which can be used where a HexLoad program can be used together with a version of MSBASIC.
  • -subtype=cpm which can be used where the RC2014 is running any version of CP/M.
All of the subtypes (except CP/M) default to the Classic or Mini RC2014 configuration of 8kB of ROM, and 32kB of RAM from 0x8000.
But they can also can easily be configured to work with 56kB of RAM if desired, using #pragma to drive the configuration.

So why is there an additional zcc +rc2014 -subtype=cpm option, when the zcc +cpm platform already exists and works perfectly with the RC2014?
Having CP/M as a subtype will allow RC2014 specific libraries (think AY/YM sound library, and graphics library) to be easily linked into programs to be used within a CP/M environment. This wouldn't be possible with the default CP/M environment, which is correctly limited to using BDOS calls.

In a related topic, the z88dk customisation of sdcc will be updated to r10892 (v3.8.5) as a precursor to moving to the to-be-announced stable v3.9.0 release later this year.
Any issues can be reported at z88dk, or perhaps better directly at sdcc.

After quite a few false starts, z88dk has now moved to sdcc r11311 (of sdcc v3.9.1 variety) and will be on this version for some time.
There were a few issues with some older versions of sdcc, but this release seems to produce good code across all the cases tested.

Of note, there are few remaining differences between zsdcc and sdcc now. The zsdcc patch is limited to adding items in sdcc needed for the z88dk environment, which wouldn't make sense for the broader sdcc community (covering many different machine types).

z88dk v2.0 is still coming... perhaps Christmas? Or perhaps once the Spectrum NEXT is launched?

Cheers, Phillip

Phillip Stevens

unread,
Dec 1, 2019, 7:12:12 AM12/1/19
to RC2014-Z80


On Tuesday, 22 January 2019 19:28:00 UTC+11, Phillip Stevens wrote:
It has been a while since I updated this thread, but over the past year there have been constant updates and improvements.

Not that z88dk is now at Release 1.99C, perhaps it is time to add some more updates about RC2014 support.
Note that the CP/M subtype was committed after the 1.99C release, and so daily builds (the normal way) after 1.99C are required.

On Friday, 2 March 2018 00:40:47 UTC+11, Phillip Stevens wrote:
I'd like to note that the serial interface drivers for the RC2014 within z88dk have been completely revamped. They are now "terminal" drivers by default, rather than "character" drivers.
 
Also the subtype options for the +rc2014 target have been expanded. There are now five options:
  • -subtype=acia which can be used when you want to create a complete standalone ROM, with the ACIA UART hardware.
  • -subtype=sio which can be used when you want to create a complete standalone ROM, with the SIO/2 UART hardware.
  • -subtype=hbios which can be used when you want an application running on ROMWBW using the HBIOS functions. NEW
All of the subtypes (except HBIOS and CP/M) default to the Classic or Mini RC2014 configuration of 8kB of ROM, and 32kB of RAM from 0x8000.
But they can also can easily be configured to work with 56kB of RAM if desired, using #pragma to drive the configuration.

So why is there an additional zcc +rc2014 -subtype=cpm option, when the zcc +cpm platform already exists and works perfectly with the RC2014?
Having CP/M as a subtype will allow RC2014 specific libraries (think AY/YM sound library, and graphics library) to be easily linked into programs to be used within a CP/M environment.
This wouldn't be possible with the default CP/M environment, which is correctly limited to using BDOS calls.

The -subtype=hbios option requires that ROMWBW is provided, which means that the application assumes loading from 0x0100 for code and data sections. The bss section is loaded from 0x8000 so that it can be used for HBIOS function buffers. The application is preferably loaded into the monitor (type M L from reboot, and then run with R 100), but will also run in CP/M when it can be loaded with XMODEM or PIP.

Currently the serial ports are working as stdin, stdout, stderr, ttyin, ttyout, ttyerr.

HBIOS functions can be reached directly from C code using the below functions (also found here).
Since the HBIOS API is not particularly orthogonal, these functions don't provide 100% coverage.
But, they do provide sufficient access to HBIOS functions for most purposes.

// HBIOS FUNCTIONS

// return DEHL, function BC
uint32_t hbios
(uint16_t func);

// return A, function BC
uint8_t hbios_a
(uint16_t func);

// return A, function BC, arg DE
uint8_t hbios_a_de
(uint16_t func,uint16_t arg);

// return A, function BC, arg DEHL
uint8_t hbios_a_dehl
(uint16_t func,uint32_t arg);

// return A, function BC, arg DE, void * HL
uint8_t hbios_a_de_hl
(uint16_t func,uint16_t arg,void * buffer);

// return E, function BC
uint8_t hbios_e
(uint16_t func);

// return E, function BC, arg DE
uint8_t hbios_e_de
(uint16_t func,uint16_t arg);

// return E, function BC, arg DEHL
uint8_t hbios_e_dehl
(uint16_t func,uint32_t arg);

// return E, function BC, arg DE, void * HL
 uint8_t hbios_e_de_hl
(uint16_t func,uint16_t arg,void * buffer);

A simple program looks like this.

// zcc +rc2014 -subtype=hbios -SO3 -clib=sdcc_iy -v -m --list --math32 --c-code-in-asm --max-allocs-per-node20000 test.c -o test -create-app

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include <arch.h>

#ifdef __RC2014
#include <arch/rc2014.h>
#include <arch/hbios.h>
#endif

#ifdef __SCZ180
#include <arch/scz180.h>
#include <arch/hbios.h>
#endif

void serialPrint( const uint8_t * str);

void main(void)
{
    serialPrint
("\nHello World\nHello World\nHello World\nHello World\nHello World\n");

    puts
("\nHello World R\nHello World C\nHello World 2\nHello World 0\nHello World 1\nHello World 4\n");

    fprintf
(stdout,"\nHello World R\nHello World C\nHello World 2\nHello World 0\nHello World 1\nHello World 4\n");
    fprintf
(ttyout,"\nHello World R\nHello World C\nHello World 2\nHello World 0\nHello World 1\nHello World 4\n");
}

void serialPrint( const uint8_t * str)
{
 int16_t i
= 0;
 size_t stringlength
;

 stringlength
= strlen((char *)str);

 
while(i < stringlength)
   hbios_a_de
(BF_CIOOUT<<8|00, str[i++]);
}


In a related topic, the z88dk customisation of sdcc will be updated to r10892 (v3.8.5) as a precursor to moving to the to-be-announced stable v3.9.0 release later this year.

zsdcc is now on r11311 (v3.9.1), but I've been testing with r11480 (v3.9.5) and have not found any regressions (yet).

P.

Phillip Stevens

unread,
Jan 6, 2020, 7:52:58 AM1/6/20
to RC2014-Z80
And, another year has passed. Time for an update on where we're at with z88dk for RC2014.


On Tuesday, 22 January 2019 19:28:00 UTC+11, Phillip Stevens wrote:
It has been a while since I updated this thread, but over the past year there have been constant updates and improvements.

Not that z88dk is now at Release 1.99C, perhaps it is time to add some more updates about RC2014 support.
Note that the CP/M subtype was committed after the 1.99C release, and so daily builds (the normal way) after 1.99C are required.

On Friday, 2 March 2018 00:40:47 UTC+11, Phillip Stevens wrote:
I'd like to note that the serial interface drivers for the RC2014 within z88dk have been completely revamped. They are now "terminal" drivers by default, rather than "character" drivers.
 
Also the subtype options for the +rc2014 target have been expanded. There are now four options:
  • -subtype=acia which can be used when you want to create a complete standalone ROM, with the ACIA UART hardware.
  • -subtype=sio which can be used when you want to create a complete standalone ROM, with the SIO/2 UART hardware.
  • -subtype=basic which can be used where a HexLoad program can be used together with a version of MSBASIC.
  • -subtype=cpm which can be used where the RC2014 is running any version of CP/M.
All of the subtypes (except CP/M) default to the Classic or Mini RC2014 configuration of 8kB of ROM, and 32kB of RAM from 0x8000.
But they can also can easily be configured to work with 56kB of RAM if desired, using #pragma to drive the configuration.

So why is there an additional zcc +rc2014 -subtype=cpm option, when the zcc +cpm platform already exists and works perfectly with the RC2014?
Having CP/M as a subtype will allow RC2014 specific libraries (think AY/YM sound library, and graphics library) to be easily linked into programs to be used within a CP/M environment.
This wouldn't be possible with the default CP/M environment, which is correctly limited to using BDOS calls.

Now there is an additional subtype been added, specifically for the ROMWBW HBIOS API from RC2014, and a new z88dk target +hbios which supports any ROMWBW capable platform.

Underlying all ROMWBW options the Hardware BIOS (HBIOS) API is always present. This means that applications built to use the HBIOS API can use almost all of the RAM (up to 0xFFE0), and have access to debugged and performant serial, disk, video, and audio drivers.

There are 
  • +rc2014 -subtype=hbios which can be used where the RC2014 is running any version of ROMWBW.
  • +hbios  which can be used where the RC2014 is running any version of ROMWBW.
The z88dk now supports a variety of functions that call the HBIOS. The HBIOS API is not orthogonal, so writing clean functions is a bit tricky, but I've got a basic set that allow most things to be done. Because each function is generic (can be used to call any HBIOS function) they are simply named after the registers they provide and return. So just read the ROMWBW API and see which calling style function you need to use.

// return DEHL, function BC
uint32_t hbios
(uint16_t func);

// return A, function BC
uint8_t hbios_a
(uint16_t func);

// return A, function BC, arg DE

uint8_t hbios_a_de
(uint16_t func, uint16_t arg);


// return A, function BC, arg DEHL

uint8_t hbios_a_dehl
(uint16_t func, uint32_t arg);


// return A, function BC, arg DE, void * HL

uint8_t hbios_a_de_hl
(uint16_t func, uint16_t arg, void * buffer);


// return E, function BC
extern uint8_t hbios_e(uint16_t func);


// return E, function BC, arg DE
extern uint8_t hbios_e_de(uint16_t func, uint16_t arg);


// return E, function BC, arg DEHL

uint8_t hbios_e_dehl
(uint16_t func, uint32_t arg);


// return E, function BC, arg DE, void * HL
uint8_t hbios_e_de_hl
(uint16_t func, uint16_t arg, void * buffer);

But, unless you want to call HBIOS directly, then you can use libraries for the FatFS file systems, using any drive attached to the RC2014.
Serial I/O is automatically implemented by the 

#pragma output CRT_ORG_BSS = 0x9000 /* move bss origin to address 0x9000 (check map to confirm there is no overlap between data and bss sections) */

static FIL FileIn, FileOut;         /* File object needed for each open file */

#define BUFFER_SIZE 4096            /* size of working buffer (on heap) */
static BYTE * buffer;               /* working buffer */
                                    
/* must be in bss (which is above 0x8000) for romwbw hbios buffer */

static FATFS * FatFs;               /* FatFs work area needed for each volume */
                                    
/* Pointer to the filesystem object (on heap) */

int main (void)
{
    UINT bw
;
    UINT br
;
    DWORD bwt 
= 0;
    FRESULT res
;

    FatFs = (FATFS *)malloc(sizeof(FATFS));                     /* Get work area for the volume */
    buffer 
= (BYTE *)malloc(sizeof(BYTE)*BUFFER_SIZE);          /* Get working buffer space */

    if ((res = f_mount(FatFs, "2:", 1)) == FR_OK) {             /* Give a work area to the default drive */
   
        printf
("\r\n\nFatFs->fs_type %u\nFatFs->fsize %lu\n", FatFs->fs_type, FatFs->fsize);
        printf
("\r\nOpening 2:random1.txt");

        
if ((res = f_open(&FileIn, "2:random1.txt", FA_READ)) == FR_OK) {
            printf(" - Opened");

            
if ((res = f_lseek(&FileIn, 0)) == FR_OK) {
                printf("\r\nCreating 2:random2.txt");

                
if ((res = f_open(&FileOut, "2:random2.txt", FA_CREATE_ALWAYS | FA_WRITE)) == FR_OK) {
                    printf(" - Created\r\n\nCopying...");

                    
for (;;) {
                        res = f_read(&FileIn, buffer, sizeof(BYTE)*BUFFER_SIZE, &br);
                        
if (res != FR_OK || br == 0) break;     // error or eof
                        res 
= f_write(&FileOut, buffer, br, &bw);
                        bwt 
+= bw;
                        
if (res != FR_OK || bw != br) break;     // error or disk full
                    }

                    f_close
(&FileOut);

                    
if ((res = f_unlink("2:random2.txt")) != FR_OK) {
                        printf("\r\nCouldn't delete 2:random2.txt - f_unlink error #%u\r\n", res);
                    
}
                
} else {
                    printf
("\r\nCouldn't open 2:random2.txt - f_open error #%u\r\n", res);                
                
}
             
} else {
                printf
("\r\nCouldn't seek 2:random1.txt - f_lseek error #%u\r\n", res);
            
}
            f_close
(&FileIn);
        
} else {
            printf
("\r\nCouldn't open 2:random1.txt - f_open error #%u\r\n", res);
        
}
        printf
("\r\nCopied %lu bytes", bwt );

        f_mount
(0, "2:", 0);                                    /* Free work area */
    
} else {
        printf("\r\nCouldn't mount drive - f_mount error #%u\r\n", res);
    
}
    
// Perform any shutdown/cleanup.
    free
(buffer);
    free
(FatFs);
    
return 0;
}

Using the below incantation, and cat the Intel Hex into the ROMWBW dbgmon using "M" and "L" . Run with "R100".

zcc +hbios -clib=sdcc_iy -SO3 -v -m --list --max-allocs-per-node100000 -llib/scz180/time -llib/hbios/diskio_hbios -llib/hbios/ff fileCopyTest.c -o fileCopyTest -create-app

Note the -llib/scz180/time is correct. This is required to access time functions compiled into the library, that access HBIOS time functions. These are not present in the default RC2014 libraries, and the library absence will cause a link error.

The ff library for FatFS and the library for diskio_hbios can be installed from the links, once the library repository has been cloned.

Good luck. Let me know of any issues.

Cheers, Phillip


Phillip Stevens

unread,
Jan 11, 2020, 2:21:38 AM1/11/20
to RC2014-Z80
Phillip Stevens wrote:
Well it has taken quite a bit of time and posts on another thread, but I think that the rc2014 is now ready for "prime time" in the z88dk.

The z88dk is a fully featured development environment for z80 processor based machines.

It was all getting a bit long and tedious.

I wrote a page in the RC2014 Wiki, which I hope will make more sense, which can be maintained and updated as needed,
and which has links across to a number of other resources already existing with much more detail where needed.

Phillip

Erik Linder

unread,
Jan 11, 2020, 4:16:21 AM1/11/20
to rc201...@googlegroups.com
Thanks a lot.
Great work, much appreciated here.


--
You received this message because you are subscribed to the Google Groups "RC2014-Z80" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rc2014-z80+...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/rc2014-z80/3d04162c-5a94-4436-923e-2a529e4935e4%40googlegroups.com.

Phillip Stevens

unread,
Jan 31, 2020, 4:09:58 AM1/31/20
to RC2014-Z80
Phillip Stevens wrote:
I wrote a page in the RC2014 Wiki, which I hope will make more sense, which can be maintained and updated as needed,
and which has links across to a number of other resources already existing with much more detail where needed.

Well some relatively big news in the world of Z80. The SDCC just hit 4.0.0 release today.
Congratulations to the team responsible.

Z88DK has also just incorporated this latest SDCC (with adaption patches called ZSDCC) into the repository.
Another big whoo hoo!

For interest, the SDCC team release big numbers when things are stable and as good as it gets.
Then, they go off and start adding new features (aka breaking things).
This means that ZSDCC 4.0.0 is a stable and solid platform for use with z80 and variants (Z180, Z80N, 8080, Gameboy) for a while.

I'm hoping that a new Z88DK v2.0.0 release can be coaxed out soon too.
Fingers crossed / Daumen drueken.

Phillip

Alan Cox

unread,
Jan 31, 2020, 6:56:54 AM1/31/20
to rc201...@googlegroups.com
> This means that ZSDCC 4.0.0 is a stable and solid platform for use with z80 and variants (Z180, Z80N, 8080, Gameboy) for a while.

I didn't realise the 8080 fork had been added. That's cool. Just need
8085 support now 8)

Alan

Phillip Stevens

unread,
Jan 31, 2020, 7:27:40 AM1/31/20
to RC2014-Z80
Alan Cox wrote:
> > This means that ZSDCC 4.0.0 is a stable and solid platform for use with z80 and variants (Z180, Z80N, 8080, Gameboy) for a while.
>
> I didn't realise the 8080 fork had been added. That's cool.

Yes it's on the classic library side only. So not for a RC2014-8080, at this stage.

It comes in two parts. The classic library has support for an Intel code path now. And the assembler has emulations of all non Z80 equivalent instructions.

This means (I think) that SDCC doesn't even know that it is not compiling for Z80, and the resulting assembly is fixed up by the z88dk assembler, and correct library functions.

What I'm not totally sure about is whether support is via both ZSDCC and SCCZ80 compilers, or just SCCZ80. But the repository tells no lies.

Phillip

Phillip Stevens

unread,
Feb 4, 2020, 7:06:29 PM2/4/20
to RC2014-Z80
Alan Cox wrote:
I didn't realise the 8080 fork had been added. That's cool.

For interest the issue covering 8080 support is #1226.
 
Just need 8085 support now 8)

And, the issue covering 8085 support is #1231.

If you'd like to add to the discussion to make sure your thoughts are covered, please chime in.

Cheers, Phillip

Phillip Stevens

unread,
Feb 7, 2020, 8:19:04 PM2/7/20
to RC2014-Z80
Phillip Stevens wrote:
I wrote a page in the RC2014 Wiki, which I hope will make more sense, which can be maintained and updated as needed, and which has links across to a number of other resources already existing with much more detail where needed.

z88dk also has an external examples repository, alongside the classic examples, and the newlib _DEVELOPMENT/EXAMPLES.

I just added an example on using the ChaN FATFS library to the external examples repository. This program will write data to the first FAT formatted drive it can find, across either the IDE, or HBIOS (and therefore any drive) disk interfaces.

The example is useful insight if you want to use your RC2014 as a data logger, or to help you write a novel, or anything else where you need data to be transferred easily to a "modern" PC using a FAT32 formatted Card or Disk.

Phillip
Reply all
Reply to author
Forward
0 new messages