Instructions for the TC-201, Fall 2007 (last update: 10/25/07) Random Access Memory (RAM) is 4096 words of 16 bits each. Memory addresses are numbers between 0 and 4095 inclusive. Each instruction consists of a 4 bit operation code (opcode) and a 12 bit address field. Not all instructions make use of the address field. The program counter (PC) is a 12 bit register. The accumulator (ACC) is a 16 bit register. There is a 1 bit arithmetic error bit (AEB). Here is a list of the instructions and what they do. opcode symbolic name function 0000 halt stops program execution 0001 load copies contents of the addressed word into ACC 0010 store copies contents of ACC into addressed word 0011 add adds contents of addressed word to ACC 0100 sub subtracts contents of addressed word from ACC 0101 read copies number from user into addressed word 0110 write writes number from addressed word out to user 0111 jump copies the instruction address to the PC 1000 skipzero skips next instruction if ACC is +0 1001 skippos skips next instruction if ACC is positive 1010 skiperr skips next instruction if AEB is 1 and sets it to 0 1011 loadi copies contents of word indirectly addressed to ACC 1100 storei copies contents of ACC to word indirectly addressed Opcodes 1101, 1110, and 1111 are unused -- they should stop program execution, just like halt. Arithmetic. By autocratic fiat, the TC-201 has sign/magnitude representation and arithmetic. This means that the bit patterns from 0000 0000 0000 0000 through 0111 1111 1111 1111 represent the numbers 0 through 32,767 (= 2^15 - 1) respectively, and the bit patterns 1000 0000 0000 0000 through 1111 1111 1111 1111 represent the numbers -0 through -32,767 respectively. Yes, there is a pesky "minus zero", which we shall treat as a negative number. Thus, if the high order bit is a 1, the number is negative. In this system, the negative of of every representable number is representable. For skipzero, the skip happens only if the accumulator contains the bit pattern 0000 0000 0000 0000. For skippos, the skip happens only if the accumulator contains one of the bit patterns 0000 0000 0000 0001 through 0111 1111 1111 1111. Note that the add and sub instructions should never produce "minus zero" (that is, the bit pattern 1000 0000 0000 0000) in the accumulator. The add instruction works as follows. Convert the two summands to integers and add them. If the resulting sum can be correctly represented in the arithmetic of the TC-201, set the AEB to 0 and put the correct representation of the sum in the ACC. If the sum cannot be correctly represented, set the AEB to 1 and put the representation of 0 into the ACC. (This is not necessarily the most useful result when AEB = 1, but it is easy to specify and implement.) The sub instruction is analogous, using subtraction instead of addition. For example, adding 0111 1111 1111 1111 to 0000 0000 0000 0001 sets the AEB to 1 and gives a result of 0000 0000 0000 0000 because the sum, 32,768, is not representable in the system above. As another example, adding 1000 0000 0000 0001 to 0000 0000 0000 0001 gives a result of 0000 0000 0000 0000 and sets the AEB to 0, because the result of adding -1 and 1 is 0, which is correctly representable. Feel free to convert between lists of binary digits and numbers and to use arithmetic in Scheme in your implementation of the TC-201 arithmetic. The instructions load, store, add, sub, read, write, and jump take the low-order 12 bits of the instruction as the representation (in binary) of the address of a memory word. Load, store, add, sub, read, write copy or modify the contents of that memory word (as indicated in "function" above), and jump causes the next instruction to be executed to be taken from that memory word. Unless modified by halt, jump, skipzero, skippos, skiperr or an undefined opcode, the program counter (PC) is incremented by 1 (modulo 4096) after the execution of an instruction, causing the next instruction to be executed in sequence. The skips cause the next instruction to be skipped if the condition they test is satisfied. The read instruction should prompt the user with: input = and accept a number from the user, convert it to the correct bit pattern to represent that number, and place it in the memory word addressed by the read. You may assume that the user will input only numbers representable in the TC-201. The write instruction should write out to the user: output = where is the integer represented by the bit pattern in the memory location addressed by the write. "Minus zero" should print out as the number 0. To read in and print out numbers from/to the user, use "read", "display" and "newline" (see online documentation.) The read and write instructions will be tested by hand by the TA's. The instructions loadi and storei use "indirect addressing," that is, they take the low-order 12 bits of the instruction as a memory address, and take the low-order 12 bits of *that* word of memory as (another) memory address, which is where data will be loaded from or stored to. As an example of the difference between load and store and their counterparts loadi and storei, consider the following two situations: ACC: 0 PC: 5 AEB: 0 0: 0 1: 3 2: 4 3: 10 4: 15 5: load 1 6: store 2 7: halt When the machine runs from this configuration, the "load 1" causes the contents of memory word 1 to be copied to the ACC, so that the ACC has 3 in it, and the "store 2" causes the contents of the ACC to be copied to memory word 2. Thus, when the program halts we have the configuration: ACC: 3 PC: 7 AEB: 0 0: 0 1: 3 2: 3 3: 10 4: 15 5: load 1 6: store 2 7: halt If, instead, we start with the following configuration: ACC: 0 PC: 5 AEB: 0 0: 0 1: 3 2: 4 3: 10 4: 15 5: loadi 1 6: storei 2 7: halt then when the machine runs, the "loadi 1" causes the low-order 12 bits of memory word 1, namely 3, to be used as the memory address to copy from, so that the ACC gets the value 10. Then the "storei 2" causes the low-order 12 bits of memory word 2, namely 4, to be used as the memory address to copy to, resulting in the following configuration when the program halts: ACC: 10 PC: 7 AEB: 0 0: 0 1: 3 2: 4 3: 10 4: 10 5: loadi 1 6: storei 2 7: halt Thus, loadi and storei can be used to implement "pointers" to tables of data or other kinds of data structures, which would otherwise require index registers or entail self-modifying code. A Simple Assembly Language. We define a simple assembly language for our machine, with symbolic opcodes, numeric or symbolic addresses, and a data statement. For example, consider an assembly-language program to read in a zero-terminated sequence of numbers and print out their sum, and its translation (when loaded at address 5.) load zero 5: 0001 0000 0001 0001 store sum 6: 0010 0000 0001 0011 readnum: read number 7: 0101 0000 0001 0010 load number 8: 0001 0000 0001 0010 skipzero 9: 1000 0000 0000 0000 jump addin 10: 0111 0000 0000 1100 jump output 11: 0111 0000 0000 1111 addin: add sum 12: 0011 0000 0001 0011 store sum 13: 0010 0000 0001 0011 jump readnum 14: 0111 0000 0000 0111 ouptput: write sum 15: 0110 0000 0001 0011 halt 16: 0000 0000 0000 0000 zero: data 0 17: 0000 0000 0000 0000 number: data 0 18: 0000 0000 0000 0000 sum: data 0 19: 0000 0000 0000 0000