Translating Classic Arcade Games to JavaScript

1.654 Aufrufe

Veröffentlicht am

These are the slides of a talk held on the viennajs JavaScript meetup in Vienna on June 24, 2015. It describes how the game program code of old arcade games based on the old 6502 microprocessor can be translated to JavaScript automatically and also describes specific optimizations of the resulting programs. By adding HTML5 canvas code for the graphics, you get a browser playable video game.

Veröffentlicht in: Software
0 Kommentare
1 Gefällt mir
Statistik
Notizen
  • Als Erste(r) kommentieren

Keine Downloads
Aufrufe
Aufrufe insgesamt
1.654
Auf SlideShare
0
Aus Einbettungen
0
Anzahl an Einbettungen
5
Aktionen
Geteilt
0
Downloads
4
Kommentare
0
Gefällt mir
1
Einbettungen 0
Keine Einbettungen

Keine Notizen für die Folie

Translating Classic Arcade Games to JavaScript

  1. 1. Translating Classic Arcade Games to JavaScript Norbert Kehrer vienna.js Meetup, June 24, 2015
  2. 2. Automatic Program Translation Is Exciting  Objective: exact conversion of the original  The traditional way: emulators  Interesting alternative: static binary translation (static recompilation)  Examples: Asteroids (1979), Astro Fighter (1980), Centipede (1981)
  3. 3. Translating 6502 to JavaScript  Emulation vs. Recompilation of „Asteroids“  The Source: the 6502  The Target: JavaScript  „Naive“ Translation Patterns  Code Optimization and the Exciting Journey into Compiler Theory
  4. 4. The Asteroids Arcade Machine is Based on the 6502 Processor Program ROM 6800–7fff Work RAM 0000–02ff Vector ROM 5000–57ff Vector RAM 4000–47ff 6502 DVG Game Logic Video Hardware
  5. 5. Traditional Emulation of the Hardware ... Program ROM 6800–7fff Work RAM 0000–02ff Vector ROM 5000–57ff Vector RAM 4000–47ff 6502 DVG Emulator in JavaScript
  6. 6. ... or Translating the Game Program to JavaScript, … Program ROM 6800–7fff Work RAM 0000–02ff Vector ROM 5000–57ff Vector RAM 4000–47ff 6502 DVG JavaScript Emulator in JavaScript
  7. 7. … and by that Create a Stand- Alone Application Program ROM 6800–7fff Work RAM 0000–02ff Vector ROM 5000–57ff Vector RAM 4000–47ff 6502 DVG JavaScript Emulator in JavaScript
  8. 8. Translating 6502 to JavaScript  Emulation vs. Recompilation of „Asteroids“  The Source: the 6502  The Target: JavaScript  „Naive“ Translation Patterns  Code Optimization and the Exciting Journey into Compiler Theory
  9. 9. The 6502 was a Popular Microprocessor in the 1980s
  10. 10. The 6502 Is Simple and Has Only a Few Registers Accumulator (A) X Register (X) Y Register (Y) Program Counter (PC) Flags: NV-BDIZC 00000001 Stack Pointer (S) 0000-00ff: Zero Page 0100-01ff: Stack 0200-ffff: Program Registers Memory
  11. 11. The 6502 Instructions Can Have Three Formats Op Code Op Code Para- meter Op Code Address Low Address High $a9 $03 … lda #3 $8d $07 $19 … sta $1907 $0a … asl
  12. 12. Some Instruction Examples  lda #1 Load accu with 1  sta 1000 Store accu in 1000  inx Add 1 to X  adc #7 Add 7 to the accu  jmp 3000 Jump to 3000  beq 2000 Conditional branch, if Z (zero) flag is set
  13. 13. Translating 6502 to JavaScript  Emulation vs. Recompilation of „Asteroids“  The Source: the 6502  The Target: JavaScript  „Naive“ Translation Patterns  Code Optimization and the Exciting Journey into Compiler Theory
  14. 14. JavaScript is the Target  Variables and arrays  Assignments and arithmetics  if (cond) { stmt1 } else { stmt2 };  switch (var) { case a: stmt1; break; case b: stmt2; break; case c: stmt3; break; … };
  15. 15. Translating 6502 to JavaScript  Emulation vs. Recompilation of „Asteroids“  The Source: the 6502  The Target: JavaScript  „Naive“ Translation Patterns  Code Optimization and the Exciting Journey into Compiler Theory
  16. 16. First, Write a Disassembler … … 6834: A2 44 ldx #$44 6836: A9 02 lda #$02 6838: 85 02 sta $02 683A: 86 03 stx $03 … … A2 44 A9 02 85 02 86 03 … Program ROM (from Asteroids) Disassembler listing
  17. 17. Then, Make a Code Generator Out of It … … ldx #$44 x=44; … lda #$02 a=2; … sta $02 mem[2]=a; … stx $03 mem[3]=x; … … A2 44 A9 02 85 02 86 03 … Program ROM (from Asteroids) JavaScript code instead of disassembler listing
  18. 18. 6502 Registers and Memory Become Variables and Arrays Accumulator X register Y register C flag N flag … Memory var a; var x; var y; var c; var n; var mem = new Array(65536);
  19. 19. „Normal“ Instructions Are Easy to Translate lda 1000 sta 1001 inc 1000 ldx #10 sta 2000,x inx a = mem[1000]; mem[1001] = a; mem[1000] = (mem[1000]+1)&0xff; x = 10; mem[2000+x] = a; x = (x+1) & 0xff;
  20. 20. „GOTO Considered Harmful“ Considered Harmful … 1000: ldx #0 ; x = 0 1002: inx ; x = x + 1 1003: stx $d020 ; x  screen color 1006: jmp 1002 ; go to 1002 … But, JavaScript has no (real) GOTO !
  21. 21. An Old „Fortran to C“ Trick pc = 1000; while (true) { switch (pc) { case 1000: x = 0; //ldx case 1002: x = (x+1) & 0xff; //inx case 1003: mem[0xd020] = x; //stx case 1006: pc = 1002; break; //jmp … }; };
  22. 22. Case Labels Are Only Needed For Jump Targets pc = 1000; while (true) { switch (pc) { case 1000: x = 0; //ldx case 1002: x = (x+1) & 0xff; //inx case 1003: mem[0xd020] = x; //stx case 1006: pc = 1002; break; //jmp … }; };
  23. 23. Conditional Branches Become “If” Statements … if (z === 1) { // beq 3000 pc = 3000; break; }; … case 3000: …
  24. 24. Dr. Sheldon Cooper‘s „Fun with Flags“  Many 6502 instructions set flags as their side effect  Example: lda 1000 if zero  Z=1 else Z=0 if neg.  N=1 else N=0 beq 4711 …
  25. 25. Instructions Need Additional Flag Calculation Code lda 1000 lda 1000 a = mem[1000]; a = mem[1000]; if (a==0) z=1; else z=0; if (a<0) n=1; else n=0;  Resulting programs are correct but big
  26. 26. Translating 6502 to JavaScript  Emulation vs. Recompilation of „Asteroids“  The Source: the 6502  The Target: JavaScript  „Naive“ Translation Patterns  Code Optimization and the Exciting Journey into Compiler Theory
  27. 27. Flag Calculations Are Often Redundant … lda 1000 a = mem[1000]; if (a==0) z=1; else z=0; if (a<0) n=1; else n=0; ldx 1200 x = mem[1200]; if (x==0) z=1; else z=0; if (x<0) n=1; else n=0; beq 4711 if (z==1) …
  28. 28. Flag Calculations Are Often Redundant … lda 1000 a = mem[1000]; if (a==0) z=1; else z=0; if (a<0) n=1; else n=0; ldx 1200 x = mem[1200]; if (x==0) z=1; else z=0; if (x<0) n=1; else n=0; beq 4711 if (z==1) …
  29. 29. ?: yes: … But Not Always lda 1000 a = mem[1000]; if (a==0) z=1; else z=0; if (a<0) n=1; else n=0; ldx 1200 x = mem[1200]; if (x==0) z=1; else z=0; if (x<0) n=1; else n=0; beq 4711 if (z==1) …
  30. 30. Redundant Code Elimination Is Difficult and Interesting  „Liveness analysis“ problem  Solution with fixpoint iteration, or more elegantly with Datalog programs  Many exciting further directions: More optimizations (combinations, high-level structure detection,…) LLVM asm.js Datalog, Logic Programming, …
  31. 31. Summary: From Asteroids to Liveness Analysis  Browser-playable „Asteroids“ as an example  6502 Processor  Translating 6502 code to JavaScript  Optimizing: Redundant Code Elimination
  32. 32. Thank you! http://members.aon.at/nkehrer/

×