;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; CS/ECE 252 - Introduction to Computer Engineering ; CONNECT FOUR ; Prof. Mark D. Hill and Prof. Gurindar Sohi ; TAs: Preeti Agarwal, Mona Jalal, Rebecca Lam, Pradip Vallathol ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; .ORIG x3000 MAIN JSR INITBOARD JSR DISPLAYINITBOARD MLOOP ; Ask player for input LEA R0, MSGST PUTS LD R0, CURPLYR LD R6, CONV ADD R0, R0, R6 OUT LEA R0, MSGED PUTS GETC OUT ADD R1, R0, #0 LEA R0, ENDL PUTS ; Check Input valid JSR CHECKINPUTVALID ADD R3, R1, #1 BRz MLOOP ADD R3, R1, #2 BRz END ; Check Column valid JSR CHECKCOLUMNVALID ADD R2, R2, #0 BRn MLOOP ; Update board state ST R1, CURCOL ST R2, CURROW LD R3, CURPLYR JSR UPDATEBOARDSTATE ; Display board LD R3, CURCLR JSR DISPLAYBOARD ; HALT if end of game ; Loop again, if not LD R1, CURCOL LD R2, CURROW LD R3, CURPLYR JSR CHECKEND ADD R1, R1, #0 BRn END ST R1, CURPLYR ST R2, CURCLR BR MLOOP END HALT CURCOL .FILL 0 ; Current piece column number CURROW .FILL 0 ; Current piece row number CURPLYR .FILL x01 ; Current player ID CURCLR .FILL x7C00 ; Current player color code MSGST .STRINGZ "Player " MSGED .STRINGZ " Enter Column: " ENDL .STRINGZ "\n" CONV .FILL x30 ; Conversion offset for char <-> int ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; FUNCTION: CHECKINPUTVALID ; INPUT : R1 - Column as ASCII ; OUTPUT : R1 - Column as INT if digit, otherwise -1 ; HELP : Checks if the input char in R1 is a digit ; If digit, convert to INT and store in R1 ; If 'x', set R1 to -2 ; Else, set R1 to -1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CHECKINPUTVALID ; Insert code for this subroutine AND R1, R1, #0 ; You may replace this instruction ENDCHECKINPUTVALID RET ; DATA NEG0 .FILL 0xFFD0 ; 2's compliment of 0 character NEG9 .FILL 0xFFC7 ; 2's compliment of 9 character NEGx .FILL 0xFF88 ; 2's compliment of x character ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; FUNCTION: CHECKCOLUMNVALID ; INPUT : R1 - Column of the board ; OUTPUT : R2 - Row of the board ; HELP : DO NOT CHANGE THE VALUE OF R1 ; Checks if the input column of the board (R1) ; is valid and not full ; If not full, set R2 to the lowest free Row ; If full or not valid, set R2 to -1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CHECKCOLUMNVALID ; Insert code for this subroutine AND R2, R2, #0 ; You may replace this instruction ENDCHECKCOLUMNVALID RET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; FUNCTION: INITBOARD ; INPUT : NONE ; OUTPUT : NONE ; HELP : Initializes the state of the board on the start ; of the game - Donot Change ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; INITBOARD AND R4, R4, #0 LEA R5, BOARD LD R6, BSIZE IBLOOP STR R4, R5, #0 ADD R5, R5, #1 ADD R6, R6, #-1 BRp IBLOOP ENDINITBOARD RET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; FUNCTION: UPDATEBOARDSTATE ; INPUT : R1, R2 - Column, Row of the board to update ; R3 - Current player ; OUTPUT : NONE ; HELP : Updates the state of the board for the current ; player, for the input Column, Row - Donot Change ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; UPDATEBOARDSTATE LEA R5, BOARD ADD R5, R5, R1 ADD R4, R2, 0 UBSLOOP BRz UPSTATE ADD R5, R5, #7 ADD R4, R4, #-1 BR UBSLOOP UPSTATE STR R3, R5, #0 ENDUPDATEBOARDSTATE RET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; FUNCTION: GETBOARDADDR ; INPUT : R1, R2 - Column, Row of the board to get data from ; OUTPUT : R5 - Board address of the location ; HELP : Gets the address of the board for the given input ; column, row - Donot Change ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; GETBOARDADDR ST R4, TMP_R4 LEA R5, BOARD ADD R5, R5, R1 ADD R4, R2, 0 GBSLOOP BRz ENDGETBOARDADDR ADD R5, R5, #7 ADD R4, R4, #-1 BR GBSLOOP ENDGETBOARDADDR LD R4, TMP_R4 RET ; Board related data BSIZE .FILL 42 ; Number of spaces on the board BOARD .BLKW 42 ; Board state. ; Each address in this range holds information about a particular location on the board ; Temporary registers for saving register data TMP_R0 .FILL 0 TMP_R1 .FILL 0 TMP_R2 .FILL 0 TMP_R3 .FILL 0 TMP_R4 .FILL 0 TMP_R5 .FILL 0 TMP_R6 .FILL 0 TMP_R7 .FILL 0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; FUNCTION: CHECKEND ; INPUT : R1,R2 - Most recently played column, row ; R3 - Current player ; OUTPUT : R1 - Next player or -1 if END ; R2 - Next player color or 0 if END ; HELP : Checks the current state of the board to check ; if the current player has won or the board is full ; If win, print message, set R1 to -1 ; Else set R1 to next player ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CHECKEND ; Insert code into this subroutine LD R1, PLYR1ID ; You may replace this instruction LD R2, PLYR1CL ; You may replace this instruction ENDCHECKEND RET ; Player related data PLYR1ID .FILL 0x01 ; ID for player 1 PLYR1CL .FILL 0x7C00 ; Color code for player 1 PLYR2ID .FILL 0x02 ; ID for player 2 PLYR2CL .FILL 0x001F ; Color code for player 2 ; CHECKEND messages WINMSG .STRINGZ "The winner is Player " TIEMSG .STRINGZ "Tie game\n" ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; FUNCTION: DISPLAYINITBOARD ; INPUT : NONE ; OUTPUT : NONE ; HELP : Displays the initial board for the game ; Implemented - Donot Change ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DISPLAYINITBOARD ST R7, SAVE_R7_1 LD R4, VIDEO LD R5, BLACK LD R3, VIDEO_INC CLEAR_BOARD STR R5,R4,0x0 ADD R4, R4, 0x1 ADD R3, R3, #-1 BRnp CLEAR_BOARD DRAW_ROW_INIT AND R0, R0, 0x0 LD R1, X_START LD R2, Y_START LD R5, COLOR DRAW_ROW_LOOP JSR CALCULATE_ADDR ; R4 gets the address STR R5, R4, 0x0 ADD R1, R1, 0x1 JSR CHECK_ROWBOUND ADD R3, R3, 0x0 BRn DRAW_COL_INIT BRnzp DRAW_ROW_LOOP DRAW_COL_INIT AND R0, R0, 0x0 LD R1, X_START LD R2, Y_START LD R5, COLOR DRAW_COL_LOOP JSR CALCULATE_ADDR STR R5, R4, 0x0 ADD R2, R2, 0x1 ST R7, SAVE_R7 JSR CHECK_COLBOUND LD R7, SAVE_R7 ADD R3, R3, 0x0 BRn ENDDISPLAYINITBOARD BRnzp DRAW_COL_LOOP ENDDISPLAYINITBOARD LD R7, SAVE_R7_1 RET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; FUNCTION: CALCULATE_ADDR ; INPUT : R1: Row, R2: Column ; OUTPUT : R4, modifies R3 ; HELP : Used in initial display; ; Calculates the memory address:xC000+row*x0080+col ; - Donot Change ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CALCULATE_ADDR ;save inputs and outputs ST R1, SAVE_R1 ST R2, SAVE_R2 ST R3, SAVE_R3 LD R3, VIDEO LD R4, ROW_WIDTH MUL R4, R4, R2 ADD R3, R3, R4 ADD R4, R3, R1 LD R1, SAVE_R1 LD R2, SAVE_R2 LD R3, SAVE_R3 RET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; FUNCTION: CHECK_ROWBOUND ; INPUT : R1 ; OUTPUT : R0,R3,R2 ; HELP : Used in initial Display; Calculates if row is ; within bound, icrements to next row if it is not. ; - Donot Change ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CHECK_ROWBOUND LD R3, X_MAX ADD R3, R3, R1 BRn CHECK_ROWBOUND_OVER LD R3, ROW_COUNT ADD R3, R0, R3 BRnz INCREMENT_ROWCOUNT AND R3, R3, 0x0 NOT R3, R3 RET INCREMENT_ROWCOUNT ADD R0, R0, 0x1 LD R3, BLOCK_HEIGHT ADD R2, R2, R3 AND R1, R1, 0x0 CHECK_ROWBOUND_OVER AND R3, R3, 0x0 RET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; FUNCTION: CHECK_ROWBOUND ; INPUT : R2 ; OUTPUT : R0,R3,R1 ; HELP : Used in initial Display; Calculates if column is ; within bound, icrements to next column if it is not. ; - Donot Change ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CHECK_COLBOUND LD R3, Y_MAX ADD R3, R3, R2 BRn CHECK_COLBOUND_OVER LD R3, COL_COUNT ADD R3, R0, R3 BRnz INCREMENT_COLCOUNT AND R3, R3, 0x0 NOT R3, R3 RET INCREMENT_COLCOUNT ADD R0, R0, 0x1 LD R3, BLOCK_WIDTH ADD R1, R1, R3 AND R2, R2, 0x0 CHECK_COLBOUND_OVER AND R3, R3, 0x0 RET VIDEO .FILL 0xC000 VIDEO_INC .FILL 0x3DFF COLOR .FILL 0x7FFF BLACK .FILL 0x0000 Y_START: .FILL 0 X_START: .FILL 0 X_MAX: .FILL 0xFF80 Y_MAX .FILL 0xFF84 ROW_COUNT .FILL 0xFFFA COL_COUNT .FILL 0xFFFA ROW_WIDTH .FILL 0x0080 BLOCK_HEIGHT .FILL 0x0014 BLOCK_WIDTH .FILL 0x0012 NEG_BLOCK_WIDTH .FILL 0xFFFE NEG_BLOCK_HEIGHT .FILL 0xFFEC NEG_ROW_WIDTH .FILL 0xFF80 MINUS_ONE .FILL 0xFFFF ROW_OFFSET .BLKW 1 BLOCK_START .BLKW 1 ;locations for saving and restoring register values SAVE_R0_1 .BLKW 1 SAVE_R1_1 .BLKW 1 SAVE_R2_1 .BLKW 1 SAVE_R3_1 .BLKW 1 SAVE_R4_1 .BLKW 1 SAVE_R5_1 .BLKW 1 SAVE_R6_1 .BLKW 1 SAVE_R7_1 .BLKW 1 SAVE_R0 .BLKW 1 SAVE_R1 .BLKW 1 SAVE_R2 .BLKW 1 SAVE_R3 .BLKW 1 SAVE_R4 .BLKW 1 SAVE_R5 .BLKW 1 SAVE_R6 .BLKW 1 SAVE_R7 .BLKW 1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; FUNCTION: DISPLAYBOARD ; INPUT : R1, R2 - Column, Row of the board to update ; R3 - Current color ; OUTPUT : NONE ; HELP : Updates the display board, for the current ; player, for the input Column, Row ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DISPLAYBOARD ST R0, SAVE_R0_1 ST R1, SAVE_R1_1 ST R2, SAVE_R2_1 ST R3, SAVE_R3_1 ST R4, SAVE_R4_1 ST R5, SAVE_R5_1 ST R7, SAVE_R7_1 LD R5, MINUS_ONE CHANGE_ROW_MAPPING AND R4, R4, 0x0 ADD R4, R4, 0x5 NOT R0, R2 ADD R0, R0, 0x1 ADD R2, R4, R0 LD R4, BLOCK_HEIGHT MUL R0, R2, R4 ADD R0, R0, 0x1 LD R4, ROW_WIDTH MUL R4, R4, R0 ST R4, ROW_OFFSET LD R4, BLOCK_WIDTH MUL R4, R1, R4 ADD R2, R4, 0x01 LD R1, ROW_OFFSET ST R7, SAVE_R7 JSR CALCULATE_ADDR_2 LD R7, SAVE_R7 ;Label: DRAW_BLOCK: INPUTS: R1 : Row , R2: column ; Outputs : R4: Memory address ;modifies, R4 DRAW_BLOCK LD R0, BLOCK_HEIGHT ADD R0, R0, #-1 DRAW_BLOCK_ROW_INIT ST R4, BLOCK_START LD R2, BLOCK_WIDTH ADD R2, R2, #-1 DRAW_BLOCK_ROW STR R3, R4, #0 ADD R4, R4, 0x1 ADD R2, R2, R5 BRp DRAW_BLOCK_ROW DRAW_BLOCK_COL LD R4, BLOCK_START LD R1, ROW_WIDTH ADD R4, R4, R1 ADD R0, R0, R5 BRp DRAW_BLOCK_ROW_INIT ENDDISPLAYBOARD LD R0, SAVE_R0_1 LD R1, SAVE_R1_1 LD R2, SAVE_R2_1 LD R3, SAVE_R3_1 LD R4, SAVE_R4_1 LD R5, SAVE_R5_1 LD R7, SAVE_R7_1 RET LD R0, SAVE_R0_1 LD R1, SAVE_R1_1 LD R2, SAVE_R2_1 LD R3, SAVE_R3_1 LD R4, SAVE_R4_1 LD R5, SAVE_R5_1 LD R6, SAVE_R6_1 LD R7, SAVE_R7_1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; FUNCTION: CALCULATE_ADDR_2 ; INPUT : R1,R2 ; OUTPUT : R4, modifies R3 ; HELP : Used in initial display; Calculates the memory address : xC000 + row*x0080 + col ; - Donot Change ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CALCULATE_ADDR_2 ;save inputs and outputs ST R1, SAVE_R1 ST R2, SAVE_R2 LD R4, VIDEO ADD R4, R4, R1 ADD R4, R4, R2 LD R1, SAVE_R1 LD R2, SAVE_R2 RET .END