Sprite color table SCREEN5

Pagina 1/2
| 2

Door Metalion

Paragon (1250)

afbeelding van Metalion

12-12-2018, 21:27


I have loaded in VRAM the attribute table and the color table for a given spriteset in SCREEN5. I know the SPAT is correctly positioned because when I change the X,Y value directly in the VRAM (BlueMSX debugger), the sprite moves.

The color table is 512 bytes before the SPAT, and therefore I have loaded my color values there. But ... nothing happens. All I get is the shape of the sprite, but with even lines white and odd lines blank. Even if I change the values directly in the VRAM, nothing happens ...

What am I missing here ?????

R#0 : xxxx100x
R#1 : xxx001xx
R#2 : 00011111

R#6 : $30 => patterns at $18000

R#5 : $C0
R#11 : $03 => attributes at $1E000 and therefore colors at $1DE00

Aangemeld of registreer om reacties te plaatsen

Van Grauw

Ascended (9486)

afbeelding van Grauw

12-12-2018, 22:43

Your problem is that you don’t set bits to 1 which must be:

Bits 0-2 of R#5 must be 1. See pages 40 and 93 of the V9938 application manual.

Bit 2 specifies A9 and must be 1, this means the attribute table must be at 1E200H and the colour table at 1E000H. Only steps of 400H are possible, and you can’t have them at the addresses you specified.

Bits 0-1 must also be 1.

(This is how the application manual describes it; another way of looking at it is that in sprite mode 2 the colour table and SAT are one unit of size 400H, with the SAT occupying the top half. Registers 5/11 specify the base address of this whole unit. As with all base addresses, bits lower than the table size must be set to 1 or it will mirror.)

Van Metalion

Paragon (1250)

afbeelding van Metalion

13-12-2018, 16:15

Thanks for pointing me to the problem ... I did not know the first 3 bits of R#5 were always set at 1.
However,$1E000 is a perfectly valid address for the sprite attribute table.

SPAT address = R#11 x 1024 + R#5 >>3 x 1024

Therefore, $1E000 can be obtained by R#11 = 3 and R#5 = 24 << 3 OR 111b = 192 OR 111b = 199

So my calculation were correct except for the fact that the first three bit were to be set at 1. Having the first three bits at zero must have put the VDP in a defective mode, and that would explain why the SCOL table was not working while the SPAT was effective (X,Y position and patterns were working).

Van Grauw

Ascended (9486)

afbeelding van Grauw

13-12-2018, 18:40

Since A9 must be 1, 1E000H is not a valid address. You will have some kind of mirroring I think, likely the SAT overlapping with the first 80H bytes of the SCT so the colours need to be specified at 1E000H as well. Pretty sure it was like this...

If you're not testing on a real MSX, make sure to at least test in openMSX as well...

Van Metalion

Paragon (1250)

afbeelding van Metalion

13-12-2018, 19:17

I understand what you're saying, but it's not that clear in the manuals whether the A9 bit is significant in the address calculation or if it is set at 1 but masked. I just tried with R#11 = 199 and it's still not working ... No sprite at all, now.

If A9 is significant, then R#11 = 199 would put the SAT at $1E200 and the SCT at $1E000.
I'll try to do something there.

EDIT : it works ! ... So it means that A9 bit must be set at 1 but is indeed significant for the SAT address.

Van wouter_

Champion (442)

afbeelding van wouter_

13-12-2018, 20:20

This (internal) document in the openMSX source tree describes what happens when bits that should be '1' according to the V9938 application manual are nevertheless set to '0'. Like Grauw already said, there is indeed some kind of mirroring.

Van Metalion

Paragon (1250)

afbeelding van Metalion

10-06-2020, 20:48

Sorry, but 2 years later, I'm still confused ...

OK, the sprite attribute and color table address should be considered as a 1024 byte block, with attributes occupying the upper 512 bytes. With that in mind, 6C00h for colors and 6E00h for attributes should be correct addresses, right ?

Well, it does not work.
Garbage on screen.

(*)  R#5     | A14| A13| A12| A11| A10| 1  | 1	| 1  |
     R#11    | 0  | 0  | 0  | 0  | 0  | 0  | A16| A15|

We know that A9 is significant and used in the calculation of the address, but not A8 or A7, even if they're set to 1. Therefore, the formula to calculate valid addresses are :

SPAT = number x 1024 + 512
SCOL = SPAT - 512

And after that, I calculate the register values :

byte	low (SPAT/128) or 111b	; R#05 | sprite attribute table (low)
byte	high (SPAT/128)		; R#11 | sprite attribute table (high)	

