News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu

Sdcc for gx4000/plus cartridge

Started by Xifos, 09:49, 05 April 15

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Xifos

Hi,

I would like to try some gx4000 programming.
I am using sdcc and i can target cpc plus disk, but not cartridge.
I am using windows 7.
I know of Arnoldemu's buildcpr tool, but it seems that is for linux only.

Are there easy tools for building cartridges files from sdcc, the same way you can have bin files for cpc disk (from sdcc at start) ?

arnoldemu

#1
Quote from: Xifos on 09:49, 05 April 15
Hi,

I would like to try some gx4000 programming.
I am using sdcc and i can target cpc plus disk, but not cartridge.
I am using windows 7.
I know of Arnoldemu's buildcpr tool, but it seems that is for linux only.

Are there easy tools for building cartridges files from sdcc, the same way you can have bin files for cpc disk (from sdcc at start) ?
Using sdcc remember to set your data segment to a different location to your code segment and use a different crt file to initialise the hardware.

The simplest choice is to make it as you would for a ram program and download it to ram before execution.
This allows you to make your program >16KB and not worry about splitting it into 16KB pages and worry about managing the rom paging. However you are limiting your main code to the main ram, but you could page in furthur rom pages in &c000-&ffff for example to run data there or download it.

If you do want to run it direct from cart you need to restrict it to 16KB pages. I'll see if I can make an example for both to give an idea of how to do that. I have some files setup already that can help.

Feel free to use my plus lib if you want.

All my tools build on windows. In recent years I have built them for linux but you can also build them for windows.

Download and register the free visual studio 2013 community edition. Create an empty win32 command line project and add the c files. Then build.

https://www.visualstudio.com/en-us/news/vs2013-community-vs.aspx

EDIT: I attached "mylib" which is the common CPC/Plus code for setting up interrupts etc.
EDIT: arkostrackerlib.zip is arkos tracker wrapped in a sdcc library. Note it's the self modifying version so can't run from rom directly.
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

Xifos

Thanks.

:)
Im downloading visual studio but it's slow with my poor connection...

How do you choose code and data segment with sdcc ?
In the crt file ?

Xifos

All right,

I could compile buildcpr, it's working.
And i managed to do a test program with sdcc, changing graphic mode, drawing a white line on the screen !
:)

Now i must learn to do without firmware, and to play with the rom and ram configurations.
;; mode 0
ld bc,&7f80
out (c),c
it works.

;; mode 0 but perhaps not the good rom config for gx4000 so crashing !
ld bc,&7f8c
out (c),c
;)

arnoldemu

Quote from: Xifos on 10:56, 05 April 15
Thanks.

:)
Im downloading visual studio but it's slow with my poor connection...

How do you choose code and data segment with sdcc ?
In the crt file ?
I specify it in the linker file, but you can also do it on the sdcc command line.


-b _CODE=0x0
-b _DATA=0x8000


With my libs you need to specify these:


-b _SCRTABLE=0x06564
-b _SPRMASK=0x07700
-b _KEYMAP=0x06fe0
-b _LETTERBUFFER=0x06d64


and link like this:


-l lib/mylib/mylib.lib
-l lib/arkostrackerlib/arkostrackerlib.lib
-l lib/pluslib/pluslib.lib

My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

Xifos

#5
For sdcc command line, is it --code-loc and --data-loc ?

Hum, I tried to change a little your buildcpr tool and add the ability of loading bin files in an existing cpr file.

Example :
cprfile.cpr is a cartridge file of 17 ko.

image.bin is a picture file (made by convimgcpc).

buildcpr image.bin cprfile.cpr 16384 128

you have now cprfile.cpr which is 33 ko, with two blocs of 16 ko, the picture file directly in the second bloc.
(the last argument is here to skip the first 128 bytes of the picture file)
(the bin file to add must not exceed 16 ko)

I 'm afraid i did not write it very well, but it's working...
(i made a cpr file of 272 ko with it)
:)

Sorry, when i write ko, just read kb !
(bytes=octets)
;)

Optimus

Not sure if I should reply on this thread or open a new thread, but here it goes.


Just got my C4CPC, I am so happy with it, favorite hardware for a long, and even managed to run on of my code on my GΧ4000.
I used buildcpr, it works if I place the cpr in one of the empty sd slots and switch the dip switches to that position. Yey!
But if I try to load it with the provided loader (the menu screen cpr that is supplied with the C4CPC sd card) it just crashes.


So, is there something additional I should be initing if I want the user to be able to load it through the menu loader?

CraigsBar

