Page 1 of 1

Made Game Boy emulator and working on GB game. Moving on to NES. Is NES harder or something? Why isn't GB more popular?

Posted: Tue Jun 14, 2022 3:32 pm
by devmas
So I wanted to write this post that's a bit aimless, but I hope you'll indulge me for a bit, and sorry in advance... I split it up into sections to hopefully make it easier to read.

Part 1.1: Game Boy emulator

So I made a Game Boy emulator in Java somewhat recently. While it doesn't have sound (I still need to figure out a good way to program sound), it works pretty well, and it can actually run some games better than any other Java Game Boy emulator I've seen on the Internet.

screenshot:
Image

Here's a video, with some lovely (read: bad, lol) music by yours truly: https://www.youtube.com/watch?v=JhX8ImUfUIc

Part 1.2: Making a Game Boy game

Inspired by the Game Boy emulator, I decided to try making a Game Boy game, purely for fun. I decided to port Celeste, the classic PICO-8 game, to it. For reference, here's a video of someone playing the official C# port of it: https://www.youtube.com/watch?v=VR3x5d8xIKk
and here's an image that I got off the Internet:
Image

Graciously, Celeste creators Maddy and Noel released the source of the C# port on GitHub. (Link: https://github.com/NoelFB/Celeste/tree/ ... rce/PICO-8) Therefore, my approach to creating the Game Boy version is simply to look at the code and translate it line-by-line to assembly. Here's what I have so far:

video: https://www.youtube.com/watch?v=Orloiyc6wS4

screenshot of super old version (above video is newer):
Image

Because I'm new to the Game Boy, I decided to fit the entire game within 32 KB, the size of the Game Boy's address space without bank switching.

I ran into the following technical challenges:
  • Compressing each screen's graphics. I came up with an encoding scheme I'm very proud of, that can compress a 20x16 tile screen into ~160 bytes, so about 50% compression. With 32 KB, I can fit more than 3x the rooms featured in the original game (which had 31 rooms).
  • Fixed point number representation. For the main character's X/Y position, I have two bytes - whole and fractional. (I bet that's standard.) For acceleration, however, at one point I had the same 2-byte representation, though with a signed whole component. But at some point I changed the acceleration code to use a 1-byte representation (1 bit sign, 3 bit whole component, and 4 bit fractional component). I semi-regret doing that now, but I feel like I'm currently too deep in to change it all back, lol.
  • An object system. I am still wrestling in my head about whether I should have a bunch of indexed variables (a "structure of arrays") or regular objects (an "array of structures"). I know of the saying, "if it's hard to decide between two things, then most likely it's because they're both good choices", but I'm still afraid I'll make the bad choice. As such, the player character is still my only object right now.

Two other thoughts:
  • The physics in my Game Boy version aren't the same as the original, despite my copying the code line for line... like, at all. To the point where the original game runs at 30 FPS and my Game Boy version runs at 60, and I barely noticed, lol. Darn floating point logic! lol. But I figure I will tweak the numbers later.
  • I've never written anything serious in assembly before, let alone anything for Game Boy. I always worry that my code will be too slow for Game Boy, but am constantly impressed by how seemingly little CPU all the character physics and collision uses.
In the meantime, I'm super happy with what I have so far, though trying to decide on how to implement the object system has been blocking me for months now.

-----

Part 2: Moving on to the NES

Because I wanted the same knowledge about the NES that I do of the Game Boy, I decided to try to write an NES emulator. But upon researching it, it seems like a far more complex system than the Game Boy, and that's not even including the mappers. With two different buses and some odd PPU quirks, it just didn't seem like as fun of a project. I still may do it in the future, but I can't say my research left me feeling excited and jazzed to do it.

Then, a couple days ago I decided to play with the "complete disassembly of Super Mario Bros." and made some small changes. in particular, I made it so when Mario gets hit with a Fire Flower, he goes back to Super Mario instead of straight to Small Mario. It was fun, but for some reason, I just got really annoyed with the 6502 assembly. It's nowhere as good as the Game Boy's Z80-like processor, with its many registers and more useful opcodes.

-----

Part 3: The point of this post?

Now I know I'm on NESDev.com, but I was curious about what you thought about Game Boy development vs NES development. Do you think it's easier? Or harder? More or less fun? And why do there seem to be fewer communities centered around GB development? Do you think it would be worth pursuing the NES over the Game Boy?

