Instructions Welcome to RRNIC! WHAT IT IS: ----------- Rrnic is a tool for debugging runcode on the RISC processor (MIPS R3000 based) on the Roadrunner based NIC. This tool does not merely simulate what happens. It lets you directly access the memory of the NIC, look at the registers, and step through the runcode. HOW TO USE IT: -------------- First of all, you can load your program (and/or data) using the "Download to NIC..." menu item in the File menu. Also, you can dump selected contents of the memory of the NIC to a file using the "Dump from NIC SRAM..." menu item in the File menu. There are big buttons for Halt, Unhalt, and Step. You have to be halted to step. If you want to set the program counter, first of all you do have to halt the runcode first (with the halt button). Then you just type the value you want (hex, dec, oct, whatever--C style constant) into the program counter text entry field, and hit enter when done. The current instruction is highlighted in white in the code display window. Similarly, you can set the program breakpoint using it's entry. The breakpoint is highlighted in red in the code display window. The breakpoint is often set to zero when you start playing. If you have set the breakpoint and stop there, then you should press the halt button before trying to step, because otherwise the program will take off like a bottle rocket out of your hand when it gets moved past the breakpoint. If you want to disable the breakpoint, you can either type in (disabled) or enter a value like 1 that has LSB set (this is how the card sees it). Or just set it to zero or some other unlikely place. Whenever you interact with these controls, the display automatically updates. This includes the register display and the extra data display if you have defined a nonempty range of memory to look at. To do this, just enter the start and end values in the entries under more data, and you will magically see the contents of memory. If at any time you want to make sure the display is up to date (if, for instance, the processor has not been halted, then values may be continually changing), you can hit the big "Update View" button. Changes to the information in the registers view and the more data view are highlighted in pink by default. If this becomes too slow, you can turn it off via menu items under Options. There's a "Reset NIC" command available under the Control menu. This causes a complete reset of the NIC just as if it had been requested by the PCI bus. I'm not entirely sure of the details of what this does :> HINTS: --------- When setting the PC, you have to halt the PC first, otherwise no effect. Also, it seems to work best to "zap" the pipeline by setting the PC to 0xFEEDFACE first, before setting PC to the desired value. Rrnic does this for you automatically by default. You can toggle this in the options menu. The register that specifies the base address for storing with the SW instruction is rs (the first register in the bit pattern); the value to store goes in rt (the second register in the bit pattern). When debugging in rrnic, you may not see the result of the store until the PC gets to the third operation after the store operation. The documentation describes the ADDIU instruction as opcode 0x11, but the roadrunner complains that this is an invalid opcode. However, I have discovered that opcode 0x10 seems to act like an ADDIU. The SDW instruction (store double word) works, but doesn't store the second word if the offset is not on an 8 byte boundary, so be careful. So, for example, the following works: _ 101000 00000 00010_ $0a00$ // ORI r0,0xA00,r2 _ 001001 00010 00100_ $0008$ // SDW r4,[r2+8] While this silently blows: _ 101000 00000 00010_ $0a0c$ // ORI r0,0xA0c,r2 _ 001001 00010 00100_ $0008$ // SDW [r2+8],r4 (N.B. r2 is the address, r4 is the data). LUI will clear the LSB's, so I guess rs is not relevant, only rt is. SLTI and SLTIU compare rs with imm and store the result in rt, considering the respective values as signed or unsigned respectively. SLT and SLTU compare rs with rt and store the result in rd, again considering whether to be signed or not. XNOR is perhaps better named NXOR, since it seems to be similar to NOR and NAND, which is to say, it does the XOR, and then negates the result. PRI tells you the bit index (i.e. bit 0 (LSB) to bit 31 (MSB)) of the MSB after ANDing rs and rt. SLL and SRL apparently ignore rs, and shifts rt by the shift amount (shamt), storing the result in rd. These, then are the immediate operand versions. SLLV and SRLV apparently take the amount to shift by as the first register (rs), and the register to shift as the second register (rt). The jump instructions that take an immediate address add two bits onto the ends of the addresses. The ones that use registers do not (naturally). The jump and link instruction stores the return addresses in r31. The jump and link (from register) instruction stores the return address in the register specified by rd. The formula put forth for the JOFF instruction is deceptive. Perhaps it should read PC <- ((rs%whatever)&~11)+((rt%yeahyeah)<<3). Anyway, the idea is to put the base address of the jump table in rs, and the index of the pair you want to jump to in rt. BEQ and BNE compare rs and rt, and branch forward or backwards by the number of instructions given (from the instruction after the branch). The other branches compare rs to zero and branch similarly. BLTZAL and BGEZAL store the return address into r31.