From 25d25d017c527a42b016aef4250bcc36e2d60b20 Mon Sep 17 00:00:00 2001 From: Virgil Dupras Date: Wed, 11 Dec 2019 14:05:34 -0500 Subject: [PATCH] Replace old shell with BASIC shell fixes #80 --- apps/basic/main.asm | 9 - apps/shell/README.md | 98 ----------- apps/shell/blkdev.asm | 118 -------------- apps/shell/fs.asm | 75 --------- apps/shell/glue.asm | 35 ---- apps/shell/gluem.asm | 22 --- apps/shell/main.asm | 361 ----------------------------------------- apps/shell/pgm.asm | 51 ------ recipes/rc2014/README.md | 27 ++- recipes/rc2014/basic/Makefile | 10 -- recipes/rc2014/basic/README.md | 46 ------ recipes/rc2014/basic/glue.asm | 57 ------- recipes/rc2014/glue.asm | 35 ++-- recipes/rc2014/zasm/README.md | 6 +- tools/emul/Makefile | 21 +-- tools/emul/README.md | 15 +- tools/emul/bshell/glue.asm | 178 -------------------- tools/emul/bshell/shell.c | 191 ---------------------- tools/emul/bshell/user.h | 35 ---- tools/emul/shell/glue.asm | 55 +++++-- tools/emul/shell/shell.c | 6 +- tools/emul/shell/user.h | 2 +- 22 files changed, 102 insertions(+), 1351 deletions(-) delete mode 100644 apps/shell/README.md delete mode 100644 apps/shell/blkdev.asm delete mode 100644 apps/shell/fs.asm delete mode 100644 apps/shell/glue.asm delete mode 100644 apps/shell/gluem.asm delete mode 100644 apps/shell/main.asm delete mode 100644 apps/shell/pgm.asm delete mode 100644 recipes/rc2014/basic/Makefile delete mode 100644 recipes/rc2014/basic/README.md delete mode 100644 recipes/rc2014/basic/glue.asm delete mode 100644 tools/emul/bshell/glue.asm delete mode 100644 tools/emul/bshell/shell.c delete mode 100644 tools/emul/bshell/user.h diff --git a/apps/basic/main.asm b/apps/basic/main.asm index 74b363e..56db9ab 100644 --- a/apps/basic/main.asm +++ b/apps/basic/main.asm @@ -124,13 +124,6 @@ basERR: ; 2 - the beginning of the arg, with whitespace properly skipped. ; ; Commands are expected to set Z on success. -basBYE: - ; To quit the loop, let's return the stack to its initial value and - ; then return. - xor a - ld sp, (BAS_INITSP) - ret - basLIST: call bufFirst jr nz, .end @@ -449,8 +442,6 @@ basR2Var: ; Just send reg to vars. Used in basPgmHook ; direct only basCmds1: - .db "bye", 0 - .dw basBYE .db "list", 0 .dw basLIST .db "run", 0 diff --git a/apps/shell/README.md b/apps/shell/README.md deleted file mode 100644 index 3cf6b07..0000000 --- a/apps/shell/README.md +++ /dev/null @@ -1,98 +0,0 @@ -# shell - -**This shell is currently being replaced with the -[BASIC shell](../basic/README.md). While it's still used in many places, it's -being phased out.** - -The shell is a text interface giving you access to commands to control your -machine. It is not built to be user friendly, but to minimize binary space and -maximize code simplicity. - -We expect the user of this shell to work with a copy of the user guide within -reach. - -It is its design goal, however, to give you the levers you need to control your -machine fully. - -## Commands and arguments - -You invoke a command by typing its name, followed by a list of arguments. All -numerical arguments have to be typed in hexadecimal form, without prefix or -suffix. Lowercase is fine. Single digit is fine for byte (not word) arguments -smaller than `0x10`. Example calls: - - mptr 01ff - peek 4 - poke 1f - call 00 0123 - -All numbers printed by the shell are in hexadecimals form. - -Whenever a command is malformed, the shell will print `ERR` with a code. This -table describes those codes: - -| Code | Description | -|------|---------------------------| -| `01` | Unknown command | -| `02` | Badly formatted arguments | -| `03` | Out of bounds | -| `04` | Unsupported command | -| `05` | I/O error | - -Applications have their own error codes as well. If you see an error code that -isn't in this list, it's an application-specific error code. - -## mptr - -The shell has a global memory pointer (let's call it `memptr`) that is used by -other commands. This pointer is 2 bytes long and starts at `0x0000`. To move -it, you use the mptr command with the new pointer position. The command -prints out the new `memptr` (just to confirm that it has run). Example: - - > mptr 42ff - 42FF - -## peek - -Read memory targeted by `memptr` and prints its contents in hexadecimal form. -This command takes one byte argument (optional, default to 1), the number of -bytes we want to read. Example: - - > mptr 0040 - 0040 - > peek 2 - ED56 - -## poke - -Puts the serial console in input mode and waits for a specific number of -characters to be typed (that number being specified by a byte argument). These -characters will be literally placed in memory, one after the other, starting at -`memptr`. - -Example: - - > poke 5 - Hello - > peek 5 - 48656C6C6F - -## call - -Calls the routine at `memptr`, setting the `A` and `HL` registers to the value -specified by its optional arguments (default to 0). - -Be aware that this results in a call, not a jump, so your routine needs to -return if you don't want to break your system. - -The following example works in the case where you've made yourself a jump table -in your glue code a `jp printstr` at `0x0004`: - - > mptr a000 - A000 - > poke 6 - Hello\0 (you can send a null char through a terminal with CTRL+@) - > mptr 0004 - 0004 - > call 00 a000 - Hello> diff --git a/apps/shell/blkdev.asm b/apps/shell/blkdev.asm deleted file mode 100644 index acb0700..0000000 --- a/apps/shell/blkdev.asm +++ /dev/null @@ -1,118 +0,0 @@ -; *** REQUIREMENTS *** -; blkSelPtr -; blkSel -; blkSeek -; blkTell - -blkBselCmd: - .db "bsel", 0b001, 0, 0 - ld a, (hl) ; argument supplied - push de - call blkSelPtr - call blkSel - pop de - jr nz, .error - xor a - ret -.error: - ld a, BLOCKDEV_ERR_OUT_OF_BOUNDS - ret - -blkSeekCmd: - .db "seek", 0b001, 0b011, 0b001 - ; First, the mode - ld a, (hl) - inc hl - push af ; save mode for later - ; HL points to two bytes that contain out address. Seek expects HL - ; to directly contain that address. - ld a, (hl) - ex af, af' - inc hl - ld a, (hl) - ld l, a - ex af, af' - ld h, a - pop af ; bring mode back - ld de, 0 ; DE is used for seek > 64K which we don't support - call blkSeek - call blkTell - ld a, h - call printHex - ld a, l - call printHex - call printcrlf - xor a - ret - -; Load the specified number of bytes (max 0x100, 0 means 0x100) from IO and -; write them in the current memory pointer (which doesn't change). If the -; blkdev hits end of stream before we reach our specified number of bytes, we -; stop loading. -; -; Returns a SHELL_ERR_IO_ERROR only if we couldn't read any byte (if the first -; call to GetB failed) -; -; Example: load 42 -blkLoadCmd: - .db "load", 0b001, 0, 0 -blkLoad: - push bc - push hl - - ld a, (hl) - ld b, a - ld hl, (SHELL_MEM_PTR) - call blkGetB - jr nz, .ioError - jr .intoLoop ; we'v already called blkGetB. don't call it - ; again. -.loop: - call blkGetB -.intoLoop: - ld (hl), a - inc hl - jr nz, .loopend - djnz .loop -.loopend: - ; success - xor a - jr .end -.ioError: - ld a, SHELL_ERR_IO_ERROR -.end: - pop hl - pop bc - ret - -; Load the specified number of bytes (max 0x100, 0 means 0x100) from the current -; memory pointer and write them to I/O. Memory pointer doesn't move. This puts -; chars to blkPutB. Raises error if not all bytes could be written. -; -; Example: save 42 -blkSaveCmd: - .db "save", 0b001, 0, 0 -blkSave: - push bc - push hl - - ld a, (hl) - ld b, a - ld hl, (SHELL_MEM_PTR) -.loop: - ld a, (hl) - inc hl - call blkPutB - jr nz, .ioError - djnz .loop -.loopend: - ; success - xor a - jr .end -.ioError: - ld a, SHELL_ERR_IO_ERROR -.end: - pop hl - pop bc - ret - diff --git a/apps/shell/fs.asm b/apps/shell/fs.asm deleted file mode 100644 index c47a734..0000000 --- a/apps/shell/fs.asm +++ /dev/null @@ -1,75 +0,0 @@ -; *** SHELL COMMANDS *** -fsOnCmd: - .db "fson", 0, 0, 0 - jp fsOn - -; Lists filenames in currently active FS -flsCmd: - .db "fls", 0, 0, 0, 0 - ld iy, .iter - call fsIter - ret z - ld a, FS_ERR_NO_FS - ret -.iter: - ld a, FS_META_FNAME_OFFSET - call addHL - call printstr - jp printcrlf - -; Takes one byte block number to allocate as well we one string arg filename -; and allocates a new file in the current fs. -fnewCmd: - .db "fnew", 0b001, 0b1001, 0b001 - push hl - ld a, (hl) - inc hl - call intoHL - call fsAlloc - pop hl - xor a - ret - -; Deletes filename with specified name -fdelCmd: - .db "fdel", 0b1001, 0b001, 0 - push hl - call intoHL ; HL now holds the string we look for - call fsFindFN - jr nz, .notfound - ; Found! delete - call fsDel - jr z, .end - ; weird error, continue to error condition -.notfound: - ld a, FS_ERR_NOT_FOUND -.end: - pop hl - ret - - -; Opens specified filename in specified file handle. -; First argument is file handle, second one is file name. -; Example: fopn 0 foo.txt -fopnCmd: - .db "fopn", 0b001, 0b1001, 0b001 - push hl - push de - ld a, (hl) ; file handle index - call fsHandle - ; DE now points to file handle - inc hl - call intoHL ; HL now holds the string we look for - call fsFindFN - jr nz, .notfound - ; Found! - ; FS_PTR points to the file we want to open - push de \ pop ix ; IX now points to the file handle. - call fsOpen - jr .end -.notfound: - ld a, FS_ERR_NOT_FOUND -.end: - pop de - pop hl - ret diff --git a/apps/shell/glue.asm b/apps/shell/glue.asm deleted file mode 100644 index 43c7493..0000000 --- a/apps/shell/glue.asm +++ /dev/null @@ -1,35 +0,0 @@ -; This repesents a full-featured shell, that is, a shell that includes all -; options it has to offer. For a minimal shell, use "gluem.asm" -.inc "user.h" -.inc "err.h" -.inc "ascii.h" -.inc "blkdev.h" -.inc "fs.h" -jp init - -.inc "core.asm" -.inc "lib/util.asm" -.inc "lib/parse.asm" -.inc "lib/args.asm" -.equ SHELL_RAMSTART USER_RAMSTART -.equ SHELL_EXTRA_CMD_COUNT 9 -.inc "shell/main.asm" -.dw blkBselCmd, blkSeekCmd, blkLoadCmd, blkSaveCmd -.dw fsOnCmd, flsCmd, fnewCmd, fdelCmd, fopnCmd - -.inc "lib/ari.asm" -.inc "lib/fmt.asm" -.inc "shell/blkdev.asm" -.inc "shell/fs.asm" - -.equ PGM_RAMSTART SHELL_RAMEND -.equ PGM_CODEADDR USER_CODE -.inc "shell/pgm.asm" - -init: - call shellInit - ld hl, pgmShellHook - ld (SHELL_CMDHOOK), hl - jp shellLoop - -USER_RAMSTART: diff --git a/apps/shell/gluem.asm b/apps/shell/gluem.asm deleted file mode 100644 index 1715d73..0000000 --- a/apps/shell/gluem.asm +++ /dev/null @@ -1,22 +0,0 @@ -; This repesents a minimal shell, that is, the smallest shell our configuration -; options allow. For a full-featured shell, see "glue.asm" -.inc "user.h" -.inc "err.h" -.inc "ascii.h" -jp init - -.inc "core.asm" -.inc "lib/util.asm" -.inc "lib/parse.asm" -.inc "lib/args.asm" -.inc "lib/fmt.asm" -.equ SHELL_RAMSTART USER_RAMSTART -.equ SHELL_EXTRA_CMD_COUNT 0 -.inc "shell/main.asm" - -init: - call shellInit - jp shellLoop - -USER_RAMSTART: - diff --git a/apps/shell/main.asm b/apps/shell/main.asm deleted file mode 100644 index 77ae1c9..0000000 --- a/apps/shell/main.asm +++ /dev/null @@ -1,361 +0,0 @@ -; shell -; -; Runs a shell over a block device interface. - -; The shell spits a welcome prompt, wait for input and compare the first 4 chars -; of the input with a command table and call the appropriate routine if it's -; found, an error if it's not. -; -; To determine the correct routine to call we first go through cmds in -; shellCmdTbl. This means that we first go through internal cmds, then cmds -; "grafted" by glue code. -; -; If the command isn't found, SHELL_CMDHOOK is called, which should set A to -; zero if it executes something. Otherwise, SHELL_ERR_UNKNOWN_CMD will be -; returned. -; -; See constants below for error codes. -; -; All numerical values in the Collapse OS shell are represented and parsed in -; hexadecimal form, without prefix or suffix. - -; *** REQUIREMENTS *** -; err -; core -; parse -; stdio - -; *** DEFINES *** -; SHELL_EXTRA_CMD_COUNT: Number of extra cmds to be expected after the regular -; ones. See comment in COMMANDS section for details. -; SHELL_RAMSTART - -; *** CONSTS *** - -; number of entries in shellCmdTbl -.equ SHELL_CMD_COUNT 6+SHELL_EXTRA_CMD_COUNT - -; maximum length for shell commands. Should be confortably below stdio's -; readline buffer length. -.equ SHELL_MAX_CMD_LEN 0x10 - -; *** VARIABLES *** -; Memory address that the shell is currently "pointing at" for peek, load, call -; operations. Set with mptr. -.equ SHELL_MEM_PTR SHELL_RAMSTART - -; Places where we store arguments specifiers and where resulting values are -; written to after parsing. -.equ SHELL_CMD_ARGS @+2 - -; Pointer to a hook to call when a cmd name isn't found -.equ SHELL_CMDHOOK @+PARSE_ARG_MAXCOUNT - -.equ SHELL_RAMEND @+2 - -; *** CODE *** -shellInit: - xor a - ld (SHELL_MEM_PTR), a - ld (SHELL_MEM_PTR+1), a - ld hl, noop - ld (SHELL_CMDHOOK), hl - - ; print welcome - ld hl, .welcome - jp printstr - -.welcome: - .db "Collapse OS", CR, LF, "> ", 0 - -; Inifite loop that processes input. Because it's infinite, you should jump -; to it rather than call it. Saves two precious bytes in the stack. -shellLoop: - call stdioReadLine - call printcrlf - call shellParse - ld hl, .prompt - call printstr - jr shellLoop - -.prompt: - .db "> ", 0 - -; Parse command (null terminated) at HL and calls it -shellParse: - ; first thing: is command empty? - ld a, (hl) - or a - ret z ; empty, nothing to do - - push af - push bc - push de - push hl - push ix - - ; Before looking for a suitable command, let's make the cmd line more - ; usable by replacing the first ' ' with a null char. This way, cmp is - ; easy to make. - push hl ; --> lvl 1 - ld a, ' ' - call findchar - jr z, .hasArgs - ; no arg, (HL) is zero to facilitate processing later, add a second - ; null next to that one to indicate unambiguously that we have no args. - inc hl - ; Oh wait, before we proceed, is our cmd length within limits? cmd len - ; is currently in A from findchar - cp SHELL_MAX_CMD_LEN - jr c, .hasArgs ; within limits - ; outside limits - ld a, SHELL_ERR_UNKNOWN_CMD - jr .error -.hasArgs: - xor a - ld (hl), a - pop hl ; <-- lvl 1, beginning of cmd - - ld de, shellCmdTbl - ld b, SHELL_CMD_COUNT - -.loop: - push de ; we need to keep that table entry around... - call intoDE ; Jump from the table entry to the cmd addr. - ld a, 4 ; 4 chars to compare - call strncmp - pop de - jr z, .found - inc de - inc de - djnz .loop - - ; exhausted loop? not found - ld a, SHELL_ERR_UNKNOWN_CMD - ; Before erroring out, let's try SHELL_HOOK. - ld ix, (SHELL_CMDHOOK) - call callIX - jr z, .end ; oh, not an error! - ; still an error. Might be different than SHELL_ERR_UNKNOWN_CMD though. - ; maybe a routine was called, but errored out. - jr .error - -.found: - ; we found our command. DE points to its table entry. Now, let's parse - ; our args. - call intoDE ; Jump from the table entry to the cmd addr. - - ; advance the HL pointer to the beginning of the args. - xor a - call findchar - inc hl ; beginning of args - ; Now, let's have DE point to the argspecs - ld a, 4 - call addDE - - ; We're ready to parse args - ld ix, SHELL_CMD_ARGS - call parseArgs - or a ; cp 0 - jr nz, .parseerror - - ; Args parsed, now we can load the routine address and call it. - ; let's have DE point to the jump line - ld hl, SHELL_CMD_ARGS - ld a, PARSE_ARG_MAXCOUNT - call addDE - push de \ pop ix - ; Ready to roll! - call callIX - or a ; cp 0 - jr nz, .error ; if A is non-zero, we have an error - jr .end - -.parseerror: - ld a, SHELL_ERR_BAD_ARGS -.error: - call shellPrintErr -.end: - pop ix - pop hl - pop de - pop bc - pop af - ret - -; Print the error code set in A (in hex) -shellPrintErr: - push af - push hl - - ld hl, .str - call printstr - call printHex - call printcrlf - - pop hl - pop af - ret - -.str: - .db "ERR ", 0 - -; *** COMMANDS *** -; A command is a 4 char names, followed by a PARSE_ARG_MAXCOUNT bytes of -; argument specs, followed by the routine. Then, a simple table of addresses -; is compiled in a block and this is what is iterated upon when we want all -; available commands. -; -; Format: 4 bytes name followed by PARSE_ARG_MAXCOUNT bytes specifiers, -; followed by 3 bytes jump. fill names with zeroes -; -; When these commands are called, HL points to the first byte of the -; parsed command args. -; -; If the command is a success, it should set A to zero. If the command results -; in an error, it should set an error code in A. -; -; Extra commands: Other parts might define new commands. You can add these -; commands to your shell. First, set SHELL_EXTRA_CMD_COUNT to -; the number of extra commands to add, then add a ".dw" -; directive *just* after your '.inc "shell.asm"'. Voila! -; - -; Set memory pointer to the specified address (word). -; Example: mptr 01fe -shellMptrCmd: - .db "mptr", 0b011, 0b001, 0 -shellMptr: - push hl - - ; reminder: z80 is little-endian - ld a, (hl) - ld (SHELL_MEM_PTR+1), a - inc hl - ld a, (hl) - ld (SHELL_MEM_PTR), a - - ld hl, (SHELL_MEM_PTR) - ld a, h - call printHex - ld a, l - call printHex - call printcrlf - - pop hl - xor a - ret - - -; peek the number of bytes specified by argument where memory pointer points to -; and display their value. If 0 is specified, 0x100 bytes are peeked. -; -; Example: peek 2 (will print 2 bytes) -shellPeekCmd: - .db "peek", 0b001, 0, 0 -shellPeek: - push bc - push hl - - ld a, (hl) - ld b, a - ld hl, (SHELL_MEM_PTR) -.loop: ld a, (hl) - call printHex - inc hl - djnz .loop - call printcrlf - -.end: - pop hl - pop bc - xor a - ret - -; poke specified number of bytes where memory pointer points and set them to -; bytes typed through stdioGetC. Blocks until all bytes have been fetched. -shellPokeCmd: - .db "poke", 0b001, 0, 0 -shellPoke: - push bc - push hl - - ld a, (hl) - ld b, a - ld hl, (SHELL_MEM_PTR) -.loop: call stdioGetC - jr nz, .loop ; nothing typed? loop - ld (hl), a - inc hl - djnz .loop - - pop hl - pop bc - xor a - ret - -; Calls the routine where the memory pointer currently points. This can take two -; parameters, A and HL. The first one is a byte, the second, a word. These are -; the values that A and HL are going to be set to just before calling. -; Example: run 42 cafe -shellCallCmd: - .db "call", 0b101, 0b111, 0b001 -shellCall: - push hl - push ix - - ; Let's recap here. At this point, we have: - ; 1. The address we want to execute in (SHELL_MEM_PTR) - ; 2. our A arg as the first byte of (HL) - ; 2. our HL arg as (HL+1) and (HL+2) - ; Ready, set, go! - ld ix, (SHELL_MEM_PTR) - ld a, (hl) - ex af, af' - inc hl - ld a, (hl) - exx - ld h, a - exx - inc hl - ld a, (hl) - exx - ld l, a - ex af, af' - call callIX - -.end: - pop ix - pop hl - xor a - ret - -shellIORDCmd: - .db "iord", 0b001, 0, 0 - push bc - ld a, (hl) - ld c, a - in a, (c) - call printHex - xor a - pop bc - ret - -shellIOWRCmd: - .db "iowr", 0b001, 0b001, 0 - push bc - ld a, (hl) - ld c, a - inc hl - ld a, (hl) - out (c), a - xor a - pop bc - ret - -; This table is at the very end of the file on purpose. The idea is to be able -; to graft extra commands easily after an include in the glue file. -shellCmdTbl: - .dw shellMptrCmd, shellPeekCmd, shellPokeCmd, shellCallCmd - .dw shellIORDCmd, shellIOWRCmd - diff --git a/apps/shell/pgm.asm b/apps/shell/pgm.asm deleted file mode 100644 index bc3bfe3..0000000 --- a/apps/shell/pgm.asm +++ /dev/null @@ -1,51 +0,0 @@ -; pgm - execute programs loaded from filesystem -; -; Implements a shell hook that searches the filesystem for a file with the same -; name as the cmd, loads that file in memory and executes it, sending the -; program a pointer to *unparsed* arguments in HL. -; -; We expect the loaded program to return a status code in A. 0 means success, -; non-zero means error. Programs should avoid having error code overlaps with -; the shell so that we know where the error comes from. -; -; *** Requirements *** -; fs -; -; *** Defines *** -; PGM_CODEADDR: Memory address where to place the code we load. -; -; *** Variables *** -.equ PGM_HANDLE PGM_RAMSTART -.equ PGM_RAMEND @+FS_HANDLE_SIZE - -; Routine suitable to plug into SHELL_CMDHOOK. HL points to the full cmdline. -; which has been processed to replace the first ' ' with a null char. -pgmShellHook: - ; (HL) is suitable for a direct fsFindFN call - call fsFindFN - jr nz, .noFile - ; We have a file! Advance HL to args - xor a - call findchar - inc hl ; beginning of args - ; Alright, ready to run! - jp .run -.noFile: - ld a, SHELL_ERR_IO_ERROR - ret -.run: - push hl ; unparsed args - ld ix, PGM_HANDLE - call fsOpen - ld hl, 0 ; addr that we read in file handle - ld de, PGM_CODEADDR ; addr in mem we write to -.loop: - call fsGetB ; we use Z at end of loop - ld (de), a ; Z preserved - inc hl ; Z preserved in 16-bit - inc de ; Z preserved in 16-bit - jr z, .loop - - pop hl ; recall args - ; ready to jump! - jp PGM_CODEADDR diff --git a/recipes/rc2014/README.md b/recipes/rc2014/README.md index 72980e5..a137888 100644 --- a/recipes/rc2014/README.md +++ b/recipes/rc2014/README.md @@ -27,11 +27,11 @@ are other recipes related to the RC2014: * [Accessing a MicroSD card](sdcard/README.md) * [Assembling binaries](zasm/README.md) * [Interfacing a PS/2 keyboard](ps2/README.md) -* [Replace shell by a BASIC interpreter](basic/README.md) ## Recipe The goal is to have the shell running and accessible through the Serial I/O. +To make things fun, we play with I/Os using RC2014's Digital I/O module. You'll need specialized tools to write data to the AT28 EEPROM. There seems to be many devices around made to write in flash and EEPROM modules, but being in @@ -44,6 +44,7 @@ device I use in this recipe. * [romwrite][romwrite] and its specified dependencies * [GNU screen][screen] * A FTDI-to-TTL cable to connect to the Serial I/O module of the RC2014 +* (Optional) RC2014's Digital I/O module ### Write glue.asm @@ -62,15 +63,15 @@ Then comes the usual `di` to aoid interrupts during init, and stack setup. We set interrupt mode to 1 because that's what `acia.asm` is written around. Then, we init ACIA, shell, enable interrupt and give control of the main loop -to `shell.asm`. +to the BASIC shell. What comes below is actual code include from parts we want to include in our OS. As you can see, we need to tell each module where to put their variables. -See `parts/README.md` for details. +See `apps/README.md` for details. -You can also see from the `SHELL_GETC` and `SHELL_PUTC` macros that the shell -is decoupled from the ACIA and can get its IO from anything. See -`parts/README.md` for details. +You can also see from the `STDIO_GETC` and `STDIO_PUTC` macros that the shell +is decoupled from the ACIA and can get its IO from anything. See comments in +`kernel/stdio.asm` for details. ### Build the image @@ -100,6 +101,20 @@ identify the tty bound to it (in my case, `/dev/ttyUSB0`). Then: screen /dev/ttyUSB0 115200 Press the reset button on the RC2014 and you should see the Collapse OS prompt! +See documentation in `apps/basic/README.md` for details. + +For now, let's have some fun with the Digital I/O module. Type this: + +``` +> a=0 +> 10 out 0 a +> 20 sleep 0xffff +> 30 a=a+1 +> 40 goto 10 +> run +``` + +You now have your Digital I/O lights doing a pretty dance, forever. [rc2014]: https://rc2014.co.uk [romwrite]: https://github.com/hsoft/romwrite diff --git a/recipes/rc2014/basic/Makefile b/recipes/rc2014/basic/Makefile deleted file mode 100644 index 33fd356..0000000 --- a/recipes/rc2014/basic/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -TARGET = os.bin -ZASM = ../../../tools/zasm.sh -KERNEL = ../../../kernel -APPS = ../../../apps - -.PHONY: all -all: $(TARGET) -$(TARGET): glue.asm - $(ZASM) $(KERNEL) $(APPS) < $< > $@ - diff --git a/recipes/rc2014/basic/README.md b/recipes/rc2014/basic/README.md deleted file mode 100644 index 5ae58b6..0000000 --- a/recipes/rc2014/basic/README.md +++ /dev/null @@ -1,46 +0,0 @@ -# BASIC as a shell - -This recipe demonstrate the replacement of the usual shell with the BASIC -interpreter supplied in Collapse OS. To make things fun, we play with I/Os -using RC2014's Digital I/O module. - -## Gathering parts - -* Same parts as in the base recipe -* (Optional) RC2014's Digital I/O module - -The Digital I/O module is only used in the example BASIC code. If you don't -have the module, just use BASIC in another fashion. - -## Build the image - -As usual, building `os.bin` is a matter of running `make`. Then, you can get -that image to your EEPROM like you did in the base recipe. - -## Usage - -Upon boot, you'll directy be in a BASIC prompt. See documentation in -`apps/basic/README.md` for details. - -For now, let's have some fun with the Digital I/O module. Type this: - -``` -> a=0 -> 10 out 0 a -> 20 sleep 0xffff -> 30 a=a+1 -> 40 goto 10 -> run -``` - -You now have your Digital I/O lights doing a pretty dance, forever. - -## Looking at the glue code - -If you look at the glue code, you'll see that it's very similar to the one in -the base recipe, except that the shell includes have been replaced by the basic -includes. Those includes have been copy/pasted from `apps/basic/glue.asm` and -`USER_RAMSTART` has been replaced with `STDIO_RAMEND` so that BASIC's memory -gets placed properly (that is, right after the kernel's memory). - -Simple, isn't it? diff --git a/recipes/rc2014/basic/glue.asm b/recipes/rc2014/basic/glue.asm deleted file mode 100644 index edf417b..0000000 --- a/recipes/rc2014/basic/glue.asm +++ /dev/null @@ -1,57 +0,0 @@ -.equ RAMSTART 0x8000 -.equ RAMEND 0xffff -.equ ACIA_CTL 0x80 ; Control and status. RS off. -.equ ACIA_IO 0x81 ; Transmit. RS on. -.equ DIGIT_IO 0x00 ; digital I/O's port - -jp init - -; interrupt hook -.fill 0x38-$ -jp aciaInt - -.inc "err.h" -.inc "ascii.h" -.inc "core.asm" -.inc "str.asm" -.equ ACIA_RAMSTART RAMSTART -.inc "acia.asm" - -.equ STDIO_RAMSTART ACIA_RAMEND -.equ STDIO_GETC aciaGetC -.equ STDIO_PUTC aciaPutC -.inc "stdio.asm" - -; *** BASIC *** - -; RAM space used in different routines for short term processing. -.equ SCRATCHPAD_SIZE 0x20 -.equ SCRATCHPAD STDIO_RAMEND -.inc "lib/util.asm" -.inc "lib/ari.asm" -.inc "lib/parse.asm" -.inc "lib/fmt.asm" -.equ EXPR_PARSE parseLiteralOrVar -.inc "lib/expr.asm" -.inc "basic/util.asm" -.inc "basic/parse.asm" -.inc "basic/tok.asm" -.equ VAR_RAMSTART SCRATCHPAD+SCRATCHPAD_SIZE -.inc "basic/var.asm" -.equ BUF_RAMSTART VAR_RAMEND -.inc "basic/buf.asm" -.equ BAS_RAMSTART BUF_RAMEND -.inc "basic/main.asm" - -init: - di - ; setup stack - ld sp, RAMEND - im 1 - - call aciaInit - ei - call basInit - jp basStart - - diff --git a/recipes/rc2014/glue.asm b/recipes/rc2014/glue.asm index f1735ae..edf417b 100644 --- a/recipes/rc2014/glue.asm +++ b/recipes/rc2014/glue.asm @@ -1,9 +1,8 @@ -; classic RC2014 setup (8K ROM + 32K RAM) and a stock Serial I/O module -; The RAM module is selected on A15, so it has the range 0x8000-0xffff .equ RAMSTART 0x8000 .equ RAMEND 0xffff .equ ACIA_CTL 0x80 ; Control and status. RS off. .equ ACIA_IO 0x81 ; Transmit. RS on. +.equ DIGIT_IO 0x00 ; digital I/O's port jp init @@ -23,24 +22,36 @@ jp aciaInt .equ STDIO_PUTC aciaPutC .inc "stdio.asm" -; *** Shell *** +; *** BASIC *** + +; RAM space used in different routines for short term processing. +.equ SCRATCHPAD_SIZE 0x20 +.equ SCRATCHPAD STDIO_RAMEND .inc "lib/util.asm" +.inc "lib/ari.asm" .inc "lib/parse.asm" -.inc "lib/args.asm" -.inc "lib/stdio.asm" -.equ SHELL_RAMSTART STDIO_RAMEND -.equ SHELL_EXTRA_CMD_COUNT 0 -.inc "shell/main.asm" +.inc "lib/fmt.asm" +.equ EXPR_PARSE parseLiteralOrVar +.inc "lib/expr.asm" +.inc "basic/util.asm" +.inc "basic/parse.asm" +.inc "basic/tok.asm" +.equ VAR_RAMSTART SCRATCHPAD+SCRATCHPAD_SIZE +.inc "basic/var.asm" +.equ BUF_RAMSTART VAR_RAMEND +.inc "basic/buf.asm" +.equ BAS_RAMSTART BUF_RAMEND +.inc "basic/main.asm" init: di ; setup stack - ld hl, RAMEND - ld sp, hl + ld sp, RAMEND im 1 call aciaInit - call shellInit ei - jp shellLoop + call basInit + jp basStart + diff --git a/recipes/rc2014/zasm/README.md b/recipes/rc2014/zasm/README.md index 41d1f04..c99cf7e 100644 --- a/recipes/rc2014/zasm/README.md +++ b/recipes/rc2014/zasm/README.md @@ -48,9 +48,9 @@ Compiling and running `hello.asm` is done very much like in Collapse OS > sdci > fson - > fopn 0 hello.asm + > fopen 0 hello.asm > fnew 1 dest - > fopn 1 dest + > fopen 1 dest > zasm 1 2 > dest Assembled from a RC2014 @@ -94,7 +94,7 @@ Now you can write this into your card and boot Collapse OS: > fson > fopn 0 glue.asm > fnew 10 dest - > fopn 1 dest + > fopen 1 dest > zasm 1 2 # This takes a while. About 7 minutes. > sdcf # success! sdcf flushes SD card buffers to the card. diff --git a/tools/emul/Makefile b/tools/emul/Makefile index 05a5425..b77838a 100644 --- a/tools/emul/Makefile +++ b/tools/emul/Makefile @@ -1,5 +1,5 @@ CFSPACK = ../cfspack/cfspack -TARGETS = shell/shell bshell/shell zasm/zasm runbin/runbin +TARGETS = shell/shell zasm/zasm runbin/runbin KERNEL = ../../kernel APPS = ../../apps ZASMBIN = zasm/zasm @@ -13,17 +13,11 @@ OBJS = emul.o libz80/libz80.o all: $(TARGETS) $(CFSIN_CONTENTS) # -o in sync with SHELL_CODE in shell/glue.asm -shell/shell.bin: $(APPS)/shell/glue.asm $(ZASMBIN) - $(ZASMSH) -o 07 $(KERNEL) shell/user.h $(APPS) < $(APPS)/shell/glue.asm | tee $@ > /dev/null +shell/shell.bin: shell/glue.asm $(ZASMBIN) + $(ZASMSH) $(KERNEL) shell/user.h $(APPS) < shell/glue.asm | tee $@ > /dev/null -shell/kernel-bin.h: shell/glue.asm shell/shell.bin $(ZASMBIN) - $(ZASMSH) $(KERNEL) shell/shell.bin < shell/glue.asm | ./bin2c.sh KERNEL | tee $@ > /dev/null - -bshell/shell.bin: bshell/glue.asm $(ZASMBIN) - $(ZASMSH) $(KERNEL) bshell/user.h $(APPS) < bshell/glue.asm | tee $@ > /dev/null - -bshell/shell-bin.h: bshell/shell.bin - ./bin2c.sh KERNEL < bshell/shell.bin | tee $@ > /dev/null +shell/shell-bin.h: shell/shell.bin + ./bin2c.sh KERNEL < shell/shell.bin | tee $@ > /dev/null zasm/kernel-bin.h: zasm/kernel.bin ./bin2c.sh KERNEL < zasm/kernel.bin | tee $@ > /dev/null @@ -31,12 +25,9 @@ zasm/kernel-bin.h: zasm/kernel.bin zasm/zasm-bin.h: zasm/zasm.bin ./bin2c.sh USERSPACE < zasm/zasm.bin | tee $@ > /dev/null -shell/shell: shell/shell.c $(OBJS) shell/kernel-bin.h +shell/shell: shell/shell.c $(OBJS) shell/shell-bin.h $(CC) shell/shell.c $(OBJS) -o $@ -bshell/shell: bshell/shell.c $(OBJS) bshell/shell-bin.h - $(CC) bshell/shell.c $(OBJS) -o $@ - $(ZASMBIN): zasm/zasm.c $(OBJS) zasm/kernel-bin.h zasm/zasm-bin.h $(CFSPACK) $(CC) zasm/zasm.c $(OBJS) -o $@ diff --git a/tools/emul/README.md b/tools/emul/README.md index 1860efd..f27efa4 100644 --- a/tools/emul/README.md +++ b/tools/emul/README.md @@ -12,11 +12,11 @@ After that, you can run `make` and it builds all tools. ## shell -Running `shell/shell` runs the shell in an emulated machine. The goal of this -machine is not to simulate real hardware, but rather to serve as a development -platform. What we do here is we emulate the z80 part, the 64K memory space and -then hook some fake I/Os to stdin, stdout and a small storage device that is -suitable for Collapse OS's filesystem to run on. +Running `shell/shell` runs the BASIC shell in an emulated machine. The goal of +this machine is not to simulate real hardware, but rather to serve as a +development platform. What we do here is we emulate the z80 part, the 64K +memory space and then hook some fake I/Os to stdin, stdout and a small storage +device that is suitable for Collapse OS's filesystem to run on. Through that, it becomes easier to develop userspace applications for Collapse OS. @@ -25,11 +25,6 @@ We don't try to emulate real hardware to ease the development of device drivers because so far, I don't see the advantage of emulation versus running code on the real thing. -## bshell - -The `basic` app is on its way to replace the shell. It is wrapped in the z80 -emulator in the same way that the shell is and interacts with `cfsin` similarly. - ## zasm `zasm/zasm` is `apps/zasm` wrapped in an emulator. It is quite central to the diff --git a/tools/emul/bshell/glue.asm b/tools/emul/bshell/glue.asm deleted file mode 100644 index 80b0c97..0000000 --- a/tools/emul/bshell/glue.asm +++ /dev/null @@ -1,178 +0,0 @@ -.inc "blkdev.h" -.inc "fs.h" -.inc "err.h" -.inc "ascii.h" -.equ RAMSTART 0x2000 -.equ USER_CODE 0x4200 -.equ STDIO_PORT 0x00 -.equ FS_DATA_PORT 0x01 -.equ FS_ADDR_PORT 0x02 - - jp init - -; *** JUMP TABLE *** - jp strncmp - jp upcase - jp findchar - jp blkSelPtr - jp blkSel - jp blkSet - jp blkSeek - jp blkTell - jp blkGetB - jp blkPutB - jp fsFindFN - jp fsOpen - jp fsGetB - jp fsPutB - jp fsSetSize - jp fsOn - jp fsIter - jp fsAlloc - jp fsDel - jp fsHandle - jp printstr - jp printnstr - jp _blkGetB - jp _blkPutB - jp _blkSeek - jp _blkTell - jp printcrlf - jp stdioGetC - jp stdioPutC - jp stdioReadLine - -.inc "core.asm" -.inc "str.asm" - -.equ BLOCKDEV_RAMSTART RAMSTART -.equ BLOCKDEV_COUNT 4 -.inc "blockdev.asm" -; List of devices -.dw fsdevGetB, fsdevPutB -.dw stdoutGetB, stdoutPutB -.dw stdinGetB, stdinPutB -.dw mmapGetB, mmapPutB - - -.equ MMAP_START 0xe000 -.inc "mmap.asm" - -.equ STDIO_RAMSTART BLOCKDEV_RAMEND -.equ STDIO_GETC emulGetC -.equ STDIO_PUTC emulPutC -.inc "stdio.asm" - -.equ FS_RAMSTART STDIO_RAMEND -.equ FS_HANDLE_COUNT 2 -.inc "fs.asm" - -; *** BASIC *** - -; RAM space used in different routines for short term processing. -.equ SCRATCHPAD_SIZE 0x20 -.equ SCRATCHPAD FS_RAMEND -.inc "lib/util.asm" -.inc "lib/ari.asm" -.inc "lib/parse.asm" -.inc "lib/fmt.asm" -.equ EXPR_PARSE parseLiteralOrVar -.inc "lib/expr.asm" -.inc "basic/util.asm" -.inc "basic/parse.asm" -.inc "basic/tok.asm" -.equ VAR_RAMSTART SCRATCHPAD+SCRATCHPAD_SIZE -.inc "basic/var.asm" -.equ BUF_RAMSTART VAR_RAMEND -.inc "basic/buf.asm" -.equ BFS_RAMSTART BUF_RAMEND -.inc "basic/fs.asm" -.inc "basic/blk.asm" -.equ BAS_RAMSTART BFS_RAMEND -.inc "basic/main.asm" - -init: - di - ; setup stack - ld sp, 0xffff - call fsInit - ld a, 0 ; select fsdev - ld de, BLOCKDEV_SEL - call blkSel - call fsOn - call basInit - ld hl, basFindCmdExtra - ld (BAS_FINDHOOK), hl - jp basStart - -basFindCmdExtra: - ld hl, basFSCmds - call basFindCmd - ret z - ld hl, basBLKCmds - call basFindCmd - ret z - jp basPgmHook - -emulGetC: - ; Blocks until a char is returned - in a, (STDIO_PORT) - cp a ; ensure Z - ret - -emulPutC: - out (STDIO_PORT), a - ret - -fsdevGetB: - ld a, e - out (FS_ADDR_PORT), a - ld a, h - out (FS_ADDR_PORT), a - ld a, l - out (FS_ADDR_PORT), a - in a, (FS_ADDR_PORT) - or a - ret nz - in a, (FS_DATA_PORT) - cp a ; ensure Z - ret - -fsdevPutB: - push af - ld a, e - out (FS_ADDR_PORT), a - ld a, h - out (FS_ADDR_PORT), a - ld a, l - out (FS_ADDR_PORT), a - in a, (FS_ADDR_PORT) - cp 2 ; only A > 1 means error - jr nc, .error ; A >= 2 - pop af - out (FS_DATA_PORT), a - cp a ; ensure Z - ret -.error: - pop af - jp unsetZ ; returns - -.equ STDOUT_HANDLE FS_HANDLES - -stdoutGetB: - ld ix, STDOUT_HANDLE - jp fsGetB - -stdoutPutB: - ld ix, STDOUT_HANDLE - jp fsPutB - -.equ STDIN_HANDLE FS_HANDLES+FS_HANDLE_SIZE - -stdinGetB: - ld ix, STDIN_HANDLE - jp fsGetB - -stdinPutB: - ld ix, STDIN_HANDLE - jp fsPutB diff --git a/tools/emul/bshell/shell.c b/tools/emul/bshell/shell.c deleted file mode 100644 index 2560414..0000000 --- a/tools/emul/bshell/shell.c +++ /dev/null @@ -1,191 +0,0 @@ -#include -#include -#include -#include "../emul.h" -#include "shell-bin.h" - -/* Collapse OS shell with filesystem - * - * On startup, if "cfsin" directory exists, it packs it as a afke block device - * and loads it in. Upon halting, unpcks the contents of that block device in - * "cfsout" directory. - * - * Memory layout: - * - * 0x0000 - 0x3fff: ROM code from shell.asm - * 0x4000 - 0x4fff: Kernel memory - * 0x5000 - 0xffff: Userspace - * - * I/O Ports: - * - * 0 - stdin / stdout - * 1 - Filesystem blockdev data read/write. Reads and write data to the address - * previously selected through port 2 - */ - -//#define DEBUG -#define MAX_FSDEV_SIZE 0x20000 - -// in sync with glue.asm -#define RAMSTART 0x2000 -#define STDIO_PORT 0x00 -#define FS_DATA_PORT 0x01 -// Controls what address (24bit) the data port returns. To select an address, -// this port has to be written to 3 times, starting with the MSB. -// Reading this port returns an out-of-bounds indicator. Meaning: -// 0 means addr is within bounds -// 1 means that we're equal to fsdev size (error for reading, ok for writing) -// 2 means more than fsdev size (always invalid) -// 3 means incomplete addr setting -#define FS_ADDR_PORT 0x02 - -static uint8_t fsdev[MAX_FSDEV_SIZE] = {0}; -static uint32_t fsdev_size = 0; -static uint32_t fsdev_ptr = 0; -// 0 = idle, 1 = received MSB (of 24bit addr), 2 = received middle addr -static int fsdev_addr_lvl = 0; -static int running; - -static uint8_t iord_stdio() -{ - int c = getchar(); - if (c == EOF) { - running = 0; - } - return (uint8_t)c; -} - -static uint8_t iord_fsdata() -{ - if (fsdev_addr_lvl != 0) { - fprintf(stderr, "Reading FSDEV in the middle of an addr op (%d)\n", fsdev_ptr); - return 0; - } - if (fsdev_ptr < fsdev_size) { -#ifdef DEBUG - fprintf(stderr, "Reading FSDEV at offset %d\n", fsdev_ptr); -#endif - return fsdev[fsdev_ptr]; - } else { - // don't warn when ==, we're not out of bounds, just at the edge. - if (fsdev_ptr > fsdev_size) { - fprintf(stderr, "Out of bounds FSDEV read at %d\n", fsdev_ptr); - } - return 0; - } -} - -static uint8_t iord_fsaddr() -{ - if (fsdev_addr_lvl != 0) { - return 3; - } else if (fsdev_ptr > fsdev_size) { - fprintf(stderr, "Out of bounds FSDEV addr request at %d / %d\n", fsdev_ptr, fsdev_size); - return 2; - } else if (fsdev_ptr == fsdev_size) { - return 1; - } else { - return 0; - } -} - -static void iowr_stdio(uint8_t val) -{ - if (val == 0x04) { // CTRL+D - running = 0; - } else { - putchar(val); - } -} - -static void iowr_fsdata(uint8_t val) -{ - if (fsdev_addr_lvl != 0) { - fprintf(stderr, "Writing to FSDEV in the middle of an addr op (%d)\n", fsdev_ptr); - return; - } - if (fsdev_ptr < fsdev_size) { -#ifdef DEBUG - fprintf(stderr, "Writing to FSDEV (%d)\n", fsdev_ptr); -#endif - fsdev[fsdev_ptr] = val; - } else if ((fsdev_ptr == fsdev_size) && (fsdev_ptr < MAX_FSDEV_SIZE)) { - // We're at the end of fsdev, grow it - fsdev[fsdev_ptr] = val; - fsdev_size++; -#ifdef DEBUG - fprintf(stderr, "Growing FSDEV (%d)\n", fsdev_ptr); -#endif - } else { - fprintf(stderr, "Out of bounds FSDEV write at %d\n", fsdev_ptr); - } -} - -static void iowr_fsaddr(uint8_t val) -{ - if (fsdev_addr_lvl == 0) { - fsdev_ptr = val << 16; - fsdev_addr_lvl = 1; - } else if (fsdev_addr_lvl == 1) { - fsdev_ptr |= val << 8; - fsdev_addr_lvl = 2; - } else { - fsdev_ptr |= val; - fsdev_addr_lvl = 0; - } -} - -int main() -{ - // Setup fs blockdev - FILE *fp = popen("../cfspack/cfspack cfsin", "r"); - if (fp != NULL) { - printf("Initializing filesystem\n"); - int i = 0; - int c = fgetc(fp); - while (c != EOF) { - fsdev[i] = c & 0xff; - i++; - c = fgetc(fp); - } - fsdev_size = i; - pclose(fp); - } else { - printf("Can't initialize filesystem. Leaving blank.\n"); - } - - // Turn echo off: the shell takes care of its own echoing. - struct termios termInfo; - if (tcgetattr(0, &termInfo) == -1) { - printf("Can't setup terminal.\n"); - return 1; - } - termInfo.c_lflag &= ~ECHO; - termInfo.c_lflag &= ~ICANON; - tcsetattr(0, TCSAFLUSH, &termInfo); - - - Machine *m = emul_init(); - m->ramstart = RAMSTART; - m->iord[STDIO_PORT] = iord_stdio; - m->iord[FS_DATA_PORT] = iord_fsdata; - m->iord[FS_ADDR_PORT] = iord_fsaddr; - m->iowr[STDIO_PORT] = iowr_stdio; - m->iowr[FS_DATA_PORT] = iowr_fsdata; - m->iowr[FS_ADDR_PORT] = iowr_fsaddr; - // initialize memory - for (int i=0; imem[i] = KERNEL[i]; - } - // Run! - running = 1; - - while (running && emul_step()); - - printf("Done!\n"); - termInfo.c_lflag |= ECHO; - termInfo.c_lflag |= ICANON; - tcsetattr(0, TCSAFLUSH, &termInfo); - emul_printdebug(); - return 0; -} diff --git a/tools/emul/bshell/user.h b/tools/emul/bshell/user.h deleted file mode 100644 index 47aac6d..0000000 --- a/tools/emul/bshell/user.h +++ /dev/null @@ -1,35 +0,0 @@ -.equ SHELL_RAMSTART 0x4100 -.equ USER_CODE 0x4200 ; in sync with glue.asm - -; *** JUMP TABLE *** -.equ strncmp 0x03 -.equ upcase @+3 -.equ findchar @+3 -.equ blkSelPtr @+3 -.equ blkSel @+3 -.equ blkSet @+3 -.equ blkSeek @+3 -.equ blkTell @+3 -.equ blkGetB @+3 -.equ blkPutB @+3 -.equ fsFindFN @+3 -.equ fsOpen @+3 -.equ fsGetB @+3 -.equ fsPutB @+3 -.equ fsSetSize @+3 -.equ fsOn @+3 -.equ fsIter @+3 -.equ fsAlloc @+3 -.equ fsDel @+3 -.equ fsHandle @+3 -.equ printstr @+3 -.equ printnstr @+3 -.equ _blkGetB @+3 -.equ _blkPutB @+3 -.equ _blkSeek @+3 -.equ _blkTell @+3 -.equ printcrlf @+3 -.equ stdioGetC @+3 -.equ stdioPutC @+3 -.equ stdioReadLine @+3 - diff --git a/tools/emul/shell/glue.asm b/tools/emul/shell/glue.asm index c74df59..80b0c97 100644 --- a/tools/emul/shell/glue.asm +++ b/tools/emul/shell/glue.asm @@ -1,17 +1,9 @@ -; Last check: -; Kernel size: 0x619 -; Kernel RAM usage: 0x66 -; Shell size: 0x411 -; Shell RAM usage: 0x11 - .inc "blkdev.h" .inc "fs.h" .inc "err.h" .inc "ascii.h" -.equ RAMSTART 0x4000 -; 0x100 - 0x66 gives us a nice space for the stack. -.equ KERNEL_RAMEND 0x4100 -.equ SHELL_CODE 0x0700 +.equ RAMSTART 0x2000 +.equ USER_CODE 0x4200 .equ STDIO_PORT 0x00 .equ FS_DATA_PORT 0x01 .equ FS_ADDR_PORT 0x02 @@ -75,16 +67,52 @@ .equ FS_HANDLE_COUNT 2 .inc "fs.asm" +; *** BASIC *** + +; RAM space used in different routines for short term processing. +.equ SCRATCHPAD_SIZE 0x20 +.equ SCRATCHPAD FS_RAMEND +.inc "lib/util.asm" +.inc "lib/ari.asm" +.inc "lib/parse.asm" +.inc "lib/fmt.asm" +.equ EXPR_PARSE parseLiteralOrVar +.inc "lib/expr.asm" +.inc "basic/util.asm" +.inc "basic/parse.asm" +.inc "basic/tok.asm" +.equ VAR_RAMSTART SCRATCHPAD+SCRATCHPAD_SIZE +.inc "basic/var.asm" +.equ BUF_RAMSTART VAR_RAMEND +.inc "basic/buf.asm" +.equ BFS_RAMSTART BUF_RAMEND +.inc "basic/fs.asm" +.inc "basic/blk.asm" +.equ BAS_RAMSTART BFS_RAMEND +.inc "basic/main.asm" + init: di ; setup stack - ld sp, KERNEL_RAMEND + ld sp, 0xffff call fsInit ld a, 0 ; select fsdev ld de, BLOCKDEV_SEL call blkSel call fsOn - call SHELL_CODE + call basInit + ld hl, basFindCmdExtra + ld (BAS_FINDHOOK), hl + jp basStart + +basFindCmdExtra: + ld hl, basFSCmds + call basFindCmd + ret z + ld hl, basBLKCmds + call basFindCmd + ret z + jp basPgmHook emulGetC: ; Blocks until a char is returned @@ -148,6 +176,3 @@ stdinGetB: stdinPutB: ld ix, STDIN_HANDLE jp fsPutB - -.fill SHELL_CODE-$ -.bin "shell.bin" diff --git a/tools/emul/shell/shell.c b/tools/emul/shell/shell.c index 215dace..2560414 100644 --- a/tools/emul/shell/shell.c +++ b/tools/emul/shell/shell.c @@ -2,7 +2,7 @@ #include #include #include "../emul.h" -#include "kernel-bin.h" +#include "shell-bin.h" /* Collapse OS shell with filesystem * @@ -26,8 +26,8 @@ //#define DEBUG #define MAX_FSDEV_SIZE 0x20000 -// in sync with shell.asm -#define RAMSTART 0x4000 +// in sync with glue.asm +#define RAMSTART 0x2000 #define STDIO_PORT 0x00 #define FS_DATA_PORT 0x01 // Controls what address (24bit) the data port returns. To select an address, diff --git a/tools/emul/shell/user.h b/tools/emul/shell/user.h index 2fb0145..47aac6d 100644 --- a/tools/emul/shell/user.h +++ b/tools/emul/shell/user.h @@ -1,5 +1,5 @@ .equ SHELL_RAMSTART 0x4100 -.equ USER_CODE 0x4200 +.equ USER_CODE 0x4200 ; in sync with glue.asm ; *** JUMP TABLE *** .equ strncmp 0x03