aboutsummaryrefslogtreecommitdiffstats
path: root/c/libc.s
diff options
context:
space:
mode:
authoruser <user@clank>2026-07-18 00:38:38 +0200
committeruser <user@clank>2026-07-18 00:38:38 +0200
commitba2d7ae1d7b319645b10aaa31a7f664f9f80c25c (patch)
treee01e6c7c710a661defe2515ff9657f08cddcb283 /c/libc.s
parenttools: gbtype prints hub errors to stderr and exits 1 (diff)
downloadgbos-ba2d7ae1d7b319645b10aaa31a7f664f9f80c25c.tar.gz
gbos-ba2d7ae1d7b319645b10aaa31a7f664f9f80c25c.tar.xz
gbos-ba2d7ae1d7b319645b10aaa31a7f664f9f80c25c.zip
refactor: c/ -> usr/, compiled program blobs out of the source tree
Userland sources live in usr/ (fits the Unix theme better than 'c'). SDCC output .bin blobs land in build/usr/ with the other build artifacts instead of littering the source dir; programs.asm INCBINs them from there. Byte-identical ROM.
Diffstat (limited to 'c/libc.s')
-rw-r--r--c/libc.s304
1 files changed, 0 insertions, 304 deletions
diff --git a/c/libc.s b/c/libc.s
deleted file mode 100644
index 5b176d9..0000000
--- a/c/libc.s
+++ /dev/null
@@ -1,304 +0,0 @@
- .module libc
- .globl _writes, _putc, _puts, _nl, _strlen, _readc, _sexit, _getpid, _getargs
- .globl _open, _close, _fgetc, _fputc, _flist, _fremove, _pipe, _ssend, _srecv, _srecv_nb, _pollin, _pollcon
- .globl _sys_net, _gsleep
- ;; SDCC sm83 sdcccall(1): 1st arg -> A (byte) or DE (pointer); ret A / BC.
- ;; rst $30 (the trap) clobbers BC/DE/HL; SDCC treats them caller-saved, so
- ;; wrappers need not preserve them - but we compute cleanly regardless.
- .area _CODE
-
- ;; void writes(const char *buf /*DE*/, unsigned char len /*A*/)
-_writes:
- ld b, a
- ld c, #3 ; SYS_WRITE
- rst #0x30
- ret
-
- ;; char *getargs(void) -> BC : the arg string (command line past word 1).
- ;; The shell leaves "cmd\0args\0" at 0xA000, inherited by the child via fork.
-_getargs:
- ld hl, #0xa000
-1$: ld a, (hl)
- inc hl
- or a
- jr nz, 1$
- ld b, h
- ld c, l
- ret
-
- ;; void putc(char c /*A*/) -> stdout via SYS_PUTC
-_putc:
- ld e, a
- ld c, #16 ; SYS_PUTC
- rst #0x30
- ret
-
- ;; void puts(const char *s /*DE*/) - write until NUL (no newline)
-_puts:
-1$: ld a, (de)
- or a
- ret z
- push de
- ld e, a
- ld c, #16 ; SYS_PUTC
- rst #0x30
- pop de
- inc de
- jr 1$
-
- ;; void nl(void) - CRLF via stdout
-_nl:
- ld e, #0x0d
- ld c, #16 ; SYS_PUTC
- rst #0x30
- ld e, #0x0a
- ld c, #16
- rst #0x30
- ret
-
- ;; unsigned char strlen(const char *s /*DE*/) -> A
-_strlen:
- ld c, #0
-1$: ld a, (de)
- or a
- jr z, 2$
- inc c
- inc de
- jr 1$
-2$: ld a, c
- ret
-
- ;; char readc(void) -> A (4 = EOF)
-_readc:
- ld c, #2 ; SYS_READ
- rst #0x30
- ret
-
- ;; void sexit(unsigned char code /*A*/) - never returns
-_sexit:
- ld b, a
- ld c, #0 ; SYS_EXIT
- rst #0x30
- ret
-
- ;; unsigned char getpid(void) -> A
-_getpid:
- ld c, #8 ; SYS_GETPID
- rst #0x30
- ret
-
- ;; unsigned char pipe(void) -> A (read fd; write end is read+1)
-_pipe:
- ld c, #28 ; SYS_PIPE
- rst #0x30
- ret
-
- ;; void ssend(unsigned char b /*A*/) -- link-port transmit
-_ssend:
- ld e, a
- ld c, #29 ; SYS_SSEND
- rst #0x30
- ret
-
- ;; unsigned char srecv(void) -> A -- link-port receive (blocks)
-_srecv:
- ld c, #30 ; SYS_SRECV
- rst #0x30
- ret
-
- ;; int srecv_nb(void) -> byte, or -1 if none (non-blocking)
-_srecv_nb:
- ld c, #31 ; SYS_SRECVNB
- rst #0x30
- jr c, 1$
- ld c, a
- ld b, #0
- ret
-1$: ld bc, #0xffff
- ret
-
- ;; unsigned char sys_net(void *req /*DE*/) -> A -- socket layer trap
-_sys_net:
- ld c, #33 ; SYS_NET (DE already = &netreq)
- rst #0x30
- ret
-
- ;; void gsleep(unsigned char units /*A*/) - delay units*(1/64)s
-_gsleep:
- ld b, a
- ld c, #34 ; SYS_SLEEP
- rst #0x30
- ret
-
- ;; unsigned char pollin(void) -> A (typed OSK char, or 0)
-_pollin:
- ld c, #32 ; SYS_POLLIN
- rst #0x30
- ret
-
- ;; unsigned char pollcon(void) -> A (queued console byte, or 0)
-_pollcon:
- ld c, #35 ; SYS_POLLCON
- rst #0x30
- ret
-
- ;; unsigned char open(const char *name /*DE*/, unsigned char mode /*A*/) -> A(fd)
-_open:
- ld b, a ; B = mode
- ld c, #4 ; SYS_OPEN
- rst #0x30
- ret
-
- ;; void close(unsigned char fd /*A*/)
-_close:
- ld b, a
- ld c, #5 ; SYS_CLOSE
- rst #0x30
- ret
-
- ;; int fgetc(unsigned char fd /*A*/) -> BC (byte, or -1 at EOF)
-_fgetc:
- ld b, a
- ld c, #12 ; SYS_GETB
- rst #0x30
- jr c, 1$
- ld c, a
- ld b, #0
- ret
-1$: ld bc, #0xffff
- ret
-
- ;; void fputc(unsigned char fd /*A*/, char ch /*E*/)
- ;; byte goes to the kernel in E (the trap clobbers A during dispatch)
-_fputc:
- ld b, a ; B = fd (ch stays in E)
- ld c, #13 ; SYS_PUTB
- rst #0x30
- ret
-
- ;; unsigned char flist(unsigned char slot /*A*/, char *namebuf /*DE*/) -> A
-_flist:
- ld b, a
- ld c, #14 ; SYS_LIST
- rst #0x30
- ret
-
- ;; void fremove(const char *name /*DE*/)
-_fremove:
- ld c, #15 ; SYS_REMOVE
- rst #0x30
- ret
-
- .globl _fork, _exec, _wait, _setin, _setout, _lookup
- ;; unsigned char fork(void) -> A (child pid in parent, 0 in child)
-_fork:
- ld c, #1 ; SYS_FORK
- rst #0x30
- ret
- ;; void exec(unsigned char id /*A*/) - never returns
-_exec:
- ld b, a
- ld c, #6 ; SYS_EXEC
- rst #0x30
- ret
- ;; unsigned char wait(void) -> A (reaped pid)
-_wait:
- ld c, #7 ; SYS_WAIT
- rst #0x30
- ret
- ;; void setin(unsigned char fd /*A*/)
-_setin:
- ld b, a
- ld c, #17 ; SYS_SETIN
- rst #0x30
- ret
- ;; void setout(unsigned char fd /*A*/)
-_setout:
- ld b, a
- ld c, #18 ; SYS_SETOUT
- rst #0x30
- ret
- ;; unsigned char lookup(const char *name /*DE*/) -> A (prog id or $FF)
-_lookup:
- ld c, #19 ; SYS_LOOKUP
- rst #0x30
- ret
-
- .globl _kill, _psget, _progname
- ;; unsigned char kill(unsigned char pid /*A*/) -> A (0 ok, $FF fail)
-_kill:
- ld b, a
- ld c, #9 ; SYS_KILL
- rst #0x30
- ret
- ;; unsigned char psget(unsigned char slot /*A*/, unsigned char *buf /*DE*/) -> A
-_psget:
- ld b, a
- ld c, #20 ; SYS_PS
- rst #0x30
- ret
- ;; void progname(unsigned char id /*A*/, char *buf /*DE*/)
-_progname:
- ld b, a
- ld c, #21 ; SYS_PROGNAME
- rst #0x30
- ret
-
- .globl _yield, _reap
- ;; void yield(void)
-_yield:
- ld c, #11 ; SYS_YIELD
- rst #0x30
- ret
- ;; unsigned char reap(void) -> A (reaped pid, or 0)
-_reap:
- ld c, #22 ; SYS_REAP
- rst #0x30
- ret
-
- .globl _bfill, _bpeek, _bpeek2
- ;; void bfill(unsigned char block /*A*/, unsigned char byte /*E*/)
-_bfill:
- ld b, a
- ld c, #23 ; SYS_BFILL
- rst #0x30
- ret
- ;; unsigned char bpeek(unsigned char block /*A*/) -> A
-_bpeek:
- ld b, a
- ld e, #0
- ld c, #24 ; SYS_BPEEK
- rst #0x30
- ret
- ;; unsigned char bpeek2(unsigned char block /*A*/, unsigned char off /*E*/) -> A
-_bpeek2:
- ld b, a
- ld c, #24 ; SYS_BPEEK (off already in E)
- rst #0x30
- ret
-
-
- .globl _mkdir, _chdir
- ;; unsigned char mkdir(const char *path /*DE*/) -> A (0 ok / $FF)
-_mkdir:
- ld c, #25 ; SYS_MKDIR
- rst #0x30
- ret
- ;; unsigned char chdir(const char *path /*DE*/) -> A (0 ok / $FF)
-_chdir:
- ld c, #26 ; SYS_CHDIR
- rst #0x30
- ret
-
- .globl _opendir
- ;; unsigned char opendir(const char *path /*DE*/) -> A (0 ok / $FF)
-_opendir:
- ld c, #27 ; SYS_OPENDIR
- rst #0x30
- ret
-
- .globl _poweroff
- ;; void poweroff(void) - execute the emulator's clean-exit opcode ($ED)
-_poweroff:
- .db 0xED
-1$: jr 1$