THE POWER AND PURPOSE OF MACHINE CODE

Kashyapgrandhi
10 min readJan 25, 2024

--

Machine code is the code in which computer does all the works and programs written in machine code much faster and takes less space of memory unlike BASIC. This article helps you to understand and write in machine code. In this we mainly considering Z80 or 6502 Microprocessor, where it is the chip containing CPU. It may be somewhat difficult to write and less easy to understand and we need to be very careful and verify twice while we write code, as is difficult to spot the bugs. This article explains basics of machine code, explaining how it works and why it’s crucial to everything your computer does.

What is machine code?
In general, when we write program in BASIC, all the instructions and data are translated into machine code inside computer. In machine code each instruction in a binary number (0 and 1). Binary numbers are represented by pulses of electricity where “1” represent “pulse” and “0 “for “no pulse”. These pulses and no pulse called as “bits” and combination of 8 bits called as “byte” that flow through computer carrying information. In general, when we give a computer BASIC command the “Interpreter” converts into machine code. The main thing in machine code is that we need to provide all separate instructions that we need to perform a task.

Programming in machine code

It can be written in different ways. As per this we understood that we can write machine instructions in binary. Can we use in different number system? Yes, we can write machine instructions in Hexadecimal, called as ‘hex’ which is easier to work than binary. We can also write machine code in “Assembly language” where each instruction represented by “Mnemonic”. The representation of machine code in hex is as follow. Here Instruction will be in hex.
3E,02
C6,04
32,577F
C9

The same program in Assembly language is represented as follow. Here there will be mnemonic for each instruction. We need a assembler if we want to give a machine code.
LD A,02
ADD A,04
LD (7F57), A
RET

What chips actually do? In process of executing instruction, it has to go along different chips in it.”
ROM Chip-it stands for Read Only Memory. It stores the instructions to be performed mentioned in machine code. In most of computers interpreter is in ROM.
Bus-There are 3 busses based on the usage. These help in flow of bytes of computer along tracks of PCB.
RAM Chip-It stands for “Random Access Memory”, it is place where programs you give computer are stored while computers working on them. RAM memory is wiped out if we turn off.
Clock-This is a quartz crystal which pulses millions of times a second and regulates the flow of pulses inside the computer.

Computer memory
Let us assume computers memory is lot of small boxes, where each box consists of instruction. Each box in memory is called as “location”, the location of that box called as “Adress”. In memory we may use different locations of memory to store information, the chart which give information about these locations called as “Memory map”. The memory of computer is consumed by different parts of computer like Operating System, BASIC, Reserved for future use, user RAM, variable storage, Screen memory, IO. While it come to memory address, it is represented in 2 bytes i.e,16 bits . The highest possible memory it holds is 64K(Biggest number of 16 bit is 65535,so there will be 65536 locations ,each location has one byte of memory, so 65536/1024 =64K(kilobyte)).Here OS and BASIC are in RAM remaining all in ROM. Some conversions are followed:
Hex addresses can be converted as follow
Address &5C64
Here first two numbers represent page number and next two represent position on page
page=&5C=92è92*256=23552
Position on page =&64=100 decimal
23552+100=23652 decimal

PEEK and POKE
With the use of PEEK and we able to access the date. With PEEK, we can get the value by mentioning address and with the POKE we can able to insert the data at a specified memory address.

Inside the CPU
All the computer’s work is done by fetching bytes of instructions and data from the memory, then carrying out the instructions in the CPU. There are 3 main regions in CPU.
They are Registers where bytes of data are held when they processed, ALU where bytes can be added, subtracted and control unit which organizes all these things. Let’s go through Registers. The arrangement of registers in Z80 and 6502 chips are different. The Z80 Registers are followed:
”A” it stands for Accumulator ,which stores bytes on their way to/from ALU .It can hold one byte at a time. “F” stands for “Flag” register it holds eight but uses six bits.
“IX,IY” are “Index registers” whichhold16 bits used in a instruction to work out address of byte in memory. “B,C,D,E,H,L” Registers where bytes can be stored. Each can hold one byte but they can be grouped in pairs like BC,DE to hold two bytes.
“SP” is a Stack Pointer 16 bit Register which stores address of last item in machine stack. “PC” is Program Counter 16 bit Register which holds address of next byte to be fetched from memory.
>While it comes to 6502 registers, The Registers A, PC,P(F) works similar as Z80 register, ”X,Y” are Index registers which work out the address of a byte of data,”S” is Stack pointer which stores the address of last item on stack, here the ninth is always fixed as 1 represents page number.

>In going further lets understand the concept of Opcode and operand. In Machine code instructions, Opcode tells CPU what to perform and Operand tells it where to find data to work. In simple Opcode are the mnemonics what we write. Consider Mnemonic LD A in Z80 and 6502 is same as 3E in Z80 and A9 in 6502 0f hex.

Finding Free RAM
We usually store machine code programs is at the top of user RAM, the place where BASIC programs are stored. You have to make sure, though, that the machine code will not get mixed up with any BASIC programs. To avoid this you can tower the top of the user RAM area. This makes a “no-man’s land” above user RAM which the computer will not use until you tell it to when you load your machine code program, The top of user RAM is called RAMTOP, or HIMEM, or just top of memory. We can lower the top of user RAM.

