aboutsummaryrefslogtreecommitdiffstats
path: root/src/programs.asm
blob: c6228f30fb040aaf5e20c6fdddf83b7534ab9300 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
; =============================================================================
; programs.asm - userland program images (text-in-ROM model) + the shell.
;
; Programs are linked to run from the ROMX window ($4000-$7FFF) and live in
; their own ROM banks. exec() maps the bank and jumps in. Programs talk to the
; kernel only via `rst $30`.
; =============================================================================
INCLUDE "include/gbos.inc"

; the shell keeps its line buffer + scratch at the bottom of its RAM bank
DEF SH_LINEBUF EQU $A000        ; up to 32 bytes
DEF SH_PROGID  EQU $A040        ; chosen program id (survives fork via bank copy)
DEF SH_MAXLINE EQU 32

; -----------------------------------------------------------------------------
; PROG_WORKER (bank 2) - print a line, exit(0).
; -----------------------------------------------------------------------------
SECTION "prog_worker", ROMX[$4000], BANK[2]
ProgWorker:
    ld de, .msg
    ld b, .msgend - .msg
    ld c, SYS_WRITE
    rst $30
    ld b, 0
    ld c, SYS_EXIT
    rst $30
.msg
    db "worker!", $0D, $0A
.msgend

; -----------------------------------------------------------------------------
; PROG_HELLO (bank 4) - print a line, exit(0).
; -----------------------------------------------------------------------------
SECTION "prog_hello", ROMX[$4000], BANK[4]
ProgHello:
    ld de, .msg
    ld b, .msgend - .msg
    ld c, SYS_WRITE
    rst $30
    ld b, 0
    ld c, SYS_EXIT
    rst $30
.msg
    db "hello world!", $0D, $0A
.msgend

; -----------------------------------------------------------------------------
; PROG_CHELLO (bank 5) - a program written in C, compiled with SDCC to a
; self-contained ROM-bank image (crt0 + libc + code) and included verbatim.
; Rebuild with: make (or: sh usr/build.sh usr/chello.c build/usr/chello.bin)
; -----------------------------------------------------------------------------
SECTION "prog_chello", ROMX[$4000], BANK[5]
ProgChello:
    INCBIN "build/usr/chello.bin"
SECTION "prog_echo",   ROMX[$4000], BANK[6]
ProgEcho:
    INCBIN "build/usr/echo.bin"
SECTION "prog_true",   ROMX[$4000], BANK[7]
ProgTrue:
    INCBIN "build/usr/true.bin"
SECTION "prog_false",  ROMX[$4000], BANK[8]
ProgFalse:
    INCBIN "build/usr/false.bin"
SECTION "prog_uname",  ROMX[$4000], BANK[9]
ProgUname:
    INCBIN "build/usr/uname.bin"
SECTION "prog_pid",    ROMX[$4000], BANK[10]
ProgPid:
    INCBIN "build/usr/pid.bin"
SECTION "prog_cat",    ROMX[$4000], BANK[11]
ProgCat:
    INCBIN "build/usr/cat.bin"
SECTION "prog_wc",     ROMX[$4000], BANK[12]
ProgWc:
    INCBIN "build/usr/wc.bin"
SECTION "prog_head",   ROMX[$4000], BANK[13]
ProgHead:
    INCBIN "build/usr/head.bin"
SECTION "prog_args",   ROMX[$4000], BANK[14]
ProgArgs:
    INCBIN "build/usr/args.bin"
SECTION "prog_ls",     ROMX[$4000], BANK[15]
ProgLs:
    INCBIN "build/usr/ls.bin"
SECTION "prog_save",   ROMX[$4000], BANK[16]
ProgSave:
    INCBIN "build/usr/save.bin"
SECTION "prog_rm",     ROMX[$4000], BANK[17]
ProgRm:
    INCBIN "build/usr/rm.bin"
SECTION "prog_ps",     ROMX[$4000], BANK[18]
ProgPs:
    INCBIN "build/usr/ps.bin"
SECTION "prog_kill",   ROMX[$4000], BANK[19]
ProgKill:
    INCBIN "build/usr/kill.bin"
SECTION "prog_spin",   ROMX[$4000], BANK[20]
ProgSpin:
    INCBIN "build/usr/spin.bin"
SECTION "prog_blk",    ROMX[$4000], BANK[21]
ProgBlk:
    INCBIN "build/usr/blk.bin"