SPAT @ 6E00h gives $DF for R#5.
Correct ?

Can someone help me to get it to work ??

Van MsxKun

Paladin (954)

afbeelding van MsxKun

10-06-2020, 21:15


I don't have adresses and registers on my memory now. And my mind is a bit blurry now...
But, if you use OpenMSX, there's the VDP registers debugger tool, where you can change those registers and see what adress you get. I did that not long ago cause i had some kind of similar problem with some addreses and it was easier to change values until I got the right address I wanted, than make any calculations. Lazy me Tongue

Van Dolphin101546015

Champion (295)

afbeelding van Dolphin101546015

10-06-2020, 21:41

Metalion wrote:

Can someone help me to get it to work ??

void	Set_SAT(uint8 SAT_Page) 	__z88dk_fastcall __naked
	ld	a,	l
	rlc	a
	rl	h
	rlc	a
	rl	h
	rlc	a
	rl	h
	or	#7
	ld	l,	a
	in	a,	(VDP)
	and	VDP_CE
	jr	NZ,	GetSATReady            

	ld	a,	l
	out	(VDP),	a
	ld	a,	#0x80+5
	out	(VDP),	a

	ld	a,	h
	out	(VDP),	a
	ld	a,	#0x80+11
	out	(VDP),	a

BTW: 3 LSB is significant too on MSX2. For example you able masking sprite colors by groups 8, 16, 32 different color masks

Van norakomi

Paragon (1084)

afbeelding van norakomi

11-06-2020, 12:14

It's documented in the vdp manual, but I agree with you, it's very confusing.

Maybe some code I use helps you see and understand a little bit more:

  ld    a,(vdp_0+6)     ;check current sprite character table
  cp    %0010 1111      ;spr chr table at $17800 now ?
  ld    hl,$6c00        ;spr color table $16c00
  ld    de,$7400        ;spr color table buffer $17400
  ld    a,%1101 1111    ;spr att table to $16e00    
  ld    b,%0010 1110    ;spr chr table to $17000
  jp    z,.setspritetables
  ld    hl,$7400        ;spr color table $17400
  ld    de,$6c00        ;spr color table buffer $16c00
  ld    a,%1110 1111    ;spr att table to $17600
  ld    b,%0010 1111    ;spr chr table to $17800

  ld    (vdp_0+5),a
  out   ($99),a		;spr att table to $16e00 / $17600
  ld    a,5+128
  out   ($99),a
  ld    a,$02     ;%0000 0010
  ld    (vdp_8+3),a
  out   ($99),a
  ld    a,11+128
  out   ($99),a

  ld    a,b
  ld    (vdp_0+6),a
  out   ($99),a		;spr chr table to $17000 / $17800
  ld    a,6+128
  out   ($99),a

  ld    bc,$200
  ld    (sprcoltableaddress),hl
  add   hl,bc
  ld    (spratttableaddress),hl
  add   hl,bc
  ld    (sprchatableaddress),hl
  ex    de,hl
  ld    (invissprcoltableaddress),hl
  add   hl,bc
  ld    (invisspratttableaddress),hl
  add   hl,bc
  ld    (invissprchatableaddress),hl

In this code you see I swap between 2 spritetables.
1 table sets color, attribute and character tables at addresses: $16c00, $16e00 + $17000
the other sets color, attribute and character tables at addresses: $17400, $17600 + $17800

I hope this helps

Van Metalion

Paragon (1250)

afbeelding van Metalion

11-06-2020, 17:01

I don't know what I'm doing wrong ... I can set up a sprite table anywhere above 10000h, and have things working, but if it's an adress below that, the VDP puts itself in some fucked up mode that shows only garbage. I would understand absent sprites, or wrong patterns, but here, the whole screen is messed up.

Once again, my example is setting

. SPAT at 06C00h (27.1024)
. SCOL at 06E00h (27.1024+512)

This translates for the VDP in those values:

. R#05: DFh / 1101_1111b [per calculation: 6C00h/80h=DCh or 111b = DFh]
. R#11: 00h / 0000_0000b

I can confirm using BlueMSX that it is those values which are loaded in the registers. This is the garbage that I get on screen. Disabling the sprites through the debugger does not change anything. Furthermore, what's strange is that it seems that none of my transfer to VRAM have got through. It's just as if the VDP had "hanged" and freezed. See picture below.

EDIT : I just tested it on OpenMSX and it DOES work! It only shows a problem on the sprite patterns.

Pagina 1/2
| 2