★ CODING ★ LISTINGS ★ Bytes and Pieces ★![]() |
| Byte and Pieces (The Amstrad User #6) | Coding Listings |
Useful Machine Code Routines from Sydney Brown This month I will present you with some short but very handy machine code routines which you can add to your own programs. I have included the source code for each routine which may help you to understand how each one works, as well as a BASIC loader which will allow you to experiment. The loader can be found at the end of this article and, as its name suggests, provides the BASIC code necessary to load each routine. Merely select the relevant lines of code for insertion into your own programs, or run the complete program to experiment. The machine code routines are held in the data statements in hexadecimal form Routine # 1 COPY SCREENThis routine will copy the screen into a second 16k block of memory located at 4000H which can be useful to re-display a title page at game over or reset the game background after it has been corrupted. |
| Mode 0 | Mode 1 | Mode 2 | |
| Left Pixel | bits 1,5,3,7 | bit 3,7 | bit 7 bit 6 |
| bit 2,6 | bit 5 bit 4 | ||
| bits 0,4,2,6 | bit 1,5 | bit 3 bit 2 | |
| Right Pixel | bit 0,4 | bit 1 |
_
Each byte in mode 1 is split into four two bit binary numbers, this allows you to select up to 4 stripes per byte in any of the four set colours:
00=lnk0 01=Ink 1 10=Ink2 11=Ink3 So if you are in mode 1 and want a solid yellow area, you would select as follows:
Yellow is the default colour for ink 1 or 01 in 2 bit binary so Yellow, Yellow, Yellow, Yellow = 01-01-01-01. However, each 2 bit number is REVERSED giving 10-10-10-10.
The reversed byte is broken into bit pairs, namely 7 and 3, 6 and 2, 5 and 1, and 4 and 0, giving a new bit pattern of 11-11-00-00.
The diagram below may help you to understand.
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
| 1 | 0 | |||||||
| 1 | 0 | |||||||
| 1 | 0 | |||||||
| 1 | 0 | |||||||
| - | - | - | - | - | - | - | - | - |
| 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 |
11110000 Binary = F0HEX = 240 Decimal
Try these others:15, 201, 252, 255.
Poke the new colour and boundary values directly into the program, variables have already been set up in the demonstration program/Basic Loader.
COL = Colour of encoded ink to fill with.
TOP = Top character row included in block.
BOT, LFT and RIT set the other sides.
Routine #5
You will get a failed read unless either the pen or paper of the character is the same as the current pen or paper. You can select the position to check by moving the cursor with the normal LOCATE X,Y command.
Routine #6
This routine can be used to save any size block up to a theoretical 64k with very little modification.
Routine #7
In both routines the sync byte is #16 Hex which represents a data block and #2C Hex represents a header block.
Have cassette deck ready before calling these routines as no PRESS KEY message is displayed.
The accompanying program loads and sets up all the previous routines, once run the program will stop and you can experiment with the different effects.
In the GET MODE and GET CHARACTER routines you must initialise the variable you are going to use before you call and you must also make sure that the variable is defined as an integer as the machine code routine requires its particular storage format to return the correct value.
All of the routines contain default values to prevent chaos if run without placing the required values in the programs.
Each routine can be used separately, and can be placed anywhere in memory, just remember to set HIMEM with the MEMORY XXXXX command and set the call label to HIMEM+1.
Remember you can experiment with any of these routines, change values and produce a program to suit your own needs but take care as you may destroy your program or anything in memory, but as long as you save your routines first there is no lasting damage as you can not physically destroy anything in your Amstrad with pokes or machine code.
The whole program could be made to take up much less memory by removing the REMS and making the machine code routines run consecutively in memory, I spaced them out for the sake of clarity.
I have used the following variable names in the Demonstration program but you can allocate any names you wish as long as you set them to equal the start of the chosen routines.
CALL CHAR Gets character from screen.
CALL SMODE Gets current Screen Mode.
CALL COPY Copies Screen to Ram.
CALL RESET Copies Ram to Screen.
CALL SSAVE Screen Save in one 16k Block.
CALL SLOAD Loads Screen in one 16k Block.
CALL FILL Fills Rectangular area with colour.
The variables TOP, BOT, LFT, RIT and COL are related to the fill routine.
Poke COL with encoded colour.
Poke TOP with top character row.
Poke BOT with Bottom character row.
Poke LFT with left column of area.
Poke RIT with Right column of area.
All poke values related to the fill routine are inclusive.
e.g. if you poke TOP with 2 and BOT with 7 then the block will be 6 characters high, 2 to 7 inclusive.
I am not quite sure what is causing the problem but if you try to put a 1 into TOP then you miss a bit of the top line of the block, it seems to be a fault somewhere in the Firmware routine.
| ![]() |
|