; *******************************************************************
; DRAW_BG: background drawer
; WHAT:    draws in peripheral graphics, scores, and strip
; CREDITS: Albert Ming
; *******************************************************************

DRAW_BG         PROC
; draws the background section.

        PUSH    DX
        PUSH    CX      ; save counter register
        PUSH    BX      ; save BX
        PUSH    AX
        
        MOV     AH,0Ch  ; set function to draw pixel
        MOV     AL,STRCOLOR        ; set pixel color to color of strip
        
        MOV     BH,0    ; set initial value to 0 (page)
        MOV     CX,0    ; set col to 0
        MOV     DX,190  ; set row to 210

        ; now we draw the big white bar.

BGLOOP1: 
        CMP     DX,350  ; is DX at 410? (end of where we want to draw)
        JE      ENDBG   ; if so, exit BG
        INC     DX      ; else increment DX and go on
        MOV     CX,0    ; set CX back to 0
BGLOOP2:
        CMP     CX,640  ; is CX at the end?
        JE      BGLOOP1 ; if so, go to the next row.
        INT     10H     ; else draw the pixel
        INC     CX      ; and move to the next column.
        JMP     BGLOOP2

ENDBG:  ; now we display the word "VGA Fencing"

; cool box around it
        DRAWCH 4,31,BCLR,201
        DRAWCH 4,32,BCLR,205
        DRAWCH 4,33,BCLR,205
        DRAWCH 4,34,BCLR,205
        DRAWCH 4,35,BCLR,205
        DRAWCH 4,36,BCLR,205
        DRAWCH 4,37,BCLR,205
        DRAWCH 4,38,BCLR,205
        DRAWCH 4,39,BCLR,205
        DRAWCH 4,40,BCLR,205
        DRAWCH 4,41,BCLR,205
        DRAWCH 4,42,BCLR,205
        DRAWCH 4,43,BCLR,205
        DRAWCH 4,44,BCLR,205
        DRAWCH 4,45,BCLR,187
        DRAWCH 5,31,BCLR,186
        DRAWCH 5,45,BCLR,186
        DRAWCH 6,31,BCLR,200
        DRAWCH 6,45,BCLR,188
        DRAWCH 6,32,BCLR,205
        DRAWCH 6,33,BCLR,205
        DRAWCH 6,34,BCLR,205
        DRAWCH 6,35,BCLR,205
        DRAWCH 6,36,BCLR,205
        DRAWCH 6,37,BCLR,205
        DRAWCH 6,38,BCLR,205
        DRAWCH 6,39,BCLR,205
        DRAWCH 6,40,BCLR,205
        DRAWCH 6,41,BCLR,205
        DRAWCH 6,42,BCLR,205
        DRAWCH 6,43,BCLR,205
        DRAWCH 6,44,BCLR,205


        DRAWCH 5,33,WCLR,'V'
        DRAWCH 5,34,WCLR,'G'
        DRAWCH 5,35,WCLR,'A'
        DRAWCH 5,37,WCLR,'F'
        DRAWCH 5,38,WCLR,'e'
        DRAWCH 5,39,WCLR,'n'
        DRAWCH 5,40,WCLR,'c'
        DRAWCH 5,41,WCLR,'i'
        DRAWCH 5,42,WCLR,'n'
        DRAWCH 5,43,WCLR,'g'