Quote from: Optimus on 10:34, 03 July 15
Not sure if I should reply on this thread or open a new thread, but here it goes.


Just got my C4CPC, I am so happy with it, favorite hardware for a long, and even managed to run on of my code on my GΧ4000.
I used buildcpr, it works if I place the cpr in one of the empty sd slots and switch the dip switches to that position. Yey!
But if I try to load it with the provided loader (the menu screen cpr that is supplied with the C4CPC sd card) it just crashes.


So, is there something additional I should be initing if I want the user to be able to load it through the menu loader?
Dunno. Is this on a plus or gx4000?
If you attach the CPR I can test it here on both of those.
IRC:  #Retro4All on Freenode

Optimus

#8
I tried it on gx4000.
It's a secret project so I can't attach, but maybe I can send a CPR in private? Or try to make a simpler CPR and test it.


Actually, I am trying to read arnold's code but I am confused. There are some points I don't understand how it's working.


There is a point where it does that:

ld hl,boot_game
ld de,&be00
push hl    ; I know guess this should be push de? Can't test it since I am at work.
ld bc,end_boot_game
ldir
ret

boot_game:
...code
end_boot_game:

So it's supposed to jump in the &be00 area but it never seems to does that (I tried to put breakpoint in winape, never landed there). Instead pushes hl which contain the address to next lines after ret, and then rets.
There is some more I am trying to understand, like if ROM is at &0000 area, and the code writes to that area, it goes to underlying RAM?


I sort of tried to follow this code in a debugger to no avail. Although by using this code blindly it worked, despite my feeling it should not.
Also, I might need some info on the cartidge banks switching, all bits which bank they switch and at which area, is there a documentation for that?

dthrone

See below for bank switching -


Arnold V Specs Revised - CPCWiki


Yes, the "write through" mechanism means you write to the underlying RAM.


I'm not sure if Gerald's cartridge selector program clears the RAM/ASIC fully before loading a cartridge, so that could cause problems.  This is based on ghost images I've seen when loading .cpr files (non-commercial ones).  Don't know though, guessing  :-\

arnoldemu

Quote from: Optimus on 10:34, 03 July 15
Not sure if I should reply on this thread or open a new thread, but here it goes.


Just got my C4CPC, I am so happy with it, favorite hardware for a long, and even managed to run on of my code on my GΧ4000.
I used buildcpr, it works if I place the cpr in one of the empty sd slots and switch the dip switches to that position. Yey!
But if I try to load it with the provided loader (the menu screen cpr that is supplied with the C4CPC sd card) it just crashes.


So, is there something additional I should be initing if I want the user to be able to load it through the menu loader?

Two possibilities.

it is initialising the hardware to a different state you don't expect.

OR the timing is different through the menu so your code doesn't do as it does without the menu.

Make sure you initialise *all* hardware as you want it including z80 interrupt mode, disable z80 ints, initialise all crtc state, all rom state, assume nothing! then you should be ok with both routes.

Z80's default interrupt mode is im 0!
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

arnoldemu

Quote from: dthrone on 12:00, 03 July 15
See below for bank switching -


Arnold V Specs Revised - CPCWiki


Yes, the "write through" mechanism means you write to the underlying RAM.


I'm not sure if Gerald's cartridge selector program clears the RAM/ASIC fully before loading a cartridge, so that could cause problems.  This is based on ghost images I've seen when loading .cpr files (non-commercial ones).  Don't know though, guessing  :-\
the real hardware doesn't clear the ram either, only specific registers, and those are mentioned in the specs.
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

arnoldemu

Quote from: Optimus on 11:25, 03 July 15

There is a point where it does that:

ld hl,boot_game
ld de,&be00
push hl    ; I know guess this should be push de? Can't test it since I am at work.
ld bc,end_boot_game
ldir
ret

boot_game:
...code
end_boot_game:

So it's supposed to jump in the &be00 area but it never seems to does that (I tried to put breakpoint in winape, never landed there). Instead pushes hl which contain the address to next lines after ret, and then rets.

Ahem, yes, that should be a push de.

I'm wondering if my code ever worked now.
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

arnoldemu

Quote from: Optimus on 11:25, 03 July 15
I tried it on gx4000.
It's a secret project so I can't attach, but maybe I can send a CPR in private? Or try to make a simpler CPR and test it.
If you want to trust me ( I will not share it or talk about it).
Send me a PM where I can get it, I'll trace the startup code and tell you what is needed (and correct my own startup code I published  :o ).
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

dthrone

"the real hardware doesn't clear the ram either, only specific registers, and those are mentioned in the specs."


