var addr_power = 0x8033B21E
if(mem.u8[addr_power] < 1)
{
mem.u8[addr_power] = 8
}
mem.bindvar(this, 0x8033B21E, 'power', u8)
if(power < 1)
{
power = 8
}
var mario = mem.bindvars({},
[
[0x8033B1B0, 'y', float],
[0x8033B21E, 'power', u8]
])
mario.power = 5
mario.y = 500.00
var marioPos = mem.bindstruct(this, 0x8033B1AC,
{
x: float,
y: float,
z: float
})
const Player = mem.typedef(
{
health: u32,
x: float,
y: float,
z: float
})
Player.prototype.move = function(x, y, z)
{
this.x = x
this.y = y
this.z = z
}
Player.prototype.heal = function()
{
this.health = 100
}
var player = new Player(0x8033B1AC)
player.move(100, 200, 300)
player.heal()
var crc1 = rom.u32[0x00000010] var crc2 = rom.u32[0x00000014]
var romName = rom.getstring(0x00000020)
console.log('Internal ROM name: ' + romName)
events.onexec(0x802CB1C0, function()
{
console.log('CPU is calling 0x802CB1C0')
})
events.onexec(ADDR_ANY, function(pc)
{
// Log every step!
console.log('CPU is executing 0x' + pc.hex())
})
events.onread(0x8033B1B0, function()
{
console.log('CPU is reading 0x8033B1B0')
})
events.onread(ADDR_ANY_CART_ROM_UNC, function(addr)
{
console.log('CPU is reading ROM 0x' + addr.hex())
})
events.onwrite(0x8033B1B0, function()
{
console.log('CPU is modifying 0x8033B1B0')
})
events.onwrite(ADDR_ANY_CART_ROM_UNC, function(addr)
{
console.log(gpr.pc.hex() + ': wrote to cartridge ' + addr.hex())
})
const JR_RA = 0x03E00008 // 'jr ra' command
events.onopcode(ADDR_ANY, JR_RA, function(pc)
{
console.log(pc.hex()) // log pc at every 'jr ra'
})
const ADDIU_SP_SP = 0x27BD0000 // 'addiu sp, sp, 0x0000'
const NO_IMM16 = 0xFFFF0000 // mask off immediate field
events.onopcode(ADDR_ANY, ADDIU_SP_SP, NO_IMM16, function(pc)
{
// log pc at every 'addiu sp, sp, x' regardless of the immediate value
console.log(pc.hex())
})
const JAL = 0x0C000000 // 'jal 0x00000000'
const NO_TARGET = 0xFC000000 // mask off target field
events.onopcode(ADDR_ANY, JAL, NO_TARGET, function(pc)
{
// log pc at every 'jal' regardless of the target address
console.log(pc.hex())
})
events.ongprvalue(ADDR_ANY, GPR_ANY, 0x49533634, function(pc, reg)
{
// log pc whenever any general purpose register contains 0x49533634
console.log(pc.hex(), asm.gprname(reg))
})
events.ongprvalue(ADDR_ANY, GPR_A0 | GPR_A1, 0x00001234, function(pc, reg)
{
// log pc whenever A0 or A1 contains 0x00001234
console.log(pc.hex(), asm.gprname(reg))
})
Valid registers:
GPR_R0 GPR_AT GPR_V0 GPR_V1 GPR_A0 GPR_A1 GPR_A2 GPR_A3 GPR_T0 GPR_T1 GPR_T2 GPR_T3 GPR_T4 GPR_T5 GPR_T6 GPR_T7 GPR_S0 GPR_S1 GPR_S2 GPR_S3 GPR_S4 GPR_S5 GPR_S6 GPR_S7 GPR_T8 GPR_T9 GPR_K0 GPR_K1 GPR_GP GPR_SP GPR_FP GPR_RA GPR_ANY_ARG -- Any of the 'A' registers GPR_ANY_TEMP -- Any of the 'T' registers GPR_ANY_SAVE -- Any of the 'S' registers GPR_ANY -- Any register
events.ondraw(function()
{
console.log('Frame drawn')
})
var callbackId = events.onexec(0x80000180, function()
{
// Only invoked once
console.log('Interrupt fired')
events.remove(callbackId)
})
events.onexec(0x802CB1C0, function()
{
if(gpr.a0 == 0)
{
console.log('0 passed to 0x802CB1C0, breaking')
debug.breakhere()
}
})
asm.gprname(4) // 'a0'
var fd = fs.open('log.txt', 'w')
Valid modes:
r or rb Open file for reading. w or wb Truncate to zero length or create file for writing. a or ab Append; open or create file for writing at end-of-file. r+ or rb+ or r+b Open file for update (reading and writing). w+ or wb+ or w+b Truncate to zero length or create file for update. a+ or ab+ or a+b Append; open or create file for update, writing at end-of-file. http://pubs.opengroup.org/onlinepubs/009695399/functions/fopen.html
var fd = fs.open('log.txt', 'w')
fs.write(fd, 'Hello world!\n')
fs.close(fd)
var buf = mem.getblock(0x8033B400, 4 * 32)
var fd = fs.open('data.bin', 'wb')
fs.write(fd, buf)
fs.close(fd)
var buf = new Buffer(128)
var fd = fs.open('data.bin', 'rb')
var nBytesRead = fs.read(fd, buf, 0, buf.length, 0)
fs.close(fd)
var stats = fs.fstat(fd)
console.log('size: ' + stats.size)
| stats.dev | ID of the device the file resides on |
| stats.ino | inode number |
| stats.mode | File permissions |
| stats.nlink | Number of links to the file |
| stats.uid | User ID |
| stats.gid | Group ID |
| stats.rdev | Device ID (if file is character or block special) |
| stats.size | Size of the file in bytes |
| stats.atimeMs | Last access timestamp in milliseconds |
| stats.mtimeMs | Last modification timestamp in milliseconds |
| stats.ctimeMs | Creation timestamp in milliseconds |
| stats.atime | JS Date object representing the last access time |
| stats.mtime | JS Date object representing the last modification time |
| stats.ctime | JS Date object representing the creation time |
console.print('Hello world\n')
console.log('Hello', 'world')
alert('Hello world') // Blocks the script's thread
events.onexec(0x80000180, function()
{
alert('Interrupt fired!') // Blocks the emulation thread
})
events.ondraw(function()
{
screen.print(20, 20, 'power: ' + mem.u8[0x8033B21E])
})
events.onexec(0x802CB1C0, function()
{
if(gpr.a0 == 2)
{
gpr.a0 = 3
}
})
events.onexec(0x802CB1C0, function()
{
if(gpr.f0 == 2.0)
{
gpr.f0 = 3.0
}
})
var server = new Server({port: 80})
server.on('connection', function(socket)
{
socket.on('data', function(data)
{
socket.write('hello')
})
})
ADDR_ANY 0x00000000 : 0xFFFFFFFF Any 32-bit address ADDR_ANY_KUSEG 0x00000000 : 0x7FFFFFFF MIPS user mode TLB mapped segment ADDR_ANY_KSEG0 0x80000000 : 0x9FFFFFFF MIPS cached unmapped segment ADDR_ANY_KSEG1 0xA0000000 : 0xBFFFFFFF MIPS uncached unmapped segment ADDR_ANY_KSEG2 0xC0000000 : 0xFFFFFFFF MIPS kernel mode TLB mapped segment ADDR_ANY_RDRAM 0x80000000 : 0x807FFFFF Cached RDRAM ADDR_ANY_RDRAM_UNC 0xA0000000 : 0xA07FFFFF Uncached RDRAM ADDR_ANY_CART_ROM 0x90000000 : 0x95FFFFFF Cached cartridge ROM ADDR_ANY_CART_ROM_UNC 0xB0000000 : 0xB5FFFFFF Uncached cartridge ROM
var sm64EntryPC = rom.u32[0x00000008]
console.log('Entry: ' + sm64EntryPC.hex()) // "Entry: 80246000"