Annotation of hatari/src/cart_asm.s, revision 1.1.1.9

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.