32
Translating Classic Arcade Games to JavaScript Norbert Kehrer vienna.js Meetup, June 24, 2015

Translating Classic Arcade Games to JavaScript

Embed Size (px)

Citation preview

Page 1: Translating Classic Arcade Games to JavaScript

Translating Classic Arcade Gamesto JavaScript

Norbert Kehrer

vienna.js Meetup, June 24, 2015

Page 2: Translating Classic Arcade Games to JavaScript

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

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

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

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

... 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

… 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

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

The 6502 was a Popular Microprocessor in the 1980s

Page 10: Translating Classic Arcade Games to JavaScript

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

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

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

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

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

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

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

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

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

„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

„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

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

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

Conditional Branches Become“If” Statements

if (z === 1) { // beq 3000

pc = 3000;

break;

};

case 3000:…

Page 24: Translating Classic Arcade Games to JavaScript

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

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

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

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

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

?:

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

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

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

Thank you!

http://members.aon.at/nkehrer/