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