1
0
mirror of https://github.com/hsoft/collapseos.git synced 2024-11-02 08:20:57 +11:00

Compare commits

..

No commits in common. "b89fa2981fab306054c3c8c339e8aa2fed682949" and "fa79e3d8a64c728b15a2f61232a9177ba9c3e707" have entirely different histories.

17 changed files with 306 additions and 72 deletions

View File

@ -8,7 +8,7 @@ MASTER INDEX
280 Z80 boot code 350 ACIA driver
370 SD Card driver 390 Inner core
420 Core words 480 AT28 Driver
490 TRS-80 Recipe
490 TRS80 Drivers

View File

@ -8,7 +8,7 @@ LD [rr, rn, ddnn, (nn)HL, HL(nn), dd(nn), (nn)dd, rIXY, IXYr,
(DE)A, A(DE)]
ADD [r, n, HLss, IXss, IXIX, IYss, IYIY]
ADC [r, HLss]
CP [r, n]
CP [r]
SBC [r, HLss]
SUB [r, n]
PUSH [qq] POP [qq]

View File

@ -11,5 +11,4 @@
0xf6 OP2n ORn,
0xd6 OP2n SUBn,
0xee OP2n XORn,
0xfe OP2n CPn,

View File

@ -1,6 +1,9 @@
: DUMP ( n a -- )
LF
SWAP 8 /MOD SWAP IF 1+ THEN
0 DO _ LOOP
BEGIN
OVER 1 < IF 2DROP EXIT THEN
_
SWAP 8 - SWAP
AGAIN
;

11
blk/490
View File

@ -1,11 +1,8 @@
TRS-80 Recipe
TRS-80 Drivers
Support code for the TRS-80 recipe. Contains drivers for the
keyboard, video and floppy. At the moment, they are thin layer
over the drivers provided by TRSDOS' SVC.
Drivers for the TRS-80 keyboard, video and floppy. At the
moment, they are thin layer over the drivers provided by
TRSDOS' SVC.
Load the Z80 words with "492 LOAD" and the high level part
with "498 LOAD".
There is also the RECV program at B502 and the XCOMP unit at
B504

16
blk/502
View File

@ -1,16 +0,0 @@
( 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. )
: @GET,
A 0x03 LDrn, ( @GET )
DE COM_DRV_ADDR LDddnn,
0x28 RSTn, JRNZ, L2 FWR ( maybeerror )
A ORr,
CZ RETcc, ( Sending a straight NULL ends the comm. ) ;
: @PUT, ( @PUT that char back )
C A LDrr,
A 0x04 LDrn, ( @PUT )
0x28 RSTn, JRNZ, L3 FWR ( error )
A C LDrr, ;
H@ ORG !
HL DEST_ADDR LDddnn, ( cont. )

15
blk/503
View File

@ -1,15 +0,0 @@
BEGIN,
A 0xff LDrn, (HL) A LDrr, ( default mask )
L1 BSET ( loop2 ) @GET, @PUT,
0x20 CPn, JRZ, L4 FWR ( escapechar )
( not an escape char, just apply the mask and write )
(HL) ANDr, (HL) A LDrr,
HL INCss,
JR, AGAIN,
L4 FSET ( escapechar, adjust by setting (hl) to 0x7f )
7 (HL) RESbr, JR, L1 BWR ( loop2 )
L2 FSET ( maybeerror, was it an error? )
A ORr, JRZ, L1 BWR ( loop2, not an error )
L3 FSET ( error )
C A LDrr, ( error code from @GET/@PUT )
A 0x1a LDrn, ( @ERROR ) 0x28 RSTn, RET,

Binary file not shown.

View File

@ -9,6 +9,7 @@
CURRENT @ XCURRENT !
H@ 256 /MOD 2 PC! 2 PC!
282 LOAD ( boot.z80 )
393 LOAD ( icore )
(entry) _
@ -18,5 +19,4 @@ PC ORG @ 8 + !
," : (emit) 0 PC! ; : (key) 0 PC@ ; "
422 459 XPACKR
," ' (key) 12 RAM+ ! "
ORG @ 256 /MOD 2 PC! 2 PC!
H@ 256 /MOD 2 PC! 2 PC!

View File