(In addition, feel free to talk about anything of mine from the post.)


I don't know the purpose of this post, except that I (for some weird reason) visit specifically the General Stuff subforum on NESDev as part of my daily Internet rounds, and I kinda just wanted to talk about the Game Boy, lol. But if you read it all, thanks!

Re: Made Game Boy emulator and working on GB game. Moving on to NES. Is NES harder or something? Why isn't GB more popul

Posted: Tue Jun 14, 2022 4:57 pm
by Dwedit
6502 is very different when you're used to the Z80. Just keep looking at the instruction set a few times. Know what the instructions can do, and what they can't. Just like how Z80 can't do "ld e,(bc)", the 6502 can't do "LDX nnnn,Y" (edit: whoops, that instruction does exist. *stands in the corner*). The zeropage is like a set of 256 more registers on the 6502.
I learned Z80 before learning classic ARM and 6502. (Modern ARM is significantly different from classic ARM)

---

As for level compression, the simplest are RLE-based. You can get a lot out of having "Take a tile from above" as a possible choice to do runs of.
Some other options include predictor-based systems, or the LZ-based systems. Either back-references, or an explicit dictionary. Back references are simple, but restrict random access to your silding window. Explicit dictionary systems are more complicated, but allow random access.

---

As for audio synthesis, first skim Blargg's guide about bandlimited synthesis a few times. In particular, the little part about adding differences. When your square wave synthesizer only has to generate a few points where the wave changes, it becomes much simpler to design.

You don't necessarily need to make an audio synthesizer that's fancy enough to do all those cool ripples around the square waves, even simple linear interpolation can sound pretty good.

You can also use a really cheap and simple DC cancellation/highpass filter when you use a difference based audio system, it just uses subtraction and bit shifting.

Re: Made Game Boy emulator and working on GB game. Moving on to NES. Is NES harder or something? Why isn't GB more popul

Posted: Tue Jun 14, 2022 7:35 pm
by devmas
Thanks very much for the response!

I think, as this kind of programming is my hobby, a lot of this stuff is a bit like a puzzle to me... I like to try to figure it out on my own first. But I've never talked with others about my findings, and I guess in a way I was craving that, lol. So thanks!
Dwedit wrote: Tue Jun 14, 2022 4:57 pm 6502 is very different when you're used to the Z80. Just keep looking at the instruction set a few times. Know what the instructions can do, and what they can't. Just like how Z80 can't do "ld e,(bc)", the 6502 can't do "LDX nnnn,Y". The zeropage is like a set of 256 more registers on the 6502.
I learned Z80 before learning classic ARM and 6502. (Modern ARM is significantly different from classic ARM)
A few things stand out to me...

First, I didn't know there was a distinction between modern and classic ARM. I've read up on the ARM instruction set before, mostly ARM7 and ARM9 because GBA and DS (and it really seems like an amazing and fun instruction set that I want to play with one day), but I didn't know it had significant changes. I suppose the distinction comes from ARM Neon? Or maybe ARMv8 when they went 64 bit?

But yeah, I figured learning 6502 would just be a case of "study the instruction set more". For some reason it just felt more difficult to me, which put me off a little, but I'll persevere. It's really good to know that the zero page is often used as extra registers; I thought it was mostly used to store specific often-used things in fast memory, like the player object, especially as the NES has very little RAM. But it makes sense to use it as registers, too.
Dwedit wrote: Tue Jun 14, 2022 4:57 pmAs for level compression, the simplest are RLE-based. You can get a lot out of having "Take a tile from above" as a possible choice to do runs of.
Some other options include predictor-based systems, or the LZ-based systems. Either back-references, or an explicit dictionary. Back references are simple, but restrict random access to your silding window. Explicit dictionary systems are more complicated, but allow random access.
That's great info! My system is basically RLE with a "copy/take a tile from above" tile. A bit in the level header also determines if the RLE is horizontal or vertical (thus, "copy/take a tile from the left"). However, I packed everything into one byte:

- If the two high bits are 11, then the remaining 6 bits are one of 64 non-RLE tiles.
- Otherwise, the high 3 bits equal the length from 1-6, and the remaining 5 bits are one of 32 RLE tiles, which includes the "copy" tile.

So, a total of 96 tiles are representable. It works out because the game only really uses 66 or so unique tiles.

