; ============================================================================= ; gbos.inc - core constants, memory map, PCB layout, syscall numbers ; Target: Game Boy Color, MBC5 + RAM + BATTERY ; ============================================================================= IF !DEF(GBOS_INC) DEF GBOS_INC EQU 1 ; ----------------------------------------------------------------------------- ; Hardware registers we touch (subset; full defs would come from hardware.inc) ; ----------------------------------------------------------------------------- DEF rIF EQU $FF0F ; interrupt flags DEF rIE EQU $FFFF ; interrupt enable DEF rDIV EQU $FF04 ; divider register: free-running 8-bit @ 16384 Hz DEF rSVBK EQU $FF70 ; CGB WRAM bank select ($D000-$DFFF): 1..7 DEF wCurMask EQU $D589 ; term/osk: cursor underline bits OR'd into a tile's last row DEF OSK_DOCK EQU 3 ; on-screen keyboard height in rows (dock at the bottom) DEF rKEY1 EQU $FF4D ; CGB speed switch DEF rSB EQU $FF01 ; serial data DEF rSC EQU $FF02 ; serial control DEF rLCDC EQU $FF40 DEF rSTAT EQU $FF41 DEF rLY EQU $FF44 ; ----------------------------------------------------------------------------- ; MBC5 mapper register addresses (writes to ROM space hit the mapper) ; ----------------------------------------------------------------------------- DEF MBC5_RAM_ENABLE EQU $0000 ; write $0A to enable cart RAM DEF MBC5_ROMB_LO EQU $2000 ; ROM bank bits 0..7 DEF MBC5_ROMB_HI EQU $3000 ; ROM bank bit 8 DEF MBC5_RAMB EQU $4000 ; RAM bank bits 0..3 ($A000-$BFFF) ; ----------------------------------------------------------------------------- ; Memory map (the gbos plan) ; $0000-$3FFF ROM0 kernel core (fixed, always mapped) ; $4000-$7FFF ROMX current task TEXT (read-only program code) ; $8000-$9FFF VRAM graphics ; $A000-$BFFF SRAM current task DATA/BSS/HEAP/STACK (MBC5 RAM bank) ; $C000-$CFFF WRAM0 kernel globals + kernel stack (never swapped) ; $D000-$DFFF WRAMX per-process u-area (SVBK bank) ; $FF80-$FFFE HRAM bank-switch trampoline + context switch ; ----------------------------------------------------------------------------- DEF TASK_RAM_BASE EQU $A000 DEF TASK_RAM_TOP EQU $C000 ; one past end of the 8 KiB window DEF TASK_STACK_TOP EQU $BFFF ; task stacks grow down from here DEF KSTACK_TOP EQU $D000 ; kernel stack top (grows down into WRAM0) ; ----------------------------------------------------------------------------- ; Process table ; ----------------------------------------------------------------------------- DEF MAX_PROCS EQU 8 DEF NUM_RAM_BANKS EQU 8 ; process data/stack banks 0..7 (of 16; -r 4 = 128 KiB) ; ----------------------------------------------------------------------------- ; Block device (persistent, battery-backed cart RAM). The "disk" is cart-RAM ; banks FS_BANK0.. accessed 256 bytes at a time through a WRAM bounce buffer ; (read_block / write_block), so only those two routines ever touch banking. ; ----------------------------------------------------------------------------- DEF FS_BANK0 EQU 8 ; disk starts at cart-RAM bank 8 DEF FS_NBLOCKS EQU 128 ; 128 blocks x 256 B = 32 KiB (banks 8..11) DEF BLK_SIZE EQU 256 DEF BLK_PERBANK EQU 32 ; 8 KiB / 256 DEF SUPER_BLOCK EQU 0 ; block 0 = superblock DEF SUPER_MAG0 EQU $47 ; 'G' DEF SUPER_MAG1 EQU $42 ; 'B' DEF SUPER_MAG2 EQU $46 ; 'F' DEF SUPER_MAG3 EQU $53 ; 'S' DEF KSTACK_TOP2 EQU $D000 ; kernel stack top reused for syscalls (fork) DEF INIT_PID EQU 1 ; pid of the init task (orphan reaper) ; process states DEF PS_FREE EQU 0 DEF PS_READY EQU 1 DEF PS_RUN EQU 2 DEF PS_BLOCKED EQU 3 DEF PS_ZOMBIE EQU 4 ; PCB (process control block) field offsets RSRESET DEF PROC_STATE RB 1 ; PS_* DEF PROC_PID RB 1 DEF PROC_SP RW 1 ; saved stack pointer (into task's RAM bank) DEF PROC_ROMB RW 1 ; text ROM bank (16-bit; MBC5 up to 511) DEF PROC_RAMB RB 1 ; data/stack cart-RAM bank DEF PROC_WRAMB RB 1 ; u-area SVBK bank (1..7) DEF PROC_PARENT RB 1 DEF PROC_EXIT RB 1 ; exit code (valid when PS_ZOMBIE) DEF PROC_STDIN RB 1 ; $FF = console, else an open-file fd DEF PROC_STDOUT RB 1 ; $FF = console, else an open-file fd DEF PROC_PROG RB 1 ; program id currently running ($FF = none), for ps DEF PROC_CWD RB 1 ; current working directory (inode #) DEF PROC_SIZE RB 0 DEF KILL_CODE EQU 137 ; exit status of a killed process (128 + SIGKILL) DEF STD_CONSOLE EQU $FF ; ----------------------------------------------------------------------------- ; Syscall numbers (passed in C; args in DE/HL/B per call, ret in A) ; ----------------------------------------------------------------------------- DEF SYS_EXIT EQU 0 DEF SYS_FORK EQU 1 DEF SYS_READ EQU 2 DEF SYS_WRITE EQU 3 DEF SYS_OPEN EQU 4 DEF SYS_CLOSE EQU 5 DEF SYS_EXEC EQU 6 DEF SYS_WAIT EQU 7 DEF SYS_GETPID EQU 8 DEF SYS_KILL EQU 9 DEF SYS_BRK EQU 10 DEF SYS_YIELD EQU 11 DEF SYS_GETB EQU 12 ; read a byte from an open file (B=fd -> A, CF=EOF) DEF SYS_PUTB EQU 13 ; append a byte to an open file (B=fd, E=byte) DEF SYS_LIST EQU 14 ; list a directory slot (B=slot, DE=namebuf) DEF SYS_REMOVE EQU 15 ; delete a file (DE=name) DEF SYS_PUTC EQU 16 ; write a byte to stdout (E=byte) DEF SYS_SETIN EQU 17 ; set current stdin fd (B=fd, $FF=console) DEF SYS_SETOUT EQU 18 ; set current stdout fd (B=fd, $FF=console) DEF SYS_LOOKUP EQU 19 ; program id for a command name (DE=name -> A=id/$FF) DEF SYS_PS EQU 20 ; process table entry (B=slot, DE=buf3 -> A=1/0) DEF SYS_PROGNAME EQU 21 ; program id -> name (B=id, DE=namebuf) DEF SYS_REAP EQU 22 ; reap a zombie child, nohang (-> A=pid or 0) DEF SYS_BFILL EQU 23 ; [debug] fill a disk block (B=block, E=byte) DEF SYS_BPEEK EQU 24 ; [debug] read a disk block (B=block, E=off -> A) DEF SYS_MKDIR EQU 25 ; make a directory (DE=path -> A=0/$FF) DEF SYS_CHDIR EQU 26 ; change directory (DE=path -> A=0/$FF) DEF SYS_OPENDIR EQU 27 ; point ls at a directory (DE=path -> A=0/$FF) DEF SYS_PIPE EQU 28 ; make a pipe (-> A=read fd; write=A+1) DEF SYS_SSEND EQU 29 ; link-port: transmit one byte (E=byte) DEF SYS_SRECV EQU 30 ; link-port: receive one byte (-> A=byte, blocks) DEF SYS_SRECVNB EQU 31 ; link-port: receive, non-blocking (-> A=byte, CF=none) DEF SYS_POLLIN EQU 32 ; poll OSK for a typed char (-> A=char or 0) DEF SYS_NET EQU 33 ; socket layer (DE=&netreq -> A=result) DEF SYS_SLEEP EQU 34 ; cooperative delay (B = 1/64-second units) DEF SYS_MAX EQU 35 ; ---- socket layer (SYS_NET) -------------------------------------------------- ; netreq struct (in caller RAM; DE points to it): DEF NR_OP EQU 0 ; operation (below) DEF NR_SOCK EQU 1 ; socket id DEF NR_BUF EQU 2 ; 2: pointer to payload buffer DEF NR_LEN EQU 4 ; 1: payload length (in) / bytes received (out) DEF NR_IP EQU 5 ; 4: IPv4 address DEF NR_PORT EQU 9 ; 2: port (hi,lo) DEF NR_SIZE EQU 11 ; ops DEF NET_SOCKET EQU 0 ; NR_SOCK(type in) -> A=sockid or $FF DEF NET_CONNECT EQU 1 ; NR_SOCK, NR_IP, NR_PORT -> set peer DEF NET_SEND EQU 2 ; NR_SOCK, NR_BUF, NR_LEN -> A=0/$FF DEF NET_RECV EQU 3 ; NR_SOCK, NR_BUF, NR_LEN(max) -> A=len or $FF(timeout); fills NR_IP DEF NET_CLOSE EQU 4 ; NR_SOCK DEF NET_BIND EQU 5 ; NR_SOCK, NR_PORT -> bind local port (UDP) DEF NET_POLL EQU 6 ; pump RX once (answer pings) -> A=0 DEF NET_SETIP EQU 7 ; set our IPv4 address from NR_IP (DHCP) ; socket types DEF SOCK_ICMP EQU 1 DEF SOCK_UDP EQU 2 DEF SOCK_TCP EQU 3 DEF MAX_SOCKS EQU 4 ; SLIP framing (RFC 1055) DEF SLIP_END EQU $C0 DEF SLIP_ESC EQU $DB DEF SLIP_ESC_END EQU $DC DEF SLIP_ESC_ESC EQU $DD ; SYS_KILL (9) is now implemented (B=pid -> A=0/$FF; pid 1 is immortal) ; (SYS_OPEN=4 / SYS_CLOSE=5 are now implemented by the filesystem) ; ----------------------------------------------------------------------------- ; Block-based filesystem (on the persistent block device; see fs.asm). ; block 0 superblock (magic + version) ; block 1 bitmaps: block bitmap @0 (16 B), inode bitmap @16 (4 B) ; blocks 2-3 inode table (32 inodes x 16 B) ; blocks 4.. data blocks ; Metadata (bitmaps + inode table) is cached in WRAMX; data/dir blocks stream ; through fs_datbuf / fs_dirbuf. ; ----------------------------------------------------------------------------- DEF BLK_SUPER EQU 0 DEF BLK_BITMAP EQU 1 DEF BLK_INODE0 EQU 2 ; inode table = blocks 2,3 DEF BLK_DATA0 EQU 4 ; first data block DEF FS_VERSION EQU 3 ; bumped: dirs now carry "."/".." entries DEF NINODES EQU 32 DEF ROOT_INO EQU 1 DEF NDIRECT EQU 8 ; direct block pointers per inode -> files <= 2 KiB DEF DIRENTS EQU 16 ; directory entries per block (256/16) ; inode fields (16 bytes) DEF I_TYPE EQU 0 ; 0=free 1=file 2=dir DEF I_NLINK EQU 1 DEF I_SIZE EQU 2 ; 16-bit DEF I_BLOCKS EQU 4 ; 8 direct block pointers (1 byte each; 0=none) DEF IT_FREE EQU 0 DEF IT_FILE EQU 1 DEF IT_DIR EQU 2 ; directory entry (16 bytes): inode(1, 0=free) + name(15, NUL-term) DEF DE_INO EQU 0 DEF DE_NAME EQU 1 ; bitmap offsets within block 1 DEF BM_BLOCKS EQU 0 DEF BM_INODES EQU 16 ; WRAMX working buffers (freed by removing the old 8-slot FS) DEF fs_bmbuf EQU $D000 ; 256 B: bitmap block cache (block 1) DEF fs_inobuf EQU $D100 ; 512 B: inode table cache (blocks 2-3) DEF fs_dirbuf EQU $D300 ; 256 B: directory block scratch DEF fs_datbuf EQU $D400 ; 256 B: data block cache ; open-file table (kernel WRAM0): inuse, inode, mode, pos(2) DEF OF_MAX EQU 4 DEF OF_INUSE EQU 0 DEF OF_INODE EQU 1 DEF OF_MODE EQU 2 DEF OF_POS EQU 3 DEF OF_SIZE EQU 5 ; anonymous pipes DEF PIPE_MAX EQU 4 ; concurrent pipes (up to 5-stage pipelines) DEF PIPE_BUFSZ EQU 64 ; ring buffer bytes per pipe DEF PIPE_FD_BASE EQU $F0 ; pipe fds: $F0+idx*2 (read), +1 (write); $FF=console ; ----------------------------------------------------------------------------- ; Program table indices (see programs.asm). exec() takes one of these in B. ; ----------------------------------------------------------------------------- DEF PROG_WORKER EQU 0 DEF PROG_SH EQU 1 DEF PROG_HELLO EQU 2 DEF PROG_CHELLO EQU 3 ; C programs (compiled with SDCC), see c/ DEF PROG_ECHO EQU 4 DEF PROG_TRUE EQU 5 DEF PROG_FALSE EQU 6 DEF PROG_UNAME EQU 7 DEF PROG_PID EQU 8 DEF PROG_CAT EQU 9 DEF PROG_WC EQU 10 DEF PROG_HEAD EQU 11 DEF PROG_ARGS EQU 12 DEF PROG_LS EQU 13 DEF PROG_SAVE EQU 14 DEF PROG_RM EQU 15 DEF PROG_PS EQU 16 DEF PROG_KILL EQU 17 DEF PROG_SPIN EQU 18 DEF PROG_BLK EQU 19 DEF PROG_MKDIR EQU 20 DEF PROG_COUNT EQU 21 DEF PROG_PTEST EQU 22 DEF PROG_NECHO EQU 23 DEF PROG_WGET EQU 24 DEF PROG_CHAT EQU 25 DEF PROG_NETD EQU 26 DEF PROG_PING EQU 27 DEF PROG_NSLOOKUP EQU 28 DEF PROG_DHCP EQU 29 ENDC