Is there ever a situation where it doesn't get cleared though, since you have to power-off between cartridge swaps?

arnoldemu

#15
Quote from: dthrone on 13:35, 03 July 15
"the real hardware doesn't clear the ram either, only specific registers, and those are mentioned in the specs."


Is there ever a situation where it doesn't get cleared though, since you have to power-off between cartridge swaps?

The asic document defines the registers that are cleared through reset or "power on". So you can know these will always be cleared.

At power on, others are not cleared so can have random data in them (sprite pixels for example). Same with the ram, it can have random values.

There is a little complication: If you have written to the registers that are not reset, and do a reset, they often retain their values. E.g. If you played burning rubber and did a reset, then the pixels for the burning rubber sprites are still in asic ram.

A lot of the CPC hardware does reset/power on into a known state, but it may not be the one you expect.

Z80: Interrupts are disabled, PC = 0, Interrupt mode 0.
CRTC: All registers are reset to 0. So screen has no dimensions.
Gate-Array: border is set to black (on cpc, not on asic). All other colours are not reset. Upper and lower rom are active, mode 0 selected.

My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

dthrone

"Make sure you initialise *all* hardware as you want it including z80 interrupt mode, disable z80 ints, initialise all crtc state, all rom state, assume nothing! then you should be ok with both routes."


I used your (Arnoldemu's) initialisation routine on your website and it works fine for me.  The only thing it didn't remind me to do was set the SP which took a bit of debugging to realise  ;D

dthrone

Quote from: arnoldemu on 13:38, 03 July 15
The asic document defines the registers that are cleared through reset or "power on". So you can know these will always be cleared.

At power on, others are not cleared so can have random data in them (sprite pixels for example). Same with the ram, it can have random values.

There is a little complication: If you have written to the registers that are not reset, and do a reset, they often retain their values. E.g. If you played burning rubber and did a reset, then the pixels for the burning rubber sprites are still in asic ram.

A lot of the CPC hardware does reset/power on into a known state, but it may not be the one you expect.

Z80: Interrupts are disabled, PC = 0, Interrupt mode 0.
CRTC: All registers are reset to 0. So screen has no dimensions.
Gate-Array: border is set to black (on cpc, not on asic). All other colours are not reset. Upper and lower rom are active, mode 0 selected.




What's your recommended way to deal with this?  Make sure you initialise the hardware properly - no problem, and push 64k zeros into the RAM to be safe?

arnoldemu

Quote from: dthrone on 13:48, 03 July 15



What's your recommended way to deal with this?  Make sure you initialise the hardware properly - no problem, and push 64k zeros into the RAM to be safe?
Yes for the hardware.

For the ram, initialising all to 64kb would take too long although it would be the safest choice.

If you are copying your code from cart into ram (as I do in one of my examples), and the code has been made using asm or linked already, then the values are defined by you in the code and copied into ram. You only need to clear the ram you did not define or you allocate when the program is running.

Using SDCC it does have code in the CRT that will initialise your variables, but I have forgotten this before, so sometimes it is best to initialise them in your code at the start of main.
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

arnoldemu

Quote from: dthrone on 13:41, 03 July 15
"Make sure you initialise *all* hardware as you want it including z80 interrupt mode, disable z80 ints, initialise all crtc state, all rom state, assume nothing! then you should be ok with both routes."


I used your (Arnoldemu's) initialisation routine on your website and it works fine for me.  The only thing it didn't remind me to do was set the SP which took a bit of debugging to realise  ;D

oops, I will correct that.
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

dthrone

Quote from: arnoldemu on 13:59, 03 July 15
Yes for the hardware.

For the ram, initialising all to 64kb would take too long although it would be the safest choice.

If you are copying your code from cart into ram (as I do in one of my examples), and the code has been made using asm or linked already, then the values are defined by you in the code and copied into ram. You only need to clear the ram you did not define or you allocate when the program is running.

Using SDCC it does have code in the CRT that will initialise your variables, but I have forgotten this before, so sometimes it is best to initialise them in your code at the start of main.




The RAM is used for screen, DMA lists and variables only, so as long as I initialise all variables, not just non-zero ones like currently, and clear the screen areas, I guess I'll be ok  8)

Optimus

Ok, it actually works now by replacing PUSH HL with PUSH DE. I guess before, the jump was wrong but it landed on a field of NOPs and went on till it found the correct code so it happened to work. Except from within the menu which loads it's own code, so no more innocent NOPfields :)

Powered by SMFPacks Menu Editor Mod