.data .text .define UART_BASE, 0x1000 .define UART_STATUS, UART_BASE+0x4 .define UART_RECV, UART_BASE+0x8 .define UART_TRANS, UART_BASE+0xC .define UART_BAUD, UART_BASE+0x10 .define UART_TRANS_EMPTY, 0 .define UART_RECV_NEW, 1 .define TIMEOUT_START, 0x13371337 .define DEFAULT_PROG_START, 0x200 .define STACKSTART, 0x500 ; FIXME ;----- main: ; setup stackframe ldil r15, STACKSTART@lo ldih r15, STACKSTART@hi movst r15 ldil r3, TIMEOUT_START@lo ldih r3, TIMEOUT_START@hi timeout_loop: ldil r3, UART_STATUS@lo ldih r3, UART_STATUS@hi ldw r3, 0(r3) andx r3, 1 << UART_RECV_NEW brzs+ next; branch if zero call recv_byte ; we received the enter bootrom sign cmpi r0, 0x48 ; 'H' breq- bt_H next: subi r3, r3, 1 brnz+ timeout_loop ; call to default entry point ldil r0, DEFAULT_PROG_START@lo ldih r0, DEFAULT_PROG_START@hi brr r0 ;----- send_byte: ldil r3, UART_STATUS@lo ldih r3, UART_STATUS@hi ldw r3, 0(r3) andx r3, 1 << UART_TRANS_EMPTY brzs+ send_byte ; branch if zero ldil r3, UART_TRANS@lo ldih r3, UART_TRANS@hi stb r1, 0(r3) ret ;----- send_word: lrs r0, r1, 0 call send_byte lrs r0, r1, 8 call send_byte lrs r0, r1, 16 call send_byte lrs r0, r1, 24 call send_byte ret ;----- recv_byte: ldil r3, UART_STATUS@lo ldih r3, UART_STATUS@hi ldw r3, 0(r3) andx r3, 1 << UART_RECV_NEW brzs+ send_byte ; branch if zero ldil r3, UART_RECV@lo ldih r3, UART_RECV@hi ldb r0, 0(r3) ret ;----- recv_word: ldisl r0, 0x0 call recv_byte or r0, r0, r1 call recv_byte lls r1, r1, 8 or r0, r0, r1 call recv_byte lls r1, r1, 16 or r0, r0, r1 call recv_byte lls r1, r1, 24 or r0, r0, r1 ret ;----- bootrom: call recv_byte cmpi r0, 0x57 ; 'W' breq- bt_W cmpi r0, 0x52 ; 'R' breq- bt_R cmpi r0, 0x51 ; 'Q' breq- bt_Q cmpi r0, 0x54 ; 'T' breq- bt_T cmpi r0, 0x4a ; 'J' breq- bt_J ; cmpi r0, 0x48 ; 'H' ; breq bt_H ; FALL THROUGH ;) bt_H: ldisl r1, 0x4f ; 'O' call send_byte br bootrom bt_W: call recv_word ; receive addr mov r6, r0 call recv_word ; receive instr stx r0, 0(r6) ldisl r1, 0x44 ; 'D' call send_byte br bootrom bt_R: call recv_word ; receive addr mov r2, r0 ldisl r1, 0x46 ; 'F' call send_byte ldx r1, 0(r2) call send_word br bootrom bt_Q: call recv_word ; receive addr mov r6, r0 call recv_word ; receive data stw r0, 0(r6) ldisl r1, 0x41 ; 'A' call send_byte br bootrom bt_T: call recv_word ; receive addr mov r2, r0 ldisl r1, 0x47 ; 'G' call send_byte ldw r1, 0(r2) call send_word br bootrom bt_J: call recv_word brr r0 ; 102 instr. please update after modification