Setting up graphics mode 7 and sprites. Also BlueMSX VRAM debugging

Page 1/2
| 2

By Sdw

Resident (50)

Sdw's picture

19-08-2015, 00:48

Hi! I really, really need help after almost tearing out my hair now for hours on end.
I am trying to set up the Graphics7 (SCREEN8) mode (256x192 in 256 colors) and also display sprites.

First of all, while I sometimes copy to disk and test on my NMS8245, most testing is done in BlueMSX 2.8.2, with emulations set to MSX2 and 50Hz (I'm in PAL territory). I tried getting OpenMSX to run, but was unable to get it set up properly so I can testrun my code from a .DSK. Since I am very pressed for time, I thought sticking with BlueMSX would be best.

Major problem number one is that the VRAM debugging (which could be very helpful) seems severly broken in BlueMSX.
In my testprogram I have the following layout of my VRAM

0x200-0x3ff: Sprite colors
0x400-0xXXX: Sprite attribute table
0x1000-0x17ff: Sprite patterns
0x10000-0x1xxxx : 256x192 picture

And I can see with my eyes that the picture is present and working properly, but looking at the VRAM in BlueMSX at address 0x10000 and forwards shows only zeroes.

Also, if I change the order of the codes that set up the sprite data in VRAM to run *after* I've set the video mode, the VRAM debugger shows only garbage there (0x200 and forwards)
If I do the setup first (as you will see in the code) it shows the data OK at 0x200 and forward. Don't know if this is some other problem, or the VRAM debugger just being broken.
As it is, I don't know how much I can trust the debugger at all.

And in an even weirder phenomenon - if I move the GFX_Init code that creates the background picture to the start of the code, that breaks as well, the picture is not generated correctly.
I am at a total loss here, I mean, it should not matter in which order I put stuff in the VRAM and set up VDP registers, right? As it is now, it seems like as soon as I move anything, everything just breaks.

Final (and worst) problem is that my sprite doesn't show up as it should at all. As I've set it up, a diamond-shape, white 16x16 sprite should appear at 128,128.
No such thing happens, instead I get some every-second line garbage graphics that shows up far left, don't know if it is a sprite or not.

What is going wrong? I have set up all the VDP regs according to V9938-Programmers-guide.pdf

Here's the complete program:

PORT_VDP_REG	equ $98	
PORT_VDP_STATE	equ $99

	OUTPUT "output.com"

	ORG 0x100

		jp start

	MACRO SetVDPReg adr,val
		ld		a,val
		out	(PORT_VDP_STATE), a
		nop
		nop
      ld    a, adr | 0x80
		out	(PORT_VDP_STATE), a
		nop
		nop
	ENDM
	
	MACRO SetVRAMAdr high,mid,low
		ld		a,high
		out 	(PORT_VDP_STATE),a
      nop
		nop
      ld    a, 14 | 0x80
		out  (PORT_VDP_STATE), a
		nop
		nop
		ld 	a,low
		out 	(PORT_VDP_STATE),a
      nop
		nop
		ld		a,mid | 0x40		
		out 	(PORT_VDP_STATE),a	
		nop
		nop
	ENDM
	
start:
		di
		
		; VRAM address 0x1000
		SetVRAMAdr 0x00,0x10,0x00
		; Copy sprite pattern data
		ld		bc,8*4
		ld		hl,sprite_pattern
SPR_Init:		
		ld		a,(hl)
		out	(PORT_VDP_REG),a
		inc	hl
		dec	bc
		ld		a,c
		or		c
		jr		nz,SPR_Init

		; VRAM address 0x0400
		SetVRAMAdr 0x00,0x04,0x00
		; Copy sprite attribute data
		ld		bc,5
		ld		hl,sprite_table
SPR_Init2:		
		ld		a,(hl)
		out	(PORT_VDP_REG),a
		inc	hl
		dec	bc
		ld		a,c
		or		c
		jr		nz,SPR_Init2

		; VRAM address 0x0200
		SetVRAMAdr 0x00,0x02,0x00
		; Setup sprite colors
		ld		bc,512
SPR_Init3:		
		ld		a,15
		out	(PORT_VDP_REG),a
		inc	hl
		dec	bc
		ld		a,c
		or		c
		jr		nz,SPR_Init3

		; Set gfx mode G7, 16x16 sprites
		SetVDPReg 0,%00001110
		SetVDPReg 1,%01000010

		; Moving the sprite VRAM init routines here (after gfx init) makes it not work anymore?!?
		; (atleast according to BlueMSX VRAM debugger)
		
		; Pattern layout at 0x10000
		SetVDPReg 2,%00111111

		; Background color
		SetVDPReg 7,0
		
		; VRAM address 0x10000
		SetVRAMAdr 0x04,0x00,0x00		
		; Generate testpicture with all colors
		ld		bc,256*192
GFX_Init:		
      dec 	bc
		ld 	a,c
      out 	(PORT_VDP_REG),a        
      or 	b
      jr 	nz,GFX_Init
      				
		; Sprite attribute table high
		SetVDPReg 11,%00000000

		; Sprite attribute table low (set to 0x0400)
		SetVDPReg 5,%00001111

		; Sprite pattern at 0x1000
		SetVDPReg 6,%00000010				
		      
inf:		
		jp		inf	
		

sprite_pattern:
		db %00000000		
		db %00000001		
		db %00000011						
		db %00000111								
		db %00001111		
		db %00011111		
		db %00111111						
		db %01111111								
		
		db %01111111								
		db %00111111						
		db %00011111		
		db %00001111		
		db %00000111								
		db %00000011						
		db %00000001		
		db %00000000		

		db %10000000								
		db %11000000						
		db %11100000		
		db %11110000		
		db %11111000								
		db %11111100						
		db %11111110		
		db %11111111		

		db %11111111		
		db %11111110		
		db %11111100						
		db %11111000								
		db %11110000		
		db %11100000		
		db %11000000						
		db %10000000
		
sprite_table: ; Y,X,Pattern,Reserved
		db 128,128,0,0
		db 0xd0		

I am trying to finish a small MSX2 demo for a compo this weekend, but unless I get the basic setup out of the way and can start actually coding stuff really, really soon there is no way I will be able to finish in time. Sad
Please help!

Login or register to post comments

By dioniso

Champion (479)

dioniso's picture

19-08-2015, 07:33

Sdw wrote:

sprite_table: ; Y,X,Pattern,Reserved
db 128,128,0,0
db 0xd0

I didn't look at all the code but... did you set the colour of the SPRITE to zero? That should be "transparent". Try white, for instance, $0f.

Edit: I forgot you are talking about SCREEN 8; I never did anything on this SCREEN. Probably I'm wrong.

By Manuel

Ascended (19468)

Manuel's picture

19-08-2015, 08:38

I can help you to set up openMSX... What was the problem exactly?

You probably should check for an interesting ZIP file on http://www.msxarchive.nl/pub/msx/emulator/openMSX and unzip it in your share/systemroms folder as described here: http://openmsx.org/manual/setup.html#romlocation

After this all emulated MSX systems work. Use one with a disk drive, or one without and add a disk drive extension like the Sony HBD-F1.

By Grauw

Ascended (10768)

Grauw's picture

19-08-2015, 09:54

In screen modes 7 and 8, the VRAM layout is different (bytes are interleaved) compared to the other screen modes. So you must set the mode before initialising the data in VRAM.

Also, just a small note to get an urban myth out of the way: your wait nops in SetVDPReg and SetVRAMAdr are unnecessary, VDP register access does not require waits, only VRAM access (port 98H) does.

By Sdw

Resident (50)

Sdw's picture

19-08-2015, 10:41

Grauw: Now that is interesting, that wasn't mentioned at all in the 9938 PDF document! Does this mean that the entire VRAM is in this interleaved mode, what about my sprite tables, should they also be copied *after* I have initialized the video mode than?
I did try this, but still didn't get any visible sprite Sad

Manuel: Thanks, with that ZIP I was able to get OpenMSX running my program! Now I just need to figure out how to get VRAM debugging going! Smile

By Manuel

Ascended (19468)

Manuel's picture

19-08-2015, 10:55

Did you install the openMSX Debugger GUI? It contains several VDP debug things.

By Sdw

Resident (50)

Sdw's picture

19-08-2015, 11:16

Manuel: Ah, thanks, I had missed that the Debugger was a separate download. Got it running now, I think it could be very helpful!

By Sdw

Resident (50)

Sdw's picture

19-08-2015, 13:07

Yes! I am finally making some progress - the OpenMSX visual VDP debugger is a godsend.

By Grauw

Ascended (10768)

Grauw's picture

19-08-2015, 13:19

Sdw wrote:

Does this mean that the entire VRAM is in this interleaved mode, what about my sprite tables, should they also be copied *after* I have initialized the video mode than?

Yes. In screen 7/8 the VDP needs to read data twice as fast, so it interleaves the VRAM to increase the speed.

You can see it, load a picture on page 2 of screen 5, then go to screen 7 and switch to page 1, it will show the picture with a vertical striped pattern (rather than two copies side-by-side, which you would get without interleaving). It also explains why you’re getting different results depending on whether you set the VRAM data before and after the mode switch.

Sdw wrote:

I did try this, but still didn't get any visible sprite Sad

Something else must be wrong... I don’t see it though. Using the debugger is probably the fastest way to find the problem.

By Sdw

Resident (50)

Sdw's picture

19-08-2015, 13:37

Alright, I think I have things sorted out now.

Fixes I needed to do were (in case anyone should run into the same problems):
* Set video mode first, copy data to VRAM later.
* Set up the sprite attribute table pointers correctly, the whole 0x200 of colordata sitting before the real attribute data and what you actually should point to wasn't exactly easy!

Again, without the OpenMSX VDP debugger I probably wouldn't have figures this out at all, an excellent tool!

By Manuel

Ascended (19468)

Manuel's picture

19-08-2015, 19:45

Sdw, glad to hear that! I'll pass the message to the developers! Looking forward to your demo entry too!

Page 1/2
| 2