SECTION "prog_mkdir",  ROMX[$4000], BANK[22]
ProgMkdir:
    INCBIN "build/usr/mkdir.bin"
SECTION "prog_count",  ROMX[$4000], BANK[23]
ProgCount:
    INCBIN "build/usr/count.bin"
SECTION "prog_ptest",  ROMX[$4000], BANK[24]
ProgPtest:
    INCBIN "build/usr/ptest.bin"
SECTION "prog_necho",  ROMX[$4000], BANK[25]
ProgNecho:
    INCBIN "build/usr/necho.bin"
SECTION "prog_wget",   ROMX[$4000], BANK[26]
ProgWget:
    INCBIN "build/usr/wget.bin"
SECTION "prog_chat",   ROMX[$4000], BANK[27]
ProgChat:
    INCBIN "build/usr/chat.bin"
SECTION "prog_netd",   ROMX[$4000], BANK[28]
ProgNetd:
    INCBIN "build/usr/netd.bin"
SECTION "prog_ping",   ROMX[$4000], BANK[29]
ProgPing:
    INCBIN "build/usr/ping.bin"
SECTION "prog_nslookup", ROMX[$4000], BANK[30]
ProgNslookup:
    INCBIN "build/usr/nslookup.bin"
SECTION "prog_dhcp",   ROMX[$4000], BANK[31]
ProgDhcp:
    INCBIN "build/usr/dhcp.bin"
SECTION "prog_irc",    ROMX[$4000], BANK[32]
ProgIrc:
    INCBIN "build/usr/irc.bin"
SECTION "prog_uptime", ROMX[$4000], BANK[33]
ProgUptime:
    INCBIN "build/usr/uptime.bin"
SECTION "prog_ansi",   ROMX[$4000], BANK[34]
ProgAnsi:
    INCBIN "build/usr/ansi.bin"

; -----------------------------------------------------------------------------
; PROG_SH (bank 3) - the shell, now written in C (usr/sh.c): parses >/</| and
; drives fork+exec+wait with I/O redirection. Command lookup + StrEqual/SkipName
; live in the kernel now (sys_lookup + NameTable + shell_lib).
; -----------------------------------------------------------------------------
SECTION "prog_sh", ROMX[$4000], BANK[3]
ProgSh:
    INCBIN "build/usr/sh.bin"

; -----------------------------------------------------------------------------
; Shell string helpers (ROM0, always mapped).
; -----------------------------------------------------------------------------
SECTION "shell_lib", ROM0
; StrEqual(HL, DE) - compare NUL-terminated strings. Z set if equal.
; Clobbers A, B; advances HL and DE.
StrEqual::
.l
    ld a, [de]
    ld b, a
    ld a, [hl]
    cp b
    ret nz
    or a
    ret z                       ; both NUL -> equal
    inc hl
    inc de
    jr .l
; SkipName(DE) - advance DE to its NUL terminator.
SkipName::
.l
    ld a, [de]
    or a
    ret z
    inc de
    jr .l

