1
0
mirror of https://github.com/hsoft/collapseos.git synced 2024-11-02 18:10:55 +11:00

Compare commits

..

3 Commits

Author SHA1 Message Date
Virgil Dupras
2860a10f71 recipes/trs80: add CFS support 2020-02-22 20:06:59 -05:00
Virgil Dupras
ec6df3087d recipes/trs80: add "recv" command
This allows us to write contents from RS-232 directly to floppy! it works!
2020-02-22 14:43:07 -05:00
Virgil Dupras
049f2cf222 Reverse ttysafe escaping order
Sending the escape after its target made things complicated for upcoming
stuff I want to add. Although it makes `recv.asm` slightly larger, it's really
worth it.
2020-02-22 14:11:43 -05:00
4 changed files with 133 additions and 18 deletions

View File

@ -204,4 +204,21 @@ get a usable Collapse OS prompt!
Like with the `recv` program, nothing stops you from dumping that binary to a Like with the `recv` program, nothing stops you from dumping that binary to a
floppy. floppy.
Have fun! ## Configuration
In addition to the generic basic shell, this build of Collapse OS has support
for floppy drive `:1` as a block device (mapped to device `0`). Block device
commands work as expected.
In addition to this, there is a `flush` command to ensure that dirty buffers are
synced to disk. Make sure you run this after a write operation or before
swapping disks.
On top of that, there's CFS support builtin. To enable a FS, type `fson` while
the active block device is properly placed (you can initialize a new FS by
writing `CFS\0\0\0\0` to the disk). If it doesn't error out, commands like
`fls` and `fnew` will work. Don't forget to flush when you're finished :)
There is also a custom `recv` command that does the same "ping pong" as in
`recv.asm`, but once. It puts the result in `A`. This can be useful to send down
a raw CFS: you just need a while loop that repeatedly call `recv:putb a`.

View File

@ -1,5 +1,9 @@
; RAMSTART is a label at the end of the file ; RAMSTART is a label at the end of the file
.equ RAMEND 0xcfff .equ RAMEND 0xcfff
; Address of the *CL driver. Same as in recv.asm
.equ COM_DRV_ADDR 0x0238
; in sync with user.h. Last BAS_RAMEND: 0x5705
.equ USER_CODE 0x5800
; Free memory in TRSDOS starts at 0x3000 ; Free memory in TRSDOS starts at 0x3000
.org 0x3000 .org 0x3000
@ -7,6 +11,7 @@
.inc "err.h" .inc "err.h"
.inc "blkdev.h" .inc "blkdev.h"
.inc "fs.h"
.inc "ascii.h" .inc "ascii.h"
.inc "core.asm" .inc "core.asm"
.inc "str.asm" .inc "str.asm"
@ -17,16 +22,22 @@
.inc "trs80/floppy.asm" .inc "trs80/floppy.asm"
.equ BLOCKDEV_RAMSTART FLOPPY_RAMEND .equ BLOCKDEV_RAMSTART FLOPPY_RAMEND
.equ BLOCKDEV_COUNT 1 .equ BLOCKDEV_COUNT 3
.inc "blockdev.asm" .inc "blockdev.asm"
; List of devices ; List of devices
.dw floppyGetB, floppyPutB .dw floppyGetB, floppyPutB
.dw blk1GetB, blk1PutB
.dw blk2GetB, blk2PutB
.equ STDIO_RAMSTART BLOCKDEV_RAMEND .equ STDIO_RAMSTART BLOCKDEV_RAMEND
.equ STDIO_GETC trs80GetC .equ STDIO_GETC trs80GetC
.equ STDIO_PUTC trs80PutC .equ STDIO_PUTC trs80PutC
.inc "stdio.asm" .inc "stdio.asm"
.equ FS_RAMSTART STDIO_RAMEND
.equ FS_HANDLE_COUNT 2
.inc "fs.asm"
; The TRS-80 generates a double line feed if we give it both CR and LF. ; The TRS-80 generates a double line feed if we give it both CR and LF.
.equ printcrlf printcr .equ printcrlf printcr
@ -34,7 +45,7 @@
; RAM space used in different routines for short term processing. ; RAM space used in different routines for short term processing.
.equ SCRATCHPAD_SIZE STDIO_BUFSIZE .equ SCRATCHPAD_SIZE STDIO_BUFSIZE
.equ SCRATCHPAD STDIO_RAMEND .equ SCRATCHPAD FS_RAMEND
.inc "lib/util.asm" .inc "lib/util.asm"
.inc "lib/ari.asm" .inc "lib/ari.asm"
.inc "lib/parse.asm" .inc "lib/parse.asm"
@ -48,14 +59,19 @@
.inc "basic/var.asm" .inc "basic/var.asm"
.equ BUF_RAMSTART VAR_RAMEND .equ BUF_RAMSTART VAR_RAMEND
.inc "basic/buf.asm" .inc "basic/buf.asm"
.equ BFS_RAMSTART BUF_RAMEND
.inc "basic/fs.asm"
.inc "basic/blk.asm" .inc "basic/blk.asm"
.inc "basic/floppy.asm" .inc "basic/floppy.asm"
.equ BAS_RAMSTART BUF_RAMEND .equ BAS_RAMSTART BFS_RAMEND
.inc "basic/main.asm" .inc "basic/main.asm"
.out BAS_RAMEND
init: init:
ld sp, RAMEND ld sp, RAMEND
call floppyInit call floppyInit
call fsInit
call basInit call basInit
ld hl, basFindCmdExtra ld hl, basFindCmdExtra
ld (BAS_FINDHOOK), hl ld (BAS_FINDHOOK), hl
@ -73,11 +89,84 @@ printcr:
pop af pop af
ret ret
; Receive a byte from *cl and put it in A.
; Returns A > 0xff when receiving the last byte
recvCmd:
xor a
ld (VAR_TBL+1), a ; pre-set MSB
; put a 0xff mask in B, which will become 0x7f if we receive a 0x20
ld b, 0xff
.inner:
ld a, 0x03 ; @GET
ld de, COM_DRV_ADDR
rst 0x28
jr nz, .maybeerror
or a
jr z, .eof ; Sending a straight NULL ends the comm.
; @PUT that char back
ld c, a
ld a, 0x04 ; @PUT
ld de, COM_DRV_ADDR
rst 0x28
ret nz ; error
ld a, c
cp 0x20
jr z, .escapechar
; not an escape char, good
and b ; apply mask
ld (VAR_TBL), a
xor a ; ensure Z
ret
.maybeerror:
; was it an error?
or a
jr z, .inner ; not an error, just loop
ret ; error
.escapechar:
ld b, 0x7f
jr .inner
.eof:
dec a ; A = 0xff
ld (VAR_TBL+1), a
xor a ; ensure Z
ret
basFindCmdExtra: basFindCmdExtra:
ld hl, basFloppyCmds ld hl, basFloppyCmds
call basFindCmd call basFindCmd
ret z ret z
ld hl, basBLKCmds ld hl, basBLKCmds
call basFindCmd
ret z
ld hl, basFSCmds
call basFindCmd
ret z
ld hl, .cmds
jp basFindCmd jp basFindCmd
.cmds:
.db "recv", 0
.dw recvCmd
.db 0xff ; end of table
; *** blkdev 1: file handle 0 ***
blk1GetB:
ld ix, FS_HANDLES
jp fsGetB
blk1PutB:
ld ix, FS_HANDLES
jp fsPutB
; *** blkdev 2: file handle 1 ***
blk2GetB:
ld ix, FS_HANDLES+FS_HANDLE_SIZE
jp fsGetB
blk2PutB:
ld ix, FS_HANDLES+FS_HANDLE_SIZE
jp fsPutB
RAMSTART: RAMSTART:

