Cartridge port uses address range: $FA0000-$FBFFFF, it is 128KB, not much these days. But we may put there several short apps. especially if we compress them (SFX). Port is read only. At beginning magic long value $ABCDEF42 means that cartridge is active, and has at least 1 programm on. (For diagnostic cartridges we have different magic, but will not deal here with..) After it comes header of first program - see attached pic about header.
CA_NEXT points to header of next program, or has value 0 if no more.
CA_INIT holds address of optional init. routine. Bits 24-31 aren't used for addressing, and ensure in which moment by system init prg. will be initialized and/or started. Bits have following meanings, 1 means execution:
bit 24: Init. or start of cartridge SW after succesfull HW init. System variables and vectors are set, screen is set, Interrupts are disabled - level 7.
bit 25: As by bit 24, but right after enabling interrupts on level 3. Before GEMDOS init.
bit 26: System init is done until setting screen resolution. Otherwise as bit 24.
bit 27: After GEMDOS init. Before booting from disks.
bit 28: -
bit 29: Program is desktop accessory - ACC .
bit 30: TOS application .
bit 31: TTP .
CA_RUN: Program start address. All optional inits are done before. This is required only if program runs under GEMDOS.
CA_TIME and CA_DATE: File's time and date stamps. In GEMDOS format.
CA_SIZE: Lenght of app. in bytes. Not really used.
CA_NAME: DOS/TOS filename 8.3 format. Terminated with 0 .
Cartridge programs for GEMDOS will appear on desktop in virtual drive c: (lowcase c) .
There are some limitations: only executables are accessible on cartridge - it means that PRG with separated RSC file will not work. Programs must be written so, that run from ROM. This latest is fortunately easy to override, what is important, because we want to put there some existing programs, written to run from RAM. I will give here simple code example, which copies and relocates executables from ROM to RAM.
- Code: Select all
*Multi Cartridge programm starter
*Rom cartridge
org $FA0000
dc.l $abcdef42 *magic
dc.l second
dc.l 0
dc.l run1
dc.w $a5CD *time
dc.w $1e28 *date
dc.l 31420
dc.b "MONC.PRG",0
even
second
dc.l third
dc.l 0
dc.l run2
dc.w $b149 *time
dc.w $1e51 *date
dc.l 7961
dc.b "FIRDC.PRG",0
even
third
dc.l 0
dc.l 0
dc.l coac
dc.w $a5CD *time
dc.w $1e28 *date
dc.l 22568
dc.b "DISKDOCT.PRG",0
even
*Input: a6-progbase adress, d2- len/4
coac lea thecoac(pc),a6
move.w #22568/4,d2
bra.s common
run1 lea themon(pc),a6
move.w #31420/4,d2
bra.s common
run2 lea thefirdc(pc),a6
move.w #7961/4,d2
*test free ram
common move.l 4(sp),a0 *tpa begin
move.l 4(a0),d0 *tpa end
sub.l a0,d0 *available len
moveq #0,d1
add.l 2(a6),d1 *text len
add.l 6(a6),d1 *data len
add.l 10(a6),d1 *bss len
add.l #512,d1 *for basepage+reserve
*d1 now holds needed ram len
cmp.l d1,d0
bmi.s noram
lea 256(a0),a1
move.l a1,8(a0) *txt beg (startadress of prg)
lea -28(a1),a2
move.l a2,a3 *store beginadr of header
*copy code
ccl move.l (a6)+,(a2)+
dbf d2,ccl
*Relocation
*a0 is base page,a1 is text begin, a3 is header addr.
move.l a1,a2
add.l 2(a3),a2 *txt len
add.l 6(a3),a2 *data len
move.l a1,d0
tst.l (a2)
beq.s corrbp
ADDA.L (A2)+,A1
clr.l d1
relol ADD.L D0,(A1)
bigd
MOVE.B (A2)+,D1
beq.s corrbp
CMP.B #1,D1
bne.s nmd
ADDA.W #$FE,A1
BRA.S bigd
nmd ADDA.L D1,A1
BRA.S relol
corrbp
MOVE.L 2(A3),$C(A0)
MOVE.L 6(A3),$14(A0)
MOVE.L $A(A3),$1C(A0)
MOVE.L $C(A0),D1
ADD.L D0,D1
MOVE.L D1,$10(A0)
ADD.L $14(A0),D1
MOVE.L D1,$18(A0)
move.l d0,a1
jmp (a1)
noram pea mess(pc)
move.w #9,-(sp)
trap #1
addq.l #6,sp
move.w #1,-(sp) *wait keypress
trap #1
addq.l #6,sp
clr.w -(sp)
trap #1 *exit
mess dc.b 13,10,"Insufficient RAM !",0
even
thecoac
incbin DISKDOCT.PRG
even
dc.l 0,0 *gap
thefirdc
incbin FIRDC.PRG
even
dc.l 0,0 *gap
themon
incbin MONC.PRG
even
dc.l 0,0 *gap
Executables may be compressed to save space - for instance with PRG FIRDC on this cartridge example.
In attachment CART1.ZIP is this source and 64KB cartridge content - binary, and splitted to Low and High parts for EPROM burners.
You may play with binary in Hatari emulator, but first expand it to full 128KB, otherwise will not activate (for instance use DOS copy command: copy /b ca3f_1w.bin + ca3f_1w.bin cart.bin - will get 128KB ).
In Steem cartridge image file format is little different, as I see it adds four zeros at beginning... Right. Attachment CARD2.ZIP holds special cartridge SW, which creates RAMdisk C at boot. I included some disk utilities, control.acc in example. Cartridge image is in STC format, what is just regular binary with 4 zeros at start. So, you may play with it in Steem, or burn it for cartridge if strip those 4 zeros and split it...



