FBS (or, an experiment of updating old code) (+source +game)
FBS (or, an experiment of updating old code) (+source +game)
While I was looking at some old thread this week, I found an old experiment of mine from 2014, called FBS.
So I decided to see if this still compiles in 2021, using the 2.1 official version (shouldn't matter that much in this case.)
Source code and compiled version in enclosed in the zip file.
If you're not interested in the technical details of porting to 2021, then it's also fine to just play with it or read the (really old) code.
Anyway, it seems the differences between the 2012(!) and the 2021 compiler in this case, are very minimal, but important. And here they were all about the inline assembly functions. (PS. I kept the compiler options the same for the old and the current compilers.)
1) __CALLEE__ behaviour has changed. Back then the behaviour of callee was that the inline assembly code is responsible for the popping of the parameters. The current 2.1 instead adds all the POPs at the end of the callee function. So I added "ret"s at the end of each callee function so that those new POPs won't be invoked.
2) __FASTCALL__ behaviour has changed too. Back then all parameter declarations in the fastcall were ignored. In 2.1, inline fastcall functions with an input parameter starts with "push hl" instead of nothing. (and probably ends with something too, not checked). It seems that removing the parameter declaration will remove the push.
3) Oh, and the resulting tap file is twice the size now. No idea why. (No I haven't included the symbols or other output. I have no idea how to generate them. But I can generate them if you need them.)
I wonder why these things were changed. I can adapt to the function behaviour changes, but I'm worried about the size blow up.
So I decided to see if this still compiles in 2021, using the 2.1 official version (shouldn't matter that much in this case.)
Source code and compiled version in enclosed in the zip file.
If you're not interested in the technical details of porting to 2021, then it's also fine to just play with it or read the (really old) code.
Anyway, it seems the differences between the 2012(!) and the 2021 compiler in this case, are very minimal, but important. And here they were all about the inline assembly functions. (PS. I kept the compiler options the same for the old and the current compilers.)
1) __CALLEE__ behaviour has changed. Back then the behaviour of callee was that the inline assembly code is responsible for the popping of the parameters. The current 2.1 instead adds all the POPs at the end of the callee function. So I added "ret"s at the end of each callee function so that those new POPs won't be invoked.
2) __FASTCALL__ behaviour has changed too. Back then all parameter declarations in the fastcall were ignored. In 2.1, inline fastcall functions with an input parameter starts with "push hl" instead of nothing. (and probably ends with something too, not checked). It seems that removing the parameter declaration will remove the push.
3) Oh, and the resulting tap file is twice the size now. No idea why. (No I haven't included the symbols or other output. I have no idea how to generate them. But I can generate them if you need them.)
I wonder why these things were changed. I can adapt to the function behaviour changes, but I'm worried about the size blow up.
You do not have the required permissions to view the files attached to this post.
Re: FBS (or, an experiment of updating old code) (+source +game)
Wow, sccz80 has got a lot stricter over the years so congrats on not using any of the dodgy constructs that used to be supported!Timmy wrote: ↑Sun Mar 07, 2021 3:18 pm Anyway, it seems the differences between the 2012(!) and the 2021 compiler in this case, are very minimal, but important. And here they were all about the inline assembly functions. (PS. I kept the compiler options the same for the old and the current compilers.)
That's actually easy to sort out - for a function that's written in assembler but framed in C, you need to mark the function as __naked This was introduced a while back for source compatibly with zsdcc.1) __CALLEE__ behaviour has changed. Back then the behaviour of callee was that the inline assembly code is responsible for the popping of the parameters. The current 2.1 instead adds all the POPs at the end of the callee function. So I added "ret"s at the end of each callee function so that those new POPs won't be invoked.
2) __FASTCALL__ behaviour has changed too. Back then all parameter declarations in the fastcall were ignored. In 2.1, inline fastcall functions with an input parameter starts with "push hl" instead of nothing. (and probably ends with something too, not checked). It seems that removing the parameter declaration will remove the push.
The best options to use when investigating this are "-Cl-v -m" the first one turns up the logging on the linker and second generates the map file.3) Oh, and the resulting tap file is twice the size now. No idea why. (No I haven't included the symbols or other output. I have no idea how to generate them. But I can generate them if you need them.)
Lets run through it (using whatever I've got in my environment)
Code: Select all
zcc +zx -zorg=24000 -create-app w1.c -Cl-v -> 3843 bytes
Linking library module 'in_Inkey'
Linking library module 'in_keytranstbl'
Linking library module 'fputc_cons_generic_full'
Linking library module 'generic_console_attrs'
Linking library module 'generic_console_printc'
Linking library module 'generic_console_cls'
Linking library module 'console_vars'
Linking library module 'code_clib'
Linking library module 'console_vars'
Linking library module 'CRT_FONT'
Linking library module 'CRT_FONT_64'
Linking library module 'generic_console_scrollup'
Linking library module 'console_coords'
Linking library module 'gencon_vars_asm'
Linking library module 'zx_border'
Linking library module 'rand'
Linking library module 'asm_rand'
Linking library module '__stdlib_seed'
Linking library module 'asm_random_uniform_xor_32'
Linking library module 'l_gintspsp'
Linking library module 'l_gt'
Linking library module 'l_compare_result'
Linking library module 'l_lneg'
Code: Select all
zcc +zx -zorg=24000 -create-app w1.c -Cl-v -pragma-define:fputc_cons=0 -Cl-v -> 2201 bytes
Code: Select all
Section 'code_crt_init' size: 42 bytes ($5E8D to $5EB6)
Section 'code_crt_exit_exit' size: 1 bytes ($5EB8 to $5EB8)
Section 'code_compiler' size: 1251 bytes ($5EB9 to $639B)
Section 'code_clib' size: 227 bytes ($639C to $647E)
Section 'code_crt0_sccz80' size: 40 bytes ($647F to $64A6)
Section 'code_stdlib' size: 66 bytes ($648C to $64CD)
Section 'data_compiler' size: 6 bytes ($658F to $6594)
Section 'bss_crt' size: 105 bytes ($6595 to $65FD)
Section 'bss_compiler' size: 11 bytes ($65FE to $6608)
Code: Select all
zcc +zx -zorg=24000 -create-app w1.c -Cl-v -pragma-define:fputc_cons=0 -pragma-define:CRT_INITIALIZE_BSS=0 -Cl-v -> 2189 bytes
Section 'code_crt_init' size: 30 bytes ($5E8D to $5EAA)
Code: Select all
zcc +zx -zorg=24000 -create-app w1.c -Cl-v -pragma-define:fputc_cons=0 -pragma-define:CRT_INITIALIZE_BSS=0 -pragma-define:CRT_ENABLE_STDIO=0 -Cl-v -> 2074 bytes
Section 'code_crt_init' size: 15 bytes ($5E8D to $5E9B)
Section 'bss_crt' size: 5 bytes ($657A to $657E)
Code: Select all
z88dk-dis -x a.map -o 24000 a.bin
loadbanks:
ld ix,$c000 ;[5df2] dd 21 00 c0
ld de,$0000 ;[5df6] 11 00 00
ld c,$10 ;[5df9] 0e 10
call load_block ;[5dfb] cd 66 5e
ret c ;[5dfe] d8
....
Re: FBS (or, an experiment of updating old code) (+source +game)
Actually, there is a way to switch off that loader:
So we're now smaller than it was in 2012, some tweaking needed obviously but there are a few more features than there were back in 2012!
Code: Select all
zcc +zx -zorg=24000 -create-app w1.c -Cl-v -pragma-define:fputc_cons=0 -pragma-define:CRT_INITIALIZE_BSS=0 -pragma-define:CRT_ENABLE_STDIO=0 -pragma-define:CRT_DISABLELOADER=1 -Cl-v -m -> 1916 bytes
Re: FBS (or, an experiment of updating old code) (+source +game)
Well, this was the easiest of the codes. I'm sure there will be some more "dodgy constructs" later on, but since many of my games almost fully used the 48k memory, I haven't tried converting them yet. Maybe one day.dom wrote: ↑Sun Mar 07, 2021 5:22 pmWow, sccz80 has got a lot stricter over the years so congrats on not using any of the dodgy constructs that used to be supported!Timmy wrote: ↑Sun Mar 07, 2021 3:18 pm Anyway, it seems the differences between the 2012(!) and the 2021 compiler in this case, are very minimal, but important. And here they were all about the inline assembly functions. (PS. I kept the compiler options the same for the old and the current compilers.)
I had just some testing with __naked, and it seems that its behaviour is a bit different than the old compiler.That's actually easy to sort out - for a function that's written in assembler but framed in C, you need to mark the function as __naked This was introduced a while back for source compatibly with zsdcc.1) __CALLEE__ behaviour has changed. Back then the behaviour of callee was that the inline assembly code is responsible for the popping of the parameters. The current 2.1 instead adds all the POPs at the end of the callee function. So I added "ret"s at the end of each callee function so that those new POPs won't be invoked.
2) __FASTCALL__ behaviour has changed too. Back then all parameter declarations in the fastcall were ignored. In 2.1, inline fastcall functions with an input parameter starts with "push hl" instead of nothing. (and probably ends with something too, not checked). It seems that removing the parameter declaration will remove the push.
In short, the old compiler always added a RET at the end of every callee or fastcall function. Naked functions are completely naked, i.e. without a RET at the end.
I agree that it is a better solution, but it is still different than it was before, so I'd still need to append a RET at the end of every inline fastcall and callee function when I'm converting them. Good to know.
===========
And since it's already past 1AM over here, I'll just brainstorm a bit about the rest of your reply...
1) So many options to just make the code smaller for games.
2) Can I use #pragma inside my source code instead, for example like "#pragma fputc_cons 0"?
3) I can't even remember we have a feature to load data into 128k banks? I thought the idea was to load them externally and use bank switching in your own code?
4) Also why is the 128k banks loading option even a default?
5) Thanks a lot to explain all these pragma defines! I don't think most of us would figure them out. They are all useful, too!
6) And I also wonder whether it makes sense to just make some of those defines to be defaults, or since most people are writing games zith z88dk nowadays anyway. Or some simple way to explain to people that these are the default options when you make games.
7) I'll check the -Cl-v option later.
Sorry for the brainstorming, but my brain is telling me to go to sleep and I don't want to forget any of these things.
Thank you so much for all the explanations! This will save some unnecessary bytes (which is really important when making games on the 48k.)
Re: FBS (or, an experiment of updating old code) (+source +game)
Yeah, I saw it was mostly asm! I suspect 90% of the trouble will be around the following areas:
1. Function pointers being defined as a void * pointer (which we've run into in the past)
2. Struct pointers
3. sdcc harmonisation
And of course the default size being bigger now than they used to be; which is what this thread is about!
That's a good point that now I remember bit me a couple of times. I guess that's another reason why AA recommended not embedding asm in C files!I had just some testing with __naked, and it seems that its behaviour is a bit different than the old compiler.
In short, the old compiler always added a RET at the end of every callee or fastcall function. Naked functions are completely naked, i.e. without a RET at the end.
I agree that it is a better solution, but it is still different than it was before, so I'd still need to append a RET at the end of every inline fastcall and callee function when I'm converting them. Good to know.
1 and 6, I think the philosophy is really to make everything work by default and then prune when it's needed - can you imagine the grief we'd get if printf didn't work by default for example? Unfortunately with stdio we've sort of hung ourselves: back before we added sections we couldn't move the FILE block out into the library so an option as added to change the number of files. Now we've got sections we can't move the FILE block into the library because of the option to change the number of files since you can't change the size of a defs block based on a symbol defined elsewhere.1) So many options to just make the code smaller for games.
2) Can I use #pragma inside my source code instead, for example like "#pragma fputc_cons 0"?
3) I can't even remember we have a feature to load data into 128k banks? I thought the idea was to load them externally and use bank switching in your own code?
4) Also why is the 128k banks loading option even a default?
5) Thanks a lot to explain all these pragma defines! I don't think most of us would figure them out. They are all useful, too!
6) And I also wonder whether it makes sense to just make some of those defines to be defaults, or since most people are writing games zith z88dk nowadays anyway. Or some simple way to explain to people that these are the default options when you make games.
3. Yes, it was added last year sometime when I was doing all the banking stuff - I wanted a way to test that what I was doing worked across multiple platforms. And 4, it's a default because there's no way to exclude code based on a linker evaluation. It has no effect if there are no banks defined, PS -subtype=plus3 will load the banks from disc instead of tape.
5. I think most of them are detailed here: https://github.com/z88dk/z88dk/wiki/Classic--Pragmas
Re: FBS (or, an experiment of updating old code) (+source +game)
Oh, I forgot to say, yes #pragma can go into the C file or a separate file.
The separate file is the best way for incremental builds, see the top of: https://github.com/z88dk/z88dk/wiki/Classic--Pragmas
One thing that's missing is the format within files, it's:
etc
The separate file is the best way for incremental builds, see the top of: https://github.com/z88dk/z88dk/wiki/Classic--Pragmas
One thing that's missing is the format within files, it's:
Code: Select all
-pragma-define:XYZ=1 -> #pragma define XYZ=1
Re: FBS (or, an experiment of updating old code) (+source +game)
dom wrote: ↑Sun Mar 07, 2021 6:21 pmCode: Select all
zcc +zx -zorg=24000 -create-app w1.c -Cl-v -pragma-define:fputc_cons=0 -pragma-define:CRT_INITIALIZE_BSS=0 -pragma-define:CRT_ENABLE_STDIO=0 -pragma-define:CRT_DISABLELOADER=1 -Cl-v -m -> 1916 bytes
Just had a quick check on this one:dom wrote: ↑Mon Mar 08, 2021 8:41 am5. I think most of them are detailed here: https://github.com/z88dk/z88dk/wiki/Classic--Pragmas
-pragma-define:fputc_cons=0 ==> not found.
-pragma-define:CRT_INITIALIZE_BSS=0 ==> found!
-pragma-define:CRT_ENABLE_STDIO=0 ==> not found, but there was a CRT_ENABLED_STDIO, likely a typo.
-pragma-define:CRT_DISABLELOADER=1 ==> not found.
1 out of 4, still not too bad.
Also, I don't have to use -Cl-v twice in the above zcc command, right?
Re: FBS (or, an experiment of updating old code) (+source +game)
Ok, I've managed to get a compile of the old compiler with "-Cl-v -m", as I promised:
Here's that output, for comparison (note, I've changed some directory names in this output):
(Also note that the source code here is a bit different than the one I've posted earlier, because that code works on the 2.1 compiler. But this source is what generates fbs.tap.)
and the map file:
I'm not planning to make any comment on this; it's all new to me.
Here's that output, for comparison (note, I've changed some directory names in this output):
(Also note that the source code here is a bit different than the one I've posted earlier, because that code works on the 2.1 compiler. But this source is what generates fbs.tap.)
Code: Select all
C:\z88dk\FLAP>zcc +zx -vn w1.c -o w1.bin -lndos -Cl-v -m -create-app -zorg=24000
1 file(s) copied.
1 file(s) copied.
sccz80:"w1.c" L:513 Warning:#17:Expected ';'
Assemble only updated files.
Create symbol table file.
Link/relocate assembled modules.
Link library modules with code.
Create address map file.
Assembling 'C:\[...]\Temp\s3k4_1.asm'...
Pass1...
C:\z88dk\lib\/spec_crt0.asm
zcc_opt.def
C:\z88dk\lib\/float.asm
Pass2...
Size of module is 157 bytes
Total of 692 lines assembled.
linking module(s)...
Pass1...
ORG address for code is 5DC0
Linking library module <IN_INKEY>
Linking library module <IN_KEYTRANSTBL>
Linking library module <L_AND>
Linking library module <L_EQ>
Linking library module <L_GINTSPSP>
Linking library module <L_GT>
Linking library module <L_LNEG>
Linking library module <RAND>
Linking library module <ZX_BORDER>
Code size of linked modules is 1875 bytes
Pass2...
Creating map...
Code generation completed.
1 file(s) copied.
Code: Select all
BASE_GRAPHICS = 5DF0, G: ZX82_CRT0
CALL_ROM3 = 5DE4, G: ZX82_CRT0
CLEANUP = 5DD9, G: ZX82_CRT0
CLEANUP_EXIT = 5DDA, L: ZX82_CRT0
COORDS = 5DEE, G: ZX82_CRT0
DLDPSH = 5E16, G: ZX82_CRT0
DLOAD = 5E0D, G: ZX82_CRT0
DPUSH = 5E1E, G: ZX82_CRT0
DPUSH2 = 5E2D, G: ZX82_CRT0
DSTORE = 5E02, G: ZX82_CRT0
EXITCOUNT = 5DF6, G: ZX82_CRT0
EXITSP = 5DF4, G: ZX82_CRT0
EXTRA = 5E44, G: ZX82_CRT0
FA = 5E4A, G: ZX82_CRT0
FASIGN = 5E50, G: ZX82_CRT0
FLOORLOOP = 5FEC, L: W1
FP_SEED = 5E3E, G: ZX82_CRT0
HEAPBLOCKS = 5DF9, G: ZX82_CRT0
HEAPLAST = 5DF7, G: ZX82_CRT0
IN_INKEY = 635D, G: IN_INKEY
IN_KEYTRANSTBL = 6427, G: IN_KEYTRANSTBL
I_10 = 61FF, L: W1
I_11 = 6210, L: W1
I_12 = 6222, L: W1
I_13 = 6234, L: W1
I_14 = 6246, L: W1
I_15 = 624D, L: W1
I_16 = 6275, L: W1
I_17 = 6296, L: W1
I_18 = 62D3, L: W1
I_18_ULE = 62A0, L: W1
I_19 = 62C3, L: W1
I_2 = 634C, L: W1
I_20 = 62DE, L: W1
I_21 = 6334, L: W1
I_22 = 631F, L: W1
I_23 = 6337, L: W1
I_24 = 633F, L: W1
I_25 = 633F, L: W1
I_26 = 6348, L: W1
I_5 = 614F, L: W1
I_6 = 6158, L: W1
I_7 = 615E, L: W1
I_8 = 61BD, L: W1
I_9 = 6337, L: W1
KEYHITA = 63C5, L: IN_INKEY
KEYHITB = 63DC, L: IN_INKEY
L_5CFE = 60B2, L: W1
L_5D01 = 60B5, L: W1
L_5D40 = 60EF, L: W1
L_5D46 = 60F5, L: W1
L_5D4D = 60FC, L: W1
L_5D53 = 6102, L: W1
L_5D5A = 6109, L: W1
L_5D5F = 610E, L: W1
L_9999 = 60A9, L: W1
L_AND = 64C7, G: L_AND
L_DCAL = 5DE3, G: ZX82_CRT0
L_EQ = 64CE, G: L_EQ
L_GINTSPSP = 64D5, G: L_GINTSPSP
L_GT = 64DE, G: L_GT
L_LNEG = 64EA, G: L_LNEG
NOCAPS = 63F8, L: IN_INKEY
NOKEY = 63C0, L: IN_INKEY
NOSYM = 6403, L: IN_INKEY
NOWA2 = 611E, L: W1
NOWALLS = 6116, L: W1
NUM3A = 5F14, L: W1
NUM4A = 5F16, L: W1
OK1 = 605A, L: W1
PP2 = 5F74, L: W1
PRINT2LOOP = 5F62, L: W1
PRINTCLOOP = 5F2D, L: W1
RAND = 64EF, G: RAND
ROWTBL = 6407, L: IN_INKEY
SND_TICK = 5DFB, G: ZX82_CRT0
START = 5DC0, L: ZX82_CRT0
START1 = 5DDF, L: ZX82_CRT0
WALLEND = 6123, L: W1
ZX_BORDER = 650C, G: ZX_BORDER
_BEEP4 = 5EE7, G: W1
_CHECKDEATH = 607C, G: W1
_CLEARATTRS = 60CF, G: W1
_DRAW4SPACES = 6025, G: W1
_DRAWBIRD = 604F, G: W1
_FLAPCOUNTER = 6357, G: W1
_FLAPPING = 6124, G: W1
_FRAMES = 635A, G: W1
_GAME_END = 6359, G: W1
_GEN_WALLS = 60E0, G: W1
_HISCORE = 5E5D, G: W1
_INITSCREEN = 5FD5, G: W1
_MAIN = 6128, G: W1
_OLD_PLAYER_Y = 635C, G: W1
_PIPECOUNTER = 6353, G: W1
_PL = 6354, G: W1
_PLAYER_Y = 6352, G: W1
_PRINTCXYW = 5F35, G: W1
_PRINTLOGO = 5F6A, G: W1
_PRINTSTRING2 = 5F62, G: W1
_PRINTSTRINGCXYS = 5F1F, G: W1
_SCORE = 6355, G: W1
_SCORECOUNTER = 635B, G: W1
_SCROLLATTRSLEFT = 60C3, G: W1
_SCROLLATTRSLEFT2 = 60AD, G: W1
_STD_SEED = 5DF2, G: ZX82_CRT0
_TIMER = 6358, G: W1
_UDG = 5E5F, L: W1
_VFPRINTF = 5DE4, G: ZX82_CRT0
_WTOA2 = 5EF2, G: W1
__SGOIOBLK = 5DFC, G: ZX82_CRT0
START = 5DC0, L: ZX82_CRT0
CLEANUP = 5DD9, G: ZX82_CRT0
CLEANUP_EXIT = 5DDA, L: ZX82_CRT0
START1 = 5DDF, L: ZX82_CRT0
L_DCAL = 5DE3, G: ZX82_CRT0
_VFPRINTF = 5DE4, G: ZX82_CRT0
CALL_ROM3 = 5DE4, G: ZX82_CRT0
COORDS = 5DEE, G: ZX82_CRT0
BASE_GRAPHICS = 5DF0, G: ZX82_CRT0
_STD_SEED = 5DF2, G: ZX82_CRT0
EXITSP = 5DF4, G: ZX82_CRT0
EXITCOUNT = 5DF6, G: ZX82_CRT0
HEAPLAST = 5DF7, G: ZX82_CRT0
HEAPBLOCKS = 5DF9, G: ZX82_CRT0
SND_TICK = 5DFB, G: ZX82_CRT0
__SGOIOBLK = 5DFC, G: ZX82_CRT0
DSTORE = 5E02, G: ZX82_CRT0
DLOAD = 5E0D, G: ZX82_CRT0
DLDPSH = 5E16, G: ZX82_CRT0
DPUSH = 5E1E, G: ZX82_CRT0
DPUSH2 = 5E2D, G: ZX82_CRT0
FP_SEED = 5E3E, G: ZX82_CRT0
EXTRA = 5E44, G: ZX82_CRT0
FA = 5E4A, G: ZX82_CRT0
FASIGN = 5E50, G: ZX82_CRT0
_HISCORE = 5E5D, G: W1
_UDG = 5E5F, L: W1
_BEEP4 = 5EE7, G: W1
_WTOA2 = 5EF2, G: W1
NUM3A = 5F14, L: W1
NUM4A = 5F16, L: W1
_PRINTSTRINGCXYS = 5F1F, G: W1
PRINTCLOOP = 5F2D, L: W1
_PRINTCXYW = 5F35, G: W1
_PRINTSTRING2 = 5F62, G: W1
PRINT2LOOP = 5F62, L: W1
_PRINTLOGO = 5F6A, G: W1
PP2 = 5F74, L: W1
_INITSCREEN = 5FD5, G: W1
FLOORLOOP = 5FEC, L: W1
_DRAW4SPACES = 6025, G: W1
_DRAWBIRD = 604F, G: W1
OK1 = 605A, L: W1
_CHECKDEATH = 607C, G: W1
L_9999 = 60A9, L: W1
_SCROLLATTRSLEFT2 = 60AD, G: W1
L_5CFE = 60B2, L: W1
L_5D01 = 60B5, L: W1
_SCROLLATTRSLEFT = 60C3, G: W1
_CLEARATTRS = 60CF, G: W1
_GEN_WALLS = 60E0, G: W1
L_5D40 = 60EF, L: W1
L_5D46 = 60F5, L: W1
L_5D4D = 60FC, L: W1
L_5D53 = 6102, L: W1
L_5D5A = 6109, L: W1
L_5D5F = 610E, L: W1
NOWALLS = 6116, L: W1
NOWA2 = 611E, L: W1
WALLEND = 6123, L: W1
_FLAPPING = 6124, G: W1
_MAIN = 6128, G: W1
I_5 = 614F, L: W1
I_6 = 6158, L: W1
I_7 = 615E, L: W1
I_8 = 61BD, L: W1
I_10 = 61FF, L: W1
I_11 = 6210, L: W1
I_12 = 6222, L: W1
I_13 = 6234, L: W1
I_14 = 6246, L: W1
I_15 = 624D, L: W1
I_16 = 6275, L: W1
I_17 = 6296, L: W1
I_18_ULE = 62A0, L: W1
I_19 = 62C3, L: W1
I_18 = 62D3, L: W1
I_20 = 62DE, L: W1
I_22 = 631F, L: W1
I_21 = 6334, L: W1
I_9 = 6337, L: W1
I_23 = 6337, L: W1
I_25 = 633F, L: W1
I_24 = 633F, L: W1
I_26 = 6348, L: W1
I_2 = 634C, L: W1
_PLAYER_Y = 6352, G: W1
_PIPECOUNTER = 6353, G: W1
_PL = 6354, G: W1
_SCORE = 6355, G: W1
_FLAPCOUNTER = 6357, G: W1
_TIMER = 6358, G: W1
_GAME_END = 6359, G: W1
_FRAMES = 635A, G: W1
_SCORECOUNTER = 635B, G: W1
_OLD_PLAYER_Y = 635C, G: W1
IN_INKEY = 635D, G: IN_INKEY
NOKEY = 63C0, L: IN_INKEY
KEYHITA = 63C5, L: IN_INKEY
KEYHITB = 63DC, L: IN_INKEY
NOCAPS = 63F8, L: IN_INKEY
NOSYM = 6403, L: IN_INKEY
ROWTBL = 6407, L: IN_INKEY
IN_KEYTRANSTBL = 6427, G: IN_KEYTRANSTBL
L_AND = 64C7, G: L_AND
L_EQ = 64CE, G: L_EQ
L_GINTSPSP = 64D5, G: L_GINTSPSP
L_GT = 64DE, G: L_GT
L_LNEG = 64EA, G: L_LNEG
RAND = 64EF, G: RAND
ZX_BORDER = 650C, G: ZX_BORDER
Re: FBS (or, an experiment of updating old code) (+source +game)
Thanks Timmy that's really useful.
In terms of the general setup, it looks like these things have changed:
1. The crt0 now has more features (initialise bss etc, but it can now be tuned down to a lot smaller)
2. The FILE block has increased size - I think it's around 60 bytes.
3. rand() is a different, much larger implementation that is actually random!
4. The comparison routine (l_gt) now as an accompanying l_compare_result routine
5. More code is being inlined (notice how there's no l_eq/l_and in the new compilation)
6. I think the actual w1.c now compiles to a smaller size - it looks like it was 1327 bytes, it's now 1266 bytes (*)
7. A screen printer gets dragged in by default
8. Incorporating sections makes it a little harder to figure out exact sizes of each component by eyeballing a .map file
(*) Easy way to see this with z88dk is to compile to an object file and then run z88dk-z80nm on the object file. Count the sizes of the listed sections.
I think on the whole it's ok, as we've added features, we've also added the ability to turn off those features. 7. is a bit annoying: because we've assigned the value of a function to a defc it gets pulled in to the binary, although we never use neither the function nor the defc. I thought there was a GitHub issue for it but I can't track it down.
In terms of the general setup, it looks like these things have changed:
1. The crt0 now has more features (initialise bss etc, but it can now be tuned down to a lot smaller)
2. The FILE block has increased size - I think it's around 60 bytes.
3. rand() is a different, much larger implementation that is actually random!
4. The comparison routine (l_gt) now as an accompanying l_compare_result routine
5. More code is being inlined (notice how there's no l_eq/l_and in the new compilation)
6. I think the actual w1.c now compiles to a smaller size - it looks like it was 1327 bytes, it's now 1266 bytes (*)
7. A screen printer gets dragged in by default
8. Incorporating sections makes it a little harder to figure out exact sizes of each component by eyeballing a .map file
(*) Easy way to see this with z88dk is to compile to an object file and then run z88dk-z80nm on the object file. Count the sizes of the listed sections.
I think on the whole it's ok, as we've added features, we've also added the ability to turn off those features. 7. is a bit annoying: because we've assigned the value of a function to a defc it gets pulled in to the binary, although we never use neither the function nor the defc. I thought there was a GitHub issue for it but I can't track it down.
Re: FBS (or, an experiment of updating old code) (+source +game)
As a follow up to this, I updated reidrac's Castaway to the latest z88dk, and sure enough I needed to do the following:
- Mark the assembler __z88dk_callee and __z88dk_fastcall as __naked
- Mark the joystick function pointer as __z88dk_fastcall (this has come up in a previous thread)
- Create a zpragma.inc to disable features
An extra gotcha was that at some point over the past decade labels have become case sensitive.
It looks like this might be the start of a recipe/checklist for updating code.
- Mark the assembler __z88dk_callee and __z88dk_fastcall as __naked
- Mark the joystick function pointer as __z88dk_fastcall (this has come up in a previous thread)
- Create a zpragma.inc to disable features
An extra gotcha was that at some point over the past decade labels have become case sensitive.
It looks like this might be the start of a recipe/checklist for updating code.
Re: FBS (or, an experiment of updating old code) (+source +game)
Thanks for letting me know Castaway was open sourced. Castaway was/is a really good "metroidvania". One day I will make my own too.
I like that his blog is mentioning this: https://www.usebox.net/jjm/blog/castaway-source-code/
The reason I started making this thread is to see if we can offer some backwards compatibility. There are so many codes out there that are using older z88dk versions that it's worth preserving. A recipe/checklist would be nice.
I will probably not using the source code myself because of the license, but it is good educational material (I hope, haven't really looked at it).
I never noticed the case sensitive labels before... I always use thought they were case sensitive in the first place.
I like that his blog is mentioning this: https://www.usebox.net/jjm/blog/castaway-source-code/
The reason I started making this thread is to see if we can offer some backwards compatibility. There are so many codes out there that are using older z88dk versions that it's worth preserving. A recipe/checklist would be nice.
I will probably not using the source code myself because of the license, but it is good educational material (I hope, haven't really looked at it).
I never noticed the case sensitive labels before... I always use thought they were case sensitive in the first place.
Re: FBS (or, an experiment of updating old code) (+source +game)
Compatibility is always a tricky one, do you keep the quirks/bugs alive? I'd like to update a few more projects and see what else can trip people up - to be honest Castaway only took a couple of hours once I remembered about this thread! The biggest issue was a faulty optimisation rule. If you want to share (privately) with me some of your projects I'm happy to give them a go and see what else pops up and then create some docs.
I suspect it's worthwhile going further with some projects and play around with how the data is stored etc - eg, castaway uses ucl to compress the assets, trying with one of the ZX* might I suspect save even more space.
I'm in the process of updating the classic sp1 so that it's the same code as newlib (it seems to be marginally smaller), opening it up to sdcc/classic compilations. I'm contemplating a port of sp1 to another platform - I'm thinking the PC88 with the ALU might be quite good fun since a) Each pixel is a 1 bit, the ALU allows us to do colour cheaply - so if I can understand what needs to be done we might be able to do a few quick ports.
Yeah, it's a weird one, it looks like z80asm was case insensitive, so although C complained about mis-matched case, if you called a library/C function from assembler with the wrong case it linked ok.
I suspect it's worthwhile going further with some projects and play around with how the data is stored etc - eg, castaway uses ucl to compress the assets, trying with one of the ZX* might I suspect save even more space.
I'm in the process of updating the classic sp1 so that it's the same code as newlib (it seems to be marginally smaller), opening it up to sdcc/classic compilations. I'm contemplating a port of sp1 to another platform - I'm thinking the PC88 with the ALU might be quite good fun since a) Each pixel is a 1 bit, the ALU allows us to do colour cheaply - so if I can understand what needs to be done we might be able to do a few quick ports.
Yeah, it's a weird one, it looks like z80asm was case insensitive, so although C complained about mis-matched case, if you called a library/C function from assembler with the wrong case it linked ok.
Re: FBS (or, an experiment of updating old code) (+source +game)
I have been thinking about it all day, and for the most of the users that aren't on 2.1 or newer, that's a really interesting question.
What I understand is that a lot of users were/are stuck on 1.10 for a very long time. Not because of its quirks or bugs, but because there wasn't any official version for a long time, and because newer versions generated larger code, or that inline assembly was changed without anyone knowing how to fix it. I honestly haven't known about the naked keyword before this thread. And if I want to migrate my old code to 2.1, I'd also have to add naked, and a "ret" at the end, to every single inline assembly function I have used (that's a lot of functions). Migration alone is a lot of work, and even after a migration it wouldn't make any sense because the executable became larger and won't fit into 48k any more. (Most games use almost every single byte of memory, so if a migration makes the executable bigger, then it's never worth it. Also it's not like we need to update our games anyway.)
I don't have a problem with sharing some sources with you, but it would take a while to find my old stuff and pack them into a correct package and all the things. (My games has a lot of resource files and other temporary files, but for compilation purposes you'll only need like 5 to 10 files out of the 50+ files I have. It's a lot of work for me to pick the correct files for you, and I don't know if I can/want to. ) Also I would need a way to send you the files. By the way, I was starting to port parts of the Cherry code to 2.1, and you can see the results in the Map Editor thread.I'd like to update a few more projects and see what else can trip people up - to be honest Castaway only took a couple of hours once I remembered about this thread! The biggest issue was a faulty optimisation rule. If you want to share (privately) with me some of your projects I'm happy to give them a go and see what else pops up and then create some docs.
Fortunately there are enough other source code "out there" that you can play with. And for some low hanging fruits, if you (or me, or together) can migrate Churrera/MK1 (with splib) to 2.1 with a smaller executable than before, we'd be able to help out a lot of users already.
That is a very interesting idea. According to the images on https://www.cpcwiki.eu/forum/programmin ... ncher-zx0/ it is certainly possible that a different compression will give at least 1 more screen.I suspect it's worthwhile going further with some projects and play around with how the data is stored etc - eg, castaway uses ucl to compress the assets, trying with one of the ZX* might I suspect save even more space.
On the other hand, setting "-pragma-define:fputc_cons=0" gives about 1600 bytes, if a screen costs about 140 bytes like it is in my Map Editor, about 10 extra screens. And that without any extra compression.
I don't know if updating sp1 would help, as I understand that sp1 would still need basically every byte between 0xd000-0xffff. It's not going to get me any more bytes for more rooms, is it?I'm in the process of updating the classic sp1 so that it's the same code as newlib (it seems to be marginally smaller), opening it up to sdcc/classic compilations.
I have tried porting sp1 to the MSX, but I couldn't. Mostly because sp1 has a lot of hidden quirks, and lot of useful functions that are useful for a software sprite engine, but I can't map them to the MSX, at all. Other problems include that the datatypes used by sp1 are really large in some functions (for example, I meed a 768 byte array just for sp1_PutTiles(), see the example in Map Editor thread), or that I need to keep flipped functions of the same sprites in memory because sp1 can't do flipped sprites. (Probably why most of my sprites looks forward instead of looking left or right.)I'm contemplating a port of sp1 to another platform - I'm thinking the PC88 with the ALU might be quite good fun since a) Each pixel is a 1 bit, the ALU allows us to do colour cheaply - so if I can understand what needs to be done we might be able to do a few quick ports.
My alternative suggestion is to start with something smaller, like splib1, or some xor based sprite engine. I could open source my engine for future looter; it's a really simple xor based 16x16 pre-shifted sprite engine with a copy of the screen in memory, so it's about 8k of memory footprint. (But it's probably too much work for now.)
Anyway, I think writing this post took me many hours. So I'll stop for now.
Re: FBS (or, an experiment of updating old code) (+source +game)
This is where things get interesting. On my sample (of 1!), I've made a saving of 500 bytes through the pragmas, sp1 updating and time.Timmy wrote: ↑Thu Apr 08, 2021 5:04 pm Migration alone is a lot of work, and even after a migration it wouldn't make any sense because the executable became larger and won't fit into 48k any more. (Most games use almost every single byte of memory, so if a migration makes the executable bigger, then it's never worth it.
Very true, unless you're recycling code of course.Timmy wrote: Also it's not like we need to update our games anyway.
Yes, I looked at that and then realised that I need to find a tutorial because I have virtually zero clue as to what is going on there. I can see that it's generating C code and relies on a modified splib2, but I've not managed to find the source for splib2 which is a big hurdle.Timmy wrote:Fortunately there are enough other source code "out there" that you can play with. And for some low hanging fruits, if you (or me, or together) can migrate Churrera/MK1 (with splib) to 2.1 with a smaller executable than before, we'd be able to help out a lot of users already.
There's two bits to the memory usage; the big 16k-ish chunk and the library routines. The chunk you can't do much about, but the library routines save about 5 bytes which isn't massively significant but every little counts! It's also the last big chunk of effectively duplicated code in the repo and it's the last package outstanding that uses weird relocations that I really can't remember why they had to be done that way.Timmy wrote:I don't know if updating sp1 would help, as I understand that sp1 would still need basically every byte between 0xd000-0xffff. It's not going to get me any more bytes for more rooms, is it?
Yes, I can see that it's going to be difficult to map the software sprites in sp1 to hardware sprites. I think for memory mapped VRAM a conversion should be "fairly easy", but you've made me think twice about the PC88, I think possibly a 6847 machine in hires mode (256x192 b&w) would be an easier starting point - I need to find one with a sensible memory layout to not have to disturb too much.I have tried porting sp1 to the MSX, but I couldn't. Mostly because sp1 has a lot of hidden quirks, and lot of useful functions that are useful for a software sprite engine, but I can't map them to the MSX, at all.
It may not be worth bothering with though, just one of those late night ideas when I forget I have a day job and thousands of other things to do.
Re: FBS (or, an experiment of updating old code) (+source +game)
I found a copy of it via the old geocities mirror here: http://www.oocities.org/aralbrec/sprite ... amples.htm
It looks like Alvin added most of the code (with asm rewrites) to the regular library, just with differing names, so modernising it should be possible.
Re: FBS (or, an experiment of updating old code) (+source +game)
Good to hear. I think I also have a copy of it (downloaded long ago).
Note that splib2 is not splib3, even though they might carry the same names. Some of the differences between them can be found in this thread: https://worldofspectrum.org/forums/disc ... edirect/p1
Also, I just realised that, I have been using 2.0+ versions for my MSX releases. That means that I already managed to migrate some of the games myself without having too much trouble. Of course the MSX is a different machine, so I didn't encounter the many quirks I've had with the Spectrum compilations.
That also means I think I had an idea how to convert some on my sp1 games to the MSX; it's easy if you only use the simple functions in sp1. And usually that means using only the functions that can be found in my sp1 flying saucers demo in the examples directory. Or the example in the map editors thread.
(I actually ported some of my action games to the MSX, but I'm still not happy with how it looks, and hardware limitations like max 4 sprites in a scanline makes conversion really difficult, so I may, or may not release them in the future.)
Re: FBS (or, an experiment of updating old code) (+source +game)
PS: If migrating Churrera directly is too difficult, some of the MK1 games sources have been released, you could try those instead. For example, I was playing a game called Red Planet the other day. I saw there were sources available but I didn't really looked into them. Also many of the Mojon's games have sources. Even if I'm really more interested into playing them.
Re: FBS (or, an experiment of updating old code) (+source +game)
Well, it's not that I'm desperately looking for things to do....
However, I took a look at Redplanet, and made the following changes:
1. zpragma.inc
2. Removing a # which was the old constant operator
I also:
1. Recompiled splib2 using the latest z88dk
Which took a handful of minutes (less time than it's taking me to write this post!). Then I recompiled...
Size of the binary before: 35935, size of the binary with the latest: 35199. Plenty of room for another few screens!
However, I took a look at Redplanet, and made the following changes:
1. zpragma.inc
2. Removing a # which was the old constant operator
I also:
1. Recompiled splib2 using the latest z88dk
Which took a handful of minutes (less time than it's taking me to write this post!). Then I recompiled...
Size of the binary before: 35935, size of the binary with the latest: 35199. Plenty of room for another few screens!
Re: FBS (or, an experiment of updating old code) (+source +game)
That sounds very promising! Perhaps this is the final step and we can now safely migrate to the 2.1!
I must say I have no idea what the # operator means, or how to recompile splib2. But I think we are there for the most part.
Because even people might need a first step to create using MK1 then can now compile it using 2.1 (with modifications) and perhaps we can get them over to 2.1.
I must say I have no idea what the # operator means, or how to recompile splib2. But I think we are there for the most part.
Because even people might need a first step to create using MK1 then can now compile it using 2.1 (with modifications) and perhaps we can get them over to 2.1.
Re: FBS (or, an experiment of updating old code) (+source +game)
Yes, I think it's very good, for me it was easy to do as well which makes me feel positive about the entire process. I suspect there's a bit more that can be squeezed out so I'll be carrying on tinkering. Given that 2.1 went out with a couple of clangers, my thoughts are:
- Raise a PR against MK1 to sort the issues I've found so far
- Creating an splib repo with usable artefacts
- Get hold of the modified source for splib2 and create artefacts (*)
- Release a 2.1.1 since there's a few clangers in 2.1
- Iterate splib2 so that all the support routines point to the routines in library (adt, heap, malloc etc)
- Import splib2 into z88dk as an alternate sprite library to sp1
- Another release
(*) I could transform the binary library, but that's more work than fiddling with the source.
Which should make the entire thing a drop in.
Re: FBS (or, an experiment of updating old code) (+source +game)
Just as an update, this in progress and going OK, there's a git project here: https://github.com/suborb/splib2 with my working copy of splib2 in it.
I've reverse engineered the MK2 source code changes (all pretty minor) and now have a variant of splib2 building with them that works.
There's also a 5 step process for updating the example MK1 projects which are all pretty easy to do. I'm fairly certain we can squeeze a bit more memory out and I do suspect I might need to fiddle with memory maps a little so that beeper code doesn't end up in contended memory.
I've reverse engineered the MK2 source code changes (all pretty minor) and now have a variant of splib2 building with them that works.
There's also a 5 step process for updating the example MK1 projects which are all pretty easy to do. I'm fairly certain we can squeeze a bit more memory out and I do suspect I might need to fiddle with memory maps a little so that beeper code doesn't end up in contended memory.
Re: FBS (or, an experiment of updating old code) (+source +game)
I just read the page, that is a good result!
I think I understand most of it starting from "Recipe for adjusting the source" but I have problems understanding the upper part.
At the bottom part I don't understand why sp and origin needs to change.
Also, I have inlined code that use ix in some of my projects. That means that migrating that would be difficult?
Also, I have no idea what you were talking about in your post 2 posts above this one. I am not very into github, and I understand that PR is a pull request, but what does "artefacts" mean?
I think I understand most of it starting from "Recipe for adjusting the source" but I have problems understanding the upper part.
At the bottom part I don't understand why sp and origin needs to change.
Also, I have inlined code that use ix in some of my projects. That means that migrating that would be difficult?
Also, I have no idea what you were talking about in your post 2 posts above this one. I am not very into github, and I understand that PR is a pull request, but what does "artefacts" mean?
Re: FBS (or, an experiment of updating old code) (+source +game)
Sorry I descended into technobabble.
If you've written a game using MK1 then all you care about is steps 1-5 to update your code. I'm hoping that steps 1-3 will be accepted by the Mojon's via PR which just leaves 4 and 5.
The changing the stack point/origin in 4 is because I've just supplied an example file which may not match with what you've setup (I've seen different values for various MK1 games).
In terms of what the artefact is, this will take the form of a zip file containing (at least): splib2.lib, splib2_mk2.lib and spritepack.h which can be unzipped onto the top of an existing z88dk.
Coming back to your point regarding inlined ix, if you're using sccz80 (which you are) then don't worry about it!
If you've written a game using MK1 then all you care about is steps 1-5 to update your code. I'm hoping that steps 1-3 will be accepted by the Mojon's via PR which just leaves 4 and 5.
The changing the stack point/origin in 4 is because I've just supplied an example file which may not match with what you've setup (I've seen different values for various MK1 games).
In terms of what the artefact is, this will take the form of a zip file containing (at least): splib2.lib, splib2_mk2.lib and spritepack.h which can be unzipped onto the top of an existing z88dk.
Coming back to your point regarding inlined ix, if you're using sccz80 (which you are) then don't worry about it!