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