Значок ресурса

Machine Code Test Tool

Нет прав на скачивание
Автор: Francis O. Ainley
Год: 1982
Издатели: Oxford Computer Publishing
Языки: 🇬🇧 Английский
Формат: 📼 TZX лента
Требования: 🖥️ ZX Spectrum 16K

Ссылки:
Страница на ZXArt
Страница на World Of Spectrum
Страница на Spectrum Computing

Скриншоты:
MachineCodeTestTool.gif


Описание:
Machine Code Test Tool (MCTT)— это программное обеспечение, разработанное для компьютераSpectrum ZX, специально для его версий 16k и 48k. Разработанное Фрэнсисом О. Эйнли и опубликованное Oxford Computer Publishing в 1982 году, оно служит учебным и отладочным инструментом для программирования на машинном коде. Программа позволяет пользователям вводить и тестировать свои программы на машинном коде, исследуя структуру ROM и RAM памяти ZX Spectrum.

MCTT особенно полезен для тех, кто интересуется пониманием системы шестнадцатеричных чисел и ее применением к памяти и регистрам компьютера. Он предоставляет практические примеры и практический опыт работы с машинным кодом, предлагая всестороннее введение в микропроцессор Zilog Z80, который используется в ZX Spectrum. Инструмент включает команды для преобразования чисел между десятичной и шестнадцатеричной системами и для изменения памяти и установки точек останова.

Пользователи могут загрузить программу на свой Spectrum ZX, введя определенные команды в зависимости от того, имеют ли они машину 16k или 48k. После загрузки заголовок программы появляется кратко, прежде чем экран очистится, и пользователи могут начать вводить инструкции на машинном коде. Инструмент также включает список команд для изменения памяти, преобразования десятичных чисел в шестнадцатеричные и многое другое, что делает его универсальным дополнением к инструментарию любого программиста.

MCTT является ценным ресурсом для тех, кто желает углубиться в программирование на машинном коде на ZX Spectrum. Он поощряет эксперименты и предоставляет структурированную среду для изучения и тестирования кода. С подробным руководством и обширным набором функций, он остается значимым инструментом для понимания тонкостей машинного кода и архитектуры ZX Spectrum.

MachineCodeTestTool_Front.jpg
MACHINE CODE TEST TOOL



Tutor and Debug Program



ZX Spectrum 16k & 48k Edition







F O Ainley



MACHINE CODE TEST TOOL



for the 16k & 48k Spectrum







Edition Two







INTRODUCTION





Welcome to this introduction to machine code. I have prepared this text to

be used in conjunction with the Machine Code Test Tool program (from here on

abbreviated and referred to as MCTT) in order to give you practical examples

and "hands-on" experience ot using machine code. Using the MCTT you can

enter and test your own machine code programs as well as examine the ZX

SPECTRUM ROM and how your BASIC programs are stored in the RAM memory.

Before beginning to read this book I strongly recommend that your read

chapters 24 and 26 of your Sinclair ZX SPECTRUM Basic Programming book

entitled "The memory" and "Using machine code", and Appendix E of the same

book entitled "Binary and Hexadecimal".



It was not my intention to write a complete treatise on the Zilog Z80 (the

microprocessor used in the ZX SPECTRUM) but if, after completing the

exercises in this book, you wish to go deeper into the subject I can

recommend two books which I have found particularly useful. They are:



Z80 Instruction Handbook Understanding your SPECTRUM

Nat Wadsworth Dr. Ian Logan

OCP Box 99 Oxford Melbourne House Publishers

#6.00 Post Free



LOADING

If you have a 16k ZX SPECTRUM

type LOAD "mctt16" ENTER

or

If you have a 48k ZX SPECTRUM

type LOAD "mctt48" ENTER



and load the program in the normal way. There is a 16k version and a 48k

version of the program on each side of the cassette. On side 1 the 16k

version is followed by the 48k version and on side 2 the 48k version is

followed by the 16k version. When the program is loaded its title will

appear for a short period, the screen will blank for a short period, then

the normal K cursor or Sinclair (c) sign will appear.



Please note that 16k program will not load

on a 48k Spectrum or vice versa. If

"mctt 16" appears first on your 16k

machine this will load successfully. If

"mctt 16" appears first and you have a

48k machine, flip the cassette, rewind

and reload which will enter 48k program

first.

For CHARACTER GENERATOR: type

LOAD "udg" ENTER and program will

start automatically.



To use the MCTT type:

1 LET A=USR 30592 ENTER

if you have a 16k ZX SPECTRUM

or

1 LET A=USR 63360 ENTER

if you have a 48k ZX SPECTRUM



From now on whenever you wish to run the MCTT just type:



RUN ENTER



and the MCTT > cursor will appear in the top left-hand corner of

your T.V. screen.

A complete list of MCTT commands is given in the Appendix.



AN IMPORTANT POINT TO REMEMBER WHEN USING THE MCTT IS THAT TYPING ENTER AT

ANY TIME WILL RETURN YOU TO THE COMMAND MODE. Thus, if you make a mistake,

typing DELETE will have no effect and your only option is to type ENTER.



I will begin with a brief explanation of the hexadecimal number system which

explains the way the MCTT displays information contained within the

computer's registers and memory.







THE HEXADECIMAL NUMBER SYSTEM



Our natural number system is decimal, ie. based on the number 10, because

the physical equipment with which we have been endowed consists of 10

