As a professional applications programmer, I generally work on either an IBM XT/AT or a UNIX workstation. When several years ago Sinclair USA offered me a great deal on some new QLs, I jumped at the chance to own a machine capable of multitasking and I ordered several. After some experimentation, I added 512K of extra memory, disk drives, and a suitable user interface. Given the wide range of languages available and the ability to remove a program gone bad without having to re-boot the machine, made the QL an excellent machine to develop and test new software on. One thing that I found to be a minor annoyance was the lack of a capslock indicator. I was forever having to re-enter code that was typed in the wrong case, simply because I forgot which state the capslock was in. The program in the listings below was written to correct this situation.
The program CAPS is presented in two formats, an assembler listing for those with a 68000 assembler and a SuperBASIC program for those who don’t. Listing 1 is the assembler listing and was written for the METACOMCO (r) MACRO ASSEMBLER. I have kept away from the macro function or special assembler directives, so the program should port easily to other assemblers. CAPS takes advantage of the systems multitasking ability to monitor two of the systems variables, SV_ARBUF(the autorepeat buffer) and SV_CAPS(the capslock flag), and control a text message to a small window. The program is written in four sections, the first being the program header. This header starts with a branch to the start of the program followed by an illegal op-code used by the system to identify the location of the job name. Lastly this is followed by the job name and if needed a pseudo-op to align the code to a long word boundry.
The next section is program initializion, first setting job priority to 1(the lowest available) so the job runs in the background. Next we open a window one character high by 4 characters long in the upper right side of the screen. Finally we set the character size to the smallest (0,0).
The next two sections are a pair of interconnected loops. The first loop starts by clearing the window and then checks SV_ARBUF, the autorepeat buffer, to see what the last key pressed was. If the last key pressed was ^Q (CTRL Q) the program then exits, removing itself from the job scheduler. Next the program looks at SV_CAPS, the capslock flag, and if flag is cleared then branch to LOOP and clear the window again. If SV_CAPS is not cleared, then the cursor is set to the first print position and write the word CAPS in the window. The program then branches back to LOOP2 and checks SV_ARBUF and SV_CAPS.
LISTING #1
*
* CAPS -- A program to monitor the capslock key and print
* an indicator message to the screen when the
* capslock is set....
*
* Copyright 1988 H. J. MicroSystems. All Rights Reserved.
*
* License is granted for all non-commercial use of this
* program.
*
MYSELF EQU -1
MT_FRJOB EQU $05 ;remove job
MT_PRIOR EQU $0B ;set priority
SD_POS EQU $10 ;position cursor
SD_SETSZ EQU $2D ;set character size
SD_CLEAR EQU $20 ;clear screen
UT_SCR EQU $C8 ;setup window
UT_MTEXT EQU $D0 ;write text
SV_CAPS EQU $28088 ;capslock flag (word)
SV_ARBUF EQU $2808A ;autorepeat buffer (word)
*
* Program header
*
BRA.S CAPS ;branch to program start
DC.L 0
DC.W $4AFB ;program locator code
DC.W 4
DC.B 'CAPS' ;program job name
CNOP 0,4 ;align to long word
*
CAPS:
MOVEQ #MT_PRIOR,D0 ;set priority to lowest
MOVEQ #MYSELF,D1
MOVEQ #1,D2
TRAP #1
*
LEA SCR,A1 ;create window in upper
MOVE.W UT_SCR,A2 ;right corner of screen
JSR (A2)
BNE ERROR ;if D0 not equal to 0 error
*
MOVEQ #SD_SETSZ,D0 ;set char size to
CLR.W D1 ;smallest size
CLR.W D2
MOVEQ #-1,D3 ;no timeout
TRAP #3
*
LOOP:
MOVEQ #SD_CLEAR,D0 ;clear window
MOVEQ #-1,D3
TRAP #3
*
LOOP2:
MOVE.L #SV_ARBUF,A1 ;fetch last key pressed
MOVE.W (A1),D2
CMPI.W #17,D2 ;exit if ^Q
BEQ.S BYE
MOVE.L #SV_CAPS,A1 ;fetch capslock flag
MOVE.W (A1),D0
BEQ.S LOOP ;if clear, clear window
*
MOVEQ #SD_POS,D0 ;set cursor to 0,0
CLR.W D1
CLR.W D2
MOVEQ #-1,D3
TRAP #3
*
LEA MESS1,A1 ;write indicator message
MOVE.W UT_MTEXT,A2
JSR (A2)
*
BRA.S LOOP2 ;loop and test
*
BYE:
CLR.L D0 ;no error
*
ERROR:
MOVE.L D0,D3 ;remove THIS job
MOVEQ #MT_FRJOB,D0
MOVEQ #MYSELF,D1
TRAP #1
*
SCR:
DC.B 0 ;no border
DC.B 0
DC.B 0 ;paper color black
DC.B 7 ;ink color white
DC.W 30 ;window dimentions
DC.W 12
DC.W 448 ;window location
DC.W 0
*
MESS1:
DC.W 4 ;indicator message
DC.B 'CAPS'
END
Listing 2 is a SuperBASIC program to generate the program CAPS and is presented for those readers who don’t have access to an assembler. This program reads the code (in word format) in the data statements and pokes it into a section of reserved memory. Then if the checksum matches, the program is then saved as a transient program.
To use the SuperBASIC version, you must reset or turn on your QL and type in the program in listing 2. After saving the code, run the program with a tape in mdv1 (line 280 may be changed for a different drive or filename). If an “ERROR IN DATA STATEMENTS…….” error occurs, add up the numbers in each line with a DATA statement and compare with the checksums listed below:
LINE 290 110252 LINE 300 130401 LINE 310 168020 LINE 320 108718 LINE 330 152682 LINE 340 118648 LINE 350 129694 LINE 360 38274
CAPS runs in 4 color (monitor) mode only as written, but the assembler version may be modified to run in any mode and any position. Feel free to experiment with it. To run CAPS enter exec mdv1_caps into your boot file or load whenever you need a capslock indicator. To deactivate CAPS, press <CTRL Q>. A note to QRAM users, this program makes use of destructive windows and to operate correctly with QRAM you will have to run the unlock utility on it. Have fun and happy computing.
H. F. Jastrzembski
LISTING #2
100 REMark ********** CAPS_BAS ************
110 REMark A BASIC program to provide a capslock indicator.
120 REMark
130 REMark Copyright 1988 H. J. MicroSystems
140 REMark License is granted for all non-commercial use of this program.
150 REMark
160 baseaddr = RESPR(200)
170 addr = baseaddr:checksum = 0
180 RESTORE 290
190 FOR inx = 1 TO 64
200 READ a
210 POKE_W addr,a
220 checksum = checksum + a
230 addr = addr + 2
240 END FOR inx
250 IF checksum <> 956689 THEN
260 PRINT#0,"ERROR IN DATA STATEMENTS......":STOP
270 END IF
280 SEXEC mdv1_caps,baseaddr,128,32
290 DATA 24590,0,0,19195,4,17217,20563,28683:REMark 110252
300 DATA 29439,29697,20033,17402,84,13432,200,20114:REMark 130401
310 DATA 26112,66,28717,16961,16962,30463,20035,28704:REMark 168020
320 DATA 30463,20035,8828,2,32906,13329,3138,17:REMark 108718
330 DATA 26400,8828,2,32904,12305,26594,28688,16961:REMark 152682
340 DATA 16962,30463,20035,17402,32,13432,208,20114:REMark 118648
350 DATA 24786,17024,9728,28677,29439,20033,0,7:REMark 129694
360 DATA 30,12,448,0,4,17217,20563,0:REMark 38274
370 STOP
ED NOTES: Here is how I made this program work. 1. Typed in listing 2. 2. Saved it to mdv1 by <save mdv1_caps_bas>. 3. Ran the program with <RUN ENTER>. 4. A program was automatically SAVED. Later investigation revealed the saved program name was “caps”.
Looking at the listing of the caps_bas program, line number 280 does the SAVE of the code generated in the data statements. The < SEXEC MDV1_caps > command is on page 54 of the KEYWORD Section of the user manual. The short CODE program may be run with the EXEC command. Page 21 of the manual says that EXEC will execute a series of stored programs “IN PARALLEL” ( hmmm ).
EXPERIMENT: I have a disk that I put all four of the PSION softwares in for faster boot up in FLP1_. The QUILL boot program was re-named “QBOOT”. The other PSION boot programs were saved as “Dboot, Sboot, and Gboot. So much for the scenario. So, the next series of steps were accomplished: The objectives will become apparant soon.
5. <copy mdv1_caps to flp1_>. 2. <load flp1_Qboot> This loaded in the Quill Boot program (without running it). 3. <EDIT 1>. This brought line 1 of the Quill boot program to screen bottom, where the line was changed to: (1 CLEAR: flp_use mdv: EXEC MDV1_caps >. The modified line was re-entered. 6. <DELETE flp1_Qboot> then <SAVE flp1_Qboot>. This eliminated the Quill boot program in disk so that the amended Quill boot program could be saved. (without a toolkit). Then it was saved.
7. <lrun flp1_Qboot>
Paydirt! When Quill came up running, a little black box appeared in the upper right hand corner of the screen. Toggling Caps Lock during Quill operation fills the block with “CAPS”, a running indicator of the CAPS Lock switch. Maybe this is not so useful in Quill, but I can see where it would be for the other three PSION programs, and many others.
While Hal’s Caps Lock indicator was designed to aid programmers while keying in code, it can be useful to have on a flp or mdv for use in programs. All we need do is edit a program line of any program and install <EXEC mdv1_caps> in the line of programming.
But I believe that “caps” gives us something else of importance as well. Isn’t this an excellent demonstration of “multitasking” and how to achieve it? Here we have the Quill software working, and all the time the “caps” program is also working, checking for Caps Lock condition and displaying the status on screen. For more on Multitasking see page 41 of the Concepts section of the QL manual. Want to multi-task another program with Quill? If so, do the Clock program on page 42.
(The PSION disk arrangement works well for me, but the <flp_use mdv> locks out Micro Drive until the reverse programming is used <flp_use flp>.)
THANKS HAL, and get off of that IBM as often as you can to do more neat utilities for us!! We appreciate! _BJ-
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.