The BBC and Master Computer Public Domain Library
Flashing LEDs by Ian Wolstenholme
Or
Return To On Line Magazine
13/04/2002
FLASHING LEDs
It is generally known that the cassette motor LED on the BBC Model B can be switched
on and off with the commands *MOTOR 1 and *MOTOR 0 (or *FX 137,1 and *FX 137,0).
However, it is not generally known that the CAPS LOCK and SHIFT LOCK LEDs can
be controlled without the need to press the CAPS LOCK or SHIFT LOCK keys. *FX202
is used to control the "keyboard status", in other words whether CAPS
LOCK or SHIFT LOCK mode is engaged:
*FX202,0 CAPS LOCK & SHIFT LOCK ON
*FX202,16 SHIFT LOCK ON
*FX202,32 CAPS LOCK ON
*FX202,63 CAPS LOCK & SHIFT LOCK OFF
After any *FX202 command within a program, it is necessary to issue *FX118 to
"update" the LEDs with the new status, although the *FX202 is usually
sufficient to change the LEDs in command mode.
This feature can be used to produce a number of effects, such as making the LEDs
flash. The three program listings below demonstrate this. The first two show how
this can be achieved in BASIC and assembly language. The third program is written
in assembly language and shows how the LED flashing routine can be made to run
in the "background" thus leaving the programmer to execute other code
whilst the lights continue to flash.
PROGRAM 1
10REPEAT Set up loop
20*FX202,0 Set status to caps lock and shift lock
25*FX118 Update LEDs
27FORA=0TO1000:NEXT Pause a while
30*FX202,63 Set status to no caps or shift lock
40*FX118 Update LEDs
45FORA=0TO1000:NEXT Pause a while
50UNTIL0 Repeat forever
When this program is run, the CAPS LOCK & SHIFT LOCK lights will flash on
and off until ESCAPE is pressed. The lights can be made to flash alternately by
using *FX202,16 at line 20 and *FX202,32 at line 30.
PROGRAM 2
10REM FLASH
20REM MACHINE CODE VERSION
30REM (C) Ian Wolstenholme 2002
40REM Version 1.0 4/iv/2002
50DIM code 255 Reserve space for code
60FORA%=0TO3STEP3 Set up assembler loop
70P%=code Reset program counter to start of code space
80[OPTA% / Set option
90.flash
100LDA#229
110LDX#0 / Do *FX229,0 : ie. enable ESCAPE key
120JSR&FFF4
130.flashloop
140LDA#202
150LDX#0 / Do *FX202,0 : ie. caps lock + shift lock on
160JSR&FFF4
170LDA#118
180JSR&FFF4 / Do *FX118 : ie. update LEDs
190JSRwait / Jump to routine to pause
200LDA#202
210LDX#63 / Do *FX202,63 - lights off
220JSR&FFF4
230LDA#118
240JSR&FFF4 / *FX118
250JSRwait / Jump to routine to pause
260CPX#240 / Check if ESCAPE is pressed
270BNEflashloop / If not, back to flashing loop
280LDA#15
290LDX#0 /*FX 15,0 : clear keyboard buffer
300JSR&FFF4
310LDA#229
320LDX#0 / *FX229,0 : enable ESCAPE key
330JSR&FFF4
340RTS / Return to BASIC
350.wait
360LDA#0
370LDX#0
380.loop
390INX / Routine to pause until next
400CPX#0 / change of LED - waits until counted
410BNEloop / to 65536
420INC A
430CMP#0
440BNEloop
450LDA#121
460LDX#240 / Check if ESCAPE pressed
470JSR&FFF4
480RTS / Back to main routine
490] End of code
500NEXT Do second pass
When RUN, CALL flash will run the code - this again will flash the keyboard LEDs
until ESCAPE is pressed.
PROGRAM 3
The following program causes the keyboard LEDs to flash in the background, returning
control to the user whilst the lights continue the flash. This is not of great
practical use if the program is simply typed in and run as it will be difficult
to enter any commands at the keyboard as CAPS LOCK and SHIFT LOCK are constantly
going on and off! However, this routine could be used within a program to make
the lights flash whilst the computer is running a different bit of code.
The program intercepts the Event vector to check for a vertical synchronisation
event. When enabled, a vertical synchronisation event is generated by the computer
50 times a second. The routine below counts up to the fiftieth vertical sync and
then changes the lights to achieve a flash at one-second intervals. The timing
of the flashing can be altered by changing the values at lines 130 and 150. Although
an interval timer event is provided which could be used to wait for the appropriate
length of time, it is much simpler to write code which checks for every 50th vertical
sync than to deal with the interval timer.
10REM FLASH USING V.SYNC EVENT
20REM (C) Ian Wolstenholme 2002
30REM Version 1.1 13/iv/2002
40DIM code 255 Reserve space for code
50FORA%=0TO3STEP3 Set up assembler loop
60P%=code Reset program counter
70[OPTA% Set option
80.event
90PHA:PHX:PHY:PHP / Save all registers
100CMP#4 / Check for vertical synchronisation
110BNEend2 / If not, goto end2
120LDAcounter
130CMP#50 / Check for 50th vertical sync
140BEQflashon / If yes, goto flashon
150CMP#100 / Check for 100th vertical sync
160BEQflashoff / If yes, goto flashoff
170.end
180LDAcounter
190INC A / Increase vertical sync counter by 1
200STAcounter
210.end2
220PLP:PLY:PLX:PLA / Restore all registers
230RTS / Return
240.flashon
250LDA#202
260LDX#0
270LDY#0 / *FX202,0
280JSR&FFF4
290LDA#118
300JSR&FFF4 / *FX118
310JMPend / Goto end
320.flashoff
330LDA#202
340LDX#63
350LDY#0 / *FX202,63
360JSR&FFF4
370LDA#118
380JSR&FFF4 / *FX118
390LDA#0
400STAcounter / Reset v. sync counter
410JMPend Goto end
420.counter EQUB0 / Reserve a byte for v. sync counter
430]
440NEXT Next pass
450?&220=event MOD256
460?&221=event DIV256 / Set event vector to start of code
470*FX14,4 / Enable v. sync event
When run, the LEDs begin to flash as line 470 enables the vertical synchronisation
event. *FX13,4 would disable vertical sync events and should be used to stop the
flashing without having to press BREAK.
NOTE: If the computers memory is altered in any way after this program is run
(e.g. new variables declared or program lines entered or altered) this will cause
the computer to crash as the code which the event vector points to will be overwritten.
If it is intended to run the program as it stands, the code should be assembled
at a safe area in memory which is not easily overwritten, e.g. &B00. To do
this, delete line 40 and change 60 to "P%=&B00".
A more practical use for this routine might be to allow the LEDs to flash whilst
the computer is busy dealing with another routine, the lights flashing to show
the user that something is happening. Such a routine could be sandwiched between
a *FX14,4 command at the beginning and *FX13,4 at the end.
Ian Wolstenholme
13/iv/2002
Or
Return To On Line Magazine