Successfully reported this slideshow.
Emulating with  JavaScript    new Cpu;
WHOAMI
WHOAMI• Alexander Dickson
WHOAMI• Alexander Dickson• @alexdickson
WHOAMI• Alexander Dickson• @alexdickson• Not an emulation expert
WHOAMI• Alexander Dickson• @alexdickson• Not an emulation expert• JavaScript developer at Atlassian
WHOAMI• Alexander Dickson• @alexdickson• Not an emulation expert• JavaScript developer at Atlassian                       ...
JavaScript today
JavaScript today• Fast
JavaScript today• Fast• Browser APIs are awesome
JavaScript today• Fast• Browser APIs are awesome• Inputs and outputs are awesome
What we have
What we have• Canvas Element
What we have• Canvas Element• Web Audio API
What we have• Canvas Element• Web Audio API• GamePad API
What we have• Canvas Element• Web Audio API• GamePad API• Typed Arrays
What we have• Canvas Element• Web Audio API• GamePad API• Typed Arrays• requestAnimationFrame()
What we don’t have
What we don’t have• Sane implementations
What we don’t have• Sane implementations• Just kidding, but some are better than  others
What we can build
What we can build• Lots of awesome, practical stuff...
What we can build• Lots of awesome, practical stuff...• ...or, emulate hardware, such as gaming  consoles.
Why?
Why?Because we can!
What is anemulator?
What is an                  emulator?  In computing, an emulator is hardware or software or both that  duplicates (or emul...
What can be emulated
What can be emulated• Church-Turing thesis
What can be emulated• Church-Turing thesis• Any system can be emulated
Implementations
Implementations• Interpreter
Implementations• Interpreter• Dynamic Re-compilation
Implementations• Interpreter• Dynamic Re-compilation• Static Re-compilation
Shhhh...
Shhhh...• Emulation can sometimes be a bit shaky  from a legal perspective.
Shhhh...• Emulation can sometimes be a bit shaky  from a legal perspective.• Emulate at your own risk and always use  free...
Shhhh...• Emulation can sometimes be a bit shaky  from a legal perspective.• Emulate at your own risk and always use  free...
Where to start      CPU
Where to start• Pick a system, anyCPU                     system
Where to start• Pick a system, anyCPU                     system• Discover its components
Where to start• Pick a system, anyCPU                      system• Discover its components• Find technical information on ...
Chip8
Chip8 is Easy
Chip8 is Easy• Simple CPU implementation
Chip8 is Easy• Simple CPU implementation• Simple graphics
Chip8 is Easy• Simple CPU implementation• Simple graphics• Fixed audio sample
Demo Time
Example System
Nintendo Entertainment System
Nintendo Entertainment System• Custom 6502 CPU
Nintendo Entertainment System• Custom 6502 CPU• 2KiB onboard RAM, 2KiB video RAM, 256B  OAM RAM, 28B palette RAM
Nintendo Entertainment System• Custom 6502 CPU• 2KiB onboard RAM, 2KiB video RAM, 256B  OAM RAM, 28B palette RAM• Custom-m...
Nintendo Entertainment System• Custom 6502 CPU• 2KiB onboard RAM, 2KiB video RAM, 256B  OAM RAM, 28B palette RAM• Custom-m...
Nintendo Entertainment System• Custom 6502 CPU• 2KiB onboard RAM, 2KiB video RAM, 256B  OAM RAM, 28B palette RAM• Custom-m...
Von-Neumann ArchitectureCPU                 Memory        Bus      Peripherals
CPU
CPU• Basically a loop
CPU• Basically a loop• Read operation codes (opcodes) from  memory, processes them
CPU• Basically a loop• Read operation codes (opcodes) from  memory, processes them• Opcodes mostly operate on registers
6502
6502•   Ricoh 2A03/2A07, customised 6502 w/ audio w/    gamepad w/o BCD
6502•   Ricoh 2A03/2A07, customised 6502 w/ audio w/    gamepad w/o BCD•   8 bit processor w/ 16 bit address bus
6502•   Ricoh 2A03/2A07, customised 6502 w/ audio w/    gamepad w/o BCD•   8 bit processor w/ 16 bit address bus•   1-2MHz...
6502•   Ricoh 2A03/2A07, customised 6502 w/ audio w/    gamepad w/o BCD•   8 bit processor w/ 16 bit address bus•   1-2MHz...
// Customised 6502 CPUNes.Cpu = function() {    this.registers = {        // Program Counter (16bit)        pc: null,     ...
Memory
Memory• Contiguous block of data
Memory• Contiguous block of data• ROM (readable)/RAM (readable/writable)
NES Memory
NES Memory• 2KiB onboard
NES Memory• 2KiB onboard• Internally stored zero-page, stack, general  purpose memory
NES Memory• 2KiB onboard• Internally stored zero-page, stack, general  purpose memory• Addressable up to 0x10000
NES Memory• 2KiB onboard• Internally stored zero-page, stack, general  purpose memory• Addressable up to 0x10000• Program ...
Typed Arrays
Typed Arrays• TypedArrays help performance critical  applications such as emulators
Typed Arrays• TypedArrays help performance critical  applications such as emulators• Makes it trivial to reach any specifie...
Typed Arrays• TypedArrays help performance critical  applications such as emulators• Makes it trivial to reach any specifie...
Nes.Cpu = function() {	 // ...	 // Our device has 2KiB of RAM.	 var memoryBuffer = new ArrayBuffer(0x800);	 // 6502 is a 8...
Need Getters/SettersMemory is mapped everywhere, so you need todelegate reads and writes to different areas.
Fetch/Decode Loop
Fetch/Decode Loop• Check for interrupts
Fetch/Decode Loop• Check for interrupts• Read memory at PC
Fetch/Decode Loop• Check for interrupts• Read memory at PC• Decode addressing mode
Fetch/Decode Loop• Check for interrupts• Read memory at PC• Decode addressing mode• Process opcode
Interrupts
Interrupts• Special signal that interrupts normal  execution
Interrupts• Special signal that interrupts normal  execution• Loads special address into PC and executes  it
Nes.Cpu = function() {	 // ...	 // Interrupt Types.	 this.interruptTypes = {	 	 NMI: 0	 	 // ...	 };	 // Current Interrupt...
SlowNes.Cpu.prototype.emulateCycle = function() {    this.interrupt != null &&    this["handle" +         (["nmi", "irq", ...
Handling Opcodes
Handling Opcodes• Read location in PC from memory
Handling Opcodes• Read location in PC from memory• Lookup opcode
Handling Opcodes• Read location in PC from memory• Lookup opcode• Find addressing mode
Handling Opcodes• Read location in PC from memory• Lookup opcode• Find addressing mode• Process opcode
Handling Opcodes• Read location in PC from memory• Lookup opcode• Find addressing mode• Process opcode• Increment PC
Cpu.prototype.emulateCycle = function() {	 // ...	 // Get opcode at PC.	 var opcode = this.getOpcode(this.loadMemory(this....
Process All The Opcodes
Process All The Opcodes• Read technical paper twice, implement  once
Process All The Opcodes• Read technical paper twice, implement  once• Debugging is hard, so get it right
Process All The Opcodes• Read technical paper twice, implement  once• Debugging is hard, so get it right• When you don’t g...
Nes.Cpu.prototype.emulateCycle = function() {	 // ...	 switch (opcode.type) {	 	 // JMP	 	 // Jump to location.	 	 case th...
PPU
PPU• Generates video signals from memory
PPU• Generates video signals from memory• Handles sprites, scrolling, colours
RP2C02RP2C07
RP2C02              RP2C07• Different chip for NTSC/PAL
RP2C02              RP2C07• Different chip for NTSC/PAL• 2KiB RAM
RP2C02              RP2C07• Different chip for NTSC/PAL• 2KiB RAM• 8x8 or 8x16 sprites
RP2C02              RP2C07• Different chip for NTSC/PAL• 2KiB RAM• 8x8 or 8x16 sprites• Resolution of 256x240
Communicating with your PPU
Communicating with your PPU• 0x2000-0x2007 on CPU memory map to  PPU’s registers
Communicating with your PPU• 0x2000-0x2007 on CPU memory map to  PPU’s registers• 8x8 or 8x16 pixel tiles, accessed on  pr...
Colour Palette• 52 colours available• 2 palettes, 16b each, image and sprite• Can use 25 colours at once on screen
TileS
TileS• Each 8x8 tile occupies 16b
TileS• Each 8x8 tile occupies 16b• Position of bit denotes position of pixel
TileS• Each 8x8 tile occupies 16b• Position of bit denotes position of pixel• First 8 bits combine with second 8 bits
TileS• Each 8x8 tile occupies 16b• Position of bit denotes position of pixel• First 8 bits combine with second 8 bits• Com...
Anatomy of a tile  1   1   1   1   1   1   1   1  1   1   1   1   1   1   1   1  1   1   0   1   1   0   0   1  1   1   0 ...
Anatomy of a tile  1   1   1    1      1     1   1   1  1   1   1    1      1     1   1   1  1   1   0    1      1     0  ...
Nametables
Nametables• Bytes which index pattern table
Nametables• Bytes which index pattern table• 32 horizontal and 30 vertical tiles, 960 tiles
Nametables• Bytes which index pattern table• 32 horizontal and 30 vertical tiles, 960 tiles• 1KiB long, delta contains ext...
Nothing is wasted
Nothing is wasted• Remaining 64b stores extra colour  information (attribute bytes)
Nothing is wasted• Remaining 64b stores extra colour  information (attribute bytes)• Attribute bytes map to 16 tiled block...
Nothing is wasted• Remaining 64b stores extra colour  information (attribute bytes)• Attribute bytes map to 16 tiled block...
Nothing is wasted• Remaining 64b stores extra colour  information (attribute bytes)• Attribute bytes map to 16 tiled block...
Put it all together  0. 1    0    1    1 0 0 1 1  8. 0    0    1    0 1 0 0 1960. 1    1    0    0 0 0 1 1================...
Put it all together  0. 1    0    1    1 0 0 1 1  8. 0    0    1    0 1 0 0 1960. 1    1    0    0 0 0 1 1================...
Put it all together  0. 1    0    1    1 0 0 1 1  8. 0    0    1    0 1 0 0 1960. 1    1    0    0 0 0 1 1================...
Put it all together  0. 1    0    1    1 0 0 1 1  8. 0    0    1    0 1 0 0 1960. 1    1    0    0 0 0 1 1================...
// Byte   at offset 0.var a =   0xB3;// Byte   at offset 8.var b =   0x29;// Byte   at offset 960.var c =   0xC3;var merge...
Scratching the surface
Scratching the surface• There is a whole lot more going on
Scratching the surface• There is a whole lot more going on• http://wiki.nesdev.com/w/index.php/PPU
Full Screen API
Full Screen API• Look ma, no chrome
Full Screen API• Look ma, no chrome• Still want Chrome for performance
Full Screen API• Look ma, no chrome• Still want Chrome for performance• https://developer.mozilla.org/en-US/docs/  DOM/Usi...
var goFullScreen = (function() {    // Polyfills for cross browser support.    return function(element, callback) {       ...
Demo Time
Sound
Sound• Vibration of air
Sound• Vibration of air• Represented as waves w/ freq. and  amplitude
Sound• Vibration of air• Represented as waves w/ freq. and  amplitude• Frequency is number of phase changes per  second
Sound• Vibration of air• Represented as waves w/ freq. and  amplitude• Frequency is number of phase changes per  second• A...
NES Sound
NES Sound• 5 sound channels
NES Sound• 5 sound channels• 2 pulse wave channels of variable duty cycle
NES Sound• 5 sound channels• 2 pulse wave channels of variable duty cycle• 16 volume levels
NES Sound• 5 sound channels• 2 pulse wave channels of variable duty cycle• 16 volume levels• Pitch bending
APU
APU• APU registers mapped to CPU memory  starting at 0x4000
APU• APU registers mapped to CPU memory  starting at 0x4000• 2 pulse-wave channels, 1 triangle-wave  channel, 1 random-wav...
PULSE Wave0x4000. 1011 11110x4002. 0001 01110x4003. 0000 0001
PULSE Wave0x4000. 1011 1111   Volume0x4002. 0001 01110x4003. 0000 0001
PULSE Wave0x4000. 1011 1111      Volume                    Low order bits0x4002. 0001 0111    of raw period0x4003. 0000 0001
PULSE Wave0x4000. 1011 1111      Volume                    Low order bits0x4002. 0001 0111    of raw period               ...
PULSE Wave0x4000. 1011 1111                         Volume                                       Low order bits0x4002. 000...
Demo Time
Web Audio API
Web Audio API• Based on Audio Routes
Web Audio API• Based on Audio Routes• Connect nodes to each other
Web Audio API• Based on Audio Routes• Connect nodes to each other• Perfect for emulator sound
var gainNode = ctx.createGainNode();gainNode.gain.value = volume;var osc = ctx.createOscillator();osc.connect(gainNode);os...
Demo Time
Sounds good
Sounds good• Again, scratching the surface
Sounds good• Again, scratching the surface• Sound information is rarer to find
Sounds good• Again, scratching the surface• Sound information is rarer to find• http://wiki.nesdev.com/w/index.php/APU
Controller
Controller• Two controllers, mapped to CPU memory  at 0x4016 and 0x4017
Controller• Two controllers, mapped to CPU memory  at 0x4016 and 0x4017• When written to, controller’s state is  stored in...
Gamepad API
Gamepad API• Firefox has an event based system
Gamepad API• Firefox has an event based system• WebKit requires polling
// Support gamepads in WebKit.var GamePad = function(callback) {	 if (typeof callback != "function") {	 	 throw Error("Cal...
Demo Time
Cycles
Cycles• Components IRL run in parallel
Cycles• Components IRL run in parallel• Count cycles, use to sync other  components
Cycles• Components IRL run in parallel• Count cycles, use to sync other  components• Try using Web Workers
Your very own emulator
Your very own emulator• Spend a lot of time researching
Your very own emulator• Spend a lot of time researching• Start programming your own programs
Your very own emulator• Spend a lot of time researching• Start programming your own programs• http://skilldrick.github.com...
Your very own emulator• Spend a lot of time researching• Start programming your own programs• http://skilldrick.github.com...
Getting Started
Getting Started      C8IYF
Getting Started          C8IYF  (Chip-8 Is Your Friend)
Tips
Tips• JavaScript as you would C
Tips• JavaScript as you would C• Optimise passing around data
Tips• JavaScript as you would C• Optimise passing around data• Know about V8 optimisations
Tips• JavaScript as you would C• Optimise passing around data• Know about V8 optimisations• Write your own programs
Possibilities
Possibilities• Multiplayer via WebSockets
Possibilities• Multiplayer via WebSockets• Vibration API for force feedback
Possibilities• Multiplayer via WebSockets• Vibration API for force feedback• File API and application cache for portable  ...
Possibilities• Multiplayer via WebSockets• Vibration API for force feedback• File API and application cache for portable  ...
Thank You
Thank YouQuestions
Emulating With JavaScript
Emulating With JavaScript
Emulating With JavaScript
Emulating With JavaScript
Upcoming SlideShare
Loading in …5
×

Emulating With JavaScript

694 views

Published on

My talk for JS Conf Down Under 2012

Published in: Technology
  • Be the first to comment

Emulating With JavaScript

  1. 1. Emulating with JavaScript new Cpu;
  2. 2. WHOAMI
  3. 3. WHOAMI• Alexander Dickson
  4. 4. WHOAMI• Alexander Dickson• @alexdickson
  5. 5. WHOAMI• Alexander Dickson• @alexdickson• Not an emulation expert
  6. 6. WHOAMI• Alexander Dickson• @alexdickson• Not an emulation expert• JavaScript developer at Atlassian
  7. 7. WHOAMI• Alexander Dickson• @alexdickson• Not an emulation expert• JavaScript developer at Atlassian ;
  8. 8. JavaScript today
  9. 9. JavaScript today• Fast
  10. 10. JavaScript today• Fast• Browser APIs are awesome
  11. 11. JavaScript today• Fast• Browser APIs are awesome• Inputs and outputs are awesome
  12. 12. What we have
  13. 13. What we have• Canvas Element
  14. 14. What we have• Canvas Element• Web Audio API
  15. 15. What we have• Canvas Element• Web Audio API• GamePad API
  16. 16. What we have• Canvas Element• Web Audio API• GamePad API• Typed Arrays
  17. 17. What we have• Canvas Element• Web Audio API• GamePad API• Typed Arrays• requestAnimationFrame()
  18. 18. What we don’t have
  19. 19. What we don’t have• Sane implementations
  20. 20. What we don’t have• Sane implementations• Just kidding, but some are better than others
  21. 21. What we can build
  22. 22. What we can build• Lots of awesome, practical stuff...
  23. 23. What we can build• Lots of awesome, practical stuff...• ...or, emulate hardware, such as gaming consoles.
  24. 24. Why?
  25. 25. Why?Because we can!
  26. 26. What is anemulator?
  27. 27. What is an emulator? In computing, an emulator is hardware or software or both that duplicates (or emulates) the functions of a first computer system (the guest) in a different second computer system (the host), so that the emulated behaviour closely resembles the behaviour of the real system.http://en.wikipedia.org/wiki/Emulator
  28. 28. What can be emulated
  29. 29. What can be emulated• Church-Turing thesis
  30. 30. What can be emulated• Church-Turing thesis• Any system can be emulated
  31. 31. Implementations
  32. 32. Implementations• Interpreter
  33. 33. Implementations• Interpreter• Dynamic Re-compilation
  34. 34. Implementations• Interpreter• Dynamic Re-compilation• Static Re-compilation
  35. 35. Shhhh...
  36. 36. Shhhh...• Emulation can sometimes be a bit shaky from a legal perspective.
  37. 37. Shhhh...• Emulation can sometimes be a bit shaky from a legal perspective.• Emulate at your own risk and always use free programs.
  38. 38. Shhhh...• Emulation can sometimes be a bit shaky from a legal perspective.• Emulate at your own risk and always use free programs.
  39. 39. Where to start CPU
  40. 40. Where to start• Pick a system, anyCPU system
  41. 41. Where to start• Pick a system, anyCPU system• Discover its components
  42. 42. Where to start• Pick a system, anyCPU system• Discover its components• Find technical information on how components work
  43. 43. Chip8
  44. 44. Chip8 is Easy
  45. 45. Chip8 is Easy• Simple CPU implementation
  46. 46. Chip8 is Easy• Simple CPU implementation• Simple graphics
  47. 47. Chip8 is Easy• Simple CPU implementation• Simple graphics• Fixed audio sample
  48. 48. Demo Time
  49. 49. Example System
  50. 50. Nintendo Entertainment System
  51. 51. Nintendo Entertainment System• Custom 6502 CPU
  52. 52. Nintendo Entertainment System• Custom 6502 CPU• 2KiB onboard RAM, 2KiB video RAM, 256B OAM RAM, 28B palette RAM
  53. 53. Nintendo Entertainment System• Custom 6502 CPU• 2KiB onboard RAM, 2KiB video RAM, 256B OAM RAM, 28B palette RAM• Custom-made PPU
  54. 54. Nintendo Entertainment System• Custom 6502 CPU• 2KiB onboard RAM, 2KiB video RAM, 256B OAM RAM, 28B palette RAM• Custom-made PPU• 5 sound channels
  55. 55. Nintendo Entertainment System• Custom 6502 CPU• 2KiB onboard RAM, 2KiB video RAM, 256B OAM RAM, 28B palette RAM• Custom-made PPU• 5 sound channels• Awesome rectangular controllers
  56. 56. Von-Neumann ArchitectureCPU Memory Bus Peripherals
  57. 57. CPU
  58. 58. CPU• Basically a loop
  59. 59. CPU• Basically a loop• Read operation codes (opcodes) from memory, processes them
  60. 60. CPU• Basically a loop• Read operation codes (opcodes) from memory, processes them• Opcodes mostly operate on registers
  61. 61. 6502
  62. 62. 6502• Ricoh 2A03/2A07, customised 6502 w/ audio w/ gamepad w/o BCD
  63. 63. 6502• Ricoh 2A03/2A07, customised 6502 w/ audio w/ gamepad w/o BCD• 8 bit processor w/ 16 bit address bus
  64. 64. 6502• Ricoh 2A03/2A07, customised 6502 w/ audio w/ gamepad w/o BCD• 8 bit processor w/ 16 bit address bus• 1-2MHz clock speed
  65. 65. 6502• Ricoh 2A03/2A07, customised 6502 w/ audio w/ gamepad w/o BCD• 8 bit processor w/ 16 bit address bus• 1-2MHz clock speed• http://www.6502.org/documents/datasheets/ rockwell/
  66. 66. // Customised 6502 CPUNes.Cpu = function() { this.registers = { // Program Counter (16bit) pc: null, // Stack Pointer (8bit) sp: null, // Accumulator (8bit) a: null, // Index X (8bit) x: null, // Index Y (8bit) y: null, // Processor Status, p: null }; // ... this.reset();};
  67. 67. Memory
  68. 68. Memory• Contiguous block of data
  69. 69. Memory• Contiguous block of data• ROM (readable)/RAM (readable/writable)
  70. 70. NES Memory
  71. 71. NES Memory• 2KiB onboard
  72. 72. NES Memory• 2KiB onboard• Internally stored zero-page, stack, general purpose memory
  73. 73. NES Memory• 2KiB onboard• Internally stored zero-page, stack, general purpose memory• Addressable up to 0x10000
  74. 74. NES Memory• 2KiB onboard• Internally stored zero-page, stack, general purpose memory• Addressable up to 0x10000• Program ROM contain opcodes, graphics and sound
  75. 75. Typed Arrays
  76. 76. Typed Arrays• TypedArrays help performance critical applications such as emulators
  77. 77. Typed Arrays• TypedArrays help performance critical applications such as emulators• Makes it trivial to reach any specified offset
  78. 78. Typed Arrays• TypedArrays help performance critical applications such as emulators• Makes it trivial to reach any specified offset• http://www.khronos.org/registry/ typedarray/specs/latest/
  79. 79. Nes.Cpu = function() { // ... // Our device has 2KiB of RAM. var memoryBuffer = new ArrayBuffer(0x800); // 6502 is a 8 bit processor, able // to address 8 bits at once. this.memory = new Uint8Array(memory); // ...};
  80. 80. Need Getters/SettersMemory is mapped everywhere, so you need todelegate reads and writes to different areas.
  81. 81. Fetch/Decode Loop
  82. 82. Fetch/Decode Loop• Check for interrupts
  83. 83. Fetch/Decode Loop• Check for interrupts• Read memory at PC
  84. 84. Fetch/Decode Loop• Check for interrupts• Read memory at PC• Decode addressing mode
  85. 85. Fetch/Decode Loop• Check for interrupts• Read memory at PC• Decode addressing mode• Process opcode
  86. 86. Interrupts
  87. 87. Interrupts• Special signal that interrupts normal execution
  88. 88. Interrupts• Special signal that interrupts normal execution• Loads special address into PC and executes it
  89. 89. Nes.Cpu = function() { // ... // Interrupt Types. this.interruptTypes = { NMI: 0 // ... }; // Current Interrupt. this.interrupt = null; // ...};Nes.Cpu.prototype.emulateCycle = function() { if (this.interrupt != null) { switch (this.interrupt) { // Non-Maskable case this.interruptTypes.NMI: this.handleNmi(); break; // ... } } // ...};
  90. 90. SlowNes.Cpu.prototype.emulateCycle = function() { this.interrupt != null && this["handle" + (["nmi", "irq", "reset"] .filter(function(type, index) { return index == this.interrupt; })[0]) ](); // ...};
  91. 91. Handling Opcodes
  92. 92. Handling Opcodes• Read location in PC from memory
  93. 93. Handling Opcodes• Read location in PC from memory• Lookup opcode
  94. 94. Handling Opcodes• Read location in PC from memory• Lookup opcode• Find addressing mode
  95. 95. Handling Opcodes• Read location in PC from memory• Lookup opcode• Find addressing mode• Process opcode
  96. 96. Handling Opcodes• Read location in PC from memory• Lookup opcode• Find addressing mode• Process opcode• Increment PC
  97. 97. Cpu.prototype.emulateCycle = function() { // ... // Get opcode at PC. var opcode = this.getOpcode(this.loadMemory(this.pc)); var address; // Get final address via addressing mode of opcode. switch (opcode.addressingMode) { // Zero Page // Uses a single operand which address // memory in zero page (0x0000-0x00FF). case this.addressingModes.ZERO_PAGE: address = this.loadMemory(this.pc + 1); break; } this.pc += opcode.bytes; // ...};
  98. 98. Process All The Opcodes
  99. 99. Process All The Opcodes• Read technical paper twice, implement once
  100. 100. Process All The Opcodes• Read technical paper twice, implement once• Debugging is hard, so get it right
  101. 101. Process All The Opcodes• Read technical paper twice, implement once• Debugging is hard, so get it right• When you don’t get it right, try again
  102. 102. Nes.Cpu.prototype.emulateCycle = function() { // ... switch (opcode.type) { // JMP // Jump to location. case this.operands.JMP: this.pc = address; break; } // ...};
  103. 103. PPU
  104. 104. PPU• Generates video signals from memory
  105. 105. PPU• Generates video signals from memory• Handles sprites, scrolling, colours
  106. 106. RP2C02RP2C07
  107. 107. RP2C02 RP2C07• Different chip for NTSC/PAL
  108. 108. RP2C02 RP2C07• Different chip for NTSC/PAL• 2KiB RAM
  109. 109. RP2C02 RP2C07• Different chip for NTSC/PAL• 2KiB RAM• 8x8 or 8x16 sprites
  110. 110. RP2C02 RP2C07• Different chip for NTSC/PAL• 2KiB RAM• 8x8 or 8x16 sprites• Resolution of 256x240
  111. 111. Communicating with your PPU
  112. 112. Communicating with your PPU• 0x2000-0x2007 on CPU memory map to PPU’s registers
  113. 113. Communicating with your PPU• 0x2000-0x2007 on CPU memory map to PPU’s registers• 8x8 or 8x16 pixel tiles, accessed on program ROM
  114. 114. Colour Palette• 52 colours available• 2 palettes, 16b each, image and sprite• Can use 25 colours at once on screen
  115. 115. TileS
  116. 116. TileS• Each 8x8 tile occupies 16b
  117. 117. TileS• Each 8x8 tile occupies 16b• Position of bit denotes position of pixel
  118. 118. TileS• Each 8x8 tile occupies 16b• Position of bit denotes position of pixel• First 8 bits combine with second 8 bits
  119. 119. TileS• Each 8x8 tile occupies 16b• Position of bit denotes position of pixel• First 8 bits combine with second 8 bits• Combine bits to get colour index
  120. 120. Anatomy of a tile 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 0 0 1 1 1 0 1 0 1 1 1 1 1 0 1 1 0 1 1 1 1 0 1 1 1 0 1 1 0 0 1 0 0 1 1 1 1 1 1 1 1 1 1
  121. 121. Anatomy of a tile 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 0 0 1 1 1 0 1 0 1 1 1 1 1 0 1 1 0 1 1 1 1 0 1 1 1 0 1 1 0 0 1 0 0 1 1 1 1 1 1 1 1 1 1 (simplified)
  122. 122. Nametables
  123. 123. Nametables• Bytes which index pattern table
  124. 124. Nametables• Bytes which index pattern table• 32 horizontal and 30 vertical tiles, 960 tiles
  125. 125. Nametables• Bytes which index pattern table• 32 horizontal and 30 vertical tiles, 960 tiles• 1KiB long, delta contains extra colour information
  126. 126. Nothing is wasted
  127. 127. Nothing is wasted• Remaining 64b stores extra colour information (attribute bytes)
  128. 128. Nothing is wasted• Remaining 64b stores extra colour information (attribute bytes)• Attribute bytes map to 16 tiled blocks of nametable (64 32x32 pixel tiles)
  129. 129. Nothing is wasted• Remaining 64b stores extra colour information (attribute bytes)• Attribute bytes map to 16 tiled blocks of nametable (64 32x32 pixel tiles)• Each of these blocks is sub-blocked into 4 tiles (4 16x16 pixel tiles)
  130. 130. Nothing is wasted• Remaining 64b stores extra colour information (attribute bytes)• Attribute bytes map to 16 tiled blocks of nametable (64 32x32 pixel tiles)• Each of these blocks is sub-blocked into 4 tiles (4 16x16 pixel tiles)• Sub blocks affected by 2 bits from attribute bytes
  131. 131. Put it all together 0. 1 0 1 1 0 0 1 1 8. 0 0 1 0 1 0 0 1960. 1 1 0 0 0 0 1 1============================= 1110 1100 0011 ...=============================
  132. 132. Put it all together 0. 1 0 1 1 0 0 1 1 8. 0 0 1 0 1 0 0 1960. 1 1 0 0 0 0 1 1============================= 1110 1100 0011 ...=============================
  133. 133. Put it all together 0. 1 0 1 1 0 0 1 1 8. 0 0 1 0 1 0 0 1960. 1 1 0 0 0 0 1 1============================= 1110 1100 0011 ...=============================
  134. 134. Put it all together 0. 1 0 1 1 0 0 1 1 8. 0 0 1 0 1 0 0 1960. 1 1 0 0 0 0 1 1============================= 1110 1100 0011 ...=============================
  135. 135. // Byte at offset 0.var a = 0xB3;// Byte at offset 8.var b = 0x29;// Byte at offset 960.var c = 0xC3;var merged = (a & 0x80) >> 0x6;merged |= b >> 0x7;merged |= (c & 0x3) << 0x2;
  136. 136. Scratching the surface
  137. 137. Scratching the surface• There is a whole lot more going on
  138. 138. Scratching the surface• There is a whole lot more going on• http://wiki.nesdev.com/w/index.php/PPU
  139. 139. Full Screen API
  140. 140. Full Screen API• Look ma, no chrome
  141. 141. Full Screen API• Look ma, no chrome• Still want Chrome for performance
  142. 142. Full Screen API• Look ma, no chrome• Still want Chrome for performance• https://developer.mozilla.org/en-US/docs/ DOM/Using_fullscreen_mode
  143. 143. var goFullScreen = (function() { // Polyfills for cross browser support. return function(element, callback) { typeof callback != "function" && (callback = function() {}); var requestFullScreen = getFullScreenMethod(element); if (requestFullScreen) { requestFullScreen = requestFullScreen.call(element); } else { return false; } document.addEventListener(fullScreenEvent, function() { callback.call(this, getFullScreenElement()); }); };})();
  144. 144. Demo Time
  145. 145. Sound
  146. 146. Sound• Vibration of air
  147. 147. Sound• Vibration of air• Represented as waves w/ freq. and amplitude
  148. 148. Sound• Vibration of air• Represented as waves w/ freq. and amplitude• Frequency is number of phase changes per second
  149. 149. Sound• Vibration of air• Represented as waves w/ freq. and amplitude• Frequency is number of phase changes per second• Amplitude is volume of the wave measured in dB
  150. 150. NES Sound
  151. 151. NES Sound• 5 sound channels
  152. 152. NES Sound• 5 sound channels• 2 pulse wave channels of variable duty cycle
  153. 153. NES Sound• 5 sound channels• 2 pulse wave channels of variable duty cycle• 16 volume levels
  154. 154. NES Sound• 5 sound channels• 2 pulse wave channels of variable duty cycle• 16 volume levels• Pitch bending
  155. 155. APU
  156. 156. APU• APU registers mapped to CPU memory starting at 0x4000
  157. 157. APU• APU registers mapped to CPU memory starting at 0x4000• 2 pulse-wave channels, 1 triangle-wave channel, 1 random-wave channel and 1 digital channel
  158. 158. PULSE Wave0x4000. 1011 11110x4002. 0001 01110x4003. 0000 0001
  159. 159. PULSE Wave0x4000. 1011 1111 Volume0x4002. 0001 01110x4003. 0000 0001
  160. 160. PULSE Wave0x4000. 1011 1111 Volume Low order bits0x4002. 0001 0111 of raw period0x4003. 0000 0001
  161. 161. PULSE Wave0x4000. 1011 1111 Volume Low order bits0x4002. 0001 0111 of raw period High order bits0x4003. 0000 0001 of raw period
  162. 162. PULSE Wave0x4000. 1011 1111 Volume Low order bits0x4002. 0001 0111 of raw periodround(111860.8 / 0x117) - 1) = 400hz High order bits0x4003. 0000 0001 of raw period
  163. 163. Demo Time
  164. 164. Web Audio API
  165. 165. Web Audio API• Based on Audio Routes
  166. 166. Web Audio API• Based on Audio Routes• Connect nodes to each other
  167. 167. Web Audio API• Based on Audio Routes• Connect nodes to each other• Perfect for emulator sound
  168. 168. var gainNode = ctx.createGainNode();gainNode.gain.value = volume;var osc = ctx.createOscillator();osc.connect(gainNode);osc.type = type;osc.frequency.value = frequency;gainNode.connect(ctx.destination);osc.noteOn(0);setTimeout(function () { osc.noteOff(0);}, duration);
  169. 169. Demo Time
  170. 170. Sounds good
  171. 171. Sounds good• Again, scratching the surface
  172. 172. Sounds good• Again, scratching the surface• Sound information is rarer to find
  173. 173. Sounds good• Again, scratching the surface• Sound information is rarer to find• http://wiki.nesdev.com/w/index.php/APU
  174. 174. Controller
  175. 175. Controller• Two controllers, mapped to CPU memory at 0x4016 and 0x4017
  176. 176. Controller• Two controllers, mapped to CPU memory at 0x4016 and 0x4017• When written to, controller’s state is stored in sequential 8 bytes, as low order bit
  177. 177. Gamepad API
  178. 178. Gamepad API• Firefox has an event based system
  179. 179. Gamepad API• Firefox has an event based system• WebKit requires polling
  180. 180. // Support gamepads in WebKit.var GamePad = function(callback) { if (typeof callback != "function") { throw Error("Callback must implement [[call]]."); } this.callback = callback; this.running = false;};GamePad.prototype.start = function() { this.running = true; this.tick();};GamePad.prototype.stop = function() { this.running = false;};GamePad.prototype.tick = function() { if ( ! this.running) { return; } this.callback(navigator.webkitGetGamepads()); webkitRequestAnimationFrame(this.tick.bind(this));};
  181. 181. Demo Time
  182. 182. Cycles
  183. 183. Cycles• Components IRL run in parallel
  184. 184. Cycles• Components IRL run in parallel• Count cycles, use to sync other components
  185. 185. Cycles• Components IRL run in parallel• Count cycles, use to sync other components• Try using Web Workers
  186. 186. Your very own emulator
  187. 187. Your very own emulator• Spend a lot of time researching
  188. 188. Your very own emulator• Spend a lot of time researching• Start programming your own programs
  189. 189. Your very own emulator• Spend a lot of time researching• Start programming your own programs• http://skilldrick.github.com/easy6502/
  190. 190. Your very own emulator• Spend a lot of time researching• Start programming your own programs• http://skilldrick.github.com/easy6502/• http://www.6502.org/books
  191. 191. Getting Started
  192. 192. Getting Started C8IYF
  193. 193. Getting Started C8IYF (Chip-8 Is Your Friend)
  194. 194. Tips
  195. 195. Tips• JavaScript as you would C
  196. 196. Tips• JavaScript as you would C• Optimise passing around data
  197. 197. Tips• JavaScript as you would C• Optimise passing around data• Know about V8 optimisations
  198. 198. Tips• JavaScript as you would C• Optimise passing around data• Know about V8 optimisations• Write your own programs
  199. 199. Possibilities
  200. 200. Possibilities• Multiplayer via WebSockets
  201. 201. Possibilities• Multiplayer via WebSockets• Vibration API for force feedback
  202. 202. Possibilities• Multiplayer via WebSockets• Vibration API for force feedback• File API and application cache for portable offline emulators
  203. 203. Possibilities• Multiplayer via WebSockets• Vibration API for force feedback• File API and application cache for portable offline emulators• localStorage for battery backed saved state
  204. 204. Thank You
  205. 205. Thank YouQuestions

×