-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgameboy.js
105 lines (84 loc) · 2.64 KB
/
gameboy.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
const CPU = require('./cpu/cpu');
const GPU = require('./gpu/gpu');
const SPU = require('./spu/spu');
const Register = require('./cpu/register');
const Memory = require('./memory/memory');
const Timer = require('./timer/timer');
const Keypad = require('./keypad/keypad');
const Compress = require('./utils/base64String');
class GameBoy {
constructor(cartridge, audioSampleRate) {
this.cartridge = cartridge;
this.audioSampleRate = 0;
this.cpu = new CPU(this);
this.gpu = new GPU(this);
this.spu = new SPU(this);
this.memory = new Memory(this);
this.keypad = new Keypad(this);
this.timer = new Timer(this);
this.register = new Register(this);
this.components = [this.cartridge, this.memory, this.cpu, this.gpu, this.spu, this.keypad, this.timer];
this.initialize();
this.reset();
this.isPoweredOn = true;
}
start() {
this.cpu.start();
}
initialize() {
this.components.forEach(c => c.initialize());
}
reset() {
this.components.forEach(c => c.reset());
}
terminate() {
this.components.forEach(c => c.shutdown());
this.isPoweredOn = false;
}
setSampleRate (audioSampleRate) {
this.audioSampleRate = audioSampleRate;
}
compress(quickSaveData) {
return btoa(
JSON.stringify(quickSaveData)
);
}
deCompress(quickSaveData) {
return JSON.parse(
atob(quickSaveData)
);
}
quickSave() {
this.cpu.isRunning = false;
while (this.cpu.isInCpuStep) {
// wait for current instruction to end
}
const data = this.compress({
register: this.register.copy(),
gpu: this.gpu.copy(),
memory: this.memory.copy(),
cartridge: this.cartridge.copy(),
keypad: this.keypad.copy(),
timer: this.timer.copy(),
spu: this.spu.copy(),
});
this.cpu.isRunning = true;
return data;
}
quickLoad(quickSaveData) {
this.cpu.isRunning = false;
while (this.cpu.isInCpuStep) {
// wait for current instruction to end
}
const data = this.deCompress(quickSaveData);
this.register.restore(data.register),
this.gpu.restore(data.gpu),
this.memory.restore(data.memory),
this.cartridge.restore(data.cartridge),
this.keypad.restore(data.keypad),
this.timer.restore(data.timer),
this.spu.restore(data.spu),
(this.cpu.isRunning = true);
}
}
module.exports = GameBoy;