Machine Code Made Easy - Part 25
Author
Description
From Fred 36
Hello, and welcome to part 25 of the ol' column. That's right.
TWENTY FIVE!!! I CAN COUNT!!! Ahem.
This is the second part of the Driver Special; last month I
discussed how Driver works, and started on modes 0, 1 and 2:
WIMP and menu modes.
In a momentary lapse of concentration I failed to mention the
exact flags for menu options:
D0 Set if the option is "on".
D1 Set to run a routine on selection.
D2 Set to open a sub-menu.
D3 Set to toggle a flag.
D4 Set to indicate that the option is simply a line.
Note that if you want an option to display a flag, but to run a
routine when selected, you simply set both D1 and D3.
Right, now that that's straight, let's continue with
MODE THREE: DIALOGUE MODE
Now, this is good. When you want your application to converse
with the user, you can open up a special window (without any of
the normal window gadgets) called a dialogue box. Now, you can
fill the box with a variety of its own gadgets, in a shorthand
form which lets you create quite complex structures without any
coding.
In your application, the data for a box looks like this:
0-1 x coord (0-255), y coord for top left of box.
2-3 x size (fat coords), y size.
4 "Reprint screen" flag. One byte, either 0 or 1.
A value of 1 will reprint the screen when the box
is closed.
5-6 Vector. See below.
7-end Gadget data.
end Terminating FFh byte.
The vectored address gets constantly called when the box is
open, to make provision for some sort of background tasking
using a dialogue box. For example, you could have a box with
some sort of meter indicating how much of a file there is left
to load/ print, while the thing is loading or printing. In
nearly all situations the vector is zero, meaning no call.
Entry to the vector is:
A = 1/0 if the box is/isn't being closed.
B = 0 - CANCEL
1 - OK (for when it is being closed)
Return the same registers with the same values, or change the
values if you want.
Note that the vector address is bit 15 dependant - see Vectors
later on.
The Gadgets.
There are 8 dialogue box gadgets which should provide for every
eventuality. The data for each consists of a number 0-7 followed
by some parameters: (You just list them end to end; type,
parameters, type, parameters.... FFh)
0 - Button: A 32x16 sized box with curved edges and a bit of
text inside (up to 9 characters - the text is centred
automatically). You can assign a flag to it, so it can be on and
off. When it is clicked, a routine is run (see notes below).
Examples of buttons I use? OK, CANCEL, CONTINUE etc..
1-2 relative coords
3-4 flag address
5 flag-on value
6-7 address of routine to call when button clicked
8-9 address of text to put inside. (Text ends with
FFh)
10-11 address of active-flag. If the byte at that
address is 0 the gadget is inactive and cannot be
clicked.
1 - Text: Simply a bit of text in the box.
1-2 relative coords
3-4 address of text (ends with FFh)
5-6 address to find colour.
(No click response)
2 - Text box: Similar to using INPUT in a BASIC program. Just
put the text in a workspace (see below) and look at the
workspace afterwards to see what the user has typed/ changed. A
variety of uses, the main one being the entry of file names and
the like.
1-2 relative coords
3 workspace no (0-7)
4-5 active-flag address (see above)
3 - Number box: Similar to text boxes, except that it only
allows the entry of numbers between 0 and 65535. It needs a
temporary workspace, but you set it up with a variable (2 bytes
of course) and look at the variable afterwards. Uses? Things
like setting page ranges and so on.
1-2 relative coords
3 workspace no (0-7)
4-5 active-flag address (see above)
6-7 variable address
4 - Icon: A rectangular symbol. Make sure it's on a white
background like the rest of the dialogue box. I normally use one
to represent the purpose of the dialogue, like "attention" and
"information" symbols.
1 internal page no. (0 to use application/ driver
data)
2-3 address of icon data (D15 = 0 to use
application
D16 = 1 to use page no.
above)
4-5 size (x,y)
6-7 relative coords
7-8 active-flag address (see above)
No click response.
5 - Switch: A bit like buttons, but more like flag menu options.
A switch consists of a little square with or without a cross in
it (on or off) which you can click, followed by a text label.
Like flag options, you can make the on/off values the same, so
that clicking merely selects it, or you can make them different
so that clicking toggles it on/off.
1-2 relative coords
3-4 text address
5-6 flag address
7 flag-on value
8 flag-off value
9-10 active-flag address (see above)
6 - User: Provided to let you design your own gadgets. When the
user clicks it your routine is called (see notes below). I use
it, together with text, icon and box gadgets to make scroll
boxes which look complex but are build out of only these four
gadgets.
1-2 relative coords
3-4 size (x,y)
5-6 routine to call when gadget clicked.
Nothing printed on screen.
7 - Box: Simply a rectangle drawn in the dialogue box.
1-2 relative coords
3-4 size (x,y)
No click response.
Notes
* If a gadget is "inactive" is is displayed faded and cannot be
selected. You can use this "active-flag" facility to activate,
say, a text box when a switch is toggled on, or simply use it to
ignore options that aren't available.
* Button routine entered with B = gadget no. (0 being the first
in the list). Zero flag set if button is on.
Return A = 0 - no response.
1 - reprint gadgets in box. (If your routine has
changed flags)
2 - close box OK
3 - close box CANCEL
* Colour for text gadget: D0-D1 = paper col. (0-3)
D2-D3 = pen col. (0-3)
* User gadget: Click routine entered with A = gadget no. DE =
gadget's relative coords within dialogue box. BC = click offset
within gadget.
When I use a register pair to pass coordinates or size, the lsb
is for x, the msb for y. eg. When I use DE to pass coords (as I
often do), E holds x coords, D holds y. To convert this to a
screen address in upper memory do:
SCF
RR D
RR E
Simple, eh?
* There are 8 workspaces for text and number boxes, found in the
Driver data page at an offset of 3800h. Each is 256 bytes long.
You only need to deal directly when using text boxes; you copy
the text in before opening the box (with a terminating FFh
byte), and copy it back when the box gets closed. In fact, all
the text mentioned above uses FFh to terminate.
ADDRESSING
Now, a note on addressing. Your application program runs in
lower memory, and pages data into upper memory. However, to
distinguish addresses in your application from addresses in
Driver and the File Manager (which also run in lower memory),
you have to set bit 15 of the address. In effect, you add 8000h
to it.
This applies to all the above variable, flag, text and routine
addresses except that for icons. It also applies to the menus
mentioned last month.
When you want to interface with Driver, you page it into upper
memory, and when it wants to interface with your application it
pages itself into upper memory. So, although your routine
addresses might have D15 set, they get run in lower memory, and
you must ensure that Driver is paged into sections C and D when
you return.
Also, Driver keeps track of the application stack as well as its
own, so you don't have to worry about that at all.
VECTORS
As mentioned previously, Driver runs in parallel with your
application, using the frame interrupt. Well, there are
occasions when you need to intervene in Driver routines. This is
done by by using vectors in a similar way to the ROM. Because
writing Driver applications is a tad confusing at first, I tried
to use things you'd all be familiar with.
For those of you who aren't too sure about vectors, they are
simply variables which hold the address of a routine to call in
certain situations. If you don't want to use the vector you
simply put 0 in the vector.
Again, make sure that all the addresses are "high" (with bit 15
set).
There is a table of application vectors inside Driver, and you
set these up when your application is opened. If you want, you
can actually set them again to change the values, but they must
all be changed together.
There are 17 vectors in version 1.0 of Driver:
0. Close window: Called when a window close gadget has been
clicked. (Not window 0, the application desktop)
Enters A = window no.
Return CY set to keep the window open.
1. Print window: Called during the construction of a window on
the screen, after clearing space and drawing the frame. You're
supposed to print the window contents and return, whereupon the
gadgets are added. There are helpful routines for putting text
and graphics in window, more of which next month.
Enters A = window no.
BC = size. (Remember, lsb (C) = x, msb (B) = y)
DE = coords.
B'C' = scroll bar positions.
2. Click: Called when a window interior has been clicked (not a
gadget). You're supposed to run the necessary routine(s).
Enters A = window no.
BC = scroll bar positions.
DE = click offset within window, after adjusting for the
name/ menu/ frame.
3. Short-cut key in WIMP mode: Called after the user presses
CNTRL with another key (with or without SHIFT/ SYMBOL). This
lets you provide short-cuts for things like open/ save/ print/
underline etc.
Enters A = key no. (from SAM keyboard map in p180 of Users
Guide)
+70 for SHIFT
+140 for SYMBOL.
4. Reserved.
5. Close application: Enters after application desktop closed.
You can use it to run a dialogue box, save changes to a file or
whatever.
Return A = 0 (close) or 1 (don't)
6. New window: Called when an active SAW is closed (after the
close window vector). You can use it to provide the number of
the new active SAW. I used it in the file manager to save
changes to folders.
Enters A = window no.
Return A = new active SAW.
If the vector is 0 (no routine) the next SAW on the screen is
used.
7. Move window: Called when a window is moved. You can use it to
adjust the position, or to keep track of it. (Although the
position of windows is held in a table, documented last month)
Enters A = window no.
BC = size.
DE = new coords.
Return DE = new coords.
8. Resize window: As above, but called after the window's size
is changed.
Enters A = window no.
BC = new size.
DE = coords.
Return BC = new size.
9. New SAW: Called when a new SAW is activated by clicking it. I
used it to do things like save folder attributes.
Enters A = new active SAW.
B = old active SAW.
10. Pointer. This is nice. It gets called every frame in WIMP
mode, and lets you change the image used for the pointer
depending where it is. For example, IconMaster uses a cross in
the editing window and Notepad uses a funny wee "I" thing (I
think it's called a caret) in the text window.
Enters A = window pointed to.
DE = adjusted relative coords. (Just like the click
vector, although you get negative y values for the
name/ menu bar)
BC = window size.
Return A = page of graphic (0 for application/ Driver data)
HL = address of new pointer to use. If D7 of H is set,
Driver data page is used.
OR A=H=0 for no change.
11. Scroll up: Called when the scroll-up window gadget is
clicked.
Enters A = window no.
B = current scroll bar position (0-255)
C = 0 for step, 1 for page.
Return B = new position.
12/13/14. Scroll down/left/right: As above.
15. Mouse scan: Use this to bypass Driver's own scan. You might
want to in a graphics package using mode 3 "thin" pixels,
although Driver still uses fat ones, so the pointer is still
working from 0-255.
Enters DE = pointer coords
Return DE = new pointer coords.
16. Pointer speed. Use this to change to speed of the pointer
when key control is in use. (ie. no mouse). The normal speed is
2 pixels per frame in both directions. The vector is called
before the coords are changed in WIMP mode. I used it to change
speed to 1 pixel per frame when more acuracy was needed in
IconMaster and Preferences.
In fact, I stored the window num from the Pointer vector, and
used that to judge which speed was needed: slow in the editing
window, fast elsewhere.
Enters BC = normal speed (0202h)
Return BC = speed to use.
NB. The key scanning is still done by Driver.
That's the 17 vectors in version 1.0, but I would suggest
leaving about 20 zero bytes afterward, to ensure compatibility
with later versions.
You should also make sure that Driver is paged into upper memory
before returning, and remember that the stack is taken care of.
Right, that's yer lot for yet another month. Next time round
we'll do the jump table and other bits and pieces. Bet you can't
wait!!!