From 70164965648d22d5064e5c99bdee5ea5e2d0863c Mon Sep 17 00:00:00 2001 From: izydorst Date: Mon, 16 Jun 2003 20:43:13 +0000 Subject: [PATCH] clean vector intercepting, added info about that to docs git-svn-id: svn://svn.cc65.org/cc65/trunk@2221 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- doc/geos.sgml | 67 ++++++++++++++++++++++++++++++++++-------- include/geos/gstruct.h | 2 ++ include/geos/gsym.h | 40 +++++++++++++------------ 3 files changed, 77 insertions(+), 32 deletions(-) diff --git a/doc/geos.sgml b/doc/geos.sgml index efbb6e19a..61e4f837e 100644 --- a/doc/geos.sgml +++ b/doc/geos.sgml @@ -6,7 +6,7 @@ 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. @@ -94,7 +94,7 @@ The software needed: 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> @@ -129,7 +129,7 @@ everything together. <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> @@ -806,7 +806,7 @@ hang on disk access. Use safe, large numbers. Note that safe IEC range is 8-31. <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)/ @@ -1247,7 +1247,8 @@ This calls system's <tt/Panic/ handler - it shows dialog box with message 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). @@ -1280,7 +1281,7 @@ but by calling this function you are sure that the results will be always differ <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. @@ -1332,7 +1333,9 @@ This structure describes a font in one pointsize. There is current font - <tt/st 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> @@ -1446,10 +1449,10 @@ just in the content. 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> @@ -1583,9 +1586,47 @@ void example = { (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> diff --git a/include/geos/gstruct.h b/include/geos/gstruct.h index 5535b9abe..85e03d317 100644 --- a/include/geos/gstruct.h +++ b/include/geos/gstruct.h @@ -17,6 +17,8 @@ #ifndef _GSTRUCT_H #define _GSTRUCT_H +typedef void (*void_func) (void); + struct f_date { /* date in filedesctiptor */ char f_year; char f_month; diff --git a/include/geos/gsym.h b/include/geos/gsym.h index da32bda93..dd1bcad4c 100644 --- a/include/geos/gsym.h +++ b/include/geos/gsym.h @@ -15,7 +15,7 @@ #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 @@ -85,9 +85,9 @@ #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 @@ -118,18 +118,19 @@ #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 @@ -188,9 +189,10 @@ #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 -- 2.39.5