]> git.sur5r.net Git - cc65/blob - samples/overlaydemo.c
Fixed gcc compiler warning (#867)
[cc65] / samples / overlaydemo.c
1 /*
2 ** Minimalistic overlay demo program.
3 **
4 ** Shows how to load overlay files from disk.
5 **
6 ** 2009-10-02, Oliver Schmidt (ol.sc@web.de)
7 **
8 */
9
10
11
12 #include <stdio.h>
13 #include <cc65.h>
14 #ifndef __CBM__
15 #include <fcntl.h>
16 #include <unistd.h>
17 #else
18 #include <cbm.h>
19 #include <device.h>
20 #endif
21
22
23 extern void _OVERLAY1_LOAD__[], _OVERLAY1_SIZE__[];
24 extern void _OVERLAY2_LOAD__[], _OVERLAY2_SIZE__[];
25 extern void _OVERLAY3_LOAD__[], _OVERLAY3_SIZE__[];
26
27
28 /* Functions resident in an overlay can call back functions resident in the
29 ** main program at any time without any precautions. The function log() is
30 ** an example for such a function resident in the main program.
31 */
32 void log (char *msg)
33 {
34     printf ("Log: %s\n", msg);
35 }
36
37
38 /* In a real-world overlay program one would probably not use a #pragma but
39 ** rather place all the code of certain source files into the overlay by
40 ** compiling them with --code-name OVERLAY1.
41 */
42 #pragma code-name (push, "OVERLAY1");
43
44 void foo (void)
45 {
46     /* Functions resident in an overlay can access all program variables and
47     ** constants at any time without any precautions because those are never
48     ** placed in overlays. The string constant below is an example for such
49     ** a constant resident in the main program.
50     */
51     log ("Calling main from overlay 1");
52 }
53
54 #pragma code-name (pop);
55
56
57 #pragma code-name (push, "OVERLAY2");
58
59 void bar (void)
60 {
61     log ("Calling main from overlay 2");
62 }
63
64 #pragma code-name (pop);
65
66
67 #pragma code-name (push, "OVERLAY3");
68
69 void foobar (void)
70 {
71     log ("Calling main from overlay 3");
72 }
73
74 #pragma code-name(pop);
75
76
77 unsigned char loadfile (char *name, void *addr, void *size)
78 {
79 #ifndef __CBM__
80
81     int file = open (name, O_RDONLY);
82     if (file == -1) {
83         log ("Opening overlay file failed");
84         return 0;
85     }
86     read (file, addr, (unsigned) size);
87     close (file);
88
89 #else
90
91     /* Avoid compiler warnings about unused parameters. */
92     (void) addr; (void) size;
93     if (cbm_load (name, getcurrentdevice (), NULL) == 0) {
94         log ("Loading overlay file failed");
95         return 0;
96     }
97
98 #endif
99     return 1;
100 }
101
102
103 void main (void)
104 {
105     log ("Calling overlay 1 from main");
106
107     /* The symbols _OVERLAY1_LOAD__ and _OVERLAY1_SIZE__ were generated by the
108     ** linker. They contain the overlay area address and size specific to a
109     ** certain program.
110     */
111     if (loadfile ("ovrldemo.1", _OVERLAY1_LOAD__, _OVERLAY1_SIZE__)) {
112
113         /* The linker makes sure that the call to foo() ends up at the right mem
114         ** addr. However it's up to user to make sure that the - right - overlay
115         ** is actually loaded before making the the call.
116         */
117         foo ();
118     }
119
120     log ("Calling overlay 2 from main");
121
122     /* Replacing one overlay with another one can only happen from the main
123     ** program. This implies that an overlay can never load another overlay.
124     */
125     if (loadfile ("ovrldemo.2", _OVERLAY2_LOAD__, _OVERLAY2_SIZE__)) {
126         bar ();
127     }
128
129     log ("Calling overlay 3 from main");
130     if (loadfile ("ovrldemo.3", _OVERLAY3_LOAD__, _OVERLAY3_SIZE__)) {
131         foobar ();
132     }
133
134     if (doesclrscrafterexit ()) {
135         getchar ();
136     }
137 }