; now we draw in the value of points scored
        DRAWCH  3,3,WCLR,'Y'
        DRAWCH  3,4,WCLR,'o'
        DRAWCH  3,5,WCLR,'u'
        MOV     AL,MYINFO[2]
        ADD     AL,48
        DRAWCH  4,4,14,AL

        DRAWCH  3,76,WCLR,'H'
        DRAWCH  3,77,WCLR,'i'
        DRAWCH  3,78,WCLR,'m'
        MOV     AL,HISINFO[2]
        ADD     AL,48
        DRAWCH  4,77,14,AL

        DRAWCH  24,32,WCLR,'F'
        DRAWCH  24,33,WCLR,'e'
        DRAWCH  24,34,WCLR,'n'
        DRAWCH  24,35,WCLR,'c'
        DRAWCH  24,36,WCLR,'e'
        DRAWCH  24,37,WCLR,'r'
        DRAWCH  24,38,WCLR,'s'
        DRAWCH  24,39,WCLR,' '
        DRAWCH  24,40,WCLR,'r'
        DRAWCH  24,41,WCLR,'e'
        DRAWCH  24,42,WCLR,'a'
        DRAWCH  24,43,WCLR,'d'
        DRAWCH  24,44,WCLR,'y'
        DRAWCH  24,45,WCLR,'?'
  
  MOV  AH,0
  INT 16H


; erase "fencers ready"
        DRAWCH  24,32,WCLR,' '
        DRAWCH  24,33,WCLR,' '
        DRAWCH  24,34,WCLR,' '
        DRAWCH  24,35,WCLR,' '
        DRAWCH  24,36,WCLR,' '
        DRAWCH  24,37,WCLR,' '
        DRAWCH  24,38,WCLR,' '
        DRAWCH  24,39,WCLR,' '
        DRAWCH  24,40,WCLR,' '
        DRAWCH  24,41,WCLR,' '
        DRAWCH  24,42,WCLR,' '
        DRAWCH  24,43,WCLR,' '
        DRAWCH  24,44,WCLR,' '
        DRAWCH  24,45,WCLR,' '


        DRAWCH  24,36,WCLR,'F'
        DRAWCH  24,37,WCLR,'e'
        DRAWCH  24,38,WCLR,'n'
        DRAWCH  24,39,WCLR,'c'
        DRAWCH  24,40,WCLR,'e'
        DRAWCH  24,41,WCLR,'!'


        POP     DX      ; restore registers
        POP     CX
        POP     BX
        POP     AX

        RET

DRAW_BG         ENDP

; *******************************************************************
; SET_GRAPHICS: initial graphics setup
; WHAT:    sets initial display mode and background color
; CREDITS: Albert Ming
; *******************************************************************

SET_GRAPHICS    PROC
        PUSH    AX
        PUSH    BX
        MOV     AH, 0           ;  sets function call 0 for int 10, display
        MOV     AL, 12H         ;  sets video mode to 600x480, 16 color
        INT     10H             
        MOV     AH, 0BH         ;  sets background function call
        MOV     BH, 0           ; 
        MOV     BL, BGCOLOR     ;  makes the background "blue"
        INT     10H
        POP     BX
        POP     AX
RET
SET_GRAPHICS    ENDP


; *******************************************************************
; SETUP_INT 
; What:    sets up interrupts for Keyboard interrupt
; Credits: taken from the book
; *******************************************************************

SETUP_INT       PROC
; saves old vector and sets up new vector
; input: AL = interrupt number
;        DI = address of buffer for old vector
;        SI = address of buffer containing new vector
; save old interrupt vector
        MOV     AH,35H          ; function 35H, get vector
        INT     21H             ; ES:BX - vector
        MOV     [DI],BX         ; save offset
        MOV     [DI+2],ES       ; save segment
; setup new vector
        MOV     DX,[SI]         ; DX has offset
        PUSH    DS              ; save DS
        MOV     DS,[SI+2]       ; DS has segment number
        MOV     AH,25H          ; function 25h, set vector
        INT     21H             
        POP     DS              ; restore DS
        RET

SETUP_INT       ENDP

; *******************************************************************
; KEYBOARD_INT: 
; WHAT:    sets up the keyboard interrupt
; CREDITS: Ytha Yu and Charles Marut
; *******************************************************************

KEYBOARD_INT    PROC
; save registers        
        PUSH    DS
        PUSH    AX
; setup ds        
        MOV     AX, SEG SCAN_CODE
        MOV     DS,AX