View File

@ -1,7 +1,17 @@
ld hl, 0x3000 ; memory address where to put contents. .equ COM_DRV_ADDR 0x0238 ; replace with *CL's DCB addr
.equ DEST_ADDR 0x3000 ; memory address where to put contents.
; We process the 0x20 exception by pre-putting a mask in the (HL) we're going
; to write to. If it wasn't a 0x20, we put a 0xff mask. If it was a 0x20, we
; put a 0x7f mask.
ld hl, DEST_ADDR
loop: loop:
ld a, 0xff
ld (hl), a ; default mask
loop2:
ld a, 0x03 ; @GET ld a, 0x03 ; @GET
ld de, 0xffff ; replace with *CL's DCB addr ld de, COM_DRV_ADDR
rst 0x28 rst 0x28
jr nz, maybeerror jr nz, maybeerror
or a or a
@ -9,25 +19,24 @@ loop:
; @PUT that char back ; @PUT that char back
ld c, a ld c, a
ld a, 0x04 ; @PUT ld a, 0x04 ; @PUT
ld de, 0xffff ; replace with *CL's DCB addr
rst 0x28 rst 0x28
jr nz, error jr nz, error
ld a, c ld a, c
cp 0x20 cp 0x20
jr z, adjust jr z, escapechar
write: ; not an escape char, just apply the mask and write
and (hl)
ld (hl), a ld (hl), a
inc hl inc hl
jr loop jr loop
adjust: escapechar:
dec hl ; adjust by setting (hl) to 0x7f
ld a, (hl) res 7, (hl)
and 0x7f jr loop2
jr write
maybeerror: maybeerror:
; was it an error? ; was it an error?
or a or a
jr z, loop ; not an error, just loop jr z, loop2 ; not an error, just loop
; error ; error
error: error:
ld c, a ; Error code from @GET/@PUT ld c, a ; Error code from @GET/@PUT

View File

@ -4,8 +4,8 @@
/* Converts stdin to a content that is "tty safe", that is, that it doesn't /* Converts stdin to a content that is "tty safe", that is, that it doesn't
* contain ASCII control characters that can mess up serial communication. * contain ASCII control characters that can mess up serial communication.
* How it works is that it leaves any char > 0x20 intact, but any char <= 0x20 * How it works is that it leaves any char > 0x20 intact, but any char <= 0x20
* is replaced by two chars: char|0x80, 0x20. A 0x20 char always indicate "take * is replaced by two chars: 0x20, then char|0x80. A 0x20 char always indicate
* the char you've just received and unset the 7th bit from it". * "take the next char you'll receive and unset the 7th bit from it".
*/ */
int main(void) int main(void)
@ -13,8 +13,8 @@ int main(void)
int c = getchar(); int c = getchar();
while (c != EOF) { while (c != EOF) {
if (c <= 0x20) { if (c <= 0x20) {
putchar(c|0x80);
putchar(0x20); putchar(0x20);
putchar(c|0x80);
} else { } else {
putchar(c&0xff); putchar(c&0xff);
} }