@ -17,7 +17,7 @@ it from the makefile. If you take the time to look at the base recipe
`xcomp.fs` in a text editor and take a look at it.
To assemble stage 1 from RC2014, all you need to do is to type those commands
in the same order, and replace the `/MOD 2 PC! 2 PC!` words with `.X`.
in the same order, and replace the `H@ 256 /MOD 2 PC! 2 PC!` lines with `H@ .X`.
Those commands will inform you of the begin/end offsets of the assembled binary.
I'm not going to explain in detail what each command do, but only give you an
@ -33,8 +33,9 @@ we'll of course need for the task ahead.
Then come xcomp overrides, which are needed for xcomp to be effective.
At this point, we're about to begin spitting binary content, this will be our
starting offset. `ORG` will soon be set to your current `H@`.
At this point, we're about to begin spitting binary content, so we want to know
where we're at. That's why you'll need to type `H@ .X` and write down the
result. That's the starting offset.
Then, we assemble the boot binary, drivers' native words, then inner core,
close the binary with a hook word. We're finished with cross-compiling.

View File

@ -15,6 +15,7 @@ RAMSTART 0x70 + CONSTANT ACIA_MEM
CURRENT @ XCURRENT !
H@ 256 /MOD 2 PC! 2 PC!
282 LOAD ( boot.z80 )
352 LOAD ( acia.z80 )
372 LOAD ( sdc.z80 )
@ -27,5 +28,4 @@ PC ORG @ 8 + !
438 452 XPACKR ( print fmt readln )
123 132 XPACKR ( linker )
," : _ ACIA$ RDLN$ (ok) ; _ "
ORG @ 256 /MOD 2 PC! 2 PC!
H@ 256 /MOD 2 PC! 2 PC!

View File

@ -103,26 +103,11 @@ As stated in the overview, we need a program on the TRS-80 that:
3. Adjusts `ttysafe` escapes
4. Stores received bytes in memory
You're in luck: that program has already been written. It's in B502 and B503.
You can compile it with:
That program has already been written, it's in `recv.asm` in this folder. You
can get the binary with `zasm < recv.asm | xxd`.
212 LOAD ( z80 assembler )
0x0238 CONSTANT COM_DRV_ADDR
0x3000 CONSTANT DEST_ADDR
502 LOAD
503 LOAD
Then, you can use `DUMP` to visualize the data you'll need to punch in:
H@ ORG @ - ORG @ DUMP
It can run from any offset (all jumps in it are relative), but writes to
`DEST_ADDR`. Make sure you don't place it in a way to be overwritten by its
received data.
Wondering what is that `COM_DRV_ADDR` constant? That's the DCB handle of your
`*cl` device. You will need to get that address before you continue. Go read
the following section and come back here.
It's designed to run from offset `0x5000` and write received data in `0x3000`
and onwards.
How will you punch that in? The `debug` program! This very useful piece of
software is supplied in TRSDOS. To invoke it, first run `debug (on)` and then
@ -138,12 +123,17 @@ begin punching in with `h5000<space>`. This will bring up a visual indicator of
the address being edited. Punch in the stuff with a space in between each byte
and end the edit session with `x`.
But wait, it's not that easy! You see those `0xffff` addresses? They're
placeholders. You need to replace those values with your DCB handle for `*cl`.
See below.
## Getting your DCB address
In the previous step, you need to set `COM_DRV_ADDR` to your "DCB" address for
`*cl`. That address is your driver "handle". To get it, first get the address
where the driver is loaded in memory. You can get this by running `device
(b=y)`. That address you see next to `*cl`? that's it. But that's not our DCB.
In the previous step, you need to replace the `0xffff` placeholders in
`recv.asm` with your "DCB" address for `*cl`. That address is your driver
"handle". To get it, first get the address where the driver is loaded in
memory. You can get this by running `device (b=y)`. That address you see next
to `*cl`? that's it. But that's not our DCB.
To get your DBC, go explore that memory area. Right after the part where there's
the `*cl` string, there's the DCB address (little endian). On my setup, the

View File

@ -0,0 +1,11 @@
.inc "user.h"
ld hl, sAwesome
call printstr
xor a ; success
ret
sAwesome:
.db "Assembled from a TRS-80", 0x0d, 0

200
recipes/trs80/glue.asm Normal file
View File

