Git Product home page Git Product logo

0dmg's People

Contributors

jeremybanks avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

0dmg's Issues

Opcodes

as defined by https://pastraiser.com/cpu/gameboy/gameboy_opcodes.html

  • 00 NOP
  • 01 LD BC, d16
  • 02 LD (BC), A
  • 03 INC BC
  • 04 INC B
  • 05 DEC B
  • 06 LD B, d8
  • 07 RLCA
  • 08 LD (a16), SP
  • 09 ADD HL, BC
  • 0A LD A, (BC)
  • 0B DEC BC
  • 0C INC C
  • 0D DEC C
  • 0E LD C, d8
  • 0F RRCA
  • 10 STOP 0
  • 11 LD DE, d16
  • 12 LD (DE), A
  • 13 INC DE
  • 14 INC D
  • 15 DEC D
  • 16 LD D, d8
  • 17 RLA
  • 18 JR r8
  • 19 ADD HL, DE
  • 1A LD A, (DE)
  • 1B DEC DE
  • 1C INC E
  • 1D DEC E
  • 1E LD E, d8
  • 1F RRA
  • 20 JR NZ, r8
  • 21 LD HL, d16
  • 22 LD (HL+), A
  • 23 INC HL
  • 24 INC H
  • 25 DEC H
  • 26 LD H, d8
  • 27 DAA
  • 28 JR Z, r8
  • 29 ADD HL, HL
  • 2A LD A, (HL+)
  • 2B DEC HL
  • 2C INC L
  • 2D DEC L
  • 2E LD L, d8
  • 2F CPL
  • 30 JR NC, r8
  • 31 LD SP, d16
  • 32 LD (HL-), A
  • 33 INC SP
  • 34 INC (HL)
  • 35 DEC (HL)
  • 36 LD (HL), d8
  • 37 SCF
  • 38 JR C, r8
  • 39 ADD HL, SP
  • 3A LD A, (HL-)
  • 3B DEC SP
  • 3C INC A
  • 3D DEC A
  • 3E LD A, d8
  • 3F CCF
  • 40 LD B, B
  • 41 LD B, C
  • 42 LD B, D
  • 43 LD B, E
  • 44 LD B, H
  • 45 LD B, L
  • 46 LD B, (HL)
  • 47 LD B, A
  • 48 LD C, B
  • 49 LD C, C
  • 4A LD C, D
  • 4B LD C, E
  • 4C LD C, H
  • 4D LD C, L
  • 4E LD C, (HL)
  • 4F LD C, A
  • 50 LD D, B
  • 51 LD D, C
  • 52 LD D, D
  • 53 LD D, E
  • 54 LD D, H
  • 55 LD D, L
  • 56 LD D, (HL)
  • 57 LD D, A
  • 58 LD E, B
  • 59 LD E, C
  • 5A LD E, D
  • 5B LD E, E
  • 5C LD E, H
  • 5D LD E, L
  • 5E LD E, (HL)
  • 5F LD E, A
  • 60 LD H, B
  • 61 LD H, C
  • 62 LD H, D
  • 63 LD H, E
  • 64 LD H, H
  • 65 LD H, L
  • 66 LD H, (HL)
  • 67 LD H, A
  • 68 LD L, B
  • 69 LD L, C
  • 6A LD L, D
  • 6B LD L, E
  • 6C LD L, H
  • 6D LD L, L
  • 6E LD L, (HL)
  • 6F LD L, A
  • 70 LD (HL), B
  • 71 LD (HL), C
  • 72 LD (HL), D
  • 73 LD (HL), E
  • 74 LD (HL), H
  • 75 LD (HL), L
  • 76 HALT
  • 77 LD (HL), A
  • 78 LD A, B
  • 79 LD A, C
  • 7A LD A, D
  • 7B LD A, E
  • 7C LD A, H
  • 7D LD A, L
  • 7E LD A, (HL)
  • 7F LD A, A
  • 80 ADD A, B
  • 81 ADD A, C
  • 82 ADD A, D
  • 83 ADD A, E
  • 84 ADD A, H
  • 85 ADD A, L
  • 86 ADD A, (HL)
  • 87 ADD A, A
  • 88 ADC A, B
  • 89 ADC A, C
  • 8A ADC A, D
  • 8B ADC A, E
  • 8C ADC A, H
  • 8D ADC A, L
  • 8E ADC A, (HL)
  • 8F ADC A, A
  • 90 SUB B
  • 91 SUB C
  • 92 SUB D
  • 93 SUB E
  • 94 SUB H
  • 95 SUB L
  • 96 SUB (HL)
  • 97 SUB A
  • 98 SBC A, B
  • 99 SBC A, C
  • 9A SBC A, D
  • 9B SBC A, E
  • 9C SBC A, H
  • 9D SBC A, L
  • 9E SBC A, (HL)
  • 9F SBC A, A
  • A0 AND B
  • A1 AND C
  • A2 AND D
  • A3 AND E
  • A4 AND H
  • A5 AND L
  • A6 AND (HL)
  • A7 AND A
  • A8 XOR B
  • A9 XOR C
  • AA XOR D
  • AB XOR E
  • AC XOR H
  • AD XOR L
  • AE XOR (HL)
  • AF XOR A
  • B0 OR B
  • B1 OR C
  • B2 OR D
  • B3 OR E
  • B4 OR H
  • B5 OR L
  • B6 OR (HL)
  • B7 OR A
  • B8 CP B
  • B9 CP C
  • BA CP D
  • BB CP E
  • BC CP H
  • BD CP L
  • BE CP (HL)
  • BF CP A
  • C0 RET NZ
  • C1 POP BC
  • C2 JP NZ, a16
  • C3 JP a16
  • C4 CALL NZ, a16
  • C5 PUSH BC
  • C6 ADD A, d8
  • C7 RST 00H
  • C8 RET Z
  • C9 RET
  • CA JP Z, a16
  • CB prefix
  • CC CALL Z, a16
  • CD CALL a16
  • CE ADC A, d8
  • CF RST 08H
  • D0 RET NC
  • D1 POP DE
  • D2 JP NC, a16
  • XD3* invalid
  • D4 CALL NC, a16
  • D5 PUSH DE
  • D6 SUB d8
  • D7 RST 10H
  • D8 RET C
  • D9 RETI
  • DA JP C, a16
  • DB invalid
  • DC CALL C, a16
  • DD invalid
  • DE SBC A, d8
  • DF RST 18H
  • E0 LDH (a8), A
  • E1 POP HL
  • E2 LD (C), A
  • E3 invalid
  • E4 invalid
  • E5 PUSH HL
  • E6 AND d8
  • E7 RST 20H
  • E8 ADD SP, r8
  • E9 JP (HL)
  • EA LD (a16), A
  • EB invalid
  • EC invalid
  • ED invalid
  • EE XOR d8
  • EF RST 28H
  • F0 LDH A, (a8)
  • F1 POP AF
  • F2 LD A, (C)
  • F3 DI
  • F4 invalid
  • F5 PUSH AF
  • F6 OR d8
  • F7 RST 30H
  • F8 LD HL, SP+r8
  • F9 LD SP, HL
  • FA LD A, (a16)
  • FB EI
  • FC invalid
  • FD invalid
  • FE CP d8
  • FF RST 38H
  • CB 00 RLC B
  • CB 01 RLC C
  • CB 02 RLC D
  • CB 03 RLC E
  • CB 04 RLC H
  • CB 05 RLC L
  • CB 06 RLC (HL)
  • CB 07 RLC A
  • CB 08 RRC B
  • CB 09 RRC C
  • CB 0A RRC D
  • CB 0B RRC E
  • CB 0C RRC H
  • CB 0D RRC L
  • CB 0E RRC (HL)
  • CB 0F RRC A
  • CB 10 RL B
  • CB 11 RL C
  • CB 12 RL D
  • CB 13 RL E
  • CB 14 RL H
  • CB 15 RL L
  • CB 16 RL (HL)
  • CB 17 RL A
  • CB 18 RR B
  • CB 19 RR C
  • CB 1A RR D
  • CB 1B RR E
  • CB 1C RR H
  • CB 1D RR L
  • CB 1E RR (HL)
  • CB 1F RR A
  • CB 20 SLA B
  • CB 21 SLA C
  • CB 22 SLA D
  • CB 23 SLA E
  • CB 24 SLA H
  • CB 25 SLA L
  • CB 26 SLA (HL)
  • CB 27 SLA A
  • CB 28 SRA B
  • CB 29 SRA C
  • CB 2A SRA D
  • CB 2B SRA E
  • CB 2C SRA H
  • CB 2D SRA L
  • CB 2E SRA (HL)
  • CB 2F SRA A
  • CB 30 SWAP B
  • CB 31 SWAP C
  • CB 32 SWAP D
  • CB 33 SWAP E
  • CB 34 SWAP H
  • CB 35 SWAP L
  • CB 36 SWAP (HL)
  • CB 37 SWAP A
  • CB 38 SRL B
  • CB 39 SRL C
  • CB 3A SRL D
  • CB 3B SRL E
  • CB 3C SRL H
  • CB 3D SRL L
  • CB 3E SRL (HL)
  • CB 3F SRL A
  • CB 40 BIT 0, B
  • CB 41 BIT 0, C
  • CB 42 BIT 0, D
  • CB 43 BIT 0, E
  • CB 44 BIT 0, H
  • CB 45 BIT 0, L
  • CB 46 BIT 0, (HL)
  • CB 47 BIT 0, A
  • CB 48 BIT 1, B
  • CB 49 BIT 1, C
  • CB 4A BIT 1, D
  • CB 4B BIT 1, E
  • CB 4C BIT 1, H
  • CB 4D BIT 1, L
  • CB 4E BIT 1, (HL)
  • CB 4F BIT 1, A
  • CB 50 BIT 2, B
  • CB 51 BIT 2, C
  • CB 52 BIT 2, D
  • CB 53 BIT 2, E
  • CB 54 BIT 2, H
  • CB 55 BIT 2, L
  • CB 56 BIT 2, (HL)
  • CB 57 BIT 2, A
  • CB 58 BIT 3, B
  • CB 59 BIT 3, C
  • CB 5A BIT 3, D
  • CB 5B BIT 3, E
  • CB 5C BIT 3, H
  • CB 5D BIT 3, L
  • CB 5E BIT 3, (HL)
  • CB 5F BIT 3, A
  • CB 60 BIT 4, B
  • CB 61 BIT 4, C
  • CB 62 BIT 4, D
  • CB 63 BIT 4, E
  • CB 64 BIT 4, H
  • CB 65 BIT 4, L
  • CB 66 BIT 4, (HL)
  • CB 67 BIT 4, A
  • CB 68 BIT 5, B
  • CB 69 BIT 5, C
  • CB 6A BIT 5, D
  • CB 6B BIT 5, E
  • CB 6C BIT 5, H
  • CB 6D BIT 5, L
  • CB 6E BIT 5, (HL)
  • CB 6F BIT 5, A
  • CB 70 BIT 6, B
  • CB 71 BIT 6, C
  • CB 72 BIT 6, D
  • CB 73 BIT 6, E
  • CB 74 BIT 6, H
  • CB 75 BIT 6, L
  • CB 76 BIT 6, (HL)
  • CB 77 BIT 6, A
  • CB 78 BIT 7, B
  • CB 79 BIT 7, C
  • CB 7A BIT 7, D
  • CB 7B BIT 7, E
  • CB 7C BIT 7, H
  • CB 7D BIT 7, L
  • CB 7E BIT 7, (HL)
  • CB 7F BIT 7, A
  • CB 80 RES 0, B
  • CB 81 RES 0, C
  • CB 82 RES 0, D
  • CB 83 RES 0, E
  • CB 84 RES 0, H
  • CB 85 RES 0, L
  • CB 86 RES 0, (HL)
  • CB 87 RES 0, A
  • CB 88 RES 1, B
  • CB 89 RES 1, C
  • CB 8A RES 1, D
  • CB 8B RES 1, E
  • CB 8C RES 1, H
  • CB 8D RES 1, L
  • CB 8E RES 1, (HL)
  • CB 8F RES 1, A
  • CB 90 RES 2, B
  • CB 91 RES 2, C
  • CB 92 RES 2, D
  • CB 93 RES 2, E
  • CB 94 RES 2, H
  • CB 95 RES 2, L
  • CB 96 RES 2, (HL)
  • CB 97 RES 2, A
  • CB 98 RES 3, B
  • CB 99 RES 3, C
  • CB 9A RES 3, D
  • CB 9B RES 3, E
  • CB 9C RES 3, H
  • CB 9D RES 3, L
  • CB 9E RES 3, (HL)
  • CB 9F RES 3, A
  • CB A0 RES 4, B
  • CB A1 RES 4, C
  • CB A2 RES 4, D
  • CB A3 RES 4, E
  • CB A4 RES 4, H
  • CB A5 RES 4, L
  • CB A6 RES 4, (HL)
  • CB A7 RES 4, A
  • CB A8 RES 5, B
  • CB A9 RES 5, C
  • CB AA RES 5, D
  • CB AB RES 5, E
  • CB AC RES 5, H
  • CB AD RES 5, L
  • CB AE RES 5, (HL)
  • CB AF RES 5, A
  • CB B0 RES 6, B
  • CB B1 RES 6, C
  • CB B2 RES 6, D
  • CB B3 RES 6, E
  • CB B4 RES 6, H
  • CB B5 RES 6, L
  • CB B6 RES 6, (HL)
  • CB B7 RES 6, A
  • CB B8 RES 7, B
  • CB B9 RES 7, C
  • CB BA RES 7, D
  • CB BB RES 7, E
  • CB BC RES 7, H
  • CB BD RES 7, L
  • CB BE RES 7, (HL)
  • CB BF RES 7, A
  • CB C0 SET 0, B
  • CB C1 SET 0, C
  • CB C2 SET 0, D
  • CB C3 SET 0, E
  • CB C4 SET 0, H
  • CB C5 SET 0, L
  • CB C6 SET 0, (HL)
  • CB C7 SET 0, A
  • CB C8 SET 1, B
  • CB C9 SET 1, C
  • CB CA SET 1, D
  • CB CB SET 1, E
  • CB CC SET 1, H
  • CB CD SET 1, L
  • CB CE SET 1, (HL)
  • CB CF SET 1, A
  • CB D0 SET 2, B
  • CB D1 SET 2, C
  • CB D2 SET 2, D
  • CB D3 SET 2, E
  • CB D4 SET 2, H
  • CB D5 SET 2, L
  • CB D6 SET 2, (HL)
  • CB D7 SET 2, A
  • CB D8 SET 3, B
  • CB D9 SET 3, C
  • CB DA SET 3, D
  • CB DB SET 3, E
  • CB DC SET 3, H
  • CB DD SET 3, L
  • CB DE SET 3, (HL)
  • CB DF SET 3, A
  • CB E0 SET 4, B
  • CB E1 SET 4, C
  • CB E2 SET 4, D
  • CB E3 SET 4, E
  • CB E4 SET 4, H
  • CB E5 SET 4, L
  • CB E6 SET 4, (HL)
  • CB E7 SET 4, A
  • CB E8 SET 5, B
  • CB E9 SET 5, C
  • CB EA SET 5, D
  • CB EB SET 5, E
  • CB EC SET 5, H
  • CB ED SET 5, L
  • CB EE SET 5, (HL)
  • CB EF SET 5, A
  • CB F0 SET 6, B
  • CB F1 SET 6, C
  • CB F2 SET 6, D
  • CB F3 SET 6, E
  • CB F4 SET 6, H
  • CB F5 SET 6, L
  • CB F6 SET 6, (HL)
  • CB F7 SET 6, A
  • CB F8 SET 7, B
  • CB F9 SET 7, C
  • CB FA SET 7, D
  • CB FB SET 7, E
  • CB FC SET 7, H
  • CB FD SET 7, L
  • CB FE SET 7, (HL)
  • CB FF SET 7, A

