collapseos/recipes/zxspectrum/glue.asm
devisn 0576d2dfa1
a recipe for the ZX Spectrum (#105)
* Add files via upload

* a monolithic build recipe for ZX Spectrum

* emulation and emulated tapes in README.md
2020-06-11 13:34:34 -04:00

263 lines
6.3 KiB
NASM

.equ IYBAS 23610 ; user.h
; The ZX Spectrum firmware requires IY value to be equal to 23610
; (in this case, to handle keyboard interrupts and screen correctly).
; an IM2 handler has to be included to manage this.
.equ RAMEND 0xffff ; user.h
.equ USER_CODE 41639 ; = BAS_RAMEND+527 in user.h
; when changing the memory layout, it should have a dummy value for a test assembly,
; then changed to the actual value in relation to the new BAS_RAMEND
.org 0x5efd
jp init
.inc "err.h"
.inc "ascii.h"
.inc "blkdev.h"
.inc "fs.h"
.inc "kernel/zxs/jumps.asm"
.inc "core.asm"
.inc "kernel/str.asm"
.inc "kernel/zxs/vid.asm"
.inc "kernel/zxs/kbd.asm"
.equ GRID_COLS 32
.equ GRID_ROWS 21 ; to avoid CRLF outside of the #2 screen
.equ GRID_SETCELL v_putc
.equ GRID_GETC k_getc
.equ GRID_RAMSTART RAMSTART
.inc "kernel/grid.asm"
.equ BLOCKDEV_RAMSTART GRID_RAMEND
.equ BLOCKDEV_COUNT 4
.inc "kernel/blockdev.asm"
; List of devices
.dw mmapGetB, mmapPutB
.dw blk1GetB, blk1PutB
.dw blk2GetB, blk2PutB
.dw tapeGetB, unsetZ ;read-only
.equ STDIO_RAMSTART BLOCKDEV_RAMEND
.equ STDIO_GETC gridGetC
.equ STDIO_PUTC gridPutC
.equ STDIO_SETCUR gridSetCurH
.inc "kernel/stdio.asm"
.equ MMAP_START 0xc000 ; 49152
.equ MMAP_LEN RAMEND-MMAP_START+1
; 16K, 64 fs blocks for MMAP FS
.inc "kernel/mmap.asm"
.equ FS_RAMSTART STDIO_RAMEND
.equ FS_HANDLE_COUNT 2
.inc "kernel/fs.asm"
; BASIC shell
; 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
.equ BUF_POOLSIZE 0x800 ; 0x1000 by default, cut to save some RAM
.equ BUF_POOL shell_buf ; in contended memory
.equ BUF_MAXLINES 0x100
.equ BUF_LINES BUF_RAMSTART+4
.equ BUF_RAMEND @+BUF_MAXLINES*4 ; continue allocating in higher RAM
.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"
; BASIC records the SP value, which is glue init value-2; the address of this storage +6 is BAS_RAMEND
; this is the value to be learned from a memory dump for user.h!
.equ tap_buffer BAS_RAMEND
.equ buf_pos @+256
.equ tap_pos @+1
.equ TAP_RAMEND @+8 ; user.h for assembling zxs/tapeutil.bin, BAS_RAMEND+265
.inc "kernel/zxs/tapeblk.asm"
;.equ USER_CODE BAS_RAMEND+527 ; 265 tapeblk + 262 tapeutil.bin below
.equ ZBCOUNT USER_CODE+14
tpztell:
; fetches the zasm internal counter (IO_OUT_BLK) at ZASM_RAMSTART+14
; it's called through 'addr ztell: s=a: usr s: print h'
ld hl, (ZBCOUNT)
xor a
ret
basFindCmdExtra:
ld hl, basBLKCmds
call basFindCmd
ret z
ld hl, basFSCmds
call basFindCmd
ret z
ld hl, .mycmds
call basFindCmd
ret z
jp basPgmHook
.mycmds:
.db "binsv", 0
.dw tapeutil
.db "binld", 0
.dw tapeutil+3
.db "head", 0
.dw tapeutil+6
.db "filsv", 0
.dw tapeutil+9
.db "filld", 0
.dw tapeutil+12
.db "cfssv", 0
.dw tapeutil+15
.db "cfsld", 0
.dw tapeutil+18
.db "cutsv", 0
.dw tapeutil+21
.db "ztell", 0
.dw tpztell
.db "ed", 0
.dw edrun
.db "zasm", 0
.dw zasmrun
.db 0xff
init:
di
ld sp, 0x8000
; if precise timings are needed,
; the stack should be moved to non-contended memory
call int_init
call v_init
call tapeblk_init
; init a FS in mmap
; possibly not needed in the final build
ld hl, MMAP_START
ld a, 'C'
ld (hl), a
inc hl
ld a, 'F'
ld (hl), a
inc hl
ld a, 'S'
ld (hl), a
call gridInit
call fsInit
xor a
ld de, BLOCKDEV_SEL
call blkSel
call fsOn
call basInit
ld hl, basFindCmdExtra
ld (BAS_FINDHOOK), hl
ei
jp basStart
; *** 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
int_init:
di
ld a,0x80
ld i,a
im 2
ret ; does not enable interrupts yet
tapeutil:
.bin "zxs/tapeutil.bin"
; all tape utilities in one block with library
; t_load ROM call routine is duplicated in zxs/tapeblk.asm in case those utilities are moved to userspace
; 0x7492 is free space, +2K=7c92, the rest 0x36e=878b for stack space
shell_buf:
; basic shell BUF_POOL points here
.fill 0x8000-$
; The ZX Spectrum hardware noises the CPU data bus so that any value can appear on interrupt instead of 0xFF.
; A 257-byte table is thus required to hold the INT handler address for IM2 mode.
; interrupt table = 128 words + 1 byte
.dw 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181
.dw 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181
.dw 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181
.dw 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181
.dw 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181
.dw 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181
.dw 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181
.dw 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181
.dw 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181
.dw 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181
.dw 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181
.dw 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181
.dw 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181
.dw 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181
.dw 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181
.dw 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181, 0x8181
.db 0x81
; the handler and the table are to reside in the non-contended memory, i.e. in 0x8000-0xC000
; (or rather in 0x8080-0xBFBF)
.fill 0x8181-$
; *** interrupt handler
; other possible int routines here, e.g. RS232 or debug calls
push iy
ld iy, IYBAS
rst 56
pop iy
ei
ret
;0x818c
edrun:
.bin "zxs/ed.bin" ;1108 = 0x0454
;0x85e0 = 0x818c+0x454
zasmrun:
.bin "zxs/zasm.bin" ;4881 = 0x1311
RAMSTART: ; 0x98f1 = 0x85e0+0x1311 (39153)
; bin length (14836)