fingers. ThiS is our hardware. In this system 1 character can represent any

one of 10 states, which we label 0, 1 ... or 9.



The natural number system of a digital computer is based on 2 because its

hardware consists of a series of electronic switches which can only register

1 of 2 states, which we label 0 or 1. Because it would be very inconvenient

for us humans to represent values using only 0 and 1 we use the hexadecimal

system which has 16 as its base, which is 2 to the power 4, ie 2x2x2x2.



We would naturally count in the hexadecimal system if we had 16 fingers

instead of 10. In that case, of course, we would need 6 extra characters to

represent the 6 extra fingers. To accomplish this, A-F are used in the

hexadecimal system to represent 10-15.



We now have a number system which is based on 16 instead of 10. To represent

any number between 0 and 15 we need use only one character:

0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F. But what about numbers greater than 15? The

system works in exactly the same way as the decimal system: with 2 decimal

characters we can represent any 1 of 100 (10x10) different states (00-99);

with 3 decimal characters any 1 of 1000 (10x10x10) different states

(000-999) and so on, ad infinitum.



With 2 hexadecimal characters we can represent any 1 of 256 (16x16)

different states (00-FF); with 3 hexadecimal characters any 1 of 4096

(16x16x16) different states (000-FFF); with 4 hexadecimal characters any 1

of 65536 (16x16x16x16) different states (0000-FFFF) and so on, ad infinitum.



The MCTT contains a command (D) to convert any decimal number in the range

00000-65535 to its hexadecimal equivalent, and another command (H) to

perform the reverse conversion, ie. any hexadecimal number in the range

0000-FFFF to its decimal equivalent.



Let's see how this works by converting a decimal number to its hexadecimal

equivalent. We will start by choosing the decimal value 200 (this value has

no special significance but is just an example).





|YOU TYPE|COMMENT |ZX DISPLAYS

| | |>

|D00200 | |

| | |D00200=H00C8

| |C8 is the hexadecimal |

| |equivalent of decimal |

| |200 |





Now let's convert a hexadecimal number to its decimal equivalent. In this

example we will choose the hexadecimal value 1000.





|YOU TYPE|COMMENT |ZX DISPLAYS

| | |>

|H1000 | |

| | |H1000=D04096

| |4096 is the decimal |

| |equivalent of hexadecimal |

| |1000 |





You should now experiment with these 2 commands in order to reach a better

understanding of the hexadecimal number system. One word of warning: if you

enter (using the D command) a decimal value greater than 65535, which is

outside the conversion range of the command, then the words "=OVERFLOW" will

appear on your T.V. screen - try it and see.



From now on we shall follow every hexadecimal value with "h" to distinguish

them from decimal values.



Appendix A of your Sinclair ZX SPECTRUM Basic Programming book contains the

first 256 decimal codes and their corresponding hexadecimal values.







HOW A COMPUTER WORKS.



To understand what machine code is, it is essential to have some idea of

what the "machine", i.e. computer, is. Although we tend to think of anything

connected with computers as being complicated because of the often

complicated nature of the tasks most computers perform, we are lucky in

that, conceptually, a computer is easy to understand.



We can understand that concept more easily if we separate HOW a computer

works from WHAT it does.



We can understand how a computer works by taking just 3 elements.



1. A block of memory

A memory block is divided up into units called BYTES. Each byte (unit) has 2

attributes:

a) every byte is made up of 8 on/off switches, called BITS, and can

contain any 1 of 256 (2 to the power of 8) codes (00-FFh);

b) every byte has a unique numbered location which is called its

ADDRESS.

The addresses of the bytes start from 0 and rise sequentially by 1 to

whatever the largest address permitted by a particular computer may be. For

the Z80 this is 65535 (FFFFh) and for a large IBM machine perhaps 16,777,215

(FFFFFFh).



2. The program counter

This is simply an amount of memory within the computer (the block of memory

described above is external to the computer although of course connected to

it), called a REGISTER, which contains an address of one of the locations

described above. When the ZX SPECTRUM is turned on the program counter

contains 0. All registers are either 1 or 2 bytes long. The program counter

is 2 bytes long, sufficient to hold the address of any one of the ZX

SPECTRUM's 65536 (0-65535) memory locations.



3. The execution unit

This is the part of the computer that carries out instructions. Instructions

alter registers and memory locations in very precisely defined ways which we

shall discuss later. Each computer has its own very particular set of

instructions which it will execute.



Now that we have described the 3 elements we can see how they work together:



1. The program counter contains a memory address. The contents of the byte

indicated by that address (which must be an instruction code, also called an

operation code) are fetched to the execution unit.

2. The length of the instruction just fetched (instructions can be 1, 2, 3

or 4 bytes long) is added to the program counter, thereby forming the

address of the next instruction to be executed.

3. The instruction is executed.



The above cycle of instructions is repeated ad infinitum until the computer

is switched off. This is all the computer ever does and in fact the power of

the computer comes from its ability to repeat this fetch/execute cycle

millions of times per second.



One obvious point which may arise from the above description is "what

happens when the program counter reaches the end of the memory?". The answer

is that it must never be allowed to. This is achieved by making one of the

instructions which is executed by the execution unit a "change program

counter" instruction. This is effectively a "branch" or "goto" instruction.







WHAT DOES A COMPUTER DO?



We have already said that instructions alter registers and memory locations,

and basically this is all that they do. We have already described one

