;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; PowerPC assembly code - Display Decoder ; This code is not ready for the assembler. ; Translate a hex digit, 0x0 - 0xF, represented as a ; 4-bit nibble 0000-1111, from a DIP switch to a 7-segment display ; Read in the hex digit to be displayed ; If bit 7 of DIP Switch 1 is set, use the upper nibble of DIP ; Switch 2 as the hex digit to be displayed ; If bit 7 of DIP Switch 1 is not set, use the lower nibble of ; DIP Switch 2 as the hex digit to be displayed ; Convert the hex digit to its 8-bit 7-segment encoding (abcdefg, dp) ; Output the 8-bit 7-segment code to drive the display (7-segment ; display to the right of the DIP switches on the PowerBox) ; Use Digital Out 1, i.e., IO_DIGITAL_OUTPUT_1, to connect ; to the 7-segment display input connector using a ribbon cable ; ADD THE NECESSARY CODE to output the 4-bit hex digit directly (before ; decoding into segments) to IO_DIGITAL_OUTPUT_7SEG (7-segment display ; above the LED bargraphs on the PowerBox) StartAsm: ; r10 = address of SegTable array ; r20 = address of Digital Output 1 ; r21 = address of DIP Input Switch 1 ; r22 = address of DIP Input Switch 2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Get the address of SegTable lis r10, SegTable@h ; r10 = Upper 16 bits of memory address ; for SegTable ; r10 = r10 | lower 16 bits of SegTable ori r10, r10, SegTable@l ; At this point, r10 contains the memory address for SegTable ; Set up the appropriate memory addresses (see Lab 6 for ; examples) ; Load up register r20 with address of Digital Out 1 ; Load into r20 the upper 16 bits of IO_DIGITAL_OUTPUT_1 lis r20, IO_DIGITAL_OUTPUT_1@h ; Load into r20 the lower 16 bits of IO_DIGITAL_OUTPUT_1 ori r20, r20, IO_DIGITAL_OUTPUT_1@l ; Load up register r21 with address of DIP Switch 1 ; Load into r21 the upper 16 bits of IO_DIGITAL_INPUT_DIP_1 lis r21, IO_DIGITAL_INPUT_DIP_1@h ; Load into r21 the lower 16 bits of IO_DIGITAL_INPUT_DIP_1 ori r21, r21, IO_DIGITAL_INPUT_DIP_1@l ; Load up register r22 with address of DIP Switch 2 ; Load into r22 the upper 16 bits of IO_DIGITAL_INPUT_DIP_2 lis r22, IO_DIGITAL_INPUT_DIP_2@h ; Load into r22 the lower 16 bits of IO_DIGITAL_INPUT_DIP_2 ori r22, r22, IO_DIGITAL_INPUT_DIP_2@l RepeatLoop: ; Should we output the upper nibble or the lower nibble ; Load into register r11 the value from DIP Switch 1 lbz r11, 0(r21) ; Load byte from r21 + 0 (DIP Switch 1) ; and immediate DIP Switch 1 with 0x80. ; If set then output upper nibble of DIP 2 andi. r12, r11, $80 ; r12 <- r11 & 0x80 ; Branch to OutputLower if CR0 EQ set, when r11 & 0x80 = 0 beq OutputLower OutputUpper: ; Get the value of the upper nibble of DIP switch 2 ; r13 = Value from DIP Switch 2 ; r14 = address of value from SegTable corresponding to value ; from upper nibble of DIP 2 ; r2 = register to store address of SegTable value to output ; Load into register r13 the value from DIP Switch 2 lbz r13, 0(r22) ; Load byte from r22 + 0 (DIP Switch 2) ; Get the uppper nibble of DIP Switch 2 andi. r13, r13, $F0 ; Bitwise AND to get upper nibble ; Shift the upper nibble by 4 bits to place into lower nibble srwi r13, r13, 4 ; r13 <- r13 >> 4 ; Get address of correct number from lower nibble, add upper ; nibble to SegTable address add r14, r13, r10 ; Add result from bitwise to SegTable mr r2, r14 ; move r14 to r2 for output in OutputResult ; Skip to the output branch always to OutputResult, skip past ; OutputLower b OutputResult OutputLower: ; Get the value of the lower nibble of DIP switch 2 ; r15 = Value from DIP Switch 2 ; r16 = address of value from SegTable corresponding to value ; from lower nibble of DIP 2 ; r2 = register to store address of SegTable value to output ; Load into register r13 the value from DIP Switch 2 lbz r15, 0(r22) ; Load byte from r22 + 0 (DIP Switch 2) ; Get the lower nibble of DIP Switch 2 ; Bitwise AND to get lower nibble, store back into r15 andi. r15, r15, $0F ; Get address of correct number from upper nibble, add upper ; nibble to SegTable address add r16, r15, r10 ; Add result from bitwise to SegTable mr r2, r16 ; move r16 to r2 for output in OutputResult ; Fall into OutputResult label so no need for a branch OutputResult: ; Keep repeating the lab ; r0 = output value to put into Digital Output 1 ; r2 = value from OutputLower or OutputUpper that is address of ; SegTable value to output ; Load byte from SegTable of value to output lbz r0, 0(r2) ; load value from SegTable at 0 + r2 ; r0 <- m[0+r2] ; Store byte from r0 out to r20, store value from SegTable out to ; Digital Output 1 stb r0, 0(r20) b RepeatLoop ; Unconditional branch to StartAsm blr ; Return back to the C code PPC_End_Asm: .data ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Table for 7 segment display ; SegTable: ; Bit 7 6 5 4 3 2 1 0 ; a b c d e f g dp .byte $FC ; 0 = 1 1 1 1 1 1 0 0 .byte $60 ; 1 = 0 1 1 0 0 0 0 0 .byte $DA ; 2 = 1 1 0 1 1 0 1 0 .byte $F2 ; 3 = 1 1 1 1 0 0 1 0 .byte $66 ; 4 = 0 1 1 0 0 1 1 0 .byte $B6 ; 5 = 1 0 1 1 0 1 1 0 .byte $BE ; 6 = 1 0 1 1 1 1 1 0 .byte $E0 ; 7 = 1 1 1 0 0 0 0 0 .byte $FE ; 8 = 1 1 1 1 1 1 1 0 .byte $E6 ; 9 = 1 1 1 0 0 1 1 0 .byte $EE ; A = 1 1 1 0 1 1 1 0 .byte $3E ; B = 0 0 1 1 1 1 1 0 'b' .byte $9C ; C = 1 0 0 1 1 1 0 0 .byte $7A ; D = 0 1 1 1 1 0 1 0 'd' .byte $9E ; E = 1 0 0 1 1 1 1 0 .byte $8E ; F = 1 0 0 0 1 1 1 0