Hi,
Long story short, I'd like to have a BASIC program with binary data attached.
The actual motivation is that a loader that is recognized as BASIC preserves the firmware and settings etc, by contrast the firmware resets itself before a binary executable (run"foo.bin") starts a firmware reset.
Of course one can load binary from BASIC like this:
10 memory XXXX : load "foo.bin" : call YYYY
Can we somehow prepare something that is technically a BASIC program but with long binary data (say, 1500-2000 bytes) inside.
We do not want BASIC DATA command here. Something space-efficient, like binary data just appended. Best would be if one has guarantees that address is the same under all circumstances. This would allow to store Z80 code compiled for fixed address.
I remember a long time ago (30-35 years) poking things in RAM to see how it would garble the BASIC program.
"LIST" would not crash. Trying to modify the program would have strange effects.
I remember seeing a game loader of some soft that would show only one line a comment.
I think I remember that just poking 0 in the "line number" part of a BASIC line would not prevent execution but cause LIST to stop.
Anyway, just ability to RUN the program is enough for this purpose.
And get access to binary data at a know address?
Perhaps there is a simple variable which BASIC uses, that tells "address of end of BASIC program"?
Has anyone tried to just append some binary data to a valid BASIC program block ?
Any other thought?
Thanks!
Maybe I didn't understand what you wanted to do (sorry if that's the case), but wouldn't a Basic stuck with an ASM code would do the trick? I did that for most of my production (check out the DemoIZart loader, or I think I did that with Orion Prime too).
The BASIC code does a CALL &xxxx (xxx is just after, and the CALL line is hidden for good measure). I have the ASM code with the right Basic token if you're interested.
Here you go, with the Imperial Mahjong bootloader, a Basic program... in disguise!!
Save this as a Basic program, and you can RUN it, it won't reset the firmware and all that.
This is my code, but I didn't invent the technique.
;BASIC program at the start.
BL_Start: equ #170
org BL_Start
BL_Line10:
defw BL_Line10F-BL_Line10
defw 10 ;Line number.
defb 1,#c0
defb "Imperial Mahjong"
defb 0
BL_Line10F:
BL_Line20:
defw BL_Line20F-BL_Line20
defw 20
defb 1,#c0
defb "----------------"
defb 0
BL_Line20F:
BL_Line50:
defw BL_Line50F-BL_Line50
defw 30
defb 1,#c0
defb 0
BL_Line50F:
BL_Line52:
defw BL_Line52F-BL_Line52
defw 40
defb 1,#c0
defb "A game by Cargosoft"
defb 0
BL_Line52F:
BL_Line55:
defw BL_Line55F-BL_Line55
defw 50
defb 1,#c0
defb 0
BL_Line55F:
BL_Line60:
defw BL_Line60F-BL_Line60
defw 60
defb 1,#c0
defb "June 2016"
defb 0
BL_Line60F:
BL_Line70:
defw BL_Line70F-BL_Line70
defw 70
defb 1,#c0
defb 0
BL_Line70F:
BL_Line90:
defw BL_Line110F-BL_Line90
defw 80
defb 1,#c0
defb "mahjong.cpcscene.net"
defb 0
BL_Line90F:
BL_Line110:
defw BL_Line110F-BL_Line110
defw 90
defb #83, #1c ;CALL mnemonic.
defw BL_InitPreIntro
defb 0
BL_Line110F:
defw 0
;ASM code after the Basic.
BL_InitPreIntro
di
....
Really cool. I believe this is what CNGSoft does when making compactages of games. Thanks for sharing it :) .
Thanks a lot Targhan!
This answer my explicit questions and some others, too, like :
- Can I generate a valid BASIC file from some PC-side tools? Answer: use an assembler, needs knowledge about how BASIC represents the program. It only needs to be valid enough to run, not even list or anything.
- I don't know very well how BASIC represents programs. Can I populate the BASIC part from a real CPC program? Answer: write a BASIC program on CPC. Prefer an emulator that allows to easily dump memory, like CPCEC. Dump from 0x170, up to, ... to where ? Well, to the first time a place for a BASIC line number is zero. Write ASM source that generates those bytes. Adjust to taste.
Quote from: Targhan on 17:31, 28 May 20
Here you go, with the Imperial Mahjong bootloader, a Basic program... in disguise!!
Save this as a Basic program, and you can RUN it, it won't reset the firmware and all that.
This is my code, but I didn't invent the technique.
Maybe this can help you. You can poke a new end address in ram.
Basic - Start - End
CPC464 - &Ae81 - &Ae83
CPC6128 - &Ae64 - &Ae66
Create a basic program
10 Call &17C
Put your code in &17c
Poke new end address in memory
limit &ffff
ORG &17c
ld hl,tekst ;skrive rutine
skriv:
ld a,(hl)
cp &ff
ret z
call &bb5a
inc hl
jr skriv
.tekst
text "Hello cpcitor and to all the cpcwiki friends"
defb &ff