; -----------------------------------------------------------------------------
; Program table (ROM0). Index = program id. Entry: bank (2) + entry addr (2).
; -----------------------------------------------------------------------------
SECTION "progtab", ROM0
ProgramTable::
    db LOW(BANK(ProgWorker)), HIGH(BANK(ProgWorker))
    dw ProgWorker
    db LOW(BANK(ProgSh)), HIGH(BANK(ProgSh))
    dw ProgSh
    db LOW(BANK(ProgHello)), HIGH(BANK(ProgHello))
    dw ProgHello
    db LOW(BANK(ProgChello)), HIGH(BANK(ProgChello))
    dw ProgChello
    db LOW(BANK(ProgEcho)), HIGH(BANK(ProgEcho))
    dw ProgEcho
    db LOW(BANK(ProgTrue)), HIGH(BANK(ProgTrue))
    dw ProgTrue
    db LOW(BANK(ProgFalse)), HIGH(BANK(ProgFalse))
    dw ProgFalse
    db LOW(BANK(ProgUname)), HIGH(BANK(ProgUname))
    dw ProgUname
    db LOW(BANK(ProgPid)), HIGH(BANK(ProgPid))
    dw ProgPid
    db LOW(BANK(ProgCat)), HIGH(BANK(ProgCat))
    dw ProgCat
    db LOW(BANK(ProgWc)), HIGH(BANK(ProgWc))
    dw ProgWc
    db LOW(BANK(ProgHead)), HIGH(BANK(ProgHead))
    dw ProgHead
    db LOW(BANK(ProgArgs)), HIGH(BANK(ProgArgs))
    dw ProgArgs
    db LOW(BANK(ProgLs)), HIGH(BANK(ProgLs))
    dw ProgLs
    db LOW(BANK(ProgSave)), HIGH(BANK(ProgSave))
    dw ProgSave
    db LOW(BANK(ProgRm)), HIGH(BANK(ProgRm))
    dw ProgRm
    db LOW(BANK(ProgPs)), HIGH(BANK(ProgPs))
    dw ProgPs
    db LOW(BANK(ProgKill)), HIGH(BANK(ProgKill))
    dw ProgKill
    db LOW(BANK(ProgSpin)), HIGH(BANK(ProgSpin))
    dw ProgSpin
    db LOW(BANK(ProgBlk)), HIGH(BANK(ProgBlk))
    dw ProgBlk
    db LOW(BANK(ProgMkdir)), HIGH(BANK(ProgMkdir))
    dw ProgMkdir
    db LOW(BANK(ProgCount)), HIGH(BANK(ProgCount))
    dw ProgCount
    db LOW(BANK(ProgPtest)), HIGH(BANK(ProgPtest))
    dw ProgPtest
    db LOW(BANK(ProgNecho)), HIGH(BANK(ProgNecho))
    dw ProgNecho
    db LOW(BANK(ProgWget)), HIGH(BANK(ProgWget))
    dw ProgWget
    db LOW(BANK(ProgChat)), HIGH(BANK(ProgChat))
    dw ProgChat
    db LOW(BANK(ProgNetd)), HIGH(BANK(ProgNetd))
    dw ProgNetd
    db LOW(BANK(ProgPing)), HIGH(BANK(ProgPing))
    dw ProgPing
    db LOW(BANK(ProgNslookup)), HIGH(BANK(ProgNslookup))
    dw ProgNslookup
    db LOW(BANK(ProgDhcp)), HIGH(BANK(ProgDhcp))
    dw ProgDhcp
    db LOW(BANK(ProgIrc)), HIGH(BANK(ProgIrc))
    dw ProgIrc
    db LOW(BANK(ProgUptime)), HIGH(BANK(ProgUptime))
    dw ProgUptime
    db LOW(BANK(ProgAnsi)), HIGH(BANK(ProgAnsi))
    dw ProgAnsi
ProgramTableEnd::

; -----------------------------------------------------------------------------
; NameTable (ROM0) - command name -> program id, searched by sys_lookup.
; -----------------------------------------------------------------------------
SECTION "nametab", ROM0
NameTable::
    db "worker", 0
    db PROG_WORKER
    db "hello", 0
    db PROG_HELLO
    db "chello", 0
    db PROG_CHELLO
    db "echo", 0
    db PROG_ECHO
    db "true", 0
    db PROG_TRUE
    db "false", 0
    db PROG_FALSE
    db "uname", 0
    db PROG_UNAME
    db "pid", 0
    db PROG_PID
    db "cat", 0
    db PROG_CAT
    db "wc", 0
    db PROG_WC
    db "head", 0
    db PROG_HEAD
    db "args", 0
    db PROG_ARGS
    db "ls", 0
    db PROG_LS
    db "save", 0
    db PROG_SAVE
    db "rm", 0
    db PROG_RM
    db "sh", 0
    db PROG_SH
    db "ps", 0
    db PROG_PS
    db "kill", 0
    db PROG_KILL
    db "spin", 0
    db PROG_SPIN
    db "blk", 0
    db PROG_BLK
    db "mkdir", 0
    db PROG_MKDIR
    db "count", 0
    db PROG_COUNT
    db "ptest", 0
    db PROG_PTEST
    db "necho", 0
    db PROG_NECHO
    db "wget", 0
    db PROG_WGET
    db "chat", 0
    db PROG_CHAT
    db "netd", 0
    db PROG_NETD
    db "ping", 0
    db PROG_PING
    db "nslookup", 0
    db PROG_NSLOOKUP
    db "dhcp", 0
    db PROG_DHCP
    db "irc", 0
    db PROG_IRC
    db "uptime", 0
    db PROG_UPTIME
    db "ansi", 0
    db PROG_ANSI
    db 0