|
|
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 root 64: bsr pexec5
65: bsr reloc
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
71: trap #1 ; call GEMDOS
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
94: bsr.s 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)
144: move #5,-(sp)
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 root 155: reloc:
156: movem.l a3-a5/d6-d7,-(sp)
157: move.l d0,a5
1.1.1.6 ! root 158: clr -(sp)
1.1 root 159: move.l 2(a6),-(sp)
1.1.1.3 root 160: move #$3d,-(sp) ; Fopen
1.1.1.2 root 161: trap #1 ; Gemdos
1.1 root 162: addq #8,sp
1.1.1.6 ! root 163:
1.1 root 164: move.l d0,d6
165: move.l a5,-(sp)
166: add.l #228,(sp)
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:
! 173: cmp.w #$601a,228(a5) ; Check program header magic
! 174: beq.s magic_ok
! 175: move d6,-(sp)
! 176: move #$3e,-(sp) ; Fclose
! 177: trap #1 ; Gemdos
! 178: addq #4,sp
! 179: move.l a5,-(sp)
! 180: move.w #$49,-(sp) ; Mfree
! 181: trap #1 ; Release "pexeced" memory
! 182: addq.l #6,sp
! 183: move.l #-66,d0 ; Error code: Invalid PRG format
! 184: movem.l (sp)+,a3-a5/d6-d7
! 185: addq #4,sp ; Drop return address
! 186: bra gohome ; Abort
! 187: magic_ok:
! 188: ; TODO: check size!!
1.1 root 189: move.l a5,-(sp)
190: add.l #256,(sp)
191: pea $7fffffff
192: move d6,-(sp)
1.1.1.3 root 193: move #$3f,-(sp) ; Fread
1.1.1.2 root 194: trap #1 ; Gemdos
1.1 root 195: lea 12(sp),sp
196: move d6,-(sp)
1.1.1.3 root 197: move #$3e,-(sp) ; Fclose
1.1.1.2 root 198: trap #1 ; Gemdos
1.1 root 199: addq #4,sp
200: lea 8(a5),a4
201: move.l a5,d0
202: add.l #$100,d0
203: move.l d0,(a4)+ ; text start
204: move.l 230(a5),d0
205: move.l d0,(a4)+ ; text length
206: add.l 8(a5),d0 ; data start
207: move.l d0,(a4)+
208: move.l 234(a5),(a4)+ ; data length
209: add.l 234(a5),d0
210: move.l d0,(a4)+ ; bss start
211: move.l 238(a5),(a4)+ ; bss length
212: move.l a5,d0
213: add.l #$80,d0
214: move.l d0,32(a5)
215: move.l 24(a5),a4
216: add.l 242(a5),a4 ; symbol table length
217: move.l 8(a5),a3
218: move.l a3,d0
219: tst.w 254(a5)
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
245: move.b #$00,(a4)+ ; Some programs like GFA-Basic expect a clear memory
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:
269:
270:
271: ; This code is called during TOS' boot sequence.
272: ; It gets a pointer to the Line-A variables and uses an illegal opcode
273: ; to run our system initialization code in OpCode_SysInit().
274: sys_init:
275: dc.w $A000 ; Line-A init (needed for VDI resolutions)
276: dc.w SYSINIT_OPCODE ; Illegal opcode to call OpCode_SysInit()
277: rts
278:
279:
280:
281: ; This code is run when the user starts the HATARI.PRG
282: ; in the cartridge. It simply displays some information text.
283: infoprgstart:
284: pea hatarix32(pc)
285: move.w #32,-(sp)
286: trap #14 ; Dosound - play some music :-)
287: addq.l #6,sp
288:
289: pea infotext(pc)
290: move.w #9,-(sp)
291: trap #1 ; Cconws - display the information text
292: addq.l #6,sp
293:
294: move.w #7,-(sp)
295: trap #1 ; Crawcin - wait for a key
296: addq.l #2,sp
297:
298: clr.w -(sp)
299: trap #1 ; Pterm0
300:
301:
302: infotext:
303: dc.b 27,'E',13,10
304: dc.b ' =========================',13,10
305: dc.b ' Hatari keyboard shortcuts',13,10
306: dc.b ' =========================',13,10
307: dc.b 13,10
308: dc.b ' F11 : toggle fullscreen/windowed mode',13,10
309: dc.b ' F12 : activate the setup GUI of Hatari',13,10
310: dc.b 13,10
311: dc.b 'All other shortcuts are activated by',13,10
312: dc.b 'pressing AltGr or Right-Alt or Meta key',13,10
313: dc.b 'together with one of the following keys:',13,10
314: dc.b 13,10
315: dc.b ' a : Record animation',13,10
316: dc.b ' g : Grab a screenshot',13,10
317: dc.b ' i : Leave full screen & iconify window',13,10
318: dc.b ' j : joystick via key joystick on/off',13,10
319: dc.b ' m : mouse grab',13,10
320: dc.b ' r : warm reset of the ST',13,10
321: dc.b ' c : cold reset of the ST',13,10
322: dc.b ' s : enable/disable sound',13,10
323: dc.b ' q : quit the emulator',13,10
324: dc.b ' x : toggle normal/max speed',13,10
325: dc.b ' y : enable/disable sound recording',13,10
326: dc.b 0
327:
328:
329: hatarix32:
1.1.1.5 root 330: ibytes 'cart_mus.x32'
1.1.1.4 root 331:
332:
333: infoprgend:
334:
335: END
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.