mirror of
https://git.k-space.ee/arti/vt1200.git
synced 2026-10-31 12:05:05 +02:00
harness/mame/NETWORK_REPORT.md: how the VT1200 firmware drives the LANCE, from ROM disassembly and MAME traces. 50 sections, each claim tied to a bit address, a trace count or a quoted source line. Covers the driver device struct (0x23CBF0), init (0x3F9D4BC0), descriptor/DMA encoding, the live handler (0x3F9D5B40) with per-status-bit dispatch, the RX poll (0x3F9D62B0), ring arming (0x3F9D36C0), TX completion (0x3F9D8AF0) and the single transmit path every protocol uses (0x3F6084E0 -> 0x3F9DC890 -> 0x3F9D4BC0), plus the IP protocol dispatch (0x3F6270F0), ICMP (343-count chain), TCP state tables and live TIME_WAIT, the ARP responder (0x3F6119A0) and the socket 4-tuple demux confirmed by a memory dump. It also records what was withdrawn: five successive explanations for the real-silicon CSR0=0x1BB / TMD1=0x8338 result, and the descriptor-length encoding bug found by comparing Linux 7990.c and NetBSD am7990.c (length must be 0xF000 | -len; MAME masks the difference in get_buf_length). harness/udpstream: the LANCE loopback/takeover payload and the variants used to test the init/kick orderings in MAME (bare TDMD, STOP before INIT, double INIT, long wait with CSR0 sampling, IDON clear, corrected descriptor length). build-lance.sh takes LANCE_SRC/LANCE_OUT so the variants build from one script.
137 lines
2.9 KiB
NASM
137 lines
2.9 KiB
NASM
; 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
|