Skip to content

Commit

Permalink
Start working on supporting the Z-Machine version 3 (#19)
Browse files Browse the repository at this point in the history
  • Loading branch information
curiousdannii committed Jul 27, 2016
1 parent 68be937 commit 6ede6f3
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 12 deletions.
2 changes: 1 addition & 1 deletion src/zvm.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
ZVM - the ifvms.js Z-Machine (versions 5 and 8)
ZVM - the ifvms.js Z-Machine (versions 3, 5 and 8)
===============================================
Copyright (c) 2016 The ifvms.js team
Expand Down
4 changes: 2 additions & 2 deletions src/zvm/disassembler.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ TODO:
*/

var AST = require( '../common/ast.js' ),
opcodes = require( './opcodes.js' );
var AST = require( '../common/ast.js' );

module.exports.disassemble = function()
{
var pc, offset, // Set in the loop below
memory = this.m,
opcodes = this.opcodes,
temp,
code,
opcode_class,
Expand Down
25 changes: 19 additions & 6 deletions src/zvm/opcodes.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,15 @@ opcode_builder = AST.opcode_builder,
simple_func = function( a ) { return '' + a; },

// Common opcodes
alwaysbranch = opcode_builder( AST.Brancher, function() { return 1; } ),
alwaysbranch = opcode_builder( Brancher, function() { return 1; } ),
not = opcode_builder( Storer, function( a ) { return 'e.S2U(~' + a + ')'; } ),

// Indirect storer opcodes - rather non-generic I'm afraid
// Not used for inc/dec
// @load (variable) -> (result)
// @pull (variable)
// @store (variable) value
Indirect = AST.Storer.subClass({
Indirect = Storer.subClass({
storer: 0,

post: function()
Expand Down Expand Up @@ -89,7 +90,10 @@ Incdec = Opcode.subClass({
/*eslint brace-style: "off" */
/*eslint indent: "off" */

module.exports = {
module.exports = function( version )
{

return {

/* je */ 1: opcode_builder( Brancher, function() { return arguments.length === 2 ? this.args( '===' ) : 'e.jeq(' + this.args() + ')'; } ),
/* jl */ 2: opcode_builder( Brancher, function( a, b ) { return a.U2S() + '<' + b.U2S(); } ),
Expand Down Expand Up @@ -135,18 +139,25 @@ module.exports = {
/* jump */ 140: opcode_builder( Stopper, function( a ) { return 'e.pc=' + a.U2S() + '+' + ( this.next - 2 ); } ),
/* print_paddr */ 141: opcode_builder( Opcode, function( addr ) { return 'e.print(2,' + addr + '*' + this.e.addr_multipler + ')'; } ),
/* load */ 142: Indirect.subClass( { storer: 1 } ),
/* call_1n */ 143: Caller,
143: version === 3 ?
/* not (v3) */ not :
/* call_1n (v5/8) */ Caller,
/* rtrue */ 176: opcode_builder( Stopper, function() { return 'return 1'; } ),
/* rfalse */ 177: opcode_builder( Stopper, function() { return 'return 0'; } ),
// Reconsider a generalised class for @print/@print_ret?
/* print */ 178: opcode_builder( Opcode, function( text ) { return 'e.print(2,' + text + ')'; }, { printer: 1 } ),
/* print_ret */ 179: opcode_builder( Stopper, function( text ) { return 'e.print(2,' + text + ');e.print(1,13);return 1'; }, { printer: 1 } ),
/* nop */ 180: Opcode,
/* save (v3) */
/* restore (v3) */
/* restart */ 183: opcode_builder( Stopper, function() { return 'e.act(183)'; } ),
/* ret_popped */ 184: opcode_builder( Stopper, function( a ) { return 'return ' + a; }, { post: function() { this.operands.push( new Variable( this.e, 0 ) ); } } ),
/* catch */ 185: opcode_builder( Storer, function() { return 'e.call_stack.length'; } ),
185: version === 3 ?
/* pop (v3) */ 0 : // TODO :
/* catch (v5/8) */ opcode_builder( Storer, function() { return 'e.call_stack.length'; } ),
/* quit */ 186: opcode_builder( Stopper, function() { return 'e.act(186)'; } ),
/* new_line */ 187: opcode_builder( Opcode, function() { return 'e.print(1,13)'; } ),
/* show_status (v3) */
/* verify */ 189: alwaysbranch, // Actually check??
/* piracy */ 191: alwaysbranch,
/* call_vs */ 224: CallerStorer,
Expand All @@ -173,7 +184,7 @@ module.exports = {
/* sound_effect */ 245: Opcode, // We don't support sounds
/* read_char */ 246: opcode_builder( Pauser, function() { return 'e.read_char(' + ( this.args() || '1' ) + ',' + this.storer.v + ')'; } ),
/* scan_table */ 247: opcode_builder( BrancherStorer, function() { return 'e.scan_table(' + this.args() + ')'; } ),
/* not */ 248: opcode_builder( Storer, function( a ) { return 'e.S2U(~' + a + ')'; } ),
/* not (v5/8) */ 248: not,
/* call_vn */ 249: Caller,
/* call_vn2 */ 250: Caller,
/* tokenise */ 251: opcode_builder( Opcode, function() { return 'e.tokenise(' + this.args() + ')'; } ),
Expand All @@ -198,3 +209,5 @@ module.exports = {
/* parchment */ //1031: opcode_builder( Storer, function() { return 'e.op_parchment(' + this.args() + ')'; } ),

};

};
9 changes: 6 additions & 3 deletions src/zvm/runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ module.exports = {
// Try to find the property
addr = this.find_prop( object, property );

( memory.getUint8( addr - 1 ) & 0x40 ? memory.setUint16 : memory.setUint8 )( addr, value );
memory[ memory.getUint8( addr - 1 ) & 0x40 ? 'setUint16' : 'setUint8' ]( addr, value );
},

random: function( range )
Expand Down Expand Up @@ -560,12 +560,12 @@ module.exports = {
var memory = utils.MemoryView( this.data ),

version = memory.getUint8( 0x00 ),
addr_multipler = version === 5 ? 4 : 8,
addr_multipler = version === 3 ? 2 : ( version === 5 ? 4 : 8 ),
property_defaults = memory.getUint16( 0x0A ),
extension = memory.getUint16( 0x36 );

// Check if the version is supported
if ( version !== 5 && version !== 8 )
if ( version !== 3 && version !== 5 && version !== 8 )
{
throw new Error( 'Unsupported Z-Machine version: ' + version );
}
Expand Down Expand Up @@ -603,6 +603,9 @@ module.exports = {
// Routine and string multiplier
addr_multipler: addr_multipler,

// Opcodes for this version of the Z-Machine
opcodes: require( './opcodes.js' )( version ),

});

this.ui = new ( require( './ui.js' ) )( this, memory.getUint8( 0x11 ) & 0x02 );
Expand Down

0 comments on commit 6ede6f3

Please sign in to comment.