╔───────────────────────────────────────╗
│ EXPERIENCE EXCHANGE │
│ ───────────────────────────────────── │
│ those who know a lot are not allowed to read │
╚───────────────────────────────────────╝
(C) Zavoдчиков Konstantin
(C) Music NEVER
Today we will address some programming questions in assembly language that often arise for beginner programmers. This article may repeat some printed or electronic publications, and someone may reproach our magazine for this. However, it is worth remembering that not everyone has a collection of ZX-REVIEWS at home for at least any year. So, those who are strong in codes and know many tricks can safely leave this article. And with those who remain, we will try to figure something out for the common good.
To start, we will touch on several procedures located in ROM:
CLEAR xxxxx - a program to clear the BASIC variable area, screen, set the stack, and the RAMTOP variable to new values. To emulate this command in the codes, the register pair BC must contain the address for setting the stack. In assembly, it will look like this:
LD BC,xxxxx
CALL 7855 (#1EAF)
If BC contains 0, then only the variables and screen area will be cleared.
CLS - a program to clear the screen. Attributes are set according to the value of the variable ATTR-P (23693). When calling this program, there is no need to load data into the registers. It is invoked:
CALL 3435 (#0D6B).
CLEAR-LINES - a subroutine to clear the lower N lines of the screen. The number of lines to be cleared is loaded into register B:
LD B,N
CALL 3652 (#0E44).
PAUSE - a complete analog of the BASIC command. The register BC contains the number of delays; if it is zero, the return from the procedure will occur only when a key is pressed:
LD BC,pause
CALL 7997 (#1F3D).
When calling this program, do not forget to enable interrupts and turn on the first interrupt mode (IM1), otherwise you can only return from this procedure by pressing the RESET button.
BREAK_KEY - a procedure that checks for the BREAK key press (do not confuse it with the SPACE key). It is called:
CALL 8020 (#1F54).
After returning from the procedure, the reset carry flag indicates that the BREAK key was pressed.
PLOT - this procedure lights up (or extinguishes, depending on system variables) a point on the screen. In register C - the X coordinate, in register B - Y:
LD B,Y
LD C,X
CALL 8933 (#22E5).
DRAW - a program to draw a straight line on the screen. Here, just like in the PLOT procedure, registers B and C contain the Y and X coordinates, but they are not fixed - they are offset coordinates. In register D, the sign of the offset along the X coordinate, in E the sign of the offset along Y. That is, if the sign of any coordinate offset is: 255 (#FF), the corresponding offset will be interpreted with a "minus" sign; 1 - the offset will be with a "plus" sign; 0 - the offset for this coordinate is simply ignored.
LD B,Y
LD C,X
LD D,sign for Y
LD E,sign for X
CALL 9402 (#24BA).
CHAN-OPEN - the subroutine serves to open a channel. Often, beginning programmers forget to open channel "S" when using the print procedure from ROM, after which they look in confusion at their message that appeared strangely, not where it should be, or, more interestingly, "OUT OF SCREEN" pops up. For the correct call of this procedure, register A must contain a number in the range from 253 (#FD) to 3. These numbers are streams leading to channels: keyboard "K", screen "S", printer "P", and workspace "R". Here are the values of the streams leading to the standard channels:
253 (#FD) - opens channel "K"
254 (#FE) - opens channel "S"
255 (#FF) - opens channel "R"
0 (#00) - opens channel "K"
1 (#01) - opens channel "K"
2 (#02) - opens channel "S"
3 (#03) - opens channel "P".
So, I repeat, when calling the procedure, the accumulator must contain the stream number (see table). Moreover, the procedure must be called according to the text below:
LD A,stream number
CALL 5633 (#1601).
And to print normally across the entire screen, you need to load the number 2 into register A and call the CHAN-OPEN procedure.
SET_ADDR - a program to calculate the address of the character cell on the screen. When calling this procedure, register B must contain the X coordinate, and register C - the Y coordinate of the required character cell. Instead of the entry point in ROM, I present you with the listing of this program.
LD B,Y coordinate
LD C,X coordinate
CALL SET_ADDR
............
SET_ADDR
LD A,B
RRCA
RRCA
RRCA
AND #E0
LD L,A
LD A,B
AND #18
OR #40
LD H,A
LD B,#00
ADD HL,BC
RET.
After calling the SET_ADDR procedure, the address of the character cell is in register HL.
SET_ATTR - this procedure calculates the attribute address for the corresponding address from the dot area. Upon entering the procedure, register HL must contain the required address from the dot area. I will also provide the listing of this procedure.
LD HL,address
CALL SET_ATTR
............
SET_ATTR
LD A,H
RRCA
RRCA
RRCA
AND #0B
OR #50
LD H,A
RET.
Here, the attribute address is returned in HL.
And now I will provide several simple tricks needed when writing programs in assembly.
Dividing a register pair by 2, 4, 8, etc.:
AND A
RR B
RR C.
By repeating this example N times, you will divide the number by 2 to the power of N. This method can also divide individual registers.
You can multiply the register pair analogously to the previous example, replacing the RR commands with RL:
AND A
RL C
RL B.
And if you need to multiply the HL register, it is better to do this using the addition command ADD:
ADD HL,HL ; multiply by two
ADD HL,HL ; by four
ADD HL,HL ; by eight
...........
and so on.
And now some specific examples:
Multiplying HL by six:
ADD HL,HL
LD B,H
LD C,L
ADD HL,HL
ADD HL,BC ; multiplying HL by forty:
ADD HL,HL
ADD HL,HL
ADD HL,HL
LD B,H
LD C,L
ADD HL,HL
ADD HL,HL
ADD HL,BC ; dividing A by six:
LD A,dividend
LD B,#00
LABEL SUB #06 (divisor)
RET C
INC B
JR LABEL
the output of this procedure will have the quotient in register B (do not forget that this method can only perform integer division!).
If you use the ADC and SBC commands for adding or subtracting register pairs, remember - during calculations they use the carry flag (CARRY FLAG). Therefore, before ADC or SBC, to obtain the correct result, this flag must be reset. It is very convenient to do this with the AND A command. The contents of the accumulator do not change.
By the way, there is a special powerful program in the SPECTRUM ROM for various mathematical calculations. But it has a number of drawbacks that make its use difficult:
1. Calculations are performed quite slowly. Therefore, it is impractical to use the calculator, for example, for calculating coordinates in programs with dynamic vector graphics.
2. Working with the calculator is done in a somewhat unusual way, although it is well known to those who have ever worked on a programmable microcalculator (PMK). The essence of the work is as follows: first, the values are loaded onto the CALCULATOR STACK (not the machine one!), and then operations are performed with them. After that, the result is again taken from the calculator's stack. Without going into details, here are some entry points necessary for operation:
value from A to stack #2D28
value from stack to A #2DD5
value from BC to stack #2D2B (*)
value from stack to BC #2DA2 (*).
Upon returning from this subroutine, the value 23610 (#5C3A) will be set in register IY.
Now a small example of practical use of the calculator.
It is necessary to compute (21-Y)*8+3:
LD A,21 ; load onto stack
CALL #2D28
LD A,(Y) ; values in order
CALL #2D28
LD A,8 ; of calculations,
CALL #2D28
LD A,3 ; i.e. 21 Y 8 3
CALL #2D28
; now we will calculate
RST #28 ; turn on calculator
DEFB #03 ; subtract
DEFB #04 ; multiply
DEFB #0F ; add
DEFB #38 ; turn off calculator
; take the result from the stack
CALL #2DD5 ; result in A.
Try to write a standalone calculation subroutine for this formula without using the calculator and compare these two procedures.
You can find the table of operation codes for the calculator in the three-volume programming in machine codes by "ИНФОР-КОМ". And if you cannot find this literature, we will share information in the next issues of the magazine.
With that, allow me to take my leave, and if anyone has any questions or something is unclear - feel free to contact the magazine's editorial office, we will make every effort to help you!
* * *
Contents of the publication: Adventurer #02
- Guests
Interview with SURDAKAR GROUP discussing their origins, notable projects, and future plans in software and game development.
- Modifications for PENTAGON 128
The article presents modifications for the PENTAGON 128 computer, including a keyboard fix to prevent accidental key presses and a joystick improvement for multi-player gaming. It also describes a stereo DAC development for enhanced sound quality with the AY 8910 audio processor. The author encourages programmers to create software supporting this DAC.
- Interface
The article discusses the ongoing engagement and challenges faced by the Adventurer magazine team, particularly in fostering contributions from readers. It highlights the importance of clarity in language and communication for potential contributors. The piece also provides game tips for several ZX Spectrum titles, emphasizing community support and collaboration.
- Interface
The article discusses the role of hackers in the SPECCY community, highlighting their contributions to software development and maintenance. It contrasts ethical hackers with those who engage in software piracy, illustrating the importance of hackers for preserving the legacy of ZX Spectrum. Ultimately, the author defends the positive impact of hackers on the gaming scene.
- Novella
This article presents a sci-fi novella detailing an interstellar conflict where Earth faces a malevolent alien race. A skilled coordinator must navigate through alien territories using robots to secure resources and defeat enemies. The story highlights strategy and exploration in a galaxy fraught with danger.
- Review
The article reviews various games from CODEMASTERS and others, evaluating them based on graphics, sound, and playability. The review highlights the evolution of game quality and the significance of user feedback in shaping perceptions. Overall, the article emphasizes the ongoing development in the gaming landscape.
- Experience Exchange
The article discusses essential assembly programming procedures for ZX Spectrum, aimed at beginners. It outlines several crucial routines, including memory clearing, screen commands, and mathematical operations. The text provides practical examples to enhance understanding and application of assembly language in programming.
- Advertisements
Article presents advertisements and calls for collaboration in the ZX Spectrum community, inviting programmers, artists, and musicians to contribute. It highlights the acceptance of any ZX Spectrum-related materials, along with details on available software and hardware for sale. The issue emphasizes the importance of participation and partnership among enthusiasts.
- Presentation of ROBIN OF SHERLOCK Adventure Game
The article presents the adventure game ROBIN OF SHERLOCK by DELTA 4 SOFTWARE, emphasizing the need for a good command of English to fully appreciate its humor and dialogues. It highlights game mechanics, including item collection, character interaction, and the interconnectedness of game parts. The text also offers tips on navigating the game and solving crimes within its storyline.
- Presentation
Авторская презентация игры 'МИНЕР', аналог MINESWEEPER для ZX Spectrum, с подробным описанием игрового процесса и особенностей управления.
- System Overview for ZX Spectrum
Overview of various utility programs for ZX Spectrum, including disk utilities and graphic editors, discussing their features and shortcomings.