I'm trying to load a code block from my assembler routine without the print output to the screen.
So I've prepared the 17-byte header in IX and called LD_BYTES at ROM $556.
Behind that header I reserved the usual 17-byte space for the header to be received.
Address $556 is being trapped by BASin/BasinC, and what happens now is that the name in the header request (part 1 of the 34-byte area) is being replaced by something entirely different - either the file name from the last LOAD, the name of the Basic project if you saved it, or the name of an auto backup (autoback0..9).
Also, I find the same file name in the header received (part 2 of the area).
Which means, my load request is happily ignored and replaced with some spurious data held by BASin.
Bananas! Potzblitz!
I don't intend to have a tape attached, it would be nice to have it loaded from BASin's work directory.
How could I achieve this from within my code?
BASin - How to load code from assembler?
BASin - How to load code from assembler?
POKE 23614,10: STOP 1..0 hold, SS/m/n colors, b/spc toggle
Re: BASin - How to load code from assembler?
If you call the ROM code directly to load data, then it expects only the data part of the tape, without the header.
If you are lazy, then just call the ROM routine twice. The first time it loads the header (which you ignore), and use the same routine to load the data afterwards.
If you are lazy, then just call the ROM routine twice. The first time it loads the header (which you ignore), and use the same routine to load the data afterwards.
Re: BASin - How to load code from assembler?
As far as I know, the only way to do it is to have a .TAP file attached as a tape. It doesn't jump out to any sort of special development environment file-handling, it just looks for the next sequential unit in a tape file, like any other emulator would.
I haven't tried loading using ROM calls from within the BASin emulation, but I've used the LOAD command from BASIC in BASin, to use my CharAde game engine, which is a chunk of machine code. I put something at the end of the BASIC program like:
9998 STOP
9999 CLEAR xxxxx : LOAD "" CODE : GOTO 1
I can then GOTO 9999 to load the CODE (after attaching a .TAP file containing just my code block) and the CLEAR and the CODE stays in the simulated machine's memory from one run of the BASIC program to another. And when I finally save the program, I re-load it all into a regular emulator, set up a simulated SAVE tape, and save it with LINE 9999. Then re-save the CODE immediately after it on the same tape.
I haven't tried loading using ROM calls from within the BASin emulation, but I've used the LOAD command from BASIC in BASin, to use my CharAde game engine, which is a chunk of machine code. I put something at the end of the BASIC program like:
9998 STOP
9999 CLEAR xxxxx : LOAD "" CODE : GOTO 1
I can then GOTO 9999 to load the CODE (after attaching a .TAP file containing just my code block) and the CLEAR and the CODE stays in the simulated machine's memory from one run of the BASIC program to another. And when I finally save the program, I re-load it all into a regular emulator, set up a simulated SAVE tape, and save it with LINE 9999. Then re-save the CODE immediately after it on the same tape.
Re: BASin - How to load code from assembler?
There's a 2nd trap in the ROM at $63a (1594), this is where the file name is taken from by BASin for the next LD_BYTES call.
Am I supposed to call this trap from assembler? It's a bit clumsy to mock all up.
Am I supposed to call this trap from assembler? It's a bit clumsy to mock all up.
POKE 23614,10: STOP 1..0 hold, SS/m/n colors, b/spc toggle
Re: BASin - How to load code from assembler?
Thank you for commenting @Joefish and @Timmy.
Here's my hacky solution to get a file loaded from code:
Here's my hacky solution to get a file loaded from code:
- Set up a 34-byte area with the following data:
- [0] 3 - this byte tells we're requesting a CODE/SCREEN$ file
- [1..10] - the name of our file, padded with blanks if less than 10 chars
- [11..12] - requested length, may be zero, but better safe than sorry so set it to limit the loaded data to an allowed maximum
- [13..14] - destination address of the data
- [15..16] - zero/unused
- [17..33] - 17 bytes space where the loaded header fits in
- Set up a single byte with value 13, needed to pretend an end of line (any address will do).
- From your code, set syntax evaluation mode, set CHADD to the end of line, set TADDR to 1 ('load') and call the ROM at $634 - this will provide BASin with your file name so that LD_BYTES knows where to find it.
The syntax evaluation mode together with the end of line condition will cause the routine to return from ROM. - Restore CHADD and switch off syntax evaluation, then call LD_BYTES to get the header. Afterwards call it again to get the file content.
Code: Select all
FileHeader:
.db 3 ; [0] type: CODE/SCREEN$
.db [10] ; [1-10] name
.dw 0 ; [11-12] len
.dw 0 ; [13-14] start
.dw 0 ; [15-16] (proglen)
.db[17] ; work header
EndOfLine:
.db 13
LoadFile ; load code/screens from assembler in BASin
-- ; ix = &header (34 bytes)
ld hl (CHADD)
push hl ; save (CHADD)
ld hl EndOfLine
ld (CHADD) hl ; indicate end of line
ld (iy+58) 1 ; (TADDR) = 'load'
res 7 (iy+1) ; enable syntax checking mode
push ix
pop de
inc de ; de = &name
ld bc 10 ; len
ld hl LoadFile2
push hl ; set return addr to LoadFile2
call $634 ; this call will drop its return addr and so continues at LoadFile2
Code: Select all
LoadFile2: ; load file without printing to screen, pt.2
pop hl
ld (CHADD) hl ; restore (CHADD)
set 7 (iy+1) ; disable syntax checking mode
ld l (ix+13)
ld h (ix+14) ; hl = &dest
; from ROM $761, without the prints
push hl ; save &dest
ld bc 17
add ix bc ; ix = work header
L1:
push ix
ld de 17 ; load 17 bytes
xor a ; 'header'
scf ; 'load'
call $556 ; LD_BYTES, trapped by BASin
; BASin jumps to REPORT_R if the file length is too small
pop ix
jr nc L1 ; repeat if error
ld c 128
ld a (ix+0)
cp (ix-17) ; compare file types
jr nz 2
ld c 246 ; types match, so count from -10
cp 4
jr nc L1 ; nonsense type, repeat
push ix
pop de
ld hl $fff0
add hl de ; point to requested/retrieved name
ld b 10
ld a (hl)
inc a ; no name requested?
jr nz 3
ld a c
add b
ld c a ; yes, always match
L2:
inc de
ld a (de)
cp (hl) ; compare requested with retrieved name
inc hl
jr nz 1
inc c ; +1 for each matching char
djnz L2
bit 7 c ; do names match?
jr nz L1 ; no, load next header
; from ROM $7cc, load CODE/SCREEN$ body (you could also do a JP $7cc to spare 40 bytes of code, it's just a tad slower)
ld l (ix-6)
ld h (ix-5) ; requested length
ld e (ix+11)
ld d (ix+12) ; retrieved length (BASin cuts it to requested length if a file with greater length was found)
ld a h
or l
jr z L3 ; take retrieved length if requested length not specified
sbc hl de
jr c L_ex
L3:
pop hl ; restore &dest
ld a h
or l
jr nz L4
ld l (ix+13)
ld h (ix+14) ; take dest from header if not specified
L4:
push hl
pop ix ; ix = &dest
scf ; 'load'
ld a $ff ; 'data'
call $556 ; load file content to ix
ret c
L_ex:
rst err
.db $1a ; tape loading error
POKE 23614,10: STOP 1..0 hold, SS/m/n colors, b/spc toggle
Re: BASin - How to load code from assembler?
Here's a warp effect that uses the file access feature from BASin.
Currently a small Basic prog that LOADs the frames one by one and a small USR routine to throw the bytes onto the screen.
The crisp effect is caused by loading the coloured frame directly followed by the dithered version of the same frame (so that 2 files make for 1 frame effectively).
In total that's 140 files with 900 Kb data loaded from the local drive.
I'm looking to switch the development platform since BasinC isn't going to support IM2 interrupts.
Maybe I can achieve the same in Fuse one day.
(flashy)
Currently a small Basic prog that LOADs the frames one by one and a small USR routine to throw the bytes onto the screen.
The crisp effect is caused by loading the coloured frame directly followed by the dithered version of the same frame (so that 2 files make for 1 frame effectively).
In total that's 140 files with 900 Kb data loaded from the local drive.
I'm looking to switch the development platform since BasinC isn't going to support IM2 interrupts.
Maybe I can achieve the same in Fuse one day.
Spoiler
POKE 23614,10: STOP 1..0 hold, SS/m/n colors, b/spc toggle
Re: BASin - How to load code from assembler?
Yes, 70 fullscreens with 6912 bytes and 70 dithered versions with 6144 bytes. Due to the 16:9 aspect mode, 48 lines of data are thrown into the bin.
The BASin profiler shows that it takes 2.8 frames for two LOAD operations. So it gets to about 230 Kb/s.
I am reading docs about divMMC and Spectranet right now.
POKE 23614,10: STOP 1..0 hold, SS/m/n colors, b/spc toggle