About Archive Tags RSS Feed

 

Simple REPL for CP/M, in Z80 assembly

24 June 2023 13:00

So my previous post documented a couple of simple "scripting languages" for small computers, allowing basic operations in a compact/terse fashion.

I mentioned that I might be tempted to write something similar for CP/M, in Z80 assembly, and the result is here:

To sum up it allows running programs like this:

0m 16k{rP _ _}
C3 03 EA 00 00 C3 06 DC 00 00 00 00 00 00 00 00

Numbers automatically get saved to the A-register, the accumulator. In addition to that there are three dedicated registers:

  • M-register is used to specify which RAM address to read/write from.
    • The instruction m copies the value of accumulator to the M-register.
    • The instruction M copies the value of the M-register to the accumulator.
  • K-register is used to execute loops.
    • The instruction k copies the value of accumulator to the K-register.
    • The instruction K copies the value of the K-register to the accumulator.
  • U-register is used to specify which port to run I/O input and output from.
    • The instruction u copies the value of accumulator to the U-register.
    • The instruction U copies the value of the U-register to the accumulator.

So the program above:

  • 0m
    • 0 is stored in the accumulator.
    • m copies the value of the accumulator to the M-register.
  • 16k
    • 16 is stored in the accumulator.
    • k copies the value of the accumulator (16) to the K-register, which is used for looping.
  • { - Starts a loop.
    • The K-register is decremented by one.
    • If the K-register is greater than zero the body is executed, up to the closing brace.
  • Loop body:
    • r Read a byte to the accumulator from the address stored in the M-register, incrementing that register in the process.
    • P: Print the contents of the accumulator.
    • _ _ Print a space.
  • } End of the loop, and end of the program.

TLDR: Dump the first sixteen bytes of RAM, at address 0x0000, to the console.

Though this program allows delays, RAM read/write, I/O port input and output, as well as loops it's both kinda fun, and kinda pointless. I guess you could spend hours flashing lights and having other similar fun. But only if you're like me!

All told the code compiles down to about 800 bytes and uses less than ten bytes of RAM to store register-state. It could be smaller with some effort, but it was written a bit adhoc and I think I'm probably done now.

| No comments