]> git.sur5r.net Git - cc65/commitdiff
Atari: fix interrupt handling if extended memory is banked in
authorChristian Groessler <chris@groessler.org>
Sun, 2 Sep 2018 21:07:03 +0000 (23:07 +0200)
committerOliver Schmidt <ol.sc@web.de>
Wed, 5 Sep 2018 09:28:15 +0000 (11:28 +0200)
Extendend memory is mapped over the main memory in the 0x4000..0x7FFF
area. Many DOSes disable interrupts while extended memory is banked in,
but not all (e.g. SpartaDOS-X).
This change modifies the initial interrupt handler to map in main memory
before chaining to the "worker" handlers.
Since the initial interrupt handler uses a data segment to store the
trampoline to chain to the original handler, introduce a new "LOWBSS"
segment to hold this trampoline. Otherwise the trampoline may end up
inside the 0x4000..0x7FFF area.

Add a link time warning if "LOWCODE" segment lays within the extended
memory window.

cfg/atari-cart.cfg
cfg/atari-cassette.cfg
cfg/atari-overlay.cfg
cfg/atari.cfg
cfg/atarixl-largehimem.cfg
cfg/atarixl-overlay.cfg
cfg/atarixl.cfg
libsrc/atari/crt0.s
libsrc/atari/irq.s

