|
|
1.1.1.4 root 1: ; Cartridge assembler code.
1.1.1.3 root 2: ; 68000 code that is used for starting programs from the emulated GEMDOS harddisk
1.1.1.4 root 3: ; and for using bigger VDI resolutions
1.1.1.3 root 4:
1.1.1.4 root 5: ; Hatari's "illegal" (free) opcodes:
6: GEMDOS_OPCODE equ 8
7: SYSINIT_OPCODE equ 10
8: VDI_OPCODE equ 12
1.1.1.3 root 9:
1.1.1.4 root 10: ; System variables:
11: _longframe equ $059E
1.1 root 12:
13:
1.1.1.4 root 14: org $fa0000
1.1.1.3 root 15:
1.1 root 16:
1.1.1.4 root 17: ; This is the cartridge header:
18: dc.l $ABCDEF42 ; C-FLAG (magic value)
19: dc.l $00000000 ; C-NEXT
20: dc.l sys_init+$08000000 ; C-INIT - flag has bit 3 set = before disk boot, but after GEMDOS init
21: dc.l infoprgstart ; C-RUN
22: dc.w %0101100000000000 ; C-TIME
23: dc.w %0011001000101001 ; C-DATE
24: dc.l infoprgend-infoprgstart ; C-BSIZ, offset: $14
25: dc.b 'HATARI.TOS',0,0 ; C-NAME
26:
27: .even
28:
29:
30: old_gemdos: ds.l 1 ; has to match the CART_OLDGEMDOS define!
31: vdi_opcode: dc.w VDI_OPCODE ; Address to call after Trap #2 (VDI), causes illegal instruction
32:
33: ; New GemDOS vector (0x84) - for intercepting Pexec
1.1.1.3 root 34: new_gemdos:
1.1 root 35: dc.w GEMDOS_OPCODE ; Returns NEG as run old vector, ZERO to return or OVERFLOW to run pexec
1.1.1.3 root 36: bvs.s pexec
37: bne.s go_oldgemdos
1.1 root 38: rte
39:
1.1.1.4 root 40: ; Branch to old GemDOS
1.1.1.3 root 41: go_oldgemdos:
1.1.1.4 root 42: move.l old_gemdos(pc),-(sp) ; Set PC to 'old_gemdos' and continue execution, WITHOUT corrupting registers!
1.1.1.3 root 43: rts
1.1 root 44:
1.1.1.4 root 45: ; Progam Execute
1.1.1.3 root 46: pexec:
1.1.1.4 root 47:
48: move usp,a0 ; Parameters on user stack pointer?
49: btst #5,(sp) ; Check if program was in user or supervisor mode
50: beq.s p_ok
51: lea 6(sp),a0 ; Parameters are on SSP
52: tst.w _longframe.w ; Do we use a CPU > 68000?
53: beq.s p_ok ; No: A0 is OK
54: addq #2,a0 ; Skip 2 additional stack frame bytes on CPUs >= 68010
55: p_ok:
56: addq #2,a0 ; Skip GEMDOS function number
1.1.1.3 root 57: tst (a0) ; Test pexec mode
1.1 root 58: bne.s no_0
1.1.1.3 root 59:
60: ; Simulate pexec mode 0
1.1 root 61: move.l a6,-(sp)
62: move.l a0,a6
1.1.1.3 root 63: bsr.s find_prog
1.1.1.7 ! root 64: bsr pexec5
! 65: bsr load_n_reloc
1.1 root 66: clr.l 2(a6)
67: clr.l 10(a6)
68: move.l d0,6(a6)
1.1.1.3 root 69:
70: move.w #48,-(sp) ; Sversion: get GEMDOS version
1.1.1.7 ! root 71: trap #1 ; call GEMDOS
1.1.1.3 root 72: addq #2,sp
73: ror.w #8,d0 ; Major version to high, minor version to low byte
74: cmp.w #$0015,d0
75: bge.s use_gemdos_015
76: move.w #4,(a6) ; pexec mode 4 for exec. prepared program
77: bra.s mode0_ok
78: use_gemdos_015:
79: move.w #6,(a6) ; On GEMDOS 0.15 and higher, we can use mode 6
80: mode0_ok:
81:
1.1 root 82: move.l (sp)+,a6
1.1.1.3 root 83: bra.s go_oldgemdos
84:
1.1 root 85: no_0:
86: cmp #3,(a0)
87: bne.s go_oldgemdos
1.1.1.3 root 88:
89: ; Simulate pexec mode 3
1.1 root 90: move.l a6,-(sp)
91: move.l a0,a6
1.1.1.3 root 92: bsr.s find_prog
93: bsr.s pexec5
1.1.1.7 ! root 94: bsr.s load_n_reloc
1.1 root 95: gohome:
96: move.l (sp)+,a6
97: rte
1.1.1.3 root 98:
1.1 root 99: find_prog:
1.1.1.3 root 100: move #$2f,-(sp) ; Fgetdta
1.1.1.2 root 101: trap #1 ; Gemdos
1.1 root 102: addq #2,sp
103: move.l d0,a0
104: move.l (a0)+,-(sp)
105: move.l (a0)+,-(sp)
106: move.l (a0)+,-(sp)
107: move.l (a0)+,-(sp)
108: move.l (a0)+,-(sp)
109: move.l (a0)+,-(sp)
110: move.l (a0)+,-(sp)
111: move.l (a0)+,-(sp)
112: move.l (a0)+,-(sp)
113: move.l (a0)+,-(sp)
114: move.l (a0)+,-(sp)
115: move.l a0,-(sp)
116: move #$17,-(sp)
117: move.l 2(a6),-(sp)
1.1.1.3 root 118: move #$4e,-(sp) ; Fsfirst
1.1.1.2 root 119: trap #1 ; Gemdos
1.1 root 120: addq #8,sp
121: move.l (sp)+,a0
122: move.l (sp)+,-(a0)
123: move.l (sp)+,-(a0)
124: move.l (sp)+,-(a0)
125: move.l (sp)+,-(a0)
126: move.l (sp)+,-(a0)
127: move.l (sp)+,-(a0)
128: move.l (sp)+,-(a0)
129: move.l (sp)+,-(a0)
130: move.l (sp)+,-(a0)
131: move.l (sp)+,-(a0)
132: move.l (sp)+,-(a0)
133: tst.l d0
134: beq.s findprog_ok
135: addq #4,sp
136: bra.s gohome
137: findprog_ok:
138: rts
1.1.1.3 root 139:
1.1 root 140: pexec5:
141: move.l 10(a6),-(sp)
142: move.l 6(a6),-(sp)
143: clr.l -(sp)
1.1.1.7 ! root 144: move #5,-(sp) ; Create basepage
1.1.1.3 root 145: move #$4b,-(sp) ; Pexec
1.1.1.2 root 146: trap #1 ; Gemdos
1.1 root 147: lea 16(sp),sp
148: tst.l d0
149: bmi.s pexecerr
150: rts
151: pexecerr:
152: addq #4,sp
153: bra.s gohome
1.1.1.3 root 154:
1.1.1.7 ! root 155:
! 156: load_n_reloc:
1.1 root 157: movem.l a3-a5/d6-d7,-(sp)
1.1.1.7 ! root 158: move.l d0,a5 ; Basepage in a5
1.1.1.6 root 159: clr -(sp)
1.1 root 160: move.l 2(a6),-(sp)
1.1.1.3 root 161: move #$3d,-(sp) ; Fopen
1.1.1.2 root 162: trap #1 ; Gemdos
1.1 root 163: addq #8,sp
1.1.1.7 ! root 164: move.l d0,d6 ; Keep file handle in d6
1.1.1.6 root 165:
1.1.1.7 ! root 166: pea 256(a5)
1.1.1.6 root 167: pea $1c.w
1.1 root 168: move d6,-(sp)
1.1.1.3 root 169: move #$3f,-(sp) ; Fread
1.1.1.2 root 170: trap #1 ; Gemdos
1.1.1.6 root 171: lea 12(sp),sp
172:
1.1.1.7 ! root 173: cmp.l #$1c,d0
! 174: bne hdr_not_ok
! 175:
! 176: lea 256(a5),a3 ; a3 points now to the program header
! 177: cmp.w #$601a,(a3) ; Check program header magic
! 178: bne hdr_not_ok
! 179:
! 180: lea 8(a5),a4
! 181: move.l a5,d0
! 182: add.l #$100,d0
! 183: move.l d0,(a4)+ ; text start
! 184: move.l 2(a3),d0
! 185: move.l d0,(a4)+ ; text length
! 186: add.l 8(a5),d0
! 187: move.l d0,(a4)+ ; data start
! 188: move.l 6(a3),(a4)+ ; data length
! 189: add.l 6(a3),d0
! 190: move.l d0,(a4)+ ; bss start
! 191: move.l 10(a3),(a4)+ ; bss length
! 192:
! 193: add.l 10(a3),d0
! 194: cmp.l 4(a5),d0 ; is the TPA big enough?
! 195: bhi hdr_not_ok
! 196:
! 197: move.l a5,d0
! 198: add.l #$80,d0
! 199: move.l d0,32(a5) ; default DTA always points to cmd line space!
! 200:
! 201: move.l 24(a5),a4
! 202: add.l 14(a3),a4 ; add symtab length => a4 points to reloc table
! 203: move.w 26(a3),d7 ; d7 is now the absflag (0 means reloc)
! 204:
! 205: pea 256(a5)
! 206: pea $7fffffff
1.1 root 207: move d6,-(sp)
1.1.1.3 root 208: move #$3f,-(sp) ; Fread
1.1.1.2 root 209: trap #1 ; Gemdos
1.1.1.7 ! root 210: lea 12(sp),sp
! 211:
1.1 root 212: move d6,-(sp)
1.1.1.3 root 213: move #$3e,-(sp) ; Fclose
1.1.1.2 root 214: trap #1 ; Gemdos
1.1 root 215: addq #4,sp
1.1.1.7 ! root 216:
1.1 root 217: move.l 8(a5),a3
218: move.l a3,d0
1.1.1.7 ! root 219: tst.w d7 ; check absflag
1.1 root 220: bne.s relocdone
1.1.1.2 root 221:
1.1.1.3 root 222: ; Get first offset of the relocation table. Since A4 seems sometimes not
223: ; to be word aligned (if symbol table length is uneven), we have to read
224: ; byte by byte...
225: move.b (a4),d7
226: clr.b (a4)+
227: lsl.w #8,d7
228: move.b (a4),d7
229: clr.b (a4)+
230: swap d7
231: move.b (a4),d7
232: clr.b (a4)+
233: lsl.w #8,d7
234: move.b (a4),d7
235: clr.b (a4)+
236:
237: tst.l d7
1.1 root 238: beq.s relocdone
1.1.1.2 root 239: adda.l d7,a3
1.1.1.3 root 240: moveq #0,d7
241: relloop0:
242: add.l d0,(a3)
243: relloop:
244: move.b (a4),d7
1.1.1.7 ! root 245: clr.b (a4)+ ; Some programs like GFA-Basic expect a clear memory
1.1.1.3 root 246: tst.b d7
247: beq.s relocdone
248: cmp.b #1,d7
249: bne.s no254
250: lea 254(a3),a3
251: bra.s relloop
252: no254:
253: adda.w d7,a3
254: bra.s relloop0
1.1.1.2 root 255:
1.1 root 256: relocdone:
257: move.l 28(a5),d0
258: beq.s cleardone
259: move.l 24(a5),a0
260: clear:
261: clr.b (a0)+
262: subq.l #1,d0
263: bne.s clear
264: cleardone:
265: move.l a5,d0
266: movem.l (sp)+,a3-a5/d6-d7
267: rts
1.1.1.4 root 268:
1.1.1.7 ! root 269: hdr_not_ok:
! 270: move d6,-(sp)
! 271: move #$3e,-(sp) ; Fclose
! 272: trap #1 ; Gemdos
! 273: addq #4,sp
! 274:
! 275: move.l a5,-(sp)
! 276: move.w #$49,-(sp) ; Mfree
! 277: trap #1 ; Release "pexeced" memory
! 278: addq.l #6,sp
! 279:
! 280: move.l #-66,d0 ; Error code: Invalid PRG format
! 281: movem.l (sp)+,a3-a5/d6-d7
! 282: addq #4,sp ; Drop return address
! 283: bra gohome ; Abort
! 284:
1.1.1.4 root 285:
286:
287: ; This code is called during TOS' boot sequence.
288: ; It gets a pointer to the Line-A variables and uses an illegal opcode
289: ; to run our system initialization code in OpCode_SysInit().
290: sys_init:
291: dc.w $A000 ; Line-A init (needed for VDI resolutions)
292: dc.w SYSINIT_OPCODE ; Illegal opcode to call OpCode_SysInit()
293: rts
294:
295:
296:
297: ; This code is run when the user starts the HATARI.PRG
298: ; in the cartridge. It simply displays some information text.
299: infoprgstart:
300: pea hatarix32(pc)
301: move.w #32,-(sp)
302: trap #14 ; Dosound - play some music :-)
303: addq.l #6,sp
304:
305: pea infotext(pc)
306: move.w #9,-(sp)
307: trap #1 ; Cconws - display the information text
308: addq.l #6,sp
309:
310: move.w #7,-(sp)
311: trap #1 ; Crawcin - wait for a key
312: addq.l #2,sp
313:
314: clr.w -(sp)
315: trap #1 ; Pterm0
316:
317:
318: infotext:
319: dc.b 27,'E',13,10
320: dc.b ' =========================',13,10
321: dc.b ' Hatari keyboard shortcuts',13,10
322: dc.b ' =========================',13,10
323: dc.b 13,10
324: dc.b ' F11 : toggle fullscreen/windowed mode',13,10
325: dc.b ' F12 : activate the setup GUI of Hatari',13,10
326: dc.b 13,10
327: dc.b 'All other shortcuts are activated by',13,10
328: dc.b 'pressing AltGr or Right-Alt or Meta key',13,10
329: dc.b 'together with one of the following keys:',13,10
330: dc.b 13,10
331: dc.b ' a : Record animation',13,10
332: dc.b ' g : Grab a screenshot',13,10
333: dc.b ' i : Leave full screen & iconify window',13,10
334: dc.b ' j : joystick via key joystick on/off',13,10
335: dc.b ' m : mouse grab',13,10
336: dc.b ' r : warm reset of the ST',13,10
337: dc.b ' c : cold reset of the ST',13,10
338: dc.b ' s : enable/disable sound',13,10
339: dc.b ' q : quit the emulator',13,10
340: dc.b ' x : toggle normal/max speed',13,10
341: dc.b ' y : enable/disable sound recording',13,10
342: dc.b 0
343:
344:
345: hatarix32:
1.1.1.5 root 346: ibytes 'cart_mus.x32'
1.1.1.4 root 347:
348:
349: infoprgend:
350:
351: END
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.