CPCWiki forum

General Category => Programming => Topic started by: teopl on 10:12, 01 March 20

Title: Using screen memory in game
Post by: teopl on 10:12, 01 March 20
Hi, I gained quite a lot space with using the memory on screen so I can finally add more levels etc to fit in 64K (don't ask why I still want that limitation although the retrodev is finished :D )

Now I can also do some tutorial levels slowly going from easy to hard and making a game more "gamer friendly".

I used code which was kindly provided by "Legend of steel" authors to do a disc load to screen memory *after* a game is started (inside main function) and this works well.

But is it possible to load binary chunks into screen memory from BASIC and then just start a game? (my experiment was that this way screen memory is erased bu not 100% sure now)
Title: Re: Using screen memory in game
Post by: Sykobee (Briggsy) on 13:18, 03 March 20
I don't quite understand the question. I presume this is about BASIC?


I presume you mean that instead of storing some graphics in memory that you will want to copy to screen memory (e.g., HUD, etc) when you start the game, you load it from disc straight to screen memory at game start, freeing up the other memory?


The (default, simple) CPC screen layout is like having 8 interleaved layers - 1234567812345678... so loading say a 4KB block of memory to the screen at &C000 results in what you load being splayed over the entire screen on lines 12..12..12.. and so on. What you need is a binary loader that takes the screen memory layout into account - which I presume LoS author provided?
Title: Re: Using screen memory in game
Post by: teopl on 22:02, 03 March 20
Yes I know that memory us not continual and these are the continual banks I am using: (they are on low part of the screen, hidden with the invisible palette)

bank1: [50592, ) = 560 bytes
bank2: [52640, ) = 560 bytes
bank3: [54688, ) = 560 bytes
bank4: [56736, ) = 560 bytes
bank5: [58784, ) = 560 bytes
bank6: [60752, ) = 640 bytes
bank7: [62800, ) = 640 bytes
bank8: [64848, ) = 640 bytes

The loading into screen memory is already done and all is working well but:

 I am wondering if this can be done from BASIC without making the screen memory being erased once the BASIC starts the main binary?
This way I could remove the disc / cassette loading code from the main binary and leave it simply in BASIC.

So, if something like this:

10 MEMORY 50591
20 LOAD "BANK1.BIN"
... (what now?) ...
1000 RUN "GAME.BIN"

could leave the screen memory intact for the GAME.BIN to use it? (my experiment was that this way screen memory is erased but not 100% sure now)

---

Edit: I implemented the tool to split the data into chunks to fit the banks and the code to concatenate it back when in the game.

From the LoS game I took the .asm code to load data from the disc within the main game. (but I would rather do this with simple BASIC "LOAD BANK1.BIN")
Title: Re: Using screen memory in game
Post by: andycadley on 20:30, 04 March 20
The screen will already be above HIMEM, so BASIC won't trash it unless you write to that part of the screen in some way (PRINT, CLS etc). If you're hoping for a way where you can PRINT as you like and have BASIC somehow a avoid using some parts of the screen memory, then that just isn't possible.
Title: Re: Using screen memory in game
Post by: teopl on 00:18, 05 March 20
I understand, I was taking care not to touch that part of screen by clearing screen or writing/drawing to it but it looked like something did.

If the BASIC didn't trash it, maybe the disabling of firmware, mode change or something else did.
Maybe I will try again to do this from BASIC and see if it works.
Title: Re: Using screen memory in game
Post by: andycadley on 09:10, 05 March 20
MODE from BASIC will clear the screen and I doubt it worries about preserving the non-visible sections, so would probably blank all the 16k bank (I haven't checked that though)
Title: Re: Using screen memory in game
Post by: roudoudou on 09:25, 05 March 20
MODE from BASIC will clear the screen and I doubt it worries about preserving the non-visible sections, so would probably blank all the 16k bank (I haven't checked that though)
ROM code is
Code: [Select]
ld hl,(#B1CA)
ld l,0
ld d,h
ld e,1
ld bc,#3FFF ; -> ALL 16K erased
ld (hl),l
ldir
Title: Re: Using screen memory in game
Post by: teopl on 00:40, 06 March 20
I forgot to say I am using cpctelera but I guess it doesn't matter.

I made test project and it looks like after RUN command the screen is erased.

This is what I did:

1) made simple "while(1);" program and compiled it to XXX.BIN
2) made LOADER.BAS

10 LOAD "XXX.BIN", 50592
20 RUN "XXX.BIN"

When I start this by RUN"LOADER.BAS" the XXX.BIN is loaded into screen memory but after line 20 it was deleted

Then I changed line 20 like this:

20 MEMORY 16000 : LOAD"XXX.BIN", 16001 : CALL 16001

and screen memory was preserved.

Now the problem is that when I try to do this with real game I get "Memory full" I guess because I am overwriting firmware or something...

Is there a clever way to still load all from basic and not delete screen memory after RUN?
Title: Re: Using screen memory in game
Post by: roudoudou on 00:55, 06 March 20
you memory directive usage is correct so...
what is the real loading adress? and the size of the file?
Title: Re: Using screen memory in game
Post by: Arnaud on 21:16, 06 March 20
Hello,
the subject is really interesting because as usual i run out of memory in my program.

I was thinking to have data at 0xC000 and at start moving it to a better place.

But it crashes directly and i don't know why. Video memory cannot be used when loading binary from Basic ?

Edit : i found why, it's so logical

0x0040 -> 0x1000 : Code & Data
0x1000 -> 0xBFFF : Mem filled with 0 by compiler  ;D
0xC000-> 0xD000 : Data to be moved


Title: Re: Using screen memory in game
Post by: teopl on 22:21, 06 March 20
I am not sure what is the real address, but this is content of .dsk file

(https://i.ibb.co/0F7DFz0/img01.png) (https://ibb.co/WPhxPRr)

code location is set by cpctelera: Z80CODELOC := 0xB18 (2840) and memory before that is game buffer: [64, 2840)

TEOPL.BIN is 40604 bytes.

I am wondering also what does RUN command do compared to CALL?
Title: Re: Using screen memory in game
Post by: teopl on 22:29, 06 March 20
Arnaud, did you manage to load .BIN from basic to screen and use it from main program? (I didn't uderstand your post)

I think I did that but I don't know how to do it with real game binary, with for example 40K+ (where to load it, how to start it...)
Title: Re: Using screen memory in game
Post by: roudoudou on 22:48, 06 March 20
I am not sure what is the real address, but this is content of .dsk file

I am wondering also what does RUN command do compared to CALL?
that's a huge file so you cannot keep the system safe and get back to basic
RUN"FILE will load a file into memory and do a CALL at the entry point
CALL is a basic directive which do a CALL to a memory adress, but if you cant load the file because it's too big...
I guess you need a cruncher to squeeze a little your program and fit below #A000
Title: Re: Using screen memory in game
Post by: Arnaud on 22:49, 06 March 20
Arnaud, did you manage to load .BIN from basic to screen and use it from main program? (I didn't uderstand your post)
No.

In cpctelera you can set a specific address for data with keyword __at(ADDRESS), and i was thinking i can do this :

Code: [Select]
__at(0xC000) const unsigned char graphics[] { ... };
But of course it doesn't work, binary code is contiguous and the memory between my code and the graphics at 0xC000 was filled with 0.

Title: Re: Using screen memory in game
Post by: teopl on 23:33, 06 March 20
that's a huge file so you cannot keep the system safe and get back to basic
RUN"FILE will load a file into memory and do a CALL at the entry point
CALL is a basic directive which do a CALL to a memory adress, but if you cant load the file because it's too big...
I guess you need a cruncher to squeeze a little your program and fit below #A000

So if the file of that size can't be loaded then I will stick to current solution which works fine: load to screen memory outside of BASIC, once the game is already started.
(because I already use crunchers but I plan to maximize the file and not to make it smaller to be able to fit maximum content)

But it's still not clear to me how can a RUN do both: LOAD and CALL but I can't manually call them? Maybe because RUN will not return to BASIC?

And what is the #A000 limit? (I found this memory map but there is no #A000 mentioned)

(https://i.ibb.co/hM64ztS/untitled.png) (https://imgbb.com/)
tab images for websites (https://imgbb.com/)

Title: Re: Using screen memory in game
Post by: roudoudou on 01:21, 07 March 20
you can't rely on absolute values
if i dump memory of a CPC at the first ready, i see DATA from #A860 but people with parados ROM, this will start at #A670, etc.
Title: Re: Using screen memory in game
Post by: mv on 18:00, 27 April 20
But it's still not clear to me how can a RUN do both: LOAD and CALL but I can't manually call them? Maybe because RUN will not return to BASIC?
RUN a binary file does not only LOAD and CALL, but also some sort of reset with clearing the screen (BD13, MC BOOT PROGRAM). It will not return to BASIC.
If your BASIC program is short enough, you can also LOAD a long binary from BASIC:

Code: [Select]
10 openout"!s":memory &1ff
20 load"test1.bin",&200
30 call &200
Title: Re: Using screen memory in game
Post by: TotO on 19:00, 27 April 20
Yes. It is fine when possible to avoid a game to start with a black splash screen, next blue screen (bin), next black screen ...
Title: Re: Using screen memory in game
Post by: teopl on 01:18, 28 April 20
RUN a binary file does not only LOAD and CALL, but also some sort of reset with clearing the screen (BD13, MC BOOT PROGRAM). It will not return to BASIC.
If your BASIC program is short enough, you can also LOAD a long binary from BASIC:

Code: [Select]
10 openout"!s":memory &1ff
20 load"test1.bin",&200
30 call &200

ok so RUN clears screen so I can't use it in that sense. Do you know what is the lowest address where I can load "test1.bin"? And what is the largest "test1.bin" size in bytes?

if I can't load file with ~41K/42K from basic then it's better for me to RUN that file (clearing the screen) and load .bin files to screen *after* the main game.bin is started.