Table of Contents
Program Control
Mnemonic | Code | short description | description |
---|---|---|---|
NOP | 00 | No Operation | Nothing happens, but the execution of this instruction will use up processor cycles. Often used to prepare for code to be added later, or to replace by jumps for debugging. |
WAIT #x | 2x | wait <time> | Delay of program execution by a defined time 1⇐ x ⇐ 15, according to the table defined ahead. . Alternatively a string can be used as well. Possible values are: 1ms, 2ms … 60s. |
RJMP #x | 3x | Jump back | A Jump Back by x instructions, or to :label |
PAGE #x | 8x | page #x | To set the Page Register 0 ⇐ x < 16 |
JMP #x | 9x | jump to #x + 16 * page | Jump to address #x + (16 * page) 0 ⇐ x < 16 |
LOOPC #x | Ax | loop c | If C>0: C=C-1; Jump to #x + (16*page), else execute next instruction |
LOOPD #x | Bx | loop d | If D>0: D=D-1; Jump to #x + (16*page), else execute next instruction |
SKIP0 | C0 | Skip if A = 0 | SKIP over next instruction if A = 0 |
AGTB | C1 | Skip if A > B | SKIP over next instruction if A > B |
ALTB | C2 | Skip if A < B | SKIP over next instruction if A < B |
AEQB | C3 | Skip if A = B | SKIP over next instruction if A = B |
DEQ#y #x | C4..CB | Skip if Din.X = Y | SKIP next instruction if the INPUT #y 0 or 1 is. x=0,1 |
PRG#x | CC, CE | Skip if PRG = x | SKIP next instruction if PRG switch is pushed(0) or not pushed (1) is. x=0,1 |
SEL#x | CD, CF | Skip if SEL = x | „ the same only for SEL |
CALL #x | Dx | Call #x + (16 * page) | Jump to subroutine at #x + (16*page) |
RTR | E0 | Return | Jump back after a CALL Instruction or at the end of a Subroutine |
CASB #x | E1..E6 | Call sub #x | CALL of a Subroutine x, 1 ⇐ x ⇐ 6 |
DFSB #x | E8..ED | Define sub #x | Definition of a Subroutine x, 1 ⇐ x ⇐ 6 |
REST | EF | Restart program | |
PEND | FF | Program end |
LOAD and STORE
Mnemonic | Code | short description | Beschreibung |
---|---|---|---|
LDA ##x | 4x | A = #x | LOAD Register A with the fixed value #x |
SWAP | 50 | Swap A & B | SWAP the contents of Register A and B |
MOV X,Y | 51..53, 61..63, 5D, 5E, 6D, 6E | X = Y | MOVE (copy) the contents of one Registerrt into another Register. X and Y can be the following values: A, B, C, D, E, F |
PUSH | 5F | push A on stack | The contents of Register A is pushed onto the Stack. |
POP | 6F | Pop value from stack to A | The Top Value on the Stack is moved into the A Register and removed from the Stack |
Math Instructions
Mnemonic | Code | short description | Beschreibung |
---|---|---|---|
INC | 71 | A = A + 1 | Increment the contents of Register A by one |
DEC | 72 | A = A - 1 | Decrement A |
ADD | 73 | A = A + B | Add contents of Register A and B into Register A |
SUB | 74 | A = A - B | Subtract B from A with result in Register A (can then be negative number) |
MUL | 75 | A = A * B | Multiply the contents of Register A and B, result in Register A. Any overflow is discarded. |
DIV | 76 | A = A / B | Divide A by B |
AND | 77 | A = A and B | Logical AND the 4 Bits in A with B, result in Register A |
OR | 78 | A = A or B | Logical OR the 4 Bits in A with B, result in Register A |
XOR | 79 | A = A xor B | Logical XOR the 4 Bits in A with B, result in Register A |
NOT | 7A | A = not A | Invert all 4 bits in Register A |
MOD | 7B | A = A % B | Remainder of A/B |
BYTE | 7C | A = A + 16 * B | Add A plus 16x B into A; now this register value has 8 Bits instead the usual 4 |
BSUBA | 7D | A = B - A | Subtract A from B with result in A |
Input / Output
Mnemonic | short description | description | |
---|---|---|---|
LDA DIN | 64 | A = Din | Load Register A with the Value of the Input bits. All 4 Bits |
LDA DINx | 65..68 | A = Din.x | Load Register A.0 with the Value of one Input bit. #x. x = 1..4 |
LDA ADCx | 69, 6A | A = ADC.x | Load Register A with the Value of an Analog Input #x. x = 1..2 |
LDA RCx 6B, 6C | A = RC.x | Load Register A with the Value of an RC Input #x. x = 1..2 | |
PORT #x | 1x | Dout = #x | Direct Output of the Value #x to the 4 Output Bits. 0 ⇐ x ⇐ 15. |
STA DOUT | 54 | Dout = A | Output of Register A to the Output Bits |
STA DOUTx | 55..58 | Dout.x = A | Output of Bit A.0 to an Output Bit x = 1..4 |
STA PWMx | 59, 5A | PWM.x = A | The Value of Regiuster A is Output on PWM.x. x = 1,2 |
STA SRVx | 5B, 5C | Servo.x = A | The Value of Regiuster A is Output as Servo.x Position. x = 1,2 |
BYTE Instructions
Mnemonic | Code | short description | description |
---|---|---|---|
BLDA ADCx | F0, F1 | A = ADC.x | LOAD BYTE Value of an Analog Input into Register A. x = 1,2 |
BLDA RCx | F2, F3 | A = RC.x | LOAD BYTE Value of an RC Channel into Register A. x = 1,2 |
BSTA PWMx | F4, F5 | PWM.x = A | STORE BYTE Value in Register A as PWM.x. x = 1,2 |
BSTA SRVx | F6, F7 | Servo.x = A | STORE BYTE Value in Register A as Servo.x Position. x = 1,2 |
TONE | F8 | Tone A | Output of a Tone according to Midi 32 ⇐ A ⇐ 108 |
Labels
You can also use a label for the Jump, Loop and Call commands. The associated PAGE command must be implemented separately. The Jump Address is calculated automatically, if the argument of the page command is set to:?. Example:
:Loop PORT #4 WAIT 200ms PORT #0 WAIT 200ms PAGE :? JMP :Loop
Labels are allowed with the Mnemonics RJMP, JMP, LOOPC, LOOPD and CALL. The two extended commands DFSB and CASB for subroutine execution do also have support for labels. Thus, something like this will also work:
CASB :Blink ... DFSB :Blink PORT #4 WAIT 200ms PORT #0 WAIT 200ms RTR
Comments
Comments are allowed. There are 2 types of comments: Block comments go over several lines, start with “ \* ” and end with “ */ ”.
Line comments start with a ; , stand behind the argument and the assembler ignores the rest of the line.
Example:
/* Comment with more lines */ :loop PORT #0x0F ; Line comment WAIT 200ms PORT #0x00 WAIT 200ms RJMP :loop
JMP, CALL, LOOPx and PAGE
For Absolute Jumps, the argument of the mnemonics and additionally the contents of the PAGE register are always used. The address is then calculated as: adr = #x + (16 * PAGE). You will have to calculate the PAGE contents and set the corresponding PAGE command before the Jump Instruction. Here the assembler can help with this calculation: If there is a PAGE instruction with an argument ? just before the Jump Instruction, the Assembler will calculate the PAGE number. Example:
PAGE :? JMP :loop2 :loop PORT #0x0F WAIT 200ms :loop2 PORT #0x00 WAIT 200ms RJMP :loop
Here, the correct page is automatically entered in the first PAGE command.
DOUT
The command DOUT can occur in 3 different variants.
- DOUT (without argument): Register A is sent on the outputs.
- DOUT 1..4: The argument is a number of 1..4. In this case, only the respective output bit (1..4) is switched. If register A = 0, the related output becomes logic 0, if A = 1, the output becomes logic 1. The remaining 3 outputs remain unchanged.
- DOUT # 0..15: The argument is output directly on all 4 outputs. Example: DOUT # 9 switches outputs 1 and 4 to logical 1 and outputs 2 and 3 to logical 0.
For example:
LDA 0x01 DOUT 0x04 ; will output 1 on output **D4** ausgeben. because Register A's value is 1. DOUT #0x04 ; will output 1 on output **D3**. (0x04 = 4 = 0b00000100)
Macros
You can also use Macros to simplify programs. First of all, you have to define a Macro. As example here the Blink function:
PORT #0B1111 WAIT 200ms PORT #0B0000 WAIT 200ms
In order to be able to use these as Macros in different places, one must first mark the place as a macro. This is done by marking beginning and end with .macro and .endmacro . After .macro you have to write the name of the macro under which you want to use the macro. Result of this Macro definition:
.macro blink PORT #0B1111 WAIT 200ms PORT #0B0000 WAIT 200ms .endmacro
And you can make certain values even variable. Here, for example, which LEDs should flash and how long the wait should be.
.macro blink output delay PORT output WAIT delay PORT #0B0000 WAIT delay .endmacro
In the actual program you can call the macro with e.g.
.blink #0B1010 200ms
aufrufen.
Macros must be defined before the first call. The whole program is now:
.macro blink output delay PORT output WAIT delay PORT #0B0000 WAIT delay .endmacro :loop .blink #0B1111 200ms RJMP :loop
Directives
The assembler supports various directives. We have already met some of them, the macros, loops…
Further:
.arduinosps: this sets the hardware to Arduino_TPS. This directive should appear before the actual code. .tinysps: sets the hardware to the Tiny_TPS. .atmega8: sets the hardware to the ATMega8. .holtek: sets the hardware to Holtek. .include
With this directive you can include a subprogram from another file. (This feature is not supported in web mode) With ``.include Blink `` a Blink.asm file is included in the program at this point. This means that the entire code of this file is in this place as if it had been written there in the original file.