|
|
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 63: move.l a6,-(sp) ;new 1.1.1.3 root 64: bsr.s find_prog 1.1 root 65: move.l (sp)+,a6 ;new 66: bsr pexec5 67: bsr reloc 68: clr.l 2(a6) 69: clr.l 10(a6) 70: move.l d0,6(a6) 1.1.1.3 root 71: 72: move.w #48,-(sp) ; Sversion: get GEMDOS version 73: trap #1 ; call GEMDOS 74: addq #2,sp 75: ror.w #8,d0 ; Major version to high, minor version to low byte 76: cmp.w #$0015,d0 77: bge.s use_gemdos_015 78: move.w #4,(a6) ; pexec mode 4 for exec. prepared program 79: bra.s mode0_ok 80: use_gemdos_015: 81: move.w #6,(a6) ; On GEMDOS 0.15 and higher, we can use mode 6 82: mode0_ok: 83: 1.1 root 84: move.l (sp)+,a6 1.1.1.3 root 85: bra.s go_oldgemdos 86: 1.1 root 87: no_0: 88: cmp #3,(a0) 89: bne.s go_oldgemdos 1.1.1.3 root 90: 91: ; Simulate pexec mode 3 1.1 root 92: move.l a6,-(sp) 93: move.l a0,a6 1.1.1.3 root 94: bsr.s find_prog 95: bsr.s pexec5 96: bsr.s reloc 1.1 root 97: gohome: 98: move.l (sp)+,a6 99: rte 1.1.1.3 root 100: 1.1 root 101: find_prog: 1.1.1.3 root 102: move #$2f,-(sp) ; Fgetdta 1.1.1.2 root 103: trap #1 ; Gemdos 1.1 root 104: addq #2,sp 105: move.l d0,a0 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.l (a0)+,-(sp) 117: move.l a0,-(sp) 118: move #$17,-(sp) 119: move.l 2(a6),-(sp) 1.1.1.3 root 120: move #$4e,-(sp) ; Fsfirst 1.1.1.2 root 121: trap #1 ; Gemdos 1.1 root 122: addq #8,sp 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: move.l (sp)+,-(a0) 134: move.l (sp)+,-(a0) 135: tst.l d0 136: beq.s findprog_ok 137: addq #4,sp 138: bra.s gohome 139: findprog_ok: 140: rts 1.1.1.3 root 141: 1.1 root 142: pexec5: 143: move.l 10(a6),-(sp) 144: move.l 6(a6),-(sp) 145: clr.l -(sp) 146: move #5,-(sp) 1.1.1.3 root 147: move #$4b,-(sp) ; Pexec 1.1.1.2 root 148: trap #1 ; Gemdos 1.1 root 149: lea 16(sp),sp 150: tst.l d0 151: bmi.s pexecerr 152: rts 153: pexecerr: 154: addq #4,sp 155: bra.s gohome 1.1.1.3 root 156: 1.1 root 157: reloc: 158: movem.l a3-a5/d6-d7,-(sp) 159: move.l d0,a5 160: clr -(sp) 161: move.l 2(a6),-(sp) 1.1.1.3 root 162: move #$3d,-(sp) ; Fopen 1.1.1.2 root 163: trap #1 ; Gemdos 1.1 root 164: addq #8,sp 165: move.l d0,d6 166: move.l a5,-(sp) 167: add.l #228,(sp) 168: pea $1c.w 169: move d6,-(sp) 1.1.1.3 root 170: move #$3f,-(sp) ; Fread 1.1.1.2 root 171: trap #1 ; Gemdos 1.1 root 172: lea 12(sp),sp 173: ; check size!! 174: move.l a5,-(sp) 175: add.l #256,(sp) 176: pea $7fffffff 177: move d6,-(sp) 1.1.1.3 root 178: move #$3f,-(sp) ; Fread 1.1.1.2 root 179: trap #1 ; Gemdos 1.1 root 180: lea 12(sp),sp 181: move d6,-(sp) 1.1.1.3 root 182: move #$3e,-(sp) ; Fclose 1.1.1.2 root 183: trap #1 ; Gemdos 1.1 root 184: addq #4,sp 185: lea 8(a5),a4 186: move.l a5,d0 187: add.l #$100,d0 188: move.l d0,(a4)+ ; text start 189: move.l 230(a5),d0 190: move.l d0,(a4)+ ; text length 191: add.l 8(a5),d0 ; data start 192: move.l d0,(a4)+ 193: move.l 234(a5),(a4)+ ; data length 194: add.l 234(a5),d0 195: move.l d0,(a4)+ ; bss start 196: move.l 238(a5),(a4)+ ; bss length 197: move.l a5,d0 198: add.l #$80,d0 199: move.l d0,32(a5) 200: move.l 24(a5),a4 201: add.l 242(a5),a4 ; symbol table length 202: move.l 8(a5),a3 203: move.l a3,d0 204: tst.w 254(a5) 205: bne.s relocdone 1.1.1.2 root 206: 1.1.1.3 root 207: ; Get first offset of the relocation table. Since A4 seems sometimes not 208: ; to be word aligned (if symbol table length is uneven), we have to read 209: ; byte by byte... 210: move.b (a4),d7 211: clr.b (a4)+ 212: lsl.w #8,d7 213: move.b (a4),d7 214: clr.b (a4)+ 215: swap d7 216: move.b (a4),d7 217: clr.b (a4)+ 218: lsl.w #8,d7 219: move.b (a4),d7 220: clr.b (a4)+ 221: 222: tst.l d7 1.1 root 223: beq.s relocdone 1.1.1.2 root 224: adda.l d7,a3 1.1.1.3 root 225: moveq #0,d7 226: relloop0: 227: add.l d0,(a3) 228: relloop: 229: move.b (a4),d7 230: move.b #$00,(a4)+ ; Some programs like GFA-Basic expect a clear memory 231: tst.b d7 232: beq.s relocdone 233: cmp.b #1,d7 234: bne.s no254 235: lea 254(a3),a3 236: bra.s relloop 237: no254: 238: adda.w d7,a3 239: bra.s relloop0 1.1.1.2 root 240: 1.1 root 241: relocdone: 242: move.l 28(a5),d0 243: beq.s cleardone 244: move.l 24(a5),a0 245: clear: 246: clr.b (a0)+ 247: subq.l #1,d0 248: bne.s clear 249: cleardone: 250: move.l a5,d0 251: movem.l (sp)+,a3-a5/d6-d7 252: rts 1.1.1.4 ! root 253: ! 254: ! 255: ! 256: ; This code is called during TOS' boot sequence. ! 257: ; It gets a pointer to the Line-A variables and uses an illegal opcode ! 258: ; to run our system initialization code in OpCode_SysInit(). ! 259: sys_init: ! 260: dc.w $A000 ; Line-A init (needed for VDI resolutions) ! 261: dc.w SYSINIT_OPCODE ; Illegal opcode to call OpCode_SysInit() ! 262: rts ! 263: ! 264: ! 265: ! 266: ; This code is run when the user starts the HATARI.PRG ! 267: ; in the cartridge. It simply displays some information text. ! 268: infoprgstart: ! 269: pea hatarix32(pc) ! 270: move.w #32,-(sp) ! 271: trap #14 ; Dosound - play some music :-) ! 272: addq.l #6,sp ! 273: ! 274: pea infotext(pc) ! 275: move.w #9,-(sp) ! 276: trap #1 ; Cconws - display the information text ! 277: addq.l #6,sp ! 278: ! 279: move.w #7,-(sp) ! 280: trap #1 ; Crawcin - wait for a key ! 281: addq.l #2,sp ! 282: ! 283: clr.w -(sp) ! 284: trap #1 ; Pterm0 ! 285: ! 286: ! 287: infotext: ! 288: dc.b 27,'E',13,10 ! 289: dc.b ' =========================',13,10 ! 290: dc.b ' Hatari keyboard shortcuts',13,10 ! 291: dc.b ' =========================',13,10 ! 292: dc.b 13,10 ! 293: dc.b ' F11 : toggle fullscreen/windowed mode',13,10 ! 294: dc.b ' F12 : activate the setup GUI of Hatari',13,10 ! 295: dc.b 13,10 ! 296: dc.b 'All other shortcuts are activated by',13,10 ! 297: dc.b 'pressing AltGr or Right-Alt or Meta key',13,10 ! 298: dc.b 'together with one of the following keys:',13,10 ! 299: dc.b 13,10 ! 300: dc.b ' a : Record animation',13,10 ! 301: dc.b ' g : Grab a screenshot',13,10 ! 302: dc.b ' i : Leave full screen & iconify window',13,10 ! 303: dc.b ' j : joystick via key joystick on/off',13,10 ! 304: dc.b ' m : mouse grab',13,10 ! 305: dc.b ' r : warm reset of the ST',13,10 ! 306: dc.b ' c : cold reset of the ST',13,10 ! 307: dc.b ' s : enable/disable sound',13,10 ! 308: dc.b ' q : quit the emulator',13,10 ! 309: dc.b ' x : toggle normal/max speed',13,10 ! 310: dc.b ' y : enable/disable sound recording',13,10 ! 311: dc.b 0 ! 312: ! 313: ! 314: hatarix32: ! 315: ibytes 'hatari.x32' ! 316: ! 317: ! 318: infoprgend: ! 319: ! 320: END
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.