The built-in monitor

This is a really very convenient part of the emulator, and I use it a lot. It is very MONS-like in its commands and visual appearance. It cannot single-step however, but on the positive side it has some features MONS hasn't. It is a part of the SamRam, and cannot therefore be used with Spectrum 128 programs. If you want to take a look at a Spectrum 128 program, press F10, then change the hardware to SamRam without resetting, and finally generate an NMI in the Extra Functions menu. You won't probably be able to continue to run the program, but at least you're able to see what it was doing.

Press F5 for NMI, and D to enter the monitor/disassembler. The first eight lines are the first eight instructions, starting at the Memory Pointer, from here on abbreviated by MP. At first, MP is zero. The disassembler knows all official instructions, and the SLL instruction. If another inofficial instruction (i.e. starting with DD, FD or ED) is encountered, the first byte is displayed on a blank line. The four lines below these display the value of PC and SP, the first nine words on the stack (including AF and the program counter, which have been pushed during NMI), and three MP-memories. These can be used for temporary storage of the MP, for instance when you take a look at the body of a CALL, and want to return to the main procedure later.

The bottom part of the screen displays 24 bytes around the memory pointer.

Commands are one letter long; no ENTER needs to be given. If one or more operands are needed, a colon will appear. By default the monitor accepts hexadecimal input. A leading $ denotes that the number is to be regarded as decimal. If you give the # command, the default will toggle to decimal, and you need to explicitly put a # in front of a number which is to be interpreted as a hex number. Also, after the # command all addresses on screen will be decimal. A single character preceded by the " symbol evaluates to its ASCII code, and the single character M will evaluate to the current value of the memory pointer. The monitor commands:

Q: Decrease the memory pointer by one. You effectively shift one byte up.
A: Increase the memory pointer, shifting one byte down.
ENTER: Shift one instruction down: the memory pointer is increased by the length of first instruction displayed on screen.
M: Change the value of the memory pointer. For instance, M:M won't change it.
P: Put. The word operand supplied will be stored in the first MP memory, and the others will shift on place to the right. Usually, you'll want to store the memory pointer by P:M
G: Get. Typing G:1, G:2 or G:3 moves the value of one of the MP memories to the MP.
B: Byte. This command needs a byte operand; it will be poked into memory, and the memory pointer will move one up.
I: Insert. The same as B, except that you can poke more than one byte. It continues to ask for bytes to poke until you type Enter on a blank line.
#: Toggles the default number base between hexadecimal and decimal.
F: Find. You can enter up to ten bytes, which will be searched through memory. Searching will stop at address 0, because since the search string is stored in shadow Ram, searching would otherwise not always terminate. Typing Enter on a blank line starts the search. Byte operands are entered as usual, but:
 If a number bigger than 256 decimal is entered, it is treated as a word in the standard LSB/MSB format. So, 1234 will search for 34,12 hex in that order. Note that 0012 will search for 12, not 12,00.
 A line starting with " decodes into the string of characters (up to ten) behind it. Normally this would only be the first character. So instead of typing "M "Y "N "A "M "E (space=enter here) you type "MYNAME. Note that any terminating " will also be searched for!
 An x is treated as a wildcard. So if you search for CD x 80 any call to a subroutine in the block 8000-80FF is a hit. If you search for x 8000, you'll see every one-byte instruction that has the address 8000 as operand.
N: Continues the search started by F from the current MP.
$: Displays one page of disassembly on screen. In this mode, the following commands are possible:
$: Back to the main screen
7: [Shift 7 also works, cursor up]: Go to the previous page. The monitor stores the addresses of the previous eight pages only.
Q: Go back one byte (decrease MP by one)
A: Go one byte forward (increase MP by one)
Z: Dump this screen to the printer, in ASCII format. Redirect the RS232 output to a file, and run CONVERT on it to convert the CR's into CR/LF's before printing (or tell your printer to do the conversion).
 Every other key displays the next page of disassembly.
K: List. The same mode as with $ is entered, but instead of a disassembly the bytes with their ASCII characters are displayed. Useful to look for text.
C: Clear. Fills blocks of memory with a specified value. The monitor prompts with `First', `Last' and `With'. The `Last' address is inclusive!
D: Dump. Prompts with `First' and `Last', and dumps a disassembly of the block between these addresses to the printer. See remark at $-Z. The `Last' address is again inclusive.
R: Registers. If you press Enter after R, an overview of the registers contents is displayed. If you type one of A, B, C, D, E, H, L, A', B', C', D', E', H', L', I, R, AF, BC, DE, HL, AF', BC', DE', HL', IX, IY, SP or PC, you can change the value of it. Changing the value of SP also changes the PC and AF values by the way. You cannot change the Interrupt mode or IFF.
V: Verplaats (Move). Prompts with `From', `To' and `Length'. Obvious.
S: Save. Enter the start of the block you wish to save first. The monitor then prompts with `Length'. The block is saved without a header, as a normal data block (A, the flagbyte, is 0FF)
L: Load. Loads a block of data from tape, at the specified address. Normal data blocks, headers and blocks with non- standard flag bytes can be loaded. The first byte in memory will contain the flag byte. If the checksum isn't 0 after loading, indicating a tape error, you'll hear a beep.
H: Header read. Loads headers and displays the contents on screen.

As you're reading this part, I assume you know something of machine code. Probably you would be interested in peeking into the software of the SamRam, the Interface I or the Spectrum 128. You'll first have to move these roms in ram to be able to look at them with the monitor.

The Interface I rom can be moved into ram by saving it to microdrive or to the "b" channel, with:
SAVE *"m";1;"rom" CODE 0,8192 or SAVE *"b" CODE 0,8192, and loading it back again at 32768 for instance. You can also put this small machine code routine at 23296 and run it: F3 21 0C 5B E5 21 00 00 E5 C3 08 00 21 00 00 11 00 80 01 00 20 ED B0 FB C3 00 07.

The two SamRam roms are easy. The first you don't need to transfer; the monitor looks at the extended basic rom by default. The second rom can be moved to 32768 by typing *SAVE 0,32768,16384. (The SAVE is not the keyword SAVE!)

The first '128 rom, the one which is active at reset and contains most of the new code, is moved up by typing SAVE!"rom"CODE 0,16384, then LOAD!"rom"CODE 32768. The other rom is most conveniently moved by saving it to a .TAP file and loading it back again in ram. To select the SamRam type SPECTRUM first, and then switch the hardware without resetting.