★ APPLICATIONS ★ PROGRAMMATION ★ AMSTRAD SCREEN SAVES (PRACTICAL COMPµTING) ★![]() |
| Amstrad Screen Saves (Practical Compµting) | Applications Programmation |
D J Ellis explains a versatile and economical method of saving CPC-464 screen displays to tape. SAVING a screen from the Amstrad CPC-464 can be a haphazard process for the unwary. The problem lies in the fact that the Amstrad uses a screen offset to perform its scrolling via hardware. If the offset on loading the information back is different from when it was saved it will probably reappear in the wrong place. Some parts may even be missing. It is possible to fetch the current screen offset by the short machine-code program shown in listing 1. Once the program has been run CALL &9000will store the current screen offset into memory locations &9500/1. The offset value is therefore PEEK(&9501) * 256 + PEEK (&9500)The corresponding program to set the screen offset is shown in listing 2. The screen offset must be placed into locations &9500/1 and then the routine is performed by a Call to &9007.Sideways scrolling is induced by lines 50 to 70. Location &9500 is Poked with the value of Scroll, which will set the screen offset. In this case a right-to-left scroll will take place. A left-to-right scroll can be implemented by changing line 50 to 50 FOR scroll = 80 to 0 STEP - 1 By experimenting with different values for the offset, scrolling can be performed in any direction — even diagonally if you wish. Similar but less flexible results can be obtained by Poking the output port 256 with a value between 0 and 255. This will cause an instant picture shift, but the cursor will not return to the left-hand side of the screen, as it does when the offset method is used. The screen offset should always be an even number. Not the same Unless the offset is the same for both saving and loading there is every chance that the original screen picture will not be reproduced in the same form. There are a number of other disadvantages too. It is possible to produce some very sophisticated graphics of up to 640 by 200 resolution using the Amstrad's 256 ASCII characters alone. But even if you only want a screen dump of ASCII characters, the whole of the 16K of screen memory has to be saved to tape. The unusual configuration of the screen memory layout also means that it is not possible to copy, say, the top half of the screen by just saving the first 8K of screen memory even if the screen offset is set to 0 — which it always is on power-up or when a Mode command is used. Digging into the ROM reveals several routines which make the following possible:
The second restriction occurs because the colours are encoded as part of the character matrix on the screen. The only way to save all the colours, as well as the characters, is to take a full screen save. Obviously, the program will therefore be of most benefit in mode 2. The first ROM routine of use is located via the jumpblock at &BB60. This will compare the character at the current cursor position to the 256 ASCII characters stored in ROM — or in RAM if the Symbol After command has been used to define your own characters. If a match is found the accumulator will hold the value of the ASCII character on return from the routine. If no match is found then the accumulator returns with a value of 0. The next routine needed is the exact opposite and is located at &BB5D. It places the ASCII character whose value is stored in the accumulator to the screen at the current cursor position. All that is needed now is a routine to position the cursor at the required screen position, and this is accomplished by the routine at &BB75. The HL register pair hold the screen co-ordinates. H is set to the column and L to the row: the top left-hand corner of the screen is location 1,1 and the bottom right-hand corner is 80,25. The flowchart shows the general algorithm for copying the ASCII characters on screen to memory. >> Utilising these three routines it becomes a fairly simple matter to copy any part of the screen to an area of memory and then transfer it as a binary file to tape or disc. The complete program to perform this and also to put the characters from memory to the screen is shown in listing 3. Once the Basic program has been run it can be dispensed with. Its only purpose is to load the machine-code routines into memory. Take a copy before you New it though. Half the program is taken up in checking that the values for the coordinates are within range. The values for the number of columns, and the number of rows will depend on the column start and row start co-ordinates. The co-ordinates are passed to the machine code routine as follows CALL &9921 ,& ( < start column > -< number of columns >), &(< start row >-< number of rows >)To save the whole of the screen, for instance, you needCALL &9921,&0150,&0119since 50 hex is 80 decimal and 19 hex is 25 decimal, and a full screen is 80 columns by 25 rows. The program is fussy about getting the right values — no leading or trailing spaces are allowed.If the values and syntax are correct, a reassuring beep will sound. The program then stores the ASCII characters to memory location &9004 onwards. For a full screen dump this will take from 10 to 20 seconds, depending upon what characters are on the screen. Any graphics characters that are not recognised, such as a line created by Draw, are converted to represent a space. Qnce the characters have been stored to memory, they can then be saved to tape by SAVE “XXXX”,B,&9000,PEEK(&99FD) * 256 + PEEK(&99FC)- 36864XXXX is whatever name you give to the binary file, B is for Binary file type, &9000 is where the data starts, and the remainder of the line calculates the number of bytes to save to type.To load characters from tape enter LOAD “XXXX” and the original coordinates and characters will then be loaded into memory from &9000 onwards. To display the characters enter CALL &99C8and the original screen picture will be displayed in a few seconds.Any part of the screen can be saved — from 1 to the full 2,000 characters. CALL &9921,&0150,&010Csaves the top half of the screen;CALL &9921 ,&0150,&0D0Dsaves the bottom half of the screen;CALL &9921,&0128,&0119saves the left half of the screen;CALL &9921,&2928,&0119saves the right half of the screen;CALL &9921,&1E14,&080Asaves a 20-by-10 window in the centre of the screen.If you have a full screen of data held in locations &9004 onwards, then by altering the co-ordinates in locations &9000 to &9003 different parts of the screen may be displayed. The values for the co-ordinates will have to be Poked into their locations. They are &9000 for row start, &9001 for column start, &9002 for number of rows, and &9003 for number of columns. No error checks are carried out now, so be careful. ASCII characters could also be Poked directly to locations &9004 onwards. For example listing 4 stores eight blocks of 256 ASCII characters from location &9004 onwards. Line 70 Pokes in the coordinates, in decimal, to display the whole screen. Line 80 then calls the machine-code routine which will display the characters stored in memory. By using the necessary combination of characters, any message or graphic picture could be displayed easily to any part of the screen. Remember that in mode 1 the effective screen width is 40 columns, and for mode 0 it is 20 columns. No harm is done if you try to save, say, 80 columns in mode 1, and the picture will be redisplayed with no ill effects. However, trying to dump 2,000 characters from a mode 2 screen to a mode 1 or mode 0 screen may produce unexpected results.
|