So, I'm trying to use Z88DK to generate ROM images for my RC2014 and I'm having some, but not quite enough, success.
So, I'm trying to use Z88DK to generate ROM images for my RC2014 and I'm having some, but not quite enough, success.Steve, the short answer is that we broke the subtype=acia option, and it hasn't been fixed yet.And we're working on fixing other things too.
I've got a ZX Spectrum, an RC2014, an Epson PX-4+, and soon a Spectrum NEXT board - and ALL of these targets are supported (or in active development). This is great - means I only need to learn one set of tools to be able to target any of them.
The biggest problem I'm having at the moment is just the learning curve.
The fact that there are two sets of compilers and libraries in particular is confusing things
I would love to have access to the Softools z180 C compiler too, because it automatically handles the memory banking available on the z180. But, it is too expensive for such an "old" product, and I object to paying for something that hasn't been developed or improved for such a long time.
This suggests that I'm building them right - but why isn't the serial working?
Is it actually working for anybody?
Lots of detailed stuff!
I have now managed to build and run a working Eliza on an RC2014 with standard ROM, using basic_dcio:
1. zcc +rc2014 -subtype=basic_dcio -v -clib=sdcc_ix -m -SO3 --c-code-in-asm --list eliza.c -o eliza_rc2014_basic32_dcio.bin -create-app -lm
4. hdoke &8049, &h9000 // This was an ordeal in itself - finding that the address is 0x8049, not 0x8048, nor 0x8224.
; BASIC WORK SPACE LOCATIONS
WRKSPC .EQU 8045H ; BASIC Work space
USR .EQU WRKSPC+3H ; "USR (x)" jump
OUTSUB .EQU WRKSPC+6H ; "OUT p,n"
OTPORT .EQU WRKSPC+7H ; Port (p)
; INITIALISATION TABLE -------------------------------------------------------
INITAB: JP WARMST ; Warm start jump <- this table is written to 8045H JP FCERR ; "USR (X)" jump (Set to Error) OUT (0),A ; "OUT p,n" skeleton
; BASIC ORIGIN ---------------------------------------------------------------
COLD: JP STARTB ; Jump in for cold startWARM: JP WARMST ; Jump in for warm startSTARTB: LD IX,0 ; Flag cold start JP CSTART ; Jump to initialise
.WORD DEINT ; Get integer -32768 to 32767 .WORD ABPASS ; Return integer in AB
CSTART: LD HL,WRKSPC ; Start of workspace RAM LD SP,HL ; Set up a temporary stack JP INITST ; Go to initialise
INIT: LD DE,INITAB ; Initialise workspace LD B,INITBE-INITAB+3; Bytes to copy LD HL,WRKSPC ; Into workspace RAMCOPY: LD A,(DE) ; Get source LD (HL),A ; To destination INC HL ; Next destination INC DE ; Next source DEC B ; Count bytes JP NZ,COPY ; More to moveI also managed to get StarTrek working - which actually revealed a very nasty bug.
Long story short, I found a very nasty bug, that is either an unpleasant obscure part of the C spec, or would appear to be a compiler bug.
It appears that in some cases, if:
1. You have an expression involving int16_t variables, and
2. the expression is used as an array index, and
2. the expression evaluates to >= 128, and
3. the array is < 256 bytes long
then the expression result will be implicitly cast to int8_t, and will be wrongly interpreted as a negative array index.
It appears that in some cases, if:
1. You have an expression involving int16_t variables, and
2. the expression is used as an array index, and
2. the expression evaluates to >= 128, and
3. the array is < 256 bytes long
then the expression result will be implicitly cast to int8_t, and will be wrongly interpreted as a negative array index.
I have now managed to build and run a working Eliza on an RC2014 with standard ROM, using basic_dcio:
1. zcc +rc2014 -subtype=basic_dcio -v -clib=sdcc_ix -m -SO3 --c-code-in-asm --list eliza.c -o eliza_rc2014_basic32_dcio.bin -create-app -lmGreat to hear, and see!
Just to note that the preferred library setting is -clib=sdcc_iy, because of the way that sdcc operates. It’s always preferable to use the “sdcc_iy” version of the library because this gives sdcc sole use of ix for its frame pointer while the library uses iy. If “sdcc_ix” is selected, sdcc and the library must share ix which means the library must insert extra code to preserve the ix register when it is used. This means the “sdcc_iy” compile will always be smaller and faster.
4. hdoke &8049, &h9000 // This was an ordeal in itself - finding that the address is 0x8049, not 0x8048, nor 0x8224.I was beginning to think that I'd sold you a dud, but in fact the hexload.bas program does actually refer to 0x8049.I'll look around to find where the bad info on 0x8048 is located.0x8048 contains the actual JP instruction, rather than the destination address
The 0x8224 address comes from the revised origin location in my HexLoadr ROM, with performance optimised ACIA code and integrated Hexload code requiring more space. Sorry that was confusing.
I also managed to get StarTrek working - which actually revealed a very nasty bug.I also couldn't get it working, because as you point out it is too large for an origin of 0x9000.But using the HexLoadr ROM, and leaving Basic only a few bytes, I could set the program origin down to 0x8400 and fit it in with the additional space.
The 0x8224 address comes from the revised origin location in my HexLoadr ROM, with performance optimised ACIA code and integrated Hexload code requiring more space. Sorry that was confusing.
Again, I realised after a while that the address changed between the HexLoadr ROM and the standard ROM.
I haven't actually tried the HexLoadr ROM yet - something for next weekend. :-)
I very much want to be able to use the RC2014 standalone without having to have another computer attached to talk to it, so I've been using SD cards so far.
I also managed to get StarTrek working - which actually revealed a very nasty bug.I also couldn't get it working, because as you point out it is too large for an origin of 0x9000.But using the HexLoadr ROM, and leaving Basic only a few bytes, I could set the program origin down to 0x8400 and fit it in with the additional space.
Ok, I'll try that. Would be nice to restore the instructions. :-)
#pragma output CRT_ORG_CODE = 0x8400 // new origin.
#pragma output REGISTER_SP = 0 // stack origin is 0 (0xFFFF).
#pragma output CLIB_MALLOC_HEAP_SIZE = -1 // -1 has the crt automatically place the heap between the end
// of the bss section and the bottom of the stack
// (now located in its usual position above the bss).Create a file to contain pragmas. Call it mypragma.inc, or whatever you like. In the file you'll need the following lines to appear.#pragma output CRT_ORG_CODE = 0x8400 // new origin.
#pragma output REGISTER_SP = 0 // stack origin is 0 (0xFFFF).
#pragma output CLIB_MALLOC_HEAP_SIZE = -1 // -1 has the crt automatically place the heap between the end
// of the bss section and the bottom of the stack
// (now located in its usual position above the bss).Then from the command line add the following incantation -pragma-include=mypragma.inc to your usual compilation instructions.
Although with startrek.c specifically, the heap should be disabled ( CLIB_MALLOC_HEAP_SIZE = 0) so that it doesn't take up memory space. There are pragmas in startrek.c that do this but your pragma file will override those. Pragma priority is: 1- specified on the compile line 2- specified in a pragma file 3- specified in a .c source file.
For compiles where the crt automatically generates a heap ( CLIB_MALLOC_HEAP_SIZE is negative), there is a heap size calculation done at runtime. If the heap size comes out negative, ie there is no space for a heap, the program will just terminate. When CLIB_MALLOC_HEAP_SIZE = -1, the crt creates a heap that extends from the end of your program to the bottom of the stack (the bottom of the stack is the current value of SP minus headroom CRT_STACK_SIZE bytes which is typically 256 or 512). When CLIB_MALLOC_HEAP_SIZE < -1, its absolute value is taken as the address of the last byte of the heap and the crt will try to make a heap from the end of your program to that address. The other options are 0 which eliminates the heap and a positive value which will create a heap of that size in the bss section.