; input scan code        
        IN      AL,60H
        PUSH    AX
        IN      AL,61H
        MOV     AH,AL
        OR      AL,80H
        OUT     61H,AL
        XCHG    AH,AL
        OUT     61H,AL
        POP     AX
        MOV     AH,AL
        TEST    AH,80H
        JNE     KEY_0
; make code        
        MOV     SCAN_CODE,AL
        MOV     KEY_FLAG,1
KEY_0:  MOV     AL,20H
        OUT     20H,AL
        POP     AX
        POP     DS
        IRET

KEYBOARD_INT    ENDP

; *******************************************************************
; RETMYPOS and RETHISPOS
; WHAT:    takes in a value from MYINFO and returns in CX a value
;          of the strip location in pixels.
; CREDITS: Albert Ming
; *******************************************************************

RETMYPOS        PROC
        PUSH    AX              ; save ax register
        MOV     AL,MYINFO[1]    ; puts my pos (0-32) in AX
        XOR     AH,AH           ; clear high byte of AX
        MOV     CL,20
        MUL     CL              ; multiplies by 20 to get pixel coord.
        MOV     CX,AX
        POP     AX      ; return ax register
        RET
RETMYPOS        ENDP

RETHISPOS       PROC
        PUSH    AX              ; save ax register
        
        XOR     CX,CX
        MOV     AL,HISPOS       ; puts my pos (0-32) in AX
        XOR     AH,AH           ; clear high byte of AX
        MOV     CL,20
        MUL     CL              ; multiplies by 20 to get pixel coord.
        MOV     CX,AX           ; CX now contains the position in pixels.
        POP     AX      ; return ax register
        RET
RETHISPOS        ENDP

; *******************************************************************
; MEWALK
; WHAT:    calls the "walk" graphic, puts in a delay, and redraws.
;          takes value from MYINFO[6].
; CREDITS: Warren Chang, Robert Kong, Albert Ming
; *******************************************************************
MEWALK        PROC
        PUSH    AX
        PUSH    CX
        MOV     MYINFO[6],1                
        MOV     AL,FENCOLOR
        CALL    DRAWME
        ; CALL DELAY
        MOV     AL,STRCOLOR
        CALL    DRAWME
        MOV     MYINFO[6],0
        POP     CX
        POP     AX
        RET
MEWALK        ENDP

; *******************************************************************
; HISWALK
; WHAT:    calls the "walk" graphic, puts in a delay, and redraws.
;          takes value from HISINFO[6].
; CREDITS: Warren Chang, Robert Kong, Albert Ming
; *******************************************************************
HISWALK        PROC
        PUSH    AX
        PUSH    CX
        MOV     HISINFO[6],1                
        MOV     AL,FENCOLOR
        CALL    DRAWHIM
        ; CALL DELAY
        MOV     AL,STRCOLOR
        CALL    DRAWHIM
        MOV     HISINFO[6],0
        POP     CX
        POP     AX
        RET
HISWALK        ENDP

; *******************************************************************
; TOUCHLEFT
; WHAT:    stops the action, puts up a graphic screen indicating this
; CREDITS: Albert Ming
; *******************************************************************

TOUCHLEFT       PROC
        DRAWCH  24,32,WCLR,'T'
        DRAWCH  24,33,WCLR,'o'
        DRAWCH  24,34,WCLR,'u'
        DRAWCH  24,35,WCLR,'c'
        DRAWCH  24,36,WCLR,'h'
        DRAWCH  24,37,WCLR,'e'
        DRAWCH  24,38,WCLR,' '
        DRAWCH  24,39,WCLR,'l'
        DRAWCH  24,40,WCLR,'e'
        DRAWCH  24,41,WCLR,'f'
        DRAWCH  24,42,WCLR,'t'
        DRAWCH  24,43,WCLR,'.'
        DRAWCH  24,44,WCLR,'.'
        DRAWCH  24,45,WCLR,'.'
        
        DRAWCH  24,32,WCLR,'P'
        DRAWCH  24,33,WCLR,'o'
        DRAWCH  24,34,WCLR,'i'
        DRAWCH  24,35,WCLR,'n'
        DRAWCH  24,36,WCLR,'t'
        DRAWCH  24,37,WCLR,' '
        DRAWCH  24,38,WCLR,'t'
        DRAWCH  24,39,WCLR,'o'
        DRAWCH  24,40,WCLR,' '
        DRAWCH  24,41,WCLR,'r'
        DRAWCH  24,42,WCLR,'i'
        DRAWCH  24,43,WCLR,'g'
        DRAWCH  24,44,WCLR,'h'
        DRAWCH  24,45,WCLR,'t'
        DRAWCH  24,46,WCLR,'.'

        CALL    DELAY2

        RET