register, the program counter, and below is a diagram of the full internal

register set of the Z80.



.---.---. .---.---.

| A | F | | A'| F'|

| B | C | | B'| C'|

| D | E | | D'| E'|

| H | L | | H'| L'|

.---.---. .---.---.

| I X |

| I Y |

| S P |

| P C |

.---.---.

| R | I |

.---.---.



To see how MCTT displays these registers:



|YOU TYPE|COMMENT |ZX DISPLAYS

| | |>

|R | |

| | |MAIN REGISTER SET

| | |AF=xxxx BC=xxxx DE=xxxx HL=xxxx

| | |FLAG S Z - H - P/V N C

| | |BITS x x - x - x x x

| | |

| | |ALTERNATE REGISTER SET

| | |AF=xxxx BC=xxxx DE=xxxx HL=xxxx

| | |FLAG S Z - H - P/V N C

| | |BITS x x - x - x x x

| | |

| | |SPECIAL PURPOSE REGISTERS

| | |IX=xxxx IY=xxxx SP=xxxx PC=xxxx

| | | I=xx R=xx

| | |>



Please note that I have used "x" above, and throughout this book, to denote

a character which is unknown and/or not relevant to our purposes. However,

the first time MCTT is entered the information contained in all these

registers is "0" because this is a display of the information contained in

the registers at the moment that a machine code routine of our own making

has been interrupted, and we have not yet written any such routines - but we

soon will.



Some registers are 2 bytes long, always contain a memory address, and can

only be used in 2 byte chunks. These are the IX, IY, SP, and PC registers

(the PC register is the program counter I have already mentioned).



The BC, DE, and HL register pairs can be used in either 1 or 2 byte

quantities, as is shown in examples below. Thus, for example, the BC

register pair can be accessed as BC, B or C.



The A register, although paired with the F register, is mostly used on its

own. The F register can only be used indirectly as we shall see later. (The

information contained in the register display against the lines beginning

"FLAG" and "BITS" is in fact purely a translation of the information

contained in the F register, which we will also use later).



The R and I registers are for special purposes and are of no interest to

most programmers.



Finally, there is a duplicate set of the AF, BC, DE, and HL register pairs,

(listed in the register display under "ALTERNATE REGISTER SET"). The use of

the HL register pair in this alternate set and of the IY register is not

recommended as the ZX SPECTRUM control program, which is contained in the

ROM and which controls many crucial operations of the computer, uses these

registers as a temporary store.



To fully explore the instruction set of the Z80, a book detailing the

execution of each instruction is necessary, which is beyond the scope of

this general introduction. However, we can now examine the operation of a

number of common instructions to gain a broad understanding of the

microprocessor.







LOAD A REGISTER PAIR FROM MEMORY



We will now enter a machine code instruction into memory at location 6000h

and then execute it. The instruction is "load the BC register pair with the

2 byte value immediately following the operation (instruction) code". In

this case we will choose the value 1122h.



|YOU TYPE|COMMENT |ZX DISPLAYS

| | |>

|A6000 | |

| |MCTT A (Alter) |

| |command |

| | |6000 xx >

|01 |operation code |

| | |6000 xx 01

| | |6001 xx >

|22 |the value to go into C |

| | |6001 xx 22

| | |6002 xx >

|11 |the value to go into B |

| | |6002 xx 11

| | |6003 xx >

|ENTER | |

| | |>

|B6003 | |

| |MCTT B (Breakpoint) |

| |command |

| | |B 6003 ? >

|X | |

| | |B 6003 ?X

|G6000 | |>

| |MCTT G (Goto) |

| |command |

| | |G 6000 ? >

|X | |

| | |BREAK AT 6003

| |Our instruction has |>

| |now been executed |

|R | |

| |MCTT R (Register |

| |display) command |

| | |MAIN REGISTER SET

| | |AF=xxxx BC=1122 DE=xxxx HL=xxxx

| | |FLAG S Z - H - P/V N C

| | |BITS x x - x - x x x

| | |

| | |ALTERNATE REGISTER SET

| | |AF=xxxx BC=xxxx DE=xxxx HL=xxxx

| | |FLAG S Z - H - P/V N C

| | |BITS x x - x - x x x

| | |

| | |SPECIAL PURPOSE REGISTERS

| | |IX=xxxx IY=xxxx SP=xxxx PC=6003

| | | I=xx R=xx

| | |>



At this point I would like to explain what we have just done. Using the A

(Alter) MCTT command we entered the instruction into memory. Using the B

(Breakpoint) MCTT command we inserted an instruction to jump to the MCTT

when address 6003h was reached, ie. immediately after our ld bc,1122h

instruction was executed. The G (Goto) MCTT command initiated execution of

that instruction.



The last command, R, displayed all of the Z80's registers after our

instruction had been executed. As you can see, these registers now contain

different values. These values represent the contents of the registers when

the program counter reached address 6003h.



From the register display we can see that the BC register pair now contains

the value 1122h. We have just written our first machine code program!



* A list of these instructions or operation codes is given in Appendix A of

your Sinclair ZX SPECTRUM Basic Programming book. For example, in this case,

under the column "HEX", you will find "01". Next to this, under the column

"Z80 Assembler" you will find "ld bc,NN", which is the instruction we are

just about to execute.







LOAD A SINGLE REGISTER FROM MEMORY



There are also instructions to alter individual registers. To demonstrate

this we will enter and execute the instruction "load the B register with the

