instruction memory progammer: is in and works in simulations
[calu.git] / 2_isa / src / bootrom.c
index d6e672eb32c55a1d3dac4de3aced68da5d0c7ed3..58a678cd10efbd4c7f29fafb1d4cf5ff812a2ecd 100644 (file)
  * 'R'0xZZZZZZZZ          | H -> C    | read instr from address (0xZZ..Z)
  * 'F'0xYYYYYYYY          | C -> H    | instr read done and return instr
  *
+ * 'Q'0xZZZZZZZZ0xYYYYYYYY| H -> C    | write data (0xYY...Y) to
+ *                                    | address (0xZZ...Z)
+ * 'A'                    | C -> H    | data write done
+ *
+ * 'T'0xZZZZZZZZ          | H -> C    | read data from address (0xZZ..Z)
+ * 'G'0xYYYYYYYY          | C -> H    | read done and return data
+ *
  * 'J'0xZZZZZZZZ          | H -> C    | jump to address (0xZZ...Z)
  */
 
 #define UART_RECV_NEW 1
 
 /* TODO:
- * - use different read/write functions for instr and data space
- * - need absolute jump for program entry?
+ * - uart: clear new_receive bit after the byte is copied?
+ *   (implementation issue...)
  */
 
+/* {d,i}{read,write}{8,32}:
+ * d ... data space
+ * i ... instruction space
+ */
+
+typedef unsigned char u8;
+typedef unsigned int u32;
+
 void send_byte(u8 x)
 {
-       while(!(UART_STATUS & (1 << UART_TRANS_EMPTY)));
-       write8(UART_TRANS, x);
+       while(!(dread32(UART_STATUS) & (1 << UART_TRANS_EMPTY)));
+       dwrite8(UART_TRANS, x);
 }
 
 void send_word(u32 x)
@@ -49,8 +64,8 @@ void send_word(u32 x)
 u8 recv_byte(void)
 {
        u8 ret;
-       while(!(UART_STATUS & (1 << UART_RECV_NEW)));
-       ret = read8(UART_RECV);
+       while(!(dread32(UART_STATUS) & (1 << UART_RECV_NEW)));
+       ret = dread8(UART_RECV);
 }
 
 u32 recv_word(void)
@@ -73,15 +88,28 @@ void bootrom(void)
                                addr = recv_word();
                                instr = recv_word();
                                /* write to programm space */
-                               write32(addr, instr);
+                               iwrite32(addr, instr);
                                send_byte('D');
                                break;
                        case 'R':
                                addr = recv_word();
-                               instr = read32(addr);
+                               instr = iread32(addr);
                                send_byte('F');
                                send_word(instr);
                                break;
+                       case 'Q':
+                               addr = recv_word();
+                               instr = recv_word();
+                               /* write to data space */
+                               dwrite32(addr, instr);
+                               send_byte('A');
+                               break;
+                       case 'T':
+                               addr = recv_word();
+                               instr = dread32(addr);
+                               send_byte('G');
+                               send_word(instr);
+                               break;
                        case 'J':
                                addr = recv_word();
                                jump_to_instr_mem(addr);
@@ -105,11 +133,10 @@ void main(void)
        u32 to = TIMEOUT_START;
        u8 rec;
 
-       /* until to overflows */
+       /* until to is zeros */
        while(to != 0) {
-               /* noob timeout hack */
-               to++;
-               if(UART_STATUS & (1 << UART_RECV_NEW)) {
+               to--;
+               if(dread32(UART_STATUS) & (1 << UART_RECV_NEW)) {
                        rec = read8(UART_RECV);
                        if(rec == 'H') {
                                send_byte('O');