COMMENT *  
    Computer Systems Organization I: The Game
    VGA Fencing
    Main Procedure: game.asm
END COMMENT *

TITLE   VGA FENCING SIMULATOR
.MODEL  SMALL
.STACK  100H
.DATA
  ; the following two arrays are informational arrays used to denote
  ; information about the player and the opponent.  
  ;   MYINFO[1]=>  position of strip (0 to 32)
  ;   MYINFO[2]=>  number of points (0-5)
  ;   MYINFO[3]=>  value of parry (0-3), none/high/med/low
  ;   MYINFO[4]=>  value of cut (0-3), none/high/med/low
  ;   MYINFO[5]=>  graphic value used by DRAWME procedure
  ;   MYINFO[6]=>  graphic value also used by DRAWME
  
  MYINFO        DB  7 DUP (0)        
 
  HISINFO       DB  7 DUP (0)        
  HISPOS        DB 0  

  NEW_KEY_VEC   DW  ?,?
  OLD_KEY_VEC   DW  ?,?
  SCAN_CODE     DB  0
  KEY_FLAG      DB  0
  TIMER_FLAG    DB  0
  DISTANCE      DB  25
  
  ; scan codes
  LEFT_ARROW = 75
  RIGHT_ARROW = 77
  ESC_KEY = 1
  W_KEY = 11h
  S_KEY = 1Fh
  X_KEY = 2Dh
  Q_KEY = 10h
  A_KEY = 1Eh
  Z_KEY = 2Ch
  
  ; colors
  FENCOLOR = 0          ; fencer color
  BGCOLOR = 1           ; background color
  STRCOLOR = 15
  BCLR = 14             ; box color
  WCLR = 14             ; word color

.CODE  

MAIN    PROC

        MOV     AX,@DATA                ; initialize data into AX
        MOV     DS,AX

        CALL    SET_GRAPHICS            ; set graphics mode
        CALL    DRAW_TITLE

MATCHLOOP:
        
        CMP     MYINFO[2],5              ; check if anyone has 5 points
        JE      MP_DONE1                ; which wins the game.
        CMP     HISINFO[2],5             ; MP_DONE1 is a midpoint label
        JE      MP_DONE1                ; used to get around the 127 byte
                                        ; limit.
        
        MOV     MYINFO[1],2             ; place me at one end of strip
        MOV     HISPOS,30               ; and opponent at other end.

; initial setup

        CALL    DRAW_BG                 ; draw background, which includes
                                        ; strip, logo, and scores
        MOV     AL,FENCOLOR             ; set color of me
        CALL    DRAWME                  ; draws me
        MOV     AL,FENCOLOR             ; set color of opponent
        CALL    DRAWHIM                 ; draws opponent

; setup keyboard interrupt vector
        MOV     NEW_KEY_VEC, OFFSET KEYBOARD_INT
        MOV     NEW_KEY_VEC+2,CS
        MOV     AL,9H                   ; interrupt number
        LEA     DI,OLD_KEY_VEC
        LEA     SI,NEW_KEY_VEC
        CALL    SETUP_INT
        JMP     TEST_KEY


; this label is used to get around the 127 byte JMP rule.
MP_DONE1:
        JMP     MP_DONE2                ; heads to the next midpoint label

; check key flag
TEST_KEY:
        CMP     KEY_FLAG,1              ; check key flag
        JNE     MP_TEST                 ; not set, go check timer flag
        MOV     KEY_FLAG,0              ; set, clear it and check for

        CMP     SCAN_CODE,ESC_KEY       ; ESC key?
        JNE     TK_1                    ; no, check other keys
        JMP     MP_ESC                  ; yes, exit program
TK_1:   CMP     SCAN_CODE,LEFT_ARROW    ; left arrow?
        JNE     TK_2                    ; if not goto next
        CMP     MYINFO[1],2                ; at end of strip?
        JE      MP_TEST                 ; ignore if so.
        ;CMP     DISTANCE,5                  ; running into him?
        ;JLE     TK_2
        CALL    CLEAROLD                ; clear the old one
        CALL    MEWALK                  ; make him walk a step
        SUB     MYINFO[1],1                ; move one space back
        MOV     AL,FENCOLOR             ; draw a new one
        CALL    DRAWME
        JMP     MP_TEST                 ; and check timer flag.
TK_2:   CMP     SCAN_CODE,RIGHT_ARROW   ; right arrow?
        JNE     TK_3                    ; if not, goto next
        CMP     MYINFO[1],25               ; at other end of strip?
        JE      MP_TEST                 ; ignore key if so.
        CALL    CLEAROLD                ; clear the old one
        CALL    MEWALK
        ADD     MYINFO[1],1                ; else add one (move one space)
        MOV     AL,FENCOLOR             ; draw a new one
        CALL    DRAWME
        JMP     MP_TEST                 ; and check timer flag.

; these labels are used to get around the 127 byte JMP rule.
   MP_TEST:
        JMP     MP_TEST2
   MP_MATCH1:
        JMP     MATCHLOOP

TK_3:   CMP     SCAN_CODE,W_KEY         ; W?
        JNE     TK_4                    ; if not, goto next
        CALL    CLEAROLD
        MOV     MYINFO[4],1             ; set strike to high
        MOV     MYINFO[6],2             ; set to graphic 2
        MOV     AL,FENCOLOR
        CALL    DRAWME
        JMP     TEST_TIMER              ; and check timer flag.