Trace call sites in disassembler

  • Update RomByte structure to add a Vec of call sites for each call target

This is a nice idea but right now we'd have no way to represent this information in the disassembled form we go through to get human-readable representation.

If we even added labels to our disassembled code blocks, we could add this information in there.

If a block is only ever jumped to from itself, maybe we call it a "loop"?

Emulator library crate

Let's break the emulator logic itself, separate from its interface or any binary targets, into a separate crate. We'll keep this in the same repository, and won't publish anything yet, but we'll use a path dependency and call it zerodmg-emulator.

Any generic logic we need to share between both can be grouped into a zerodmg-utils crate, though the ideal would be to move anything substantial into an appropriate standalone package.

For now, the root zerodmg crate will remain the only one with a binary target. Even if we end up having multiple distinct interfaces (perhaps web vs headless CLI), we may still want to keep the single binary target and entry point, with flags to show what we want to invoke.

Initial functionality spike for AssembledRom/DisassembledRom

  • Instruction

    • a minimal initial set of instructions:
      • NOP
      • INC(U8Register)
      • DEC(U8Register)
      • JP(u16)
      • JP_NZ(u16)
    • .to_bytes()
    • .from_byte_iter()
      • assert that result length matches .byte_length()
    • .byte_length()
    • .to_string() (pseudo-assembly)
  • rom::FlowsTo for instruction::Instruction with next/absolute/relative instruction flows.

  • DisassembledRom

    • .assemble()
      • mark first instruction of Code blocks as known jump destination.
  • AssembledRom

    • ::new(u8)
      • should trace control flow from 0x0000 (real game entry points can wait)
    • .to_bytes() instead of .into::<Vec<u8>>()
    • .from_bytes() instead of .from::<Vec<u8>>()
    • .to_string() (pseudo-assembly)
    • .read_known_instruction()
      • should panic! if read is mis-aligned
      • trace control flow
    • .disassemble()
      • strip padding: NOPs trailing code blocks, and NOPs starting code blocks but aren't jump destinations

