OR D1, D2 IFC
or d1 d2,ifc
Or D1 d2 IfC
oR d1, D2, iFc
ADD -6 PC IFNZ ; subtract 6 from PC if Z flag is 0
.ORG 42
.EQU plop 42
.DW 42
.DW 1,1,2,3,5,8,13,21,33
.DW forward,1,2,3
.EQU forward 21
.DB 11, "hello world"
.DH 26, "Bonjour le monde du haut !\n"
.OVL 23 MyCustomLibrary
plop:
.EQU plop $
plop : ; MUST_FAIL: don't allow spaces before ":"
NOP ; do nothing
HLT ; properly terminate a program
INV ; trigger a trap/reboot/panic
OVL 42 ; Load and execute overlay #42 (special case for CALL 42 PC)
IN 67, D3 ; get value from IOspace at address 67 and write register D3
OUT 45 A1 ; Put the value of A1 into IOspace at address 45
RC 1 D1 ; Rotate register D1 through carry by 1 position (left)
RO -3 D2 ; Rotate register D2 by 3 positions (right)
SA R1 A1 ; Arithmetic Shift of A1 by R1 positions
SH R2 A2 ; Logic shift of A2 by R2 positions
PF R3 ; put the next result in R3
; default condition is ALWS so Carry-In is set to 1
PF R1 IFN2 ; put the next result in R1
; and copy the negated condition bit #2 in the Carry-in flag
AND 123 R1 ; bit-mask R1 with byte 123
ADD -76 R2 ; subtract byte 76 from register R2
SUB 95 R3 ; Subtract R3 from byte 95 and put the result in R3
ADD 1 A1 IFC ; increment A1 by short 1 if the carry bit is set
ADD D1 A1 IFS ; Add D1 to A1 (result in A1) if the Sign/Negative flag is set.
LDCH -2 R1 ; quite pointless since it
; could be directly done with SET
; this code sends 12 constant bytes to an IO register:
set start_string R1
ldch R1 R2 ; load the constant from program memory
out 123 R2 ; send the constant to I/O
add 1 R1
cmpu end_string R1
add -4 PC IFNZ
HLT
start_string:
.BH 12, "hello world!\n"
end_string:
SA 3 R1 ; R1 = R1 << 3
SA -3 R1 ; R1 = R1 >>> 3
SA R2 R1 ; R1 arithmetic-shifted depending on the 4 LSB of R2
; TODO : more numerical examples
ADD R1 R2 ; R2 = R1 + R2
ADD 123 R3 ; R3 = R3 + 123
PF R3
ADD R1 R2 ; R3 = R1 + R2
; increment:
ADD 1 R1 ; R1 = R1 + 1
; decrement:
ADD -1 R1 ; R1 = R1 - 1
; add 5 if Zero flag is set
ADD 5 R1 IFZ ; R1 = R1 + 5
; add R2 to R1 if B2 is not set
ADD R2 R1 IF2
; If R1==42 then do something:
CMPU 42 R1 ; update the Z flag
ADD 7 PC IFNZ ; skip up to 7 instructions if Z is cleared
NOP ; 1
NOP ; 2
NOP ; 3 conditional block
NOP ; 4
NOP ; 5
NOP ; 6
; end of conditional block: 7th instruction here
; Add 16 bits (R1,R2)+=(D1,D2)
ADD D1, R1 ; might generate a carry
PF R2 IFC ; preload the Carry flag into the ALU's carry input
ADD D2, R2 ; R2=R2+D2+C
; emulate a shift-left-through-carry
; (serial input in B0, parallel output in R1)
PF R1 IF0
ADD R1 R1 ; x+x=2x, shift left, fill LSB with b0
AND R1 R2 ; R2 = R2 & R1
AND 123 R3 ; R3 = R3 & 123
; mask R2's bits into R1 if external bit 1 is set
AND R2 R1 IF0
; keep only bit 1 of R3 if the last result was positive
AND 2 R3 IFNS
OUT 123 R3 ; write the contents of R3 to the IO register #123
CALL R1 R2 ; Jump to address in R1, saves return address in R2
CALL 123 R3 ; jump to address 123, saves return address in R3
CALL R3 R1 IFZ ; Call address in R3, save in R1, if previous result is 0
CALL 46, PC ; effectively an OVL instruction, that switches to overlay #46
OVL 46 ; the equivalent of the previous line.
OVL 255 ; Overlay #255 manages program terminations.
HLT ; Equivalent of the previous line.
RO 3 R1 ; R1 = R1 rotated left by 3 bits
RO -3 R1 ; MUST_FAIL: legal(?) but pointless,
; use RO 5 R1 instead (8-3=5)
; (issue a warning ?)
RO R2 R1 ; R1 rotated depending on the 3 LSB of R2
; TODO : more numerical examples
RC 3 R1 ; R1 = R1 rotated left by 3 bits
RC -3 R1 ; MUST_FAIL: legal(?) but pointless,
; use RO 5 R1 instead (8-3=5)
; (issue a warning ?)
RC R2 R1 ; R1 rotated depending on the 3 LSB of R2
; TODO : more numerical examples and diagrams.
INV ; something went wrong here.
XOR R1 R2 ; R2 = R2 ^ R1
XOR 123 R3 ; R3 = R3 ^ 123
; XOR R2 into R1 if external bit 1 is set
XOR R2 R1 IF1
; flip bit 1 of R3 if the last result was positive
XOR 2 R3 IFNS
SUB R1 R2 ; R2 = R1 - R2
PF R1 ; reverse the destination register:
SUB R1 R2 ; R1 = R1 - R2
SUB 123 R3 ; R3 = 123 - R3
SUB 0 R1 IFNZ ; Negate R1 if last result is not zero
; TODO : multi-byte subtraction
SH 3 R1 ; R1 = R1 << 3
SH -3 R1 ; R1 = R1 >> 3
SH R2 R1 ; R1 shifted depending on the 4 LSB of R2
; TODO : more numerical examples
OR R1 R2 ; R2 = R2 | R1
OR 123 R3 ; R3 = R3 | 123
; OR R2 into R1 if external bit 2 is set
OR R2 R1 IF2
; set bit 1 of R3 if the last result was not zero.
OR 2 R3 IFNZ
; Alias:
OR D1 D1 NEVR ; must assemble to 0000h
NOP ; must also assemble to 0000h
LDCL 3 R1 ; quite pointless since it
; could be directly done with SET
; this code sends 12 constant bytes to an IO register:
set start_string R1
ldcl R1 R2 ; load the constant from program memory
out 123 R2 ; send the constant to I/O
add 1 R1
cmpu end_string R1
add -4 PC IFNZ
HLT
start_string:
.BL 12, "hello world!\n"
end_string:
; this code loops 42 times:
set 0 R1
loop:
add 1 R1
cmpu 42 R1
add -2 PC IFNZ
; TODO : multi-byte comparison
; this code loops 42 times:
set -22 R1
loop:
add 1 R1
cmps 21 R1
add -2 PC IFNZ
; TODO : multi-byte comparison
SET R1 R2 ; R2 = R1
SET 123 R3 ; R3 = 123
; set to 5 if Zero flag is set
SET 5 R1 IFZ ; R1 = 5 if previous result is 0
; copies the value of R2 into R1 if B0 is set
SET R2 R1 IF0
IN 123 R3 ; read IO register #123 and write the value to R3
PF R1 ; the next instruction will write to R1, default ALWS => Carry In = 1
PF D1 IFN2 ; next instruction writes to D1, Carry In = bit 2.
ANDN R1 R2 ; R2 = ~R2 & R1
ANDN 123 R3 ; R3 = ~R3 & 123
ANDN R2 R1 IF0 ; whatever, it's legal.
ANDN 2 R3 IFNS ; it's legal, too.
; here is how to multiplex/select arbitrary bits
; from two operands R1 and R2, and merge them into
; one byte in R3:
SET 01101101b R3 ; some mask (usually not a constant)
AND R3, R1 ; all 1s in R3 will keep R1's bits
ANDN R2, R3 ; R3 is negated then ANDed with R2
OR R1 R3 ; merge the two temporary results
; note: only R1 and R3 are modified
SUB 4 R1
PF R2
SUB R2 R1 ; R2=R2-R1
; 16-bit add:
ADD D1 R1
PF R2 IFC
ADD D2 R2
set 123 A1
add 42 D1
; PUSH:
set R1 D1 ; Write R1 to the ToS
add 1 A1
; POP:
add -1 A1
set D1 R2 ; read the ToS into R2
; The main program:
set 42 R2 ; argument for myfunction
call myfunction D1
add 24 R3 : do something
;...
myfunction:
add 1 A1 ; update the stack pointer
;...
; do something useful here
call leaf_function D1
;...
; return:
add -1 A1 ; restore the stack pointer
set PC D1 ; jump back to the caller
leaf_function:
; no other call here so no need to
; fiddle with the stack pointer
;...
; do something
set PC D1 ; return
.END
somefunction:
add 1 A1 ; prolog: update the stack pointer
; you can use D1 as a temporary register here
; until the next function call:
call another_function D1
; D1 is available for temporary use here again.
; return / epilog:
add -1 A1 ; restore the stack pointer
set PC D1 ; jump back to the caller
set 42 a1
set 21 d1
set a1 a2
; -> d2=21
set 77 d2
; -> d2=77 but d1 is still 21
set a1 a1
; refresh => d1=77
; if R1==42 then...
cmpu 42 R1
add endofif-$ PC NZ
; do something useful here
; (only 6 instructions at most)
endofif:
; if R1==42 then...
set endofif D1
cmpu 42 R1
set D1 PC NZ
; do something useful here that
; takes more than 6 instructions
endofif:
set 42 R1; some loop counter
set dumbloop R2
dumbloop:
; do something long and hopefully useful here
add -1 R1
set R2 PC NZ ; loop back if R1 has not reached zero
set 42 R1 ; some loop counter
loopentry:
; do something long and useful here
set loopentry R2
add -1 R1
set R2 PC NZ
; end of loop
ConstantStrings:
.BL "Hello world"
EndOfFirstString:
.ORG ConstantStrings ; go back to the address
; of the first byte created by BL and write
; to the upper byte.
.BH "This is another test string"
EndOfSecondString:
; Now go to the very end of the longest string:
.ORG (EndOfFirstString UMAX EndOfSecondString)
; More constants or instructions here.
; Streams the first string to IO register #123:
set ConstantStrings R1
ldcl R1 R2 ; load the constant from program memory
out 123 R2 ; send the constant to I/O
add 1 R1
cmpu EndOfFirstString R1
add -4 PC IFNZ
HLT
ConstantData:
.DW 1234, 4567, 9012, 3456
EndOfData:
set ConstantData R1
ldcl R1 R2
out 123 R2
ldch R1 R2
out 123 R2
add 1 R1
cmpu EndOfData R1
add -6 PC IFNZ
HLT