From 2a94dfb8d5052b9cef22f8ba060c05a0add27d68 Mon Sep 17 00:00:00 2001 From: Elmar Kresse Date: Thu, 3 Jul 2025 15:53:46 +0200 Subject: [PATCH] Add initial source files for Tic-Tac-Toe game implementation Signed-off-by: Elmar Kresse --- MAIN.EXE | Bin 0 -> 3053 bytes MAIN.MAP | 9 ++ MAIN.OBJ | Bin 0 -> 3534 bytes MAIN.TR | Bin 0 -> 59 bytes data.asm | 49 +++++++ draw.asm | 344 ++++++++++++++++++++++++++++++++++++++++++++++ game.asm | 401 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ logic.asm | 140 +++++++++++++++++++ main.asm | 133 ++++++++++++++++++ sound.asm | 45 ++++++ 10 files changed, 1121 insertions(+) create mode 100644 MAIN.EXE create mode 100644 MAIN.MAP create mode 100644 MAIN.OBJ create mode 100644 MAIN.TR create mode 100644 data.asm create mode 100644 draw.asm create mode 100644 game.asm create mode 100644 logic.asm create mode 100644 main.asm create mode 100644 sound.asm diff --git a/MAIN.EXE b/MAIN.EXE new file mode 100644 index 0000000000000000000000000000000000000000..d1364048ed46a37c5acecf24520cb5f77aee15e1 GIT binary patch literal 3053 zcmeHIe`phT6n~dXFG;OQbo9+c31?t+*tq$;DQmL73A01x8CT-muFtRXn7XzFY*5W`Y%?% zdCkpT<7yg!HZKQPr`t1DHDb90h}}q3`+Wf~U9+Mr?rU3TUIB-{6P-6a+zk%BX=EwO zfOh3@fBQP*Mg~`>XH0joV$^&I64fy;jF}R32r#3S3b3aD7)BS!0GrXp&O*4J=h+M$ z8-?&v`Ar{rp6AiaFuG9j`X0hM1oBiSmFnFBRiz4?Q~+{gT10X+0q#_r+T}Jb@MAA}pH&yEMu|%dNneEimYzHNBNs`%0G(8ge zOkpe0ydn`+VOvURqsG`8B+{#}m1wFZvO{4j(fs{{tdX!2ZqH!mH_GzSF&ND3rsB+U z2vLXZJU^JZjYU}wzrvvg%l0&X`Ui$mWAi?6ifJVMy432Wr}eCT0GwbX#*c;nxGQoL7eos3T@IT!*O%yv`I+*1x^VvD61~Dt7tY6ho-f#Zd~&qrw>TXbX@O(+mMU2e}#>GbPu$%SySYG zv_n>v;_R%c+wb!R!Wa+^e^d|TPm27g6J5JHk&*jrIw{Wvz(%x;JeY$z=Ab~2SKP^^ zT(UU^FnuR~ESC~!t-xpmc9ss{cDzmHohXe;&}#*QMo^vFR41KAB~)kyqef7js>(SP z9jgsob@~Z+Q_iUL^Ik=iXOb*VRGM)H2QRnyCd}0>W3Fm?da_@<- z7=L}ln?bLHll0-sFz5O`^^*jKJ{;$N7{ALo(Z9k|9xN6Ju+QLKWZ_ z$!thCl@P?Mc)a`>VXXM|PdMejru-iwuVtOTC>Az@yinIB1rSb52q)phEhUH86?#N> zzkS4VpKv*0A!cPJj~_ZG5;ZNW!p4^7@K#)g2ZYXvR+r-CwO!A9(`Y+VJBCpXTW8=n za}%r>;29%g%P>fCI;XI_5P3wtlA>6gp&TalR9$UKNpY?c)m+UCoV$r}K!PCb|M}|rryvVG?)+cAJz7`MF0Q* literal 0 HcmV?d00001 diff --git a/MAIN.MAP b/MAIN.MAP new file mode 100644 index 0000000..5d13b3e --- /dev/null +++ b/MAIN.MAP @@ -0,0 +1,9 @@ + + Start Stop Length Name Class + + 00000H 0090EH 0090FH _TEXT CODE + 00910H 009ECH 000DDH _DATA DATA + 009F0H 00AEFH 00100H STACK STACK + +Program entry point at 0000:08A6 + diff --git a/MAIN.OBJ b/MAIN.OBJ new file mode 100644 index 0000000000000000000000000000000000000000..17d36b91153fb329f55f86313fab9f925e47a39f GIT binary patch literal 3534 zcma)Z!!+Cmoo+xS0IuzY=NQ7NC6t8gIS{C z@S;IBxQYy(Id=GUa24{rXO0^l1lM}{Bym5^^Oz+YTrFmWz{R2=E|r;(dTvoFD`9w9 zG+65E#{7C1&Vn9XM-Q$eEG>pt8R0=xP{sUa7*?csUI1YGr zoL8d4M3mIdJgRmyDqM+@TAHUZD*QrJOY`iB3La5yJ(FBD*0w1sG>d9!o}8#qBdVo& z{`0x;WE8&%gRyh&uZ;4g6VN&LG!vF?1Uu8A=K0RK_iCeMgyHPI;&&^PzW_KYn^8o1}M8+tp1?)>sw%A%Jchez%*Kv zUA81sW!!XtJ*$D804^!dD_^`I9?M11rMugFP>-oEC?TR!XG3? zgGnEjmf(_cZ&AmCTVLwI%_|)##l0wjQmE;BfeFgiGHh@a;R(V{LKR^@!A>|%c!hAD zaD{M{WnDaWWt}Fe0a!Tl{`5#O3i~8K+{CKx6AKvBqmi$bb zUz~qQKjrWny}2d8jdSBY_#b-|5ATogs;Cz2MUzF7qJ8&{!0`;8pB|4s(j`82u}dJS zOR$N>E~x~e7pP0zt9ahefl$Q?8#sZ1fJtvK)?$ZXpA2KaZ3FN1i3i?kPT0jYLYZei z(>?32Bv-oKvyjzxAkCsf8OQ!lp zOQ6;}t*3A-VB$f1TJN-vOCCs*2A&139&f52F!3ZN$>ozI4`fM$M3OF%#3s3X8OZ~A z(jbwPy;4%jw8@1hlJ4R?Noz`3MoM|f(q}mSFReV6ljm31y_A{KleRA= zrOcF)l)Ob^dE%F>=<-TmdN18$w z(TXJmZlF5debRh1{b|7yEtL(|2gj3Qx zkdFoS$?Jf34iTILH=zS#e@U?y5jR4$%#DRw<|bFm#E-!`w1)D{ zOsEWlL!=U_BU1xnZGSP~&xR=_K>rB_#@8hN=it5u0QTm^$7i1a*u9#Aj{Y}+rMHOx z=g(YKz8QZ}Y&O?a6xLU?wA$L#)ophC*`(h3&8h=s4TW3Po7Ma6j`l-G)J^s#yCX3u zEI~W|rfRWatfLTf+&@$wvAHnlS*ODhH#N7XnrhMRLZxQ=VGNk<&jR*tqR5VuGPni| Ib3q>cFE@wIJpcdz literal 0 HcmV?d00001 diff --git a/MAIN.TR b/MAIN.TR new file mode 100644 index 0000000000000000000000000000000000000000..1aacd97d42d2ab66264198a4e4fe6a02b98a1c0c GIT binary patch literal 59 zcmWG3ElSE)a7j%nO;1lPQYcC-E=epZQAo?oNtH@2S1T?gGVEF%^5lF%S6BCF9 E060kwQUCw| literal 0 HcmV?d00001 diff --git a/data.asm b/data.asm new file mode 100644 index 0000000..89bb731 --- /dev/null +++ b/data.asm @@ -0,0 +1,49 @@ +;**************************************** +; Elmar Kresse 19-INB-1 (2021) +; data.asm +; file contains variables and constant +; for music, drawing, text and game +; +;**************************************** + + +;Sounds +placeSound DD 4070, 100000 ; Note with pause +placeSoundLength = $ - placeSound + +gameOverSound DD 4560, 100000, 4304, 50000, 7239, 100000, 9121, 200000 +gameOverSoundLength = $ - gameOverSound + + +;coordinates and size +x_wert DW ? ;16 Bit variable +y_wert DW ? ;16 Bit variable +d_wert DW ? ;16 Bit variable + + +spieler DW ? ;current player (0,1) +field DW ? ;selected field (0-8) +balance dw 0 ;balance for check won (3 = 3 in a row) + + +;Player Arrays +player1 DW 0,0,0,0,0,0,0,0,0 +player2 DW 0,0,0,0,0,0,0,0,0 + +;main menue strings +title_str DB "TIC-TAC-TOE$" +signature_str DB "[Elmar Kresse 19INB]$" +choose1_str DB "1 - Mensch gegen Mensch$" +choose2_str DB "2 - Verlassen$" +cross_win DB "Kreuz hat gewonnen$" +circle_win DB "Kreis hat gewonnen$" +draw DB "Unentschieden$" + +;reset ISR var +oldIOFF DW ? +oldISeg DW ? + +;timer vector vars +old_timer DW 0 ;original int 1c vector +old_segment DW 0 ;original int 1c segment +timer_ticks DW 0 ;timer_ticks \ No newline at end of file diff --git a/draw.asm b/draw.asm new file mode 100644 index 0000000..72649be --- /dev/null +++ b/draw.asm @@ -0,0 +1,344 @@ +;**************************************** +; Elmar Kresse 19-INB-1 (2021) +; draw.asm +; file contains source code for +; drawing and maths for circle +; +; - draw_pixel MACRO x, y, c +; - circle_draw macro x, y, radius +; Reference Digital differential analyzer (graphics algorithm) +; https://en.wikipedia.org/wiki/Digital_differential_analyzer_(graphics_algorithm) +; +; - cross_draw MACRO x, y, d +; - rectangle_draw MACRO x, y, d +; - line_print_down PROC +; - line_print_straight PROC +; - paint_menu PROC FAR +; - prepare_display PROC +;**************************************** + +draw_pixel MACRO x, y, c + push ax + push bx + push cx + push dx + MOV AH, 0Ch ;setzen der Konfig fürs schreiben + MOV AL, c ; Farbe + MOV BH, 00h ;Set Seitennummber + MOV CX, x + MOV DX, y + INT 10h + pop dx + pop cx + pop bx + pop ax + ENDM + +circle_draw macro x, y, radius + push dx + push cx + push bx + push ax + + ;Werte zurücksetzen + mov balance, 0 + mov ax, 0 + mov bx, 0 + + ;Verschiebung Mitte + add x, 60 + add y, 60 + + mov bx, radius + mov balance, radius + neg balance + + + zeichne_kreis_schleife: + + ;0 to 45 + mov cx, x + add cx, bx + mov dx, y + sub dx, ax + draw_pixel cx, dx, 0Fh + ;90 to 45 + mov cx, x + add cx, ax + mov dx, y + sub dx, bx + draw_pixel cx, dx, 0Ch + ;90 to 135 + mov cx, x + sub cx, ax + mov dx, y + sub dx, bx + draw_pixel cx, dx, 04h + ;180 to 135 + mov cx, x + sub cx, bx + mov dx, y + sub dx, ax + draw_pixel cx, dx, 06h + ;180 to 225 + mov cx, x + sub cx, bx + mov dx, y + add dx, ax + draw_pixel cx, dx, 12h + ;270 to 225 + mov cx, x + sub cx, ax + mov dx, y + add dx, bx + draw_pixel cx, dx, 0Bh + ;270 to 315 + mov cx, x + add cx, ax + mov dx, y + add dx, bx + draw_pixel cx, dx, 01h + ;360 to 315 + mov cx, x + add cx, bx + mov dx, y + add dx, ax + draw_pixel cx, dx, 0Dh + + + push dx + mov dx, balance + add dx, ax + add dx, ax + mov balance, dx + pop dx + + + cmp balance, 0 + jl balance_negative + ;balance_positive: + dec bx + + push dx + mov dx, balance + sub dx, bx + sub dx, bx + mov balance, dx + pop dx + + + balance_negative: + inc ax + + cmp ax, bx + jg end_drawing + jmp zeichne_kreis_schleife + + + end_drawing: + ; pause the screen for dos compatibility: + + pop ax + pop bx + pop cx + pop dx + +endm + +cross_draw MACRO x, y, d + push ax + push bx + push cx + push dx + + + ;Erste FOR Schleife nach rechts unten + mov cx, x + mov dx, y + + xor cx,cx ; cx-register is the counter, setn to 0 + loop1: + push cx + mov cx, cx + mov dx, y + add dx, cx + add cx, x + draw_pixel cx, dx, 0Fh + pop cx + inc cx + cmp cx, d ; cx vergleich mit der Größe (Dimension d) + jle loop1 ; Loop while less or equal + + + xor cx,cx ; cx-register is the counter, setn to 0 + loop2: + push cx + mov cx, cx + mov dx, y + sub dx, cx + add cx, x + add dx, d + draw_pixel cx, dx, 0Dh + pop cx + inc cx + cmp cx, d ; cx vergleich mit der Größe (Dimension d) + jle loop2 ; Loop while less or equal + + pop ax + pop bx + pop cx + pop dx + + ENDM + +rectangle_draw MACRO x, y, d + ;Verwaltet move und call + mov cx, x + mov dx, y + mov x_wert, cx + mov y_wert, dx + mov d_wert, d + call line_print_down + call line_print_straight + ENDM + +line_print_down PROC + xor cx,cx ; cx-register is the counter, setn to 0 + loop3: + push cx + mov cx, cx + mov dx, y_wert + add cx, x_wert + draw_pixel cx, dx, 0Fh + add dx, d_wert + draw_pixel cx, dx, 0Fh + pop cx + inc cx + cmp cx, d_wert ; cx vergleich mit der Größe (Dimension d) + jle loop3 ; Loop while less or equal + ret +line_print_down endp + +line_print_straight PROC + xor dx,dx ; cx-register is the counter, setn to 0 + loop4: + push dx + mov dx, dx + mov cx, x_wert + add dx, y_wert + draw_pixel cx, dx, 0Fh + add cx, d_wert + draw_pixel cx, dx, 0Fh + pop dx + inc dx + cmp dx, d_wert ; cx vergleich mit der Größe (Dimension d) + jle loop4 ; Loop while less or equal + ret +line_print_straight endp + +paint_menu PROC FAR + + push ax + push bx + push dx + ;set pointer + mov ah,2 + mov dh,5 + mov dl,14 + mov bh,0 + int 10h + mov dx,offset title_str + mov ah,9 + int 21h + ;set pointer + mov ah,2 + mov dh,6 + mov dl,10 + mov bh,0 + int 10h + mov dx,offset signature_str + mov ah,9 + int 21h + + + ;set pointer + mov ah,2 + mov dh,7 + mov dl,11 + mov bh,0 + int 10h + + cmp cx, 2 + mov dx,offset cross_win + je zeige_gewinner + + + cmp cx, 3 + mov dx,offset circle_win + je zeige_gewinner + + + cmp cx, 4 + jne kein_gewinner + + mov ah,2 + mov dh,7 + mov dl,13 + mov bh,0 + int 10h + mov dx,offset draw + je zeige_gewinner + + zeige_gewinner: + mov ah,9 + int 21h + + kein_gewinner: + + + ;set pointer + mov ah,2 + mov dh,9 + mov dl,10 + mov bh,0 + int 10h + mov dx,offset choose1_str + mov ah,9 + int 21h + + ;set pointer + mov ah,2 + mov dh,10 + mov dl,10 + mov bh,0 + int 10h + mov dx,offset choose2_str + mov ah,9 + int 21h + + pop ax + pop bx + pop dx + + ret +paint_menu endp + +prepare_display PROC + ;Videomode clear alles entfernen + ;Spielfeld initialisieren + rectangle_draw 80, 10, 405 ; Kreuz MACRO + rectangle_draw 84, 14, 130 ; 1 + rectangle_draw 218, 14, 130 ; 2 + rectangle_draw 352, 14, 130 ; 3 + + rectangle_draw 84, 148, 130 ; 4 + rectangle_draw 218, 148, 130 ; 5 + rectangle_draw 352, 148, 130 ; 6 + + rectangle_draw 84, 282, 130 ; 7 + rectangle_draw 218, 282, 130 ; 8 + rectangle_draw 352, 282, 130 ; 9 + ret +prepare_display ENDP + +;---------------------------------------- DRAW ENDE --------------------------------------- \ No newline at end of file diff --git a/game.asm b/game.asm new file mode 100644 index 0000000..7153124 --- /dev/null +++ b/game.asm @@ -0,0 +1,401 @@ +;**************************************** +; Elmar Kresse 19-INB-1 (2021) +; game.asm +; file contains source code for the +; basic functions of the game logic +; +; - conkf MACRO x_kord, y_kord +; - conkf_prog PROC FAR +; - game_logic PROC +; - check_won_value MACRO a, b, c +; - check_draw PROC +; - reset_player_data PROC +; - check_won PROC +; - reset_timerisr PROC +; - start_game PROC +;**************************************** + +conkf MACRO x_kord, y_kord ;MACRO for coordinates to field + push dx + push cx + + + mov cx, x_kord + mov dx, y_kord + mov field, 0h + call conkf_prog + + pop cx + pop dx + ENDM + +conkf_prog PROC FAR ;PROC for coordinates to field +push ax +push bx +push cx +push dx + ;horizontal x + cmp cx, 482 + jg out_of_range + cmp cx, 352 + mov x_wert, 357 + jnl x_3 + cmp cx, 218 + mov x_wert, 223 + jnl x_2 + cmp cx, 84 + mov x_wert, 89 + jnl x_1 + jmp out_of_range + + x_3: + mov ax, 2 + jmp y_kordi + x_2: + mov ax, 1 + jmp y_kordi + x_1: + mov ax, 0 + +y_kordi: + ;vertical y + cmp dx, 412 + jg out_of_range + cmp dx, 282 + mov y_wert, 287 + jnl y_3 + cmp dx, 148 + mov y_wert, 153 + jnl y_2 + cmp dx, 14 + mov y_wert, 19 + jnl y_1 + jmp out_of_range + + y_3: + mov bx, 6 + jmp calc_field + y_2: + mov bx, 3 + jmp calc_field + y_1: + mov bx, 0 + + calc_field: + add ax, bx ;(A = ax) * (B = bx) = (goal = AX) + mov field, ax + jmp kord_final + + out_of_range: + mov field, 10 ;not in range(0-8) 10 is set for later checks + + kord_final: + + + pop dx + pop cx + pop bx + pop ax + + + + + ret +conkf_prog ENDP + +game_logic PROC + +conkf x_wert, y_wert + +;check valid field 0-8 +cmp field, 0ah +je end_game_logic + +;Feld frei + push ax + push si + mov si, field + shl si, 1 + cmp player1[si], 1 + pop si + pop ax + je end_game_logic + + push ax + push si + mov si, field + shl si, 1 + cmp player2[si], 1 + pop si + pop ax + je end_game_logic + + + +mov ax, spieler +cmp ax, 0 +je kreuz_spieler +jne kreis_spieler + +kreuz_spieler: + cross_draw x_wert, y_wert, 120 + + ;Sound + PUSH AX BX CX DX + MOV BX, OFFSET placeSound + MOV CX, OFFSET placeSoundLength + CALL playbeep + POP DX CX BX AX + + mov spieler, 1 ;Spieler umschalten + + ;Geklicketes Feld belegen + push ax + push si + mov si, field + shl si, 1 + mov player1[si], 1 + pop si + pop ax + + push cx + mov cx, offset player1 + call check_won + pop cx + cmp ax, 1 + jne end_game_logic + mov cx, 2 + call reset_timerisr + call start_programm + +kreis_spieler: + ;Kreis zeichnen + circle_draw x_wert, y_wert, 60 + + + ;Sound + PUSH AX BX CX DX + MOV BX, OFFSET placeSound + MOV CX, OFFSET placeSoundLength + CALL playbeep + POP DX CX BX AX + + mov spieler, 0 ;Spieler umschalten + + ;Geklicketes Feld belegen + push ax + push si + mov si, field + shl si, 1 + mov player2[si], 1 + pop si + pop ax + + push cx + mov cx, offset player2 + call check_won + pop cx + + cmp ax, 1 + jne end_game_logic + mov cx, 3 + call reset_timerisr + call start_programm + +end_game_logic: + +call check_draw +ret +game_logic ENDP + +check_won_value MACRO a, b, c +push ax +push bx + mov bx, 0 + mov ax, a; + shl ax, 1 + add bp, ax + add bx, ds:[bp] + mov bp, cx + mov ax, b; + shl ax, 1 + add bp, ax + add bx, ds:[bp] + mov bp, cx + mov ax, c; + shl ax, 1 + add bp, ax + add bx, ds:[bp] + mov bp, cx + cmp bx, 3 +pop bx +pop ax + je got_winner +ENDM + +check_draw PROC + + ;Überprüfen ob Unentschieden + push bx ;Counter ob alle Felder belegt sind + push ax ;Zahlvariable für Shiften + push cx ;Pointer für das Array des jeweiligen Spielers + push dx ;Zählvariable für Schleifen + push bp + mov bx, 0 + mov ax, 0 + mov dx, 0 + + mov cx, offset player1 ;pointer for player1 + + player1_field_loop: + mov ax, dx + shl ax, 1 + mov bp, cx + add bp, ax + add bx, ds:[bp] + inc dx + cmp dx, 9 + jne player1_field_loop + + mov cx, offset player2 ;pointer for player2 + mov dx, 0 + player2_field_loop: + mov ax, dx + shl ax, 1 + mov bp, cx + add bp, ax + add bx, ds:[bp] + inc dx + cmp dx, 9 + jne player2_field_loop + + + cmp bx, 9 + + pop bp + pop dx + pop cx + pop ax + pop bx + + je draw_end + jmp check_draw_end + +draw_end: + mov cx, 4 ; 4 = Unentschieden + call reset_timerisr + call start_programm + +check_draw_end: +ret +check_draw ENDP + +reset_player_data PROC + + push ax + push si + push bx ;Schleifen Zähler + mov bx, 0 + +resetloop_player1: + mov si, bx + shl si, 1 + mov player1[si], 0 + inc bx + cmp bx, 9 + jne resetloop_player1 + + mov bx, 0 +resetloop_player2: + mov si, bx + shl si, 1 + mov player2[si], 0 + inc bx + cmp bx, 9 + jne resetloop_player2 + + pop bx + pop si + pop ax +ret +reset_player_data ENDP + +check_won PROC +push bp +mov bp, cx + +;vertical + check_won_value 0, 3, 6 + check_won_value 1, 4, 7 + check_won_value 2, 5, 8 + +;horizontal + + check_won_value 2, 1, 0 + check_won_value 3, 4, 5 + check_won_value 6, 7, 8 + +;cross + check_won_value 0, 4, 8 + check_won_value 6, 4, 2 + jmp ende_check_won + +got_winner: +pop bp + +;play gameover sound +MOV BX, OFFSET gameOverSound +MOV CX, gameOverSoundLength +CALL playbeep + +mov ax, 1 ;var for save winner exists +ret + +ende_check_won: +pop bp +mov ax, 0 +ret +check_won ENDP + +reset_timerisr PROC + PUSH CX + PUSH DS + PUSH AX + PUSH DX + MOV AX, 251Ch ; Restore old user timer interrupt vector + MOV DX, [CS:old_timer] + MOV CX, [CS:old_segment] + MOV DS, CX + INT 21h + POP DX + POP AX + POP DS + POP CX + ret +reset_timerisr ENDP + +start_game PROC + CLI + + mov ax,00h + int 33h + or ax,ax + + call reset_player_data ;Spieler Array reset + mov ax,12h ;Videomodus + int 10h + + call prepare_display + + mov ax, 1 ;Curser an + int 33h + + ;Ersten Spieler setzten + + call prepare_mouse + mov spieler, 0 + call prepare_display + + STI + ret +start_game endp \ No newline at end of file diff --git a/logic.asm b/logic.asm new file mode 100644 index 0000000..8a6b2bf --- /dev/null +++ b/logic.asm @@ -0,0 +1,140 @@ +;**************************************** +; Elmar Kresse 19-INB-1 (2021) +; logic.asm +; file contains source code for the +; logic (mouse, timer, programm) +; +; - handle_timer_tick PROC +; - prepare_timer_tick PROC +; - prepare_mouse PROC +; - mouseProc PROC FAR +; - start_programm PROC +;**************************************** + +handle_timer_tick PROC + ; Call the original interrupt vector + ; by pushing flags register and doing a FAR CALL to old vector + PUSHF + CALL DWORD ptr [CS:old_timer] + INC WORD ptr [CS:timer_ticks] ; Increase timer counter + + IRET +handle_timer_tick ENDP + +prepare_timer_tick PROC + + PUSH DS + MOV AX, 351Ch ; Get user timer interrupt vector + INT 21h + ; ES:BX now has the address of the interrupt vector + MOV [CS:old_timer], BX + MOV AX, ES + MOV [CS:old_segment], AX + + MOV AX, 251ch ; Set user timer interrupt vector + PUSH CS + POP DS + MOV DX, OFFSET handle_timer_tick + INT 21h + + POP ds + + ret +prepare_timer_tick ENDP + +prepare_mouse PROC + + mov dx, OFFSET mouseProc ;jump to click_event_handler + mov ax, 0Ch + mov cx, 00000010b ; on left click + push cs ;es:dx + pop es + int 33h + + mov ax, 1 ;show cursor + int 33h + + ret +prepare_mouse ENDP + +mouseProc PROC FAR ;other doc segment therefore FAR + enter 0, 0 + push ax + push bx + push cx + push dx + push es + push ds + + mov ax, 2 ;hide cursor + int 33h + + ;dx contains coordinates of "rows" + mov y_wert, dx ;save y coordinate in variable + ;cx contains coordinates of "columns" + mov x_wert, cx ;save y coordinate in variable + + call game_logic + + xor bx, bx ;button pressed clear result + + mov ax, 1 ;show cursor + int 33h + + pop ds + pop es + pop dx + pop cx + pop bx + pop ax + leave + ret +mouseProc ENDP + +start_programm PROC + + mov AX, video_seg + mov es, AX + + + mov ax, @DATA + mov ds, ax + + + mov ax, 12h + int 10h + + mov dx, 03C4h ;address of the index port (share) + mov al, 2 ;index of control register + out dx, al ;Set index: output out :: dx to port al(2) + inc dx ;index of dataport + mov al, 0Fh ;value (1 = bit plane enabled, here all) fi + out dx, al + + + call prepare_timer_tick + + mov ax,0Dh + int 10h + + call paint_menu + + check_mode_loop: + xor ax, ax ;delete ah + int 16h ;keyboard query + + cmp al,'1' + je short playgame + + cmp al,'2' + je ende + + jmp check_mode_loop + + playgame: + call start_game + + +ret +start_programm ENDP + diff --git a/main.asm b/main.asm new file mode 100644 index 0000000..3d0300c --- /dev/null +++ b/main.asm @@ -0,0 +1,133 @@ +;**************************************** +; Elmar Kresse 19-INB-1 (2021) +; main.asm +; file contains source code for the +; main operations +; +;**************************************** + +.model small +.STACK 100h +.486 +esc_code = 1Bh ;esc key +video_seg = 0B800h + +.data +INCLUDE data.asm + + +.code +INCLUDE draw.asm +INCLUDE game.asmn +INCLUDE sound.asm +INCLUDE logic.asm + +ISR1Ch: push ds + push ax + mov ax, @DATA + mov ds, ax + pop ax + pop ds + iret + +;start of the main program +;---------------------------------------------------------------------------------------------------------- +Beginn: + + mov ax, @DATA + mov ds, ax + mov ax, 3 + int 10h + ;read old VT entry + mov al, 1Ch + mov ah, 35h + int 21h + ;es:bx address old ISR + ;save + mov oldIOFF, bx + mov oldISeg, es + ;store new ISR + push ds ; store ds + push cs + pop ds ; ds <- cs + mov dx, OFFSET ISR1Ch ; address in ds:dx + mov al, 1Ch ; + mov ah, 25h + int 21h + pop ds ; restore ds + + + call start_programm + +;-------------------------------------------------------------------------------------------------------- + +;Endlosschleife +;-------------------------------------------------------------------------------------------------------- +endlloop: + xor ax, ax ;delete ah + int 16h ;Keyboard query, waits for any key is pressed + cmp al, esc_code ;If esc is not pressed, the program remains in the endless loop + jne short endlloop ;jmp not equal + call reset_timerisr + mov cx, 0 + call start_programm + +;------------------------------------------------------------------------------------------------------- + +;End of the program and return to DOS +;----------------------------------------------------------------------------------------------------- +ende: + + PUSH DS + MOV AX, 251Ch ;Restore old user timer interrupt vector + MOV DX, [CS:old_timer] + MOV CX, [CS:old_segment] + MOV DS, CX + INT 21h + POP DS + + mov ax, 0 ;reset mouse programm + int 33h ;mouse interrupt + + MOV ax, 3 ;Reset screen mode + INT 10h + + mov dx, oldIOFF ;order is important + mov ax, oldISeg + mov ds, ax + mov al, 1Ch + mov ah, 25h + int 21h + + mov ah, 4Ch ;Backflow to DOS + int 21h + .stack 100h + end Beginn +;--------------------------------------------------------------------------------------------------- + + + + + + +; Convert X: Y coordinates to fields +; Check whether the field is free +; if free field +; test whether the player has won + +; 1 2 3 0 1 2 +; 1|2 3 4 0|0 1 2 +; 4|5 6 7 3|3 4 5 +; 7|8 9 10 6|6 7 8 + +;8 test cases +; 0,3,6 +; 1,4,7 +; 2,5,8 + +; 0,1,2 +; 3,4,5 +; 6,7,8 + +; 0,4,8 +; 6,4,2 \ No newline at end of file diff --git a/sound.asm b/sound.asm new file mode 100644 index 0000000..f17789e --- /dev/null +++ b/sound.asm @@ -0,0 +1,45 @@ +;**************************************** +; Elmar Kresse 19-INB-1 (2021) +; sound.asm +; file contains source code for +; only playing sounds +; +; - playbeep PROC +;source: http://muruganad.com/8086/8086-assembly-language-program-to-play-sound-using-pc-speaker.html +;**************************************** + + +playbeep PROC + MOV AL, 182 + OUT 43h, AL + beep: + + ;set frequency + MOV AX, [BX] + OUT 42h, AL + MOV AL, AH + OUT 42h, AL + ;sound on + IN AL, 61h + OR AL, 00000011b + OUT 61h, AL + + ADD BX, 4 + MOV WORD ptr [CS:timer_ticks], 0 + + ;break + timer_loop: + CMP WORD ptr [CS:timer_ticks], 3 + jne timer_loop + MOV WORD ptr [CS:timer_ticks], 0 + + ;sound off + IN AL, 61h + AND AL, 11111100b + OUT 61h, AL + + ADD BX, 4 + SUB CX, 8 + JNE beep + ret +playbeep ENDP