]> git.sur5r.net Git - cc65/commitdiff
Add support to create cartridges.
authorChristian Groessler <chris@groessler.org>
Mon, 6 Jan 2014 19:24:29 +0000 (20:24 +0100)
committerChristian Groessler <chris@groessler.org>
Tue, 14 Jan 2014 21:53:49 +0000 (22:53 +0100)
cfg/atari-cart.cfg [new file with mode: 0644]
libsrc/atari/carthdr.s [new file with mode: 0644]
libsrc/atari/cartinit.s [new file with mode: 0644]
libsrc/atari/cartstart.s [new file with mode: 0644]

diff --git a/cfg/atari-cart.cfg b/cfg/atari-cart.cfg
new file mode 100644 (file)
index 0000000..cf64726
--- /dev/null
@@ -0,0 +1,43 @@
+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__;
+}
diff --git a/libsrc/atari/carthdr.s b/libsrc/atari/carthdr.s
new file mode 100644 (file)
index 0000000..7ec2fc9
--- /dev/null
@@ -0,0 +1,20 @@
+; 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__
diff --git a/libsrc/atari/cartinit.s b/libsrc/atari/cartinit.s
new file mode 100644 (file)
index 0000000..5930c62
--- /dev/null
@@ -0,0 +1,13 @@
+; Cartridge init routine
+;
+; Christian Groessler, 06-Jan-2014
+
+.ifndef __ATARIXL__
+
+.export                cartinit
+
+.segment       "STARTUP"
+
+cartinit:      rts
+
+.endif ; .ifndef __ATARIXL__
diff --git a/libsrc/atari/cartstart.s b/libsrc/atari/cartstart.s
new file mode 100644 (file)
index 0000000..60771d5
--- /dev/null
@@ -0,0 +1,67 @@
+; 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__