--- /dev/null
+FEATURES {
+ STARTADDRESS: default = $2000;
+}
+SYMBOLS {
+ __CART_HEADER__: type = import;
+ __STACKSIZE__: type = weak, value = $0800; # 2k stack
+ __STARTADDRESS__: type = export, value = %S;
+ __RESERVED_MEMORY__: type = export, value = $0000;
+ __CARTFLAGS__: type = weak, value = $01; # see documentation for other possible values
+}
+MEMORY {
+ ZP: file = "", define = yes, start = $0082, size = $007E;
+ RAM: file = "", define = yes, start = %S, size = $2000;
+ ROM: file = %O, define = yes, start = $A000, size = $1FFA, fill = yes, fillval = $ff;
+ CARTID: file = %O, start = $BFFA, size = $0006;
+}
+SEGMENTS {
+ STARTUP: load = ROM, type = ro, define = yes;
+ LOWCODE: load = ROM, type = ro, define = yes, optional = yes;
+ INIT: load = ROM, type = ro, optional = yes;
+ CODE: load = ROM, type = ro, define = yes;
+ RODATA: load = ROM, type = ro;
+ DATA: load = ROM, run = RAM, type = rw, define = yes;
+ BSS: load = RAM, type = bss, define = yes;
+ CARTHDR: load = CARTID, type = ro;
+ ZEROPAGE: load = ZP, type = zp;
+ EXTZP: load = ZP, type = zp, optional = yes;
+}
+FEATURES {
+ CONDES: type = constructor,
+ label = __CONSTRUCTOR_TABLE__,
+ count = __CONSTRUCTOR_COUNT__,
+ segment = INIT;
+ CONDES: type = destructor,
+ label = __DESTRUCTOR_TABLE__,
+ count = __DESTRUCTOR_COUNT__,
+ segment = RODATA;
+ CONDES: type = interruptor,
+ label = __INTERRUPTOR_TABLE__,
+ count = __INTERRUPTOR_COUNT__,
+ segment = RODATA,
+ import = __CALLIRQ__;
+}
--- /dev/null
+; Cartridge "header"
+; (In fact, it's at the end of the cartridge, so more a "trailer".)
+;
+; Christian Groessler, 06-Jan-2014
+
+.ifndef __ATARIXL__
+
+.import __CARTFLAGS__, cartinit, cartstart
+.export __CART_HEADER__: absolute = 1
+
+.include "atari.inc"
+
+ .segment "CARTHDR"
+
+ .word cartstart ; start routine
+ .byte 0 ; must be zero
+ .byte <__CARTFLAGS__
+ .word cartinit ; init routine
+
+.endif ; .ifndef __ATARIXL__
--- /dev/null
+; Cartridge start routine
+;
+; Christian Groessler, 06-Jan-2014
+
+.ifndef __ATARIXL__
+
+.export cartstart
+
+.import start
+.import __DATA_LOAD__, __DATA_SIZE__, __DATA_RUN__
+.importzp ptr1, ptr2, tmp1, tmp2
+
+.include "atari.inc"
+
+.segment "STARTUP"
+
+; start routine of cartridge
+; copy data segment to RAM and chain to entry point of crt0.s
+
+cartstart: lda #<__DATA_LOAD__
+ sta ptr1
+ lda #>__DATA_LOAD__
+ sta ptr1+1
+ lda #<__DATA_RUN__
+ sta ptr2
+ lda #>__DATA_RUN__
+ sta ptr2+1
+ lda #>__DATA_SIZE__
+ sta tmp2
+ lda #<__DATA_SIZE__
+ sta tmp1
+ jsr memcopy
+ jsr start ; run program
+ jmp (DOSVEC) ; return to DOS
+
+
+; routine taken from http://www.obelisk.demon.co.uk/6502/algorithms.html
+;
+; copy memory
+; ptr1 - source
+; ptr2 - destination
+; tmp2:tmp1 - len
+
+.proc memcopy
+
+ ldy #0
+ ldx tmp2
+ beq last
+pagecp: lda (ptr1),y
+ sta (ptr2),y
+ iny
+ bne pagecp
+ inc ptr1+1
+ inc ptr2+1
+ dex
+ bne pagecp
+last: cpy tmp1
+ beq done
+ lda (ptr1),y
+ sta (ptr2),y
+ iny
+ bne last
+done: rts
+
+.endproc
+
+.endif ; .ifndef __ATARIXL__