In this post I will describe how to display an image from tiles on the Sega Genesis emulator using assembler.
The splash picture of Demens Deum in Exodus emulator will look like this:
The process of outputting a PNG image using tiles is done in steps:
- Reducing the image to fit the Sega screen
- Convert PNG to assembler data-code, with division into colors and tiles
- Loading the color picker into CRAM
- Loading tiles / patterns into VRAM
- Loading tile indices at Plane A / B addresses in VRAM
You can reduce the image to fit Sega’s screen using your favorite graphics editor, for example Blender.
To convert images, you can use the ImaGenesis tool, to work under wine you need Visual Basic 6 libraries, they can be installed using winetricks (winetricks vb6run), or RICHTX32.OCX can be downloaded from the Internet and put into the application folder for correct operation. < / p>
In ImaGenesis, you need to select a 4-bit chroma, export colors and tiles in two assembly files. Next, in the file with colors, you need to put each color in a word (2 bytes), for this you use the dc.w opcode.
For example CRAM splash screen:
Leave the tile file as it is, it already contains the correct format for loading. An example of a part of a tile file:
dc.l $11111111 ; Tile #0
dc.l $11111111 ; Tile #1
As you can see from the example above, the tiles are an 8×8 grid of CRAM color palette indices.
Colors in CRAM
Loading into CRAM is performed by setting the color load command at a specific CRAM address to the vdp control port. The command format is described in the Sega Genesis Software Manual (1989), I just add that it is enough to add to the address 0x20000 to go to the next color.
Next, you need to load the color into the data port (vdp data); The easiest way to understand loading is with the example below:
lea Colors,a0 ; pointer to Colors label
move.l #15,d7; colors counter
move.l d0,vdp_control_port ;
add.l #$20000,d0 ; increment CRAM address
Tiles in VRAM
Next comes the loading of tiles / patterns into VRAM. To do this, select an address in VRAM, for example 0x00000000. By analogy with CRAM, we address the VDP control port with a command to write to VRAM and a starting address.
After that, you can upload longwords to VRAM, compared to CRAM, you do not need to specify an address for each longword, since there is a VRAM auto-increment mode. You can enable it using the register flag VDP 0x0F (dc.b $ 02)
move.l #$40200000,vdp_control_port; write to VRAM command
move.w #6136,d0 ; (767 tiles * 8 rows) counter
Tile indices in Plane A / B
Now we have to fill the screen with tiles by their index. For this, VRAM is filled at the Plane A / B address, which is put in the VDP registers (0x02, 0x04). For more information about tricky addressing, see Sega’s manual, in my example the VRAM address is 0xC000, let’s unload the indexes there.
Your picture will fill the VRAM off-screen space anyway, so after rendering the screen space, your render should stop rendering and resume when the cursor moves to a new line. There are many ways to implement this set, I used the simplest version of counting on two registers of the image width counter, the cursor position counter.
move.w #0,d0 ; column index
move.w #1,d1 ; tile index
move.l #$40000003,(vdp_control_port) ; initial drawing location
move.l #2500,d7 ; how many tiles to draw (entire screen ~2500)
imageWidth = 31
screenWidth = 64
dbra d7,FillBackgroundStep ; loop to next tile
move.w d1,(vdp_data_port) ; copy the pattern to VPD
move.w #0,(vdp_data_port) ; copy the pattern to VPD
After that, it remains only to collect rum using vasm, launching the simulator, and see the picture.
Not everything will work out right away, so I would like to recommend the following Exodus emulator tools:
- m68k processor debugger
- Changing the number of cycles of the m68k processor (for slow-mo mode in debugger)
- Viewers CRAM, VRAM, Plane A / B
- Carefully read the documentation for m68k, used opcodes (not everything is as obvious as it seems at first glance)
- See examples of code / game disassembly on github
- Implement processor execution sabrutines, process them
Pointers to processor execution sabrutines are put in the title of the rum, there is also a project on GitHub with an interactive runtime debugger for Sega, called genesis-debugger.
Use all available tools, nice old school coding and may Blast Processing come with you!
https://www.chibiakumas.com/68000/helloworld .php # LessonH5