start.S revision 1.1 1 ; $NetBSD: start.S,v 1.1 2014/02/24 07:23:43 skrll Exp $
2
3 ; Copyright (c) 2003 ITOH Yasufumi.
4 ; All rights reserved.
5 ;
6 ; Redistribution and use in source and binary forms, with or without
7 ; modification, are permitted provided that the following conditions
8 ; are met:
9 ; 1. Redistributions of source code must retain the above copyright
10 ; notice, this list of conditions and the following disclaimer.
11 ; 2. Redistributions in binary forms are unlimited.
12 ;
13 ; THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS''
14 ; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 ; THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 ; PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS
17 ; BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 ; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 ; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 ; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 ; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 ; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 ; THE POSSIBILITY OF SUCH DAMAGE.
24
25 .level 1.0
26
27 .code
28 .origin 0
29 ;
30 ; LIF (Logical Interchange Format) header
31 ;
32 lifhdr: .byte 0x80,0x00 ; LIF magic
33 .string "NetBSD" ; volume label (6 chars, fill with space)
34 .origin 0xf0
35 ; 0xf0
36 lif_ipl_addr:
37 .word top-lifhdr ; start at 4KB (must be 2KB aligned)
38 lif_ipl_size:
39 .word 0x00001000 ; size 4KB (must be 2KB aligned)
40 lif_ipl_entry:
41 .word $START$-top ; entry offset
42
43 ; ipl part 1 starts here
44 .origin 4096
45 top:
46 ;
47 ; IPL startup
48 ;
49 ; arg0 = interact flag (1: interactive, 0: otherwise)
50 ; arg1 = address of first doubleword past the end of ipl part 1
51 ;
52 .export $START$,entry
53 $START$:
54 b,n start ; 0: entry address
55
56 ; version of interface of primary to secondary boot
57 BOOT_IF_VERSION: .equ 0
58 ; version 0: arg0 = interact flag, arg1 = version (0),
59 ; arg2 = end addr, arg3 = selected boot partition
60 ; r1, r3 - r22, r28, r29, r31 = cleared to zeros
61
62 cksum: .word 0 ; 4: checksum will be stored here
63 version: .word BOOT_IF_VERSION ; 8: version of interface
64 rsvd1: .word 0 ; 12: future use
65 rsvd2: .word 0 ; 16: future use
66 rsvd3: .word 0 ; 20: future use
67
68 start:
69 ; set data pointer for relocatable data access
70 blr %r0,%r27
71 ; get PSW at entry
72 ssm 0,%r4
73 .export $global$,data
74 $global$:
75
76 ; save parameters for main
77 copy %arg0,%r3
78
79 tmpdiskbufsz: .equ 0x1000 ; 4KB
80 tmpdiskbuf_labelsec: .equ 0x0200 ; dbtob(LABELSECTOR)
81 tmpdiskbuf_labelsecsz: .equ 512
82 tmpdiskbuf_part2: .equ 0x0400
83 tmpdiskbuf_part2sz: .equ 0x0400
84 tmpdiskbuf_part3: .equ 0x0A00
85 tmpdiskbuf_part3sz: .equ 0x0600
86
87 part1sz: .equ 0x1000
88
89 ; get next free address
90 .import _end,data
91 addil L%_end-$global$,%r27;%r1
92 ldo R%_end-$global$(%r1),%r1
93
94 ; 32bit environment (and this code) requires stack is 64byte aligned.
95 ldi 64-1,%r2
96 add %r1,%r2,%r1
97 andcm %r1,%r2,%r6 ; r6 = tmp disk buffer
98 ldo tmpdiskbufsz+64(%r6),%sp ; tmp stack
99
100 bl print,%rp
101 ldo str_startup-$global$(%r27),%arg0
102
103 ;
104 ; read part 2 and 3 of ipl (see README.ipl)
105 ;
106
107 ; read disk blocks which contains ipl part 2 and part 3
108 copy %r6,%arg0
109 ldi 0,%arg2 ; offset = 0
110 bl boot_input,%rp
111 ldi tmpdiskbufsz,%arg1 ; read size
112
113 ; part 2 address
114 ldo top-$global$+part1sz(%r27),%r19
115
116 ; copy part 2
117 ldo tmpdiskbuf_part2(%r6),%r20
118 addi,tr tmpdiskbuf_part2sz/4,%r0,%r2 ; loop count, skip next
119 cpipl2: stws,ma %r1,4(0,%r19) ; write to dst
120 addib,uv,n -1,%r2,cpipl2 ; check loop condition
121 ldws,ma 4(0,%r20),%r1 ; read from src
122
123 ; copy part 3
124 ; (r19 already has destination address of part 3)
125 ldo tmpdiskbuf_part3(%r6),%r20
126 addi,tr tmpdiskbuf_part3sz/4,%r0,%r2 ; loop count, skip next
127 cpipl3: stws,ma %r1,4(0,%r19) ; write to dst
128 addib,uv,n -1,%r2,cpipl3 ; check loop condition
129 ldws,ma 4(0,%r20),%r1 ; read from src
130
131 ; flush data cache / invalidate instruction cache
132 ldo top-$global$+part1sz(%r27),%r1 ; part 2 address
133 ldi 16,%r20 ; 16: cache line size
134 flipl: fdc 0(0,%r1) ; flush data cache line at r1
135 comb,< %r1,%r19,flipl
136 fic,m %r20(0,%r1) ; flush instruction cache line at r1, r1 += 16
137 sync ; I/O operation is guaranteed to finish
138 ; in eight instructions after sync
139 ;
140 ; Now, whole the IPL is loaded
141 ;
142
143 ; clear BSS
144 .import _edata,data
145 addil L%_edata-$global$,%r27;%r1
146 ldo R%_edata-$global$(%r1),%r1
147 clrbss: comb,< %r1,%r6,clrbss
148 stws,ma %r0,4(0,%r1)
149
150 ; we have read disklabel -- save it for later use
151 .import labelsector,data
152 addil L%labelsector-$global$,%r27;%r1
153 ldo R%labelsector-$global$(%r1),%r20
154 ldo tmpdiskbuf_labelsec(%r6),%r21
155 addi,tr tmpdiskbuf_labelsecsz/4,%r0,%r2 ; loop count, skip next
156 cplbl: stws,ma %r1,4(0,%r20) ; write to dst
157 addib,uv,n -1,%r2,cplbl ; check loop condition
158 ldws,ma 4(0,%r21),%r1 ; read from src
159
160 ; set stack
161 ; (r6 points at free space, 64byte aligned)
162 ; 32bit environment (and this code) requires stack is 64byte aligned.
163 ldo 64(%r6),%sp ; 64 > 48: frame marker (32) + args(up to 4)
164
165 ; stack usage
166 ; 12bytes arguments
167 ; 32 frame marker
168
169 ; parameters for main
170 copy %r3,%arg0
171 copy %r4,%arg2
172
173 .import ipl_main,entry
174 bl ipl_main,%rp
175 copy %sp,%arg1
176
177 ; main returned --- perform reset
178 bl print,%rp
179 ldo str_reset-$global$(%r27),%arg0
180 ; FALLTHROUGH
181
182 IOMOD_CMD: .equ 0xFFFC0000 + (4*12)
183 IOMOD_CMD_STOP: .equ 0
184 IOMOD_CMD_RESET: .equ 5
185
186 ; void reboot(void)
187 ; void halt(void)
188 .export reboot,entry
189 .export halt,entry
190 reboot:
191 addi,tr IOMOD_CMD_RESET,%r0,%r1 ; %r1 = IOMOD_CMD_RESET, skip next
192 halt: ldi IOMOD_CMD_STOP,%r1
193 iomcmd: ldil L%IOMOD_CMD,%r2
194 ldo R%IOMOD_CMD(%r2),%r2
195 stwas %r1,0(%r2)
196 b,n .
197
198 str_startup:
199 .string "\r\n\n"
200 .stringz "NetBSD/hppa FFS/LFS Primary Bootstrap\r\n\n"
201 str_reset:
202 .stringz "\r\nresetting..."
203 .align 4
204
205 ; void dispatch(unsigned interactive, unsigned top, unsigned end, int part,
206 ; unsigned entry)
207 .export dispatch,entry
208 dispatch:
209 ; flush data cache / invalidate instruction cache
210 ldi 16,%r20 ; 16: cache line size
211 flush: fdc 0(0,%arg1) ; flush data cache line at arg1
212 comb,< %arg1,%arg2,flush
213 fic,m %r20(0,%arg1) ; flush instruction cache line at arg1, arg1+=16
214 sync
215 copy %r0,%r1 ; I/O operation is guaranteed to finish
216 copy %r0,%r3 ; in eight instructions after sync
217 copy %r0,%r4
218 copy %r0,%r5 ; while waiting, clear unused registers
219 copy %r0,%r6 ; for future compatibility
220 copy %r0,%r7
221 copy %r0,%r8
222 copy %r0,%r9
223 copy %r0,%r10
224 copy %r0,%r11
225 copy %r0,%r12
226 copy %r0,%r13
227 copy %r0,%r14
228 copy %r0,%r15
229 copy %r0,%r16
230 copy %r0,%r17
231 copy %r0,%r18
232 copy %r0,%r19
233 copy %r0,%r20
234 copy %r0,%r21
235 copy %r0,%r22
236 copy %r0,%r28 ; r23-r26: arg3-arg0, r27: dp
237 copy %r0,%r29 ; r30: sp
238 copy %r0,%r31
239 ldw -52(%sp),%arg1 ; arg4: exec address
240 ldo reboot-$global$(%r27),%rp ; reboot if returns
241 bv %r0(%arg1) ; execute
242 ldi BOOT_IF_VERSION,%arg1
243
244 ;
245 ; IODC subroutines
246 ;
247 PZ_MEM_CONSOLE: .equ 0x3a0
248 PZ_MEM_BOOT: .equ 0x3d0
249 PZ_MEM_KEYBOARD: .equ 0x400
250
251 DEV_PATH: .equ 0x00
252 DEV_LAYERS: .equ 0x08
253 DEV_HPA: .equ 0x20 ; hard physical address space
254 DEV_SPA: .equ 0x24 ; soft physical address space
255 DEV_IODC_ENTRY: .equ 0x28
256 DEV_CLASS: .equ 0x2c
257 DEV_CL_DUPLEX: .equ 0x7 ; full-duplex console class
258
259 IODC_ENTRY_IO_BOOTIN: .equ 0
260 IODC_ENTRY_IO_CONSOLEIN: .equ 2
261 IODC_ENTRY_IO_CONSOLEOUT: .equ 3
262
263 ; call_iodc
264 ; inputs:
265 ; %ret0 IODC base in page zero
266 ; %rp return address
267 ; %r29 arg 8
268 ; %r19 arg 7
269 ; %r20 arg 6
270 ; %r21 arg 5
271 ; %r25 arg 1
272 ; outputs
273 ; all scratch regs undefined, unless defined by the IODC call
274 call_iodc:
275 ; set common arguments in registers
276 addil L%retbuf-$global$,%r27;%r1
277 ldo R%retbuf-$global$(%r1),%r22 ; arg4: return buffer
278 ldo DEV_LAYERS(%ret0),%arg3 ; arg3: layer
279 ldw DEV_SPA(%ret0),%arg2 ; arg2: spa
280 ldw DEV_HPA(%ret0),%arg0 ; arg0: hpa
281 ; check if narrow or wide mode
282 ssm 0,%r1 ; get PSW
283 bb,< %r1,4,call_iodc_64 ; if W, call in 64bit mode
284 ldw DEV_IODC_ENTRY(%ret0),%r1 ; ENTRY_IO address
285
286 ; narrow mode
287 stw %r29,-68(%sp) ; arg8: maxsize / lang
288 stw %r19,-64(%sp) ; arg7: size
289 stw %r20,-60(%sp) ; arg6: buf
290 stw %r21,-56(%sp) ; arg5: devaddr / unused
291 bv %r0(%r1) ; call ENTRY_IO
292 stw %r22,-52(%sp) ; arg4: return buffer
293
294 call_iodc_64:
295 .allow 2.0
296 ; On PA64 convention, arg0 - arg7 are passed in registers.
297 ; Parameters are placed in INCREASING order.
298 ; The argument pointer points at the first stack parameter.
299 ; stack usage:
300 ; 64bytes allocated for register arguments arg0-arg7
301 ; 8 arg8 (argument pointer points here)
302 ; 16 frame marker
303 std %r29,-16-8(%sp) ; arg8: maxsize / lang
304 ; std %sp,-8(%sp) ; psp in frame marker
305 bv %r0(%r1) ; call ENTRY_IO
306 ldo -16-8(%sp),%r29 ; argument pointer
307 .allow
308
309 ;
310 ; console output
311 ;
312 ; void putch(int)
313 ; void print(const char *string)
314 .align 4
315 .export putch,entry
316 .export print,entry
317 putch:
318 stwm %arg0,128(%sp) ; fake up a string on the stack
319 stb %r0,-124(%sp) ; (see stack usage below)
320 addi,tr -125,%sp,%arg0 ; string address, skip next
321 print:
322 .proc
323 .callinfo frame=128,save_rp,no_unwind
324 .entry
325 ldo 128(%sp),%sp
326 stw %rp,-128-20(%sp)
327
328 ; stack usage:
329 ; 36byte IODC buffer (assume %sp was 64byte aligned)
330 ; 4 saved reg
331 ; 88 arguments, frame marker
332 ; 32bit: 36 (arguments) + 32 (frame marker)
333 ; 64bit: 72 (arguments) + 16 (frame marker)
334 prbufsiz: .equ 36
335
336 ; save callee-saves
337 stw %r3,-92(%sp)
338
339 copy %arg0,%r3
340
341 prloop:
342 copy %r0,%r19
343 ldi prbufsiz,%r20
344 ldo -128(%sp),%r1
345
346 strloop:
347 ldb 0(%r3),%r2
348 comb,= %r2,%r0,endstr
349 stbs,ma %r2,1(0,%r1)
350 ldo 1(%r19),%r19
351 comb,<> %r19,%r20,strloop
352 ldo 1(%r3),%r3
353
354 endstr:
355 comb,=,n %r19,%r0,endpr
356
357 ; see IODC 3-51
358 ; arg0 hpa
359 ; arg1 option (ENTRY_IO_CONSOLEOUT (3))
360 ; arg2 spa
361 ; arg3 ID_addr (pointer to LAYER)
362 ; arg4 R_addr (pointer to return buffer (64word?))
363 ; arg5 unused (0)
364 ; arg6 memaddr (64byte-aligned) string buffer
365 ; arg7 reqsize
366 ; arg8 lang (0)
367 ldi PZ_MEM_CONSOLE,%ret0 ; IODC base in page zero
368 copy %r0,%r29 ; arg8: lang
369 ; copy %r19,%r19 ; arg7: size
370 ldo -128(%sp),%r20 ; arg6: buf
371 ; copy %r0,%r21 ; arg5: unused
372 bl call_iodc,%rp
373 ldi IODC_ENTRY_IO_CONSOLEOUT,%arg1 ; arg1: option
374 b,n prloop
375
376 endpr:
377 ; restore callee-saves
378 ldw -92(%sp),%r3
379
380 ; return subroutine
381 ldw -128-20(%sp),%rp
382 bv %r0(%rp)
383 .exit
384 ldo -128(%sp),%sp
385 .procend
386
387 ;
388 ; console input
389 ;
390 ; int getch(void)
391 .align 4
392 .export getch,entry
393 getch:
394 .proc
395 .callinfo frame=192,save_rp,no_unwind
396 .entry
397 stw %rp,-20(%sp)
398 ldo 192(%sp),%sp
399
400 ; stack usage:
401 ; 64byte IODC buffer (assume %sp was 64byte aligned)
402 ; 40 unused
403 ; 88 arguments, frame marker
404 ; 32bit: 36 (arguments) + 32 (frame marker)
405 ; 64bit: 72 (arguments) + 16 (frame marker)
406
407 ; check if console is full or half duplex
408 ldw PZ_MEM_CONSOLE+DEV_CLASS(%r0),%r1 ; device class
409 extru %r1,31,4,%r1 ; right 4bits are valid
410 ldi PZ_MEM_CONSOLE,%ret0
411 comib,=,n DEV_CL_DUPLEX,%r1,getch_console ; use CONSOLE if full
412 ldi PZ_MEM_KEYBOARD,%ret0 ; otherwise KEYBOARD
413 getch_console:
414
415 ; see IODC 3-50
416 ; arg0 hpa
417 ; arg1 option (ENTRY_IO_CONSOLEIN (2))
418 ; arg2 spa
419 ; arg3 ID_addr (pointer to LAYER)
420 ; arg4 R_addr (pointer to return buffer (64word?))
421 ; arg5 unused (0)
422 ; arg6 memaddr (64byte-aligned, must have 64byte) data buffer
423 ; arg7 reqsize
424 ; arg8 lang (0)
425 ; copy %rp,%rp ; IODC base in page zero
426 copy %r0,%r29 ; arg8: lang
427 ldi 1,%r19 ; arg7: size (1)
428 ldo -192(%sp),%r20 ; arg6: buf
429 ; copy %r0,%r21 ; arg5: unused
430 bl call_iodc,%rp
431 ldi IODC_ENTRY_IO_CONSOLEIN,%arg1 ; arg1: option
432
433 ; make return value
434 comb,<> %ret0,%r0,getch_ret ; return -1 on error
435 ldi -1,%ret0
436 ldi 1,%r19
437
438 ; check if narrow or wide mode
439 ssm 0,%r1 ; get PSW
440 bb,< %r1,4,getch_64
441 addil L%retbuf-$global$,%r27;%r1
442 ldw R%retbuf-$global$(%r1),%r2 ; ret[0]
443 comclr,<> %r19,%r2,%ret0 ; return 0 if no char available
444 getch_retc:
445 ldb -192(%sp),%ret0 ; otherwise return the char
446
447 getch_ret:
448 ; return subroutine
449 ldw -192-20(%sp),%rp
450 bv %r0(%rp)
451 .exit
452 ldo -192(%sp),%sp
453
454 getch_64:
455 .allow 2.0
456 ldd R%retbuf-$global$(%r1),%r2 ; ret[0] (64bit)
457 b getch_retc
458 cmpclr,*<> %r19,%r2,%ret0 ; return 0 if no char available
459 .allow
460 .procend
461
462 ;
463 ; read boot device
464 ;
465 ; void boot_input(void *buf, unsigned len, unsigned pos)
466 .align 4
467 .export boot_input,entry
468 boot_input:
469 .proc
470 .callinfo frame=128,save_rp,no_unwind
471 .entry
472 stw %rp,-20(%sp)
473 ldo 128(%sp),%sp
474
475 ; stack usage:
476 ; 40byte unused (alignment)
477 ; 88 arguments, frame marker
478 ; 32bit: 36 (arguments) + 32 (frame marker)
479 ; 64bit: 72 (arguments) + 16 (frame marker)
480
481 ; see IODC 3-46
482 ; arg0 hpa
483 ; arg1 option (ENTRY_IO_BOOTIN (0))
484 ; arg2 spa
485 ; arg3 ID_addr (pointer to LAYER)
486 ; arg4 R_addr (pointer to return buffer (64word?))
487 ; arg5 devaddr
488 ; arg6 memaddr (64byte-aligned) string buffer
489 ; arg7 reqsize
490 ; arg8 maxsize
491 ldi PZ_MEM_BOOT,%ret0 ; IODC base in page zero
492 copy %arg1,%r29 ; arg8: maxsize
493 copy %arg1,%r19 ; arg7: size
494 copy %arg0,%r20 ; arg6: buf
495 copy %arg2,%r21 ; arg5: devaddr
496 bl call_iodc,%rp
497 ldi IODC_ENTRY_IO_BOOTIN,%arg1 ; arg1: option
498
499 ; return subroutine
500 ldw -128-20(%sp),%rp
501 bv %r0(%rp)
502 .exit
503 ldo -128(%sp),%sp
504 .procend
505
506 ;
507 ; utilities
508 ; optimized for size
509 ;
510
511 ; int strcmp(const char *str1, const char *str2)
512 .align 4
513 .export strcmp,entry
514 strcmp:
515 .proc
516 .callinfo frame=0,no_calls
517 .entry
518 ldbs,ma 1(0,%arg0),%r1
519 strcmp_loop:
520 comb,= %r1,%r0,strcmp_eos
521 ldbs,ma 1(0,%arg1),%r19
522 comb,=,n %r1,%r19,strcmp_loop
523 ldbs,ma 1(0,%arg0),%r1
524 strcmp_eos:
525 bv %r0(%rp)
526 .exit
527 sub %r1,%r19,%ret0
528 .procend
529
530 ; void memcpy(void *dst, const void *src, unsigned len)
531 .align 4
532 .export memcpy,entry
533 .export memmove,entry
534 memcpy:
535 memmove:
536 .proc
537 .callinfo no_unwind ; multiple exit points
538 .entry
539 ; copy %arg0,%ret0 ; uncomment this to conform ANSI
540 comb,<<,n %arg0,%arg1,memcpy0 ; copy forward or backward?
541 add %arg0,%arg2,%arg0 ; dst end address
542 add,tr %arg1,%arg2,%arg1 ; src end address, skip next
543 memcpy_bwd:
544 stbs,mb %r1,-1(0,%arg0) ; write to dst
545 addib,uv,n -1,%arg2,memcpy_bwd ; check loop condition
546 ldbs,mb -1(0,%arg1),%r1 ; read from src
547 bv,n %r0(%rp) ; return subroutine
548 memcpy_fwd:
549 stbs,ma %r1,1(0,%arg0) ; write to dst
550 memcpy0:
551 addib,uv,n -1,%arg2,memcpy_fwd ; check loop condition
552 ldbs,ma 1(0,%arg1),%r1 ; read from src
553 .exit
554 bv,n %r0(%rp) ; return subroutine
555 .procend
556
557 ;
558 ; string table
559 ; placed here to save space
560 ;
561 .export str_seekseq, data
562 .export str_startup, data
563 .export str_bit_firmware, data
564 .export str_crlf, data
565 .export str_space, data
566 .export str_rubout, data
567 str_seekseq:
568 .stringz "repositioning media...\r\n"
569 str_bit_firmware:
570 .stringz "bit firmware\r\n"
571 str_rubout:
572 .byte 0x08, 0x20, 0x08, 0x00 ; "\b \b"
573
574 .export str_bootpart, data
575 str_bootpart:
576 .string "boot partition (a-p, ! to reboot) [a]:"
577 str_space:
578 .stringz " "
579 .export str_booting_part, data
580 str_booting_part:
581 .string "\r\nbooting from partition _"
582 str_crlf:
583 .stringz "\r\n"
584 .export str_warn_2GB, data
585 str_warn_2GB:
586 .stringz "boot partition exceeds 2GB boundary\r\n"
587 .export str_warn_unused, data
588 str_warn_unused:
589 .stringz "unused partition\r\n"
590 .export str_nolabel, data
591 str_nolabel:
592 .stringz "no disklabel\r\n"
593
594 .export str_filesystem, data
595 str_filesystem:
596 .stringz "filesystem: _FS\r\n"
597 .export str_nofs, data
598 str_nofs:
599 .stringz "no filesystem found\r\n"
600 .export str_lookup, data
601 .export str_loading, data
602 .export str_at, data
603 .export str_dddot, data
604 .export str_done, data
605 str_lookup:
606 .stringz "looking up "
607 str_loading:
608 .stringz "loading "
609 str_at:
610 .stringz " at 0x"
611 str_dddot:
612 .stringz "..."
613 str_done:
614 .stringz "done\r\n"
615
616 .export str_boot1, data
617 .export str_boot2, data
618 .export str_boot3, data
619 str_boot1:
620 .stringz "boot.hp700"
621 str_boot2:
622 .stringz "boot"
623 str_boot3:
624 .stringz "usr/mdec/boot"
625
626 .export str_noboot, data
627 str_noboot:
628 .stringz "no secondary boot found\r\n"
629
630 .export str_ukfmt, data
631 str_ukfmt:
632 .stringz ": unknown format -- exec from top\r\n"
633
634 .bss
635 .align 64
636 retbuf: .block 32*8 ; *4 for narrow mode / *8 for wide mode
637
638 .export diskbuf,data
639 .align 64
640 diskbuf:
641 .block 2048
642