Inside the Einstein: The MOS, a TatungBytes course: the MOS 1.2 start up screen on a rainbow sunburst
← Back to Modules
module
9

The Monitor

Introduction

When your program finishes, the MOS shows its registers and waits at >. From there you can type a command - T to look at memory, M to change it, D and H to convert numbers - and come back to the same prompt. This section reads the loop that makes that work, and the clever route your program takes back into it.

The loop

The prompt is MONITR, at 0171h:

MONITR:
        ld sp,0fcffh            ;0171
        ei                      ;0174
        rst 8                   ;0175
        defb 0a7h               ;0176
l0177h:
        ld a,(0fb40h)           ;0177
        rst 10h                 ;017a
        ld de,0fbb8h            ;017b
        rst 8                   ;017e
        defb 09dh               ;017f
        ld a,(de)               ;0180
        or a                    ;0181
        jr z,l0177h             ;0182
  • A fresh stack at FCFFh every time round. Whatever a command left on the stack, the monitor starts clean.
  • The prompt character comes from FB40h - in RAM, so it can be changed. Type M FB40, ENTER, 23, ENTER, then . and ENTER, and the prompt becomes #.
  • RST 8 / 9Dh is call 157, the same line reader your programs can use, reading what you type into memory at FBB8h.
  • An empty line - just ENTER - goes back for another prompt.

Then S8's code takes the first letter, finds its entry in FMTBL, reads the numbers you typed after it, and enters the handler.

How a handler reports back

Every handler is entered with one address already on the stack as its return address: MONDUN, at 01F2h.

MONDUN:
        jp nc,MONITR            ;01f2
ERROR:
        rst 18h                 ;01f5
        defb ' Erro','r'+80h
        rst 18h
        defb '!',07h,0dh,0ah+80h
        jp MONITR               ;0201

(The source shows the two messages as bytes; they are written out here.)

A handler that worked returns with the carry flag clear, and JP NC goes straight back to the prompt. A handler that failed returns with carry set, and falls into ERROR, which prints Error! and then goes back. A letter with no command has ERROR itself as its table entry, so it arrives at the same message by a shorter road.

One flag, one instruction: the whole of the monitor's error handling.

How your program gets back

Your program's last RET has to arrive somewhere in the MOS. But your program runs with RAM in, and the MOS's code is in the ROM. The return cannot be a plain jump into the ROM.

The MOS solves it with one byte. The return address your program pops is 0FA5h, and in RAM at 0FA5h there is the byte FFh. FFh is the opcode of RST 38h: a one-byte call to 0038h. And at 0038h in RAM is:

        out (024h),a            ; RAM 0038h: switch the ROM in
        jp 0204h                ; into the ROM: BREAK

BREAK, at 0204h, saves your registers before anything can disturb them:

BREAK:
        ld (0fb65h),sp          ;0204
        di                      ;0208
        ld sp,0fb77h            ;0209
        push hl                 ;020c
        push de                 ;020d
        push bc                 ;020e
        push af                 ;020f

With SP set to FB77h, the four pushes lay HL, DE, BC and AF down in memory from FB76h to FB6Fh - a neat way to store four registers in four instructions. The register display that follows prints them from there.

The display shows PC as the address of the RST 38h that brought the MOS in. After a normal return, that is 0FA5h.

The same route serves another purpose. Because RST 38h is one byte, FFh, it can be put into any program in place of an instruction, and the program will stop there and show its registers, with PC giving the address where it stopped - a breakpoint. The name of the routine says so: BREAK.

The code

        ORG 256

        LD A,12h
        LD BC,3456h
        LD DE,789Ah
        LD HL,0BCDEh
        SCF             ; carry set
        RET

Build and run

Press Run.

What you should see

 A   BC   DE   HL   PC  SZ-H-PNC
12 3456 789A BCDE 0FA5 00101001

Every value your program left is there. The last column is F, the flags, as eight bits; the final 1 is the carry your SCF set.

Summary

MONITR resets the stack, prints the prompt from FB40h, reads a line with call 157 and dispatches the letter through FMTBL. Handlers return to MONDUN with carry clear for success or set for Error!. Your program's RET reaches the MOS through an RST 38h byte at 0FA5h and a ROM switch at RAM 0038h, and BREAK saves your registers for the display.

Next

S10: every character you have seen so far was drawn by the MOS. How, and where do their shapes come from?

Get the Newsletter

New guides, disk images and community finds, roughly once a quarter. No spam, we promise, this isn't Tatung's marketing department.
Your subscription could not be saved. Please try again.
Your subscription has been successful.

Newsletter

Subscribe to our newsletter and stay updated.

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.