This should be useful for switching between output and pull-up input,
which can be useful for scanning switch matrices.
2XY5 shra
2XY6 rol
2XY7 ror
-2XY8
-2XY9 spi
-2XYA mft
-2XYB mtt
+2XY8 spi
+2XY9 mft
+2XYA mtt
+2XYB ddir
2XYC din
2XYD dout
2XYE ain
rjmp exec_shra
rjmp exec_rol
rjmp exec_ror
- rjmp exec_nop
rjmp exec_spi
rjmp exec_mft
rjmp exec_mtt
+ rjmp exec_ddir
rjmp exec_din
rjmp exec_dout
rjmp exec_ain
rjmp _dispatch_done
+exec_ddir:
+ ; Restrict operand to 0-f
+ ldi r25, 0x0f
+ and r10, r25
+
+ ; Extract LSB from first operand
+ ldi r23, 0x01
+ and r6, r23
+ clr r7
+
+ ; Mask of all bits except LSB
+ ldi r24, 0xfe
+ ldi r25, 0xff
+
+ ; Rotate LSB and mask into position specified by second operand
+_ddir_loop:
+ dec r10
+ brlt _din_loop_done
+
+ sec
+ rol r24
+ rol r25
+
+ clc
+ rol r6
+ rol r7
+
+ rjmp _ddir_loop
+_ddir_loop_done:
+
+ ; Read-modify-write
+ in r22, DDRB
+ in r23, DDRC
+ and r22, r24
+ and r23, r25
+ or r22, r6
+ or r23, r7
+ out DDRB, r22
+ out DDRC, r23
+
+ rjmp _dispatch_done
+
+
exec_din:
; Restrict operand to 0-f
ldi r25, 0x0f
.if @1 < 1 || @1 > 0x10
.error "Tortoise Bytecode: SPI immediate value outside 4-bit range"
.endif
- .dw (0x2 << 12) | (@0 << 8) | ((@1 & 0xf) << 4) | (0x9)
+ .dw (0x2 << 12) | (@0 << 8) | ((@1 & 0xf) << 4) | (0x8)
.endmacro
.macro T_MFT
.if @1 < 0 || @1 > 0xf
.error "Tortoise Bytecode: immediate value outside 4-bit range"
.endif
- .dw (0x2 << 12) | (@0 << 8) | (@1 << 4) | (0xa)
+ .dw (0x2 << 12) | (@0 << 8) | (@1 << 4) | (0x9)
.endmacro
.macro T_MTT
+ .if @0 < 0 || @0 > 0xf
+ .error "Tortoise Bytecode: invalid variable register"
+ .endif
+ .if @1 < 0 || @1 > 0xf
+ .error "Tortoise Bytecode: immediate value outside 4-bit range"
+ .endif
+ .dw (0x2 << 12) | (@0 << 8) | (@1 << 4) | (0xa)
+.endmacro
+
+.macro T_DDIR
.if @0 < 0 || @0 > 0xf
.error "Tortoise Bytecode: invalid variable register"
.endif