mirror of
https://github.com/cc65/cc65.git
synced 2025-01-09 11:30:29 +00:00
Atari: fix interrupt handling if extended memory is banked in
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.
This commit is contained in:
parent
d199ca1460
commit
1cc4fa9356
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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: jmp $0000
|
||||
IRQInd: .res 3
|
||||
|
||||
.end
|
||||
|
Loading…
Reference in New Issue
Block a user