/* FSE_parse_opcode: parsing opcodes from generated code
* In: $r10: pointer to generated code
*Out: none
*/
FSE_parse_opcode:
push $r1
push $r2
push $r3
push $r4
push $r5
push $r6
push $r7
push $r8
push $r9
FSE_parse_opcode_loop:
/* store the opcodes */
mov $r1 0x00
mov $r2 0x01
mov $r3 0x02
mov $r4 0x10
mov $r5 0x11
mov $r6 0x12
mov $r7 0x13
mov $r8 0x20
mov $r9 0xff
mov b32 $r15 $r10
/* load the first position of generated code */
ld b8 $r11 D[$r15 + 0]
cmpu b8 $r11 $r1
bra e #FSE_delay_ns_fr
cmpu b8 $r11 $r2
bra e #FSE_delay_ns
cmpu b8 $r11 $r3
bra e #FSE_delay_us
cmpu b8 $r11 $r4
bra e #FSE_write
cmpu b8 $r11 $r5
bra e #FSE_write_b8
cmpu b8 $r11 $r6
bra e #FSE_mask
cmpu b8 $r11 $r7
bra e #FSE_wait
cmpu b8 $r11 $r8
bra e #FSE_send_msg
cmpu b8 $r11 $r9
bra e #FSE_exit
/* unknown opcode*/
mov $r10 0
bra #FSE_exit
/* Full range delay */
FSE_delay_ns_fr:
mov b32 $r1 $r15
/* ld b32 $r10 D[$r1 + 1] */
add b32 $r10 $r1 1
call #ld_32
/* r2 = r10 = HIGH */
mov b32 $r2 $r10
/* ld b32 $r11 D[$r1 + 5] */
add b32 $r10 $r1 5
call #ld_32
/* r11 = r10 = LOW */
mov b32 $r11 $r10
/* r10 = r2 = HIGH */
mov b32 $r10 $r2
/* r10 = HIGH r11 = LOW */
call #sleep_ns
/* Position + 9 */
add b32 $r10 $r1 9
bra #FSE_parse_opcode_loop
FSE_delay_ns:
mov b32 $r1 $r15
/* ld b32 $r11 D[$r1 + 1] */
/* r11 = LOW */
add b32 $r10 $r1 1
call #ld_16
mov b32 $r11 $r10
/* r10 = HIGH = 0 */
mov $r10 0x0
call #sleep_ns
add b32 $r10 $r1 3
bra #FSE_parse_opcode_loop
FSE_delay_us:
mov b32 $r1 $r15
/* ld b32 $r11 D[$r1 + 1] */
/* r11 = LOW */
add b32 $r10 $r1 1
call #ld_16
mov b32 $r11 $r10
mulu $r11 1000
/* r10 = HIGH = 0 */
mov $r10 0x0
call #sleep_ns
add b32 $r10 $r1 3
bra #FSE_parse_opcode_loop
FSE_write:
mov b32 $r1 $r15
/* r2 = REG */
/* ld b32 $r2 D[$r1 + 1] */
add b32 $r10 $r1 1
call #ld_32
mov b32 $r2 $r10
/* r11 = VAL */
/* ld b32 $r11 D[$r1 + 5] */
add b32 $r10 $r1 5
call #ld_32
mov b32 $r11 $r10
/* r10 = r2 = reg */
mov b32 $r10 $r2
call #mmwr
add b32 $r10 $r1 9
bra #FSE_parse_opcode_loop
FSE_write_b8:
mov b32 $r1 $r15
/* r2 = REG */
/* ld b32 $r2 D[$r1 + 1] */
add b32 $r10 $r1 1
call #ld_32
mov b32 $r2 $r10
/* r11 = VAL */
/* ld b8 $r11 D[$r1 + 5] */
add b32 $r10 $r1 5
call #ld_08
mov b32 $r11 $r10
/* r10 = r2 = reg */
mov b32 $r10 $r2
call #mmwr
add b32 $r10 $r1 6
bra #FSE_parse_opcode_loop
FSE_mask:
mov b32 $r1 $r15
/* r2 = REG */
/* ld b32 $r2 D[$r1 + 1] */
add b32 $r10 $r1 1
call #ld_32
mov b32 $r2 $r10
/* r3 = MASK */
/* ld b32 $r3 D[$r1 + 5] */
add b32 $r10 $r1 5
call #ld_32
mov b32 $r3 $r10
/* r4 = DATA */
/* ld b32 $r4 D[$r1 + 9] */
add b32 $r10 $r1 9
call #ld_32
mov b32 $r4 $r10
mov b32 $r10 $r2
call #mmrd
and $r11 $r10 $r3
or $r11 $r11 $r4
mov b32 $r10 $r2
call #mmwr
add b32 $r10 $r1 13
bra #FSE_parse_opcode_loop
FSE_wait:
mov b32 $r1 $r15
/* r2 = REG */
/* ld b32 $r2 D[$r1 + 1] */
add b32 $r10 $r1 1
call #ld_32
mov b32 $r2 $r10
/* r3 = MASK */
/* ld b32 $r3 D[$r1 + 5] */
add b32 $r10 $r1 5
call #ld_32
mov b32 $r3 $r10
/* r4 = DATA */
/* ld b32 $r4 D[$r1 + 9] */
add b32 $r10 $r1 9
call #ld_32
mov b32 $r4 $r10
FSE_wait_loop:
mov b32 $r10 $r2
call #mmrd
and $r11 $r10 $r3
cmpu b32 $r11 $r4
bra ne #FSE_wait_loop
add b32 $r10 $r1 13
bra #FSE_parse_opcode_loop
FSE_send_msg:
mov b32 $r1 $r15
/* r12 = payload_size */
/*ld b16 $r12 D[$r1 + 1] */
add b32 $r10 $r1 1
call #ld_16
mov b32 $r12 $r10
/* r13 = start of payload */
add b32 $r13 $r1 3
/*store incremented pointer*/
add b32 $r1 $r1 3
add b32 $r1 $r1 $r12
/* Add value $r11:msg_id */
mov $r11 0x02
/* pid = r10 = 0x02 */
mov $r10 0x02
call #rdispatch_send_msg
mov b32 $r10 $r1
bra #FSE_parse_opcode_loop
FSE_exit:
pop $r9
pop $r8
pop $r7
pop $r6
pop $r5
pop $r4
pop $r3
pop $r2
pop $r1
ret