This file is indexed.

/usr/share/z88dk/lib/z88s_crt0.asm is in z88dk-data 1.8.ds1-10.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
;
;       Startup stub for z88 Shell programs
;
;       Created 12/2/2002 djm
;
;	$Id: z88s_crt0.asm,v 1.8 2007/06/27 20:49:28 dom Exp $



	INCLUDE	"#stdio.def"
	INCLUDE "#error.def"

	INCLUDE	"#shellapi.def"

	org	shell_loadaddr-shell_headerlen

.header_start
        defm    "!bin"
	defb	shell_verh
	defb	shell_verm
	defb	shell_verl
	defb	13
.shell_length
        defw    0		; Fill in by make program
        defw    start


;-----------
; Code starts executing from here
;-----------
.start
	push	bc		; Preserve registers that need to be
	push	de	
	ld	(saveix),ix
	ld	(saveiy),iy
	ld	(start1+1),sp	;Save starting stack
	ld	hl,(shell_cmdlen)
	ld	de,(shell_cmdaddr)
	add	hl,de
	ld	(hl),0		; terminate command line
	ld	hl,-100		; atexit stack (64) + argv space
	add	hl,sp
        ld      sp,hl
        ld      (exitsp),sp	
        call    doerrhan	;Initialise a laughable error handler

		
;-----------
; Initialise the (ANSI) stdio descriptors so we can be called agin
;-----------
IF DEFINED_ANSIstdio
	ld	hl,__sgoioblk+2
	ld	(hl),19	;stdin
	ld	hl,__sgoioblk+6
	ld	(hl),21	;stdout
	ld	hl,__sgoioblk+10
	ld	(hl),21	;stderr
ENDIF
	;; Read in argc/argv
	ld	hl,0		; NULL pointer at end just in case
	push	hl
	;; Try and work out the length available
	ld	hl,(shell_cmdlen)
	ld	de,(shell_cmdaddr)
	add	hl,de		; points to end
	ex	de,hl		; end now in de, hl=cmdaddr
	ld	bc,(shell_cmdptr)
	add	hl,bc		; start in hl
	push	de		; save end
	ex	de,hl		; hl = end, de = start
	and	a
	sbc	hl,de		; hl is length available
	ex	de,hl		; is now in de
	pop	hl		; points to terminator
	ld	c,0		; number of arguments
	ld	a,d
	or	e
	jr	z,argv_none
	dec	hl
	dec	de		; available length
.argv_loop
	ld	a,d
	or	e
	jr	z,argv_exit
	ld	a,(hl)
	cp	' '
	jr	nz,argv_loop2
	ld	(hl),0		; terminate previous one
	inc	hl
	inc	c
	push	hl
	dec	hl
.argv_loop2
	dec	hl
	dec	de
	jr	argv_loop
.argv_exit
	push	hl		; first real argument
	inc	c
.argv_none
	ld	hl,end		; program name
	inc	c
	push	hl		
	ld	hl,0
	add	hl,sp		; address of argv
	ld	b,0
	push	bc		; argc
	push	hl		; argv
	ld	hl,(shell_cmdlen)
	ld	(shell_cmdptr),hl
	call_oz(gn_nln)		; Start a new line...
IF DEFINED_farheapsz
        call    init_far        ;Initialise far memory if required
ENDIF
        call    _main		;Run the program
IF DEFINED_farheapsz
        call    freeall_far        ;Initialise far memory if required
ENDIF
	pop	bc		; kill argv
	pop	bc		; kill argc
	
.cleanup			;Jump back here from exit() if needed
IF DEFINED_ANSIstdio
	LIB	closeall
	call	closeall	;Close any open files (fopen)
ENDIF
        call    resterrhan	;Restore the original error handler
	
.start1	ld	sp,0		;Restore stack to entry value
	ld	ix,(saveix)	;Get back those registers
	ld	iy,(saveiy)
	pop	de
	pop	bc
	jp	shell_next	; phew! back to Forth at last.

;-----------
; Install the error handler
;-----------
.doerrhan
        xor     a
        ld      (exitcount),a
        ld      b,0
        ld      hl,errhand
        call_oz(os_erh)
        ld      (l_erraddr),hl
        ld      (l_errlevel),a
        ret

;-----------
; Restore BASICs error handler
;-----------
.resterrhan
        ld      hl,(l_erraddr)
        ld      a,(l_errlevel)
        ld      b,0
        call_oz(os_erh)
.processcmd			;processcmd is called after os_tin
        ld      hl,0
        ret


;-----------
; The error handler
;-----------
.errhand
        ret     z   		;Fatal error
        cp      rc_esc
        jr     z,errescpressed
        ld      hl,(l_erraddr)	;Pass everything to BASIC's handler
        scf
.l_dcal	jp	(hl)		;Used for function pointer calls also

.errescpressed
        call_oz(os_esc)		;Acknowledge escape pressed
        jr      cleanup		;Exit the program


