diff options
| author | user <user@clank> | 2026-09-22 16:02:55 +0200 |
|---|---|---|
| committer | user <user@clank> | 2026-09-22 16:02:55 +0200 |
| commit | 43e43b6dcec29e2b008d20135f5d02523b62fbcf (patch) | |
| tree | d647acd07596e290c70a9884c1dc5d8c20a31067 /src | |
| parent | net: three TCP receive bugs - caller corruption, data loss, early EOF (diff) | |
| download | gbos-43e43b6dcec29e2b008d20135f5d02523b62fbcf.tar.gz gbos-43e43b6dcec29e2b008d20135f5d02523b62fbcf.tar.xz gbos-43e43b6dcec29e2b008d20135f5d02523b62fbcf.zip | |
usr: grep, more, cp, nc - and make pollcon pump the link
The shell has had pipes for a while with nothing to pipe *through*, and
an 18-row screen with no way to stop output scrolling off it.
- grep [-vin] PAT [file]: substring match (no regex), stdin or a file,
grep(1)'s exit convention. The other end of the pipe, at last.
- more [file]: pages 17 lines at a time, --More-- bar in white-on-blue,
any key pages, q quits. Counts *screen* rows, so wrapped lines pay
their real cost. Keys come from pollin/pollcon, not stdin, so
`cat big | more` still has a keyboard.
- cp SRC DST: the fs has rm/mkdir but no way to duplicate a file. mv is
this plus rm (there is no rename). Rejects SRC == DST, which would
otherwise truncate the source via O_WRITE before reading a byte.
- nc [-s] HOST PORT: raw TCP. Interactive (START sends the line with a
CRLF, /q quits) or -s to pump stdin and print the reply with its own
wall-clock idle timeout, because the kernel's blocking recv counts
pumps, not seconds. Generalizes what chat/irc hardcode:
`nc towel.blinkenlights.nl 23` works.
sys_pollcon now pumps the link before draining the console ring. The
ring is filled *by* net_pump, so a program that never touches the
network polled a ring nothing would ever fill: host-injected keys
(gbtype/gbdemo) hung `more` forever, and the Game Boy stopped answering
pings for as long as it ran. KGetc already pumps for this reason.
New tools take banks 35-38. Locals over statics in all four: a program's
_DATA starts at $A000, where the shell leaves the command line.
Diffstat (limited to 'src')
| -rw-r--r-- | src/net.asm | 11 | ||||
| -rw-r--r-- | src/programs.asm | 28 |
2 files changed, 37 insertions, 2 deletions
diff --git a/src/net.asm b/src/net.asm index 8309242..a5f0210 100644 --- a/src/net.asm +++ b/src/net.asm @@ -56,9 +56,16 @@ sys_srecv_nb:: ; sys_pollcon() -> A = a queued console-ring byte (link-injected input, ; e.g. gbhub 'type'), or 0 if none. Non-blocking twin of KGetc's con_pop -; path: programs that own their main loop (irc) poll this alongside the OSK. -; The ring fills during net pumps, which such programs do constantly. +; path: programs that own their main loop (irc, nc, more) poll this alongside +; the OSK. +; +; Pump the link first. The ring is filled BY net_pump, so a caller that never +; touches the network (a pager, a game) would otherwise poll a ring nothing +; ever fills - host-injected keys (gbtype/gbdemo) would hang it forever, and +; the Game Boy would stop answering pings for as long as it ran. KGetc already +; pumps for exactly this reason; pollcon now matches it. sys_pollcon:: + call net_pump call con_pop ret nc ; got a byte xor a diff --git a/src/programs.asm b/src/programs.asm index c6228f3..a3bd680 100644 --- a/src/programs.asm +++ b/src/programs.asm @@ -139,6 +139,18 @@ ProgUptime: SECTION "prog_ansi", ROMX[$4000], BANK[34] ProgAnsi: INCBIN "build/usr/ansi.bin" +SECTION "prog_grep", ROMX[$4000], BANK[35] +ProgGrep: + INCBIN "build/usr/grep.bin" +SECTION "prog_more", ROMX[$4000], BANK[36] +ProgMore: + INCBIN "build/usr/more.bin" +SECTION "prog_cp", ROMX[$4000], BANK[37] +ProgCp: + INCBIN "build/usr/cp.bin" +SECTION "prog_nc", ROMX[$4000], BANK[38] +ProgNc: + INCBIN "build/usr/nc.bin" ; ----------------------------------------------------------------------------- ; PROG_SH (bank 3) - the shell, now written in C (usr/sh.c): parses >/</| and @@ -247,6 +259,14 @@ ProgramTable:: dw ProgUptime db LOW(BANK(ProgAnsi)), HIGH(BANK(ProgAnsi)) dw ProgAnsi + db LOW(BANK(ProgGrep)), HIGH(BANK(ProgGrep)) + dw ProgGrep + db LOW(BANK(ProgMore)), HIGH(BANK(ProgMore)) + dw ProgMore + db LOW(BANK(ProgCp)), HIGH(BANK(ProgCp)) + dw ProgCp + db LOW(BANK(ProgNc)), HIGH(BANK(ProgNc)) + dw ProgNc ProgramTableEnd:: ; ----------------------------------------------------------------------------- @@ -320,4 +340,12 @@ NameTable:: db PROG_UPTIME db "ansi", 0 db PROG_ANSI + db "grep", 0 + db PROG_GREP + db "more", 0 + db PROG_MORE + db "cp", 0 + db PROG_CP + db "nc", 0 + db PROG_NC db 0 |
