.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)