-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconnect.asm
509 lines (424 loc) · 7.94 KB
/
connect.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
;*******************************************************************************
; CONNECT-4 GAME
; AUTOR: MANUEL PABLO GONZALEZ CALZON
;*******************************************************************************
; DATA SEGMENT DEFINITION
DATOS SEGMENT
TURNS DB 0
BOARD DB 6 DUP( 7 DUP(' '))
NEXTLINE DB 13, 10, '$'
PLAYER DB 31H
PMESSAGE DB 13, 10,"PLAYER X TURN (TIME LEFT TO SELECT MOVE: XYs): $"
PPOSITION DW 9
SECPOSITION DW 43
MESSAGEMPATE DB 13,10,"FULL BOARD, THE GAME ENDS IN DRAW$"
MESSAGEWIN DB 13,10, "PLAYER X WINS!!!!!!!!! :-D$"
MESSAGEFULLCOLUMN DB 13,10, "ALREDY FULL COLUMN, CHOOSE ANOTHER ONE$"
MESSAGEINVALIDCOLUMN DB 13,10, "INVALID COLUMN, COLUMNS VALID FROM 1 TO 7$"
INPUT DB 2, 3 DUP(?)
LASTPOS DW 2 DUP(?)
WINNER DB 0
CORRECTURN DB 0
DATOS ENDS
; STACK SEGMENT DEFINITION
PILA SEGMENT STACK "STACK"
DB 40H DUP (0)
PILA ENDS
; EXTRA SEGMENT DEFINITION
EXTRA SEGMENT
RESULT DW 0,0 ; 2 WORDS ( 4 BYTES )
EXTRA ENDS
; DEFINICION DEL SEGMENTO DE CODIGO
CODE SEGMENT
ASSUME CS:CODE, DS:DATOS, ES: EXTRA, SS:PILA
FACT_DATO_1 DW 0
; MAIN PROCEDURE START
START PROC
;INITIALIZE REGISTERS
MOV AX, DATOS
MOV DS, AX
MOV AX, PILA
MOV SS, AX
MOV AX, EXTRA
MOV ES, AX
; LOAD SP TO STACK TOP
MOV SP, 64
;PROGRAM START
;SI MUST ALWAYS BE EQUAL TO THIS FOR A CORRECT INTERRUPTION PRINTING
MOV SI, OFFSET PMESSAGE
ADD SI, DS:SECPOSITION
MAINLOOP:
CALL PRINTBOARD ;PRINT BOARD
CALL TURN ;PLAYER TURN
CALL CHECKTURNS ;CHECK IF THE TURN WAS VALID
CMP DS:WINNER, 0 ;IF THERE IS WINNER THE GAME HAS ENDED
JE MAINLOOP
;ENDING OF THE GAME
;DISABLE TIMER
MOV AX,00H
INT 30H
;PRINT LAST BOARD
CALL PRINTBOARD
;CHECK IF THE GAME ENDED IN DRAW (EQUAL TO 1)
MOV AL,DS:WINNER
CMP AL,1
JE EMPATE
;CHANGE PLAYER (TO REVERT PLAYER CHANGING FOR THE NEW ROUND
MOV BX, PPOSITION
CMP AL,'1'
JNE WIN1
MOV AL,'2'
JMP MESSAGEACT
WIN1:
MOV AL,'1'
;SET MESSAGE TO WRITE
MESSAGEACT:
MOV DS:MESSAGEWIN[BX],AL
MOV DX,OFFSET MESSAGEWIN
JMP PRINT
EMPATE:
MOV DX,OFFSET MESSAGEMPATE
;PRINT THE END MESSAGE
PRINT:
MOV AH,09H
INT 21H
;END PROGRAM
MOV AX, 4C00H
INT 21H
START ENDP
PRINTBOARD PROC NEAR
;CLEAR SCREEN
MOV AH,0H
MOV AL,03H
INT 10H
;SET STARTING CORNER
MOV BX,0
MOV DI,35
ROW:
;JUMP TO A NEW LINE
MOV AH,09H
MOV DX, OFFSET NEXTLINE
INT 21H
COLUMN:
;PRINT CARACTER
MOV DL,DS:BOARD [BX] [DI]
XOR DH,DH
CALL PRINTCARACTER
;PRINT SEPARATOR
MOV DL, '|'
MOV AH,2
INT 21H
;INCREASE COLUMN
INC BX
CMP BX,7 ;IF ITS THE LAST COLUMN JUMP TO A NEW ROW
JNE COLUMN
;INCREASE ROW
MOV BX,0
SUB DI,7
CMP DI,0 ;IF ITS THE LAST ROW ITS DONE
JGE ROW
CMP DS:WINNER,0 ; IF THE IS WINNER DONT PRINT THE TURN MESSAGE
JNE ENDPR
;SET ACTUAL PLAYER
MOV DL, DS:PLAYER
MOV DI, DS:PPOSITION
MOV BX, OFFSET PMESSAGE
MOV DS:[BX][DI],DL
;PRINT TURN MESSAGE
MOV AH,09H
MOV DX, OFFSET PMESSAGE
INT 21H
ENDPR:
RET
ENDP PRINTBOARD
TURN PROC NEAR
;IF THE LAST TURN WAS CORRECT RESTART TIMER
CMP DS:CORRECTURN,0
JNE NOTRESTART
MOV AH,01H
INT 30H
NOTRESTART:
;RESET CORRECT TURN
MOV CX,0
MOV DS:CORRECTURN,0
;CHECK FOR INPUT UNTIL RECIVED OR IF THE TIMER RUNS OUT
READLOOP:
;IF TIMER EQUALS 0 IN ASCII THE TIMER IS OUT
MOV BX,DS:[SI]
CMP BX,3030H
JLE RANDOM
;CHECK FOR INPUT
MOV AH,0BH
INT 21H
;WHILE NOT INPUT RECEIVED AL EQUALS 0
CMP AL,0
JE READLOOP
;GET THE INPUT
MOV AH, 8H
INT 21H
JMP CONTIN
;IF THERE WAS NO INPUT SET COLUMN AT RANDOM
RANDOM:
MOV AH, 00H ; INTERRUPTS TO GET SYSTEM TIME
INT 1AH ; CX:DX NOW HOLD NUMBER OF CLOCK TICKS SINCE MIDNIGHT
MOV AX, DX
XOR DX, DX
;MULTIPLY AND ADD A NUMBER FOR SPREADING THE RANDOM RESULT
MOV CX,16645
MUL CX
ADD AX,2345
XOR DX,DX
; GET THE REMAINDER OF THE DIVISION - FROM 0 TO 7 (NUMBER OF COLUMNS)
MOV CX, 7
DIV CX
ADD DL, '1' ; CONVERT TO ASCII
MOV AL,DL
CONTIN:
;CHECK IF THE VALUE IS BETWEEN 1 AND 7 (IN ASCII)
MOV BL, AL
CMP BL,31H
JGE CHECKED
MOV DS:CORRECTURN,1
JMP ENDPROCESS
CHECKED:
CMP BL, 37H
JBE CHECKED1
MOV DS:CORRECTURN,1
JMP ENDPROCESS
CHECKED1:
;CONVERT FROM ASCII TO HEXADECIMAL (-1 BECAUSE THE FIRST COLUMN IS 0 IN REALITY)
SUB BL,31H
XOR BH,BH
;CHECK FOR A PLACE IN THE COLUMN
MOV DI,0
CHECKPLACE:
CMP DS:BOARD [BX][DI], ' ' ; IF THE CARACTER IN THAT CELL IS SPACE THE CELL IS EMPTY
JE TOKEN
;ADD SEVEN TO CHECK THE NEXT ROW
ADD DI,7
;IF DI IS GREATER THAN 35 WE ARE OUT OF THE BOARD (THE COLUMN IS FULL)
CMP DI,35
JBE CHECKED2
MOV DS:CORRECTURN,2
JMP ENDPROCESS
CHECKED2:
JMP CHECKPLACE
;SELECT PLAYER TOKEN (O FOR PLAYER 1, X FOR PLAYER 2)
TOKEN:
CMP DS:PLAYER,31H
JNE PLAYER2
MOV AL, 'O'
MOV DS:PLAYER,32H
JMP PLACETOKEN
PLAYER2:
MOV DS:PLAYER,31H
MOV AL, 'X'
;PLACE THE TOKEN IN THE EMPTY CELL ON THE BOARD
PLACETOKEN:
MOV DS:BOARD [BX][DI], AL
;CHECK IF THE MOVE MAKES SOMEONE WIN
MOV DS:LASTPOS, BX
MOV DS:LASTPOS+2,DI
MOV CX,0
;CHECK THE RIGHT
RIGHT:
INC CX
INC BX
CMP BX,7
JGE RIGHTC
CMP DS:BOARD [BX][DI], AL
JE RIGHT
RIGHTC:
MOV BX,DS:LASTPOS
DEC CX ;CORRECT COUNTING THE STARTING POSITION TWO TIMES
;CHECK THE LEFT WITHOUT RESTARTING THE COUNTER
LEFT:
INC CX
DEC BX
CMP BX,0
JL HORCOMP
CMP DS:BOARD [BX][DI], AL
JE LEFT
;CHECK IF THERE IS FOUR IN A ROW
HORCOMP:
CMP CX,4
JB VERT
MOV AH,DS:PLAYER
MOV DS:WINNER, AH
JMP ENDPROCESS
VERT:
MOV CX ,0
MOV BX,DS:LASTPOS
;CHECK UP RESTARTING THE COUNTER
UP:
INC CX
ADD DI,7
CMP DI,6*7
JGE UPC
CMP DS:BOARD [BX][DI], AL
JE UP
UPC:
MOV DI,DS:LASTPOS+2
DEC CX ;CORRECT COUNTING THE STARTING POSITION TWO TIMES
;CHECK DOWN WITHOUT RESTARTING THE COUNTER
DOWN:
INC CX
SUB DI, 7
CMP DI,0
JL VERTCOMP
CMP DS:BOARD [BX][DI], AL
JE DOWN
;CHECK IF THERE IS FOUR IN A ROW
VERTCOMP:
CMP CX,4
JB RIGHTUPD
MOV AH,DS:PLAYER
MOV DS:WINNER, AH
JMP ENDPROCESS
;CHECK RIGHT UP RESTARTING THE COUNTER
RIGHTUPD:
MOV CX,0
MOV DI,DS:LASTPOS+2
MOV BX,DS:LASTPOS
RIGHTUP:
INC CX
INC BX
ADD DI, 7
CMP BX,7
JGE RIGHTUPC
CMP DI,6*7
JGE RIGHTUPC
CMP DS:BOARD [BX][DI], AL
JE RIGHTUP
RIGHTUPC:
MOV BX,DS:LASTPOS
MOV DI,DS:LASTPOS+2
DEC CX ;CORRECT COUNTING THE STARTING POSITION TWO TIMES
;CHECK LEFT DOWN WITHOUT RESTARTING THE COUNTER
LEFTDOWN:
INC CX
DEC BX
SUB DI,7
CMP BX,0
JL RIGHTUPDCOMP
CMP DI,0
JL RIGHTUPDCOMP
CMP DS:BOARD [BX][DI], AL
JE LEFTDOWN
;CHECK IF THERE IS FOUR IN A ROW
RIGHTUPDCOMP:
CMP CX,4
JB RIGHTDOWND
MOV AH,DS:PLAYER
MOV DS:WINNER, AH
JMP ENDPROCESS
;CHECK RIGHTDOWN RESTARTING THE COUNTER
RIGHTDOWND:
MOV CX,0
MOV DI,DS:LASTPOS+2
MOV BX,DS:LASTPOS
RIGHTDOWN:
INC CX
INC BX
SUB DI, 7
CMP BX,7
JGE RIGHTDOWNC
CMP DI,0
JL RIGHTDOWNC
CMP DS:BOARD [BX][DI], AL
JE RIGHTDOWN
RIGHTDOWNC:
MOV BX,DS:LASTPOS
MOV DI,DS:LASTPOS+2
DEC CX ;CORRECT COUNTING THE STARTING POSITION TWO TIMES
;CHECK LEFT UP WITHOUT RESTARTING THE COUNTER
LEFTUP:
INC CX
DEC BX
ADD DI,7
CMP BX,0
JL LEFTUPDCOMP
CMP DI,7*6
JL LEFTUPDCOMP
CMP DS:BOARD [BX][DI], AL
JE LEFTUP
;CHECK IF THERE IS FOUR IN A ROW
LEFTUPDCOMP:
CMP CX,4
JB ENDPROCESS
MOV AH,DS:PLAYER
MOV DS:WINNER, AH
JMP ENDPROCESS
;IF IT IS NOT A CORRECT TURN DONT DESACTIVATE THE COUNTER
CMP DS:CORRECTURN,0
JNE ENDPROCESS
MOV AX,00H
INT 30H
ENDPROCESS:
RET
ENDP TURN
CHECKTURNS PROC NEAR
;CHECK IF THERE HAS BEEN AN ERROR AND SELECT THE MESAGGE
CMP DS: CORRECTURN,1
JNE CONT
MOV DX, OFFSET MESSAGEINVALIDCOLUMN
JMP PRINTERROR
CONT:
CMP DS: CORRECTURN,2
JNE CONT1
MOV DX, OFFSET MESSAGEFULLCOLUMN
;PRINT THE ERROR MESSAGE ON SCREEN
PRINTERROR:
MOV AH,09H
INT 21H
JMP ENDPROC
;IF THERE HAS BEEN NO ERROR ADD A TURN TO THE COUNT
CONT1:
MOV AL,DS:TURNS
INC AL
MOV DS:TURNS,AL
CMP AL,6*7 ; IF THERE HAS BEEN 6*7 TURNS THE BOARD IS FULL SO THERE IS A DRAW
JNE ENDPROC
MOV DS:WINNER, 1H ; SET WINNER TO DRAW
ENDPROC:
RET
ENDP CHECKTURNS
PRINTCARACTER PROC NEAR
PUSH AX SI DI BX CX
;GET CURSOR AND STORE IT
MOV DI,DX
MOV BH,0
MOV AH,03H
INT 10H
MOV SI,DX
;SELECT COLOR, CIAN FOR PLAYER ONE, MAGENTA FOR PLAYER TWO
MOV CX,DI
MOV BX,DI
MOV AL, CL
MOV BL,0H
CMP AL,'O'
JE CIAN
CMP AL,'X'
JE MAGENTA
JMP PRINTC
CIAN:
MOV BL,0BH
JMP PRINTC
MAGENTA:
MOV BL,0DH
;PRINT CARACTER
PRINTC:
MOV CX,1
MOV BH,0
MOV AH,09H
INT 10H
;SET CURSOR TO THE NEXT POSITION
MOV DX,SI
INC DL
MOV AH,02H
INT 10H
POP CX BX DI SI AX
RET
ENDP PRINTCARACTER
CODE ENDS
END START