Skip to content

Commit

Permalink
refactor RUMBLE
Browse files Browse the repository at this point in the history
  • Loading branch information
ardean committed Jun 12, 2018
1 parent f45ab46 commit 0909c89
Show file tree
Hide file tree
Showing 11 changed files with 134 additions and 106 deletions.
2 changes: 1 addition & 1 deletion dist/jsgbc-core.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions dist/typings/core/GameBoyCore.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ export default class GameBoyCore {
loadState(state: any): void;
jumpCompile(): void;
connectCartridge(cartridge: Cartridge): void;
onRUMBLE(): void;
loadCartridgeRomIntoMemory(): void;
loadBootROMIntoMemory(): void;
start(cartridge: Cartridge): void;
Expand Down
2 changes: 1 addition & 1 deletion dist/typings/core/cartridge/RUMBLE.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import MBC5 from "./mbc5";
export default class RUMBLE extends MBC5 {
writeRAMBank(address: any, data: any): void;
writeRAMBank(address: number, data: number): void;
}
2 changes: 1 addition & 1 deletion dist/typings/core/cartridge/mbc5.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ export default class MBC5 extends MBC {
setCurrentROMBank(): void;
writeROMBankLow(address: any, data: any): void;
writeROMBankHigh(address: any, data: any): void;
writeRAMBank(address: any, data: any): void;
writeRAMBank(address: number, value: number): void;
}
1 change: 1 addition & 0 deletions dist/typings/core/memory/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export default class Memory {
constructor(gameboy: GameBoyCore, data: any);
write(address: number, value: number): void;
read(address: number): number;
hasReader(address: number): boolean;
jumpCompile(): void;
setReaders(from: number, to: number, reader: ReaderFunction): void;
setReader(address: number, reader: ReaderFunction): void;
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "jsgbc",
"version": "0.5.5",
"version": "0.5.6",
"description": "jsGBC Core Emulator",
"main": "./dist/jsgbc-core.js",
"types": "./dist/typings/index.d.ts",
Expand Down
167 changes: 86 additions & 81 deletions src/core/GameBoyCore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ export default class GameBoyCore {
this.MBC5WriteRAMBank = this.MBC5WriteRAMBank.bind(this);
this.MBCWriteEnable = this.MBCWriteEnable.bind(this);
this.RUMBLEWriteRAMBank = this.RUMBLEWriteRAMBank.bind(this);
this.onRUMBLE = this.onRUMBLE.bind(this);
this.memoryReadMBC = this.memoryReadMBC.bind(this);
this.memoryReadMBC3 = this.memoryReadMBC3.bind(this);
this.memoryReadMBC7 = this.memoryReadMBC7.bind(this);
Expand Down Expand Up @@ -331,20 +332,23 @@ export default class GameBoyCore {
}

connectCartridge(cartridge: Cartridge) {
if (this.cartridge && this.cartridge.mbc) this.cartridge.mbc.removeListener("rumble", this.onRUMBLE);

cartridge.connect(this);
this.cartridge = cartridge;

if (this.cartridge && this.cartridge.mbc) this.cartridge.mbc.on("rumble", this.onRUMBLE);

this.loadCartridgeRomIntoMemory();
if (this.bootROM) this.loadBootROMIntoMemory();

this.cartridge.interpret();
}

// TODO: cleanup
this.cartridge.mbc.on("rumble", () => {
if (typeof window !== "undefined" && "vibrate" in window.navigator) {
window.navigator.vibrate(200);
}
});
onRUMBLE() {
if (typeof window !== "undefined" && "vibrate" in window.navigator) {
window.navigator.vibrate(200);
}
}

loadCartridgeRomIntoMemory() {
Expand Down Expand Up @@ -412,7 +416,7 @@ export default class GameBoyCore {

initMemory() {
// Initialize the RAM:
this.memory = util.getTypedArray(0x10000, 0, "uint8"); // TODO: remove
this.memory = util.getTypedArray(0x10000, 0, "uint8"); // TODO: replace with Memory Class
this.audioController.setMemory(this.memory);
this.frameBuffer = util.getTypedArray(23040, 0xf8f8f8, "int32");
this.BGCHRBank1 = util.getTypedArray(0x800, 0, "uint8");
Expand Down Expand Up @@ -2379,6 +2383,12 @@ export default class GameBoyCore {
//Memory Reading:
memoryRead(address) {
// Act as a wrapper for reading the returns from the compiled jumps to memory.

if (0xFFFF < address) {
console.log(address, this.memoryReader[address]);
}

if (this.memoryNew.hasReader(address)) return this.memoryNew.read(address);
return this.memoryReader[address].apply(this, [address]);
}

Expand Down Expand Up @@ -2427,17 +2437,14 @@ export default class GameBoyCore {
} else if (index >= 0xff00) {
switch (index) {
case MemoryLayout.JOYPAD_REG:
//JOYPAD:
this.memoryHighReader[0] = this.memoryReader[MemoryLayout.JOYPAD_REG] = address => 0xc0 | this.memory[MemoryLayout.JOYPAD_REG]; // top nibble returns as set.
break;
case MemoryLayout.SB_REG:
// SB
this.memoryHighReader[0x01] = this.memoryReader[MemoryLayout.SB_REG] = address => {
return this.memory[MemoryLayout.SC_REG] < 0x80 ? this.memory[MemoryLayout.SB_REG] : 0xff;
};
break;
case MemoryLayout.SC_REG:
// SC
if (this.cartridge.useGBCMode) {
this.memoryHighReader[0x02] = this.memoryReader[MemoryLayout.SC_REG] = address => {
return (this.serialTimer <= 0 ? 0x7c : 0xfc) | this.memory[MemoryLayout.SC_REG];
Expand Down Expand Up @@ -3166,56 +3173,54 @@ export default class GameBoyCore {
//Clock the CPU for the DMA transfer (CPU is halted during the transfer):
this.CPUTicks += 4 | tilesToTransfer << 5 << this.doubleSpeedShifter;
}
//Source address of the transfer:
// Source address of the transfer:
var source = this.memory[0xff51] << 8 | this.memory[0xff52];
//Destination address in the VRAM memory range:
// Destination address in the VRAM memory range:
var destination = this.memory[0xff53] << 8 | this.memory[0xff54];
//Creating some references:
var memoryReader = this.memoryReader;
//JIT the graphics render queue:
// JIT the graphics render queue:
this.graphicsJIT();
var memory = this.memory;
//Determining which bank we're working on so we can optimize:
// Determining which bank we're working on so we can optimize:
if (this.currVRAMBank === 0) {
//DMA transfer for VRAM bank 0:
// DMA transfer for VRAM bank 0:
do {
if (destination < 0x1800) {
memory[0x8000 | destination] = memoryReader[source].apply(this, [source++]);
memory[0x8001 | destination] = memoryReader[source].apply(this, [source++]);
memory[0x8002 | destination] = memoryReader[source].apply(this, [source++]);
memory[0x8003 | destination] = memoryReader[source].apply(this, [source++]);
memory[0x8004 | destination] = memoryReader[source].apply(this, [source++]);
memory[0x8005 | destination] = memoryReader[source].apply(this, [source++]);
memory[0x8006 | destination] = memoryReader[source].apply(this, [source++]);
memory[0x8007 | destination] = memoryReader[source].apply(this, [source++]);
memory[0x8008 | destination] = memoryReader[source].apply(this, [source++]);
memory[0x8009 | destination] = memoryReader[source].apply(this, [source++]);
memory[0x800a | destination] = memoryReader[source].apply(this, [source++]);
memory[0x800b | destination] = memoryReader[source].apply(this, [source++]);
memory[0x800c | destination] = memoryReader[source].apply(this, [source++]);
memory[0x800d | destination] = memoryReader[source].apply(this, [source++]);
memory[0x800e | destination] = memoryReader[source].apply(this, [source++]);
memory[0x800f | destination] = memoryReader[source].apply(this, [source++]);
memory[0x8000 | destination] = this.memoryRead(source++);
memory[0x8001 | destination] = this.memoryRead(source++);
memory[0x8002 | destination] = this.memoryRead(source++);
memory[0x8003 | destination] = this.memoryRead(source++);
memory[0x8004 | destination] = this.memoryRead(source++);
memory[0x8005 | destination] = this.memoryRead(source++);
memory[0x8006 | destination] = this.memoryRead(source++);
memory[0x8007 | destination] = this.memoryRead(source++);
memory[0x8008 | destination] = this.memoryRead(source++);
memory[0x8009 | destination] = this.memoryRead(source++);
memory[0x800a | destination] = this.memoryRead(source++);
memory[0x800b | destination] = this.memoryRead(source++);
memory[0x800c | destination] = this.memoryRead(source++);
memory[0x800d | destination] = this.memoryRead(source++);
memory[0x800e | destination] = this.memoryRead(source++);
memory[0x800f | destination] = this.memoryRead(source++);
this.generateGBCTileBank1(destination);
destination += 0x10;
} else {
destination &= 0x7f0;
this.BGCHRBank1[destination++] = memoryReader[source].apply(this, [source++]);
this.BGCHRBank1[destination++] = memoryReader[source].apply(this, [source++]);
this.BGCHRBank1[destination++] = memoryReader[source].apply(this, [source++]);
this.BGCHRBank1[destination++] = memoryReader[source].apply(this, [source++]);
this.BGCHRBank1[destination++] = memoryReader[source].apply(this, [source++]);
this.BGCHRBank1[destination++] = memoryReader[source].apply(this, [source++]);
this.BGCHRBank1[destination++] = memoryReader[source].apply(this, [source++]);
this.BGCHRBank1[destination++] = memoryReader[source].apply(this, [source++]);
this.BGCHRBank1[destination++] = memoryReader[source].apply(this, [source++]);
this.BGCHRBank1[destination++] = memoryReader[source].apply(this, [source++]);
this.BGCHRBank1[destination++] = memoryReader[source].apply(this, [source++]);
this.BGCHRBank1[destination++] = memoryReader[source].apply(this, [source++]);
this.BGCHRBank1[destination++] = memoryReader[source].apply(this, [source++]);
this.BGCHRBank1[destination++] = memoryReader[source].apply(this, [source++]);
this.BGCHRBank1[destination++] = memoryReader[source].apply(this, [source++]);
this.BGCHRBank1[destination++] = memoryReader[source].apply(this, [source++]);
this.BGCHRBank1[destination++] = this.memoryRead(source++);
this.BGCHRBank1[destination++] = this.memoryRead(source++);
this.BGCHRBank1[destination++] = this.memoryRead(source++);
this.BGCHRBank1[destination++] = this.memoryRead(source++);
this.BGCHRBank1[destination++] = this.memoryRead(source++);
this.BGCHRBank1[destination++] = this.memoryRead(source++);
this.BGCHRBank1[destination++] = this.memoryRead(source++);
this.BGCHRBank1[destination++] = this.memoryRead(source++);
this.BGCHRBank1[destination++] = this.memoryRead(source++);
this.BGCHRBank1[destination++] = this.memoryRead(source++);
this.BGCHRBank1[destination++] = this.memoryRead(source++);
this.BGCHRBank1[destination++] = this.memoryRead(source++);
this.BGCHRBank1[destination++] = this.memoryRead(source++);
this.BGCHRBank1[destination++] = this.memoryRead(source++);
this.BGCHRBank1[destination++] = this.memoryRead(source++);
this.BGCHRBank1[destination++] = this.memoryRead(source++);
destination = destination + 0x1800 & 0x1ff0;
}
source &= 0xfff0;
Expand All @@ -3226,42 +3231,42 @@ export default class GameBoyCore {
//DMA transfer for VRAM bank 1:
do {
if (destination < 0x1800) {
VRAM[destination] = memoryReader[source].apply(this, [source++]);
VRAM[destination | 0x1] = memoryReader[source].apply(this, [source++]);
VRAM[destination | 0x2] = memoryReader[source].apply(this, [source++]);
VRAM[destination | 0x3] = memoryReader[source].apply(this, [source++]);
VRAM[destination | 0x4] = memoryReader[source].apply(this, [source++]);
VRAM[destination | 0x5] = memoryReader[source].apply(this, [source++]);
VRAM[destination | 0x6] = memoryReader[source].apply(this, [source++]);
VRAM[destination | 0x7] = memoryReader[source].apply(this, [source++]);
VRAM[destination | 0x8] = memoryReader[source].apply(this, [source++]);
VRAM[destination | 0x9] = memoryReader[source].apply(this, [source++]);
VRAM[destination | 0xa] = memoryReader[source].apply(this, [source++]);
VRAM[destination | 0xb] = memoryReader[source].apply(this, [source++]);
VRAM[destination | 0xc] = memoryReader[source].apply(this, [source++]);
VRAM[destination | 0xd] = memoryReader[source].apply(this, [source++]);
VRAM[destination | 0xe] = memoryReader[source].apply(this, [source++]);
VRAM[destination | 0xf] = memoryReader[source].apply(this, [source++]);
VRAM[destination] = this.memoryRead(source++);
VRAM[destination | 0x1] = this.memoryRead(source++);
VRAM[destination | 0x2] = this.memoryRead(source++);
VRAM[destination | 0x3] = this.memoryRead(source++);
VRAM[destination | 0x4] = this.memoryRead(source++);
VRAM[destination | 0x5] = this.memoryRead(source++);
VRAM[destination | 0x6] = this.memoryRead(source++);
VRAM[destination | 0x7] = this.memoryRead(source++);
VRAM[destination | 0x8] = this.memoryRead(source++);
VRAM[destination | 0x9] = this.memoryRead(source++);
VRAM[destination | 0xa] = this.memoryRead(source++);
VRAM[destination | 0xb] = this.memoryRead(source++);
VRAM[destination | 0xc] = this.memoryRead(source++);
VRAM[destination | 0xd] = this.memoryRead(source++);
VRAM[destination | 0xe] = this.memoryRead(source++);
VRAM[destination | 0xf] = this.memoryRead(source++);
this.generateGBCTileBank2(destination);
destination += 0x10;
} else {
destination &= 0x7f0;
this.BGCHRBank2[destination++] = memoryReader[source].apply(this, [source++]);
this.BGCHRBank2[destination++] = memoryReader[source].apply(this, [source++]);
this.BGCHRBank2[destination++] = memoryReader[source].apply(this, [source++]);
this.BGCHRBank2[destination++] = memoryReader[source].apply(this, [source++]);
this.BGCHRBank2[destination++] = memoryReader[source].apply(this, [source++]);
this.BGCHRBank2[destination++] = memoryReader[source].apply(this, [source++]);
this.BGCHRBank2[destination++] = memoryReader[source].apply(this, [source++]);
this.BGCHRBank2[destination++] = memoryReader[source].apply(this, [source++]);
this.BGCHRBank2[destination++] = memoryReader[source].apply(this, [source++]);
this.BGCHRBank2[destination++] = memoryReader[source].apply(this, [source++]);
this.BGCHRBank2[destination++] = memoryReader[source].apply(this, [source++]);
this.BGCHRBank2[destination++] = memoryReader[source].apply(this, [source++]);
this.BGCHRBank2[destination++] = memoryReader[source].apply(this, [source++]);
this.BGCHRBank2[destination++] = memoryReader[source].apply(this, [source++]);
this.BGCHRBank2[destination++] = memoryReader[source].apply(this, [source++]);
this.BGCHRBank2[destination++] = memoryReader[source].apply(this, [source++]);
this.BGCHRBank2[destination++] = this.memoryRead(source++);
this.BGCHRBank2[destination++] = this.memoryRead(source++);
this.BGCHRBank2[destination++] = this.memoryRead(source++);
this.BGCHRBank2[destination++] = this.memoryRead(source++);
this.BGCHRBank2[destination++] = this.memoryRead(source++);
this.BGCHRBank2[destination++] = this.memoryRead(source++);
this.BGCHRBank2[destination++] = this.memoryRead(source++);
this.BGCHRBank2[destination++] = this.memoryRead(source++);
this.BGCHRBank2[destination++] = this.memoryRead(source++);
this.BGCHRBank2[destination++] = this.memoryRead(source++);
this.BGCHRBank2[destination++] = this.memoryRead(source++);
this.BGCHRBank2[destination++] = this.memoryRead(source++);
this.BGCHRBank2[destination++] = this.memoryRead(source++);
this.BGCHRBank2[destination++] = this.memoryRead(source++);
this.BGCHRBank2[destination++] = this.memoryRead(source++);
this.BGCHRBank2[destination++] = this.memoryRead(source++);
destination = destination + 0x1800 & 0x1ff0;
}
source &= 0xfff0;
Expand Down
9 changes: 4 additions & 5 deletions src/core/cartridge/RUMBLE.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import MBC5 from "./mbc5";

export default class RUMBLE extends MBC5 {
writeRAMBank(address, data) {
writeRAMBank(address: number, data: number) {
// MBC5 RAM bank switching
// Like MBC5, but bit 3 of the lower nibble is used for rumbling and bit 2 is ignored.
// console.log((data & 0x03).toString(2));
this.currentMBCRAMBank = data & 0x03;
this.currentRAMBankPosition = (this.currentMBCRAMBank << 13) - 0xa000;
if (data & 0x08) this.emit("rumble");
data &= 0x7;

super.writeRAMBank(address, data);
}
}
8 changes: 3 additions & 5 deletions src/core/cartridge/mbc5.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,9 @@ export default class MBC5 extends MBC {
this.setCurrentROMBank();
}

writeRAMBank(address, data) {
writeRAMBank(address: number, value: number) {
// MBC5 RAM bank switching
this.currentMBCRAMBank = data & 0xf;
this.currentRAMBankPosition = (
this.currentMBCRAMBank << 13
) - 0xa000;
this.currentMBCRAMBank = value & 0xf;
this.currentRAMBankPosition = (this.currentMBCRAMBank << 13) - 0xa000;
}
}
9 changes: 5 additions & 4 deletions src/core/memory/Layout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ export const INTERNAL_RAM_BANK0_END = 0xCFFF;
export const INTERNAL_RAM_SWITCH_BANK_START = 0xD000;
export const INTERNAL_RAM_SWITCH_BANK_END = 0xDFFF;

export const ECHO_RAM_START = 0xE000; /* Mirrored Memory */
// Mirrored Memory
export const ECHO_RAM_START = 0xE000;
export const ECHO_RAM_END = 0xFDFF;

/*--------------- HIGH MEM-------------- */
Expand All @@ -61,9 +62,9 @@ export const ZERO_PAGE_END = 0xFFFE;

/* -------------------------------------*/

//Convert between local IO memory address and global address
// export const GLOBAL_TO_IO_ADDR(A) A - 0xFF00
// export const IO_TO_GLOBAL_ADDR(A) A + 0xFF00
// Convert between local IO memory address and global address
// export const GLOBAL_TO_IO_ADDR(A) A - 0xFF00
// export const IO_TO_GLOBAL_ADDR(A) A + 0xFF00

/* -------------IO ports/registers ------------------*/
export const JOYPAD_REG = 0xFF00; /* Register for reading joy pad info */
Expand Down
Loading

0 comments on commit 0909c89

Please sign in to comment.