blob: acf5533b3f4eced7fef8b7b88f4dc99e935c4439 [file] [log] [blame]
oliverschmidt3cf3d302004-06-08 20:28:33 +00001;
oliverschmidt76872e82004-12-26 14:13:34 +00002; Startup code for Contiki (Apple2 version)
oliverschmidt3cf3d302004-06-08 20:28:33 +00003;
oliverschmidt76872e82004-12-26 14:13:34 +00004; This must be the *first* file on the linker command line
5;
oliverschmidt3cf3d302004-06-08 20:28:33 +00006
oliverschmidt46ea6732005-01-07 09:50:52 +00007 .export _exit
oliverschmidtd86377a2005-03-09 00:51:51 +00008 .import zerobss, initlib, callmain, donelib
oliverschmidte769f0a2006-04-09 16:42:17 +00009.ifdef __APPLE2ENH__
oliverschmidt027febe2006-05-17 15:55:29 +000010 .import _uip_buf, callirq
oliverschmidte769f0a2006-04-09 16:42:17 +000011.endif
oliverschmidt027febe2006-05-17 15:55:29 +000012 .import __STARTUP_RUN__ ; Linker generated
oliverschmidte769f0a2006-04-09 16:42:17 +000013 .import __BSS_RUN__, __BSS_SIZE__ ; Linker generated
14 .import __INIT_RUN__, __INIT_SIZE__ ; Linker generated
15 .import __CODE_RUN__, __CODE_SIZE__ ; Linker generated
oliverschmidt027febe2006-05-17 15:55:29 +000016 .import __BOOT_SIZE__, __UIP_SIZE__ ; Linker generated
oliverschmidt76872e82004-12-26 14:13:34 +000017 .importzp sp
oliverschmidt97e39572005-03-29 23:10:40 +000018 .linecont +
oliverschmidt3cf3d302004-06-08 20:28:33 +000019
oliverschmidt76872e82004-12-26 14:13:34 +000020; ------------------------------------------------------------------------
21; The executable header
oliverschmidt3cf3d302004-06-08 20:28:33 +000022
oliverschmidt76872e82004-12-26 14:13:34 +000023.segment "EXEHDR"
oliverschmidt3cf3d302004-06-08 20:28:33 +000024
oliverschmidte769f0a2006-04-09 16:42:17 +000025 .word __STARTUP_RUN__ ; Start address
26 .word __BSS_RUN__ + __BOOT_SIZE__ + \
oliverschmidt027febe2006-05-17 15:55:29 +000027 __INIT_SIZE__ + __CODE_SIZE__ + \
28 __UIP_SIZE__ - __STARTUP_RUN__ ; Size
oliverschmidt3cf3d302004-06-08 20:28:33 +000029
oliverschmidt76872e82004-12-26 14:13:34 +000030; ------------------------------------------------------------------------
oliverschmidt33d8fad2006-05-18 16:20:08 +000031; Place the startup code in a special segment
oliverschmidt3cf3d302004-06-08 20:28:33 +000032
oliverschmidt76872e82004-12-26 14:13:34 +000033.segment "STARTUP"
oliverschmidt19032c62004-06-14 22:30:32 +000034
oliverschmidtd86377a2005-03-09 00:51:51 +000035; Forward control to the code in the "BOOT" segment
oliverschmidt19032c62004-06-14 22:30:32 +000036
oliverschmidtd86377a2005-03-09 00:51:51 +000037 jmp __BSS_RUN__
oliverschmidt67fa2ac2005-02-08 00:32:10 +000038
oliverschmidte769f0a2006-04-09 16:42:17 +000039.ifdef __APPLE2ENH__
40
41; ProDOS TechRefMan, chapter 6.2:
42; "Each installed routine must begin with a CLD instruction."
43
oliverschmidt027febe2006-05-17 15:55:29 +000044irq: cld
oliverschmidte769f0a2006-04-09 16:42:17 +000045
46; Switch in LC bank 2 for R/O
47
48 bit $C080
49
50; Call interruptors
51
52 jsr callirq
53
54; Switch in LC bank 1 for R/W
55
56 bit $C08B
57 bit $C08B
58
59; Check for success
60
61 bcc :+
62
63; ProDOS TechRefMan, chapter 6.2:
64; "When the routine that can process the interrupt is called, it
65; should ... return (via an RTS) with the carry flag clear."
66
67 clc
68 rts
69
70; ProDOS TechRefMan, chapter 6.2:
71; "When a routine that cannot process the interrupt is called,
72; it should return (via an RTS) with the cary flag set ..."
73
74: sec
75 rts
76
77.endif
78
oliverschmidt67fa2ac2005-02-08 00:32:10 +000079; Avoid re-entrance of donelib. This is also the _exit entry
80
81_exit: ldx #$02
82: lda rvsave,x
83 sta $03F2,x
84 dex
85 bpl :-
86
87; Switch in LC bank 2 for R/O
88
89 bit $C080
90
91; Call module destructors
92
93 jsr donelib
94
oliverschmidte769f0a2006-04-09 16:42:17 +000095.ifdef __APPLE2ENH__
oliverschmidt01e5b372006-05-24 19:41:20 +000096
97; Switch in $2000-$3FFF from aux memory
98
99 lda $C018 ; 80Store ?
oliverschmidt2b9fbcd2006-06-28 20:15:34 +0000100 pha
oliverschmidt01e5b372006-05-24 19:41:20 +0000101 sta $C001 ; 80Store On
102
103 bit $C055 ; Page2
104 bit $C057 ; HiRes
105
106; Call the cleanup code in the "UIP" segment
107
108 jsr cleanup
109
110; Switch in $2000-$3FFF from main memory
111
112 bit $C056 ; LoRes
113 bit $C054 ; Page1
114
oliverschmidt2b9fbcd2006-06-28 20:15:34 +0000115 pla
oliverschmidt01e5b372006-05-24 19:41:20 +0000116 bmi :+
117 sta $C000 ; 80Store Off
118
119.endif
120
121; Switch in ROM
122
123: bit $C082
124
125; Back to DOS
126
127 jmp $03D0
128
129.ifdef __APPLE2ENH__
130; ------------------------------------------------------------------------
131; There's space left in the "UIP" segment so we move all cleanup code here
132
133.segment "UIP"
134
135.proc cleanup
oliverschmidte769f0a2006-04-09 16:42:17 +0000136
137; Deallocate interrupt vector table entry
138
oliverschmidt027febe2006-05-17 15:55:29 +0000139 dec intrpt ; Adjust parameter count
oliverschmidte769f0a2006-04-09 16:42:17 +0000140 jsr $BF00
141 .byte $41 ; Dealloc interrupt
oliverschmidt027febe2006-05-17 15:55:29 +0000142 .addr intrpt
oliverschmidte769f0a2006-04-09 16:42:17 +0000143
oliverschmidt01e5b372006-05-24 19:41:20 +0000144; Save last used device number
145
146 lda $BF30 ; DEVNUM
147 sta devnum
148
149; Read ProDOS dispatcher from /RAM
150
151 jsr $BF00
152 .byte $C8 ; Open file
153 .addr open
154
155 lda o_ref
156 sta r_ref
157 sta c_ref
158
159 jsr $BF00
160 .byte $CA ; Read file
161 .addr read
162
163 jsr $BF00
164 .byte $CC ; Close file
165 .addr close
166
167; Destroy /RAM files
168
169 jsr $BF00
170 .byte $C1 ; Destroy file
171 .addr destr
172
173 dec n_ext ; CONTIKI.2 -> CONTIKI.1
174
175 jsr $BF00
176 .byte $C1 ; Destroy file
177 .addr destr
178
179; Restore last used device number
180
181 lda devnum
182 sta $BF30 ; DEVNUM
183
184; Switch in LC bank 2 for W/O
185
186 bit $C081
187 bit $C081
188
189; Set source start
190
191 lda #<__BSS_RUN__
192 ldx #>__BSS_RUN__
193 sta $3C
194 stx $3D
195
196; Set source end
197
198 lda #<(__BSS_RUN__ + $0300)
199 ldx #>(__BSS_RUN__ + $0300)
200 sta $3E
201 stx $3F
202
203; Set destination
204
205 lda #<$D100
206 ldx #>$D100
207 sta $42
208 stx $43
209
210; Reset index and call MOVE to copy ProDOS dispatcher into LC
211
212 ldy #$00
213 jmp $FE2C
214
215open: .byte $03 ; Parameter count
216 .addr name ; Pathname
217 .addr _uip_buf ; IO buffer
218o_ref: .byte $00 ; Reference number
219
220read: .byte $04 ; Parameter count
221r_ref: .byte $00 ; Reference number
222 .addr __BSS_RUN__ ; Data buffer
223 .word $0300 ; Requested count
224 .word $0000 ; Transfered count
225
226close: .byte $01 ; Parameter count
227c_ref: .byte $00 ; Reference number
228
229destr: .byte $01 ; Parameter count
230 .addr name ; Pathname
231
232name: .byte .strlen("/RAM/CONTIKI.2")
233 .byte "/RAM/CONTIKI."
234n_ext: .byte '2'
235
236devnum: .res 1
237
238.endproc
oliverschmidte769f0a2006-04-09 16:42:17 +0000239.endif
240
oliverschmidt67fa2ac2005-02-08 00:32:10 +0000241; ------------------------------------------------------------------------
oliverschmidt027febe2006-05-17 15:55:29 +0000242; The linker doesn't understand that the "BOOT" segment overlays the "BSS"
243; segment so the automatic fixup of references to the "BOOT" segment does
244; not work. Therefore references to this segment have to be expressed as
245; offsets to __BSS_RUN__.
oliverschmidt67fa2ac2005-02-08 00:32:10 +0000246
oliverschmidtd86377a2005-03-09 00:51:51 +0000247.segment "BOOT"
248
oliverschmidt01e5b372006-05-24 19:41:20 +0000249.ifdef __APPLE2ENH__
250
251; Save potential command line arguments from being overwritten by
252; a slot-based realtime clock being called by ProDOS on file I/O
253
254 ldx #$7F
255: lda $0200,x
256 sta $0100,x
257 dex
258 bpl :-
259
260; ProDOS TechRefMan, chapter 5.2.2.1:
261; "... you may protect those areas of auxiliary memory. If you save a
262; dummy 8K file as the first entry in /RAM, it will always be saved
263; at $2000 to $3FFF."
264;
265; Read /RAM directory
266
267 jsr $BF00
268 .byte $C8 ; Open file
269 .addr open
270
271 lda o_ref
272 sta r_ref
273 sta c_ref
274
275 jsr $BF00
276 .byte $CA ; Read file
277 .addr read
278
279 jsr $BF00
280 .byte $CC ; Close file
281 .addr close
282
283; ProDOS TechRefMan, chapter B.2.5:
284; "FileCount := ThisBlock[$25] + (256 * ThisBlock[$26]);"
285;
286; Make sure /RAM is empty
287
288 lda END + $25
289 ora END + $26
290 beq :++
291
292 ldx #.strlen("Fatal error: /RAM not empty !")
293: lda error,x
294 jsr $FDED ; COUT
295 dex
296 bpl :-
297
298 jsr $FD0C ; RDKEY
299 jmp $03D0 ; DOSWARM
300
301; Switch to 80 column mode here to show some progress
302
303: lda #$0D
304 jsr $C300
305
306; Relocate the "UIP" segment by writing it to /RAM as the first file
307
308 lda #.strlen("/RAM/CONTIKI.1")
309 sta name
310 jsr ramfile
311
312; Switch in LC bank 2 for R/O
313
314 bit $C080
315
316; Copy ProDOS dispatcher out of LC
317
318 ldx #$00
319l_mod = __BSS_RUN__ + *
320: lda $D100,x
321s_mod = __BSS_RUN__ + *
322 sta UIP,x
323 inx
324 bne :-
325 inc l_mod+2
326 inc s_mod+2
327 lda l_mod+2
328 cmp #>$D400
329 bne :-
330
331; Write ProDOS dispatcher to /RAM
332
333 lda #>$0300
334 sta w_cnt+1
335 inc n_ext ; CONTIKI.1 -> CONTIKI.2
336 jsr ramfile
337
338; Restore potential command line arguments
339
340 ldx #$7F
341: lda $0100,x
342 sta $0200,x
343 dex
344 bpl :-
345
346; Allocate interrupt vector table entry
347
348 jsr $BF00
349 .byte $40 ; Alloc interrupt
350 .addr intrpt
351
352.endif
353
oliverschmidt67fa2ac2005-02-08 00:32:10 +0000354; Setup the stack at HIMEM
355
356 lda $73
357 ldx $73+1
358 sta sp
oliverschmidte769f0a2006-04-09 16:42:17 +0000359 stx sp+1
oliverschmidt67fa2ac2005-02-08 00:32:10 +0000360
oliverschmidt76872e82004-12-26 14:13:34 +0000361; Save the original RESET vector
oliverschmidt3cf3d302004-06-08 20:28:33 +0000362
oliverschmidt76872e82004-12-26 14:13:34 +0000363 ldx #$02
364: lda $03F2,x
365 sta rvsave,x
366 dex
367 bpl :-
oliverschmidt3cf3d302004-06-08 20:28:33 +0000368
oliverschmidt76872e82004-12-26 14:13:34 +0000369; ProDOS TechRefMan, chapter 5.3.5:
370; "Your system program should place in the RESET vector the address of a
371; routine that ... closes the files."
oliverschmidt3cf3d302004-06-08 20:28:33 +0000372
oliverschmidt76872e82004-12-26 14:13:34 +0000373 lda #<_exit
374 sta $03F2
375 lda #>_exit
376 sta $03F3
377 eor #$A5
378 sta $03F4
379
oliverschmidta330e332005-01-22 03:00:27 +0000380; Switch in LC bank 2 for W/O
oliverschmidt3cf3d302004-06-08 20:28:33 +0000381
oliverschmidta330e332005-01-22 03:00:27 +0000382 bit $C081
383 bit $C081
oliverschmidt76872e82004-12-26 14:13:34 +0000384
oliverschmidta330e332005-01-22 03:00:27 +0000385; Set source start
386
oliverschmidtd86377a2005-03-09 00:51:51 +0000387 lda #<(__BSS_RUN__ + __BOOT_SIZE__ + __INIT_SIZE__)
388 ldx #>(__BSS_RUN__ + __BOOT_SIZE__ + __INIT_SIZE__)
oliverschmidta330e332005-01-22 03:00:27 +0000389 sta $3C
390 stx $3D
391
392; Set source end
393
oliverschmidtd86377a2005-03-09 00:51:51 +0000394 lda #<(__BSS_RUN__ + __BOOT_SIZE__ + __INIT_SIZE__ + __CODE_SIZE__)
395 ldx #>(__BSS_RUN__ + __BOOT_SIZE__ + __INIT_SIZE__ + __CODE_SIZE__)
oliverschmidta330e332005-01-22 03:00:27 +0000396 sta $3E
397 stx $3F
398
399; Set destination
400
401 lda #<__CODE_RUN__
402 ldx #>__CODE_RUN__
403 sta $42
404 stx $43
405
oliverschmidtd86377a2005-03-09 00:51:51 +0000406; Reset index and call MOVE to relocate the "CODE" segment
oliverschmidta330e332005-01-22 03:00:27 +0000407
408 ldy #$00
409 jsr $FE2C
410
oliverschmidt67fa2ac2005-02-08 00:32:10 +0000411; Set source start
oliverschmidta330e332005-01-22 03:00:27 +0000412
oliverschmidtd86377a2005-03-09 00:51:51 +0000413 lda #<(__BSS_RUN__ + __BOOT_SIZE__)
414 ldx #>(__BSS_RUN__ + __BOOT_SIZE__)
oliverschmidt67fa2ac2005-02-08 00:32:10 +0000415 sta $3C
416 stx $3D
oliverschmidta330e332005-01-22 03:00:27 +0000417
oliverschmidt67fa2ac2005-02-08 00:32:10 +0000418; Set source end
oliverschmidt76872e82004-12-26 14:13:34 +0000419
oliverschmidtd86377a2005-03-09 00:51:51 +0000420 lda #<(__BSS_RUN__ + __BOOT_SIZE__ + __INIT_SIZE__)
421 ldx #>(__BSS_RUN__ + __BOOT_SIZE__ + __INIT_SIZE__)
oliverschmidt67fa2ac2005-02-08 00:32:10 +0000422 sta $3E
423 stx $3F
oliverschmidt3cf3d302004-06-08 20:28:33 +0000424
oliverschmidt67fa2ac2005-02-08 00:32:10 +0000425; Set destination
oliverschmidt76872e82004-12-26 14:13:34 +0000426
oliverschmidtd86377a2005-03-09 00:51:51 +0000427 lda #<__INIT_RUN__
428 ldx #>__INIT_RUN__
oliverschmidt67fa2ac2005-02-08 00:32:10 +0000429 sta $42
430 stx $43
oliverschmidt76872e82004-12-26 14:13:34 +0000431
oliverschmidtd86377a2005-03-09 00:51:51 +0000432; Reset index and call MOVE to relocate the "INIT" segment
oliverschmidt76872e82004-12-26 14:13:34 +0000433
oliverschmidt67fa2ac2005-02-08 00:32:10 +0000434 ldy #$00
oliverschmidtd86377a2005-03-09 00:51:51 +0000435 jsr $FE2C
436
437; Switch in LC bank 2 for R/O
438
439 bit $C080
440
441; Forward control to code in the "INIT" segment
442
443 jmp init
oliverschmidt027febe2006-05-17 15:55:29 +0000444
445.ifdef __APPLE2ENH__
446
oliverschmidt01e5b372006-05-24 19:41:20 +0000447; Create a temporary file in /RAM
448
449ramfile = __BSS_RUN__ + *
450 jsr $BF00
451 .byte $C0 ; Create file
452 .addr create
453
454 jsr $BF00
455 .byte $C8 ; Open file
456 .addr open
457
458 lda o_ref
459 sta w_ref
460 sta c_ref
461
462 jsr $BF00
463 .byte $CB ; Write file
464 .addr write
465
466 jsr $BF00
467 .byte $CC ; Close file
468 .addr close
469
470 rts
471
472UIP = __BSS_RUN__ + __BOOT_SIZE__ + __INIT_SIZE__ + __CODE_SIZE__
473END = __BSS_RUN__ + __BOOT_SIZE__ + __INIT_SIZE__ + __CODE_SIZE__ + __UIP_SIZE__
474
oliverschmidt027febe2006-05-17 15:55:29 +0000475create = __BSS_RUN__ + *
476 .byte $07 ; Parameter count
477 .addr name ; Pathname
478 .byte %11000011 ; Access: Standard full access
479 .byte $00 ; File type: Typeless file
480 .word $0000 ; Aux type: N/A
481 .byte $01 ; Storage type: Standard seedling file
482 .word $0000 ; Create date: Current date
483 .word $0000 ; Create time: Current time
484
485open = __BSS_RUN__ + *
486 .byte $03 ; Parameter count
487 .addr name ; Pathname
488 .addr _uip_buf ; IO buffer
489o_ref = __BSS_RUN__ + *
490 .byte $00 ; Reference number
491
oliverschmidt01e5b372006-05-24 19:41:20 +0000492read = __BSS_RUN__ + *
493 .byte $04 ; Parameter count
494r_ref = __BSS_RUN__ + *
495 .byte $00 ; Reference number
496 .addr END ; Data buffer
497 .word $0200 ; Requested count
498 .word $0000 ; Transfered count
499
oliverschmidt027febe2006-05-17 15:55:29 +0000500write = __BSS_RUN__ + *
501 .byte $04 ; Parameter count
502w_ref = __BSS_RUN__ + *
503 .byte $00 ; Reference number
oliverschmidt01e5b372006-05-24 19:41:20 +0000504 .addr UIP ; Data buffer
505w_cnt = __BSS_RUN__ + *
506 .word $2000 ; Requested count
oliverschmidt027febe2006-05-17 15:55:29 +0000507 .word $0000 ; Transfered count
508
509close = __BSS_RUN__ + *
510 .byte $01 ; Parameter count
511c_ref = __BSS_RUN__ + *
512 .byte $00 ; Reference number
513
514name = __BSS_RUN__ + *
oliverschmidt01e5b372006-05-24 19:41:20 +0000515 .byte .strlen("/RAM")
516 .byte "/RAM/CONTIKI."
517n_ext = __BSS_RUN__ + *
518 .byte '1'
519
520error = __BSS_RUN__ + *
521 .byte $8D, '!'|$80, ' '|$80, 'y'|$80, 't'|$80, 'p'|$80
522 .byte 'm'|$80, 'e'|$80, ' '|$80, 't'|$80, 'o'|$80, 'n'|$80
523 .byte ' '|$80, 'M'|$80, 'A'|$80, 'R'|$80, '\'|$80, ' '|$80
524 .byte ':'|$80, 'r'|$80, 'o'|$80, 'r'|$80, 'r'|$80, 'e'|$80
525 .byte ' '|$80, 'l'|$80, 'a'|$80, 't'|$80, 'a'|$80, 'F'|$80
oliverschmidt027febe2006-05-17 15:55:29 +0000526
527.endif
oliverschmidtd86377a2005-03-09 00:51:51 +0000528
529; ------------------------------------------------------------------------
530; The "INIT" segment will be overwritten by the heap
531
532.segment "INIT"
533
534; Clear the BSS data (and thus overwrite the "BOOT" segment)
535
536init: jsr zerobss
537
538; Call module constructors
539
540 jsr initlib
541
542; Push arguments and call main()
543
544 jmp callmain
oliverschmidt3cf3d302004-06-08 20:28:33 +0000545
oliverschmidt76872e82004-12-26 14:13:34 +0000546; ------------------------------------------------------------------------
547; Data
oliverschmidt3cf3d302004-06-08 20:28:33 +0000548
oliverschmidt76872e82004-12-26 14:13:34 +0000549.data
oliverschmidt3cf3d302004-06-08 20:28:33 +0000550
oliverschmidt76872e82004-12-26 14:13:34 +0000551rvsave: .res 3
oliverschmidte769f0a2006-04-09 16:42:17 +0000552
553.ifdef __APPLE2ENH__
554
oliverschmidt027febe2006-05-17 15:55:29 +0000555intrpt: .byte $02 ; Parameter count
oliverschmidte769f0a2006-04-09 16:42:17 +0000556 .byte $00 ; Interrupt number
oliverschmidt027febe2006-05-17 15:55:29 +0000557 .addr irq ; Interrupt handler
oliverschmidte769f0a2006-04-09 16:42:17 +0000558
559.endif