The Editor stopped me. "Waddilove," he slurred. "Christmas is coming. Do something."
After spending a week or so racking my brains trying to think of an original Christmas program I came up with Christmas Carol. It simply wishes everyone a Merry Christmas to the accompaniment of a few festive tunes.
You may be wondering where the originality is in that. Well, it's not what it does, it's how it does it.
The program demonstrates the use of interrupts by playing carols while text is printed in different directions and with various degrees of rotation.
One of the most advanced features of the Electron, and the BBC Micro as well, is the extensive use of interrupts to control many of the background operating system tasks.
An interrupt is a signal sent to the microprocessor telling it to stop what it is doing and switch its attention to something else.
When it has finished this task it returns to whatever it was doing and carries on as if nothing had happened.
These background tasks include updating the clock, used by the pseudo variable TIME, processing ENVELOPEs and maintaining the many input and output buffers and queues.
Interrupts give the impression that the Electron is capable of doing more than one thing at a time by repeatedly switching rapidly between tasks.
Interrupts must not have any effect on the interrupted program. If any of the processor's registers or flags are altered by the interrupt routine, then it will get in a terrible muddle when it returns, probably with disastrous consequences.
Acorn have thoughtfully provided the user with an easy to use, pre-packaged interrupt facility. Every ten milliseconds an interrupt is generated by one of the timers inside the ULA to transfer program control to routines to deal with the background work.
In the process of carrying out this background work a number of events may be generated, such as the interval timer crossing zero. An event handling routine can be written by the user to which control is passed when the appropriate even has been detected by the Operating System.
The Operating System detects all events but ignores them if they have not been enabled with a *FX14 command. If an event has been enabled then program execution indirects via the event vector at &220. (See Page 242 of the User Guide.)
The machine code routine in Xmas Carol is called fifty times a second, coincident with the start of certical synchronisation of the screen display, by setting the event vector to point to the start of the code, and enabling it with *FX 14,4.
When the code is called the registers and flags are saved. As only one event has been enabled there is no need to check that it is the right one.
First it is necessary to see if there is enough space in the sound buffer for the next note, otherwise the program would grind to a halt when it was full.
If there is not enough room, the regsiters are restored and the routine ends.
If there is enough room, then the next note and its length are read from the data stored at page &A and placed in the parameter block at &71. OSWORD is called to insert the note into the sound buffer.
A check is made to see if the pointer is at the last note. If it is, then it is reset to the start again. The registers are restored and the routine ends.
All this happens while the Electron is busy drawing the message on screen, giving the appearance of doing two things at once.
The print routine works by printing the letter at the bottom left hand corner of the screen, and looking at the dot pattern produced.
You can't see it as it is printed in colour 3 which is set to black, the same as the background.
By using some elementary trigonometry the dot pattern can be rotated and drawn at any position on the screen. A point I%, J% when rotated through an angle theta becomes:
An allowance has to be made for the odd shaped pixels in Mode 5 but it is fairly straightforward.
To print text round in a circle you just move to a point on the circumference x%, y% which is radius*SIN(theta), radius*COS(theta). To make the text stand outwards the angle of rotation is -theta.
The machine code is placed at &900 and the data for the carols at &A00, which are buffers used by the cassette system.
It is safe to type in and run programs while the carols are playing, but loading or saving a program may corrupt the code so it is best to disable the routine with *FX13,4.
Don't just use the program as it is. Try experiemtning with different tunes. (Lines 220, 230 and 790 must be set to the number of items in the DATA statement, 254 maximum.)
Alter the messages printed and see what happens if the size of the letters is changed.
Will it run in Mode 1? Try it and see. Alter it if necessary.
||Used as loop counters
||Messages to be printed
||Angle of letter in radians
||Angle of letter in radians
||Position of letter
||Position of letter
||Size of letter
||Work out SIN and COS function to save time
||Letter to be printed
||Pointer to next note
||Parameter block for OSWORD call
||Disable start of screen synchronisation display event. Switch off ADC channels. Read and store data for tunes. Define function keys.
||Assemble machine code routine to play carols. Set event vector to point to code. Enable event
||Print the message
||Print a character at a given angle and position
A game of strategy by John Woollard
CHRISTMAS BOX is a game of strategy designed to while away a pleasant time after a substantial Christmas dinner.
The rules are simple: Two players take turns to enter a Christmas Box into the grid by pressing a letter key from A to F.
The piles of presents build up to the top, but no further, to the accompaniment of We Wish You A Merry Christmas.
Q cuts the music, S starts it again.
The winner is the first person to get four of their presents in a straight line - vertically, horizontally or diagonally.
If you don't want to type the whole thing by hand then send off for this month's tape. If you want to learn some new techniques to aid your programming then read on.
And if you want to write a program with a structured format so that it can be changed to your requirements then start key tapping.
The program has been written so that another programmer can easily see how it works and therefore be able to change it to suit themselves.
The first nineteen lines do everything. They form the main control module.
The lines call procedures or functions in a sequence that creates the effect seen on the screen. There is a single REPEAT UNTIL loop which continues until one or other of the players has won.
After the end message has been displayed the program automatically starts again.
The program was designed to be flexible in its use. The tune can be changed by changing the values in the DATA statements of lines 1760 and 1170. The shape of the Christmas Boxes can be changed entirely by altering lines 1690 to 1720.
The shape of moving sleight is set in line 470.
Obviously, all text can be changed by changing the appropriate PROCPrint calls.
It is most important that these statements are entered accurately as mistakes may not appear as syntax errors but as spurious errors whose source is hard to determine.
Lines 1730, 1740 and 1750 contain the winning combinations. Lines 1760 and 1770 contain the notes of the tune.
||Contains the names of the two players
||Contains a value for each position on the display. Those unique values are used to determine if a player has a winning combination of Christmas Boxes
||Contains the totals of the 39 winning positions
|Contain the pitch and duration of the 54 notes of the tune that plays during the game
||A flag that starts at zero and becomes positive to show that a player has achieved a winning position
||Either 1 or 0 and indicates which player's turn it is
|k, k1, k2 ...
||General purpose counters that do not cross procedure boundaries
||Contains a string that produces the moving sleigh at the top of the screen
||Used to count through each note of the tune and determine the position of the sleigh on the screen
||Stores the value of the player's choice of letter
|I and inkey%
||Temporary stores of the result of an INKEY statement
Procedures & Functions
||Sets up the initial screen with a display of grid and title
||Dimensions all variables used, reads the DATA statements and assembles a machine code routine that creates double height characters. (That routine was described and explained in the July edition of Electron User) The initialisation procedure also contains several *FX calls which are useful in many programs. *FX 16,0 disables the analogue/digital sampling. This is an advantage only if the Plus 1 is fitted. *FX229,1 disables the action of ESC. It may be useful to set it to *FX229,0 while debugging is carried out. The other *FX calls are documented in the Electron User Guide.
||Allows the two players to enter their names and wishes them luck
||Creates an empty grid for the players to enter their Christmas Boxes
||Waits for the player to make a choice and enters the Christmas Box
||Checks to discover if that move was a winning move. If it was then win% is set to a positive value
||Displays its Christmas Greetings when the loop ends
||Waits for a letter key to be pressed between A and F. However, if Q is pressed the sound is quietened, if S is pressed then it is enabled. The procedure uses *FX210,0 to enable all sound output and *FX210,1 to disable all sound output
||An input routine that prints the inputted characters in double height to a maximum length of twelve characters
||Utilities the machine code routine created in the initialisation procedure so that whole strings can be printed in double height
|Displays a coloured shape determined by the value of shape% and colour% at a position on the screen determined by xcoord% and ycoord%