Translating Classic Arcade Games to JavaScript
-
Upload
norbertkehrer -
Category
Software
-
view
285 -
download
3
Transcript of Translating Classic Arcade Games to JavaScript
![Page 1: Translating Classic Arcade Games to JavaScript](https://reader036.fdocuments.net/reader036/viewer/2022062420/55cc4db8bb61eb2d258b4673/html5/thumbnails/1.jpg)
Translating Classic Arcade Gamesto JavaScript
Norbert Kehrer
vienna.js Meetup, June 24, 2015
![Page 2: Translating Classic Arcade Games to JavaScript](https://reader036.fdocuments.net/reader036/viewer/2022062420/55cc4db8bb61eb2d258b4673/html5/thumbnails/2.jpg)
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)
![Page 3: Translating Classic Arcade Games to JavaScript](https://reader036.fdocuments.net/reader036/viewer/2022062420/55cc4db8bb61eb2d258b4673/html5/thumbnails/3.jpg)
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
![Page 4: Translating Classic Arcade Games to JavaScript](https://reader036.fdocuments.net/reader036/viewer/2022062420/55cc4db8bb61eb2d258b4673/html5/thumbnails/4.jpg)
The Asteroids Arcade Machine is Based on the 6502 Processor
Program ROM6800–7fff
Work RAM0000–02ff
Vector ROM5000–57ff
Vector RAM4000–47ff
6502 DVG
Game Logic Video Hardware
![Page 5: Translating Classic Arcade Games to JavaScript](https://reader036.fdocuments.net/reader036/viewer/2022062420/55cc4db8bb61eb2d258b4673/html5/thumbnails/5.jpg)
Traditional Emulation of the Hardware ...
Program ROM6800–7fff
Work RAM0000–02ff
Vector ROM5000–57ff
Vector RAM4000–47ff
6502 DVG
Emulator inJavaScript
![Page 6: Translating Classic Arcade Games to JavaScript](https://reader036.fdocuments.net/reader036/viewer/2022062420/55cc4db8bb61eb2d258b4673/html5/thumbnails/6.jpg)
... or Translating the Game Program to JavaScript, …
Program ROM6800–7fff
Work RAM0000–02ff
Vector ROM5000–57ff
Vector RAM4000–47ff
6502 DVG
JavaScript
Emulator inJavaScript
![Page 7: Translating Classic Arcade Games to JavaScript](https://reader036.fdocuments.net/reader036/viewer/2022062420/55cc4db8bb61eb2d258b4673/html5/thumbnails/7.jpg)
… and by that Create a Stand-Alone Application
Program ROM6800–7fff
Work RAM0000–02ff
Vector ROM5000–57ff
Vector RAM4000–47ff
6502 DVG
JavaScript
Emulator inJavaScript
![Page 8: Translating Classic Arcade Games to JavaScript](https://reader036.fdocuments.net/reader036/viewer/2022062420/55cc4db8bb61eb2d258b4673/html5/thumbnails/8.jpg)
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
![Page 9: Translating Classic Arcade Games to JavaScript](https://reader036.fdocuments.net/reader036/viewer/2022062420/55cc4db8bb61eb2d258b4673/html5/thumbnails/9.jpg)
The 6502 was a Popular Microprocessor in the 1980s
![Page 10: Translating Classic Arcade Games to JavaScript](https://reader036.fdocuments.net/reader036/viewer/2022062420/55cc4db8bb61eb2d258b4673/html5/thumbnails/10.jpg)
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
![Page 11: Translating Classic Arcade Games to JavaScript](https://reader036.fdocuments.net/reader036/viewer/2022062420/55cc4db8bb61eb2d258b4673/html5/thumbnails/11.jpg)
The 6502 Instructions Can Have Three Formats
Op Code
Op CodePara-meter
Op CodeAddress
LowAddress
High
$a9 $03 … lda #3
$8d $07 $19 … sta $1907
$0a … asl
![Page 12: Translating Classic Arcade Games to JavaScript](https://reader036.fdocuments.net/reader036/viewer/2022062420/55cc4db8bb61eb2d258b4673/html5/thumbnails/12.jpg)
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
![Page 13: Translating Classic Arcade Games to JavaScript](https://reader036.fdocuments.net/reader036/viewer/2022062420/55cc4db8bb61eb2d258b4673/html5/thumbnails/13.jpg)
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
![Page 14: Translating Classic Arcade Games to JavaScript](https://reader036.fdocuments.net/reader036/viewer/2022062420/55cc4db8bb61eb2d258b4673/html5/thumbnails/14.jpg)
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;…
};
![Page 15: Translating Classic Arcade Games to JavaScript](https://reader036.fdocuments.net/reader036/viewer/2022062420/55cc4db8bb61eb2d258b4673/html5/thumbnails/15.jpg)
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
![Page 16: Translating Classic Arcade Games to JavaScript](https://reader036.fdocuments.net/reader036/viewer/2022062420/55cc4db8bb61eb2d258b4673/html5/thumbnails/16.jpg)
First, Write a Disassembler …
…6834: A2 44 ldx #$446836: A9 02 lda #$026838: 85 02 sta $02683A: 86 03 stx $03…
…A2 44A9 0285 0286 03…
Program ROM(from Asteroids)
Disassembler listing
![Page 17: Translating Classic Arcade Games to JavaScript](https://reader036.fdocuments.net/reader036/viewer/2022062420/55cc4db8bb61eb2d258b4673/html5/thumbnails/17.jpg)
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 44A9 0285 0286 03…
Program ROM(from Asteroids)
JavaScript code instead of disassembler listing
![Page 18: Translating Classic Arcade Games to JavaScript](https://reader036.fdocuments.net/reader036/viewer/2022062420/55cc4db8bb61eb2d258b4673/html5/thumbnails/18.jpg)
6502 Registers and Memory Become Variables and ArraysAccumulator
X register
Y register
C flag
N flag
…
Memory
var a;
var x;
var y;
var c;
var n;
var mem = new Array(65536);
![Page 19: Translating Classic Arcade Games to JavaScript](https://reader036.fdocuments.net/reader036/viewer/2022062420/55cc4db8bb61eb2d258b4673/html5/thumbnails/19.jpg)
„Normal“ Instructions Are Easy to Translatelda 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;
![Page 20: Translating Classic Arcade Games to JavaScript](https://reader036.fdocuments.net/reader036/viewer/2022062420/55cc4db8bb61eb2d258b4673/html5/thumbnails/20.jpg)
„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 !
![Page 21: Translating Classic Arcade Games to JavaScript](https://reader036.fdocuments.net/reader036/viewer/2022062420/55cc4db8bb61eb2d258b4673/html5/thumbnails/21.jpg)
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
…
};};
![Page 22: Translating Classic Arcade Games to JavaScript](https://reader036.fdocuments.net/reader036/viewer/2022062420/55cc4db8bb61eb2d258b4673/html5/thumbnails/22.jpg)
Case Labels Are Only Needed For Jump Targetspc = 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
…
};};
![Page 23: Translating Classic Arcade Games to JavaScript](https://reader036.fdocuments.net/reader036/viewer/2022062420/55cc4db8bb61eb2d258b4673/html5/thumbnails/23.jpg)
Conditional Branches Become“If” Statements
…
if (z === 1) { // beq 3000
pc = 3000;
break;
};
…
case 3000:…
![Page 24: Translating Classic Arcade Games to JavaScript](https://reader036.fdocuments.net/reader036/viewer/2022062420/55cc4db8bb61eb2d258b4673/html5/thumbnails/24.jpg)
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
…
![Page 25: Translating Classic Arcade Games to JavaScript](https://reader036.fdocuments.net/reader036/viewer/2022062420/55cc4db8bb61eb2d258b4673/html5/thumbnails/25.jpg)
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
![Page 26: Translating Classic Arcade Games to JavaScript](https://reader036.fdocuments.net/reader036/viewer/2022062420/55cc4db8bb61eb2d258b4673/html5/thumbnails/26.jpg)
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
![Page 27: Translating Classic Arcade Games to JavaScript](https://reader036.fdocuments.net/reader036/viewer/2022062420/55cc4db8bb61eb2d258b4673/html5/thumbnails/27.jpg)
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) …
![Page 28: Translating Classic Arcade Games to JavaScript](https://reader036.fdocuments.net/reader036/viewer/2022062420/55cc4db8bb61eb2d258b4673/html5/thumbnails/28.jpg)
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) …
![Page 29: Translating Classic Arcade Games to JavaScript](https://reader036.fdocuments.net/reader036/viewer/2022062420/55cc4db8bb61eb2d258b4673/html5/thumbnails/29.jpg)
?:
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) …
![Page 30: Translating Classic Arcade Games to JavaScript](https://reader036.fdocuments.net/reader036/viewer/2022062420/55cc4db8bb61eb2d258b4673/html5/thumbnails/30.jpg)
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,…)
LLVMasm.jsDatalog, Logic Programming, …
![Page 31: Translating Classic Arcade Games to JavaScript](https://reader036.fdocuments.net/reader036/viewer/2022062420/55cc4db8bb61eb2d258b4673/html5/thumbnails/31.jpg)
Summary: From Asteroids to Liveness Analysis Browser-playable „Asteroids“ as an
example 6502 Processor Translating 6502 code to JavaScript Optimizing: Redundant Code Elimination
![Page 32: Translating Classic Arcade Games to JavaScript](https://reader036.fdocuments.net/reader036/viewer/2022062420/55cc4db8bb61eb2d258b4673/html5/thumbnails/32.jpg)
Thank you!
http://members.aon.at/nkehrer/