I figured all that out on my own, but I'll have to look into the other options you presented. In particular, I don't know anything about LZ compression, it would probably be fun to study. Dictionary-based compression has always seemed daunting to me, but I'm sure it would show huge benefits with certain types of levels.
Dwedit wrote: Tue Jun 14, 2022 4:57 pmAs for audio synthesis, first skim Blargg's guide about bandlimited synthesis a few times. In particular, the little part about adding differences. When your square wave synthesizer only has to generate a few points where the wave changes, it becomes much simpler to design.

You don't necessarily need to make an audio synthesizer that's fancy enough to do all those cool ripples around the square waves, even simple linear interpolation can sound pretty good.

You can also use a really cheap and simple DC cancellation/highpass filter when you use a difference based audio system, it just uses subtraction and bit shifting.
Ah, audio... I really need to figure out a good way to handle it in my emulator's code, just in general. I've actually not really built anything meaningful yet.

How I'm trying to implement it is basically to add a getAudioSample() function that can be called to calculate what the audio sample would be at any point, with clock rate precision. That way, it could easily be adapted to a 44,100, 48,000, or whatever sample rate by just calling that function when necessary. Though as someone who's pretty much done zero audio programming ever, getting there is not easy!

Thanks for the resources, I'll be sure to take a look at them! I read the "adding differences" portion, and it really seems like it may be helpful to represent, or at least think of, the audio in that way. I figured I would implement a simple synthesizer, and THEN think about all the fancy audio filtering.

Re: Made Game Boy emulator and working on GB game. Moving on to NES. Is NES harder or something? Why isn't GB more popul

Posted: Wed Jun 15, 2022 12:29 am
by org
To program sound, you have to rearrange your mind a little bit. If emulation of processor and video is discrete and more or less constant in time (1 instruction at a time, 1 dot on the screen), then sound is a time-varying process.
It's kind of like comparing ordinary equations and differential equations.
Going into the "time domain" is not easy for everyone.
Good luck :beer:

Re: Made Game Boy emulator and working on GB game. Moving on to NES. Is NES harder or something? Why isn't GB more popul

Posted: Wed Jun 15, 2022 2:49 am
by calima
Why is NES more popular for homebrew than GB?

Tools: NES has far more tools. This is a positive loop with popularity. One tool in particular is important, a C compiler. NES has had a decent C compiler for years, while the GB side situation has been bad (though seems to be improving recently).

Distribution: If I was to distribute a GB game, I'd be limited to 32kb or poor quality Chinese boards. For NES, every popular mapper is available, in high quality, from multiple vendors.

Capabilities: GB has a small screen, and it's grayscale. Multiplayer is slow, cumbersome and not widely available.

Alternatives: For GB, both GBA and DS are easier to target and far more capable. For NES, this is not so: SNES, N64 and GC have bigger barriers to entry. Wii and WiiU are easier, but they have the barrier of higher expectations. To find an easier and more capable target you'd have to jump manufacturers to Sega Genesis and Dreamcast; and indeed, both are more popular for homebrew than NES.

GBC would have color yes, but all the other points apply to it.

Homebrew in general: for new devs starting now, all the current consoles offer easy to obtain Unity licenses. This diminishes the shine of homebrew for older consoles a bit.

--

As for what you should do, do what you feel like. I don't think there's much point to making a new emulator, other than for your own learning. For games, depends what you're after.

Re: Made Game Boy emulator and working on GB game. Moving on to NES. Is NES harder or something? Why isn't GB more popul

Posted: Thu Jun 16, 2022 8:16 pm
by devmas
org wrote: Wed Jun 15, 2022 12:29 am To program sound, you have to rearrange your mind a little bit. If emulation of processor and video is discrete and more or less constant in time (1 instruction at a time, 1 dot on the screen), then sound is a time-varying process.
It's kind of like comparing ordinary equations and differential equations.
Going into the "time domain" is not easy for everyone.
Good luck :beer:
Thanks very much for the encouragement! Will keep that in mind.
calima wrote: Wed Jun 15, 2022 2:49 am Why is NES more popular for homebrew than GB?

Tools: NES has far more tools. This is a positive loop with popularity. One tool in particular is important, a C compiler. NES has had a decent C compiler for years, while the GB side situation has been bad (though seems to be improving recently).

