; entry.asm -- C process entry + call-throughs to the firmware socket API. ; ; _start replaces boot.obj (whose exit() spins and whose _c_int00 ends in ; `reti`): set up the C program stack, call main, return with `rets` to the ; create_process trampoline. ; ; The socket wrappers are NOT a bare `calla`/`rets`. The firmware's wrappers ; end in `RETS 2`: they pop the return address *and* two argument words, and ; they restore A14 from a caller-pushed slot. A plain thunk therefore returns ; with SP one word off, and its own `rets` pops the saved-A14 slot (a bit ; pointer into .bss) as the return address -- the CPU then executes data and ; the board lands in its reset/delay path. dwt/tcpip/tftpc.asm avoids this by ; saving SP and A14 in cells around every ROM call; these thunks do the same. ; ; socket = 3F5C9A00h socket(domain, type, protocol) -> fd ; bind = 3F5CAA80h bind(fd, sockaddr*, len) -> 0 / -1 ; recvfrom = 3F5D7D50h recvfrom(fd, buf, len, flags, &from, &fromlen) -> n ; close = 3F5E8930h close(fd) ; malloc = 3F701230h malloc(bytes) -> bit pointer ; free = 3F702440h free(bit pointer) ; ; See dwt/notes/TCPIP.md. .text .globl _start .globl _main _start: setf 32, 0, 1 movi _cstack, a14 move a14, a13 calla _main rets .globl _socket_ _socket_: move sp, @_sys_sp, 1 move a14, @_sys_a14, 1 calla 3F5C9A00h move @_sys_sp, sp, 1 move @_sys_a14, a14, 1 rets 2 .globl _bind_ _bind_: move sp, @_sys_sp, 1 move a14, @_sys_a14, 1 calla 3F5CAA80h move @_sys_sp, sp, 1 move @_sys_a14, a14, 1 rets 2 .globl _recvfrom_ _recvfrom_: move sp, @_sys_sp, 1 move a14, @_sys_a14, 1 calla 3F5D7D50h move @_sys_sp, sp, 1 move @_sys_a14, a14, 1 rets 2 .globl _close_ _close_: move sp, @_sys_sp, 1 move a14, @_sys_a14, 1 calla 3F5E8930h move @_sys_sp, sp, 1 move @_sys_a14, a14, 1 rets 2 .globl _malloc_ _malloc_: move sp, @_sys_sp, 1 move a14, @_sys_a14, 1 calla 3F701230h move @_sys_sp, sp, 1 move @_sys_a14, a14, 1 rets 2 .globl _delay_ _delay_: move sp, @_sys_sp, 1 move a14, @_sys_a14, 1 calla 3F833A20h move @_sys_sp, sp, 1 move @_sys_a14, a14, 1 rets 2 .globl _listen_ _listen_: move sp, @_sys_sp, 1 move a14, @_sys_a14, 1 calla 3F5CBCD0h move @_sys_sp, sp, 1 move @_sys_a14, a14, 1 rets 2 .globl _accept_ _accept_: move sp, @_sys_sp, 1 move a14, @_sys_a14, 1 calla 3F5CCB40h move @_sys_sp, sp, 1 move @_sys_a14, a14, 1 rets 2 .globl _read_ _read_: move sp, @_sys_sp, 1 move a14, @_sys_a14, 1 calla 3F5D8E70h move @_sys_sp, sp, 1 move @_sys_a14, a14, 1 rets 2 .globl _select_ _select_: move sp, @_sys_sp, 1 move a14, @_sys_a14, 1 calla 3F871CE0h move @_sys_sp, sp, 1 move @_sys_a14, a14, 1 rets 2 .globl _free_ _free_: move sp, @_sys_sp, 1 move a14, @_sys_a14, 1 calla 3F702440h move @_sys_sp, sp, 1 move @_sys_a14, a14, 1 rets 2 .bss _cstack, 32768, 16 ; 32768 bits = 4096 bytes .bss _sys_sp, 32, 16 .bss _sys_a14, 32, 16 .end