home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
alib
/
d1xx
/
d133
/
overscan.lha
/
Overscan
/
Overscan.doc
< prev
next >
Wrap
Text File
|
1988-03-13
|
6KB
|
129 lines
(overscan.doc)
Overscan
----------
By Ari Freund - 20/11/87
General
Patches up the Intuition library so that sizable windows with MaxHeight = 200
(or 400 in lace), and screens with Height = 200 (or 400 in lace) will take
advantage of the PAL overscan capability of Intuition V1.2.
To install the patch type: overscan
To remove it type: overscan delete
Compile and assemble using Aztec C V3.40a: cc overscan.c +C +D
as overscan_lib.asm
Create a library file using the librarian: lb overscan.lib overscan_lib.o
Link using Aztec C V3.40a: ln +S overscan.o overscan.lib c.lib
You may also execute the overscan.make file.
Detail
'overscan' patches the Intuition jump vectors to OpenScreen() and OpenWindow()
and points them to its own functions: screenpatch() and windowpatch().
These functions check if apropriate, and if so, change the Height/MaxHeight
member in the NewScreen/NewWindow structure to STDSCREENHEIGHT and send
the structure to Intuition to do the openning. 'Apropriate' in this context
means that the screen/window is not a super/custom bitmap, that its intended
Height/MaxHeight is 200 (or 400 for lace), etc. Note that with screens the
patch actually causes a larger screen to open, whereas with windows it only
allows the resizing of it to the full height of the screen but the initial
window opens at its intended size.
Before changing Intuition's vectors, overscan saves the original vectors
at data.oldscreen and data.oldwindow. After doing its thing, each function
(screenpatch() and windowpatch()) calls its respective vector to get Intuition
to do the openning job. screenpatch() also uses IntuitionBase.
In order for the patch functions to stay around after overscan finishes
and exits (and gets unloaded), the segment containing the functions
and the relevant data (IntuitionBase, oldscreen, oldwindow, etc.) is
disconnected from overscan's SegList, so that when it (overscan) exits,
they are not unloaded. A BPTR (data.myseg) to the segment is also left behind.
Since overscan has the capability to delete the patch and restore
Intuition to normal, it must be able to find the segment left behind
from the invokation of overscan which installed the patch. Thus, when
installing the patch, overscan adds a public message port (data.port)
to the system's message port list. In addition, the name of this port is
also left behind.
In order to avoid unloading the patch by one task while another is using it
to open a screen/window, each time either routine is entered it increments
the in_use count variable by one. When the routine exits it decrements the
count. When 'overscan' is called to delete the patch it first checks to see
if the patch is in use (in_use!=0), and only if not does it delete the patch.
This greatly reduces the danger of deleting the patch while it is in use.
However, it does not eliminate this possibility entirely. If the patch is
unloaded after the 68000 has executed the 'jmp' instruction in Intuition's
vector table (called by a task attempting to open a screen/window) but before
it had a chance to execute the first instruction in the patch (increment
the in_use count) the system may crash. A similiar thing may occur between the
'decrement the in_use count' and the 'rts' instructions at the end of both
routines.
Thus when 'overscan' has finished installing the patch
and has been unloaded, the following items remain:
struct myvars {
struct MsgPort port; /* the message port */
BPTR myseg; /* BPTR to one of the segments */
ULONG oldscreen; /* the original Intuition vectors */
ULONG oldwindow;
ULONG in_use; /* count of tasks using the patch */
} data;
struct IntuitionBase *IntuitionBase; /* pointer to Intuition */
char myname[]="<the port's name>" /* the message port's name */
void screenpatch()
{
... mainpulate the NewScreen struct ...
... call Intuition via data.oldscreen ...
}
void windowpatch()
{
... mainpulate the NewWindow struct ...
... call Intuition via data.oldwindow ...
}
Note that the both the data and the code for the routines reside in one (CODE)
segment. This is done for the sake of compactness.
In order to avoid clashes between tasks using the patch simultaneously
I have written the patch in assembly language. The patch only alters
scratch registers (a0/a1/d0/d1) and saves intermediate values on the
stack.
Before returning to the caller, after possibly altering the Height/MaxHeight
member, each routine restores the Height/MaxHeight member to its original value.
This way the calling program gets back exactly the same NewScreen/NewWindow
structure it sent to Intuition.
When 'overscan' is invoked to remove the patch, it FindPort()'s data.port.
At fixed offsets from data.port it finds the addresses of Intuition's
routines (data.oldscreen and data.oldwindow) and puts them back
in Intuition's vector table. It RemPort()'s the data.port and using myseg,
which too is at a fixed offset from data.port, chains the segment to the
end of its (overscan's) SegList. 'overscan' then simply exits and lets DOS
unload itself (overscan) together with the patch. You can now appreciate why
myseg, port, oldscreen, and newscreen were placed together in a single structure
(data). This was done to ensure that these variables will be compiled at this
precise order relative to the message port.
In order to isolate the patch from the installing/deleting function
(main()), it is necessary to assemble it seperately and then link
it as a library to main() using the +S option, which will cause the patch to
reside in a different segment than main()'s. Compilation of overscan.c
with the +C and +D options is necessary so that code and data references
be compiled as absolute mode references, which is essential for correct
operation of the patch routines.
________________________________