CODINGLISTINGS ★ Bytes and Pieces ★

Byte and Pieces (The Amstrad User #6)Coding Listings
★ Ce texte vous est présenté dans sa version originale ★ 
 ★ This text is presented to you in its original version ★ 
 ★ Este texto se presenta en su versión original ★ 
 ★ Dieser Text wird in seiner Originalfassung präsentiert ★ 

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 SCREEN
21 00 C0 LD HL,#C000 Load source address (SCREEN)
11 00 40 LD DE,#4000 Load destination address(RAM)
01 00 40 LD BC,#4000 Load length to move (16k)
ED B0 LDIR Perform block move
C9 RET Return to Basic

This 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.

Routine # 2

RESET SCREEN
21 00 40 LDHL,#4000 Load source address (RAM)
11 00 C0 LD DE,#C000 Load destination address (SCREEN)
01 00 40 LD BC,#4000 Load length to move (16k)
ED B0 LDIR Perform block move
C9 RET Return to Basic

This routine transfers all the data back to the screen. Both routines #1 and #2 could be modified to suit other requirements but TAKE CARE!!

Routine # 3

GET SCREEN MODE
D5 PUSH DE Save address of chosen variable
CD 11 BC CALL #BC11 Call Firmware GET MODE
E1 POP HL Get variable address off stack
77 LD (HL),A Place mode value into variable
C9 RET Return to Basic

In some programs you may need to tell which mode the computer is currently using while it is still running.

This routine will call the Firmware GET MODE routine and return the mode value into a chosen integer variable.

It can be used as follows:-

10 CALL SMODE,A% : REM A% will now contain the current screen mode.

Routine #4

FILL BLOCK
3E FC LD A,#FC Load encoded ink into A.
26 02 LD H,#02 Load Left column of block.
2E 03 LD L,#03 Load Top row of block.
16 0A LD D,#0A Load Right column of block.
IE OB LD E,#0B Load Bottom row of block.
CD 44 BC CALL #BC44 Call SCR FILL BOX
C9 RET Return to Basic.

This routine will fill a rectangular area of the screen with a chosen solid or striped colour in an instant which can be useful when setting up backgrounds or borders around windows.

The encoding used by the Amstrad can be very confusing, but with a bit of time and some experimenting you should be able to get the colours you require.

The ink colour is encoded differently for each mode.

Mode 2 is quite simple as each pixel represents one bit of the byte.

Mode 1 is more complicated, as the byte is split into 4 sections.

Bits 3 and 7 determine the colour of the left most pixel in the byte, (Ink 0 to 3).

Bits 2 and 6 are next, then bits 1 and 5, and lastly Bits 0 and 4 control the colour of the right-most pixel.

Mode 0 is the most complicated as bits 1,5,3 and 7 control the left pixel and bits 0,4,2 and 6 control the right pixel.

Take particular notice of the order of bits as it does not seem to make sense.

The following is a diagramatic representation of what I am trying to explain.

Mode 0Mode 1Mode 2
Left Pixelbits 1,5,3,7bit 3,7bit 7
bit 6
bit 2,6bit 5
bit 4
bits 0,4,2,6bit 1,5bit 3
bit 2
Right Pixel bit 0,4

bit 1
bit 0

_

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.

76543210
1 0
1 0
1 0
1 0
---------
111100000

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

Get CHARACTER
D5 PUSH DE Save address of variable
CD 60 BB CALL #BB60 Call GET CHAR routine
E1 POPHL Get address of variable
77 LD (HL),A Store character value
69 RET Return to Basic

This routine will look at the current cursor position and return the value of the character at that spot if it is readable. If the character is recognized then the value will be placed in the chosen integer variable, if not then a value of 0 will be returned instead.

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

Write 16k Block.
21 00 C0 LD HL,#C000 START OF DATA BLOCK
11 00 40 LD DE,#4000 Length of Data Block
3E 16 LD A,#16 Sync Byte #16 for Data
CD9EBC CALL #BC9E Call CASS WRITE
C9 RET RETURN TO BASIC

This routine will save the complete 16k screen block in one go without headers or inter-record gaps, giving a huge advantage in time, as the screen saved at the slow, super-safe speed with this method will save and load in the same time as the high speed save normally does.

This routine can be used to save any size block up to a theoretical 64k with very little modification.

Routine #7

Read 16k Block
21 00 C0 LD HL,#C000 START OF LOAD AREA.
11 00 40 LD DE,#4000 Length of Load block.
3E 16 LDA,#16 Sync byte #16 for Data.
CD A1 BC CALL #BCA1 Call CASS READ
C9 RET RETURN TO BASIC.

This routine will load the block saved by the program above.

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.

The Amstrad User

★ PUBLISHER: The Amstrad User (Australia)
★ YEAR: 1985
★ AUTHOR: Sydney BROWN
 



★ AMSTRAD CPC ★ DOWNLOAD ★

Type-in/Listing:
» Byte  and  Pieces    (The  Amstrad  User-6)    LISTINGDATE: 2024-08-17
DL: 140
TYPE: PDF
SiZE: 286Ko
NOTE: 1 page/PDFlib v1.6

★ AMSTRAD CPC ★ A voir aussi sur CPCrulez , les sujets suivants pourront vous intéresser...

Lien(s):
» Coding Src's » Byte and Pieces (The Amstrad User #7)
Je participe au site:
» Pour ce titre nous ne disposons de fichier executable sur CPC (Dump, Saisie du listing) , alors si vous avez ça dans vos cartons ou vous désirez usé vos petit doigts boudinés sur votre clavier faites le nous savoir.
» Vous avez des infos personnel ?
» Vous avez remarqué une erreur dans ce texte ?
» Aidez-nous à améliorer cette page : en nous contactant via le forum ou par email.

CPCrulez[Content Management System] v8.732-desktop/c
Page créée en 769 millisecondes et consultée 659 fois

L'Amstrad CPC est une machine 8 bits à base d'un Z80 à 4MHz. Le premier de la gamme fut le CPC 464 en 1984, équipé d'un lecteur de cassettes intégré il se plaçait en concurrent  du Commodore C64 beaucoup plus compliqué à utiliser et plus cher. Ce fut un réel succès et sorti cette même années le CPC 664 équipé d'un lecteur de disquettes trois pouces intégré. Sa vie fut de courte durée puisqu'en 1985 il fut remplacé par le CPC 6128 qui était plus compact, plus soigné et surtout qui avait 128Ko de RAM au lieu de 64Ko.