1 byte value immediately following the operation code". In this case we will

choose the value 33h.



|YOU TYPE|COMMENT |ZX DISPLAYS

| | |

|A6000 | |

| | |6000 xx >

|06 |operation code |

| | |6000 xx 06

| | |6001 xx >

|33 |value to go into B |

| | |6001 xx 33

| | |6002 xx >

|ENTER | |

| | |>

|B6002 | |

| | |B 6002 ? >

|X | |

| | |B 6002 ?X

| | |>

|G6000 | |

| | |G 6000 ? >

|X | |

| | |BREAK AT 6002

| | |>

|R | |

| | |MAIN REGISTER SET

| | |AF=xxxx BC=3322 DE=xxxx HL=xxxx

| | |FLAG S Z - H - P/V N C

| | |BITS x x - x - x x x

| | |

| | |ALTERNATE REGISTER SET

| | |AF=xxxx BC=xxxx DE=xxxx HL=xxxx

| | |FLAG S Z - H - P/V N C

| | |BITS x x - x - x x x

| | |

| | |SPECIAL PURPOSE REGISTERS

| | |IX=xxxx IY=xxxx SP=xxxx PC=6002

| | | I=xx R=xx

| | |>



From the register display we can see that the B register (remember we are

only altering directly the registers in the Main Register Set) now contains

the value 33h while the C register retains the value 22h which we loaded

into it with our ld bc,1122h instruction.







ADD ONE REGISTER PAIR TO ANOTHER

REGISTER PAIR



The Z80 has various instructions to perform addition and subtraction but

none to perform multiplication or division or other mathematical functions.

If you want to do anything other than addition or subtraction in machine

code I'm afraid you'll just have to write a program to do it yourself.



To demonstrate an addition we will load the DE register pair with a value,

load the HL register pair with a value, and add the DE register pair to the

HL register pair, leaving the result in HL. In this case we will choose the

values 1028h for HL and 2002h for DE



ld hl,1028h put 1028h into HL;

ld de,2002h put 2002h into DE;

add hl,de add DE to HL





An important point to bear in mind is that this is hexadecimal, not decimal,

arithmetic.



|YOU TYPE|COMMENT |ZX DISPLAYS

| | |>

|A6000 | |

| | |6000 xx >

|21 |the operation code |

| |ld hl,NN |

| | |6000 xx 21

| | |6001 xx >

|28 |the value to go into L |

| | |6001 xx 28

| | |6002 xx >

|10 |the value to go into H |

| | |6002 xx 10

| | |6003 xx >

|11 |the operation code |

| |ld de,NN |

| | |6003 xx 11

| | |6004 xx >

|02 |the value to go into E |

| | |6004 xx 02

| | |6005 xx >

|20 |the value to go into D |

| | |6005 xx 20

| | |6006 xx >

|19 |the operation code |

| |add hl,de |

| | |6006 xx 19

| | |6007 xx >

|ENTER | |

| | |>

|B6007 | |

| | |B 6007 ? >

|X | |

| | |B 6007 ?X

| | |>

|G6000 | |

| | |G 6000 ? >

|X | |

| | |BREAK AT 6007

| | |>

|R | |

| | |MAIN REGISTER SET

| | |AF=xxxx BC=xxxx DE=2002 HL=302A

| | |FLAG S Z - H - P/V N C

| | |BITS x x - x - x x x

| | |

| | |ALTERNATE REGISTER SET

| | |AF=xxxx BC=xxxx DE=xxxx HL=xxxx

| | |FLAG S Z - H - P/V N C

| | |BITS x x - x - x x x

| | |

| | |SPECIAL PURPOSE REGISTERS

| | |IX=xxxx IY=xxxx SP=xxxx PC=6007

| | | I=xx R=xx

| | |>



From the register display we can see that DE now contains the value 2002h we

loaded into it, while HL now contains 302Ah, which is the result of the

hexadecimal addition of 2002h and 1028h.







COMPARE AND BRANCH



Now we come to a very important set of instructions - the compare and branch

instructions. In order to be able to make decisions the computer must have a

mechanism for determining if certain conditions have occurred and how to

communicate the fact that those conditions have occurred to other

instructions.



The mechanism to accomplish this is very simple and involves a register set

aside specifically for this purpose. This register is the F (flag) register,

so called because its function is to flag, or signal to other instructions

the results of preceding instructions.



The flag register has 8 bits, the same as any other byte, and 6 of these

bits are used as 6 separate flags, called the S,Z,H,P/V,N and C flags. When

you use the MCTT register display command "R", the hexadecimal value of the

flag register is shown, together with the setting of each bit of the flag

register (next to the words "FLAG" and "BITS"). (When we talk about bit

settings we usually refer to a bit being "set" if = 1, otherwise "reset" if

= 0). To demonstrate their use we shall concentrate on one flag, the Z

(zero) flag.



Most compare instructions use the A register for one half of the comparison.

The operation of a compare between, for example, the A and B registers works

like this: the computer performs an imaginary subtraction of the B register

from the A register, leaving both registers unaltered, and if the result of

that imaginary subtraction would have resulted in the A register containing

0, it sets the Z flag. In all other cases the Z flag is reset; ie. if A>B or

A<B.



After compare instructions there are generally branch instructions which

alter the program counter as a result of the comparison.



To demonstrate this we will enter this short program.



ld a,1 put 1 into A register;

ld b,1 put 1 into B register;

cp b compare A:B

jp z,600Ah branch to address 600Ah if A = B;

ld a,FFh otherwise put FFh into register A.



|YOU TYPE|COMMENT |ZX DISPLAYS

| | |>

| | |6000

|3E |operation code |

| |ld a,N |

| | |6000 xx 3E

| | |6001 xx >

|01 |value to go into A |

| | |6001 xx 01

| | |6002 xx >

|06 |operation code |

| |ld b,N |

| | |6002 xx 06

| | |6003 xx >

|01 |value to go into B |

| | |6003 xx 01

| | |6004 xx >

|B8 |operation code |

| |cp b |

| | |6004 xx B8

| | |6005 xx >

|CA |operation code |

| |jp z,NN |

| | |6005 xx CA

| | |6006 xx >

|0A |second byte of the |

| |branch address |

| | |6006 xx 0A

| | |6007 xx >

|60 |first byte of the |

| |branch address |

| | |6007 xx 60

| | |6008 xx >

|3E |operation code |

| |ld a,N |

| | |6008 xx 3E

| | |6009 xx >

|FF |value to go into A |

| | |6009 xx FF

| | |600A xx >

|ENTER | |

| | |>

|B600A | |

| | |B 600A ? >

|X | |

| | |B 600A ?X >

|G6000 | |

| | |G 6000 ? >

|X | |

| | |BREAK AT 600A

| | |>

|R | |

| | |MAIN REGISTER SET

| | |AF=0142 BC=xxxx DE=xxxx HL=xxxx

| | |FLAG S Z - H - P/V N C

| | |BITS 0 1 - 0 - 0 1 0

| | |

| | |ALTERNATE REGISTER SET

| | |AF=xxxx BC=xxxx DE=xxxx HL=xxxx

| | |FLAG S Z - H - P/V N C

| | |BITS x x - x - x x x

| | |

| | |SPECIAL PURPOSE REGISTERS

| | |IX=xxxx IY=xxxx SP=xxxx PC=600A

| | | I=xx R=xx

| | |>



From the register display we can see that the Z flag is set; ie. = 1, and

that the A register now contains the value 01h we loaded into it. This means

that the branch instruction skipped around the ld a,FFh instruction before

stopping at location 600Ah because the contents of the A register were equal

to the contents of the B register. If we change the value that is loaded

into B as follows, we can see the result:



|YOU TYPE|COMMENT |ZX DISPLAYS

| | |>

|A6003 | |

| | |6003 01 >

|02 |change the value |

| |loaded into B |

| | |6003 xx 02 >

| | |6004 xx >

|ENTER | |

| | |>

|G6000 | |

| | |G 6000 ? >

|X | |

| | |BREAK AT 600A

| | |>

|R | |

| | |MAIN REGISTER SET

| | |AF=FF93 BC=02xx DE=xxxx HL=xxxx

| | |FLAG S Z - H - P/V N C

| | |BITS 1 0 - 1 - 0 1 1

| | |

| | |ALTERNATE REGISTER SET

| | |AF=xxxx BC=xxxx DE=xxxx HL=xxxx

| | |FLAG S Z - H - P/V N C

| | |BITS x x - x - x x x

| | |

| | |SPECIAL PURPOSE REGISTERS

| | |IX=xxxx IY=xxxx SP=xxxx PC=600A

| | | I=xx R=xx

| | |>



From this we can see that the Z flag is reset to 0 and therefore the

instruction to skip around the ld a,FFh instruction has not been executed

and as a result the A register now contains FFh. It is important to realise

that only some instructions affect the flag register and in this last

example the last instruction to be executed, ld a,FFh, did not affect the

flag register in any way.



We have just seen the operation of a conditional branch instruction. Of

course branch instructions do not have to be conditional and unconditional

branch instructions do exist in the Z80 instruction set and are frequently

used.







CALL & RETURN



A very special version of the jump instruction - call - is one of the most

widely used machine code instructions. The idea behind the call is this: the

execution of one group of instructions may be temporarily interrupted to

execute another group of instructions, generally referred to as a

subroutine.



The mechanism to accomplish this also involves a register set aside

specifically for this purpose. This register is the SP (stack pointer)

register. This is simply a register which points to an area of memory,

called the stack, which is used to store the address following the call

instruction (the return address). When a call is executed the current

contents of the program counter (the return address) are moved to the

address pointed to by the stack pointer, and the stack pointer is

decremented by 2. The address contained in the call instruction is moved to

the program counter and thus the instruction at that address becomes the

next instruction to be executed. When it is desired to return to the

instruction following the call instruction, a return instruction is

executed. This simply reverses the above process: the contents of the

address pointed to by the stack pointer are moved back to the program

counter and the stack pointer is incremented by 2. It is obviously essential

that the contents of the stack pointer are not changed in between these

operations - a common programming error.



The call instruction is best illustrated using the following diagram. When

the call 7000h instruction is executed, control passes to address 7000h and

instruction A at that address becomes the next instruction to be executed.

When the ret (return) instruction is executed, control passes back to

address 6003h and execution of the original routine is resumed with the

execution of instruction B. In this way self-contained routines may be

written to perform specific tasks, thus easing program development and

making possible the logical structuring of large programs.



6000h CALL 7000h ---.

.---> 6003h instr B |

| * * * |

| * * * |

| .--------------------------------.

| |

| .---> 7000h instr A subroutine starts here

