/* * memory_open * * Begin output redirection to the memory of the Z-machine. * */ internal static void MemoryOpen(zword table, zword xsize, bool buffering) { if (++depth < MAX_NESTING) { if (!buffering) { xsize = 0xffff; } if (buffering && (short)xsize <= 0) { xsize = Screen.GetMaxWidth((zword)(-(short)xsize)); } FastMem.StoreW(table, 0); redirect[depth].Table = table; redirect[depth].Width = 0; redirect[depth].Total = 0; redirect[depth].XSize = xsize; Main.ostream_memory = true; } else { Err.RuntimeError(ErrorCodes.ERR_STR3_NESTING); } }/* memory_open */
}/* z_check_unicode */ /* * z_encode_text, encode a ZSCII string for use in a dictionary. * * zargs[0] = address of text buffer * zargs[1] = length of ASCII string * zargs[2] = offset of ASCII string within the text buffer * zargs[3] = address to store encoded text in * * This is a V5+ opcode and therefore the dictionary resolution must be * three 16bit words. * */ internal static void ZEncodeText() { LoadString((zword)(Process.zargs[0] + Process.zargs[2]), Process.zargs[1]); EncodeText(0x05); if (Encoded is null) { ThrowHelper.ThrowInvalidOperationException("Encoding not initialized."); } for (int i = 0; i < Resolution; i++) { FastMem.StoreW((zword)(Process.zargs[3] + 2 * i), Encoded[i]); } }/* z_encode_text */
}/* z_push */ /* * z_push_stack, push a value onto a user stack then branch if successful. * * zargs[0] = value to push onto the stack * zargs[1] = address of user stack * */ internal static void ZPushStack() { zword addr = Process.zargs[1]; FastMem.LowWord(addr, out ushort size); if (size != 0) { FastMem.StoreW((zword)(addr + 2 * size), Process.zargs[0]); size--; FastMem.StoreW(addr, size); } Process.Branch(size > 0); // TODO I think that's what's expected here }/* z_push_stack */
internal static void ZPop() => Main.sp++; /* z_pop */ /* * z_pop_stack, pop n values off the game or user stack and discard them. * * zargs[0] = number of values to discard * zargs[1] = address of user stack (optional) * */ internal static void ZPopStack() { if (Process.zargc == 2) { /* it's a user stack */ zword addr = Process.zargs[1]; FastMem.LowWord(addr, out ushort size); size += Process.zargs[0]; FastMem.StoreW(addr, size); } else { Main.sp += Process.zargs[0]; /* it's the game stack */ } }/* z_pop_stack */
}/* z_pop_stack */ /* * z_pull, pop a value off... * * a) ...the game or a user stack and store it (V6) * * zargs[0] = address of user stack (optional) * * b) ...the game stack and write it to a variable (other than V6) * * zargs[0] = variable to write value to * */ internal static void ZPull() { zword value; if (Main.h_version != ZMachine.V6) { /* not a V6 game, pop stack and write */ value = Main.Stack[Main.sp++]; if (Process.zargs[0] == 0) { Main.Stack[Main.sp] = value; } else if (Process.zargs[0] < 16) { // *(fp - Process.zargs[0]) = value; Main.Stack[Main.fp - Process.zargs[0]] = value; } else { zword addr = (zword)(Main.h_globals + 2 * (Process.zargs[0] - 16)); FastMem.SetWord(addr, value); } } else { /* it's V6, but is there a user stack? */ if (Process.zargc == 1) { /* it's a user stack */ zword addr = Process.zargs[0]; FastMem.LowWord(addr, out ushort size); size++; FastMem.StoreW(addr, size); addr += (zword)(2 * size); FastMem.LowWord(addr, out value); } else { value = Main.Stack[Main.sp++];// value = *sp++; /* it's the game stack */ } Process.Store(value); } }/* z_pull */
}/* memory_new_line */ /* * memory_word * * Redirect a string of characters to the memory of the Z-machine. * */ internal static void MemoryWord(ReadOnlySpan <zword> s) { zword addr; zword c; int pos = 0; if (Main.h_version == ZMachine.V6) { int width = OS.StringWidth(s); if (redirect[depth].XSize != 0xffff) { if (redirect[depth].Width + width > redirect[depth].XSize) { if (s[pos] is ' ' or CharCodes.ZC_INDENT or CharCodes.ZC_GAP) { width = OS.StringWidth(s.Slice(++pos)); } MemoryNewline(); } } redirect[depth].Width += (zword)width; } addr = redirect[depth].Table; FastMem.LowWord(addr, out zword size); addr += 2; while ((c = s[pos++]) != 0) { FastMem.StoreB((zword)(addr + (size++)), Text.TranslateToZscii(c)); } FastMem.StoreW(redirect[depth].Table, size); }/* memory_word */
}/* memory_open */ /* * memory_new_line * * Redirect a newline to the memory of the Z-machine. * */ internal static void MemoryNewline() { zword addr; redirect[depth].Total += redirect[depth].Width; redirect[depth].Width = 0; addr = redirect[depth].Table; FastMem.LowWord(addr, out zword size); addr += 2; if (redirect[depth].XSize != 0xffff) { redirect[depth].Table = (zword)(addr + size); size = 0; } else { FastMem.StoreB((zword)(addr + (size++)), 13); } FastMem.StoreW(redirect[depth].Table, size); }/* memory_new_line */
} /* z_storeb */ /* * z_storew, write a word into a table of words. * * zargs[0] = address of table * zargs[1] = index of table entry * zargs[2] = value to be written * */ internal static void ZStoreW() { FastMem.StoreW((zword)(Process.zargs[0] + 2 * Process.zargs[1]), Process.zargs[2]); } /* z_storew */