From f571664853f93e9b315701df69387c4de02ede14 Mon Sep 17 00:00:00 2001 From: Virgil Dupras Date: Mon, 15 Apr 2019 13:18:29 -0400 Subject: [PATCH] Improve user guide --- doc/README.md | 2 +- doc/load-run-code.md | 110 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 doc/load-run-code.md diff --git a/doc/README.md b/doc/README.md index bccd46c..0b1d193 100644 --- a/doc/README.md +++ b/doc/README.md @@ -7,4 +7,4 @@ properly running. ## Table of Contents * [The shell](shell.md) - +* [Load code in RAM and run it](load-run-code.md) diff --git a/doc/load-run-code.md b/doc/load-run-code.md new file mode 100644 index 0000000..3526bfa --- /dev/null +++ b/doc/load-run-code.md @@ -0,0 +1,110 @@ +# Load code in RAM and run it + +Collapse OS likely runs from ROM code. If you need to fiddle with your machine +more deeply, you will want to send arbitrary code to it and run it. You can do +so with the shell's `load` and `call` commands. + +For example, let's say that you want to run this simple code that you have +sitting on your "modern" machine and want to execute on your running Collapse OS +machine: + + ld a, (0xa100) + inc a + ld (0xa100), a + ret + +(we must always return at the end of code that we call with `call`). This will +increase a number at memory address `0xa100`. First, compile it: + + scas -o tosend.bin tosend.asm + +Now, we'll send that code to address `0xa000`: + + > seek a000 + A000 + > load 8 (resulting binary is 8 bytes long) + +Now, at this point, it's a bit delicate. To pipe your binary to your serial +connection, you have to close `screen` with CTRL+A then `:quit` to free your +tty device. Then, you can run: + + cat tosend.bin > /dev/ttyUSB0 (or whatever is your device) + +You can then re-open your connection with screen. You'll have a blank screen, +but if the number of characters sent corresponds to what you gave `load`, then +Collapse OS will be waiting for a new command. Go ahead, verify that the +transfer was successful with: + + peek 8 + 3A00A13C3200A1C9 + +Good! Now, we can try to run it. Before we run it, let's peek at the value at +`0xa100` (being RAM, it's random): + + > seek a100 + A100 + > peek + 61 + +So, we'll expect this to become `62` after we run the code. Let's go: + + > seek a000 + A000 + > call 00 0000 + > seek a100 + A100 + > peek + 62 + +Success! + +## Labels in RAM code + +If your code contains any label, make sure that you add a `.org` directive at +the beginning of your code with the address you're planning on uploading your +code to. Otherwise, those labels are going to point to wrong addresses. + +## Calling ROM code + +The ROM you run Collapse OS on already has quite a bit of code in it, some of +it could be useful to programs you run from RAM. + +If you know exactly where a routine lives in the ROM, you can `call` the address +directly, no problem. However, getting this information is tedious work and is +likely to change whenever you change the kernel code. + +A good approach is to define yourself a jump table that you put in your glue +code. A good place for this is in the `0x03` to `0x37` range, which is empty +anyways (unless you set yourself up with some `rst` jumps) and is needed to +have a proper interrupt hook at `0x38`. For example, your glue code could look +like (important fact: `jp ` uses 3 bytes): + + jp init + ; JUMP TABLE + jp printstr + jp aciaPutC + + .fill 0x38-$ + jp aciaInt + + init: + [...] + +It then becomes easy to build yourself a predictable and stable jump header, +something you could call `jumptable.inc`: + + JUMP_PRINTSTR .equ 0x03 + JUMP_ACIAPUTC .equ 0x06 + +You can then include that file in your "user" code, like this: + + #include "jumptable.inc" + .org 0xa000 + ld hl, label + call JUMP_PRINTSTR + ret + + label: .db "Hello World!", 0 + +If you load that code at `0xa000` and call it, it will print "Hello World!" by +using the `printstr` routine from `core.asm`.