| * * *

| * * *

| * * *

.-------------- RET



To demonstrate this we can enter and execute the following program:



address



6000h call 7000h go to address 7000h;

6003h



7000h pop hl put last 2 bytes of stack into HL;

7001h push hl reset stack pointer;

7002h ret return to address 6003h



|YOU TYPE|COMMENT |ZX DISPLAYS

| | |>

|A6000 | |

| | |6000 xx >

|CD |the operation code |

| |call |

| | |6000 xx CD

| | |6001 xx >

|00 |the second byte of the |

| |call address |

| | |6001 xx 00

| | |6002 xx >

|70 |the first byte of the |

| |call address |

| | |6002 xx 70

| | |6003 xx >

|ENTER | |

| | |>

|A7000 | |

| | |7000 xx >

|E1 |the operation code |

| |pop hl |

| | |7000 xx E1

| | |7001 xx >

|E5 |the operation code |

| |push hl |

| | |7001 xx E5

| | |7002 xx >

|C9 |the operation code |

| |ret |

| | |7002 xx C9

| | |7003 xx >

|ENTER | |

| | |>

|B7002 | |

| | |B 7002 ? >

|X | |

| | |B 7002 ?X >

|G6000 | |

| | |G 6000 ? >

|X | |

| | |BREAK AT 7002

| | |>

|R | |

| | |MAIN REGISTER SET

| | |AF=xxxx BC=xxxx DE=xxxx HL=6003

| | |FLAG S Z - H - P/V N C

| | |BITS x x - x - x x x

| | |

| | |ALTERNATE REGISTER SET

| | |AF=xxxx BC=xxxx DE=xxxx HL=xxxx

| | |FLAG S Z - H - P/V N C

| | |BITS x x - x - x x x

| | |

| | |SPECIAL PURPOSE REGISTERS

| | |IX=xxxx IY=xxxx SP=xxxx PC=7002

| | | I=xx R=xx

| | |>



From this register display we can see that the HL register pair now contains

the return address (pop hl put the contents of the stack into HL and

decremented the stack pointer by 2 - push hl incremented the stack pointer

by 2 to restore the status quo).



If we examine the contents of the stack by taking the value of the SP

register, we shall see that the first 2 bytes on the stack are the return

address 6003h in REVERSE order. (In reverse order as all addresses used by

the Z80 stored in memory are in reverse order. Eg. if the contents of these

2 bytes are 0360h the actual address is 6003h.



To examine the stack, note the value of the SP register given under the

"SPECIAL PURPOSE REGISTERS" heading. You will use this address where xxxx is

indicated below. E.g. if the SP contained 7764h you must type P7764.



|YOU TYPE|COMMENT |ZX DISPLAYS

| | |>

|Pxxxx | |

| | |a hexadecimal page



If we remove the breakpoint at 7002h and execute the call at 6000h again, we

shall see that the execution sequence will be halted at address 6003h -

showing that the subroutine at 7000h has been executed and control has

returned to address 6003h.



|YOU TYPE|COMMENT |ZX DISPLAYS

| | |>

|N | |

| | |N 7002

| | |>

|G6000 | |

| | |G 6000 ? >

|X | |

| | |BREAK AT 6003

| | |>







LOAD A MEMORY LOCATION FROM REGISTER



We have already seen how to load a register and register pair from the

memory. We can also do the reverse of course, ie. load a memory location

from a register. Part of the memory is used by the ZX SPECTRUM to store the

information that appears on your T.V. screen, so if we change that memory we

should be able to see the results immediately.



The display memory begins at address 4000h and is in two parts. The first

part has a bit set aside for each dot that appears on the T.V. screen, the

maximum number of bits being 256*192 which is 49152 bits or 6144 (1800h)

bytes (49152/8). This portion of the display memory occupies addresses 4000h

to 57FFh.



The second part of the display memory controls the attributes of the 768

(32*24) blocks that make up the display and is 768 (300h) bytes long. Each

byte controls the flashing, brightness, foreground and background colour

attributes of each of the blocks. This portion of the display memory

occupies addresses 5800h to 5AFFh.



To get an idea of how the information contained in the display memory

relates to what appears on the T.V. screen, try altering the values

contained in the above locations using the MCTT A (Alter) command. At this

point you might like to re-read chapter 24 of your Sinclair ZX SPECTRUM

BASIC programming book entitled "The memory" for additional information.



We can demonstrate the use of the display memory by writing a short program

to completely till each screen dot position.



address



6000h ld bc,1800h put length of display memory

into BC (this will act as a

counter for the number of

times we are going to move

FFh to the display memory);

6003h ld hl,4000h put start address of display

memory into HL;

6006h ld a,FF load FFh into A;

6008h Id (hl),a load the contents of A into

the memory location whose

address is contained in HL;

6009h inc hl point HL to next memory

location;

600Ah dec bc decrement move counter;

600Bh ld a,b if either B or

600Ch or c C are not=0 then

600Dh jp nz,6006h repeat the instructions at

address 6006h.



|YOU TYPE|COMMENT |ZX DISPLAYS

| | |>

|A6000 | |

| | |6000 xx >

|01 |the operation code |

| |ld bc,NN |

| | |6000 xx 01

| | |6001 xx >

|00 |the value to go into C |

| | |6001 xx 00

| | |6002 xx >

|18 |the value to go into B |

| | |6002 xx 18

| | |6003 xx >

|21 |the operation code |

| |ld hl,NN |

| | |6003 xx 21

| | |6004 xx >

|00 |the second byte of |

| |address 4000h |

| | |6004 xx 00

| | |6005 xx >

|40 |the first byte of |

| |address 4000h |

| | |6005 xx 40

| | |6006 xx >

|3E |the operation code |

| |ld a,N |

| | |6006 xx 3E

| | |6007 xx >

|FF |the value to go into A |

| | |6007 xx FF

| | |6008 xx >

|77 |the operation code |

| |ld (hl),a |

| | |6008 xx 77

| | |6009 xx >

|23 |the operation code |

| |inc hl |

| | |6009 xx 23

| | |600A xx >

|0B |the operation code |

| |dec bc |

| | |600A xx 0B

| | |600B xx >

|78 |the operation code |

| |ld a,b |

| | |600B xx 78

| | |600C xx >

|B1 |the operation code |

| |or c |

| | |600C xx B1

| | |600D xx >

|C2 |the operation code |

| |jp nz,NN |

| | |600D xx C2

| | |600E xx >

|06 |the second byte of |

| |address 6006h |

| | |600E xx 06

| | |600F xx >

|60 |the first byte of |

| |address 6006h |

| | |600F xx 60

| | |6010 xx >

|ENTER | |

| | |>

|B6010 | |

| | |B 6010 ? >

|X | |

| | |B 6010 ?X

| | |>

|G6000 | |

| | |G 6000 ? >

|X | |

| | |a completely black page then

| | |BREAK AT 6010

| | |>







|YOU TYPE|COMMENT |ZX DISPLAYS

| | |>

|M0000 |17FF 4000 |

| | |M 0000 17FF 4000 ?

|X | |

| | |a random bit pattern

|ENTER | |

| | |>







EPILOGUE



As I said in the introduction, should you wish to proceed further you will

almost certainly need additional literature to enable you to reach a fuller

understanding of the Z80 and its operation within the framework of the ZX

SPECTRUM. You have, however, the MCTT, which is a powerful tool in machine

code program development and one with which you should become well

acquainted in order to simplify that development.



In developing machine code programs you might find the following tips of

some use:



1) Write your machine code program down on paper first and try to resolve