;-----------
; Select which vfprintf routine is needed
;-----------
._vfprintf
IF DEFINED_floatstdio
	LIB	vfprintf_fp
	jp	vfprintf_fp
ELSE
	IF DEFINED_complexstdio
		LIB	vfprintf_comp
		jp	vfprintf_comp
	ELSE
		IF DEFINED_ministdio
			LIB	vfprintf_mini
			jp	vfprintf_mini
		ENDIF
	ENDIF
ENDIF


;--------
; Far memory setup
;--------
IF DEFINED_farheapsz
        LIB     freeall_far
        XDEF    farpages
        XDEF    malloc_table
        XDEF    farmemspec
        XDEF    pool_table
        INCLUDE "#init_far.asm"

; Variables that can't be place in the normal defvars
.copybuff	defs	258
.actual_malloc-table
		defs	((farheapsz/256)+1)*2

; Now some memory shared with Forth - same as application setup
DEFVARS 8192
{
        pool_table      ds.b    224
        malloc_table    ds.w    1
        farpages        ds.w    1
        farmemspec      ds.b    1
}
ENDIF

;--------
; This bit of code allows us to use OZ ptrs transparently
; We copy any data from up far to a near buffer so that OZ
; is happy about it
; Prototype is extern void __FASTCALL__ *cpfar2near(far void *)
;--------
IF DEFINED_farheapsz
        LIB     strcpy_far
._cpfar2near
        pop     bc      ;ret address
        pop     hl
        pop     de      ;far ptr
        push    bc      ;keep ret address
        ld      a,e
        and     a
        ret     z       ;already local
        push    ix      ;keep ix safe
        ld      bc,0    ;local
        push    bc
        ld      bc,copybuff
        push    bc      ;dest
        push    de      ;source
        push    hl
        call    strcpy_far
        pop     bc      ;dump args
        pop     bc
        pop     bc
        pop     bc
        pop     ix      ;get ix back
        ld      hl,copybuff
        ret
ELSE
; We have no far code installed so all we have to do is fix the stack
._cpfar2near
        pop     bc
        pop     hl
        pop     de
        push    bc
        ret
ENDIF


;----------
; The system() function for the shell 
;----------
	XDEF	_system
._system
	pop	de		; DE=return address
	pop	bc		; BC=command address
	push	bc
	push	de
	push	bc		; Forth stack: addr--
	ld	hl,system_forthcode
	call	_shellapi
				; Forth stack: flag--
	pop	hl		; HL=0 or error code
	ret

.system_forthcode
	defw	shell_also,shell_internal,shell_ztos,shell_eval,shell_previous
	defw	shellapi_back

;----------
; The shellapi() interface
;----------
	XDEF	_shellapi

._shellapi
	push	hl
	call	resterrhan	;restore forth error handler
	pop	de		; DE=Forth's IP
	ld	iy,(saveiy)	; IY=Forth's UP
	ld	ix,(saveix)	; IX=Forth's RSP
	pop	hl
	dec	ix
	ld	(ix+0),h	; save return address on Forth's return stack
	dec	ix
	ld	(ix+0),l
	pop	bc		; BC=TOS
	jp	shell_next	; execute Forth code
.shellapi_back
	push	bc		; stack TOS
	ld	e,(ix+0)
	ld	d,(ix+1)
	push	de		; stack return address
	call	doerrhan	;put c error hander back
	ret


;-----------
; Define the stdin/out/err area. For the z88 we have two models - the
; classic (kludgey) one and "ANSI" model
;-----------
.__sgoioblk
IF DEFINED_ANSIstdio
	INCLUDE	"#stdio_fp.asm"
ELSE
        defw    -11,-12,-10
ENDIF


;-----------
; Now some variables
;-----------
.l_erraddr	defw	0	; BASIC error handler address
.l_errlevel	defb	0	; And error level


.coords         defw	0	; Current graphics xy coordinates
.base_graphics  defw	0	; Address of the Graphics map
.gfx_bank       defb    0	; And the bank

._std_seed       defw    0	; Seed for integer rand() routines

.exitsp		defw	0	; Address of where the atexit() stack is
.exitcount	defb	0	; How many routines on the atexit() stack

IF DEFINED_NEED1bitsound
.snd_asave      defb    0	; Sound variable
.snd_tick       defb    0	;  "      "
ENDIF


.heaplast	defw	0	; Address of last block on heap
.heapblocks	defw 	0	; Number of blocks

.packintrout	defw	0	; Address of user interrupt routine

.saveix		defw	0	; Save ix for system() calls
.saveiy		defw	0	; Save iy for system() calls


;-----------
; Unnecessary file signature
;-----------
		defm	"Small C+ z88shell"
.end		defb	0

;-----------
; Floating point
;-----------
IF NEED_floatpack
        INCLUDE         "#float.asm"

.fp_seed        defb    $80,$80,0,0,0,0	; FP seed (unused ATM)
.extra          defs    6		; Extra register temp store
.fa             defs    6		; ""
.fasign         defb    0		; ""

ENDIF