Interrupts

What are interrupts?

The Game Boy defines five types of "interrupts". Each is a type of event that can occur during execution. Each interrupt type has a constant handler address. When an interrupt is triggered, the CPU jumps to the handler instead of executing the next instruction. It will also temporarily disable interrupts, so that your interrupt doesn't itself get interrupted, although this can be toggled back if desired. Each interrupt handler routine typically ends with a RETI instruction to jump back to the original instruction address and re-enable interrupts.

An interrupt is "triggered", either manually or automatically, by setting the appropriate bit of the interrupt trigger flag register at 0xFF0F. The corresponding bit in the interrupt enable flag register at 0xFFFF must be set, or else the request is ignored. If the interrupt is triggered, the corresponding request flag bit is cleared, but if it's ignored it remains set, and may be triggered if the corresponding enable bit becomes set later.

  • 0b00000001 0x0040 V-Blank
    Triggered after each frame, when VRAM becomes available for general writing again.
  • 0b00000010 0x0048 LCD Status
    Triggered at different points during a frame based on the value of the "STAT" register at 0xFF41.
  • 0b00000100 0x0050 Timer Overflow
    Triggered when the timer overflows and resets, based on the the frequency and limits set in the timer registers at 0xFF04, 0xFF05, and 0xFF06.
  • 0b00001000 0x0058 Serial Transfer
    Triggered after a byte of data has been received over the serial port. The byte will be available at 0xFF01.
  • 0b00100000 0x0060 Button Released
    Triggered after a button has been released. Often requires debouncing due to duplicate triggers on physical hardware.

