Special instructions - CodeAbbey/intel4004-emu GitHub Wiki

There remain few instructions still not discussed, but quite useful in certain cases.

###Loading data from code memory

  • FIN loads a byte into register pair specified from the code memory pointed by R0:R1
  • DB - not an instruction, but a directive used to store arbitrary bytes in the code rather than compiled instructions

This instruction is useful for long constant data, i.e. text strings. As you know, instructions after compilation are stored in code memory (ROM) taking one or two bytes each. It is possible to use part of this memory not for commands but for storing arbitrary bytes with special directive db.

Let us see how this may work:

jun start

something:
db $41

start:
fim r0 something   ; load address of data byte to r0:r1
fin r2             ; load byte from code pointed by r0:r1 into r2:r3
jms $3e0           ; print a character

Run this in emulator to see letter A printed (ASCII code is $41) as a result (don't forget to clear input before running).

How this works?

First two bytes of code memory are taken by jun instruction, then follows byte $41 which we mark with something to refer to it later, and then remaining code follows (from address 3).

We load the address of label something (which is 2) into the pair r0:r1 with fim instruction and then execute fin which fetches the byte from code and places it where we want it (into r2:r3). So now we call magic print character subroutine and see A at console.

The DB directive could be followed by decimal or hexadecimal values - each meaning a separate byte, or character strings (in single quotes) - and any mix of them, for example:

hw_str: db 'Hello, World!' 13 $a 0   ; zero-terminated sequence of bytes with line-end characters

Note that usually we place our data at beginning of the program (and jump over it) for several reasons:

  • we do not want CPU to try to execute them as code if they are placed after some meaningful instructions;
  • we want data addresses be small so that they fit into one byte (real CPU loads data from specific page of code memory but emulator does not follow this queer behavior).

Check hellow.asm from examples folder to see how longer string could be printed.

###Decimal correction

To work with decimal numbers there are two handy instructions, which allow storing numbers as decimal values in a series of registers (or memory cells):

  • DAA performs decimal adjust for addition on Accumulator - it means, if accumulator is 10 or greater, then 10 is subtracted from it and Carry is set
  • TCS (transfer carry subtract) - Accumulator is loaded either with 10 if Carry was set, or with 9 if was not - and Carry itself is cleared

The first of them allows us perform decimal addition easily. For example let us sum 6+7:

fim r0 $67  ; r0 = 6, r1 = 7
ld r0       ; acc = 6
clc         
add r1      ; acc += 7, now it is 13
daa         ; acc -= 10, carry = 1

You see, after this Accumulator gets the lower decimal digit (3) and Carry is raised so it could be added to next digit.

The second could be used in the similar manner for subtraction. I hope to add comprehensive example later.

Next: Debugging and working with Console - read about emulator's special features