TK_4:   CMP     SCAN_CODE,S_KEY         ; S?
        JNE     TK_5                    ; if not, goto next
        CALL    CLEAROLD
        MOV     MYINFO[4],2              ; set strike to medium
        MOV     MYINFO[6],3              ; set to graphic 3
        MOV     AL,FENCOLOR
        CALL    DRAWME
        JMP     TEST_TIMER              ; and check timer flag.

; these labels used to get around the 127 byte JMP rule.
   MP_TEST2:
        JMP     TEST_TIMER              ; to get around 127 byte rule
   MP_TESTKEY:
        JMP     TEST_KEY                ; to get around 127 byte rule
   MP_MATCH2:
        JMP     MP_MATCH1


TK_5:   CMP     SCAN_CODE,X_KEY         ; X?
        JNE     TK_6                    ; if not, goto next
        CALL    CLEAROLD
        MOV     MYINFO[4],3              ; set strike to low
        MOV     MYINFO[6],4              ; set to graphic 4
        MOV     AL,FENCOLOR
        CALL    DRAWME
        JMP     TEST_TIMER              ; and check timer flag.

TK_6:   CMP     SCAN_CODE,Q_KEY         ; Q?
        JNE     TK_7                    ; if not, goto next
        CALL    CLEAROLD
        MOV     MYINFO[3],1              ; set guard to high
        MOV     MYINFO[6],5              ; set to graphic 5
        MOV     AL,FENCOLOR
        CALL    DRAWME
        JMP     TEST_TIMER              ; and check timer flag.

TK_7:   CMP     SCAN_CODE,A_KEY         ; A?
        JNE     TK_8
        CALL    CLEAROLD
        MOV     MYINFO[3],2              ; set guard to medium
        MOV     MYINFO[6],6              ; set to graphic 6
        MOV     AL,FENCOLOR
        CALL    DRAWME
        JMP     TEST_TIMER              ; and check timer flag.

; these labels used to get around the 127 byte JMP rule.
   MP2_TESTKEY:    JMP     MP_TESTKEY

TK_8:   CMP     SCAN_CODE,Z_KEY         ; Z?
        JNE     TEST_TIMER              ; if not, goto timer flag
        CALL    CLEAROLD
        MOV     MYINFO[3],3              ; set guard to low
        MOV     MYINFO[6],7              ; set to graphic 7
        MOV     AL,FENCOLOR
        CALL    DRAWME
        JMP     TEST_TIMER

; these labels used to get around the 127 byte JMP rule.
   MP_DONE2:
        JMP     DONE                    ; gets around the 127 byte JMP rule
   MP_ESC:
        JMP     DONEESC

; check timer

TEST_TIMER:
        MOV     AL,FENCOLOR
        CALL    DRAWME
        CALL    ENEMYACT               ; enemy does something (flagset)
        MOV     AL, FENCOLOR
        CALL    DRAWHIM                 ; draw the new "him" erase old
        
        MOV     AL,HISPOS
        SUB     AL,MYINFO[1]           ; load DISTANCE between us
        MOV     DISTANCE,AL

; all the checks

        ; am I within range?
        CMP     DISTANCE,8              ; if we're within 5, we can
        JG      MP2_TESTKEY

        CMP     MYINFO[4],0             ; am I not striking?
        JE      CHECKHISSTR             ; see if he is.
                                        ; if I AM striking,
        MOV     AL,MYINFO[4]
        CMP     HISINFO[3],AL           ; is my strike=hisguard?
        JNE     HITHIM
        
CHECKHISSTR:        
        CMP     HISINFO[4],0            ; is he striking?
        JE      MP2_TESTKEY              ; if not, no one's doing stuff.
        MOV     AL,MYINFO[3]
        CMP     HISINFO[4],AL           ; is his strike=myguard?
        JNE     HITME                   ; I'm hit.

        JMP     MP_TESTKEY              ; else forget it.

HITHIM:
        INC     MYINFO[2]               ; I get a point.
        ; put some display stuff here
        CALL    TOUCHRIGHT        
        JMP     RESTART

HITME:
        INC     HISINFO[2]              ; he gets a point.
        ; put some display stuff here
        CALL    TOUCHLEFT        
        JMP     RESTART

RESTART:
        LEA     DI,NEW_KEY_VEC
        LEA     SI,OLD_KEY_VEC
        MOV     AL,9H
        CALL    SETUP_INT
        MOV     MYINFO[3],0
        MOV     HISINFO[3],0
        MOV     MYINFO[4],0
        MOV     HISINFO[4],0
        MOV     MYINFO[6],0
        MOV     MYINFO[6],0
        JMP     MP_MATCH2

DONE:   
        CALL    MATCHEND
        CALL    DRAW_FINISH

DONEESC:
; reset timer interrupt vector
        LEA     DI,NEW_KEY_VEC
        LEA     SI,OLD_KEY_VEC
        MOV     AL,9H
        CALL    SETUP_INT
; read key
        MOV     AH,0
        INT     16H
        
        CALL    DRAW_FINISH
; reset to text mode
        MOV     AH,0
        MOV     AL,3
        INT     10H

; return to DOS
        MOV     AH,4CH
        INT     21H

MAIN    ENDP

INCLUDE MAC.ASM
INCLUDE SETUP.ASM
INCLUDE DRAWME.ASM
INCLUDE DRAWHIM.ASM
INCLUDE ENEMYACT.ASM
INCLUDE TITLE.ASM        
INCLUDE FINISH.ASM
        END MAIN
