]> git.sur5r.net Git - cc65/blob - samples/geos/overlay-demo.c
atari5200: implement bgcolor() and textcolor()
[cc65] / samples / geos / overlay-demo.c
1 /*
2 ** Minimalistic GEOSLib overlay demo program
3 **
4 ** 2012-01-01, Oliver Schmidt (ol.sc@web.de)
5 **
6 */
7
8
9 #include <stdio.h>
10 #include <geos.h>
11 #include "overlay-demores.h"
12
13
14 /* Functions resident in an overlay can call back functions resident in the
15 ** main program at any time without any precautions. The function show() is
16 ** an example for such a function resident in the main program.
17 */
18 void show(char *name)
19 {
20     char line1[40];
21
22     sprintf(line1, CBOLDON "Overlay Demo - Overlay %s" CPLAINTEXT, name);
23     DlgBoxOk(line1, "Click OK to return to Main.");
24 }
25
26 /* In a real-world overlay program one would probably not use a #pragma but
27 ** rather place the all the code of certain source files into the overlay by
28 ** compiling them with --code-name OVERLAY1.
29 */
30 #pragma code-name(push, "OVERLAY1");
31
32 void foo(void)
33 {
34     /* Functions resident in an overlay can access all program variables and
35     ** constants at any time without any precautions because those are never
36     ** placed in overlays. The string constant "One" is an example for such 
37     ** a constant resident in the main program.
38     */
39     show("One");
40 }
41
42 #pragma code-name(pop);
43
44
45 #pragma code-name(push, "OVERLAY2");
46
47 void bar(void)
48 {
49     show("Two");
50 }
51
52 #pragma code-name(pop);
53
54
55 #pragma code-name(push, "OVERLAY3");
56
57 void foobar (void)
58 {
59     show("Three");
60 }
61
62 #pragma code-name(pop);
63
64
65 void main(int /*argc*/, char *argv[])
66 {
67     if (OpenRecordFile(argv[0])) {
68         _poserror("OpenRecordFile");
69         return;
70     }
71
72     DlgBoxOk(CBOLDON "Overlay Demo - Main" CPLAINTEXT,
73              "Click OK to call Overlay One.");
74
75     if (PointRecord(1)) {
76         _poserror("PointRecord.1");
77         return;
78     }
79
80     /* The macro definitions OVERLAY_ADDR and OVERLAY_SIZE were generated in
81     ** overlay-demores.h by grc65. They contain the overlay area address and
82     ** size specific to a certain program.
83     */
84     if (ReadRecord(OVERLAY_ADDR, OVERLAY_SIZE)) {
85         _poserror("ReadRecord.1");
86         return;
87     }
88
89     /* The linker makes sure that the call to foo() ends up at the right mem
90     ** addr. However, it's up to user to make sure that the -- right -- overlay
91     ** actually is loaded before making the call.
92     */
93     foo();
94
95     DlgBoxOk(CBOLDON "Overlay Demo - Main" CPLAINTEXT,
96              "Click OK to call Overlay Two.");
97
98     if (PointRecord(2)) {
99         _poserror("PointRecord.2");
100         return;
101     }
102
103     /* Replacing one overlay with another one can only happen from the main
104     ** program. This implies that an overlay can never load another overlay.
105     */
106     if (ReadRecord(OVERLAY_ADDR, OVERLAY_SIZE)) {
107         _poserror("ReadRecord.2");
108         return;
109     }
110
111     bar();
112
113     DlgBoxOk(CBOLDON "Overlay Demo - Main" CPLAINTEXT,
114              "Click OK to call Overlay Three.");
115
116     if (PointRecord(3)) {
117         _poserror("PointRecord.3");
118         return;
119     }
120
121     if (ReadRecord(OVERLAY_ADDR, OVERLAY_SIZE)) {
122         _poserror("ReadRecord.3");
123         return;
124     }
125
126     foobar();
127
128     if (CloseRecordFile()) {
129         _poserror("CloseRecordFile");
130         return;
131     }
132 }