any problems at that stage before typing it into the memory.



2) Don't be afraid to experiment; your program may crash and force you to

reload the MCTT but you can't physically damage the ZX SPECTRUM with

software.



3) Try to imagine what is happening in the registers and memory, and what

sequence the instructions are being executed in when things don't work out

as expected; very often you will find that what you expect to happen is not

what is actually happening.



4) Try to isolate the problem; use of the B (breakpoint) MCTT command

enables you to interrupt your machine code programs at pre-specified points

to ensure that any intermediate results are correct.



5) The computer is an absolutely obedient servant; if you make a mistake and

force it to perform nonsense that is exactly what it will do. It is your

task to impose order and logic on its sequence of operations. If you write

in machine code there is no safety net in the shape of a BASIC interpreter

to bail you out if things go wrong.



I hope that this introduction to machine code programming has been

instructive and helped you to a clearer understanding of what machine code

programming is all about. In trying to resolve seemingly intractable

problems I find it very helpful to keep in mind the old IBM motto, THINK.



Good luck!







APPENDIX



The Machine Code Test Tool (MCTT) is a machine code program designed

to run on the Sinclair ZX SPECTRUM with a 16k or 48k RAM. The 16k

version occupies addresses 7780h to 7FFFh; the 48k version occupies

addresses F780h to FFFFh. On loading, RAMTOP is set to 7880h or F780h

respectively. The program is supplied on a cassette containing four

copies of the program, a 16k and 48k version on both sides.



The MCTT will allow you to easily enter machine code instructions and

to test these instructions in operation. Should you wish to save any

machine code programs you write, you should enter them into dummy REM

statements and use the BASIC SAVE statement to save them on cassette

in the normal way.



Loading the MCTT



To load the MCTT type

LOAD "mctt16" ENTER

if you have a 16k ZX SPECTRUM

or LOAD "mctt48" ENTER

if you have a 48k ZX SPECTRUM



and load the program in the normal way. There is a 16k version

and a 48k version

of the program on each side of the cassette. On side 1 the 16k

version is followed

by the 48k version and on side 2 the 48k version is followed by

the 16k version.



When the program is loaded its title will appear for a short

period, the screen will

blank for a short period, then the normal K cursor

will appear. To then use MCTT type:

1 LET A=USR 30592 ENTER

if you have a 16k ZX SPECTRUM

or 1 LET A=USR 63360 ENTER

if you have a 48k ZX SPECTRUM



From now on whenever you wish to run the MCTT just type: RUN ENTER

and the MCTT > cursor will appear in the top left-hand corner of

your T.V. screen.







COMMANDS



A - Alter memory.

A aaaa



This command allows you to alter any RAM byte to any hexadecimal

character desired. At the end of a page this routine will only accept

X, to continue with the next page, or ENTER to return to the command

mode.



B - Breakpoint.

B aaaa?X



This command allows you to insert a breakpoint in any piece of machine

code, in RAM.

The following points should be kept in mind when inserting breakpoints:

Breakpointing works by inserting a call instruction (which is 3 bytes

long) to a routine within MCTT at the address where a breakpoint is

desired. This address must obviously be the first byte of an

instruction - it is not possible to put a breakpoint in the middle of