What do I need to implement?

  • Jump to interrupts when they're triggered.
    This should be a pretty simple new branch at the beginning of each CPU tick. If interrupt trigger register bitwise-and interrupt enable register is nonzero, then clear the first set bit and jump to the corresponding handler instead of running the next instruction.

  • Trigger interrupts

    • V-Blank
      The VideoController already keeps track of our draw line, so we just needs it to signal the CPU every time that value reaches the first "off-screen" v-blank line.
    • LCD Status
      I'd like to punt on this, at least for a little while. My currently very-primitive drawing routines do not work like they really do on the game boy, and probably don't have any notion of the timings that should trigger this.
    • Timer Overflow
      This shouldn't be very complicated, and I'm sure it's very widely used.
    • Serial Transfer
      When hell freezes over.
    • Button Released
      It'll probably be a while before we get any game to the point where it's actually waiting on this, but connecting our UI input events into the Game Boy state should be a useful, feasible, and neat.

Blargg's test suites

Blargg wrote a series of test suites for the Game Boy. We have the corresponding ROMs included in this repository, and will use them to measure and confirm progress.

  • Execute any test so that its result (pass or fail) is displayed.
  • Pass any test.
  • Pass cpu_instrs suite.
  • Pass instr_timing suite.
  • Pass interrupt_time suite.
  • Pass mem_timing suite.
  • Pass mem_timing-2 suite.
  • Pass dmg_sound suite.
  • Pass oam_bug suite.
  • Pass halt_bug suite.

