<title>GEOSLib docs
<author>Maciej Witkowiak, <htmlurl url="mailto:ytm@elysium.pl" name="ytm@elysium.pl">
-<date>v1.3, 26.12.1999, 16.03.2000, 19-22.03.2000, 11,29.07.2000, 3-4,15.07.2001, 27.10.2001
+<date>v1.5, 26.12.1999, 2000, 2001, 2002, 2003
<abstract>
This is the documentation of cc65's GEOSLib, but information contained here may be also
useful for writting GEOS applications in general.
VICE and cc65 are portable - they run on variety of platforms - DOS, Win32 and UNIX. GEOSLib only
needs cc65.
<p>
-<em/Update:/ starting from v2.5.0 GEOSLib is a part of cc65 package as its GEOS support.
+<em/Update:/ starting from v2.5.0 GEOSLib is a part of cc65 package as its GEOS support library.
<sect1>Legal
<p>
<p>
All in all, you just need to place
<tscreen><verb>
-#include <geos.h>
+#include <geos.h>
</verb></tscreen>
on top of your source.
<p>
<sect2>Disk Initialization
<p>
-GEOS has two functions for initialization ('logging' as they say on CP\M) the disk.
+GEOS has two functions for initialization ('logging in' as they say on CP\M) the disk.
<sect3>OpenDisk
<p>
<tt/char OpenDisk (void)/
System error at:xxxx
</verb></tscreen>
where <tt/xxxx/ is last known execution address (caller). By default this is bound to <tt/BRK/
-instruction, but it might be usable in debugging as kind of <tt/assert/.
+instruction, but it might be usable in debugging as kind of <tt/assert/. (Note that <tt/assert/
+is available as a separate function and will give you more information than that).
<p>
System is halted after call to <tt/Panic/ which means that library destructors will not be
called and some data may be lost (no wonder you're panicking).
<tt/random/ is updated once a frame (50Hz PAL) and on every call to <tt/GetRandom/.
<p>
Note that it is not the same as <tt/rand/ function from the standard library. <tt/GetRandom/
-will give you unpredictable results (if IRQs will occur between calls to it) while
+will give you unpredictable results (if IRQs would occur between calls to it) while
<tt/rand/ conforms to the standard and for given seed (<tt/srand/) it always returns with the
same sequence of values.
bound to <tt/curFontDesc/. You can also force GEOS to use your own fonts by calling
<tt/LoadCharSet/. You just need to open a VLIR font file and load one record - one pointsize
somewhere. At the start of this area you already have all data for <tt/fontdesc/ so you can
-pass a pointer to the load adress of that pointsize to <tt/LoadCharSet/.
+pass a pointer to the load adress of that pointsize to <tt/LoadCharSet/. (Note that although
+it has 'Load' in the name, that function loads only GEOS internal data structures, not data
+from disk).
<sect2>window
<p>
Here is how single descriptor looks like:
<tscreen><verb>
void myMenu = {
- (char)top, (char)botom, // this is the size of the menubox
- (unsigned)left, (unsigned)right, // counting all items in current descriptor
- (char)number_of_items | type_of_menu, // number of following items ORed with
- // type of this menu, it can be either
+ (char)top, (char)bottom, // this is the size of the menubox
+ (unsigned)left, (unsigned)right, // counting all items in current descriptor
+ (char)number_of_items | type_of_menu, // number of following items ORed with
+ // type of this menu, it can be either
// HORIZONTAL or VERTICAL if you will have also bit 6 set then menu won't be closed
// after moving mouse pointer outside the menubox. You can have at most 31 items.
</verb></tscreen>
(unsigned)address_to_store_values_at,
(char)number_of_bytes_that_follow,
(char)data,(char)data (...)
- (...) - more such definitions
- (unsigned)NULL - address of 0 ends the table
+ // more such definitions
+ (unsigned)NULL // address of 0 ends the table
};
</verb></tscreen>
+<sect2>Intercepting system vectors
+<p>
+It is possible to intercept and hook in the GEOS Kernal using vectors. Here is a little example:
+<tscreen><verb>
+void (*oldVector)(void);
+
+void NewVectorHandler(void) {
+ // do something and at the end call the old vector routine
+ oldVector();
+}
+
+void hook_into_system(void) {
+ oldVector = mouseVector;
+ mouseVector = NewVectorHandler;
+}
+
+void remove_hook(void) {
+ mouseVector = oldVector;
+}
+</verb></tscreen>
+<p>
+In your <tt/main/ function you should call <tt/hook_into_system()/ but <em/after/ all calls to GEOS
+kernal (like <tt/DoMenu/, <tt/DoIcons/, etc.) - right before passing control to the <tt/MainLoop()/.
+It is critical to restore old vector values before exiting the program. If you have more than one
+place where you call <tt/exit()/ then it might be worth to register <tt/remove_hook/ function to
+be called upon exiting with <tt/atexit(&remove_hook);/ call. This way you will ensure that
+such destructor will be always called.
+<p>
+That little example above intercepts <tt/mouseVector/. The <tt/NewVectorHandler/ function will be
+called every time the mouse button changes status. Other important vectors you should know about
+are:
+<itemize>
+ <item><tt/appMain/ - this is called from within <tt/MainLoop/ system loop
+ <item><tt/keyVector/ - called whenever a keypress occurs
+ <item><tt/intTopVector/ - called at the start of IRQ routine
+ <item><tt/intBotVector/ - called at the end of IRQ routine
+</itemize>
+
</article>
#define nameBuf char[17]
#define blockBuf char[256]
-#define zpage (char*)0x0000
+#define zpage ((blockBuf)0x0000)
#define CPU_DDR *(char*)0x00
#define CPU_DATA *(char*)0x01
#define STATUS *(char*)0x90
#define curDevice *(char*)0xba
-#define irqvec *(unsigned int*)0x0314
-#define bkvec *(unsigned int*)0x0316
-#define nmivec *(unsigned int*)0x0318
+#define irqvec (*(void_func*)0x0314)
+#define bkvec (*(void_func*)0x0316)
+#define nmivec (*(void_func*)0x0318)
#define APP_RAM (char*)0x0400
#define BACK_SCR_BASE (char*)0x6000
#define VLIRInfo (*(struct VLIR_info*)0x8496)
-#define appMain *(unsigned int*)0x849b
-#define intTopVector *(unsigned int*)0x849d
-#define intBotVector *(unsigned int*)0x849f
-#define mouseVector *(unsigned int*)0x84a1
-#define keyVector *(unsigned int*)0x84a3
-#define inputVector *(unsigned int*)0x84a5
-#define mouseFaultVec *(unsigned int*)0x84a7
-#define otherPressVec *(unsigned int*)0x84a9
-#define StringFaultVec *(unsigned int*)0x84ab
-#define alarmTmtVector *(unsigned int*)0x84ad
-#define BRKVector *(unsigned int*)0x84af
-#define RecoverVector *(unsigned int*)0x84b1
+#define appMain (*(void_func*)0x849b)
+#define intTopVector (*(void_func*)0x849d)
+#define intBotVector (*(void_func*)0x849f)
+#define mouseVector (*(void_func*)0x84a1)
+#define keyVector (*(void_func*)0x84a3)
+#define inputVector (*(void_func*)0x84a5)
+#define mouseFaultVec (*(void_func*)0x84a7)
+#define otherPressVec (*(void_func*)0x84a9)
+#define StringFaultVec (*(void_func*)0x84ab)
+#define alarmTmtVector (*(void_func*)0x84ad)
+#define BRKVector (*(void_func*)0x84af)
+#define RecoverVector (*(void_func*)0x84b1)
+
#define selectionFlash *(char*)0x84b3
#define alphaFlag *(char*)0x84b4
#define iconSelFlg *(char*)0x84b5
#define config *(char*)0xff00
#define END_MOUSE (char*)0xfffa
-#define NMI_VECTOR *(unsigned int*)0xfffa
-#define RESET_VECTOR *(unsigned int*)0xfffc
-#define IRQ_VECTOR *(unsigned int*)0xfffe
+
+#define NMI_VECTOR (*(void_func*)0xfffa)
+#define RESET_VECTOR (*(void_func*)0xfffc)
+#define IRQ_VECTOR (*(void_func*)0xfffe)
#define vicbase (char*)0xd000
#define sidbase (char*)0xd400