@ -0,0 +1,200 @@
; RAMSTART is a label at the end of the file
.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: 0x600b
.equ USER_CODE 0x6100
; Free memory in TRSDOS starts at 0x3000
.org 0x3000
jp init
; *** Jump Table ***
jp strncmp
jp upcase
jp findchar
jp printstr
jp printcrlf
jp blkSet
jp blkSel
jp _blkGetB
jp _blkPutB
jp _blkSeek
jp _blkTell
jp fsFindFN
jp fsOpen
jp fsGetB
jp fsPutB
jp fsSetSize
jp stdioPutC
jp stdioReadLine
.inc "err.h"
.inc "blkdev.h"
.inc "fs.h"
.inc "ascii.h"
.inc "core.asm"
.inc "str.asm"
.inc "trs80/kbd.asm"
.inc "trs80/vid.asm"
.equ FLOPPY_RAMSTART RAMSTART
.inc "trs80/floppy.asm"
.equ GRID_RAMSTART FLOPPY_RAMEND
.equ GRID_ROWS TRS80_ROWS
.equ GRID_COLS TRS80_COLS
.equ GRID_SETCELL trs80SetCell
.equ GRID_GETC trs80GetC
.equ gridPushScr fastPushScr
.inc "grid.asm"
.equ BLOCKDEV_RAMSTART GRID_RAMEND
.equ BLOCKDEV_COUNT 3
.inc "blockdev.asm"
; List of devices
.dw floppyGetB, floppyPutB
.dw blk1GetB, blk1PutB
.dw blk2GetB, blk2PutB
.equ STDIO_RAMSTART BLOCKDEV_RAMEND
.equ STDIO_GETC gridGetC
.equ STDIO_PUTC gridPutC
.equ STDIO_SETCUR gridSetCurH
.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 STDIO_BUFSIZE
.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"
.inc "basic/floppy.asm"
.equ BAS_RAMSTART BFS_RAMEND
.inc "basic/main.asm"
.out BAS_RAMEND
init:
ld sp, RAMEND
call gridInit
call floppyInit
call fsInit
call basInit
ld hl, basFindCmdExtra
ld (BAS_FINDHOOK), hl
xor a
ld de, BLOCKDEV_SEL
call blkSel
jp basStart
; 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:
ld hl, basFloppyCmds
call basFindCmd
ret z
ld hl, basBLKCmds
call basFindCmd
ret z
ld hl, basFSCmds
call basFindCmd
ret z
ld hl, .cmds
call basFindCmd
ret z
jp basPgmHook
.cmds:
.db "recv", 0
.dw recvCmd
.db 0xff ; end of table
fastPushScr:
push hl
ld hl, GRID_BUF
call trs80PushScr
pop hl
ret
; *** 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:

45
recipes/trs80/recv.asm Normal file
View File

@ -0,0 +1,45 @@
.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:
ld a, 0xff
ld (hl), a ; default mask
loop2:
ld a, 0x03 ; @GET
ld de, COM_DRV_ADDR
rst 0x28
jr nz, maybeerror
or a
ret z ; Sending a straight NULL ends the comm.
; @PUT that char back
ld c, a
ld a, 0x04 ; @PUT
rst 0x28
jr nz, error
ld a, c
cp 0x20
jr z, escapechar
; not an escape char, just apply the mask and write
and (hl)
ld (hl), a
inc hl
jr loop
escapechar:
; adjust by setting (hl) to 0x7f
res 7, (hl)
jr loop2
maybeerror:
; was it an error?
or a
jr z, loop2 ; not an error, just loop
; error
error:
ld c, a ; Error code from @GET/@PUT
ld a, 0x1a ; @ERROR
rst 0x28
ret

19
recipes/trs80/user.h Normal file
View File

@ -0,0 +1,19 @@
.org 0x6100
.equ strncmp 0x3003
.equ upcase @+3
.equ findchar @+3
.equ printstr @+3
.equ printcrlf @+3
.equ blkSet @+3
.equ blkSel @+3
.equ _blkGetB @+3
.equ _blkPutB @+3
.equ _blkSeek @+3
.equ _blkTell @+3
.equ fsFindFN @+3
.equ fsOpen @+3
.equ fsGetB @+3
.equ fsPutB @+3
.equ fsSetSize @+3
.equ stdioPutC @+3
.equ stdioReadLine @+3

View File

@ -9,6 +9,7 @@ RS_ADDR 0x80 - CONSTANT RAMSTART
CURRENT @ XCURRENT !
H@ 256 /MOD 2 PC! 2 PC!
0x3000 BIN( !
282 LOAD ( boot.z80 )
492 LOAD ( trs80.z80 )
@ -21,5 +22,4 @@ PC ORG @ 8 + !
499 500 XPACKR ( trs80.fs )
( 0x0a == NLPTR. TRS-80 wants CR-only newlines )
," : _ ['] CR 0x0a RAM+ ! BLK$ FD$ (ok) RDLN$ ; _ "
ORG @ 256 /MOD 2 PC! 2 PC!
H@ 256 /MOD 2 PC! 2 PC!