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"