Steps to be done
After finding free RAM ,we need to load and run a program. In order to that we have to poke each byte into area of memory. On most of computers we can only poke in decimal numbers ,this will done by ‘hexloder’. This is how we perform load and run a program. At end of every program we use instruction “RET” or “RTS”, this make computer to stop running code. In order to start machine code there are different commands on different systems like”CALL”,”SYS”,”PRINT USR” with the decimal address of location to be mentioned .Finally to see the result we have to use command “PRINT PEEK”.
Ok its look good but when we want to add data from memory , will this work? In order to counter this we have concept of “Addressing Modes”. There are different addressing modes based on data it require. “Immediate Addressing” is a type where we directly gives data in program itself whereas “Absolute Addressing” give the address of data.

What if numbers are greater than 255? For this we have concept to work with big numbers. Inside the computer, numbers over 255 are stored in two bytes, called the ‘high order byte” and the l low order byte 1 ‘, just like addresses The high order byte shows how many 256s there are in the number and the low order byte is the remainder. As with addresses, the computer always deals with the low order byte before the high order byte and we have to store them in that order in the memory.

12420/256= 48 remainder 132
|| ||
(High order byte)( Low order byte)

What if we add number greater than 256? Here comes “Carry flag”. The carry flag is a single bit in the flags register (also called the processor status register}, which is used to indicate when the answer to a sum is greater than 255 and will not fit into one byte. Whenever this happens the computer automatically puts a 1 in the carry flag. This is called setting the carry flag and making it 0 is called clearing it. In Z80 we have instructions of “ADD”, “ADC”.If we use ADD the carry will be left and flag set to 1 and if we use ADC the carry also will be added. In case of 6502 we always use ADC and CLC instruction when we do additions.

Jumping and branching
What if we want to use data in other part of program? Making the computer go to an instruction in another part of the program is called branching. There are three different ways of branching: jumps, subroutines and conditional branches. In a conditional branch the computer carries out a lest and then branches, or goes on with the next instruction, depending on the result of the test You can find out more about conditional branches over the page Jumps just tell the computer to go to a certain address.

Program counter
The program counte r is a special 1 6-bit register which holds the address of the next instruct ion the computer is to carry out. The computer reads the number in the program counter and then goes to the location with that address to fetch its next instruction. Then the program counter is increased by one so it points to the next memory location.

Subroutine
A set of instructions that are used repeatedly in a program can be referred to as a Subroutine. The instruction “CALL address” on the Z80 and “JSR address” (jump to subroutine) on the 6502, tell the computer to go to a subroutine. This is just like in BASIC and at the end of the subroutine you need the return instruction (RET on the Z3G and RTS on the 6502).

Conditional Branches
In this the computer tests one of bits in flags register and based on result either branches or carries with next instruction. Following gives the bits in flag register.

N or S -N on 6502 and S on Z80 is set to 1 when result is negative and 0 for positive
V or P/V-This is Overflow bit on 6502 and on Z80 it is called “Parity/overflow”.
C — This is a Carry flag set to 1 when the answer to sum will not fit in one byte.
The following are some instructions in Conditional branch opcodes-
In Z80
JP C(There is carry)
JP NC(No carry)
JP NZ(Not equal)

In 6502
BCS (There is carry)
BEQ(No carry)
BNE(Not equal)

After the “JP test” instruction on the Z80 you we have to give computer the address of the instruction you want it to jump to. On the 6502 we will give the computer a number which tells it how many locations it must jump forwards or backwards to find the instruction. This is called “relative addressing” and the number is called the “displacement “or “offset 1 .

How displacement work? When we give the computer a displacement number in a conditional branch, the computer works out the address of the instruction it is to jump to by adding or subtracting the displacement from the program counter. In order to work, count the number of bytes up to and including the instruction you want to jump to. So start at the instruction after the conditional branch and count that as 0.For forward jump we have to translate displacement into hex number and insert it and for backward the displacement is negative number as we know ,we can’t indicate negative number in binary .To solve that we will use 2’s complement, in this the left-hand bit is used as sign bit ,if it is 1 the number is negative else positive.

Screen Flash Program
Screen flash program is used to swap the blocks of display by loading a byte from each block into registers. Following shows the Screen flash of Z80 and 6502.
Z80 Screen Flash-
Here the program on considering two blocks swaps two blocks of display by loading byte from each block into registers, then storing byte from block b in screen address for block a and vice-versa. It uses the screen addresses for the first byte of each block are stored in registers HL and DE, the computer reads the addresses in these registers each time it loads or stores the bytes .After swapping two bytes the instruction INC (mnemonic for increment) makes it add one to HL and DE so that when the program repeats, these are the addresses of the next two bytes in each block on the screen.Register B holds the number of bytes to be swapped. Each time the program repeats, Bis decremented (decreased) by 1 so it acts as a counter. When B = 0 all the bytes have been swapped. This is how Z80 Screen Flash works.
6052 Screen Flash-
Here this program swaps the two blocks, byte by byte (character by character), starting with the last byte in each block. It loads these bytes into the registers, then stores the byte from block a in the screen location for block b and vice versa. Then the program is repeated to swap the next pair of bytes. It uses Indexed Addressing. The total number of bytes in one block is loaded into the X register Then, to store or load a byte, the number in the X register is added to the starting address for each block. The instruction DEX (decrement X) makes the computer subtract 1 from X so when the program repeats, the computer fetches the next byte back in the display. This is how 6052 Screen Flash work.

In conclusion, machine code is the behind-the-scenes that makes your computer run smoothly. It’s the language computers speak fluently, enabling them to execute tasks from the simplest to the most complex. While we may not directly interact with machine code, it forms the backbone of software and ensures your digital devices respond to your commands.

--

--