So boy, much virtual

So boy, much virtual

by ferris

This week I mainly continued work on my little Virtual Boy emulator! Still lots to do, but I made good progress.

Particularly, I was able to finish most of the opcodes in the CPU (minus floating point/bit string things and some more obscure op's), as well as a bunch of mem mapping, some dummy reg impl's for stuff like the sound unit/timer, and made some progress with implementing the video hardware (and some basic interrupts). So far I've only got some games showing some warning messages, but hey, it's actual, coherent pixels :)

The basic debugger I started with last week really shined here, as I was able to disassemble a lot of game code to see what was happening at different times. I also did a lot of debug printing when unimplemented reg's were hit etc, so I got a huge amount of data when executing anything. Here's a small snippet of what that looked like earlier on:

VSU write word not yet implemented (addr: 0x010001fc, value: 0x01070b0f)
VSU write word not yet implemented (addr: 0x0100027c, value: 0x0f1f2f3f)
VSU write word not yet implemented (addr: 0x010002fc, value: 0xfffef7ef)
VSU write byte not yet implemented (addr: 0x01000600, value: 0x00)
WARNING: Read halfword from Drawing Control Read Reg not yet implemented
WARNING: Write halfword to Drawing Control Write Reg not yet implemented (value: 0x0002)
WARNING: Read halfword from Interrupt Pending Reg not yet implemented
WARNING: Write halfword to Interrupt Clear Reg not yet implemented (value: 0x0000)
WARNING: Write halfword to Interrupt Enable Reg not yet implemented (value: 0x4008)
WARNING: ldsr chcw not yet implemented (value: 0x00000002)
WARNING: Write halfword to Interrupt Enable Reg not yet implemented (value: 0x0000)
WARNING: Attempted read halfword from Drawing Control Write Reg
WARNING: Write halfword to Drawing Control Write Reg not yet implemented (value: 0x0000)
WARNING: Read halfword from Drawing Control Read Reg not yet implemented
WARNING: Read halfword from Drawing Control Read Reg not yet implemented
WARNING: Attempted read halfword from Drawing Control Write Reg
WARNING: Write halfword to Drawing Control Write Reg not yet implemented (value: 0x0002)
WARNING: Write halfword to Interrupt Enable Reg not yet implemented (value: 0x4018)
Frame clock rising edge
Game clock rising edge
Frame clock rising edge
Game clock rising edge
Frame clock rising edge
Game clock rising edge
Frame clock rising edge
Game clock rising edge

Actually getting pixels out of the thing took some work to understand the hw. The display hw consists of two main units; one that's concerned with streaming the contents of VRAM to the LED displays, and the other that's concerned with drawing a bunch of "worlds" or "windows" (I've seen both terms used; they're interchangeable) to the framebuffers. Since there are a lot of details to take in with how these units work/interact, I let myself cheat a bit for starters and just drew stuff into my window's framebuffer rather than the emulated one. This still meant simulating some of the timing of the drawing hw and parsing the various graphics tables to find out what to draw, but with some more poking around in vram with the debugger and good ol' printf, the details eventually became clear.

For some more debug output, here's the drawing routine (before it was actually able to draw anything) printing out the attributes for a couple windows, and then printing char values for the background that should be displayed:

Window 31
 Header: 0xc001
  base: 0x01
  stop: false
  out of bounds: false
  w, h: 0, 0
  mode: 0
  l, r: true, true
 X: 0
 Parallax: 0
 Y: 0
 BG X: 0
 BG Parallax: 0
 BG Y: 0
 Width: 383
 Height: 223
 Param base: 0x0000
 Out of bounds char: 0x0000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000010203040506070806090000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000050a070b0001080c06050d0e060104080007080b00000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000003050a0e070d06010408000f040410110a060c0000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000f0a1204050a0004030a0507060108130000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000151617181709000000000000000000000000000000000000000000000000000000000000
000000000000000000000000140000000014000000000000000000000000000014000000000000000000000000000000
000000000000000000000000191a1b1c1d151e1f20212223161724152500262728000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000014000014001400000000000000000000000000
000000000000000000000000292a2b2c2d242e2c2f2415251c002d303132273334353637240000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

May not look like much, but this was invaluable as a sanity check while figuring out the various data alignments etc for the graphics data in VRAM. Super fun stuff :)

So yeah, that's probably what this next week will be like as well; poking in the debugger, tweaking stuff, etc... Looking forward to it :)

Last Edited on Sun Dec 18 2016 20:33:55 GMT-0500 (EST)


Artie Breakfast commented

heh the sanity check reminds me of the fun I had with the 'integral' and 'the thing that is not an integral' bits in the examples for the lua study: step 1: "Ok what is that supposed to do" step 2: "so did it do it? cuz I can't tell" step 3: "do what now?" step 4: "um I have no idea if what I ... what should the output be?" step 5: "ok if you don't show me what I'm supposed to produce I have no idea how I could possibly do that without a lot of study of whatever that heck you're talking about is. I went to US public schools, 20 or so of them, and I do not have anything beyond algebra for math, so ... those greek symbols... they don't... say anything to me."

Having data to compare is very useful for situations like this where you might be grasping the concept but you aren't sure and need a check.

I basically skipped those exercises after a bit because guessing is not learning.

on Mon Dec 19 2016 17:12:50 GMT-0500 (EST)