an instruction. For this reason also, no two breakpoints should be

within less than 3 bytes of each other.

When a breakpoint is reached the message "BREAK AT AAAA" is displayed.



D - Decimal to Hexadecimal conversion.

D ddddd = HHHH



This command converts any decimal value in the range 00000-65535 to

its hexadecimal equivalent. If a value > 65535 is typed in then the

words "= OVERFLOW" will appear.



G - Go to address.

G aaaa?X



This command will allow you to begin executing any machine code

instructions at the address given.



H - Hexadecimal to decimal conversion.

H hhhh = DDDDD



This command converts any hexadecimal value in the range 0000-FFFFh to

its decimal equivalent.



M - Moves memory block.

M aaaa aaaa aaaa



This command moves a block of memory to a RAM location. The parameters

of this command are three addresses. Address 1 is the address of the

start of the block, address 2 is the address of the end of the block.

If this address is less than address 1, ie. an error, no further input

for this command will be accepted and a new command must be typed in.

Address 3 is the address of the location where the block will be moved

to.



N - Nullify breakpoint.

N



This command nullifies the LAST breakpoint inserted and restores the

instructions contained at that address. Each time a breakpoint is

nullified, the address of the breakpoint is displayed. You can have as

many breakpoints active at one time as you like, but if you insert

more than 1 breakpoint, the 3 byte call to the routine within MCTT

discussed above, can never be replaced by your original instructions.

In that case you will have to manually re-enter those instructions

using the A (Alter) command.



P - Page memory display.

P aaaa



This command will display a page of memory. After displaying a page

you can display the next page by typing "X".



R - Register display.

R



All registers saved at the execution of a breakpoint are displayed.

The 2 flag registers are displayed in hexadecimal and bit form. If it

is desired to alter the contents of the first four register pairs then

the A (Alter) command should be used to alter the memory locations

where they are stored and loaded from when the G (Goto) command is

executed. These addresses are 793Ch to 7943h in the 16k version, and

F93CH to F943h in the 48k version.



S - Stop.

S



This command will return you to BASIC.



V - View breakpoint.

V AAAA



This command will display the last breakpoint you entered.







GLOSSARY



aaaa - 4 character (2 byte) hexadecimal address supplied by you.

ddddd - 5 decimal characters supplied by you.

hhhh - 4 hexadecimal characters supplied by you.

AAAA - 4 byte hexadecimal address supplied by MCTT.

DDDDD - 5 decimal characters supplied by MCTT.

HHHH - 4 hexadecimal characters supplied by MCTT.

X - Confirmation character that the command entered is correct. No

other characters besides X and ENTER (to cancel the command)

will be accepted.

? - Prompt character displayed by MCTT to solicit the confirmation

character "X".



ENTER typed at any time will return the control to command mode.







Copyright 1982 F.O. Ainley.



Design: Scott/Kemp Design Ltd.



Produced by Artset Graphics, The Old British School House, East Street,

Chesham, Buckinghamshire. Tel. (0494) 771938.







OTHER ZX PROGRAMS FROM OCP.



1. FULL SCREEN EDITOR/ the latest and most comprehensive Editor/

ASSEMBLER Assembler yet produced. FULL SCREEN 42

(16 & 48k) column input, text editor, assemble to tape,

screen or memory, assemble derivatives DEFM,

DEFS, DEFW, DEFB, DEFL, ORG, EQU, END.

Comprehensive syntax check, binary, octal,

HEX and ASCII constants. Superb fully notated

"SNAKE" demonstration program as well as our

42-page instruction manual complete this

essential piece of software.

This program is co-resident with the MACHINE

CODE TEST TOOL; the two programs create a

powerful and complete machine code

programming environment

#9.95



2. MASTER TOOL KIT: add many new commands and facilities to your

(16 & 48k) ZX Spectrum with this remarkable program.

Re-Number, Auto-Number, Delete/Copy and

Move Block, String Search and Substitute,

Variable Dump, Cross Reference, Trace

Function, Real Time Clock and Alarm,

Operating Program Line Display plus many more

features. Programming will never be the same

after you have purchased MASTER TOOL KIT.

#9.95



3. CHESS THE TURK: a very comprehensive chess program for the 48k

(48k) Spectrum

#8.95



4. ADDRESS MANAGER: a fast machine-coded application program that

(48k) Limited on 16k offers Spectrum owners a professional standard

address/data filing, indexing and retrieval system.

Will store up to 400 full name and addresses in

48k, full screen entry is standard.

#8.95



5. FINANCE MANAGER: a powerful and flexible MENU DRIVEN program

(48k) program for practically all domestic and business

accounting applications. Features include

AUTOMATIC DOUBLE ENTRY, ANALYSIS,

STANDING ORDERS, RECONCILIATION and

FULL SCREEN ENTRY. Available for 48k only.

#8.95



80 COLUMN PRINTOUTS

Items 1, 4 & 5 can be supplied as Plus 80 versions and used in conjunction

with a Centronics Interface. They include software to call up most Centronic

printer routines. Price #19.95.



A V.A.T. Manager in both editions will be available soon.
Автор
Verter_bot
Загрузки
0
Просмотры
1
Расширение
zip
Размер
6 КБ
Хэш
31aa16a82232c7b4e94e0d99680a6ff2
Первый выпуск
Последнее обновление

Оценки

0.00 звезд(ы) 0 оценок
Назад
Вверх