M/C Part 26 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.