PC-6002: The Pixels - Part 1
Toolbox
The most important tool you need is a good emulator! Here are two excellent emulators with all necessary settings and files as well as a collection of PC-6001 games and demos for testing here:
- PC6001VW3: Full featured accurate emulator with a built-in debugger and many useful tools.
- iP6+: Light-weight emulator, great for quick testing.
Of course both emulators use Japanese ROMs, maybe in the future if I had access to a Warka ROM chip I could dump it and use that instead. The main difference is language, the Warka had an Arabic font built-in while the PC-6001 had Japanese fonts.
Assembly programming
All PC-60 models use a Z80 processor. I found a nice tutorial online that goes through setting up and using ZASM (z80 assembler) to compile PC-6001 programs then injecting them into PC-6001 at runtime using the PC6001VW3’s debugger: http://www.geocities.jp/tiny_yarou/asmdev/asmdev.html (japanese)
This is the easiest development path for deployment, it also produces the fastest & smallest code. For actual programming though, assembly may not be for everyone.
I will cover development using z80 and ZASM in a future post.
C programming
For the next level we will introduce a C compiler that supports Z80 and integrate it into the pipeline. I am still working on the deployment pipeline but it’s already working as I managed to deploy correct PC-6001 code.
I am using SDCC with a combination of tools and scripts to compile output.
I will cover the C programming pipeline for PC-6001 in a future post.
Mode 5: The Pixels
For this trip through Pixel lane, we’ll use MODE 5 with 4 PAGES.
The main sample program this exploration is based on is written by Tiny Yarou who seems to be the most active PC-60 developer on the internet. Here’s the sample program: http://www.tiny-yarou.com/p6sample.html
The information are in Japanese of course but the BASIC code and hex code tell us everything we need.
What the sample does is use SCREEN mode 3 in PAGE 2 and 3 as a front-buffer and a sprite-buffer.
It first draws a simple sprite sheet to PAGE 3. Then switches to PAGE 2 and uses a z80 program and parameters set via BASIC POKE instructions to blit the sprites to custom X and Y coordinates.
The coordinates and size of sprites are limited by a single rule: all X values must be multiples of 8. SCREEN mode 3 is 320 pixels wide so X range must be 0 to 40.
Reverse Engineering
The BASIC code in the sample is self-explaintory, it sets up addresses, writes the z80 procedure to RAM using POKE, draws the sprite sheet, and then execute the procedure continuously.
Disassembling (and reverse engineering) the z80 procedure, I was able to learn a lot:
Here are some observations:
- Procedure program address is at 0xd000 (notice that 300 bytes are cleared in BASIC starting at that address)
- PAGE 2 and PAGE 3 memory addresses are set (SCRBUF and SPRBUF), these are effectively the pointers to the first pixel in each. When number of pages is set to 3 instead of 4, the memory map is different and PAGE 2(SCRBUF) and PAGE 3 (SPRBUF) start at 0x4000 and 0x0000 respectively.
- Notice DI and EI in the beginning and end effectively disabling hardware interrupts. Otherwise if an interrupt happens while the procedure is running, registers will get messed up. When I tried removing those I either got random looking noise and glitching or a crash then restart of the PC.
- The last label ‘MOVETOY’ simply multiplies HL by 40 (which is 320 pixels divided by 8) and that’s how many bytes in memory represent a single horizontal line in mode 320x200.
The rest is pretty straight forward assembly. What the procedure is doing on a high level is this:
- Figure out the pointer to the first pixel block in spritebuffer for the sprite and first pixel in frontbuffer to draw the sprite to.
- Loop while copying bytes from spritebuffer to frontbuffer one horizontal line at a time.
Every block of 8 pixels are represented by 2 bytes. The first is in the specified PAGE address and the second is offset by +0x2000 in memory (that’s what SET 5, H and D effectively do). The combination of the first and second bytes produces the pattern and colors of that particular 8 pixels block.
So the reason why X is limited to multiples of 8 is simply because thats how pixels are layed out in memory, if you want to change a single pixel/color from assembly you’d have to do some bit wrangling.
The way they managed to encode 8 pixels (16 color each) in 2 bytes is by cheating! Mode 3 is actually 160x200 where every pixel is doubled horizontally. As a result this is how text looks like in mode 3:
Sprite Movement
PC-6001 doesn’t support hardware sprites (as far as I know), so moving sprites around requires some trickery.
In general, there are 2 methods to do this based on what I currently know:
- Backpage/frontpage switching: this will work only in Mode 5 a(Mode 6 has single graphics PAGE). Simply clear and move sprites in the backpage then switch pages and repeat.
- frontbuffer movement: this will not look nice, but essentially clear sprite then draw it in new position. it won’t look nice because you will see the clearing and drawing.
For both methods we need a clear procedure. So I modified the sample program to do just that:
I created a minimal test for the two procedures:
For the next part, I’m going to write a tool to help import PNGs into N66 BASIC then code a movement function that does the blitting and clearing automatically.
blog comments powered by Disqus