New dev using sjasm for MSX2, requesting aid :)

Page 5/7
1 | 2 | 3 | 4 | | 6 | 7

By ARTRAG

Enlighted (6250)

ARTRAG's picture

28-04-2019, 10:34

Reading back my text I have found a typo here 'ISR handler at 030h': the ISR starts at 38h not at 30h

By shram86

Expert (88)

shram86's picture

28-04-2019, 22:54

Thanks for the explanation.

I think I almost have it Smile
The init space definition is actually what sparks the interslot call - and this is specific to cartridge boot, and only swaps the page that the init is directed to (not the location of the header), and only that one page.
For a complicated example, if you have a cart in slot 2 (and slot 1 is empty), and the first byte in the cart @ $8000 (but not 4000) is $AB, even if the init location is set to $4000 it will only swap active memory page 1 (40xx-7fxx) to cartridge slot 2 - leaving the page with the cartridge header itself not swapped in, which you have to do manually.

Realistically this means 32kb of active swappable code (4000-bfff while still preserving bios/sys) with an additional theoretical 96kb of storage in the VDP for GRAPHIC3 mode, depending on how you want to use it. Locations $c000 to approx $de3f (7.5kb) is still empty and usable with disk rom still loaded but should probably be used in a particular way, like space for loading in system and commonly used routines.

I think part of my confusion came from the fact that some systems depends on the user to send code to the cartridge itself to configure which memory pages are visible, while the msx2 uses a system variable to set which pages the processor sees.

By NYYRIKKI

Enlighted (5391)

NYYRIKKI's picture

28-04-2019, 23:27

Yes, you got it right.

shram86 wrote:

I think part of my confusion came from the fact that some systems depends on the user to send code to the cartridge itself to configure which memory pages are visible, while the msx2 uses a system variable to set which pages the processor sees.

This method is also sometimes used and we call them MegaROM mappers, but that is another switching mechanism on top of the standard one.

By shram86

Expert (88)

shram86's picture

29-04-2019, 02:32

Now for whatever reason the bin/dsk version of my program has stopped working. I was doing data copy to the top of the program space, which is usually where I keep my work variables, but this is not possible for ROMs, so I was experimenting back and forth.

I was loading the program at $8020 after using an autoexec.bas with only one line,
1bload"test.bin",r
This worked fine until I added a bit more code, I did some searching and it seems reconfiguration of BASIC memory is necessary. Now, however, nothing I do can seem to get the file to boot from disk (the ROM image works perfectly fine). The system seems to run the init code and then resets itself.
My new autoexec:

1clear &HC000
2bload"test.bin",r

My new .bin header:

 org $c000
binheader:
 byte $fe       ; .bin identifier
 word init     ; start-addr
 word EOF 
 word init      ; execute-addr

init: 
(my code, identical to .rom version)
EOF:

Two questions:
1. Why would the autoexec work fine before but not now?
and
2. Where and how does one define work RAM with cartridges? I found this in the technical doc:

Quote:

3) When more than three bytes are needed for the work area, allocates it
from RAM used by BASIC. To do this, put the contents of BOTTOM (FC48H)
to the area corresponding to SLTWRK (FD09H to ...), and increase the
value of BOTTOM by the needed work area, then allocate it for the
work area

but it makes no sense to me. Obviously more than 3 bytes are going to be needed for any program. Maybe this is a bad translation but the entire listing of 5.13 is too complicated for my needs. I THINK what it is trying to say is set $fc48 and $fc49 (BOTTOM) to, for example $00/$81 to point to $8100, moving it up 256 bytes. I assume slot 1 is always cartridge 1, so if your cart loads into $8000, the work RAM location would be SLTWRK+(8*4)+1 and +2 (slot 1 page 1), which you then set to $00/$80.
Of course, this again makes little sense - if you load your cart into $4000, wouldn't you have to then set BOTTOM to $4100? Is that even possible?

This is all so confusing Wink

Edit: It's not the autoexec because just inserting the disc and running bload causes the same odd resetting behavior.

By NYYRIKKI

Enlighted (5391)

NYYRIKKI's picture

29-04-2019, 08:54

You have moved your ORG-statement to wrong side of header... In BIN-file it should be after the header and on ROM-file before the header.

What comes to reserving memory I just suggest that at this point you don't... If you don't do anything the BASIC-program is in beginning of memory and variables at end... Your program fits neatly in between. CLEAR-command usually makes the situation just more unclear and in case your program does not exit that memory reservation is even more useless.

By ARTRAG

Enlighted (6250)

ARTRAG's picture

29-04-2019, 09:48

If you put your ROM at 4000h-7FFFh, just assume ram in 8000h-FFFFh. You can use it all taking care to not overwrite in the FDXXh area useful hooks from the ISR in the BIOS a a few values about system status you could need later (e.g. image of VDP registers and slot configurations).
If you put your ROM at 4000h-BFFFh, just assume ram in C000h-FFFFh. The advice to not abuse too much of the system areas you could need later is the same.

By shram86

Expert (88)

shram86's picture

29-04-2019, 23:42

So this is interesting-

The system was resetting on the .bin version because of a bit of test code that used an ldir loop to copy my initial attribute table into the space I was using as my sprite work RAM. LDIR is clearly an acceptable opcode for MSX2 (I've seen examples that use it) and as far as I can tell I'm using it correctly so I don't know why it would cause the system to reset.

ld hl, testSpriteAttributes
ld de, SPRITE_OAM
ld bc, 16       ; 16 bytes to copy
ldir 

This was done before setting graphics mode. The sprite work ram (SPRITE_OAM) is stored atm close to the top of program memory (approx $800A+). I assume it wasn't resetting the ROM version because the code was simply failing to write (as to be expected if its a ROM).
I know the data can be changed, though, because my movement code atm manipulates those variables in their current locations and that works fine:

ld a, [SPRITE_OAM]
inc a 
ld [SPRITE_OAM], a

Thanks for the info on the RAM and header info, even though that wasn't the exact problem with my BIN it helped me figure it out.

By shram86

Expert (88)

shram86's picture

30-04-2019, 01:50

Definitely something weird going on with RAM.

Without any additional setup or changing anything, I am starting the ROM at $4000, and telling openMSX its a 16kb cart.
According to what you say, about $8000-$ddff should be fair game as RAM. Unfortunately, when I set my RAM base at $c000, it just doesn't work. No sprites are displayed.

When I set it to $8000, only one of four sprites will load, and only at the correct Y position, not X. This tells me that probably only one byte (the one at 8000?) is getting copied in correctly. The rest appear to not want to load into ram. I am not using the ldir code above, but tried a manual loop:

Edit: That loop code is definitely broken somehow. I unrolled it and it loads the rest of the data. I must be missing something somewhere.

Edit 2:
Must be tired. Removed the offensive code Wink

Edit 3:
This time it was a bizarre bug with sjasm. The code "?" variable doesn't work as intended. I think it was assembling the code with incorrect addresses, causing the glitches I was seeing on different versions of the compiled app. I think for now I've figured out most of my issues Smile

By shram86

Expert (88)

shram86's picture

30-04-2019, 18:13

I bet everyone is getting tired of seeing me ask stupid questions, but here's one more rational one.

I understand the impracticality of attempting to develop both a disk and cartridge version of an app in tandem, but here's where I stand:

Disk version:
- Loads into $8000 fine, cannot load into $4000 due to BASIC
- Limited to one 16kb of space for initial bload command
- Can't overwrite page 1 while using disk basic

Cart version:
- Forced contiguous memory due to cartridge mapper config, e.g. if loading into $4000, basic 32kb pg1/2 cart now resides at $4000-$bfff
- Doesn't require page 1 of system ROM due to being a cartridge and not disk reliant

So, let's say I am stubborn and want to use 32kb with a disk based game, and since I don't have MSX-DOS handy and I like doing things the hard way, I want to try this:

1. Boot using autoexec.bas and load file "A" into page 2 ($8000) and memory swap routine into page 3 ($c000)
Mem config at this point: 0/1: system ROM, 2/3: page 2/3 of RAM
2. Execute memory swap to point page 2 to page 1 of RAM
Memory = 0/1: system ROM, 2/3: page 1/3 of RAM
3. Use tokenized BLOAD call to load file "B" into page 2 (still at $8000)
4. Execute memory swap to point page 1 and 2 back to page 1 and 2 of RAM
Memory = 0: system ROM, 1/2/3: pages 1/2/3 of RAM (with both files "A" and "B" loaded)

Does this sound right? This way you would have the same 32kb game in memory, presuming all the orgs were done properly.

Edit: Couple close calls and a lot of self-deprication later I think I got it. If someone else can try this example code and let me know if I got it right I'd appreciate it.
File A:

output A.bin
 byte $fe
 word init 
 word EOF
 word init

 org $8000
init:
 call RAMCopyAndSetup
 call $c100
(rest of code, snip)
RAMCopyAndSetup:
    ld hl, code_to_copy
    ld de, $c100
    ld b, end_copy-code_to_copy
1
    ld a, [hl++]
    ld [de++], a
    dec b 
    jr nz, 1b 
    ret

code_to_copy:    
    di
    ToggleRAMPage 1, $8000
EXEBAS equ $4646
    ld hl,blcommand 
    ld a,[hl]
    call EXEBAS
    ToggleRAMPage 1, $4000
    ToggleRAMPage 2, $8000
    ei
    ret
blcommand:
    defb $cf,$22,"B.bin",$22
    defb 0
end_copy:
MACRO ToggleRAMPage page, address16
    ld a, ($F341+page)
    ld hl, address16 
    call ENASLT    ; $24 
ENDMACRO
EOF:

and file B:

 output B.bin
 byte $fe
 word init 
 word EOF
 word init  
init:             ; I omitted org statement 
 ret              ; to return to $c1xx routine
(data or code to include... snip)
EOF:

And this seems to work, but my brain is mush Wink Any one can confirm?
definitely doesn't but can't seem to figure out why. Doesn't crash, but the values in $40xx are all 255 for some reason.

By Manuel

Ascended (15762)

Manuel's picture

30-04-2019, 19:50

If you want .to load a piece of code in a place that normally isn't accessible in basic, like page 1, you could create a 16kB or whatever fits block which loads in page 2 and 3 with normal bload,r and at run time copies itself to the right place in ram. Then returns. You can repeat this for next blocks, if necessary. The last block starts the actual program in ram.

Page 5/7
1 | 2 | 3 | 4 | | 6 | 7