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

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

unix.superglobalmegacorp.com

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