TOUCHLEFT       ENDP

; *******************************************************************
; TOUCHRIGHT
; WHAT:    stops the action, puts up a graphic screen indicating this
;          i.e. that the left player got the point.
; CREDITS: Albert Ming
; *******************************************************************

TOUCHRIGHT      PROC
        DRAWCH  24,32,WCLR,'T'
        DRAWCH  24,33,WCLR,'o'
        DRAWCH  24,34,WCLR,'u'
        DRAWCH  24,35,WCLR,'c'
        DRAWCH  24,36,WCLR,'h'
        DRAWCH  24,37,WCLR,'e'
        DRAWCH  24,38,WCLR,' '
        DRAWCH  24,39,WCLR,'r'
        DRAWCH  24,40,WCLR,'i'
        DRAWCH  24,41,WCLR,'g'
        DRAWCH  24,42,WCLR,'h'
        DRAWCH  24,43,WCLR,'t'
        DRAWCH  24,44,WCLR,'.'
        DRAWCH  24,45,WCLR,' '

        DRAWCH  24,32,WCLR,'P'
        DRAWCH  24,33,WCLR,'o'
        DRAWCH  24,34,WCLR,'i'
        DRAWCH  24,35,WCLR,'n'
        DRAWCH  24,36,WCLR,'t'
        DRAWCH  24,37,WCLR,' '
        DRAWCH  24,38,WCLR,'t'
        DRAWCH  24,39,WCLR,'o'
        DRAWCH  24,40,WCLR,' '
        DRAWCH  24,41,WCLR,'l'
        DRAWCH  24,42,WCLR,'e'
        DRAWCH  24,43,WCLR,'f'
        DRAWCH  24,44,WCLR,'t'
        DRAWCH  24,45,WCLR,'.'
        DRAWCH  24,46,WCLR,' '

        CALL    DELAY2

        RET
TOUCHRIGHT      ENDP

; *******************************************************************
; MATCHEND 
; WHAT:    says who won
; CREDITS: Albert Ming
; *******************************************************************
MATCHEND        PROC
        DRAWCH  24,32,WCLR,'M'
        DRAWCH  24,33,WCLR,'a'
        DRAWCH  24,34,WCLR,'t'
        DRAWCH  24,35,WCLR,'c'
        DRAWCH  24,36,WCLR,'h'
        DRAWCH  24,37,WCLR,' '
        DRAWCH  24,38,WCLR,'i'
        DRAWCH  24,39,WCLR,'s'
        DRAWCH  24,40,WCLR,' '
        DRAWCH  24,41,WCLR,'e'
        DRAWCH  24,42,WCLR,'n'
        DRAWCH  24,43,WCLR,'d'
        DRAWCH  24,44,WCLR,'e'
        DRAWCH  24,45,WCLR,'d'
        DRAWCH  24,46,WCLR,'.'

        MOV     AL,MYINFO[2]            ; load score
        CMP     HISINFO[2],AL           ; how does he compare?
        JLE     IWIN0

        DRAWCH  24,32,WCLR,'W'
        DRAWCH  24,33,WCLR,'i'
        DRAWCH  24,34,WCLR,'n'
        DRAWCH  24,35,WCLR,'n'
