 So yeah, my name's Tim and I wrote a Gameboy emulator and not only did I do that, I wrote it in JavaScript And I think everyone else should too Start by saying I'm Self-talk and I quite often Well, some of the things I say might just be wrong or I often find holes in my knowledge Happens embarrassingly frequently, but you can't argue with the result because the emulator works. So And you can play it after this talk Okay, maybe you should write it in JavaScript So the question I get asked often maybe not so much from this crowd is why why would you do this? First reason is there's already loads of Gameboy emulators And particularly if you wanted a web-based one, there's you know web assembly You could just port an existing emulator to wasm and it would run faster and it'd be easier to make But that misses the point The short answer is it's fun So an analogy I can give is a Rubik's Cube here's a Rubik's Cube if you haven't seen one before The whole point of a Rubik's Cube is to solve it You're you're just moving bits of plastic around if you just wanted it to be solved You could just take it apart or peel the stickers off Nobody questions. Oh, why are you doing that Rubik's Cube? It's it's understood that it's just for the challenge Yet somehow with a Gameboy emulator because it does something at the end. It's like it's not allowed to be for fun. I don't know But yeah, I'm probably preaching to the choir here. So Gameboy emulators why is a Gameboy perfect for emulation? Well First of all is challenging but achievable It is very hard. There are easier things to emulate, but Gameboy is just about doable by one person on their own Another reason is that the hardware is fairly simple. There are a lot of sim similar era consoles which are Not necessarily harder, but tedious for instance the the NES family com They tended to put a lot of like custom hardware in the cartridges So in order to emulate all of the games you have to emulate all of that custom hardware And there's like hundreds of different types of cartridge and for the Gameboy there are there's a bit of that You know, this is like the Gameboy camera, but there's basically there's just five main types of Memory back controller on the cartridge. So it's it's easier than some other consoles in that sense less tedious Another thing is that it's already reverse engineered because Well, if you're writing an emulator for a modern console, most of the work is reverse engineering what the hardware does But in the case of the Gameboy if you don't want to do all that reverse engineering people have done it for you And you can focus just on the emulation Another point I wanted to make is that it feels like a fractal because There's something about it when you start to write the emulator you can get Tetris running very early on Maybe maybe 20% of an emulator is enough to run Tetris And yet, you know, you even have to patch all of the things that don't work for other games Tetris doesn't use any of like the graphics features apart from like the very basic stuff and it doesn't have a memory bank controller at all Yeah, so Moving on to oh, yes, I love bare metal machine code. I Love a JavaScript. How can I combine these things by writing an emulator in JavaScript? So An emulator is a description of how a computer works and If you've not written an emulator, do you really know how computers work? Well, how do we start? How do we what's the first thing to do to make an emulator? Well, there is a cartridge for instance Tetris and What's on there? Well, it's a ROM It's filled with bytes What do those bytes mean? Well, they're instructions for the CPU What is the CPU? Well on the Game Boy the CPU is almost a Z80. It's It's got a few instructions added a few taken away, but it's basically a Z80 That table there, which is probably too small to see Is someone's made a lovely diagram of all of the instructions, but basically it's mostly one byte instructions One byte is read from memory and does something For instance, it might move some memory from one place to another or work with registers the all all CPUs well, but I know use registers which They're basically like hands for the CPU you pick something up you do something with it. You put it back so How can we emulate that? How can you make a? Say the load instruction move from one register to another well We could have a switch statement. We could just say read each byte. What does that byte do? Have a condition do do it to our virtual memory, you know have an array that is our RAM array That is our registers But of course, what's what's the most JavaScript solution? Well, my approach was to do this which What are we doing here? We've got an opcode array and it's filled with function pointers and The thing at the top is a function factory so to make it less tedious to write I've I've defined a bunch of constants That's the capital ABC Capital Reg reg all the registers and I'm returning a function which moves from one register to another And then at the end of the function it advances PC, which is a program counter, which tells a spider on my display The PC which is pointing to what current byte is being read and so then the emulator is just that it's while true execute the current opcode Done right, that's that's it. We've got a processor working There's there's a few more things you have to count cycles for some of the instructions and some of them are two bytes Oh, but that gets handled by this because it'll just advance the PC by by more I Got to this point. I was like, yeah, yeah, it runs. It's great. That's it's done But unfortunately the CPU is only a small part of the emulator. So Oh, yes, the boot code I'll come back to that after we've got our display CPU working the next thing is the display it turns out that writing the display is Maybe two or three times as much work as writing the CPU. It's not like a frame before you just put pixels No, you've got you've got hardware that renders tiles and sprites object attribute memory You've got pallets that can be swapped. You've got a thing called the window. That's that screenshot. You've got Where it says pause in the bottom that is a separate bank of tiles that can be super imposed called the window I don't know why it's called the window. It's useful kinds of things. It's only used for pause there You've also got the coincidence interrupt, which You know, sometimes you're looking at the hardware. You think what uses ours a simple game like Mario isn't gonna use like a scan line coincidence interrupt but no, it does the Background where it's an arrangement of tiles gets shifted as the level moves along But also in the background you've got the top two rows, which is you know Mario World time and number of coins, whatever those two rows are rendered into the background tiles and as the frame is drawn Partway through at line 17. It will trigger the coincidence interrupt, which then changes the value of the background So even a simple game like this uses it and then like more complicated games like You know the opening to Zelda Lynx Awakening. We've got like that parallax effect of them scrolling That's all done with the coincidence interrupt and some games do even more they they interrupt mid scan line just to do like effects and stuff so There's a lot to the display, but seeing the Nintendo logo for the first time is glorious getting it to run and then even when you think it's done right you get these This happened everything looked fine until I got to this. This is the first dungeon of Lynx Awakening and There's the heart is too high and there's a quarter heart underneath and it's like what? What it is is that it uses this 8 by 16 sprite mode and It's accessing sprites The hardware officially you can you can access it either by the high Bite or the high tile or the low tide it accesses the next sequential tile in memory and The way the game is written it always accesses it by the first tile Except in this one instance access it by the second tile and because I didn't Basically, you just have to zero the low bite But I hadn't spotted that and it just you can get quite far into the game before spotting these weird things. I mean That's what it's supposed to look like Yes more than that but once Once you've got the display working you can then start working on the sound Which is generally agreed to be the hardest bit of all now There's a few reasons why it's hard one is that like you know generating square waves aren't anti-aliased is difficult That's not a problem in JavaScript because we've got the web audio API, but The main reason it's hard is that it's not actually that well documented a lot of it is things like you know You can have a square wave do a sweep in volume, but how long does that sweep take and it's just a little bit Unclear in many places and also some games do weird things like instead of muting a channel They'll just send like a zero-length sweep to make it make it turn off So you can have the sound working perfectly in one game and then not working at all in another and But the hardest part of the sound is the noise channel which I Thought was just you know like noise for percussion. It's more than that You've got a linear feedback shift register, which is pseudo random noise generator and you can control both the clock speed to that and the period of the Tap point on the on the LFSR so It's used for well if you think of the links awakening opening screen You've got the shore noises going shh, and you've got the thunder noise going And you've also got as the title screen appears it goes So all of that's done with just sending different numbers to the linear feedback shift register Here's an interesting moment. This is when you go to rescue bow-wow and links awakening at this point in my emulator It just crashed entirely. It's like it was working fine just completely home. The reason was The actual hardware what's happening is it's only got a certain number of address lines to the cartridge For some reason at this point it loads another memory bank, which is just like way off Very very high number that's non-existent and of course in actual hardware. It just wraps because it doesn't have that extra address line so Here's it's a fun reason It's an explanation of why you have to play the game all the way through to the end to To prove that it works because I think a lot of people are emulates in this show the title screen and it's just I mean sure to play as many games as I could to the end. Here's the editing screen. I think it's awakening Just ruined it for anyone hasn't played it And there's Mario Let's go back to the boot code bit So When you first turn on the game, but it doesn't have an operating system But it does have the boot code so the purpose of the boot code is to load up the Nintendo logo and go And the reason they had that was for like legal defense So if you had a an unauthorized cartridge, it wouldn't run unless it included the Nintendo logo So Yeah, the boot code I thought it was kind of interesting it's it was ripped by looking at the the silicon die Someone traced out the the links in in the in the microscope image. So that's just an interesting point to add Yeah, so what else does skip over the I Didn't talk about memory maps peripherals so Kind of interesting to think like so once you've got your your CPU working and your registers How does it actually talk to the display or to the sound hardware? It's all just sort of just talking to bits of memory Like how do you read the controller that's When you press a button on the control what's that doing? it's it's making an electrical signal go high and You can just read a bit of memory from from that address and that tells you the state of the controller Yeah, I have Fair bit of time left. So I would hmm. Should I try and load up? We didn't arrange the sound. I don't know I Don't know that's pretty much the end of my talk to be honest But I would like to convince you all that writing an emulator is a lot of fun and Yeah, I think I'm about five minutes short. So feel free to ask me questions I'll show the emulator basically can I put it onto that screen? Okay, the sound is coming out my laptop. So So there you can see the parallax scrolling in the in the waves. That's coincidence a truck being used there I think the sound is coming out of my speakers on the laptop. I don't know how to rewrite route that I can confirm It is working. I can't hear it One of the games I didn't get to emulate correctly is prehistoric man, which it's like a 90s demo At the opening it does like pseudo 3d effects very cool very good music in that game prehistoric man. We really like it Yes, and if you if you missed it the The URL is mitzel.com slash swatch GB. It's stupid waste of time game boy. So Swatch GB is the emulator have a have a go on it and Yeah, how many minutes left Well, the the original idea was to try and write the whole thing in one day and I didn't manage that Just about got the CPU done in one day after After I got Tetris working on like I don't know a few days in Then lost a few more days to playing Tetris Overall, I mean I I estimate it was I Don't know maybe three weeks a bit longer I mean, I'm a very obsessive person. So I I kind of just Emulator So I don't know Yeah, I actually made a time lapse of me writing the emulator Which you can find on the page if you go to the emulator there's a link to an about page where there's lots more information and Yeah, there's there's a time lapse I put on YouTube which is generated from the get history which is Yeah, it's kind of funny to look at is anyone convinced to write an emulator. Come on. It's really good Yes Yes, some of you Well, I'm certainly am as well to be honest, but it's also bringing back bad memories of When I was doing writing a compiler coursework and stuff like that too writing. What was it a MIPS? Emulator as well. I had to write one of those for coursework or doing it for coursework not fun doing it for fun Fun. All right So thank you very much Tim. That was very very eye-opening and I'm certainly am inspired as well. So thank you