index 31d2cb1b97ec93a9554a14c666b9148d6318db15..16208f90d9b0977a406e392ec94a1aae74217e45 100644 (file)
@@ -10,23 +10,25 @@ SYMBOLS {
     __CARTFLAGS__:       type = weak,   value = $01;   # see documentation for other possible values
 }
 MEMORY {
-    ZP:     file = "", define = yes, start = $0082,                size = $007E;
-    MAIN:   file = "", define = yes, start = %S,                   size = __CARTSIZE__;
-    ROM:    file = %O, define = yes, start = $C000 - __CARTSIZE__, size = __CARTSIZE__ - 6, fill = yes, fillval = $FF;
-    CARTID: file = %O,               start = $BFFA,                size = $0006;
+    ZP:      file = "", define = yes, start = $0082,                size = $007E;
+    MAIN:    file = "", define = yes, start = %S,                   size = __CARTSIZE__;
+    ROM:     file = %O, define = yes, start = $C000 - __CARTSIZE__, size = __CARTSIZE__ - 6, fill = yes, fillval = $FF;
+    CARTID:  file = %O,               start = $BFFA,                size = $0006;
+    DISCARD: file = "",               start = $0100,                size = $FF00;
 }
 SEGMENTS {
-    ZEROPAGE: load = ZP,              type = zp,                optional = yes;
-    EXTZP:    load = ZP,              type = zp,                optional = yes;
-    STARTUP:  load = ROM,             type = ro,  define = yes, optional = yes;
-    LOWCODE:  load = ROM,             type = ro,  define = yes, optional = yes;
-    ONCE:     load = ROM,             type = ro,                optional = yes;
-    CODE:     load = ROM,             type = ro,  define = yes;
-    RODATA:   load = ROM,             type = ro,                optional = yes;
-    DATA:     load = ROM, run = MAIN, type = rw,  define = yes, optional = yes;
-    INIT:     load = MAIN,            type = bss,               optional = yes;
-    BSS:      load = MAIN,            type = bss, define = yes, optional = yes;
-    CARTHDR:  load = CARTID,          type = ro;
+    ZEROPAGE: load = ZP,                  type = zp,                optional = yes;
+    EXTZP:    load = ZP,                  type = zp,                optional = yes;
+    STARTUP:  load = ROM,                 type = ro,  define = yes, optional = yes;
+    LOWBSS:   load = DISCARD, run = MAIN, type = rw,                optional = yes;  # not zero-initialized
+    LOWCODE:  load = ROM,                 type = ro,  define = yes, optional = yes;
+    ONCE:     load = ROM,                 type = ro,                optional = yes;
+    CODE:     load = ROM,                 type = ro,  define = yes;
+    RODATA:   load = ROM,                 type = ro,                optional = yes;
+    DATA:     load = ROM, run = MAIN,     type = rw,  define = yes, optional = yes;
+    INIT:     load = MAIN,                type = bss,               optional = yes;
+    BSS:      load = MAIN,                type = bss, define = yes, optional = yes;
+    CARTHDR:  load = CARTID,              type = ro;
 }
 FEATURES {
     CONDES: type    = constructor,
index 5e99c303e8bcff3c4648142aa66236940a36cec3..465add95e3bc809a7943c8f143908dfc4646e650 100644 (file)
@@ -16,6 +16,7 @@ SEGMENTS {
     EXTZP:    load = ZP,   type = zp,                optional = yes;
     CASHDR:   load = MAIN, type = ro;
     STARTUP:  load = MAIN, type = ro,  define = yes, optional = yes;
+    LOWBSS:   load = MAIN, type = rw,                optional = yes;  # not zero-initialized
     LOWCODE:  load = MAIN, type = ro,  define = yes, optional = yes;
     ONCE:     load = MAIN, type = ro,                optional = yes;
     CODE:     load = MAIN, type = ro,  define = yes;
index 87e62d7648936db308695de14d71e4f41f4426d4..fdf2e983c63e412f922c7fc0f90e4248fe21cb6a 100644 (file)
@@ -46,6 +46,7 @@ SEGMENTS {
     SYSCHKTRL: load = SYSCHKTRL,  type = ro,                optional = yes;
     MAINHDR:   load = MAINHDR,    type = ro;
     STARTUP:   load = MAIN,       type = ro,  define = yes;
+    LOWBSS:    load = MAIN,       type = rw,                optional = yes;  # not zero-initialized
     LOWCODE:   load = MAIN,       type = ro,  define = yes, optional = yes;
     ONCE:      load = MAIN,       type = ro,                optional = yes;
     CODE:      load = MAIN,       type = ro,  define = yes;
index 4680a89edb0537cefb773d053171f75a1d43ae5e..9e0ea474fc62a41930bc89ad53145f3ebfe5fdff 100644 (file)
@@ -34,6 +34,7 @@ SEGMENTS {
     SYSCHKTRL: load = SYSCHKTRL,  type = ro,                optional = yes;
     MAINHDR:   load = MAINHDR,    type = ro;
     STARTUP:   load = MAIN,       type = ro,  define = yes;
+    LOWBSS:    load = MAIN,       type = rw,                optional = yes;  # not zero-initialized
     LOWCODE:   load = MAIN,       type = ro,  define = yes, optional = yes;
     ONCE:      load = MAIN,       type = ro,                optional = yes;
     CODE:      load = MAIN,       type = ro,  define = yes;
index 56d2af15bbbdcf6d3e57ec195f1087e87039e275..842a485a1a8821c25a554cf2fb697ebac090791e 100644 (file)
@@ -61,6 +61,7 @@ SEGMENTS {
 
     MAINHDR:     load = MAINHDR,                      type = ro;
     STARTUP:     load = MAIN,                         type = ro,  define = yes;
+    LOWBSS:      load = MAIN,                         type = rw,                optional = yes;  # not zero-initialized
     LOWCODE:     load = MAIN,                         type = ro,  define = yes, optional = yes;
     ONCE:        load = MAIN,                         type = ro,                optional = yes;
     CODE:        load = MAIN,                         type = ro,  define = yes;
index 923436497558b77768bae748419c37b8d78291b9..f3a40b6a73c18b468f7bb96949ffaebc9577f8f6 100644 (file)
@@ -72,6 +72,7 @@ SEGMENTS {
 
     MAINHDR:     load = MAINHDR,                       type = ro;
     STARTUP:     load = MAIN,                          type = ro,  define = yes;
+    LOWBSS:      load = MAIN,                          type = rw,                optional = yes;  # not zero-initialized
     LOWCODE:     load = MAIN,                          type = ro,  define = yes, optional = yes;
     ONCE:        load = MAIN,                          type = ro,                optional = yes;
     CODE:        load = MAIN,                          type = ro,  define = yes;
index 197daace6a67b18fc9a4b4b38c32b72e8edf1b36..c2d331fab793c6a1e7e2f30af420f53eec704736 100644 (file)
@@ -59,6 +59,7 @@ SEGMENTS {
 
     MAINHDR:     load = MAINHDR,                       type = ro;
     STARTUP:     load = MAIN,                          type = ro,  define = yes;
+    LOWBSS:      load = MAIN,                          type = rw,                optional = yes;  # not zero-initialized
     LOWCODE:     load = MAIN,                          type = ro,  define = yes, optional = yes;
     ONCE:        load = MAIN,                          type = ro,                optional = yes;
     CODE:        load = MAIN,                          type = ro,  define = yes;
index d14567491cb40e44069e2cb310e5350af2c3016d..97b7d7e95df3f344e66f5047770ecda27f1a0750 100644 (file)
@@ -15,6 +15,7 @@
         .import         callmain, zerobss
         .import         __RESERVED_MEMORY__
         .import         __MAIN_START__, __MAIN_SIZE__
+        .import         __LOWCODE_RUN__, __LOWCODE_SIZE__
 .ifdef __ATARIXL__
         .import         __STACKSIZE__
         .import         sram_init
@@ -199,3 +200,11 @@ LMARGN_save:    .res    1
 .ifndef __ATARIXL__
 APPMHI_save:    .res    2
 .endif
+
+; ------------------------------------------------------------------------
+
+.segment "LOWCODE"       ; have at least one (empty) segment of LOWCODE, so that the next line works even if the program doesn't make use of this segment
+.assert (__LOWCODE_RUN__ + __LOWCODE_SIZE__ <= $4000 || __LOWCODE_RUN__ > $7FFF || __LOWCODE_SIZE__ = 0), warning, "'lowcode area' reaches into $4000..$7FFF bank memory window"
+; check for LOWBSS_SIZE = 0 not needed since the only file which uses LOWBSS (irq.s) also uses LOWCODE
+; check for LOWCODE_RUN > $7FFF is mostly for cartridges, where this segment is loaded high (into cart ROM)
+; there is a small chance that if the user loads the program really high, LOWCODE is above $7FFF, but LOWBSS is below -- no warning emitted in this case
index 1878ea0a2bd0e35df46a9a5e783c3330fddb925b..86fef609b3044861a2294c7b75bd93a986f4d262 100644 (file)
@@ -16,6 +16,8 @@
 .segment        "ONCE"
 
 initirq:
+        lda     #$4C                    ; JMP opcode
+        sta     IRQInd
         lda     VVBLKD
         ldx     VVBLKD+1
         sta     IRQInd+1
@@ -45,17 +47,22 @@ IRQStub:
 .ifdef CHARGEN_RELOC
         lda     CHBAS
         pha
+.endif
 .endif
         lda     PORTB
         pha
-        and     #$FE
-        sta     PORTB                   ; disable ROM
+.ifdef __ATARIXL__
+        and     #$FE                    ; disable ROM
+.endif
+        ora     #$10                    ; map main memory into $4000..$7FFF area
+        sta     PORTB
+.ifdef __ATARIXL__
         set_chbase >__CHARGEN_START__
 .endif
         jsr     callirq                 ; Call the functions
-.ifdef __ATARIXL__
         pla
-        sta     PORTB                   ; restore old ROM setting
+        sta     PORTB                   ; restore old memory settings
+.ifdef __ATARIXL__
 .ifdef CHARGEN_RELOC
         pla
         sta     CHBAS
@@ -66,6 +73,8 @@ IRQStub:
 
 ; ------------------------------------------------------------------------
 
-.data
+.segment        "LOWBSS"
+
+IRQInd: .res    3
 
-IRQInd: jmp     $0000
+.end