From 855aceaba8f78f66cf5134ae707b4cee11c6e9e9 Mon Sep 17 00:00:00 2001
From: Oliver Schmidt
Date: Mon, 29 Jan 2018 17:46:36 +0100
Subject: [PATCH] Added Apple II linker configs for programs including a hires
screen.
The Apple II hires screen buffer is located at $2000 (and can't be moved). The usual way to get along with this is to load the cc65 program above the hires screen buffer at $4000. However, that means that it becomes difficult to make good use of the memory below the hires screen buffer. The simplest approach is to add that memory to the heap. But there are programs containing just lots of code and not much data. One could think of moving the code to the area below the hires screen after loading (like it is done with the code for the language card). But if the program is really large (and already contains code to be moved to the language card) it won't just fit into memory in the first place.
The alternative is to load the program at the usual $803 and have it "cover" the hires screen buffer. Of course the part of the program that actually "covers" the hires screen buffer mustn't contain anything necessary for the program. The downside of this approach is that the program file on disk contains 8kB that can't be used by the program. But instead of just containing zeros the program can as well contain a hires screen picture that can be displayed right after startup.
Now the user can have code loaded below the hires screen buffer by setting the code-name to LOWCODE. However, he needs to explicitly do so. Otherwise the memory below the hires screen is totally wasted.
Trivia: Allowing to do this hires screen buffer "covering" was the very reason to change tgi_init() to not clear the hires screen anymore.
---
cfg/apple2-hgr.cfg | 52 +++++++++++++++++++++++++++++++++
cfg/apple2enh-hgr.cfg | 52 +++++++++++++++++++++++++++++++++
testcode/lib/apple2/hgrtest.c | 26 +++++++++++++++++
testcode/lib/apple2/werner.pic | Bin 0 -> 8184 bytes
testcode/lib/apple2/werner.s | 2 ++
5 files changed, 132 insertions(+)
create mode 100644 cfg/apple2-hgr.cfg
create mode 100644 cfg/apple2enh-hgr.cfg
create mode 100644 testcode/lib/apple2/hgrtest.c
create mode 100644 testcode/lib/apple2/werner.pic
create mode 100644 testcode/lib/apple2/werner.s
diff --git a/cfg/apple2-hgr.cfg b/cfg/apple2-hgr.cfg
new file mode 100644
index 000000000..540578b25
--- /dev/null
+++ b/cfg/apple2-hgr.cfg
@@ -0,0 +1,52 @@
+# Configuration for programs including a hires screen (with 6KB LOWCODE)
+
+FEATURES {
+ STARTADDRESS: default = $0803;
+}
+SYMBOLS {
+ __EXEHDR__: type = import;
+ __STACKSIZE__: type = weak, value = $0800; # 2k stack
+ __HIMEM__: type = weak, value = $9600; # Presumed RAM end
+ __LCADDR__: type = weak, value = $D400; # Behind quit code
+ __LCSIZE__: type = weak, value = $0C00; # Rest of bank two
+ __MAIN_START__: type = export, value = %S;
+ __MAIN_LAST__: type = export, value = __HIGH_LAST__;
+}
+MEMORY {
+ ZP: file = "", define = yes, start = $0080, size = $001A;
+ HEADER: file = %O, start = %S - 4, size = $0004;
+ LOW: file = %O, fill = yes, start = %S, size = $2000 - %S;
+ HGR: file = %O, fill = yes, start = $2000, size = $2000;
+ HIGH: file = %O, define = yes, start = $4000, size = __HIMEM__ - $4000;
+ BSS: file = "", start = __ONCE_RUN__, size = __HIMEM__ - __STACKSIZE__ - __ONCE_RUN__;
+ LC: file = "", define = yes, start = __LCADDR__, size = __LCSIZE__;
+}
+SEGMENTS {
+ ZEROPAGE: load = ZP, type = zp;
+ EXEHDR: load = HEADER, type = ro;
+ STARTUP: load = LOW, type = ro;
+ LOWCODE: load = LOW, type = ro, optional = yes;
+ HGR: load = HGR, type = rw, optional = yes;
+ CODE: load = HIGH, type = ro;
+ RODATA: load = HIGH, type = ro;
+ DATA: load = HIGH, type = rw;
+ INIT: load = HIGH, type = rw;
+ ONCE: load = HIGH, type = ro, define = yes;
+ LC: load = HIGH, run = LC, type = ro, optional = yes;
+ BSS: load = BSS, type = bss, define = yes;
+}
+FEATURES {
+ CONDES: type = constructor,
+ label = __CONSTRUCTOR_TABLE__,
+ count = __CONSTRUCTOR_COUNT__,
+ segment = ONCE;
+ 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/cfg/apple2enh-hgr.cfg b/cfg/apple2enh-hgr.cfg
new file mode 100644
index 000000000..540578b25
--- /dev/null
+++ b/cfg/apple2enh-hgr.cfg
@@ -0,0 +1,52 @@
+# Configuration for programs including a hires screen (with 6KB LOWCODE)
+
+FEATURES {
+ STARTADDRESS: default = $0803;
+}
+SYMBOLS {
+ __EXEHDR__: type = import;
+ __STACKSIZE__: type = weak, value = $0800; # 2k stack
+ __HIMEM__: type = weak, value = $9600; # Presumed RAM end
+ __LCADDR__: type = weak, value = $D400; # Behind quit code
+ __LCSIZE__: type = weak, value = $0C00; # Rest of bank two
+ __MAIN_START__: type = export, value = %S;
+ __MAIN_LAST__: type = export, value = __HIGH_LAST__;
+}
+MEMORY {
+ ZP: file = "", define = yes, start = $0080, size = $001A;
+ HEADER: file = %O, start = %S - 4, size = $0004;
+ LOW: file = %O, fill = yes, start = %S, size = $2000 - %S;
+ HGR: file = %O, fill = yes, start = $2000, size = $2000;
+ HIGH: file = %O, define = yes, start = $4000, size = __HIMEM__ - $4000;
+ BSS: file = "", start = __ONCE_RUN__, size = __HIMEM__ - __STACKSIZE__ - __ONCE_RUN__;
+ LC: file = "", define = yes, start = __LCADDR__, size = __LCSIZE__;
+}
+SEGMENTS {
+ ZEROPAGE: load = ZP, type = zp;
+ EXEHDR: load = HEADER, type = ro;
+ STARTUP: load = LOW, type = ro;
+ LOWCODE: load = LOW, type = ro, optional = yes;
+ HGR: load = HGR, type = rw, optional = yes;
+ CODE: load = HIGH, type = ro;
+ RODATA: load = HIGH, type = ro;
+ DATA: load = HIGH, type = rw;
+ INIT: load = HIGH, type = rw;
+ ONCE: load = HIGH, type = ro, define = yes;
+ LC: load = HIGH, run = LC, type = ro, optional = yes;
+ BSS: load = BSS, type = bss, define = yes;
+}
+FEATURES {
+ CONDES: type = constructor,
+ label = __CONSTRUCTOR_TABLE__,
+ count = __CONSTRUCTOR_COUNT__,
+ segment = ONCE;
+ 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/testcode/lib/apple2/hgrtest.c b/testcode/lib/apple2/hgrtest.c
new file mode 100644
index 000000000..7323cbb73
--- /dev/null
+++ b/testcode/lib/apple2/hgrtest.c
@@ -0,0 +1,26 @@
+// cl65 -t apple2 -C apple2-hgr.cfg hgrtest.c werner.s
+
+#include
+#include
+
+#pragma code-name (push, "LOWCODE")
+
+void say (const char* text)
+{
+ tgi_setcolor (TGI_COLOR_BLACK);
+ tgi_outtextxy (41, 33, text);
+}
+
+#pragma code-name (pop)
+
+void main (void)
+{
+ tgi_install (a2_hi_tgi);
+ tgi_init ();
+ cgetc ();
+
+ say ("Hi Dude !");
+ cgetc ();
+
+ tgi_uninstall ();
+}
diff --git a/testcode/lib/apple2/werner.pic b/testcode/lib/apple2/werner.pic
new file mode 100644
index 0000000000000000000000000000000000000000..2405e2409470d0de0e017194f6f81e9b058511e1
GIT binary patch
literal 8184
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
VhJ3ty9*hckkxri4g4MRT{{gd9*mnQ`
literal 0
HcmV?d00001
diff --git a/testcode/lib/apple2/werner.s b/testcode/lib/apple2/werner.s
new file mode 100644
index 000000000..6456ade13
--- /dev/null
+++ b/testcode/lib/apple2/werner.s
@@ -0,0 +1,2 @@
+.segment "HGR"
+.incbin "werner.pic"
--
2.39.5