Distribution: If I was to distribute a GB game, I'd be limited to 32kb or poor quality Chinese boards. For NES, every popular mapper is available, in high quality, from multiple vendors.

Capabilities: GB has a small screen, and it's grayscale. Multiplayer is slow, cumbersome and not widely available.

Alternatives: For GB, both GBA and DS are easier to target and far more capable. For NES, this is not so: SNES, N64 and GC have bigger barriers to entry. Wii and WiiU are easier, but they have the barrier of higher expectations. To find an easier and more capable target you'd have to jump manufacturers to Sega Genesis and Dreamcast; and indeed, both are more popular for homebrew than NES.

GBC would have color yes, but all the other points apply to it.

Homebrew in general: for new devs starting now, all the current consoles offer easy to obtain Unity licenses. This diminishes the shine of homebrew for older consoles a bit.

--

As for what you should do, do what you feel like. I don't think there's much point to making a new emulator, other than for your own learning. For games, depends what you're after.
That's interesting. I didn't realize the SNES was so much more difficult to develop for than the NES. Though I do recognize that the GBA is very easy to develop for... I didn't write it in my post, but I also tested making a GBA Celeste port as well, based on my GB one (same black-and-white graphics, etc.), and it was shockingly easy to make. But it wasn't as fun as making the GB version.

Interesting that there aren't a lot of high quality mapper chips available for Game Boy games, I would've thought a good FPGA-based implementation would've existed, at least. It's not like a mapper needs complex logic that requires a big FPGA chip, or someone particularly skilled at Verilog. (Though I say that as someone with very little FPGA knowledge.)

As for my goals, programming is my hobby, so I'm really just doing all of this to have fun, become comfortable with new tools + a new language, and learn a little something in the process.

Re: Made Game Boy emulator and working on GB game. Moving on to NES. Is NES harder or something? Why isn't GB more popul

Posted: Fri Jun 17, 2022 1:22 pm
by jsburke
devmas wrote: Thu Jun 16, 2022 8:16 pm Interesting that there aren't a lot of high quality mapper chips available for Game Boy games, I would've thought a good FPGA-based implementation would've existed, at least. It's not like a mapper needs complex logic that requires a big FPGA chip, or someone particularly skilled at Verilog. (Though I say that as someone with very little FPGA knowledge.)
FPGAs are something I work with pretty much daily, so maybe I can pitch in here?

I think I'm following this convo correctly, if you're talking about using a tiny FPGA as a mapper where other physical ones are not often available, it should be possible, but would present new challenges. I'm thinking of something like this https://store.tinyfpga.com/products/tinyfpga-a1 with 256 4LUTs it would be able to do some pretty decent work; however everything I say comes with the big caveat of having never used this element myself before, so please keep it in mind.

I only did a quick look around, and I can't find the FPGA separate from the board it's on, so it might be tricky to fit in a cartridge; it would be nice to be able to just have the FPGA to put on a custom PCB. Assuming the sizing issue is met the next concern I'd have would be electrical. I don't know the voltages driven in Game Boy Cartridges, but if it differs a lot from 3.3V you could damage the fpga.

Finally, the boot up of the game would have to include configuring the FPGA itself. You need to store the bitstream for it in something non-volatile, and my go to would be the GB's PRG ROM somewhere. Effectively, the boot section will have to configure the FPGA everytime it powers on and then probably run some test to ensure it was done correctly. I'd avoid storing the bitstream in a dedicated batter backed RAM as well since if the battery goes, so does all the functionality.

Re: Made Game Boy emulator and working on GB game. Moving on to NES. Is NES harder or something? Why isn't GB more popul

Posted: Fri Jun 17, 2022 2:50 pm
by lidnariq
As far as I can tell, the reason we aren't seeing more interesting GB carts is space.

1- NES, SNES, SMS, and SMD games can all be DIP. Even GG carts are large enough. So these all afford convenient end-user-buildable designs.

2- GB is unique in that it's 5V, CMOS thresholds, and the shell is comparatively small, so fitting in 3V memories and programmable logic and active voltage translation is a bit of a challenge.

3- With the exception of the MBC3 RTC interface, the mappers are very simple, to the point of feeling a little awkward using a whole CPLD for it. It's a decoder, a few latches, and some AND gates.

3b- on the other hand, the MBC3 RTC interface is so different from any now-affordable RTC that you basically can't make anything suitable at all without exceeding your cost or power budget