IWIN0:  JMP     IWIN1
        DRAWCH  24,36,WCLR,'e'
        DRAWCH  24,37,WCLR,'r'
        DRAWCH  24,38,WCLR,' '
        DRAWCH  24,39,WCLR,'i'
        JMP     NEXTSPT        
IWIN1:  JMP     IWIN2
NEXTSPT:
        DRAWCH  24,40,WCLR,'s'
        DRAWCH  24,41,WCLR,' '
        DRAWCH  24,42,WCLR,'r'
        DRAWCH  24,43,WCLR,'i'
        DRAWCH  24,44,WCLR,'g'
IWIN2:  JMP     IWIN3
        DRAWCH  24,45,WCLR,'h'
        DRAWCH  24,46,WCLR,'t'
        DRAWCH  24,47,WCLR,'.'
        CALL    DELAY2
        JMP     WINFIN

IWIN3:  DRAWCH  24,32,WCLR,'M'
        DRAWCH  24,33,WCLR,'a'
        DRAWCH  24,34,WCLR,'t'
        DRAWCH  24,35,WCLR,'c'
        DRAWCH  24,36,WCLR,'h'
        DRAWCH  24,37,WCLR,' '
        DRAWCH  24,38,WCLR,'i'
        DRAWCH  24,39,WCLR,'s'
        DRAWCH  24,40,WCLR,' '
        DRAWCH  24,41,WCLR,'l'
        DRAWCH  24,42,WCLR,'e'
        DRAWCH  24,43,WCLR,'f'
        DRAWCH  24,44,WCLR,'t'
        DRAWCH  24,45,WCLR,'.'
        DRAWCH  24,46,WCLR,'.'


WINFIN: 
        CALL    DELAY2
        
        RET
MATCHEND        ENDP

; *******************************************************************
; CLEAROLD 
; WHAT:    used to erase the old image and clear attack/guard regs.
; CREDITS: Albert Ming
; *******************************************************************
CLEAROLD        PROC
        MOV     AL,STRCOLOR
        CALL    DRAWME
        MOV     MYINFO[3],0
        MOV     MYINFO[4],0
        RET
CLEAROLD        ENDP

; *******************************************************************
; HCLEAROLD 
; WHAT:    used to erase the old image and clear attack/guard regs.
;          used by the ENEMYACT procedure.
; CREDITS: Albert Ming
; *******************************************************************

HCLEAROLD       PROC
        MOV     AL,STRCOLOR
        CALL    DRAWHIM
        MOV     HISINFO[3],0
        MOV     HISINFO[4],0
        RET
HCLEAROLD       ENDP

; *******************************************************************
; declarations taken from Nathan Hull's GAME96 program
; *******************************************************************

CTRL      EQU   61H           ; timer gate control port
TIMR      EQU   00000001B     ; bit to turn timer on
SPKR      EQU   00000010B     ; bit to turn speaker on
;
;  Definitions of input/output ports to access timer chip
;
TCTL      EQU   043H          ; port for timer control
TCTR      EQU   042H          ; port for timer count values
;
;  Definitions of timer control values (to send to control port)
;
TSQW      EQU   10110110B     ; timer 2, 2 bytes, sq wave, binary
LATCH     EQU   10000000B     ; latch timer 2
;
;  Define 32 bit value used to set timer frequency
;
FRHI      EQU   0012H          ; timer frequency high (1193180 / 256)
FRLO      EQU   34DCH          ; timer low (1193180 mod 256)
;

; *******************************************************************
; DELAY
; this is a variation on Nathan Hull's delay routine.
; *******************************************************************
DELAY           PROC
      PUSH  AX             ; save registers
      PUSH  DX
      SUB   AX,AX          ; zero frequency for rest
      MOV   DX,6           ; delay of 0.06 secs is reasonable
      CALL  NOTE
      POP   DX             ; restore registers
      POP   AX
      RET                  ; return to caller
