aboutsummaryrefslogtreecommitdiffstats
path: root/src/syscall.asm
diff options
context:
space:
mode:
Diffstat (limited to 'src/syscall.asm')
-rw-r--r--src/syscall.asm146
1 files changed, 134 insertions, 12 deletions
diff --git a/src/syscall.asm b/src/syscall.asm
index 5ed3d6f..f149a76 100644
--- a/src/syscall.asm
+++ b/src/syscall.asm
@@ -50,6 +50,10 @@ SyscallTable:
dw sys_putb ; 13 PUTB
dw sys_list ; 14 LIST
dw sys_remove ; 15 REMOVE
+ dw sys_putc ; 16 PUTC
+ dw sys_setin ; 17 SETIN
+ dw sys_setout ; 18 SETOUT
+ dw sys_lookup ; 19 LOOKUP
; -----------------------------------------------------------------------------
sys_nosys:
@@ -64,33 +68,151 @@ sys_write:
ld a, b
or a
ret z ; len 0
- ld c, b ; C = remaining
.loop
ld a, [de]
- call PutChar
+ push de
+ push bc
+ ld e, a
+ call KPutc ; route the byte to this process's stdout
+ pop bc
+ pop de
inc de
- dec c
+ dec b
jr nz, .loop
- ld a, b ; return len
ret
; -----------------------------------------------------------------------------
-; sys_read() -> A = one input byte from the console (blocking).
-; Uses an external-clock serial transfer as a clean RX: it completes only when
-; the host has a byte (no stdout echo). While waiting we yield so other procs
-; run. Preserves BC/DE/HL (the context switch saves/restores them).
+; CurStdin / CurStdout -> A = current process PROC_STDIN / PROC_STDOUT
; -----------------------------------------------------------------------------
-sys_read:
+CurStdin:
+ ld a, [wCurProc]
+ add PROC_STDIN
+ ld l, a
+ ld a, [wCurProc+1]
+ adc 0
+ ld h, a
+ ld a, [hl]
+ ret
+CurStdout:
+ ld a, [wCurProc]
+ add PROC_STDOUT
+ ld l, a
+ ld a, [wCurProc+1]
+ adc 0
+ ld h, a
+ ld a, [hl]
+ ret
+
+; -----------------------------------------------------------------------------
+; KGetc -> A = byte, CF set on EOF. Reads this process's stdin (console/file).
+; -----------------------------------------------------------------------------
+KGetc::
+ call CurStdin
+ cp STD_CONSOLE
+ jr z, .console
+ ld b, a
+ jp sys_getb ; B=fd -> A=byte, CF=EOF
+.console
.poll
ld a, $80
- ld [rSC], a ; request a byte (external clock)
+ ld [rSC], a
ld a, [rSC]
bit 7, a
- jr z, .got ; bit7 clear => transfer completed
- call SchedYield ; nothing yet: let others run, then retry
+ jr z, .got
+ call SchedYield
jr .poll
.got
ld a, [rSB]
+ and a ; CF = 0
+ ret
+
+; -----------------------------------------------------------------------------
+; KPutc(E = byte) - write to this process's stdout (console/file).
+; -----------------------------------------------------------------------------
+KPutc::
+ ld a, e
+ ld [wKChar], a
+ call CurStdout
+ cp STD_CONSOLE
+ jr z, .console
+ ld b, a ; fd
+ ld a, [wKChar]
+ ld e, a
+ jp sys_putb ; B=fd, E=byte
+.console
+ ld a, [wKChar]
+ ld [rSB], a
+ ld a, $81
+ ld [rSC], a
+ ret
+
+; -----------------------------------------------------------------------------
+; sys_putc(E = byte), sys_setin/sys_setout(B = fd)
+; -----------------------------------------------------------------------------
+sys_putc:
+ call KPutc
+ ret
+sys_setin:
+ ld a, [wCurProc]
+ add PROC_STDIN
+ ld l, a
+ ld a, [wCurProc+1]
+ adc 0
+ ld h, a
+ ld a, b
+ ld [hl], a
+ ret
+sys_setout:
+ ld a, [wCurProc]
+ add PROC_STDOUT
+ ld l, a
+ ld a, [wCurProc+1]
+ adc 0
+ ld h, a
+ ld a, b
+ ld [hl], a
+ ret
+
+; -----------------------------------------------------------------------------
+; sys_lookup(DE = name) -> A = program id, or $FF if not a known command.
+; -----------------------------------------------------------------------------
+sys_lookup:
+ ld h, d
+ ld l, e ; HL = query name
+ ld de, NameTable
+.l
+ ld a, [de]
+ or a
+ jr z, .none
+ push hl
+ push de
+ call StrEqual ; HL=query vs DE=table name -> Z if equal
+ pop de
+ pop hl
+ jr z, .match
+ call SkipName ; DE -> NUL
+ inc de ; -> id
+ inc de ; -> next entry
+ jr .l
+.match
+ call SkipName
+ inc de ; -> id
+ ld a, [de]
+ ret
+.none
+ ld a, $FF
+ ret
+
+; -----------------------------------------------------------------------------
+; sys_read() -> A = one input byte from the console (blocking).
+; Uses an external-clock serial transfer as a clean RX: it completes only when
+; the host has a byte (no stdout echo). While waiting we yield so other procs
+; run. Preserves BC/DE/HL (the context switch saves/restores them).
+; -----------------------------------------------------------------------------
+sys_read:
+ call KGetc ; A=byte, CF=EOF (file); console EOF is $04
+ ret nc
+ ld a, $04 ; file EOF -> EOT
ret
; -----------------------------------------------------------------------------