The cgb_sound suite is omitted because we're not CGB-compatible.

In zerodmg_codes

  • Provide any Blargg test suites AssembledRom
  • Provide all Blargg test suites AssembledRom
  • Successfully sanity-check (disassemble/reassemble) any test suite
  • Successfully sanity-check (disassemble/reassemble) all test suites

Graphics debug panes

Current State

Requirements

  • background palette
  • object palette 0 (magenta for transparent)
  • object palette 1 (magenta for transparent)
  • tiles:
    • display all tiles (no palette applies)
    • grid between tiles
  • background 0
    • display all tiles, with offset
    • apply palette
  • background 1
    • display all tiles, with offset
    • apply palette
  • sprites
    • display all sprites
    • grid between sprites
    • apply palettes (magenta for transparent)

Use codes::Instruction in emulator::CPU

Initially, the only logic we'll be using is decoding individual instructions -- not touching the ROM types.

This will still require a lot of change, and possibly some horrible giant match blocks until/unless Rust eventually adds impl for enum variants: rust-lang/rfcs#1450.

Command-line debugger capabilities

We aren't have a fully-featured debugger, but we should add a few initial debugging features to our interpreter.

Currently, once per second we print the latest N (100?) instructions that we've executed, including their opcodes, addresses, clock time, and some debug info about what they modified. We throttle our execution so it doesn't exceed real-time, but aside from that we just run undisturbed until we hit a panic.

We should allow you to run in --debugger mode where you have commands like:

  • next $N=1: Run next $N instructions.
  • until $T: Run until clock time >= T.
  • to $A: Run until instruction pointer equals $A.
  • resume: Run forever.
  • log: Displays the latest 20(?) instructions, and the next 8 bytes from the instruction pointer.
  • registers: Show all registers.
  • memory $N: Show value in memory at address $N.
  • read $A: Displays the value in memory at address $A.

To make this most useful, we also need to:

  • Update all methods that can panic so they instead return Results. If they return an Err, they must make sure to have had no side effects, so we can (if appropriate) bring up the debugger instead of aborting the program.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.