Department of Electrical and Computer Engineering
Dalhousie University

ECED 3403: Computer Architecture

Summer 2018

Assignment 2

Last updated: 15 June 2018


  • For a copy of assignment 2, click here.

  • The loader will read S-Records. A description of the S-Record format can be found here.

  • This assignment requires the emulator to catch control-C signals to let the user abort the emulator. This requires the use of Unix signals as supported by Microsoft Windows:

  • For some ideas on how XMakina's devices can be designed and implemented, click here.

  • The program counter is always incremented (by 2) before any offset calculations are made in the execution step of a branching instruction. Table 8 in the XMakina's ISA document is incorrect, although the supporting text, when read, explains the steps in detail.

  • If you haven't already implemented them yet, it has been suggested that the constant values 0xFF and 0xFF00 be replaced with the constants 32 and 48, respectively. The choice of these constants may appear arbitrary; however, they represent ASCII space (which is also the difference between lower and upper case characters) and ASCII zero (useful for converting an ASCII digit to binary and vice-versa).

  • Test files and the most up-to-date versions of the assembler and X-Makina documentation can be found on the X-Makina documentation and software webpage.

  • The DADD (Decimal Add with Carry) instruction adds two “decimal” numbers to produce a decimal result. The decimal numbers are stored as BCD (Binary Coded Decimal) digits, one digit per nibble; a BCD digit has a value 0 (binary 0000 or 0x0) through 9 (binary 1001 or 0x9). The range of possible BCD numbers is 00 (0x00) through 99 (0x99) for byte arithmetic and 0000 (0x0000) through 9999 (0x9999) for word arithmetic.
    The result of adding two BCD digits together will be a number in the range 0 through 18; the numbers 10 through 18 cannot be represented in a BCD digit, so the ‘1’ is considered to be the carry. This means that every BCD digit added should take the carry from the previous addition and produces a carry for the next BCD digit to include in its addition; note that the carry should not be set if the result of the addition is less than 10. The units BCD digit has an input carry of ‘0’.
    If the carry is set, the addition of two BCD digits will be the sum of the two digits (0 through 10 through 18) plus the carry (1 through 10 through 19). The resulting BCD digit will therefore be 0 through 9, with the carry set.
    Emulating the DADD instruction requires each nibble in the operand (byte or word) to be extracted, added, and stored, from the least-significant nibble to the most-significant:
    /*
     Add least significant nibbles (digit 0)
     Initial carry (argument 3) is from status register (SR)
    */
    bcdsum(srcdig0, dstdig0, carry, &dstdig0, &carry);
    /*
     Add next nibble (digit 1)
     This carry (argument 3) is the carry from the sum (argument 5) in
     the previous call to bcdsum.
    */
    bcdsum(srcdig1, dstdig1, carry, &dstdig1, &carry);
    /* etc */
    
    Notes:
    When using the DADC instruction to add two BCD numbers together, it is good practice to clear the carry before adding the numbers together. For example, to add 75 and 6, one could write:
            CLRC
            MOVLZ.B   #$75,R0
            MOVLZ.B   #$06,R1
            DADD.B      R1,R0   ; R0 = R0 + R1
    
    Like many other microprocessors, the Motorola 6811 supports BCD arithmetic using its DAA (Decimal Adjust Accumulator A) instruction. Although the instruction is quite different (it handles both addition and subtraction), it gives some insight into how Motorola solved the problem. The 6811's DAA documentation can be found here.
    The following program is an example of how BCD arithmetic can be implemented in C.

  • The S0 record checksum can be ignored. The filename can be extracted as follows:
    #define LINE_LEN   256
    ...
    char srec[LINE_LEN];
    ...
    fgets(srec, LINE_LEN, fp);
    ...
    /* Header record - display name and ignore checksum*/
    sscanf_s(&srec[2], "%2x", &length);
    length -=3;
    pos = 8;
    printf("Source filename: ");
    for (i=0; i<length; i++)
    {
    	printf("%c", srec[pos]);
    	pos += 1;
    }
    

  • Important dates: