;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; description: Connect 4 game starter code ;
; ;
; ;
; connect4.asm ;
; ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.ORIG x3000
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Main Program ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
JSR INIT
ROUND
JSR DISPLAY_BOARD
JSR GET_MOVE
JSR UPDATE_BOARD
JSR UPDATE_STATE
ADD R6, R6, #0
BRz ROUND
JSR DISPLAY_BOARD
JSR GAME_OVER
HALT
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Functions & Constants!!! ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; DISPLAY_TURN ;
; description: Displays the appropriate prompt. ;
; inputs: None! ;
; outputs: None! ;
; assumptions: TURN is set appropriately! ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DISPLAY_TURN
ST R0, DT_R0
ST R7, DT_R7
LD R0, TURN
ADD R0, R0, #-1
BRp DT_P2
LEA R0, DT_P1_PROMPT
PUTS
BRnzp DT_DONE
DT_P2
LEA R0, DT_P2_PROMPT
PUTS
DT_DONE
LD R0, DT_R0
LD R7, DT_R7
RET
DT_P1_PROMPT .STRINGZ “Player 1, choose a column: ”
DT_P2_PROMPT .STRINGZ “Player 2, choose a column: ”
DT_R0 .BLKW x1
DT_R7 .BLKW x1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; GET_MOVE ;
; description: gets a column from the user. ;
; also checks whether the move is valid, ;
; or not, by calling the CHECK_VALID ;
; subroutine! ;
; inputs: None! ;
; outputs: R6 has the user entered column number! ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
GET_MOVE
ST R0, GM_R0
ST R7, GM_R7
GM_REPEAT
JSR DISPLAY_TURN
GETC
OUT
JSR CHECK_VALID
LD R0, ASCII_NEWLINE
OUT
ADD R6, R6, #0
BRp GM_VALID
LEA R0, GM_INVALID_PROMPT
PUTS
LD R0, ASCII_NEWLINE
OUT
BRnzp GM_REPEAT
GM_VALID
LD R0, GM_R0
LD R7, GM_R7
RET
GM_INVALID_PROMPT .stringz “Invalid move. Try again.”
GM_R0 .blkw x1
GM_R7 .blkw x1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; UPDATE_BOARD ;
; description: updates the game board with the last ;
; move! ;
; inputs: R6 has the column for last move. ;
; outputs: R5 has the row for last move. ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
UPDATE_BOARD
ST R1, UP_R1
ST R2, UP_R2
ST R3, UP_R3
ST R4, UP_R4
ST R6, UP_R6
ST R7, UP_R7
; clear R5
AND R5, R5, #0
ADD R5, R5, #6
LEA R4, ROW6
UB_NEXT_LEVEL
ADD R3, R4, R6
LDR R1, R3, #-1
LD R2, ASCII_NEGHYP
ADD R1, R1, R2
BRz UB_LEVEL_FOUND
ADD R4, R4, #-7
ADD R5, R5, #-1
BRnzp UB_NEXT_LEVEL
UB_LEVEL_FOUND
LD R4, TURN
ADD R4, R4, #-1
BRp UB_P2
LD R4, ASCII_O
STR R4, R3, #-1
BRnzp UB_DONE
UB_P2
LD R4, ASCII_X
STR R4, R3, #-1
UB_DONE
LD R1, UP_R1
LD R2, UP_R2
LD R3, UP_R3
LD R4, UP_R4
LD R6, UP_R6
LD R7, UP_R7
RET
ASCII_X .fill x0058
ASCII_O .fill x004f
UP_R1 .blkw x1
UP_R2 .blkw x1
UP_R3 .blkw x1
UP_R4 .blkw x1
UP_R5 .blkw x1
UP_R6 .blkw x1
UP_R7 .blkw x1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; CHANGE_TURN ;
; description: changes the turn by updating TURN! ;
; inputs: none! ;
; outputs: none! ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CHANGE_TURN
ST R0, CT_R0
ST R1, CT_R1
ST R7, CT_R7
LD R0, TURN
ADD R1, R0, #-1
BRz CT_TURN_P2
ST R1, TURN
BRnzp CT_DONE
CT_TURN_P2
ADD R0, R0, #1
ST R0, TURN
CT_DONE
LD R0, CT_R0
LD R1, CT_R1
LD R7, CT_R7
RET
CT_R0 .blkw x1
CT_R1 .blkw x1
CT_R7 .blkw x1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; CHECK_WINNER ;
; description: checks if the last move resulted in a ;
; win or not! ;
; inputs: R6 has the column of last move. ;
; R5 has the row of last move. ;
; outputs: R4 has 0, if not winning move, ;
; 1, otherwise. ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CHECK_WINNER
ST R5, CW_R5
ST R6, CW_R6
ST R7, CW_R7
AND R4, R4, #0
JSR CHECK_HORIZONTAL
ADD R4, R4, #0
BRp CW_DONE
JSR CHECK_VERTICAL
ADD R4, R4, #0
BRp CW_DONE
JSR CHECK_DIAGONALS
CW_DONE
LD R5, CW_R5
LD R6, CW_R6
LD R7, CW_R7
RET
CW_R5 .blkw x1
CW_R6 .blkw x1
CW_R7 .blkw x1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; UPDATE_STATE ;
; description: updates the state of the game by ;
; checking the board. i.e. tries to figure;
; out whether the last move ended the game;
; or not! if not updates the TURN! also ;
; updates the WINNER if there is a winner!;
; inputs: R6 has the column of last move. ;
; R5 has the row of last move. ;
; outputs: R6 has 1, if the game is over, ;
; 0, otherwise. ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
UPDATE_STATE
ST R0, US_R0
ST R1, US_R1
ST R4, US_R4
ST R7, US_R7
; checking if the last move resulted in a win or not!
JSR CHECK_WINNER
ADD R4, R4, #0
BRp US_OVER
; checking if the board is full or not!
AND R6, R6, #0
LD R0, NBR_FILLED
ADD R0, R0, #1
ST R0, NBR_FILLED
LD R1, MAX_FILLED
ADD R1, R0, R1
BRz US_TIE
US_NOT_OVER
JSR CHANGE_TURN
BRnzp US_DONE
US_OVER
ADD R6, R6, #1
LD R0, TURN
ST R0, WINNER
BRnzp US_DONE
US_TIE
ADD R6, R6, #1
US_DONE
LD R0, US_R0
LD R1, US_R1
LD R4, US_R4
LD R7, US_R7
RET
NBR_FILLED .fill #0
MAX_FILLED .fill #-36
US_R0 .blkw x1
US_R1 .blkw x1
US_R4 .blkw x1
US_R7 .blkw x1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; INIT ;
; description: simply sets the BOARD_PTR appropriately!;
; inputs: none! ;
; outputs: none! ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
INIT
ST R0, I_R0
ST R7, I_R7
LEA R0, ROW1
ST R0, BOARD_PTR
LD R0, I_R0
LD R7, I_R7
RET
I_R0 .blkw x1
I_R7 .blkw x1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Global Constants!!! ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ASCII_SPACE .fill x0020 ;
ASCII_NEWLINE .fill x000A ;
TURN .fill x1 ;
WINNER .fill x0 ;
;
ASCII_OFFSET .fill x-0030 ;
ASCII_NEGONE .fill x-0031 ;
ASCII_NEGSIX .fill x-0036 ;
ASCII_NEGHYP .fill x-002d ;
;
ROW1 .stringz “——” ;
ROW2 .stringz “——” ;
ROW3 .stringz “——” ;
ROW4 .stringz “——” ;
ROW5 .stringz “——” ;
ROW6 .stringz “——” ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; DISPLAY_BOARD ;
; description: Displays the board. ;
; inputs: None! ;
; outputs: None! ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DISPLAY_BOARD
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; GAME_OVER ;
; description: checks WINNER and outputs the proper ;
; message! ;
; inputs: none! ;
; outputs: none! ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
GAME_OVER
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; CHECK_VALID ;
; description: checks whether a move is valid or not! ;
; inputs: R0 has the ASCII value of the move! ;
; outputs: R6 has: 0, if invalid move, ;
; decimal col. val., if valid. ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CHECK_VALID
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;USE THE FOLLOWING TO ACCESS THE BOARD!!!;;;;;;;;;;;;;;;;;;
;;;;;IT POINTS TO THE FIRST ELEMENT OF ROW1 (TOP-MOST ROW)!!!;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
BOARD_PTR .blkw 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; CHECK_HORIZONTAL ;
; description: horizontal check. ;
; inputs: R6 has the column of the last move. ;
; R5 has the row of the last move. ;
; outputs: R4 has 0, if not winning move, ;
; 1, otherwise. ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CHECK_HORIZONTAL
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; CHECK_VERTICAL ;
; description: vertical check. ;
; inputs: R6 has the column of the last move. ;
; R5 has the row of the last move. ;
; outputs: R4 has 0, if not winning move, ;
; 1, otherwise. ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CHECK_VERTICAL
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; CHECK_DIAGONALS ;
; description: checks diagonals by calling ;
; CHECK_D1 & CHECK_D2. ;
; inputs: R6 has the column of the last move. ;
; R5 has the row of the last move. ;
; outputs: R4 has 0, if not winning move, ;
; 1, otherwise. ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CHECK_DIAGONALS
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; CHECK_D1 ;
; description: 1st diagonal check. ;
; inputs: R6 has the column of the last move. ;
; R5 has the row of the last move. ;
; outputs: R4 has 0, if not winning move, ;
; 1, otherwise. ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CHECK_D1
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; CHECK_D2 ;
; description: 2nd diagonal check. ;
; inputs: R6 has the column of the last move. ;
; R5 has the row of the last move. ;
; outputs: R4 has 0, if not winning move, ;
; 1, otherwise. ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CHECK_D2
RET
.END