CMPE 401 - Computer Interfacing

Assignment #2 Model Solutions

Due: In the CMPE 401 assignment box at 15:45 on Wednesday, Oct. 19, 2005


  1. All of the microprocessors in the 68000 family require machine language instructions, data words and data long words to be "word-aligned" in memory. In other words, these three kinds of data objects must be stored in memory with the first occupied byte having an even address. Why do you think would be the most important advantage of adopting this constraint? What would be some potential disadvantages of this constraint?

    [15 marks]
    Advantages:
    The word-aligned constraint would simplify the implementation of 68000 processors that use a 16-bit data bus. If 16-bit-sized objects (data words and 16-bit instructions) are word-aligned, then any such object can be transferred over the data bus in only one transaction. If a 16-bit object were to be aligned on an odd-numbered address, then transferring the object over the data bus would require two bus operations instead of one. Also, the 16-bit object would need to be split into two 8-bit-sized pieces, and the pieces would need to be re-assembled correctly at the destination. All of these manipulations would require additional logic to implement, and these operations would consume extra time thereby slowing down the processor a bit.

    In the case of long words, three bus operations (rather than two) would be required for transfers if the long word is aligned on an odd-numbered address. In the case of machine language instructions, it makes it simpler for the instruction fetch logic if word alignment can be assumed. The extra time that would otherwise be required to reassemble non-aligned instructions is thereby avoided.

    Disadvantages:
    One possible disadvantage is that memory space will be wasted since objects are restricted in their possible positioning in memory. Objects can perhaps not be packed as "tightly" together, leaving unused byte-sized gaps between objects. Objects that are inherently an odd number of bytes long (e.g. 24-bit integers) cannot be represented efficiently (e.g. 24-bit integers must be represented as 32-bit integers).

  2. Briefly describe the difference between the LSR.W and ASR.W instructions. Be sure to explain how the condition code register bits are updated for each instruction. Now explain the difference between the LSL.B and ASL.B instructions.

    [15 marks]
    The LSR.W (i.e. word-sized logical shift right) and ASR.W (word-sized arithmetic shift right) are quite similar in that they both involve shifting bits rightways through a word in a data registers or a memory location. The instructions differ in how the most significant bit (i.e. bit #15) is updated, and differ in how the overflow bit V in the CCR is updated. In LSR.W, a 0 is shifted into bit #15, whereas in ASR.W, the former value of bit #15 is retained in bit #15. In both instructions, a multiple number of 1-bit shifts can be specified either as a 3-bit immediate value or as the contents of a data register. The V bit is always cleared by the execution of LSR.W; in ASR.W the V bit is set if bit #15 changes at least once during the execution of the instruction, otherwise the V bit is cleared.

    LSL.W and ASL.W are even more similar than LSR.W and ASR.W. They both cause the bits in the word-sized destination to be shift lefted by one or more bit positions. Both instructions insert 0's into the least significant bit position. The instructions differ only in how the overflow bit V is updated. In LSL.W the V bit is always cleared to 0, whereas in ASL.W the V bit is set if bit $15 changes at least once during execution of the instruction, otherwise the V bit is cleared.

  3. Consult the on-line documentation for the CPU32 and then briefly explain how the four table interpolation instructions work (i.e., TBLS, TBLSN, TBLU and TBLUN).

    [15 marks]
    The four instruction types perform variations on a basic table lookup and linear interpolate function. The instructions TBLS, TBLSN, TBLU and TBLUN are, respectively, the signed with rounding, signed with no rounding, unsigned with rounding, and unsigned with no rounding versions of the instruction. The two entries to be interpolated are either two stored entries in memory, or are stored in two data registers: In the first case the first entry is specified by the source effective address and the second entry is located at the next entry higher in address at a distance in bytes corresponding to the instruction data size (1, 2 or 4 bytes). In the second case, the source operand is given as a data register pair (e.g. D2:D3). In all forms of the instructions, the destination operand is a data register Dn, where bits 7-0 of Dn specify the fractional part of the independent index variable and bits 15-8 of Dn specify the integer part. The result of the linear interpolation is written into Dn, with the correct data size given by the instruction.

    In linear interpolation, the second table entry is substracted from the first, then the difference is multiplied by the fraction contained in the lower 8 bits of Dn, and the resulting product is added to the first table entry. This result is then written back to Dn.

    In the rounding forms of the instruction (e.g. TBLS and TBLU), the result of linear interpolation is left justified in the available space (.B, .W or .L) of the destination data register Dn. The fractional portion of the result is rounded according the conventional arithmetic algorithm. The other bits in Dn are not changed.

    In the nonrounding forms of the instructioon (e.g. TBLSN and TBLUN), the result of linear interpolation is left justified into the rightmost 16 bits, 24 bits and 32-bits of the destination register Dn for the .B, .W and .L forms of the instruction. The upper bits of Dn are filled in using sign extension for the .B and.W forms of the instruction.

  4. Write an assembly language subroutine, called CASE_CHANGE, that receives two 32-bit pointers on the stack. These pointers point to the first and last bytes in a packed array of stored ASCII characters. CASE_CHANGE is to scan through the character array, and is to convert all upper case letters to lower case letters, and vice versa. All other ASCII codes in the array are to be left unchanged. The two pointers on the stack are not to be altered during the execution of the subroutine.

    [20 marks]
    
    CASE_CHANGE:
              MOVEM.L  A0-A1/D0,-(SP)  /* save registers */
    
              MOVE.L   16(SP),A1       /* retrieve ptr to 2nd byte */
              MOVE.L   20(SP),A0       /* retrieve ptr to 1st byte */
    
    LOOP:     CMPA.L   A1,A0           /* compare pointers */
              BGT      EXIT_CC         /* exit if past last byte */
    
                                       /* check byte for upper case */
              CMPI.B   #0x41,(A0)      /* compare with ASCII A */
              BLT      NEXT_B          /* skip byte if too low */
              CMPI.B   #0x5A,(A0)      /* compare byte with ASCII Z */
              BLE      CHG_CASE        /* found an upper case letter */
    
                                       /* check for lower case */
              CMPI.B   #0x61,(A0)      /* compare byte with ASCII a */
              BLT      NEXT_B          /* skip byte if too low */
              CMPI.B   #0x7A,(A0)      /* compare byte with ASCII z */
              BGT      NEXT_B          /* skip byte if too high */
                                       /* found a lower case letter */
    
    CHG_CASE: BCHG     #5,(A0)         /* change case of letter */
    NEXT_B:   ADDA.L   #1,A0           /* advance char ptr */
              BRA      LOOP
    
    EXIT_CC:  MOVEM.L  (SP)+,A0-A1/D0  /* restore registers */
              RTS
    

  5. Consider the design of an asynchronous serial interface (not RS232C). Each data frame is to consist of one stop bit, 1000 data bits, 10 bits for error detection and correction, and two stop bits. The transmitter and receiver circuits are to base their timing on 8-MHz crystal-stabilized oscillator circuits that are divided down in frequency by a factor of 16 to get the bit rate in the data frames. You are to assume that bits are recovered reliably at the receiver if the actual sampling point drifts by no more than 25% on either side (leading or lagging) of the ideal sampling point in the middle of each bit. More accurate crystals cost more than less accurate crystals, and your company wants to use the cheapest crystals that it can get away with. Determine the worst-case error that can be present in the raw oscillator frequencies while still ensuring reliable data recovery at the receiver.

    [15 marks]
    Let 16 * f_tx and 16 * f_rx be the frequencies of the transmitter and receiver clocks, respectively. Thus the bit periods at the transmitter and receiver are 1/f_tx and 1/f_rx, respectively. The nominal value of both f_tx and f_rx is f = 8 MHz / 16 = 500 KHz.

    Let "err" be the worst case percentage error in f_tx and f_rx.

    The worst possible acceptable situation is expressed by the following equation:

    1010 / (f*(1 - (0.01 * err))) = 1010.25 / (f*(1 + (0.01 * err)))

    The left side represents the total time elapsed for 1010 bit periods using the slowest allowable clock frequency. The right side represents the total time elapsed for 1010.25 periods of the fastest possible clock frequency. The difference in the two clocks has caused the sampling time to drift to 25% past the middle of the last bit in the 10 error detection and correction bits. Solving for err we obtain:

    err = 0.25 / 20.2025 = 0.012375% = 123.75 ppm

  6. Write a short assembly language routine that initializes a DUART for normal duplex communications as follows. Both ports are to use busy waiting to synchronize the CPU with data communication over the A and B side ports. Port A is to carry 7-bit data, with even parity, at 9600 baud (bits/sec). Error indications are to be on a per-character basis. The CTS input is to automatically disable the port A transmitter. The port A RTS output function is to be disabled. Port B is to carry 8-bit data, with no parity, at 4800 baud. Error indications are to be formed over all characters in the receiver FIFO buffer. The CTS input is to have no automatic effect on the port A transmitter. However, the port B RTS output function is to be enabled. All DUART interrupts are to be disabled. In your answer, be sure to justify the bit patterns that are loaded into DUART command registers.

    [20 marks]
    
    .equ  MR1A,    0   /* Mode Reg 1 A */
    .equ  MR2A,    0   /* Mode Reg 2 A */
    .equ  CSRA,    1   /* Clock Select Reg A */
    .equ  CRA,     2   /* Command Reg A */
    .equ  ACR,     4   /* Auxiliary Command Reg */
    .equ  IMR,     5   /* Interrupt Mask Reg */
    .equ  MR1B,    8   /* Mode Reg 1 B */
    .equ  MR2B,    8   /* Mode Reg 2 B */
    .equ  CSRB,    9   /* Clock Select Reg B */
    .equ  CRB,     10  /* Command Reg B */
    
          LEA.L    DUART_BASE,A0    /* assume DUART_BASE already defined */
    
          CLR.B    IMR(A0)          /* disable all interrupts */
    
          /* reset the hardware as a precaution */
          MOVE.B   #0x10,CRA(A0)    /* reset MR A pointer */
          MOVE.B   #0x20,CRA(A0)    /* reset Rx A */
          MOVE.B   #0x30,CRA(A0)    /* reset Tx A */
          MOVE.B   #0x40,CRA(A0)    /* reset A error status */
          MOVE.B   #0x50,CRA(A0)    /* reset A break change interrupt */
          MOVE.B   #0x70,CRA(A0)    /* stop sending A break signal */
          MOVE.B   #0x00,CRA(A0)    /* no cmd & A Tx off & A Rx off */
    
          MOVE.B   #0x10,CRB(A0)    /* reset MR B pointer */
          MOVE.B   #0x20,CRB(A0)    /* reset Rx B */
          MOVE.B   #0x30,CRB(A0)    /* reset Tx B */
          MOVE.B   #0x40,CRB(A0)    /* reset B error status */
          MOVE.B   #0x50,CRB(A0)    /* reset B break change interrupt */
          MOVE.B   #0x70,CRB(A0)    /* stop sending B break signal */
          MOVE.B   #0x00,CRB(A0)    /* no cmd & B Tx off & B Rx off */
    
          /* configure the mode registers */
          MOVE.B   #0b00000010,MR1A(A0)  /* RTR ctl off; char err; even par; 7-bit data */
          MOVE.B   #0b00000000,MR2A(A0)  /* duplex mode; auto CTS-en off; 1 stop bit */
    
          MOVE.B   #0b00110011,MR1B(A0)  /* RTR ctl off; FIFO err; no par; 8-bit data */
          MOVE.B   #0b00000000,MR2B(A0)  /* duplex mode; auto CTS-en on; 1 stop bit */
    
          MOVE.B   #0x00,ACR(A0)    /* select timing set 1, ACR[7]=0 */
          MOVE.B   #0xBB,CSRA(A0)   /* select 9600 baud for A Tx & Rx */
          MOVE.B   #0x99,CSRB(A0)   /* select 4800 baud for B Tx & Rx */
    
          MOVE.B   #0x05,CRA(A0)    /* no cmd & A Tx on & A Rx on */
          MOVE.B   #0x05,CRB(A0)    /* no cmd & B Tx on & B Rx on */