Megarom bank switching affecting RAM?

Página 1/3
| 2 | 3

Por thegeps

Paladin (895)

Imagen del thegeps

11-03-2021, 18:38

Hi all!
trying to free some space in a 16Kb page of my Freedom Fighter megarom (new prologue gfx need room, even if pletter compressed) I tried to move the prologue music (about 2Kbytes) in another page where there is enough room.
My idea was to copy the song data to RAM and let the player read it from RAM instead of ROM.
I did the very first try without moving the song to another page in this way, at the beginning of active page:

	ld	hl,prologue_music
	ld	de,0e880h
	ld	bc,prolmus_end-prologue_music
	ldir

then I've set the source of data with:

	ld	hl,0e880h
	xor	a
	call	PLY_AKG_INIT

and hooked my routine that call arkos player. And all went fine...

so I've moved the song and the code to copy it to from ROM to RAM to another page leaving the player settings and hooking in the active (during prologue sequence) page.
The game freeze at the black screen before the prologue sequence.
If I remove the hook (or the player call inside the hook) the prologue works (without music, of course).
So probably the music data are corrupted (but I have no clue of when, or where, it happens)
Someone has any thought about this strange beaviour?

I tried this only on openMSX (I'll try on real hardware this weekend using my SD mapper).

Login sesión o register para postear comentarios

Por Grauw

Ascended (10174)

Imagen del Grauw

11-03-2021, 18:40

Is there an interrupt handler which switches ROM banks, or makes an assumption about which ROM bank is active?

Por Daemos

Paragon (1955)

Imagen del Daemos

11-03-2021, 19:12

Check if any data is executed as code. As grauw stated most propably a isr is switching to wrong memblock or restores the memblocks in a erroneous matter. Comment out the call to the replayer and leave the rest of the isr intact. If it still crashes you might have a clue there. Does the replayer switch banks or mapper?

Por thegeps

Paladin (895)

Imagen del thegeps

11-03-2021, 19:25

I have a routine hooked in the bios isr with h.timi
It doesn,t swithc banks nor assume about active banks
this is the complete code of hooked routine:

skippable_play:
	push	af
	ld	a,(player_input)
	call	gttrig
	jr	nz,fire_pressed
	ld	a,1
	ld	(release),a
fire_pressed:
	ld	a,(freq)
	or	a
	jp	nz,skip_not_ntsc
	ld	a,(frame_count)
	inc	a
	cp	6
	jp	z,do_not_play
	ld	(frame_count),a
skip_not_ntsc:
	call	PLY_AKG_PLAY		;call music player
	ld	a,(release)
	or	a
	jr	z,do_not_skip
	ld	a,(player_input)
	call	gttrig
	jp	nz,exit
do_not_skip:
	pop	af
	ret
exit:
	xor	a
	ld	(skip_tmp),a
	pop	af
	ret

and this is the full code that run from bank7 (where the prologue is). the remaining room is fillede by gfx data

prologue:


	ld	b,50
	call	wait

;	ld	hl,prologue_music
;	ld	de,0e880h
;	ld	bc,prolmus_end-prologue_music
;	ldir

	ld	hl,prologue_music
;	ld	hl,0e880h
	ld	a,1
	ld	(skip_tmp),a
	ld	(intro_is_active),a
	xor	a
	call	PLY_AKG_INIT	
	ld	hl,skippable_play
	call	hook_routine

write_prologue:
	ld	ix,prologue_data
	ld	iy,to_vram
	ld	hl,timings
	ld	a,6	;number of images to process
pic_countdown:
	ld	b,5
	push	af
	push	hl
unpack_loop:
	push	bc
	push	ix
	push	iy
	ld	l,(ix+0)	;packed file address lowbyte
	ld	h,(ix+1)	;packed file address hibyte
	ld	de,0c000h
	call	unpack		;this calls pletter
	pop	iy
	pop	ix
	ld	hl,0c000h
	ld	e,(iy+0)
	ld	d,(iy+1)
	ld	c,(iy+2)
	ld	b,(iy+3)
	call	ldirvm
	ld	bc,4
	add	iy,bc
	ld	bc,2
	add	ix,bc
	pop	bc
	djnz	unpack_loop
	call	44h
	pop	hl
	ld	d,3
pic_wait:
	ld	a,(hl)
	ld	b,a
	call	wait
	inc	hl
	dec	d
	jp	nz,pic_wait
	call	41h
	pop	af
	dec	a
	jp	nz,pic_countdown



exit_from_prologue:
	ld	a,0c9h			;opcode for RET (remove prev routine from hook)
	ld	(hook),a
	xor	a
	ld	(intro_is_active),a
	call	PLY_AKG_STOP
	ret

Por Daemos

Paragon (1955)

Imagen del Daemos

11-03-2021, 21:15

Do your ints reenable after return? Where does do not play jump to?

Then from int do you switch to the corrects slots/banks before calling your replayer?

Por thegeps

Paladin (895)

Imagen del thegeps

11-03-2021, 21:48

As I said, this routine is hooked in htimi. Interrupts are reenabled by the bios isr. Do not play is a piece of code that is executed in the ingame isr too when the replayer has to be skipped to sync music with pal/ntsc.
The code works fine if the song is in rom or if I copy it to ram from actual bank.
So it works fine as it is written here
And works fine too if you uncomment actual commented lines.
But if I move the song on another bank and copy it to ram from that bank before switch to this and execute same code it doesn't work.
But if doing so I comment in the isr the line that call the replayer

call PLY_AKG_PLAY

All works fine but, obviously, without music

Por santiontanon

Paragon (1526)

Imagen del santiontanon

11-03-2021, 23:58

To me the easiest way would be to set a break point right after the song is copied to RAM, and then set a breakpoint for any write operation to the area of RAM that has the song. That would give you exactly the code that is writing over your song data if that is the problem. You can do this easily from the openMSX console, or via the GUI of the openMSX debugger, no?

Por gdx

Enlighted (4830)

Imagen del gdx

12-03-2021, 00:49

What are the music location and its lenght? If it is too long some system variables can be overwritten.

Por thegeps

Paladin (895)

Imagen del thegeps

12-03-2021, 01:17

But why it happens only if I do copy song from another bank?

Usually I have the code I posted, followed by a series of "incbin" (gfx data), then the tables "prologue_data" "to_vram" and "timings" and last an "include" song. All in segment 7

If I do copy the song to RAM from these conditions all works fine.

If I move the include song to segment 6 and the code to copy it to RAM im segment 6 (wich is active during boot intro and title screen) and execute it after showing title screen it doesn't work.
So I thought that something overwrite it and I moved the code to copy song in RAM just before the call for prologue, in segment 0 to be sure the code were in a segment active for sure. And to be evwn more sure I did this:

        ld a,6
        ld (bank2),a  ;bank2 is the ASCII16 bank selector
	ld	hl,prologue_music
	ld	de,0e880h
	ld	bc,prolmus_end-prologue_music
	ldir
        ld a,7
        ld (bank2),a
        call prologue

But the result was always the same. It works only if done from segment7...

Por thegeps

Paladin (895)

Imagen del thegeps

12-03-2021, 01:20

引用:

What are the music location and its lenght? If it is too long some system variables can be overwritten.

Music location is 0e880h ant song is less than 2K. And it works if done from segment7

Por sdsnatcher73

Prophet (2353)

Imagen del sdsnatcher73

12-03-2021, 05:47

So to be clear, I cannot read assembly code, just English Wink

You are saying:

1. Intro code in bank 6 executes the copy to RAM.
2. Prologue code in bank 7 starts.
3. Song does not play.

But if

1. Prologue code in bank 7 executes the copy to RAM.
2. Song does play.

Could there be an issue in how the location of the code of the replayer is handed over between the bank 6 and bank 7 ROM code? Possibly some registers or variables are overwritten?

Página 1/3
| 2 | 3