InsideGadgets.com is selling programmable GB carts. Some use GreenPaks.

Re: Made Game Boy emulator and working on GB game. Moving on to NES. Is NES harder or something? Why isn't GB more popul

Posted: Fri Jun 17, 2022 11:26 pm
by calima
lidnariq wrote: Fri Jun 17, 2022 2:50 pm InsideGadgets.com is selling programmable GB carts. Some use GreenPaks.
Oh, a new option *checks*. Their MBC3 carts use donor chips, but others are new. The prices however are nonviable (50$ CIB for a game can't have 30$ go to the board and case; even less so for cart only).

Re: Made Game Boy emulator and working on GB game. Moving on to NES. Is NES harder or something? Why isn't GB more popul

Posted: Tue Sep 06, 2022 6:06 pm
by tepples
As discussed in topic "What instead of indexed addressing modes?" from 2016, the Sharp CPU core in the Game Boy system on chip (believed to be designated SM83) is like the Intel 8080 in that it lacks indexed addressing modes. This makes it harder to come up with efficient code to access properties of an object in a pool unless the access order can be predicted in advance. Contrast with Z80, where offsets from registers IX and IY make array-of-structures convenient, and with 6502, where absolute,X mode makes structure-of-arrays convenient. While the 6502 beats the 8080 and SM83 at random access, the 8080 and SM83 beat the 6502 at sequential access.

The answers I remember getting fall in the following categories:

Be psychic
Use array-of-structures, and predict in what order all enemies' move routines will access the properties of the actor structure so that you can use inc l and ld a, [hl+] to step through them sequentially. You may have to predict this order several months in advance for a game of sufficiently large scope.

Allocate in two dimensions
Treat the 8 KiB work RAM at $C000-$DFFF as an array 256 bytes wide by 32 bytes down. Allocate the actor pool as a rectangle where the Y coordinate or high byte specifies which actor and the X coordinate or low byte specifies which property of the actor. This lets you quickly jump to one property to another:

Code: Select all

ld l, whichProperty
ld a, [hl]
A drawback is that if actors and other rectangular data occupy half of each page of work RAM ($hh00 through $hh7F of each 256-byte page), any bulk data (such as decompressed maps of large scrolling levels) will have to be stored in such a way as to skip over the rectangles. Another is lack of tools to perform this allocation without hardcoding addresses, as packing rectangles into a larger rectangle is NP-hard (though first fit decreasing height is a quite effective approximation).

Copy the struct to HRAM
Before executing each actor's move routine, copy the data in the actor's state struct into available HRAM ($FF80-$FFFE). Then the routine can use the ldh instruction which is analogous to 6502 zero page. Once the move routine is done, copy the state back. Incidentally, a behavior like this is seen in Tetris for NES.

Suck it up
Put the base of the actor struct in BC or DE, and do this for each property access:

Code: Select all

ld hl, whichProperty
add hl, de
ld a, [hl]
This uses 5 bytes and 7 cycles each time, which is more than the 3-4 bytes and 4-5 cycles that comparable 6502 code (lda whichProperty,x) would use. A member of the gbdev server told me that Wisdom Tree games operate this way, possibly using a macro pack for translation of 6502 idioms. Excuses given by "suck it up" proponents include the following:
  • You can optimize later. Getting a game feature-complete before you lose interest in the Game Boy platform is itself an accomplishment.
  • There are probably fewer actors on a 160x144-pixel screen. (This disregards the possibility that there may be the same number of actors, just drawn smaller, as seen in the early titles Super Mario Land and Batman.)
  • It's acceptable to run a Game Boy game at 30 frames per second because the display of a Game Boy (DMG) or Game Boy pocket (MGB) has a slow response time anyway.
  • Other parts of the program are likely more sequential, and the SM83's advantage at sequential processing compared to 6502 are likely to outweigh its disadvantage at random access to properties of members of an actor pool.
Coming from the NES scene to the GB scene, I found some surprising attitudes. I've read one take to the following effect: "Don't worry that carts bigger than 32 KiB are unaffordable. You shouldn't be expecting to make a profit from releasing a Game Boy game physically. Instead, develop your Game Boy game on your own time and your own dime, and expect to distribute it to the public without charge through the Internet. You have effectively forever to finish this project."

Another take: "InsideGadgets' pricing is reasonable. Because of wage increases over time, someone who would have paid 30 USD for a Game Boy game in 1994 is likely to be willing to pay 60 USD nearly three decades later in 2022. Physical copies are collectors' items anyway. Use whatever ROM and SRAM size you need, price the physical copy at 60 USD, and expect to make the bulk of your sales on Itch.io, GOG, or Steam at 10 USD. You can trust honest people to pay you rather than turning to the warez scene."

EDIT (April 2023): typo fix; NP-hard

Re: Made Game Boy emulator and working on GB game. Moving on to NES. Is NES harder or something? Why isn't GB more popul

Posted: Mon Jul 10, 2023 10:21 am
by devmas
Thanks everyone for your replies, they were all very helpful and insightful!

After months and months of agonizing over array of structures versus a structure of arrays, and making zero progress, I decided over the weekend to Just Do Ittm and make something, anything, screw the optimization, lol.



What the game looks like now:

https://www.youtube.com/watch?v=XPiBCQaanRg

Finally, an object system! The game looks a million times better and more lively now, IMO.



Part 1: How I Created the Object System

I just did the "Suck It Up" approach Tepples mentioned in the post above. "Suck it up" also perfectly describes my mood as I wrote it, too, lol. It's simple and straightforward, maybe naive? I don't know how I feel about being compared to Wisdom Tree, haha, but hey, if it works, it works!

Here is an excerpt from the Smoke particle update code that shows how I handle objects:

Code: Select all

UpdateSmoke:
	ld hl, objectSpeedX  ;load objectSpeedX object variable
	add hl, de
	ld a, [hl]
	;the speed is a fixed point number, 3 bits whole, 5 bits fractional.
	
	rlca
	rlca
	rlca ;make the 5 most sig. bits the fractional and 3 least sig. bits the whole component
    
	ld b, a
	and a, %11111000
	ld c, a ;isolate fractional component and store into c
	
	ld a, b
	and a, %00000111
	ld b, a ;isolate whole component and store into b
    
;use the sign to determine if we are gonna add or subtract
	ld hl, objectSpeedXSign  ;load objectSpeedXSign object variable
	add hl, de
	ld a, [hl]
	sub 1 ;use sub because dec doesn't set carry
	jr nc, .subtractValueFromSmokeX

;if we need to add...
.addValueToSmokeX:
	;add fractional part, and keep the carry to use later with adc
	ld hl, objectXFrac  ;load objectXFrac object variable
	add hl, de
	ld a, [hl]
	add a, c
	ld [hl], a
	push af    ;save carry
	
	;now adc the whole component
	ld hl, objectX  ;load objectX object variable
	add hl, de
	pop af      ;restore carry
	ld a, [hl]
	adc a, b
	ld [hl], a
	jr .finishedSmokeMoveX
I really wanted to try other approaches and optimize things, e.g. by making sure object variables won't cross page boundaries, but I figured that I should just make something, even the naive approach, instead of sitting around and doing nothing like the last year, and it turned out great anyway.



Part 2: The Game Boy is amazing

Developing for the Game Boy I feel like it has limitless hardware. I feel like I've done soooo much, yet I used only like 1/4 of the RAM, like 1/3 of the 32 KB ROM, and I still have plenty of CPU power to spare.
  • RAM:
    There's soooo much. I have all the objects stored + a copy of OAM + a copy of the tiles on screen for collision purposes + a lot more, and I'm still only at about 1/4 of RAM usage, if that.
  • ROM:
    Even after using the music engine and making unoptimized music for it, I still have tons of ROM left for my 32 KB limit. (I am limiting myself to 32K because this is my first Game Boy project and I don't want to mess with bank switching.)
  • CPU:
    I need to make sure all code is completed running before the PPU goes to VSYNC, at line 0x90. See the number on the lower left corner? That's the Y coordinate that the screen is drawing when the game logic is finished running. Worst case, with 15 or so objects on screen, It's at 0x30, up from around 0x10 before I implemented the object system. I thought it would be a far bigger performance hit.
Long story short, maybe I worried too much about optimization, lol.

Maybe as someone who's never written for any old systems before, I had the impression that they're far weaker than I think, but now I have the opposite feeling on the Game Boy, at least. And developing for it is incredibly fun, too.



Anyway, thanks for your replies on GB programming so far, they've been very fun to read and mull over!