DELAY      ENDP

DELAY2           PROC
      PUSH  AX             ; save registers
      PUSH  DX
      SUB   AX,AX          ; zero frequency for rest
      MOV   DX,400         ; delay of 4 secs is reasonable
      POP   DX             ; restore registers
      POP   AX
      RET                  ; return to caller
DELAY2      ENDP
      
; *******************************************************************
; NOTE 
; this is a variation on Nathan Hull's note routine. 
; *******************************************************************
NOTE            PROC
              PUSH  AX          ; save registers
              PUSH  BX
              PUSH  CX
              PUSH  DX
              PUSH  SI
              MOV   BX,AX          ; save frequency in BX
              MOV   CX,DX          ; save duration in CX
;
;  We handle the rest (silence) case by using an arbitrary frequency to
;  program the clock so that the normal approach for getting the right
;  delay functions, but we will leave the speaker off in this case.
;
              MOV   SI,BX          ; copy frequency to BX
              OR    BX,BX          ; test zero frequency (rest)
              JNZ   NOT1           ; jump if not
              MOV   BX,256         ; else reset to arbitrary non-zero;

        ;  Initialize timer and set desired frequency
        ;
        NOT1: MOV   AL,TSQW          ; set timer 2 in square wave mode
              OUT   TCTL,AL
              MOV   DX,FRHI          ; set DX:AX = 1193180 decimal
              MOV   AX,FRLO          ;      = clock frequency
              DIV   BX               ; divide by desired frequency
              OUT   TCTR,AL          ; output low order of divisor
              MOV   AL,AH            ; output high order of divisor
              OUT   TCTR,AL
        ;
        ;  Turn the timer on, and also the speaker (unless frequency 0 = rest)
        ;
              IN    AL,CTRL          ; read current contents of control port
              OR    AL,TIMR          ; turn timer on
              OR    SI,SI            ; test zero frequency
              JZ    NOT2             ; skip if so (leave speaker off)
              OR    AL,SPKR          ; else turn speaker on as well
        ;
        ;  Compute number of clock cycles required at this frequency
        ;
        NOT2: OUT   CTRL,AL          ; rewrite control port
              XCHG  AX,BX            ; frequency to AX
              MUL   CX               ; frequency times secs/100 to DX:AX
              MOV   CX,100           ; divide by 100 to get number of beats
              DIV   CX
              SHL   AX,1             ; times 2 because two clocks/beat
              XCHG  AX,CX            ; count of clock cycles to CX
        ;
        ;  Loop through clock cycles
        ;
        NOT3:      CALL  RCTR          ; read initial count
        ;
        ;  Loop to wait for clock count to get reset. The count goes from the
        ;  value we set down to 0, and then is reset back to the set value
        ;
        NOT4: MOV   DX,AX          ; save previous count in DX
              CALL  RCTR           ; read count again
              CMP   AX,DX          ; compare new count : old count
              JB    NOT4           ; loop if new count is lower
              LOOP  NOT3           ; else reset, count down cycles
        ;
        ;  Wait is complete, so turn off clock and return
        ;
              IN    AL,CTRL           ; read current contents of port
              AND   AL,0FFH-TIMR-SPKR ; reset timer/speaker control bits
        ; note that the above statement is an equation
              OUT   CTRL,AL           ; rewrite control port
              POP   SI                ; restore registers
              POP   DX
              POP   CX
              POP   BX
              POP   AX
        RET      
NOTE    ENDP           

; *******************************************************************
; RCTR 
; this is a variation on Nathan Hull's delay routine stuff.
; *******************************************************************
RCTR      PROC
      MOV   AL,LATCH         ; latch the counter
      OUT   TCTL,AL          ; latch counter
      IN    AL,TCTR          ; read lsb of count
      MOV   AH,AL
      IN    AL,TCTR          ; read msb of count
      XCHG  AH,AL            ; count is in AX
      RET                    ; return to caller
RCTR      ENDP


