936 lines
32 KiB
HTML
936 lines
32 KiB
HTML
<!DOCTYPE HTML>
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>Project64 JS API</title>
|
|
<link rel="shortcut icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAAAlwSFlzAAAOwwAADsMBx2+oZAAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xOdTWsmQAAAOgSURBVDhPZZJ9UNMFGMd/f9Vf3PB4uS3EyxDmTZTXWFIdZEsxmOImTS4Zc3O8jMHaCxsOAhFhgwYTOF7magwGswXuUJcOhgiCuBgQYJyBpFB3HL3cmZ11peA35FZd9bl7/vne9/Pc88dD/MUT/Bpz68ux+UuOKy0Gg5bkjf/Fvfvzwv5h102tVrvVGxHE1YX6F5e/Wy5vGaj/QzmdhKyeA2i0tiw5Hc4kb+VvxtxuQd5AEpov63/qtnanb4Yz38xMyRw8NDxKx0WINufM3UNQtkkwMDRkKqoq8tssbjA8MiIoX2Ch/mEqVBez0GRs0ROWcQM6NyQ7ZPjwi6MwfM9HNyQw/y7cuIaJVptxxel0sp8vGBkbE5y+y4H5mQCa5cOQnVZ4iK4JIzrWc9C1LobIlopLN3tROZkBy1oeOp6IUDLLQlGbHH0ul+3G8I2Sstnj+ORxFjSLaSgolnoIs7sZ1T8no+5RKjItb8Pe02s0tpusZdey8dEPLNT9eBSalVQcaXoL10cGn8lvs6Ff5UA98y5EqnwPcX60Afn3wyF7EIFUQzSufd6nWfp2qVZ/uxJZd6LwwXw0sid3Q1ibsd7aer6PP3gA0jk6eEMRyFbkeojGwVqwxsk45qEgUReGr+7MrZ4b1ILhCkHarWAkOyngVh5bV8gUuaOjozmH7PFgD4WA0bMVQlmOh6jrq0a8g4SEq76IObMdVy47ZnlVJx5HmkiI6fQBX5P5VCKR8KenJ5mW6x8/pLfvBN0WCFqrL07kn/QQOocWsdYgxF14CRHFYbB9ajsr4Ar2KKoK50TVeU8L5YUZU9MTp+qd1Wu79DuwrZGEl5tIoKi2oEApdRO6Xg0SO+hItMQhWhkFV79rUafTxVOpVB8Oh7P/3oMFc6ldgVd1UaDqQxFWF4IwKRWnyksWExISwgntZ2fxWkMc9jbREVkQDavdipJm9Zrtgq1h6uvxidw2LhKr38QbdfHYW0PHPvk7UKmL+slkcsDmd1V0liJEuR2h6lcQyqOivceMCDkNaRVH8F4tE3sU4YhQ7wZNthMpksMQi8V6Go32wqb8HNU5JUjpPvDjbUEQKximLhMC2H4IzPBH4Pv+IHMD4Z/mj+OyzN/4mXyhV/sHvlAoOShM+YWUTEIQMxg12pohcbFklZJCgW/KxuKDAcgpFK2wmKzXvcr/Ye5n7hDknxyOZMdCo9FoGQzGttKKMncCdx8kKqkndldssLf6HwjiT/PF9/HEYv4PAAAAAElFTkSuQmCC"/>
|
|
<link href='https://fonts.googleapis.com/css?family=Open+Sans:400,400italic,700,700italic' rel='stylesheet' type='text/css'>
|
|
<style>
|
|
body {
|
|
font-family: "Open Sans", segoe ui, tahoma, sans;
|
|
font-size: 14px;
|
|
background-color: #EEE;
|
|
}
|
|
a {
|
|
color: #494;
|
|
text-decoration: none;
|
|
font-weight: bold;
|
|
}
|
|
div.inline-content {
|
|
display: inline-block;
|
|
vertical-align: top;
|
|
}
|
|
div.panel {
|
|
background-color: #FFF;
|
|
padding: 10px;
|
|
border-top: 4px solid #FFAAAA;
|
|
margin-bottom: 10px;
|
|
box-shadow: -5px 5px 5px #DDD;
|
|
}
|
|
div.classname {
|
|
font-weight: bold;
|
|
font-size: 18px;
|
|
}
|
|
div.propertyname {
|
|
font-weight: bold;
|
|
}
|
|
div.property {
|
|
padding: 10px;
|
|
}
|
|
div.propertydesc {
|
|
padding: 10px;
|
|
}
|
|
pre.example {
|
|
background-color: #EFE;
|
|
border: 1px solid #BCB;
|
|
padding: 5px;
|
|
font-family: consolas, courier new, monospace;
|
|
white-space: pre;
|
|
margin: 10px;
|
|
font-size: 12px;
|
|
color: #020;
|
|
}
|
|
pre.example::before {
|
|
content: "Example";
|
|
float: right;
|
|
opacity: 0.5;
|
|
font-size: 11px;
|
|
font-family: "Open Sans", segoe ui, tahoma, sans;
|
|
}
|
|
span.snip {
|
|
background-color: #EFE;
|
|
border: 1px solid #BCB;
|
|
padding: 0px 2px;
|
|
font-size: 13px;
|
|
color: #020;
|
|
font-family: consolas, courier new, monospace;
|
|
border-radius: 3px;
|
|
}
|
|
span.tag {
|
|
float: right;
|
|
margin-left: 2px;
|
|
border: 2px solid #885;
|
|
border-radius: 5px;
|
|
background-color: #FFE;
|
|
color: #885;
|
|
font-weight: bold;
|
|
padding: 0px 2px;
|
|
font-size: 11px;
|
|
}
|
|
span.tag2 {
|
|
float: right;
|
|
margin-left: 2px;
|
|
border: 2px solid #588;
|
|
border-radius: 5px;
|
|
background-color: #EFF;
|
|
color: #588;
|
|
font-weight: bold;
|
|
padding: 0px 2px;
|
|
font-size: 11px;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div style="margin: 10px; font-size: 24px;">Project64 Javascript API</div>
|
|
<div class="inline-content" style="width: 150px; min-width: 150px; margin-left: 10px;">
|
|
<div class="panel" id="sidebar" style="width: 120px; position: absolute;">
|
|
<a href="#mem">mem</a><br>
|
|
<a href="#rom">rom</a><br>
|
|
<a href="#events">events</a><br>
|
|
<a href="#debug">debug</a><br>
|
|
<a href="#asm">asm</a><br>
|
|
<a href="#console">console</a><br>
|
|
<a href="#fs">fs</a><br>
|
|
<a href="#fs.Stats">fs.Stats</a><br>
|
|
<a href="#alert">alert</a><br>
|
|
<a href="#screen">screen</a><br>
|
|
<a href="#gpr">gpr</a><br>
|
|
<a href="#ugpr">ugpr</a><br>
|
|
<a href="#fpr">fpr</a><br>
|
|
<a href="#dfpr">dfpr</a><br>
|
|
<a href="#cop0">cop0</a><br>
|
|
<a href="#Server">Server</a><br>
|
|
<a href="#Socket">Socket</a><br>
|
|
<a href="#AddressRange">AddressRange</a><br>
|
|
<a href="#Number">Number</a><br>
|
|
</div>
|
|
</div>
|
|
<div class="inline-content" style="max-width: 700px;">
|
|
<div class="panel" id="mem">
|
|
<div class="classname">mem</div>
|
|
<div class="property">
|
|
<div class="propertyname">mem.u8|u16|u32|s8|s16|s32|float|double</div>
|
|
<div class="propertydesc">
|
|
Arrays for reading and modifying values in virtual memory.
|
|
Virtual addresses are always used for indeces regardless of type size.
|
|
<pre class="example">
|
|
var addr_power = 0x8033B21E
|
|
|
|
if(mem.u8[addr_power] < 1)
|
|
{
|
|
mem.u8[addr_power] = 8
|
|
}
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
<div class="property">
|
|
<div class="propertyname">mem.getblock(baseAddr, size)</div>
|
|
<div class="propertydesc">
|
|
Returns a Buffer object from a block of data of <span class="snip">size</span> bytes at <span class="snip">baseAddr</span> in virtual memory.
|
|
</div>
|
|
</div>
|
|
<div class="property">
|
|
<div class="propertyname">mem.getstring(baseAddr[, maxLen])</div>
|
|
<div class="propertydesc">
|
|
Returns a string from a zero-terminated ASCII string at <span class="snip">baseAddr</span> in virtual memory.
|
|
</div>
|
|
</div>
|
|
<div class="property">
|
|
<div class="propertyname">mem.bindvar(obj, baseAddr, name, type)</div>
|
|
<div class="propertydesc">
|
|
Adds property <span class="snip">name</span> to <span class="snip">obj</span> and "binds" it to the virtual address specified by <span class="snip">baseAddr</span>.
|
|
Valid types are: <span class="snip">u8</span>, <span class="snip">u16</span>, <span class="snip">u32</span>, <span class="snip">s8</span>, <span class="snip">s16</span>, <span class="snip">s32</span>, <span class="snip">float</span>, and <span class="snip">double</span>.
|
|
<pre class="example">
|
|
mem.bindvar(this, 0x8033B21E, 'power', u8)
|
|
|
|
if(power < 1)
|
|
{
|
|
power = 8
|
|
}
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
<div class="property">
|
|
<div class="propertyname">mem.bindvars(obj, vars)</div>
|
|
<div class="propertydesc">
|
|
Adds multiple virtual memory-bound properties to <span class="snip">obj</span>.
|
|
Returns <span class="snip">obj</span>.
|
|
<pre class="example">
|
|
var mario = mem.bindvars({},
|
|
[
|
|
[0x8033B1B0, 'y', float],
|
|
[0x8033B21E, 'power', u8]
|
|
])
|
|
|
|
mario.power = 5
|
|
mario.y = 500.00
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
<div class="property">
|
|
<div class="propertyname">mem.bindstruct(obj, baseAddr, props)</div>
|
|
<div class="propertydesc">
|
|
Adds multiple virtual memory-bound properties to <span class="snip">obj</span>.
|
|
Addresses are determined by type sizes.
|
|
Returns <span class="snip">obj</span>.
|
|
<pre class="example">
|
|
var marioPos = mem.bindstruct(this, 0x8033B1AC,
|
|
{
|
|
x: float,
|
|
y: float,
|
|
z: float
|
|
})
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
<div class="property">
|
|
<div class="propertyname">mem.typedef(props)</div>
|
|
<div class="propertydesc">
|
|
Returns a "struct" class that may be constructed using the address of a real struct in virtual memory.
|
|
<pre class="example">
|
|
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()
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<div class="panel" id="rom">
|
|
<div class="classname">rom</div>
|
|
<div class="property">
|
|
<div class="propertyname">rom.u8|u16|u32|s8|s16|s32|float|double</div>
|
|
<div class="propertydesc">
|
|
Arrays for reading values in cartridge ROM. Indexing works in a similar manner to <a href="#mem">mem</a>'s.
|
|
<pre class="example">
|
|
var crc1 = rom.u32[0x00000010]
|
|
var crc2 = rom.u32[0x00000014]
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
<div class="property">
|
|
<div class="propertyname">rom.getblock(baseAddr, size)</div>
|
|
<div class="propertydesc">
|
|
Returns a Buffer object from a block of data of size bytes at <span class="snip">baseAddr</span> in cartridge ROM.
|
|
</div>
|
|
</div>
|
|
<div class="property">
|
|
<div class="propertyname">rom.getstring(baseAddr[, maxLen])</div>
|
|
<div class="propertydesc">
|
|
Returns a string from a zero-terminated ASCII string at <span class="snip">baseAddr</span> in cartridge ROM.
|
|
<pre class="example">
|
|
var romName = rom.getstring(0x00000020)
|
|
console.log('Internal ROM name: ' + romName)</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<div class="panel" id="events">
|
|
<div class="classname">events</div>
|
|
<!--
|
|
<div class="property">
|
|
<div class="propertyname">events.on(hook, callback, tag)</div>
|
|
<div class="propertydesc">
|
|
<pre class="example"></pre>
|
|
</div>
|
|
</div>-->
|
|
<div class="property">
|
|
<span class="tag2">emulation thread</span>
|
|
<span class="tag">interpreter mode only</span>
|
|
<div class="propertyname">events.onexec(address, callback)</div>
|
|
<div class="propertydesc">
|
|
Adds a CPU execution callback for a virtual address or <a href="#AddressRange">AddressRange</a> and returns a callback ID.
|
|
<span class="snip">callback</span> will be invoked at the beginning of a CPU step if the program counter is at <span class="snip">address</span>.
|
|
<span class="snip">callback</span> receives the program counter address at which the event is fired.
|
|
<pre class="example">
|
|
events.onexec(0x802CB1C0, function()
|
|
{
|
|
console.log('CPU is calling 0x802CB1C0')
|
|
})
|
|
</pre>
|
|
<pre class="example">
|
|
events.onexec(ADDR_ANY, function(pc))
|
|
{
|
|
// Log every step!
|
|
console.log('CPU is executing 0x' + pc.hex())
|
|
})
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
<div class="property">
|
|
<span class="tag2">emulation thread</span>
|
|
<span class="tag">interpreter mode only</span>
|
|
<div class="propertyname">events.onread(address, callback)</div>
|
|
<div class="propertydesc">
|
|
Adds a CPU read callback for a virtual address or <a href="#AddressRange">AddressRange</a> and returns a callback ID.
|
|
<span class="snip">callback</span> will be invoked at the beginning of a CPU step if the current instruction is going to read from <span class="snip">address</span>.
|
|
<span class="snip">callback</span> receives the virtual address that the CPU is going to read.
|
|
<pre class="example">
|
|
events.onread(0x8033B1B0, function()
|
|
{
|
|
console.log('CPU is reading 0x8033B1B0')
|
|
})
|
|
</pre>
|
|
<pre class="example">
|
|
events.onread(ADDR_ANY_CART_ROM_UNC, function(addr)
|
|
{
|
|
console.log('CPU is reading ROM 0x' + addr.hex())
|
|
})
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
<div class="property">
|
|
<span class="tag2">emulation thread</span>
|
|
<span class="tag">interpreter mode only</span>
|
|
<div class="propertyname">events.onwrite(address, callback)</div>
|
|
<div class="propertydesc">
|
|
Adds a CPU write callback for a virtual address or <a href="#AddressRange">AddressRange</a> and returns a callback ID.
|
|
<span class="snip">callback</span> will be invoked at the beginning of a CPU step if the current instruction is going to write to <span class="snip">address</span>.
|
|
<span class="snip">callback</span> receives the virtual address that the CPU is going to write to.
|
|
<pre class="example">
|
|
events.onwrite(0x8033B1B0, function()
|
|
{
|
|
console.log('CPU is modifying 0x8033B1B0')
|
|
})
|
|
</pre>
|
|
<pre class="example">
|
|
events.onwrite(ADDR_ANY_CART_ROM_UNC, function(addr)
|
|
{
|
|
console.log(gpr.pc.hex() + ': wrote to cartridge ' + addr.hex())
|
|
})
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
<div class="property">
|
|
<span class="tag2">emulation thread</span>
|
|
<span class="tag">interpreter mode only</span>
|
|
<div class="propertyname">events.onopcode(address, opcode, callback)</div>
|
|
<div class="propertydesc">
|
|
Adds a CPU execution callback for a virtual address or <a href="#AddressRange">AddressRange</a> and returns a callback ID.
|
|
<span class="snip">callback</span> will be invoked at the beginning of a CPU step if the program counter is at <span class="snip">address</span> and <span class="snip">opcode</span> is equal to the opcode to be executed.
|
|
<span class="snip">callback</span> receives the program counter address at which the event is fired.
|
|
<pre class="example">
|
|
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'
|
|
})
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
<div class="property">
|
|
<span class="tag2">emulation thread</span>
|
|
<span class="tag">interpreter mode only</span>
|
|
<div class="propertyname">events.onopcode(address, opcode, mask, callback)</div>
|
|
<div class="propertydesc">
|
|
Adds a CPU execution callback for a virtual address or <a href="#AddressRange">AddressRange</a> and returns a callback ID.
|
|
<span class="snip">callback</span> will be invoked at the beginning of a CPU step if the program counter is at <span class="snip">address</span> and <span class="snip">opcode</span> is equal to the opcode to be executed ANDed with <span class="snip">mask</span>.
|
|
<span class="snip">callback</span> receives the program counter address at which the event is fired.
|
|
<pre class="example">
|
|
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())
|
|
})
|
|
</pre>
|
|
<pre class="example">
|
|
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())
|
|
})
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
<div class="property">
|
|
<span class="tag2">emulation thread</span>
|
|
<span class="tag">interpreter mode only</span>
|
|
<div class="propertyname">events.ongprvalue(address, registers, value, callback)</div>
|
|
<div class="propertydesc">
|
|
Adds a CPU execution callback for a virtual address or <a href="#AddressRange">AddressRange</a> and returns a callback ID.
|
|
<span class="snip">callback</span> will be invoked at the beginning of a CPU step if the program counter is at <span class="snip">address</span> and the lower 32 bits of the general purpose registers specified by <span class="snip">registers</span> are equal to <span class="snip">value</span>.
|
|
<span class="snip">callback</span> receives the program counter address at which the event is fired, and the index of the first register that contains the value.
|
|
<pre class="example">
|
|
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))
|
|
})
|
|
</pre>
|
|
<pre class="example">
|
|
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))
|
|
})
|
|
</pre>
|
|
Valid registers:
|
|
<pre style="font-size: 13px;">
|
|
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
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
<div class="property">
|
|
<span class="tag2">emulation thread</span>
|
|
<div class="propertyname">events.ondraw(callback)</div>
|
|
<div class="propertydesc">
|
|
Adds a callback which will be invoked immediately after Project64 requests a screen update from the graphics plugin.
|
|
Returns a callback ID.
|
|
<pre class="example">
|
|
events.ondraw(function()
|
|
{
|
|
console.log('Frame drawn')
|
|
})
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
<div class="property">
|
|
<div class="propertyname">events.remove(callbackId)</div>
|
|
<div class="propertydesc">
|
|
Removes a registered callback by its ID.
|
|
<pre class="example">
|
|
var callbackId = events.onexec(0x80000180, function()
|
|
{
|
|
// Only invoked once
|
|
console.log('Interrupt fired')
|
|
events.remove(callbackId)
|
|
})
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
<!-- template
|
|
<div class="property">
|
|
<div class="propertyname"></div>
|
|
<div class="propertydesc">
|
|
<pre class="example"></pre>
|
|
</div>
|
|
</div>
|
|
-->
|
|
</div>
|
|
|
|
<div class="panel" id="debug">
|
|
<div class="classname">debug</div>
|
|
<div class="property">
|
|
<div class="propertyname">debug.breakhere()</div>
|
|
<div class="propertydesc">
|
|
Pauses emulation and opens the debugger window. Useful for creating conditional breakpoints.
|
|
<pre class="example">
|
|
events.onexec(0x802CB1C0, function()
|
|
{
|
|
if(gpr.a0 == 0)
|
|
{
|
|
console.log('0 passed to 0x802CB1C0, breaking')
|
|
debug.breakhere()
|
|
}
|
|
})
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="panel" id="asm">
|
|
<div class="classname">asm</div>
|
|
<div class="property">
|
|
<div class="propertyname">asm.gprname(regIndex)</div>
|
|
<div class="propertydesc">
|
|
Returns the name of the general purpose register specified by <span class="snip">regIndex</span>.
|
|
<pre class="example">
|
|
asm.gprname(4) // 'a0'
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="panel" id="fs">
|
|
<div class="classname">fs</div>
|
|
<div class="property">
|
|
<div class="propertyname">fs.open(path, mode)</div>
|
|
<div class="propertydesc">
|
|
Opens the file pointed to by <span class="snip">path</span> in the mode specified by <span class="snip">mode</span>.
|
|
Returns a file descriptor on success or <span class="snip">false</span> if the operation failed.
|
|
<pre class="example">var fd = fs.open('log.txt', 'w')</pre>
|
|
|
|
Valid modes:
|
|
|
|
<pre>
|
|
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.
|
|
|
|
<a href="http://pubs.opengroup.org/onlinepubs/009695399/functions/fopen.html">http://pubs.opengroup.org/onlinepubs/009695399/functions/fopen.html</a>
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
<div class="property">
|
|
<div class="propertyname">fs.close(fd)</div>
|
|
<div class="propertydesc">
|
|
Closes the file referenced by <span class="snip">fd</span>.
|
|
</div>
|
|
</div>
|
|
<div class="property">
|
|
<div class="propertyname">fs.write(fd, buffer[, offset[, length[, position]]])</div>
|
|
<div class="propertydesc">
|
|
Writes <span class="snip">buffer</span> to the file referenced by <span class="snip">fd</span>. Returns the number of bytes written.
|
|
<pre class="example">var fd = fs.open('log.txt', 'w')
|
|
fs.write(fd, 'Hello world!\n')
|
|
fs.close(fd)</pre>
|
|
<pre class="example">var buf = mem.getblock(0x8033B400, 4 * 32)
|
|
var fd = fs.open('data.bin', 'wb')
|
|
fs.write(fd, buf)
|
|
fs.close(fd)</pre>
|
|
</div>
|
|
</div>
|
|
<div class="property">
|
|
<div class="propertyname">fs.writeFile(path, buffer)</div>
|
|
<div class="propertydesc">
|
|
Writes <span class="snip">buffer</span> to the file pointed to by <span class="snip">path</span>.
|
|
Returns <span class="snip">true</span> if the operation was successful or <span class="snip">false</span> if the operation failed.
|
|
</div>
|
|
</div>
|
|
<div class="property">
|
|
<div class="propertyname">fs.read(fd, buffer, offset, length, position)</div>
|
|
<div class="propertydesc">
|
|
Reads the file referenced by <span class="snip">fd</span> into <span class="snip">buffer</span>. Returns the number of bytes read.
|
|
<pre class="example">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)</pre>
|
|
</div>
|
|
</div>
|
|
<div class="property">
|
|
<div class="propertyname">fs.readFile(path)</div>
|
|
<div class="propertydesc">
|
|
Reads the file pointed to by <span class="snip">path</span>. Returns a Buffer object representing the file, or <span class="snip">false</span> if the operation failed.
|
|
</div>
|
|
</div>
|
|
<div class="property">
|
|
<div class="propertyname">fs.fstat(fd)</div>
|
|
<div class="propertydesc">
|
|
Returns an <a href="#fs.Stats">fs.Stats</a> object describing the file referenced by <span class="snip">fd</span>.
|
|
<pre class="example">var stats = fs.fstat(fd)
|
|
console.log('size: ' + stats.size)
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
<div class="property">
|
|
<div class="propertyname">fs.stat(path)</div>
|
|
<div class="propertydesc">
|
|
Returns an <a href="#fs.Stats">fs.Stats</a> object describing the file or directory pointed to by <span class="snip">path</span>. Returns <span class="snip">false</span> if the operation failed.
|
|
</div>
|
|
</div>
|
|
<div class="property">
|
|
<div class="propertyname">fs.unlink(path)</div>
|
|
<div class="propertydesc">Deletes a file. Returns <span class="snip">true</span> if the operation was successful.</div>
|
|
</div>
|
|
<div class="property">
|
|
<div class="propertyname">fs.mkdir(path)</div>
|
|
<div class="propertydesc">Creates a directory. Returns <span class="snip">true</span> if the operation was successful.</div>
|
|
</div>
|
|
<div class="property">
|
|
<div class="propertyname">fs.rmdir(path)</div>
|
|
<div class="propertydesc">Removes a directory. The directory must be empty. Returns <span class="snip">true</span> if the operation was successful.</div>
|
|
</div>
|
|
<div class="property">
|
|
<div class="propertyname">fs.readdir(path)</div>
|
|
<div class="propertydesc">
|
|
Returns an array of file names in the directory pointed to by <span class="snip">path</span>.
|
|
Returns <span class="snip">false</span> if the operation failed.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="panel" id="fs.Stats">
|
|
<div class="classname">fs.Stats</div>
|
|
<div class="propertydesc">
|
|
<table>
|
|
<tr><td><b>stats.dev</b> </td><td> ID of the device the file resides on</td></tr>
|
|
<tr><td><b>stats.ino</b> </td><td> inode number</td></tr>
|
|
<tr><td><b>stats.mode</b> </td><td> File permissions</td></tr>
|
|
<tr><td><b>stats.nlink</b> </td><td> Number of links to the file</td></tr>
|
|
<tr><td><b>stats.uid</b> </td><td> User ID</td></tr>
|
|
<tr><td><b>stats.gid</b> </td><td> Group ID</td></tr>
|
|
<tr><td><b>stats.rdev</b> </td><td> Device ID (if file is character or block special)</td></tr>
|
|
<tr><td><b>stats.size</b> </td><td> Size of the file in bytes</td></tr>
|
|
<tr><td><b>stats.atimeMs</b> </td><td> Last access timestamp in milliseconds</td></tr>
|
|
<tr><td><b>stats.mtimeMs</b> </td><td> Last modification timestamp in milliseconds</td></tr>
|
|
<tr><td><b>stats.ctimeMs</b> </td><td> Creation timestamp in milliseconds</td></tr>
|
|
<tr><td><b>stats.atime</b> </td><td> JS Date object representing the last access time</td></tr>
|
|
<tr><td><b>stats.mtime</b> </td><td> JS Date object representing the last modification time</td></tr>
|
|
<tr><td><b>stats.ctime</b> </td><td> JS Date object representing the creation time</td></tr>
|
|
</table>
|
|
</div>
|
|
<div class="property">
|
|
<div class="propertyname">stats.isDirectory()</div>
|
|
<div class="propertydesc">
|
|
Returns <span class="snip">true</span> if the <a href="#fs.Stats">fs.Stats</a> object describes a directory.
|
|
</div>
|
|
</div>
|
|
<div class="property">
|
|
<div class="propertyname">stats.isFile()</div>
|
|
<div class="propertydesc">
|
|
Returns <span class="snip">true</span> if the <a href="#fs.Stats">fs.Stats</a> object describes a regular file.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="panel" id="console">
|
|
<div class="classname">console</div>
|
|
<div class="property">
|
|
<div class="propertyname">console.print(text)</div>
|
|
<div class="propertydesc">
|
|
Prints text to the script console.
|
|
<pre class="example">console.print('Hello world\n')</pre>
|
|
</div>
|
|
</div>
|
|
<div class="property">
|
|
<div class="propertyname">console.log(text[, text2, ...])</div>
|
|
<div class="propertydesc">
|
|
Concatenates all provided text arguments with spaces and prints the result to the script console with a trailing newline.
|
|
<pre class="example">console.log('Hello', 'world')</pre>
|
|
</div>
|
|
</div>
|
|
<div class="property">
|
|
<div class="propertyname">console.clear()</div>
|
|
<div class="propertydesc">
|
|
Clears all previously printed text from the script console.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="panel" id="alert">
|
|
<div class="classname">alert</div>
|
|
<div class="property">
|
|
<div class="propertyname">alert(message[, caption])</div>
|
|
<div class="propertydesc">
|
|
Shows a message box with an optional caption.
|
|
The calling thread will be blocked until the message box is dismissed.
|
|
<pre class="example">
|
|
alert('Hello world') // Blocks the script's thread
|
|
|
|
events.onexec(0x80000180, function()
|
|
{
|
|
alert('Interrupt fired!') // Blocks the emulation thread
|
|
})</pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="panel" id="screen">
|
|
<div class="classname">screen</div>
|
|
<div class="property">
|
|
<div class="propertyname">screen.print(x, y, text)</div>
|
|
<div class="propertydesc">
|
|
Prints <span class="snip">text</span> to the screen at the provided <span class="snip">x</span> and <span class="snip">y</span> coordinates.
|
|
Should be called from an <span class="snip">events.ondraw</span> callback.
|
|
<b>(Unstable!)</b>
|
|
<pre class="example">
|
|
events.ondraw(function()
|
|
{
|
|
screen.print(20, 20, 'power: ' + mem.u8[0x8033B21E])
|
|
})</pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="panel" id="gpr">
|
|
<div class="classname">gpr</div>
|
|
<div class="property">
|
|
<div class="propertyname">gpr.r0|at|v0|v1|a0 ...</div>
|
|
<div class="propertyname">gpr[0|1|2 ...]</div>
|
|
<div class="propertydesc">
|
|
Variables representing the lower 32 bits of each general purpose register.
|
|
<pre class="example">
|
|
events.onexec(0x802CB1C0, function()
|
|
{
|
|
if(gpr.a0 == 2)
|
|
{
|
|
gpr.a0 = 3
|
|
}
|
|
})
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
<div class="property">
|
|
<div class="propertyname">gpr.pc</div>
|
|
<div class="propertydesc">
|
|
Variable representing the CPU's program counter.
|
|
</div>
|
|
</div>
|
|
<div class="property">
|
|
<div class="propertyname">gpr.hi</div>
|
|
<div class="propertydesc">
|
|
Variable representing the lower 32 bits of the HI register.
|
|
</div>
|
|
</div>
|
|
<div class="property">
|
|
<div class="propertyname">gpr.lo</div>
|
|
<div class="propertydesc">
|
|
Variable representing the lower 32 bits of the LO register.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="panel" id="ugpr">
|
|
<div class="classname">ugpr</div>
|
|
<div class="property">
|
|
<div class="propertyname">ugpr.r0|at|v0|v1|a0 ...</div>
|
|
<div class="propertyname">ugpr[0|1|2 ...]</div>
|
|
<div class="propertydesc">
|
|
Variables representing the upper 32 bits of each general purpose register.
|
|
</div>
|
|
</div>
|
|
<div class="property">
|
|
<div class="propertyname">ugpr.hi</div>
|
|
<div class="propertydesc">
|
|
Variable representing the upper 32 bits of the HI register.
|
|
</div>
|
|
</div>
|
|
<div class="property">
|
|
<div class="propertyname">ugpr.lo</div>
|
|
<div class="propertydesc">
|
|
Variable representing the upper 32 bits of the LO register.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="panel" id="fpr">
|
|
<div class="classname">fpr</div>
|
|
<div class="property">
|
|
<div class="propertyname">fpr.f0|f1|f2|f3|f4 ...</div>
|
|
<div class="propertyname">fpr[0|1|2 ...]</div>
|
|
<div class="propertydesc">
|
|
Variables representing the 32-bit floating point registers.
|
|
<pre class="example">
|
|
events.onexec(0x802CB1C0, function()
|
|
{
|
|
if(gpr.f0 == 2.0)
|
|
{
|
|
gpr.f0 = 3.0
|
|
}
|
|
})
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="panel" id="dfpr">
|
|
<div class="classname">dfpr</div>
|
|
<div class="property">
|
|
<div class="propertyname">dfpr.f0|f2|f4|f6 ...</div>
|
|
<div class="propertyname">dfpr[0|2|4 ...]</div>
|
|
<div class="propertydesc">
|
|
Variables representing the 64-bit floating point registers.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="panel" id="cop0">
|
|
<div class="classname">cop0</div>
|
|
<div class="property">
|
|
<div class="propertyname">cop0.cause</div>
|
|
<div class="propertydesc">
|
|
Variable representing the Cause register. Updates interrupts when written.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<div class="panel" id="Server">
|
|
<div class="classname">Server</div>
|
|
<div class="property">
|
|
<div class="propertyname">new Server(settings)</div>
|
|
<div class="propertydesc">
|
|
Creates a new server socket.
|
|
If <span class="snip">port</span> is provided in <span class="snip">settings</span>, the server will start listening immediately.
|
|
<pre class="example">var server = new Server({port: 80})</pre>
|
|
</div>
|
|
</div>
|
|
<div class="property">
|
|
<div class="propertyname">server.listen(port)</div>
|
|
<div class="propertydesc">
|
|
Binds the server socket to a port and starts listening.
|
|
</div>
|
|
</div>
|
|
<div class="property">
|
|
<div class="propertyname">server.on('connection', callback)</div>
|
|
<div class="propertydesc">
|
|
Starts accepting clients.
|
|
When a client is accepted, a Socket object for it is created and passed to <span class="snip">callback</span>.
|
|
<pre class="example">
|
|
server.on('connection', function(socket)
|
|
{
|
|
socket.on('data', function(data)
|
|
{
|
|
socket.write('hello')
|
|
})
|
|
})</pre>
|
|
</div>
|
|
</div>
|
|
<!--
|
|
server.listen(port)
|
|
server.on(evt, callback)
|
|
'connection' -> callback(socket)-->
|
|
</div>
|
|
|
|
<div class="panel" id="Socket">
|
|
<div class="classname">Socket</div>
|
|
<div class="property">
|
|
<div class="propertyname">new Socket([fd])</div>
|
|
<div class="propertydesc">
|
|
Creates a new socket object.
|
|
</div>
|
|
</div>
|
|
<div class="property">
|
|
<div class="propertyname">socket.connect(settings[, callback])</div>
|
|
<div class="propertydesc">
|
|
Connects the socket to the <span class="snip">host</span> and <span class="snip">port</span> specified by the <span class="snip">settings</span> object.
|
|
The default values for the host and port are <span class="snip">"127.0.0.1"</span> and <span class="snip">80</span> respectively.
|
|
</div>
|
|
</div>
|
|
<div class="property">
|
|
<div class="propertyname">socket.write(data[, callback])</div>
|
|
<div class="propertydesc">
|
|
Writes <span class="snip">data</span> to the socket.
|
|
</div>
|
|
</div>
|
|
<div class="property">
|
|
<div class="propertyname">socket.on('data', callback)</div>
|
|
<div class="propertydesc">
|
|
Starts reading data from the socket asynchronously. When data arrives, it is passed to <span class="snip">callback</span> as a Buffer object.
|
|
<!--<pre class="example"></pre>-->
|
|
</div>
|
|
</div>
|
|
<div class="property">
|
|
<div class="propertyname">socket.on('close', callback)</div>
|
|
<div class="propertydesc">
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="panel" id="AddressRange">
|
|
<div class="classname">AddressRange</div>
|
|
<div class="property">
|
|
<div class="propertyname">new AddressRange(start, end)</div>
|
|
<div class="propertydesc">
|
|
Creates an immutable object with <span class="snip">start</span> and <span class="snip">end</span> address properties.<br>
|
|
The following <b>AddressRange</b> objects are defined globally:
|
|
<pre>
|
|
<b>ADDR_ANY</b> 0x00000000 : 0xFFFFFFFF Any 32-bit address
|
|
|
|
<b>ADDR_ANY_KUSEG</b> 0x00000000 : 0x7FFFFFFF MIPS user mode TLB mapped segment
|
|
<b>ADDR_ANY_KSEG0</b> 0x80000000 : 0x9FFFFFFF MIPS cached unmapped segment
|
|
<b>ADDR_ANY_KSEG1</b> 0xA0000000 : 0xBFFFFFFF MIPS uncached unmapped segment
|
|
<b>ADDR_ANY_KSEG2</b> 0xC0000000 : 0xFFFFFFFF MIPS kernel mode TLB mapped segment
|
|
|
|
<b>ADDR_ANY_RDRAM</b> 0x80000000 : 0x807FFFFF Cached RDRAM
|
|
<b>ADDR_ANY_RDRAM_UNC</b> 0xA0000000 : 0xA07FFFFF Uncached RDRAM
|
|
|
|
<b>ADDR_ANY_CART_ROM</b> 0x90000000 : 0x95FFFFFF Cached cartridge ROM
|
|
<b>ADDR_ANY_CART_ROM_UNC</b> 0xB0000000 : 0xB5FFFFFF Uncached cartridge ROM
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="panel" id="Number">
|
|
<div class="classname">Number</div>
|
|
<div class="property">
|
|
<div class="propertyname">number.hex([nChars])</div>
|
|
<div class="propertydesc">
|
|
Returns a hexadecimal string representation of the number object. The resulting string is prepended with zeroes until its character length meets <span class="snip">nChars</span> or 8 by default.
|
|
<pre class="example">
|
|
var sm64EntryPC = rom.u32[0x00000008]
|
|
console.log('Entry: ' + sm64EntryPC.hex()) // "Entry: 80246000"</pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!--
|
|
<div class="panel">
|
|
alert(message)<br>
|
|
_native<br>
|
|
_native.addCallback(hook, callback, tag)<br>
|
|
_native.setGPRVal(regnum, val)<br>
|
|
_native.getGPRVal(regnum)<br>
|
|
_native.getRDRAMInt(address, bitWidth)<br>
|
|
_native.setRDRAMInt(address, bitWidth, val)<br>
|
|
_native.getRDRAMFloat(address[, bDouble])<br>
|
|
_native.setRDRAMFloat(address, val[, bDouble])<br>
|
|
_native.sockCreate(port)<br>
|
|
_native.sockListen(fd)<br>
|
|
_native.sockAccept(fd)<br>
|
|
_native.sockRead(fd, callback)<br>
|
|
_native.sockWrite(fd, data, callback)<br>
|
|
_native.msgBox(message[, caption])<br>
|
|
</div>
|
|
-->
|
|
</div>
|
|
|
|
<script>
|
|
(function(){
|
|
var domSidebar = document.getElementById('sidebar');
|
|
var baseTop = domSidebar.getBoundingClientRect().top + window.scrollY;
|
|
document.onscroll = function(){
|
|
if(window.scrollY > baseTop) {
|
|
domSidebar.style.position = "fixed";
|
|
domSidebar.style.top = '0px';
|
|
} else {
|
|
domSidebar.style.position = "absolute";
|
|
domSidebar.style.top = baseTop + 'px';
|
|
}
|
|
}
|
|
})();
|
|
</script>
|
|
</body>
|
|
</html> |