clean vector intercepting, added info about that to docs
git-svn-id: svn://svn.cc65.org/cc65/trunk@2221 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
b50ac78a2a
commit
7016496564
3 changed files with 77 additions and 32 deletions
|
@ -6,7 +6,7 @@
|
|||
|
||||
<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.
|
||||
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue