|
| 1 | +.text |
| 2 | + .global main: |
| 3 | + |
| 4 | +; (blocking) reads one char from uart to the D register |
| 5 | +; pollutes A, B, C, D |
| 6 | +; needs 1 stack space |
| 7 | +uart_read_char: |
| 8 | + ; push address of misc.in (which contains if uart is writeable/readable), and read option |
| 9 | + LDV B, (0b110) |
| 10 | + PSH B |
| 11 | + SYS |
| 12 | + ; pop read value in B |
| 13 | + POP B |
| 14 | + ; get second-to-last bit: AND with 2 |
| 15 | + LDV A, 2 |
| 16 | + AND A, B |
| 17 | + ; if A now contains 2, that means we can read from uart |
| 18 | + LDV C, uart_read_char: |
| 19 | + LDV B, 2 |
| 20 | + ; if A == 0, then A < B and we will retry |
| 21 | + JLT B, C |
| 22 | + |
| 23 | + ; read from uart to D register |
| 24 | + |
| 25 | + LDV A, (0b1010) |
| 26 | + PSH A |
| 27 | + SYS |
| 28 | + POP D |
| 29 | + RET |
| 30 | + |
| 31 | +; (blocking) write the D register to uart |
| 32 | +; pollutes A, B, C |
| 33 | +; needs 2 stack space |
| 34 | +uart_send_char: |
| 35 | + LDV B, (0b110) |
| 36 | + PSH B |
| 37 | + SYS |
| 38 | + ; pop read value in B |
| 39 | + POP B |
| 40 | + ; get last bit: AND with 1 |
| 41 | + LDV A, 1 |
| 42 | + AND A, B |
| 43 | + ; if A now contains 1, that means we can write to uart |
| 44 | + LDV C, uart_send_char: |
| 45 | + LDV B, 1 |
| 46 | + ; if A == 0, then A < B and we will retry |
| 47 | + JLT B, C |
| 48 | + |
| 49 | + ; else write to uart |
| 50 | + PSH D |
| 51 | + LDV A, (0b1001) |
| 52 | + PSH A |
| 53 | + SYS |
| 54 | + RET |
| 55 | + |
| 56 | +; blocking, reads two chars from uart into a 16-bit value into the D register |
| 57 | +; the first character is the most significant byte, the second character the least |
| 58 | +; pollutes A, B, C, D |
| 59 | +read_16_bits_from_uart: |
| 60 | + LDV A, uart_read_char: |
| 61 | + CAL A |
| 62 | + ; D contains the first 8 bits of the address, shift it and push it onto the stack |
| 63 | + LSH D, 7 |
| 64 | + LSH D, 1 |
| 65 | + PSH D |
| 66 | + LDV A, uart_read_char: |
| 67 | + CAL A |
| 68 | + ; D now contains the last 8 bits of the address |
| 69 | + |
| 70 | + POP C |
| 71 | + ; C now contains the first 8 bits of the address |
| 72 | + |
| 73 | + OR D, C |
| 74 | + ; now D contains the full address |
| 75 | + RET |
| 76 | + |
| 77 | +main: |
| 78 | + ; send a single '>' |
| 79 | + LDV A, uart_send_char: |
| 80 | + LDV D, 62 |
| 81 | + CAL A |
| 82 | + |
| 83 | + LDV A, read_16_bits_from_uart: |
| 84 | + CAL A |
| 85 | + ; push the address onto the stack |
| 86 | + PSH D |
| 87 | + LDV A, read_16_bits_from_uart: |
| 88 | + CAL A |
| 89 | + ; the value to load is now in the D register |
| 90 | + POP C |
| 91 | + LDP C, D |
| 92 | + ; The first ever instruction will be a jump to main |
| 93 | + ; this makes it easy to transfer control flow to the now-loaded program: |
| 94 | + ; you just need to overwrite the jump in address 0 with a jump to your loaded program |
| 95 | + JMP 0 |
0 commit comments