Copper horizontal wait problem

Do you live and breathe hexadecimal? Do you like speaking to hardware directly?

Moderator: Programming Moderators

fran_matsusaka
Posts: 2
Joined: Thu Sep 10, 2020 10:23 am

Copper horizontal wait problem

Postby fran_matsusaka » Sun Jan 10, 2021 4:44 pm

I'm trying to change layer priorities in a region in the bottom of the screen using the copper. At the moment I was able to make it work vertically, but I have not found the way to make it wait until the line is in a given position horizontally. I want to swap layer priorities from pixel 64, so I add to the opcode this: (8<<1). But it ignores that and always start from the very beggining of the line.

I don't know if is an emulator problem (I'm using Cpect). I tried in real hardware and the result is event worse, with a game reset. But that seems to be another problem.

Any help would be really apreciated.

Code: Select all

SET_COPPER_STAGE:

	NEXTREG_nn COPPER_CONTROL_HI_BYTE_REGISTER, %00000000		; stop
	NEXTREG_nn COPPER_CONTROL_LO_BYTE_REGISTER, %00000000

	ld	bc, TBBLUE_REGISTER_SELECT:ld a, COPPER_DATA:out (c),a	; select copper data port

	break

	ld	hl, CopperListStage
	ld	bc, CopperListStageEnd - CopperListStage
	call	TransferDMAPort

	NEXTREG_nn COPPER_CONTROL_HI_BYTE_REGISTER, %11000000 		; start
	NEXTREG_nn COPPER_CONTROL_LO_BYTE_REGISTER, %00000000

	ret


;---------------------------
CopperListStage:
	db COPPER_WAIT+(8<<1), 176
	db SPRITE_CONTROL_REGISTER, GRAPHIC_PRIORITIES_ULS + GRAPHIC_SPRITES_VISIBLE
	db COPPER_WAIT+(0<<1), 177
	db SPRITE_CONTROL_REGISTER, GRAPHIC_PRIORITIES_SLU + GRAPHIC_SPRITES_VISIBLE
	db COPPER_WAIT+(8<<1), 178
	db SPRITE_CONTROL_REGISTER, GRAPHIC_PRIORITIES_ULS + GRAPHIC_SPRITES_VISIBLE
	db COPPER_WAIT+(0<<1), 179
	db SPRITE_CONTROL_REGISTER, GRAPHIC_PRIORITIES_SLU + GRAPHIC_SPRITES_VISIBLE
	db COPPER_WAIT+(8<<1), 180

;------------
	dw $ffff
	CopperListStageEnd:

Ped7g
Posts: 256
Joined: Mon Jul 16, 2018 7:11 pm

Re: Copper horizontal wait problem

Postby Ped7g » Sun Jan 10, 2021 7:48 pm

CSpect + ZEsarUX (+ZESERUse fork) run the CPU until the left-edge of pixels is reached, then they draw previous pixel + right border + left border with *current* status of nextregs. So your change from horizontal pixel 64 is retroactively applied since pixel 0.

I'm not aware of any emulator working in more accurate way, my fork ZESERUse has extra compilation flag `-DTBBLUE_DELAYED_COPPER_WAITS` to at least postpone changed done in h-blank to not affect previous line, but that makes them still per-line changes (CSpect and ZEsarUX will affect full previous line even if you do the modification in h-blank ahead of left border of next line).

In your case there's no help, emulators are not at this level of fidelity yet (and I wouldn't hold my breath for some emulator to get there any time soon).

Anyway, it's documented:
https://wiki.specnext.dev/CSpect:known_bugs

fran_matsusaka
Posts: 2
Joined: Thu Sep 10, 2020 10:23 am

Re: Copper horizontal wait problem

Postby fran_matsusaka » Sun Jan 10, 2021 9:24 pm

Ped7g wrote:
Sun Jan 10, 2021 7:48 pm
In your case there's no help, emulators are not at this level of fidelity yet (and I wouldn't hold my breath for some emulator to get there any time soon).
Thank you for the info! I found the problem in the real Next. I was setting copper twice in the same frame. For some reasson thats something that the Next doesn't like, but in the emulator works. Once that was fixed I found that the horizontal wait was working properlly.

Ped7g
Posts: 256
Joined: Mon Jul 16, 2018 7:11 pm

Re: Copper horizontal wait problem

Postby Ped7g » Mon Jan 11, 2021 9:45 am

setting it twice shouldn't pose a big problem even for real Next, depends what exactly you did and how it fizzled. Updating "live" copper code can be somewhat tricky, for example you can overwrite "halt" instruction without having rest of buffer cleared/initialized and if all the waits are already passed at that point the copper will very quickly execute rest of the [uninitialized] copper memory, as you are filling the instructions with new "halt" at much slower pace than what the execution speed of copper is. And if you use nextreg $60 instead of new $63, the partial writes may be visible to copper executing instruction with only one byte overwritten. But if you design for it, the live-updating of copper memory should work, I'm not aware of any extra HW effect (beyond the expected complexity). The code you posted is too incomplete to check all the consequences and missing the info how/when exactly you called it twice, so I didn't even read into it too much. :)

The current public emulators are unlikely to get near "cycle perfect" type of emulation, so one has to understand the limitations and use them as tools helping to develop SW, but not expecting 1:1 fidelity when running the Next SW. (and I can't speak for emulator authors, but from my short effort to fix ZEsarUX emulation of TBBlue as much as possible, I can tell you it's already hitting the limits of the emulator architecture, while it's still missing some accuracy and features, and to push it much further into more accurate emulator - it would IMHO require full rewrite with new architecture specialized for Next emulation ... or CPUs with single-core (and that's quite stagnating feature for last ~decade) performance like x50 to what we have today (I have in new notebook Ryzen 7 4800H which single-core performance is not shabby, but ZESERUse at 28MHz could send it down to knees easily if I use many layers/sprites/copper ... and that's not even accurate emulation, lot of shortcuts/simplifications are currently used, to make the emulator run at least at some acceptable/usable speed).


Who is online

Users browsing this forum: No registered users and 2 guests