home *** CD-ROM | disk | FTP | other *** search
/ Bart's Pacman Hits / BPACMAN.iso / BPACMAN / COIN / INVADERS / INVADERS.ASM < prev    next >
Encoding:
Assembly Source File  |  1995-08-14  |  129.2 KB  |  2,844 lines

  1. ;-------------------------------;
  2. ; 6k Space Invaders Version 1.0 ;
  3. ;                               ;
  4. ; Copyright (c) by Paul S. Reid ;
  5. ;      All rights reserved.     ;
  6. ;-------------------------------;
  7.  
  8. CODE_SEG                SEGMENT
  9.                         ASSUME  CS:CODE_SEG,DS:CODE_SEG
  10.                         ORG     100h
  11.  
  12. BEGIN:
  13.  
  14. ;----------------------------------------------------------------------------------------------------------------------------------
  15. ; 6k Space Invaders
  16. ;----------------------------------------------------------------------------------------------------------------------------------
  17.  
  18. Start                   PROC    NEAR
  19.                         Assume  CS:CODE_SEG,DS:CODE_SEG
  20.  
  21.                         MOV     AH,0
  22.                         MOV     AL,13h
  23.                         INT     10h
  24.  
  25.                         CALL    InstallNewInt9          ; Install game keyboard handler
  26. ; Seed random number generator with clock
  27.                         MOV     AX,040h
  28.                         MOV     ES,AX
  29.                         MOV     AX,ES:[06ch]
  30.                         MOV     Seed,AX
  31. ; Set color palette
  32.                         MOV     AX,CS                   ; Segment of palette buffer
  33.                         MOV     ES,AX                   ; in ES
  34.                         MOV     DX,OFFSET Palette       ; Offset of palette buffer in DX
  35.                         MOV     AH,10h                  ; Function 10h (Get/set palette registers)
  36.                         MOV     AL,12h                  ; Subfunction 12h (Set block of color registers)
  37.                         MOV     BX,00h                  ; First color register to set
  38.                         MOV     CX,05bh                 ; Number of color registers to set (255 = all of them)
  39.                         INT     10h                     ; Set registers
  40. ; Draw top and bottom borders
  41.                         MOV     AX,0a000h       ; Get segment of video memory
  42.                         MOV     ES,AX           ; Store it in destination segment register
  43.                         MOV     DI,0            ; Store address in destination register
  44.                         MOV     CX,10240        ; 32 lines
  45. DrawTop:                MOV     BX,0008fh       ; Random number between 0 and 20 in AX
  46.                         MOV     TempStore,CX
  47.                         CALL    Random          ; Call random routine
  48.                         CMP     RandomNumber,1
  49.                         JNZ     NoStar
  50.                         MOV     AL,12
  51.                         JMP     DrawTop2
  52. NoStar:                 MOV     AL,8
  53. DrawTop2:               STOSB
  54.                         MOV     CX,TempStore
  55.                         LOOP    DrawTop
  56.                         MOV     DI,54400        ; Store address in destination register
  57.                         MOV     CX,9600         ; 32 lines
  58. DrawBottom:             MOV     BX,0008fh       ; Random number between 0 and 20 in AX
  59.                         MOV     TempStore,CX
  60.                         CALL    Random          ; Call random routine
  61.                         CMP     RandomNumber,1
  62.                         JNZ     NoStar2
  63.                         MOV     AL,12
  64.                         JMP     DrawBottom2
  65. NoStar2:                MOV     AL,8
  66. DrawBottom2:            STOSB
  67.                         MOV     CX,TempStore
  68.                         LOOP    DrawBottom
  69. ;Draw Invaders logo
  70.                         LEA     AX,LogoOutline      ; Get address of sprite
  71.                         MOV     BX,74               ; Get X position to draw sprite at
  72.                         MOV     DL,0                ; Get Y position to draw sprite at
  73.                         MOV     DH,10               ; Get color to draw sprite
  74.                         CALL    DrawLogoLayer       ; Draw sprite
  75.                         LEA     AX,LogoShadow       ; Get address of sprite
  76.                         MOV     BX,74               ; Get X position to draw sprite at
  77.                         MOV     DL,0                ; Get Y position to draw sprite at
  78.                         MOV     DH,9                ; Get color to draw sprite
  79.                         CALL    DrawLogoLayer       ; Draw sprite
  80.                         LEA     AX,LogoLetters      ; Get address of sprite
  81.                         MOV     BX,74               ; Get X position to draw sprite at
  82.                         MOV     DL,0                ; Get Y position to draw sprite at
  83.                         MOV     DH,11               ; Get color to draw sprite
  84.                         CALL    DrawLogoLayer       ; Draw sprite
  85.  
  86.                         JMP     TitleScreen
  87. ; Clear video buffer
  88. StartGame:              CALL    ResetGame
  89.  
  90.                         MOV     AX,CS           ; Get segment of video memory
  91.                         MOV     ES,AX           ; Store it in destination segment register
  92.                         LEA     DI,VideoBuffer  ; Store address in destination register
  93.                         MOV     CX,21760        ; 136 lines (160 * 136)
  94.                         MOV     AX,0
  95. ClearAll2:              STOSW
  96.                         LOOP    ClearAll2
  97.  
  98. ; Display "SCORE"
  99.                         LEA     AX,SCO              ; Get address of sprite
  100.                         MOV     BX,80               ; Get X position to draw sprite at
  101.                         MOV     DL,0                ; Get Y position to draw sprite at
  102.                         MOV     DH,5                ; Get color to draw sprite
  103.                         CALL    DrawSprite          ; Draw sprite
  104.                         LEA     AX,ORE              ; Get address of sprite
  105.                         MOV     BX,96               ; Get X position to draw sprite at
  106.                         MOV     DL,0                ; Get Y position to draw sprite at
  107.                         MOV     DH,5                ; Get color to draw sprite
  108.                         CALL    DrawSprite          ; Draw sprite
  109.                         LEA     AX,PlayersShip      ; Get address of sprite
  110.                         MOV     BX,220              ; Get X position to draw sprite at
  111.                         MOV     DL,0                ; Get Y position to draw sprite at
  112.                         MOV     DH,5                ; Get color to draw sprite
  113.                         CALL    DrawSprite          ; Draw sprite
  114.                         LEA     AX,Equal            ; Get address of sprite
  115.                         MOV     BX,232              ; Get X position to draw sprite at
  116.                         MOV     DL,0                ; Get Y position to draw sprite at
  117.                         MOV     DH,5                ; Get color to draw sprite
  118.                         CALL    DrawSprite          ; Draw sprite
  119. ; Display lives
  120.                         MOV     AL,Lives
  121.                         MOV     BX,239
  122.                         MOV     DL,0
  123.                         MOV     DH,5
  124.                         CALL    DisplayDigit
  125.                         CALL    DisplayScore
  126.  
  127. ; Outter game loop
  128.  
  129. RedrawBunkers:          CALL    DrawBunkers
  130.                         MOV     FirstFrame,1
  131.  
  132. ; Inner game loop
  133.  
  134. NoExit:                 LEA     AX,PlayersShip      ; Get address of sprite
  135.                         MOV     BX,PlayerX          ; Get X position to draw sprite at
  136.                         MOV     DL,130              ; Get Y position to draw sprite at
  137.                         MOV     DH,1                ; Get color to draw sprite
  138.                         CALL    DrawSprite          ; Draw sprite
  139.                         CALL    CheckPlayerDead
  140.                         CALL    DisplayScore
  141. ; Prepare for buffer blit
  142.                         LEA     SI,VideoBuffer
  143.                         MOV     DI,10560        ; Store address in destination register
  144.                         MOV     AX,0a000h       ; Get segment of video memory
  145.                         MOV     ES,AX           ; Store it in destination segment register
  146.                         MOV     CX,21760        ; 150 lines (136 * 150)
  147. ; Check vertical retrace
  148.                         MOV        DX,03DAh            ; Get vertical retrace port address in DX
  149. ;RetraceStart:           IN        AL,DX               ; Grab retrace information
  150. ;                        TEST    AL,8                ; Did it start yet?
  151. ;                        JNZ        RetraceStart        ; No, wait until it does
  152. RetraceEnd:             IN        AL,DX               ; Grab retrace information again
  153.                         TEST    AL,8                ; Did it end yet?
  154.                         JZ        RetraceEnd          ; No, loop until it does
  155. ; Blit buffer to video memory
  156. BlitAll:                MOVSW
  157.                         LOOP    BlitAll
  158.  
  159.                         CMP     FirstFrame,1
  160.                         JNZ     NoFirstFrame
  161.                         CALL    DrawInvaders
  162.                         LEA     AX,GetReady
  163.                         MOV     BX,82
  164.                         MOV     DL,20
  165.                         MOV     DH,7
  166.                         CALL    PrintText
  167.                         MOV     CX,0
  168.                         MOV     DX,0
  169.                         MOV     AH,1
  170.                         INT     01ah
  171. Wait1:                  MOV     AH,0
  172.                         INT     01ah
  173.                         CMP     DL,18
  174.                         JB      Wait1
  175.                         LEA     AX,GetReady
  176.                         MOV     BX,82
  177.                         MOV     DL,20
  178.                         MOV     DH,0
  179.                         CALL    PrintText
  180.                         MOV     FirstFrame,0
  181.  
  182. NoFirstFrame:           CMP     SoundToggle,1
  183.                         JNZ     NoSoundToggle
  184.                         MOV     SoundToggle,0
  185.                         XOR     Sound,080h
  186.  
  187. NoSoundToggle:          CALL    EraseInvaders
  188.                         DEC     MoveCount
  189.                         JNZ     NoInvaderMove
  190.                         CALL    MoveInvaders
  191.  
  192. NoInvaderMove:          CMP     FireToggle,1
  193.                         JNZ     NoFire
  194.                         CMP     MissileX,0
  195.                         JNZ     NoFire
  196.                         CALL    ShootPlayerMissile
  197.  
  198. NoFire:                 CALL    DrawInvaders
  199.  
  200.                         CMP     MissileX,0
  201.                         JZ      NoMissile
  202.                         CALL    MovePlayerMissile
  203.  
  204.                         CMP     Collision,0
  205.                         JZ      NoMissile
  206.                         CALL    EraseInvaders
  207.                         CALL    EraseScore
  208.                         CALL    CheckInvaderKill
  209.                         CALL    DrawInvaders
  210.                         MOV     Collision,0     ; Reset collision flag
  211.  
  212. NoMissile:              CMP     NextLevelToggle,0
  213.                         JZ      NoNextLevel
  214.                         CALL    NextLevel
  215.                         JMP     RedrawBunkers
  216.  
  217. NoNextLevel:            CMP     PlayerDead,0
  218.                         JZ      NoPlayerDead
  219.                         JMP     KillPlayer
  220.  
  221. NoPlayerDead:           MOV     BX,0ffffh       ; Random number between 0 and 20 in AX
  222.                         CALL    Random          ; Call random routine
  223.                         CMP     RandomNumber[0],1
  224.                         JNZ     NoMakeUFO
  225.                         CMP     UFOX,0
  226.                         JNZ     NoMakeUFO
  227.                         DEC     UFOCounter
  228.                         CMP     UFOCounter,0
  229.                         JNZ     NoMakeUFO
  230.                         MOV     UFOCounter,6
  231.                         MOV     UFOX,50
  232.  
  233. NoMakeUFO:              CMP     UFOX,0
  234.                         JZ      NoUFO
  235.                         CALL    MoveUFO
  236.  
  237. NoUFO:                  MOV     BX,BombFreq     ; Random number between 0 and 20 in AX
  238.                         CALL    Random          ; Call random routine
  239.                         CMP     RandomNumber[0],1
  240.                         JNZ     NoInvaderBomb
  241.                         CALL    InvaderBomb
  242.  
  243. NoInvaderBomb:          DEC     BombMove
  244.                         CMP     BombMove,0
  245.                         JNZ     NoMoveBombs
  246.                         MOV     AL,BombSpeed
  247.                         MOV     BombMove,AL
  248.                         CALL    MoveBombs
  249.  
  250. NoMoveBombs:            LEA     AX,PlayersShip      ; Get address of sprite
  251.                         MOV     BX,PlayerX          ; Get X position to draw sprite at
  252.                         MOV     DL,130              ; Get Y position to draw sprite at
  253.                         CALL    EraseSprite         ; Draw sprite
  254.  
  255.                         CMP     LeftToggle,1
  256.                         JNZ     NoLeft
  257.                         CALL    MovePlayerLeft
  258.  
  259. NoLeft:                 CMP     RightToggle,1
  260.                         JNZ     NoRight
  261.                         CALL    MovePlayerRight
  262.  
  263. NoRight:                CMP     ExitToggle,1
  264.                         JZ      Exit
  265.                         JMP     NoExit
  266.  
  267. ; Clean up and exit
  268.  
  269. Exit:                   CALL    RemoveNewInt9
  270.  
  271.                         MOV     AH,0
  272.                         MOV     AL,3
  273.                         INT     10h
  274.  
  275.                         MOV     AH,4Ch          ; Exit function
  276.                         INT     21h             ; Call DOS for exit
  277.  
  278. Start                   ENDP
  279.  
  280. ;----------------------------------------------------------------------------------------------------------------------------------
  281. ; Reset Game
  282. ;----------------------------------------------------------------------------------------------------------------------------------
  283.  
  284. ResetGame               PROC    NEAR
  285.                         Assume  CS:CODE_SEG,DS:CODE_SEG
  286.  
  287.                         MOV     Frame,0
  288.  
  289.                         MOV     InvadersX,275
  290.                         MOV     InvadersY,30
  291.                         MOV     InvadersToggle[0],07ff0h
  292.                         MOV     InvadersToggle[2],07ff0h
  293.                         MOV     InvadersToggle[4],07ff0h
  294.                         MOV     InvadersToggle[6],07ff0h
  295.                         MOV     InvadersToggle[8],07ff0h
  296.                         MOV     PlayerX,154
  297.                         MOV     LeftToggle,0
  298.                         MOV     RightToggle,0
  299.                         MOV     FireToggle,0
  300.                         MOV     ExitToggle,0
  301.                         MOV     NextLevelToggle,0
  302.                         MOV     MissileX,0
  303.                         MOV     MissileY,0
  304.                         MOV     UFOX,0
  305.                         MOV     AX,CS           ; Get segment of video memory
  306.                         MOV     ES,AX           ; Store it in destination segment register
  307.                         LEA     DI,BombX
  308.                         MOV     CX,22
  309.                         MOV     AX,0
  310. ClearLoop1:             STOSW
  311.                         LOOP    ClearLoop1
  312.                         LEA     DI,BombY
  313.                         MOV     CX,22
  314. ClearLoop2:             STOSB
  315.                         LOOP    ClearLoop2
  316.                         LEA     DI,BombType
  317.                         MOV     CX,22
  318. ClearLoop3:             STOSB
  319.                         LOOP    ClearLoop3
  320.                         MOV     BombFreq,010h
  321.                         MOV     MoveCount,1
  322.                         MOV     InvaderSpeed,55
  323.                         MOV     Direction,0
  324.                         MOV     Reversing,0
  325.                         MOV     Collision,0
  326.                         MOV     Score[0],48
  327.                         MOV     Score[1],48
  328.                         MOV     Score[2],48
  329.                         MOV     Score[3],48
  330.                         MOV     Score[4],48
  331.                         MOV     Lives,51
  332.                         MOV     BombMove,2
  333.                         MOV     BombSpeed,2
  334.                         MOV     PlayerDead,0
  335.                         MOV     GameOverToggle,0
  336.                         MOV     CurrentInvaderSpeed,55
  337.                         MOV     CurrentInvaderY,30
  338.                         MOV     CurrentBombFreq,010h
  339.  
  340.                         RET
  341.  
  342. ResetGame               ENDP
  343.  
  344. ;----------------------------------------------------------------------------------------------------------------------------------
  345. ; Print Text
  346. ;----------------------------------------------------------------------------------------------------------------------------------
  347.  
  348. PrintText               PROC    NEAR
  349.                         Assume  CS:CODE_SEG,DS:CODE_SEG
  350.  
  351.                         MOV     LetterCounter,AX
  352.                         MOV     LetterXPos,BX
  353.                         MOV     LetterYPos,DL
  354.                         MOV     LetterColor,DH
  355.                         SUB     LetterXPos,6
  356.  
  357.                         CMP     KeyPress,1
  358.                         JNZ     PrintNext
  359.  
  360.                         MOV     KeyPress,0
  361.  
  362.                         CMP     ExitToggle,1
  363.                         JNZ     NotExit2
  364.                         JMP     Exit
  365.  
  366. NotExit2:               CMP     SoundToggle,1
  367.                         JNZ     NotSound
  368.                         MOV     SoundToggle,0
  369.                         XOR     Sound,080h
  370.                         JMP     PrintNext
  371.  
  372. NotSound:               CMP     GameStart,1
  373.                         JNZ     PrintNext
  374.                         MOV     GameStart,0
  375.                         JMP     StartGame
  376.  
  377. PrintNext:              MOV     SI,LetterCounter
  378.                         LODSB
  379.                         INC     LetterCounter
  380.                         ADD     LetterXPos,6
  381.                         CMP     AL,0
  382.                         JZ      DonePrinting
  383.                         CMP     AL,32
  384.                         JZ      PrintNext
  385.                         MOV     BX,LetterXPos
  386.                         MOV     DL,LetterYPos
  387.                         MOV     DH,LetterColor
  388.                         CALL    DisplayDigit
  389.                         LEA     SI,VideoBuffer
  390.                         MOV     DI,10560        ; Store address in destination register
  391.                         MOV     AX,0a000h       ; Get segment of video memory
  392.                         MOV     ES,AX           ; Store it in destination segment register
  393.                         MOV     CX,21760        ; 150 lines (136 * 150)
  394.                         MOV        DX,03DAh        ; Get vertical retrace port address in DX
  395. RetraceEnd3:            IN        AL,DX           ; Grab retrace information again
  396.                         TEST    AL,8            ; Did it end yet?
  397.                         JZ        RetraceEnd3     ; No, loop until it does
  398. BlitAll3:               MOVSW
  399.                         LOOP    BlitAll3
  400.                         JMP     PrintNext
  401.  
  402. DonePrinting:           RET
  403.  
  404. LetterCounter           DW      0
  405. LetterXPos              DW      0
  406. LetterYPos              DB      0
  407. LetterColor             DB      0
  408.  
  409. PrintText               ENDP
  410.  
  411. ;----------------------------------------------------------------------------------------------------------------------------------
  412. ; Title Screen - Never Returns!
  413. ;----------------------------------------------------------------------------------------------------------------------------------
  414.  
  415. TitleScreen             PROC    NEAR
  416.                         Assume  CS:CODE_SEG,DS:CODE_SEG
  417.  
  418. ; Clear video buffer
  419.                         MOV     AX,CS           ; Get segment of video memory
  420.                         MOV     ES,AX           ; Store it in destination segment register
  421.                         LEA     DI,VideoBuffer  ; Store address in destination register
  422.                         MOV     CX,21760        ; 136 lines (160 * 136)
  423.                         MOV     AX,0
  424. ClearAll:               STOSW
  425.                         LOOP    ClearAll
  426.  
  427.                         MOV     KeyPress,0
  428.                         MOV     GameStart,1
  429.  
  430.                         LEA     AX,InvadersTitle
  431.                         MOV     BX,40
  432.                         MOV     DL,0
  433.                         MOV     DH,7
  434.                         CALL    PrintText
  435.  
  436.                         LEA     AX,Copyright
  437.                         MOV     BX,61
  438.                         MOV     DL,10
  439.                         MOV     DH,030h
  440.                         CALL    PrintText
  441.  
  442.                         LEA     AX,Rights
  443.                         MOV     BX,101
  444.                         MOV     DL,20
  445.                         MOV     DH,030h
  446.                         CALL    PrintText
  447.  
  448.                         LEA     AX,UFO              ; Get address of sprite
  449.                         MOV     DL,40               ; Get Y position to draw sprite at
  450.                         MOV     DH,3                ; Get color to draw sprite
  451.                         MOV     BX,100              ; Get X position to draw sprite at
  452.                         CALL    DrawLetter          ; Draw sprite
  453.                         LEA     AX,UFOScore
  454.                         MOV     BX,137
  455.                         MOV     DL,40
  456.                         MOV     DH,7
  457.                         CALL    PrintText
  458.  
  459.                         LEA     AX,TopInvader1      ; Get address of sprite
  460.                         MOV     DL,50               ; Get Y position to draw sprite at
  461.                         MOV     DH,010h             ; Get color to draw sprite
  462.                         MOV     BX,103              ; Get X position to draw sprite at
  463.                         CALL    DrawLetter          ; Draw sprite
  464.                         LEA     AX,Row1Score
  465.                         MOV     BX,137
  466.                         MOV     DL,50
  467.                         MOV     DH,7
  468.                         CALL    PrintText
  469.  
  470.                         LEA     AX,MiddleInvader2   ; Get address of sprite
  471.                         MOV     DL,60               ; Get Y position to draw sprite at
  472.                         MOV     DH,020h             ; Get color to draw sprite
  473.                         MOV     BX,103              ; Get X position to draw sprite at
  474.                         CALL    DrawLetter          ; Draw sprite
  475.                         LEA     AX,Row2Score
  476.                         MOV     BX,137
  477.                         MOV     DL,60
  478.                         MOV     DH,7
  479.                         CALL    PrintText
  480.  
  481.                         LEA     AX,MiddleInvader1   ; Get address of sprite
  482.                         MOV     DL,70               ; Get Y position to draw sprite at
  483.                         MOV     DH,030h             ; Get color to draw sprite
  484.                         MOV     BX,103              ; Get X position to draw sprite at
  485.                         CALL    DrawLetter          ; Draw sprite
  486.                         LEA     AX,Row3Score
  487.                         MOV     BX,137
  488.                         MOV     DL,70
  489.                         MOV     DH,7
  490.                         CALL    PrintText
  491.  
  492.                         LEA     AX,BottomInvader1   ; Get address of sprite
  493.                         MOV     DL,80               ; Get Y position to draw sprite at
  494.                         MOV     DH,040h             ; Get color to draw sprite
  495.                         MOV     BX,103              ; Get X position to draw sprite at
  496.                         CALL    DrawLetter          ; Draw sprite
  497.                         LEA     AX,Row4Score
  498.                         MOV     BX,137
  499.                         MOV     DL,80
  500.                         MOV     DH,7
  501.                         CALL    PrintText
  502.  
  503.                         LEA     AX,BottomInvader1   ; Get address of sprite
  504.                         MOV     DL,90               ; Get Y position to draw sprite at
  505.                         MOV     DH,050h             ; Get color to draw sprite
  506.                         MOV     BX,103              ; Get X position to draw sprite at
  507.                         CALL    DrawLetter          ; Draw sprite
  508.                         LEA     AX,Row5Score
  509.                         MOV     BX,137
  510.                         MOV     DL,90
  511.                         MOV     DH,7
  512.                         CALL    PrintText
  513.  
  514.                         LEA     AX,StartDocs
  515.                         MOV     BX,79
  516.                         MOV     DL,109
  517.                         MOV     DH,050h
  518.                         CALL    PrintText
  519.  
  520.                         LEA     AX,ExitDocs
  521.                         MOV     BX,52
  522.                         MOV     DL,119
  523.                         MOV     DH,050h
  524.                         CALL    PrintText
  525.  
  526.                         LEA     AX,Distribution
  527.                         MOV     BX,4
  528.                         MOV     DL,129
  529.                         MOV     DH,7
  530.                         CALL    PrintText
  531.  
  532.                         MOV     GameStart,0
  533.  
  534.                         MOV     AH,1
  535.                         MOV     CX,0
  536.                         MOV     DX,0
  537.                         INT     01ah
  538.  
  539. GetKey:                 CMP     KeyPress,1
  540.                         JZ      KeyWasPressed
  541.  
  542.                         MOV     AH,0
  543.                         INT     01ah
  544.                         CMP     DH,1
  545.                         JNZ     GetKey
  546.                         JMP     TitleScreen2
  547.  
  548. KeyWasPressed:          CMP     ExitToggle,1
  549.                         JNZ     NotExit
  550.                         JMP     Exit
  551.  
  552. NotExit:                CMP     SoundToggle,1
  553.                         JNZ     NotSound2
  554.                         MOV     SoundToggle,0
  555.                         XOR     Sound,080h
  556.                         JMP     GetKey
  557.  
  558. NotSound2:              JMP     StartGame
  559.  
  560. TitleScreen             ENDP
  561.  
  562. ;----------------------------------------------------------------------------------------------------------------------------------
  563. ; Title Screen 2 - Never Returns!
  564. ;----------------------------------------------------------------------------------------------------------------------------------
  565.  
  566. TitleScreen2            PROC    NEAR
  567.                         Assume  CS:CODE_SEG,DS:CODE_SEG
  568.  
  569. ; Clear video buffer
  570.                         MOV     AX,CS           ; Get segment of video memory
  571.                         MOV     ES,AX           ; Store it in destination segment register
  572.                         LEA     DI,VideoBuffer  ; Store address in destination register
  573.                         MOV     CX,21760        ; 136 lines (160 * 136)
  574.                         MOV     AX,0
  575. ClearAllZ:              STOSW
  576.                         LOOP    ClearAllZ
  577.  
  578.                         MOV     KeyPress,0
  579.                         MOV     GameStart,1
  580.  
  581.                         LEA     AX,InvadersTitle
  582.                         MOV     BX,40
  583.                         MOV     DL,0
  584.                         MOV     DH,7
  585.                         CALL    PrintText
  586.  
  587.                         LEA     AX,Copyright
  588.                         MOV     BX,61
  589.                         MOV     DL,10
  590.                         MOV     DH,030h
  591.                         CALL    PrintText
  592.  
  593.                         LEA     AX,Rights
  594.                         MOV     BX,101
  595.                         MOV     DL,20
  596.                         MOV     DH,030h
  597.                         CALL    PrintText
  598.  
  599.                         LEA     AX,Dedication
  600.                         MOV     BX,70
  601.                         MOV     DL,40
  602.                         MOV     DH,010h
  603.                         CALL    PrintText
  604.  
  605.                         LEA     AX,ThankYou
  606.                         MOV     BX,64
  607.                         MOV     DL,60
  608.                         MOV     DH,010h
  609.                         CALL    PrintText
  610.  
  611.                         LEA     AX,SoundTog
  612.                         MOV     BX,55
  613.                         MOV     DL,80
  614.                         MOV     DH,7
  615.                         CALL    PrintText
  616.  
  617.                         LEA     AX,PlayKeys
  618.                         MOV     BX,31
  619.                         MOV     DL,90
  620.                         MOV     DH,7
  621.                         CALL    PrintText
  622.  
  623.                         LEA     AX,StartDocs
  624.                         MOV     BX,79
  625.                         MOV     DL,109
  626.                         MOV     DH,050h
  627.                         CALL    PrintText
  628.  
  629.                         LEA     AX,ExitDocs
  630.                         MOV     BX,52
  631.                         MOV     DL,119
  632.                         MOV     DH,050h
  633.                         CALL    PrintText
  634.  
  635.                         LEA     AX,Distribution
  636.                         MOV     BX,4
  637.                         MOV     DL,129
  638.                         MOV     DH,7
  639.                         CALL    PrintText
  640.  
  641.                         MOV     GameStart,0
  642.  
  643.                         MOV     AH,1
  644.                         MOV     CX,0
  645.                         MOV     DX,0
  646.                         INT     01ah
  647.  
  648. GetKey2:                CMP     KeyPress,1
  649.                         JZ      KeyWasPressed2
  650.  
  651.                         MOV     AH,0
  652.                         INT     01ah
  653.                         CMP     DH,1
  654.                         JNZ     GetKey2
  655.                         JMP     TitleScreen
  656.  
  657. KeyWasPressed2:         CMP     ExitToggle,1
  658.                         JNZ     NotExitZ
  659.                         JMP     Exit
  660.  
  661. NotExitZ:               CMP     SoundToggle,1
  662.                         JNZ     NotSound3
  663.                         MOV     SoundToggle,0
  664.                         XOR     Sound,080h
  665.                         JMP     GetKey2
  666.  
  667. NotSound3:              JMP     StartGame
  668.  
  669. TitleScreen2            ENDP
  670.  
  671. ; Draw Letter with pause
  672.  
  673. DrawLetter              PROC    NEAR
  674.                         Assume  CS:CODE_SEG,DS:CODE_SEG
  675.  
  676.                         CALL    DrawSprite      ; Draw sprite
  677. ; Prepare for buffer blit
  678.                         LEA     SI,VideoBuffer
  679.                         MOV     DI,10560        ; Store address in destination register
  680.                         MOV     AX,0a000h       ; Get segment of video memory
  681.                         MOV     ES,AX           ; Store it in destination segment register
  682.                         MOV     CX,21760        ; 150 lines (136 * 150)
  683. ; Check vertical retrace
  684.                         MOV        DX,03DAh        ; Get vertical retrace port address in DX
  685. RetraceEnd2:            IN        AL,DX           ; Grab retrace information again
  686.                         TEST    AL,8            ; Did it end yet?
  687.                         JZ        RetraceEnd2     ; No, loop until it does
  688. ; Blit buffer to video memory
  689. BlitAll2:               MOVSW
  690.                         LOOP    BlitAll2
  691.  
  692. NoKey:                  MOV     CX,0
  693.                         MOV     DX,0
  694.                         MOV     AH,1
  695.                         INT     01ah
  696. Wait2:                  MOV     AH,0
  697.                         INT     01ah
  698.                         CMP     DL,3
  699.                         JB      Wait2
  700.  
  701.                         RET
  702.  
  703. DrawLetter              ENDP
  704.  
  705. ;----------------------------------------------------------------------------------------------------------------------------------
  706. ; Game Over - Never Returns!
  707. ;----------------------------------------------------------------------------------------------------------------------------------
  708.  
  709. GameOver                PROC    NEAR
  710.                         Assume  CS:CODE_SEG,DS:CODE_SEG
  711.  
  712.                         MOV     GameOverToggle,1
  713.  
  714.                         LEA     AX,GameOverMsg
  715.                         MOV     BX,82
  716.                         MOV     DL,20
  717.                         MOV     DH,7
  718.                         CALL    PrintText
  719.  
  720.                         MOV     GameOverToggle,0
  721.                         MOV     CX,0
  722.                         MOV     DX,0
  723.                         MOV     AH,1
  724.                         INT     01ah
  725. Wait3:                  MOV     AH,0
  726.                         INT     01ah
  727.                         CMP     DL,180
  728.                         JB      Wait3
  729.  
  730.                         JMP     TitleScreen
  731.  
  732. GameOver                ENDP
  733.  
  734. ;----------------------------------------------------------------------------------------------------------------------------------
  735. ; Kill Player - Never returns!
  736. ;----------------------------------------------------------------------------------------------------------------------------------
  737.  
  738. KillPlayer              PROC    NEAR
  739.                         Assume  CS:CODE_SEG,DS:CODE_SEG
  740.  
  741.                         MOV     AL,Lives
  742.                         MOV     BX,239
  743.                         MOV     DL,0
  744.                         MOV     DH,0
  745.                         CALL    DisplayDigit
  746.                         DEC     Lives
  747.                         MOV     AL,Lives
  748.                         MOV     BX,239
  749.                         MOV     DL,0
  750.                         MOV     DH,5
  751.                         CALL    DisplayDigit
  752.  
  753.                         CMP     Lives,48
  754.                         JNZ     LifeLeft
  755. ; No life left - Wait for key before exiting game
  756.                         JMP     GameOver
  757. ; Life left - Pause before continuing
  758. LifeLeft:               MOV     CX,0
  759.                         MOV     DX,0
  760.                         MOV     AH,1
  761.                         INT     01ah
  762. Wait4:                  MOV     AH,0
  763.                         INT     01ah
  764.                         CMP     DL,18
  765.                         JB      Wait4
  766.                         CALL    EraseInvaders
  767.                         CALL    ResetLevel
  768.  
  769.                         MOV     BX,0
  770. Search3:                CMP     [BombY+BX],0
  771.                         JNZ     KillBomb2
  772.                         JMP     NoFoundSlot1
  773.  
  774. KillBomb2:              MOV     KillBombs,BX
  775.                         MOV     DL,[BombY+BX]       ; Get Y position to draw sprite at
  776.                         CMP     [BombType+BX],0
  777.                         JZ      AnimatedBomb4
  778.                         LEA     AX,StraightMissile  ; Get address of sprite
  779.                         JMP     AllDone4
  780. AnimatedBomb4:          CMP     Frame,1
  781.                         JNZ     IsFrame004
  782.                         LEA     AX,TwistedMissile1  ; Get address of sprite
  783.                         JMP     AllDone4
  784. IsFrame004:             LEA     AX,TwistedMissile2  ; Get address of sprite
  785. AllDone4:               SHL     BX,1
  786.                         MOV     BX,[BombX+BX]       ; Get X position to draw sprite at
  787.                         CALL    EraseSprite         ; Draw sprite
  788.                         MOV     BX,KillBombs
  789.                         MOV     [BombY+BX],0        ; Get X position to draw sprite at
  790.  
  791. NoFoundSlot1:           INC     BX
  792.                         CMP     BX,22
  793.                         JZ      AllBombsDead
  794.                         JMP     Search3
  795.  
  796. AllBombsDead:           JMP     RedrawBunkers
  797.  
  798. KillBombs               DW      0
  799.  
  800. KillPlayer              ENDP
  801.  
  802. ;----------------------------------------------------------------------------------------------------------------------------------
  803. ; Drop Invader Bomb
  804. ;----------------------------------------------------------------------------------------------------------------------------------
  805.  
  806. InvaderBomb             PROC    NEAR
  807.                         Assume  CS:CODE_SEG,DS:CODE_SEG
  808.  
  809.                         MOV     BX,0002h
  810.                         CALL    Random
  811. ;------------------------------------------------------------------
  812. ;                        CMP     RandomNumber[0],0
  813. ;                        JNZ     NoGood
  814. ;                        MOV     DL,83
  815. ;                        MOV     AH,2
  816. ;                        INT     21h
  817. ;                        JMP     Good
  818. ;NoGood:                 MOV     DL,32
  819. ;                        MOV     AH,2
  820. ;                        INT     21h
  821. ;Good:                   MOV     DL,00dh
  822. ;                        MOV     AH,2
  823. ;                        INT     21h
  824. ;------------------------------------------------------------------
  825.                         MOV     DH,RandomNumber[0]
  826.                         MOV     TempRand,DH
  827.                         MOV     BX,0000bh       ; Random number between 0 and 11 in AX
  828.                         CALL    Random          ; Call random routine
  829.                         MOV     AX,08000h
  830.                         MOV     CH,0
  831.                         MOV     CL,RandomNumber[0]
  832.                         INC     CX
  833. LoopingZ:               SHR     AX,1
  834.                         LOOP    LoopingZ
  835.                         MOV     DL,0
  836.                         TEST    InvadersToggle[8],AX
  837.                         JZ      NoRow5Invader
  838.                         MOV     DL,44
  839.                         JMP     FoundY
  840. NoRow5Invader:          TEST    InvadersToggle[6],AX
  841.                         JZ      NoRow4Invader
  842.                         MOV     DL,34
  843.                         JMP     FoundY
  844. NoRow4Invader:          TEST    InvadersToggle[4],AX
  845.                         JZ      NoRow3Invader
  846.                         MOV     DL,24
  847.                         JMP     FoundY
  848. NoRow3Invader:          TEST    InvadersToggle[2],AX
  849.                         JZ      NoRow2Invader
  850.                         MOV     DL,14
  851.                         JMP     FoundY
  852. NoRow2Invader:          TEST    InvadersToggle[0],AX
  853.                         JZ      NoInvaders
  854.                         MOV     DL,4
  855.  
  856. FoundY:                 MOV     AL,RandomNumber[0]
  857.                         MOV     AH,0
  858.                         MOV     CL,16
  859.                         MUL     CL
  860.  
  861.                         ADD     AX,InvadersX
  862.                         SUB     AX,200
  863.                         ADD     DL,InvadersY
  864.  
  865. ; AX Holds X, DL holds Y of bomb start position
  866.  
  867.                         MOV     BX,0
  868. Search:                 CMP     [BombY+BX],0
  869.                         JZ      FoundSlot
  870.                         INC     BX
  871.                         CMP     BX,22
  872.                         JNZ     Search
  873.                         JMP     NoInvaders
  874.  
  875. ; BX Holds offset (bomb number)
  876.  
  877. FoundSlot:              MOV     [BombY+BX],DL
  878.                         MOV     DH,TempRand
  879.                         MOV     [BombType+BX],DH
  880.                         SHL     BX,1
  881.                         MOV     [BombX+BX],AX
  882.  
  883. NoInvaders:             RET
  884.  
  885. TempRand                DB      0
  886.  
  887. InvaderBomb             ENDP
  888.  
  889. ;----------------------------------------------------------------------------------------------------------------------------------
  890. ; Move Invader Bombs
  891. ;----------------------------------------------------------------------------------------------------------------------------------
  892.  
  893. MoveBombs               PROC    NEAR
  894.                         Assume  CS:CODE_SEG,DS:CODE_SEG
  895.  
  896.                         MOV     BX,0
  897. Search2:                CMP     [BombY+BX],0
  898.                         JNZ     GotSlot
  899.                         JMP     NoFoundSlot
  900.  
  901. GotSlot:                MOV     TempCounter,BX
  902.                         MOV     DL,[BombY+BX]       ; Get Y position to draw sprite at
  903.                         CMP     [BombType+BX],0
  904.                         JZ      AnimatedBomb1
  905.                         LEA     AX,StraightMissile  ; Get address of sprite
  906.                         JMP     AllDone1
  907. AnimatedBomb1:          CMP     Frame,1
  908.                         JNZ     IsFrame001
  909.                         LEA     AX,TwistedMissile1  ; Get address of sprite
  910.                         JMP     AllDone1
  911. IsFrame001:             LEA     AX,TwistedMissile2  ; Get address of sprite
  912. AllDone1:               SHL     BX,1
  913.                         MOV     BX,[BombX+BX]       ; Get X position to draw sprite at
  914.                         CALL    EraseSprite         ; Draw sprite
  915.                         MOV     BX,TempCounter
  916.                         INC     [BombY+BX]
  917.                         INC     [BombY+BX]
  918.                         CMP     [BombY+BX],130
  919.                         JNZ     DrawNextFrameA
  920.                         MOV     [BombY+BX],0
  921.                         JMP     NoFoundSlot
  922. DrawNextFrameA:         MOV     DL,[BombY+BX]       ; Get Y position to draw sprite at
  923.                         CMP     [BombType+BX],0
  924.                         JZ      AnimatedBomb2
  925.                         LEA     AX,StraightMissile  ; Get address of sprite
  926.                         JMP     AllDone2
  927. AnimatedBomb2:          CMP     Frame,1
  928.                         JNZ     IsFrame002
  929.                         LEA     AX,TwistedMissile1  ; Get address of sprite
  930.                         JMP     AllDone2
  931. IsFrame002:             LEA     AX,TwistedMissile2  ; Get address of sprite
  932. AllDone2:               SHL     BX,1
  933.                         MOV     BX,[BombX+BX]       ; Get X position to draw sprite at
  934.                         MOV     DH,06h              ; Get color to draw sprite
  935.                         MOV     Collision,0
  936.                         CALL    DrawSprite          ; Draw sprite
  937.                         CMP     Collision,1
  938.                         JNZ     NoDeadPlayer
  939.                         JMP     KillPlayer
  940. NoDeadPlayer:           CMP     Collision,2
  941.                         JZ      KillBomb
  942.                         CMP     Collision,4
  943.                         JNZ     NoAction
  944. KillBomb:               MOV     BX,TempCounter
  945.                         MOV     DL,[BombY+BX]       ; Get Y position to draw sprite at
  946.                         CMP     [BombType+BX],0
  947.                         JZ      AnimatedBomb3
  948.                         LEA     AX,StraightMissile  ; Get address of sprite
  949.                         JMP     AllDone3
  950. AnimatedBomb3:          CMP     Frame,1
  951.                         JNZ     IsFrame003
  952.                         LEA     AX,TwistedMissile1  ; Get address of sprite
  953.                         JMP     AllDone3
  954. IsFrame003:             LEA     AX,TwistedMissile2  ; Get address of sprite
  955. AllDone3:               SHL     BX,1
  956.                         MOV     BX,[BombX+BX]       ; Get X position to draw sprite at
  957.                         CALL    EraseSprite         ; Draw sprite
  958.                         MOV     BX,TempCounter
  959.                         MOV     [BombY+BX],0        ; Get X position to draw sprite at
  960.                         CMP     Collision,4
  961.                         JNZ     NoAction
  962.                         CALL    KillMissile
  963. NoAction:               MOV     Collision,0
  964.                         MOV     BX,TempCounter
  965.  
  966. NoFoundSlot:            INC     BX
  967.                         CMP     BX,22
  968.                         JZ      DoneMoveBombs
  969.                         JMP     Search2
  970.  
  971. DoneMoveBombs:          RET
  972.  
  973. TempCounter             DW      0
  974.  
  975. MoveBombs               ENDP
  976.  
  977. ;----------------------------------------------------------------------------------------------------------------------------------
  978. ; Move UFO
  979. ;----------------------------------------------------------------------------------------------------------------------------------
  980.  
  981. MoveUFO                 PROC    NEAR
  982.                         Assume  CS:CODE_SEG,DS:CODE_SEG
  983.  
  984.                         DEC     UFOMove
  985.                         CMP     UFOMove,0
  986.                         JNZ     DoneUFO
  987.                         MOV     UFOMove,2
  988.  
  989.                         LEA     AX,UFO              ; Get address of sprite
  990.                         MOV     BX,UFOX             ; Get X position to draw sprite at
  991.                         MOV     DL,10               ; Get Y position to draw sprite at
  992.                         CALL    EraseSprite         ; Draw sprite
  993.  
  994.                         INC     UFOX
  995.                         CMP     UFOX,254
  996.                         JNZ     DoNextUFOFrame
  997.                         MOV     UFOX,0
  998.                         JMP     DoneUFO
  999.  
  1000. DoNextUFOFrame:         LEA     AX,UFO              ; Get address of sprite
  1001.                         MOV     BX,UFOX             ; Get X position to draw sprite at
  1002.                         MOV     DL,10               ; Get Y position to draw sprite at
  1003.                         MOV     DH,3                ; Get color to draw sprite
  1004.                         CALL    DrawSprite          ; Draw sprite
  1005.  
  1006. ; Make sound
  1007.  
  1008.                         TEST    Sound,080h
  1009.                         JZ      NoSound1
  1010.  
  1011.                         MOV     AL,0b6h
  1012.                         OUT     043h,AL
  1013.                         MOV     AL,090h
  1014.                         OUT     042h,AL
  1015.                         MOV     AL,000h
  1016.                         OUT     042h,AL
  1017.                         IN      AL,061h
  1018.                         OR      AL,3
  1019.                         OUT     061h,AL
  1020.  
  1021. NoSound1:               MOV     CX,08000h
  1022. TimerZ:                 LOOP    TimerZ
  1023.  
  1024.                         IN      AL,061h
  1025.                         AND     AL,0fch
  1026.                         OUT     061h,AL
  1027.  
  1028. DoneUFO:                RET
  1029.  
  1030. UFOMove                 DB      2
  1031. UFOCounter              DB      6
  1032.  
  1033. MoveUFO                 ENDP
  1034.  
  1035. ;----------------------------------------------------------------------------------------------------------------------------------
  1036. ; Generate Random Number
  1037. ;----------------------------------------------------------------------------------------------------------------------------------
  1038.  
  1039. Random                  PROC    NEAR
  1040.                         Assume  CS:CODE_SEG,DS:CODE_SEG
  1041.  
  1042.                         MOV     AX,Seed
  1043.                         MUL     BX
  1044.                         MOV     CX,65531
  1045.                         DIV     CX
  1046.                         MOV     Seed,DX
  1047.                         MOV     RandomNumber[0],AL
  1048.  
  1049.                         RET
  1050.  
  1051. Seed                    DW      0
  1052. RandomNumber            DB      0
  1053.  
  1054. Random                  ENDP
  1055.  
  1056. ;----------------------------------------------------------------------------------------------------------------------------------
  1057. ; Next Level
  1058. ;----------------------------------------------------------------------------------------------------------------------------------
  1059.  
  1060. NextLevel               PROC    NEAR
  1061.                         Assume  CS:CODE_SEG,DS:CODE_SEG
  1062.  
  1063.                         DEC     CurrentInvaderSpeed
  1064.                         ADD     CurrentInvaderY,2
  1065.                         CMP     CurrentBombFreq,0
  1066.                         JZ      NoDecrease
  1067.                         DEC     CurrentBombFreq
  1068.  
  1069. NoDecrease:             CALL    ResetLevel
  1070.  
  1071.                         RET
  1072.  
  1073. NextLevel               ENDP
  1074.  
  1075. ; Reset Level
  1076.  
  1077. ResetLevel              PROC    NEAR
  1078.                         Assume  CS:CODE_SEG,DS:CODE_SEG
  1079.  
  1080.                         MOV     PlayerDead,0
  1081.                         MOV     NextLevelToggle,0
  1082.                         MOV     Frame,0
  1083.                         MOV     InvadersX,275
  1084.                         MOV     AL,CurrentInvaderY
  1085.                         MOV     InvadersY,AL
  1086.                         MOV     InvadersToggle[0],07ff0h
  1087.                         MOV     InvadersToggle[2],07ff0h
  1088.                         MOV     InvadersToggle[4],07ff0h
  1089.                         MOV     InvadersToggle[6],07ff0h
  1090.                         MOV     InvadersToggle[8],07ff0h
  1091.                         MOV     MoveCount,1
  1092.                         MOV     AL,CurrentInvaderSpeed
  1093.                         MOV     InvaderSpeed,AL
  1094.                         MOV     Direction,0
  1095.                         MOV     Reversing,0
  1096.                         MOV     Collision,0
  1097.                         MOV     AX,CurrentBombFreq
  1098.                         MOV     BombFreq,AX
  1099.  
  1100.                         RET
  1101.  
  1102. CurrentInvaderSpeed     DB      55
  1103. CurrentInvaderY         DB      30
  1104. CurrentBombFreq         DW      010h
  1105.  
  1106. ResetLevel              ENDP
  1107.  
  1108. ;----------------------------------------------------------------------------------------------------------------------------------
  1109. ; Increase Score
  1110. ;----------------------------------------------------------------------------------------------------------------------------------
  1111.  
  1112. IncreaseScore           PROC    NEAR
  1113.                         Assume  CS:CODE_SEG,DS:CODE_SEG
  1114.  
  1115. RackScore:              CALL    ScorePlusOne
  1116.                         LOOP    RackScore
  1117.  
  1118.                         RET
  1119.  
  1120. IncreaseScore           ENDP
  1121.  
  1122. ; Bump score up by 1
  1123.  
  1124. ScorePlusOne            PROC    NEAR
  1125.                         Assume  CS:CODE_SEG,DS:CODE_SEG
  1126.  
  1127.                         INC     Score[4]
  1128.                         CMP     Score[4],58
  1129.                         JNZ     Done
  1130.                         MOV     Score[4],48
  1131.                         INC     Score[3]
  1132.                         CMP     Score[3],58
  1133.                         JNZ     Done
  1134.                         MOV     Score[3],48
  1135.                         INC     Score[2]
  1136.                         CMP     Score[2],58
  1137.                         JNZ     Done
  1138.                         MOV     Score[2],48
  1139.                         INC     Score[1]
  1140.                         CMP     Score[1],58
  1141.                         JNZ     Done
  1142.                         MOV     Score[1],48
  1143.                         INC     Score[0]
  1144.                         MOV     TempCX,CX
  1145.                         MOV     AL,Lives
  1146.                         MOV     BX,239
  1147.                         MOV     DL,0
  1148.                         MOV     DH,0
  1149.                         CALL    DisplayDigit
  1150.                         INC     Lives
  1151.                         MOV     AL,Lives
  1152.                         MOV     BX,239
  1153.                         MOV     DL,0
  1154.                         MOV     DH,5
  1155.                         CALL    DisplayDigit
  1156.                         MOV     CX,TempCX
  1157.                         CMP     Score[0],58
  1158.                         JNZ     Done
  1159.  
  1160. Done:                   RET
  1161.  
  1162. TempCX                  DW      0
  1163.  
  1164. ScorePlusOne            ENDP
  1165.  
  1166. ;----------------------------------------------------------------------------------------------------------------------------------
  1167. ; Display Score
  1168. ;----------------------------------------------------------------------------------------------------------------------------------
  1169.  
  1170. DisplayScore            PROC    NEAR
  1171.                         Assume  CS:CODE_SEG,DS:CODE_SEG
  1172.  
  1173.                         MOV     AL,Score[0]
  1174.                         MOV     BX,119
  1175.                         MOV     DL,0
  1176.                         MOV     DH,5
  1177.                         CALL    DisplayDigit
  1178.  
  1179.                         MOV     AL,Score[1]
  1180.                         MOV     BX,126
  1181.                         MOV     DL,0
  1182.                         MOV     DH,5
  1183.                         CALL    DisplayDigit
  1184.  
  1185.                         MOV     AL,Score[2]
  1186.                         MOV     BX,133
  1187.                         MOV     DL,0
  1188.                         MOV     DH,5
  1189.                         CALL    DisplayDigit
  1190.  
  1191.                         MOV     AL,Score[3]
  1192.                         MOV     BX,140
  1193.                         MOV     DL,0
  1194.                         MOV     DH,5
  1195.                         CALL    DisplayDigit
  1196.  
  1197.                         MOV     AL,Score[4]
  1198.                         MOV     BX,147
  1199.                         MOV     DL,0
  1200.                         MOV     DH,5
  1201.                         CALL    DisplayDigit
  1202.  
  1203.                         RET
  1204.  
  1205. DisplayScore            ENDP
  1206.  
  1207. ;----------------------------------------------------------------------------------------------------------------------------------
  1208. ; Erase Score
  1209. ;----------------------------------------------------------------------------------------------------------------------------------
  1210.  
  1211. EraseScore              PROC    NEAR
  1212.                         Assume  CS:CODE_SEG,DS:CODE_SEG
  1213.  
  1214.                         MOV     AL,Score[0]
  1215.                         MOV     BX,119
  1216.                         MOV     DL,0
  1217.                         MOV     DH,0
  1218.                         CALL    DisplayDigit
  1219.  
  1220.                         MOV     AL,Score[1]
  1221.                         MOV     BX,126
  1222.                         MOV     DL,0
  1223.                         MOV     DH,0
  1224.                         CALL    DisplayDigit
  1225.  
  1226.                         MOV     AL,Score[2]
  1227.                         MOV     BX,133
  1228.                         MOV     DL,0
  1229.                         MOV     DH,0
  1230.                         CALL    DisplayDigit
  1231.  
  1232.                         MOV     AL,Score[3]
  1233.                         MOV     BX,140
  1234.                         MOV     DL,0
  1235.                         MOV     DH,0
  1236.                         CALL    DisplayDigit
  1237.  
  1238.                         MOV     AL,Score[4]
  1239.                         MOV     BX,147
  1240.                         MOV     DL,0
  1241.                         MOV     DH,0
  1242.                         CALL    DisplayDigit
  1243.  
  1244.                         RET
  1245.  
  1246. EraseScore              ENDP
  1247.  
  1248. ;----------------------------------------------------------------------------------------------------------------------------------
  1249. ; Display / Erase Digit In Decimal
  1250. ;----------------------------------------------------------------------------------------------------------------------------------
  1251.  
  1252. DisplayDigit            PROC    NEAR
  1253.                         Assume  CS:CODE_SEG,DS:CODE_SEG
  1254.  
  1255.                         CALL    FindDigit
  1256.                         CALL    DrawSprite          ; Draw sprite
  1257.  
  1258.                         RET
  1259.  
  1260. DisplayDigit            ENDP
  1261.  
  1262. FindDigit               PROC    NEAR
  1263.                         Assume  CS:CODE_SEG,DS:CODE_SEG
  1264.  
  1265. ; Find Digit
  1266.                         CMP     AL,48
  1267.                         JNZ     NotZero
  1268.                         LEA     AX,Zero
  1269.                         JMP     GotDigit
  1270. NotZero:                CMP     AL,49
  1271.                         JNZ     NotOne
  1272.                         LEA     AX,One
  1273.                         JMP     GotDigit
  1274. NotOne:                 CMP     AL,50
  1275.                         JNZ     NotTwo
  1276.                         LEA     AX,Two
  1277.                         JMP     GotDigit
  1278. NotTwo:                 CMP     AL,51
  1279.                         JNZ     NotThree
  1280.                         LEA     AX,Three
  1281.                         JMP     GotDigit
  1282. NotThree:               CMP     AL,52
  1283.                         JNZ     NotFour
  1284.                         LEA     AX,Four
  1285.                         JMP     GotDigit
  1286. NotFour:                CMP     AL,53
  1287.                         JNZ     NotFive
  1288.                         LEA     AX,Five
  1289.                         JMP     GotDigit
  1290. NotFive:                CMP     AL,54
  1291.                         JNZ     NotSix
  1292.                         LEA     AX,Six
  1293.                         JMP     GotDigit
  1294. NotSix:                 CMP     AL,55
  1295.                         JNZ     NotSeven
  1296.                         LEA     AX,Seven
  1297.                         JMP     GotDigit
  1298. NotSeven:               CMP     AL,56
  1299.                         JNZ     NotEight
  1300.                         LEA     AX,Eight
  1301.                         JMP     GotDigit
  1302. NotEight:               CMP     AL,57
  1303.                         JNZ     NotNine
  1304.                         LEA     AX,Nine
  1305.                         JMP     GotDigit
  1306.  
  1307. NotNine:                CMP     AL,65
  1308.                         JNZ     NotA
  1309.                         LEA     AX,LetterA
  1310.                         JMP     GotDigit
  1311. NotA:                   CMP     AL,66
  1312.                         JNZ     NotB
  1313.                         LEA     AX,LetterB
  1314.                         JMP     GotDigit
  1315. NotB:                   CMP     AL,67
  1316.                         JNZ     NotC
  1317.                         LEA     AX,LetterC
  1318.                         JMP     GotDigit
  1319. NotC:                   CMP     AL,68
  1320.                         JNZ     NotD
  1321.                         LEA     AX,LetterD
  1322.                         JMP     GotDigit
  1323. NotD:                   CMP     AL,69
  1324.                         JNZ     NotE
  1325.                         LEA     AX,LetterE
  1326.                         JMP     GotDigit
  1327. NotE:                   CMP     AL,70
  1328.                         JNZ     NotF
  1329.                         LEA     AX,LetterF
  1330.                         JMP     GotDigit
  1331. NotF:                   CMP     AL,71
  1332.                         JNZ     NotG
  1333.                         LEA     AX,LetterG
  1334.                         JMP     GotDigit
  1335. NotG:                   CMP     AL,72
  1336.                         JNZ     NotH
  1337.                         LEA     AX,LetterH
  1338.                         JMP     GotDigit
  1339. NotH:                   CMP     AL,73
  1340.                         JNZ     NotI
  1341.                         LEA     AX,LetterI
  1342.                         JMP     GotDigit
  1343. NotI:                   CMP     AL,74
  1344.                         JNZ     NotJ
  1345.                         LEA     AX,LetterJ
  1346.                         JMP     GotDigit
  1347. NotJ:                   CMP     AL,75
  1348.                         JNZ     NotK
  1349.                         LEA     AX,LetterK
  1350.                         JMP     GotDigit
  1351. NotK:                   CMP     AL,76
  1352.                         JNZ     NotL
  1353.                         LEA     AX,LetterL
  1354.                         JMP     GotDigit
  1355. NotL:                   CMP     AL,77
  1356.                         JNZ     NotM
  1357.                         LEA     AX,LetterM
  1358.                         JMP     GotDigit
  1359. NotM:                   CMP     AL,78
  1360.                         JNZ     NotN
  1361.                         LEA     AX,LetterN
  1362.                         JMP     GotDigit
  1363. NotN:                   CMP     AL,79
  1364.                         JNZ     NotO
  1365.                         LEA     AX,LetterO
  1366.                         JMP     GotDigit
  1367. NotO:                   CMP     AL,80
  1368.                         JNZ     NotP
  1369.                         LEA     AX,LetterP
  1370.                         JMP     GotDigit
  1371. NotP:                   CMP     AL,81
  1372.                         JNZ     NotQ
  1373.                         LEA     AX,LetterQ
  1374.                         JMP     GotDigit
  1375. NotQ:                   CMP     AL,82
  1376.                         JNZ     NotR
  1377.                         LEA     AX,LetterR
  1378.                         JMP     GotDigit
  1379. NotR:                   CMP     AL,83
  1380.                         JNZ     NotS
  1381.                         LEA     AX,LetterS
  1382.                         JMP     GotDigit
  1383. NotS:                   CMP     AL,84
  1384.                         JNZ     NotT
  1385.                         LEA     AX,LetterT
  1386.                         JMP     GotDigit
  1387. NotT:                   CMP     AL,85
  1388.                         JNZ     NotU
  1389.                         LEA     AX,LetterU
  1390.                         JMP     GotDigit
  1391. NotU:                   CMP     AL,86
  1392.                         JNZ     NotV
  1393.                         LEA     AX,LetterV
  1394.                         JMP     GotDigit
  1395. NotV:                   CMP     AL,87
  1396.                         JNZ     NotW
  1397.                         LEA     AX,LetterW
  1398.                         JMP     GotDigit
  1399. NotW:                   CMP     AL,88
  1400.                         JNZ     NotX
  1401.                         LEA     AX,LetterX
  1402.                         JMP     GotDigit
  1403. NotX:                   CMP     AL,89
  1404.                         JNZ     NotY
  1405.                         LEA     AX,LetterY
  1406.                         JMP     GotDigit
  1407. NotY:                   CMP     AL,90
  1408.                         JNZ     NotZ
  1409.                         LEA     AX,LetterZ
  1410.                         JMP     GotDigit
  1411. NotZ:                   CMP     AL,61
  1412.                         JNZ     NotEqual
  1413.                         LEA     AX,Equal
  1414.                         JMP     GotDigit
  1415. NotEqual:               CMP     AL,40
  1416.                         JNZ     NotCopyright
  1417.                         LEA     AX,CopyrightSymbol
  1418.                         JMP     GotDigit
  1419. NotCopyright:           LEA     AX,Period
  1420.  
  1421. GotDigit:               RET
  1422.  
  1423. FindDigit               ENDP
  1424.  
  1425. ;----------------------------------------------------------------------------------------------------------------------------------
  1426. ; Check If Player Is Dead
  1427. ;----------------------------------------------------------------------------------------------------------------------------------
  1428.  
  1429. CheckPlayerDead         PROC    NEAR
  1430.                         Assume  CS:CODE_SEG,DS:CODE_SEG
  1431.  
  1432.                         CMP     InvadersToggle[8],0
  1433.                         JZ      NoRow5Left
  1434.                         CMP     InvadersY,84
  1435.                         JNZ     NotDead
  1436.                         MOV     PlayerDead,1
  1437.                         JMP     NotDead
  1438.  
  1439. NoRow5Left:             CMP     InvadersToggle[6],0
  1440.                         JZ      NoRow4Left
  1441.                         CMP     InvadersY,94
  1442.                         JNZ     NotDead
  1443.                         MOV     PlayerDead,1
  1444.                         JMP     NotDead
  1445.  
  1446. NoRow4Left:             CMP     InvadersToggle[4],0
  1447.                         JZ      NoRow3Left
  1448.                         CMP     InvadersY,104
  1449.                         JNZ     NotDead
  1450.                         MOV     PlayerDead,1
  1451.                         JMP     NotDead
  1452.  
  1453. NoRow3Left:             CMP     InvadersToggle[2],0
  1454.                         JZ      NoRow2Left
  1455.                         CMP     InvadersY,114
  1456.                         JNZ     NotDead
  1457.                         MOV     PlayerDead,1
  1458.                         JMP     NotDead
  1459.  
  1460. NoRow2Left:             CMP     InvadersY,124
  1461.                         JNZ     NotDead
  1462.                         MOV     PlayerDead,1
  1463.  
  1464. NotDead:                RET
  1465.  
  1466. CheckPlayerDead         ENDP
  1467.  
  1468. ;----------------------------------------------------------------------------------------------------------------------------------
  1469. ; Check Invader Killed
  1470. ;----------------------------------------------------------------------------------------------------------------------------------
  1471.  
  1472. CheckInvaderKill        PROC    NEAR
  1473.                         Assume  CS:CODE_SEG,DS:CODE_SEG
  1474.  
  1475.                         MOV     AL,Collision
  1476.                         AND     AL,0f0h
  1477.                         CMP     AL,050h
  1478.                         JNZ     NoRow5Kill
  1479.                         CALL    SpeedUpInvaders
  1480.                         MOV     CH,0
  1481.                         MOV     CL,Collision
  1482.                         AND     CL,00fh
  1483.                         INC     CL
  1484.                         MOV     AX,08000h
  1485. Shifting1:              SHR     AX,1
  1486.                         LOOP    Shifting1
  1487.                         XOR     InvadersToggle[8],AX
  1488.                         MOV     CX,5
  1489.                         CALL    IncreaseScore
  1490.  
  1491.                         JMP     NoRow1Kill
  1492.  
  1493. NoRow5Kill:             MOV     AL,Collision
  1494.                         AND     AL,0f0h
  1495.                         CMP     AL,040h
  1496.                         JNZ     NoRow4Kill
  1497.                         CALL    SpeedUpInvaders
  1498.                         MOV     CH,0
  1499.                         MOV     CL,Collision
  1500.                         AND     CL,00fh
  1501.                         INC     CL
  1502.                         MOV     AX,08000h
  1503. Shifting2:              SHR     AX,1
  1504.                         LOOP    Shifting2
  1505.                         XOR     InvadersToggle[6],AX
  1506.                         MOV     CX,10
  1507.                         CALL    IncreaseScore
  1508.                         JMP     NoRow1Kill
  1509.  
  1510. NoRow4Kill:             MOV     AL,Collision
  1511.                         AND     AL,0f0h
  1512.                         CMP     AL,030h
  1513.                         JNZ     NoRow3Kill
  1514.                         CALL    SpeedUpInvaders
  1515.                         MOV     CH,0
  1516.                         MOV     CL,Collision
  1517.                         AND     CL,00fh
  1518.                         INC     CL
  1519.                         MOV     AX,08000h
  1520. Shifting3:              SHR     AX,1
  1521.                         LOOP    Shifting3
  1522.                         XOR     InvadersToggle[4],AX
  1523.                         MOV     CX,15
  1524.                         CALL    IncreaseScore
  1525.                         JMP     NoRow1Kill
  1526.  
  1527. NoRow3Kill:             MOV     AL,Collision
  1528.                         AND     AL,0f0h
  1529.                         CMP     AL,020h
  1530.                         JNZ     NoRow2Kill
  1531.                         CALL    SpeedUpInvaders
  1532.                         MOV     CH,0
  1533.                         MOV     CL,Collision
  1534.                         AND     CL,00fh
  1535.                         INC     CL
  1536.                         MOV     AX,08000h
  1537. Shifting4:              SHR     AX,1
  1538.                         LOOP    Shifting4
  1539.                         XOR     InvadersToggle[2],AX
  1540.                         MOV     CX,20
  1541.                         CALL    IncreaseScore
  1542.                         JMP     NoRow1Kill
  1543.  
  1544. NoRow2Kill:             MOV     AL,Collision
  1545.                         AND     AL,0f0h
  1546.                         CMP     AL,010h
  1547.                         JNZ     NoRow1Kill
  1548.                         CALL    SpeedUpInvaders
  1549.                         MOV     CH,0
  1550.                         MOV     CL,Collision
  1551.                         AND     CL,00fh
  1552.                         INC     CL
  1553.                         MOV     AX,08000h
  1554. Shifting5:              SHR     AX,1
  1555.                         LOOP    Shifting5
  1556.                         XOR     InvadersToggle[0],AX
  1557.                         MOV     CX,25
  1558.                         CALL    IncreaseScore
  1559.                         JMP     NoUFOKill
  1560.  
  1561. NoRow1Kill:             CMP     Collision,3
  1562.                         JNZ     NoUFOKill
  1563.                         LEA     AX,UFO              ; Get address of sprite
  1564.                         MOV     BX,UFOX             ; Get X position to draw sprite at
  1565.                         MOV     DL,10               ; Get Y position to draw sprite at
  1566.                         CALL    EraseSprite         ; Draw sprite
  1567.                         MOV     UFOX,0
  1568.                         MOV     CX,100
  1569.                         CALL    IncreaseScore
  1570.  
  1571. NoUFOKill:              CMP     InvadersToggle[0],00000h
  1572.                         JNZ     NotAllDeadYet
  1573.                         CMP     InvadersToggle[2],00000h
  1574.                         JNZ     NotAllDeadYet
  1575.                         CMP     InvadersToggle[4],00000h
  1576.                         JNZ     NotAllDeadYet
  1577.                         CMP     InvadersToggle[6],00000h
  1578.                         JNZ     NotAllDeadYet
  1579.                         CMP     InvadersToggle[8],00000h
  1580.                         JNZ     NotAllDeadYet
  1581.                         MOV     NextLevelToggle,1
  1582.  
  1583. NotAllDeadYet:          RET
  1584.  
  1585. CheckInvaderKill        ENDP
  1586.  
  1587. ; Speed up invaders upon a kill
  1588.  
  1589. SpeedUpInvaders         PROC    NEAR
  1590.                         Assume  CS:CODE_SEG,DS:CODE_SEG
  1591.  
  1592.                         CMP     InvaderSpeed,1
  1593.                         JZ      NoSpeedIncrease
  1594.                         DEC     InvaderSpeed
  1595.  
  1596. NoSpeedIncrease:        RET
  1597.  
  1598. SpeedUpInvaders         ENDP
  1599.  
  1600. ;----------------------------------------------------------------------------------------------------------------------------------
  1601. ; Move Invaders
  1602. ;----------------------------------------------------------------------------------------------------------------------------------
  1603.  
  1604. MoveInvaders            PROC    NEAR
  1605.                         Assume  CS:CODE_SEG,DS:CODE_SEG
  1606.  
  1607.                         TEST    Reversing,080h
  1608.                         JNZ     NoReverse
  1609.  
  1610.                         MOV     BX,250
  1611.                         MOV     AX,InvadersToggle[0]
  1612.                         OR      AX,InvadersToggle[2]
  1613.                         OR      AX,InvadersToggle[4]
  1614.                         OR      AX,InvadersToggle[6]
  1615.                         OR      AX,InvadersToggle[8]
  1616.                         MOV     CX,10
  1617. FindLeft:               SHL     AX,1
  1618.                         TEST    AX,08000h
  1619.                         JNZ     DoneLeft
  1620.                         SUB     BX,16
  1621.                         LOOP    FindLeft
  1622.  
  1623. DoneLeft:               MOV     DX,298
  1624.                         MOV     AX,InvadersToggle[0]
  1625.                         OR      AX,InvadersToggle[2]
  1626.                         OR      AX,InvadersToggle[4]
  1627.                         OR      AX,InvadersToggle[6]
  1628.                         OR      AX,InvadersToggle[8]
  1629.                         MOV     CX,10
  1630.                         SHR     AX,1
  1631.                         SHR     AX,1
  1632.                         SHR     AX,1
  1633. FindRight:              SHR     AX,1
  1634.                         TEST    AX,00001h
  1635.                         JNZ     DoneRight
  1636.                         ADD     DX,16
  1637.                         LOOP    FindRight
  1638.  
  1639. DoneRight:              CMP     InvadersX,DX
  1640.                         JZ      Reverse
  1641.                         CMP     InvadersX,BX
  1642.                         JNZ     NoReverse
  1643. Reverse:                XOR     Direction,080h
  1644.                         ADD     InvadersY,2
  1645.                         MOV     Reversing,080h
  1646.                         JMP     Animate
  1647.  
  1648. NoReverse:              MOV     Reversing,0
  1649.                         TEST    Direction,080h
  1650.                         JZ      MoveInvadersLeft
  1651.  
  1652.                         INC     InvadersX
  1653.                         JMP     Animate
  1654.  
  1655. MoveInvadersLeft:       DEC     InvadersX
  1656.  
  1657. Animate:                XOR     Frame,080h
  1658.                         MOV     AH,InvaderSpeed
  1659.                         MOV     MoveCount,AH
  1660.  
  1661. ; Make sound
  1662.  
  1663.                         TEST    Sound,080h
  1664.                         JZ      NoSound2
  1665.  
  1666.                         MOV     AL,0b6h
  1667.                         OUT     043h,AL
  1668.                         MOV     AL,090h
  1669.                         OUT     042h,AL
  1670.                         MOV     AL,00Fh
  1671.                         OUT     042h,AL
  1672.                         IN      AL,061h
  1673.                         OR      AL,3
  1674.                         OUT     061h,AL
  1675.  
  1676. NoSound2:               MOV     CX,08000h
  1677. Timer1:                 LOOP    Timer1
  1678.  
  1679.                         IN      AL,061h
  1680.                         AND     AL,0fch
  1681.                         OUT     061h,AL
  1682.  
  1683.                         RET
  1684.  
  1685. MoveInvaders            ENDP
  1686.  
  1687. ;----------------------------------------------------------------------------------------------------------------------------------
  1688. ; Shoot Player Missile
  1689. ;----------------------------------------------------------------------------------------------------------------------------------
  1690.  
  1691. ShootPlayerMissile      PROC    NEAR
  1692.                         Assume  CS:CODE_SEG,DS:CODE_SEG
  1693.  
  1694.                         MOV     AX,PlayerX
  1695.                         MOV     MissileX,AX
  1696.                         MOV     MissileY,123
  1697.  
  1698. ; Make sound
  1699.  
  1700.                         TEST    Sound,080h
  1701.                         JZ      NoSound3
  1702.  
  1703.                         MOV     AL,0b6h
  1704.                         OUT     043h,AL
  1705.                         MOV     AL,090h
  1706.                         OUT     042h,AL
  1707.                         MOV     AL,001h
  1708.                         OUT     042h,AL
  1709.                         IN      AL,061h
  1710.                         OR      AL,3
  1711.                         OUT     061h,AL
  1712.  
  1713. NoSound3:               MOV     CX,08000h
  1714. Timer2:                 LOOP    Timer2
  1715.  
  1716.                         IN      AL,061h
  1717.                         AND     AL,0fch
  1718.                         OUT     061h,AL
  1719.  
  1720.                         RET
  1721.  
  1722. ShootPlayerMissile      ENDP
  1723.  
  1724. ;----------------------------------------------------------------------------------------------------------------------------------
  1725. ; Move Player Missile
  1726. ;----------------------------------------------------------------------------------------------------------------------------------
  1727.  
  1728. MovePlayerMissile       PROC    NEAR
  1729.                         Assume  CS:CODE_SEG,DS:CODE_SEG
  1730.  
  1731.                         LEA     AX,StraightMissile  ; Get address of sprite
  1732.                         MOV     BX,MissileX         ; Get X position to draw sprite at
  1733.                         MOV     DL,MissileY         ; Get Y position to draw sprite at
  1734.                         CALL    EraseSprite         ; Draw sprite
  1735.  
  1736.                         DEC     MissileY
  1737.                         DEC     MissileY
  1738.  
  1739.                         CMP     MissileY,09
  1740.                         JNZ     DrawNextFrame
  1741.                         MOV     MissileX,0
  1742.                         JMP     MissileDead
  1743.  
  1744. DrawNextFrame:          LEA     AX,StraightMissile  ; Get address of sprite
  1745.                         MOV     BX,MissileX         ; Get X position to draw sprite at
  1746.                         MOV     DL,MissileY         ; Get Y position to draw sprite at
  1747.                         MOV     DH,04h              ; Get color to draw sprite
  1748.                         CALL    DrawSprite          ; Draw sprite
  1749.  
  1750.                         CMP     Collision,0
  1751.                         JZ      MissileDead
  1752.                         CMP     Collision,4
  1753.                         JZ      MissileDead
  1754.                         CMP     Collision,6
  1755.                         JZ      MissileDead
  1756.                         CALL    KillMissile
  1757.  
  1758. MissileDead:            RET
  1759.  
  1760. MovePlayerMissile       ENDP
  1761.  
  1762. ; Kill Player Missile
  1763.  
  1764. KillMissile             PROC    NEAR
  1765.                         Assume  CS:CODE_SEG,DS:CODE_SEG
  1766.  
  1767.                         LEA     AX,StraightMissile  ; Get address of sprite
  1768.                         MOV     BX,MissileX         ; Get X position to draw sprite at
  1769.                         MOV     DL,MissileY         ; Get Y position to draw sprite at
  1770.                         CALL    EraseSprite         ; Draw sprite
  1771.                         MOV     MissileX,0
  1772.  
  1773.                         RET
  1774.  
  1775. KillMissile             ENDP
  1776.  
  1777. ;----------------------------------------------------------------------------------------------------------------------------------
  1778. ; Move Player's Ship Left
  1779. ;----------------------------------------------------------------------------------------------------------------------------------
  1780.  
  1781. MovePlayerLeft          PROC    NEAR
  1782.                         Assume  CS:CODE_SEG,DS:CODE_SEG
  1783.  
  1784.                         CMP     PlayerX,50
  1785.                         JZ      NoMoreLeft
  1786.                         DEC     PlayerX
  1787.  
  1788. NoMoreLeft:             RET
  1789.  
  1790. MovePlayerLeft          ENDP
  1791.  
  1792. ;----------------------------------------------------------------------------------------------------------------------------------
  1793. ; Move Player's Ship Right
  1794. ;----------------------------------------------------------------------------------------------------------------------------------
  1795.  
  1796. MovePlayerRight         PROC    NEAR
  1797.                         Assume  CS:CODE_SEG,DS:CODE_SEG
  1798.  
  1799.                         CMP     PlayerX,259
  1800.                         JZ      NoMoreRight
  1801.                         INC     PlayerX
  1802.  
  1803. NoMoreRight:            RET
  1804.  
  1805. MovePlayerRight         ENDP
  1806.  
  1807. ;----------------------------------------------------------------------------------------------------------------------------------
  1808. ; New Interrupt 9 Handler - Replaces normal keyboard handler during game play
  1809. ;
  1810. ; Interrupt 015h: Calling AH = 04fh (check for this - Int 15 also has other
  1811. ;                                    subfuctions!)
  1812. ;                 Routine will look at AL, where the caller (Int 9) will have
  1813. ;                 placed the scan code.
  1814. ;
  1815. ;                 Place any new scan code for int 9 to process into AL and set
  1816. ;                 carry flag before return.
  1817. ;
  1818. ;                 Just clear carry flag to have int 9 ignore the keypress.
  1819. ;----------------------------------------------------------------------------------------------------------------------------------
  1820.  
  1821. ; Installs new int 9 handler
  1822.  
  1823. InstallNewInt9          PROC    NEAR
  1824.                         Assume  CS:CODE_SEG,DS:CODE_SEG
  1825.  
  1826.                         MOV     AH,035h                         ; Ask for interrupt address function
  1827.                         MOV     AL,015h                         ; Interrupt we're asking for
  1828.                         INT     021h                            ; Ask for it
  1829.                         MOV     Word Ptr OldInt9Address,BX      ; Save current segment of interrupt
  1830.                         MOV     Word Ptr OldInt9Address[2],ES   ; Save current offset of interrupt
  1831.  
  1832.                         MOV     AH,025h                         ; Insert new address for interrupt function
  1833.                         MOV     AL,015h                         ; Interupt we want to change
  1834.                         MOV     DX,Offset NewInt9Handler        ; New address to point to (this TSR)
  1835.                         INT     021h                            ; Set it
  1836.  
  1837.                         RET
  1838.  
  1839. OldInt9Address          DD      0   ; Buffer for original interrupt address
  1840. StoreAX                 DW      0
  1841.  
  1842. InstallNewInt9          ENDP
  1843.  
  1844. ; Removes new int 9 handler
  1845.  
  1846. RemoveNewInt9           PROC    NEAR
  1847.                         Assume  CS:CODE_SEG,DS:NOTHING
  1848.  
  1849.                         MOV     AX,Word Ptr OldInt9Address[2]
  1850.                         MOV     DS,AX
  1851.                         MOV     AH,025h                         ; Insert new address for interrupt function
  1852.                         MOV     AL,015h                         ; Interupt we want to change
  1853.                         MOV     DX,Word Ptr OldInt9Address      ; New address to point to (this TSR)
  1854.                         INT     021h                            ; Set it
  1855.  
  1856.                         RET
  1857.  
  1858. RemoveNewInt9           ENDP
  1859.  
  1860. ; Actual routine to be called when int 9 is tripped
  1861.  
  1862. NewInt9Handler          PROC    FAR
  1863.                         Assume  CS:CODE_SEG,DS:Nothing
  1864.  
  1865.                         CMP     AH,04fh
  1866.                         JNZ     NotIntercept
  1867.  
  1868.                         TEST    AL,080h
  1869.                         JNZ     NoKeyPress
  1870.                         MOV     KeyPress,1
  1871.  
  1872. ; Check left arrow
  1873.  
  1874. NoKeyPress:             CMP     AL,04Bh                 ; Has left arrow been pressed?
  1875.                         JNZ     NoLeftOn
  1876.                         MOV     LeftToggle,1
  1877.  
  1878. NoLeftOn:               CMP     AL,0CBh                 ; Has left arrow been released?
  1879.                         JNZ     NoLeftOff
  1880.                         MOV     LeftToggle,0
  1881.  
  1882. ; Check right arrow
  1883.  
  1884. NoLeftOff:              CMP     AL,04Dh                 ; Has right arrow been pressed?
  1885.                         JNZ     NoRightOn
  1886.                         MOV     RightToggle,1
  1887.  
  1888. NoRightOn:              CMP     AL,0CDh                 ; Has right arrow been released?
  1889.                         JNZ     NoRightOff
  1890.                         MOV     RightToggle,0
  1891.  
  1892. ; Check ctrl
  1893.  
  1894. NoRightOff:             CMP     AL,01Dh                 ; Has ctrl been pressed?
  1895.                         JNZ     NoFireOn
  1896.                         MOV     FireToggle,1
  1897.  
  1898. NoFireOn:               CMP     AL,09Dh                 ; Has ctrl been released?
  1899.                         JNZ     NoFireOff
  1900.                         MOV     FireToggle,0
  1901.  
  1902. ; Check ESC
  1903.  
  1904. NoFireOff:              CMP     AL,001h                 ; Has ESC been pressed?
  1905.                         JNZ     NoESCOn
  1906.                         MOV     ExitToggle,1
  1907.  
  1908. NoESCOn:                CMP     AL,01fh
  1909.                         JNZ     NotIntercept
  1910.                         MOV     SoundToggle,1
  1911.  
  1912. ; Clear keyboard buffer (BIOS routine is still called, and it annoyingly beeps when it's buffer is full)
  1913.  
  1914.  
  1915.  
  1916. NotIntercept:
  1917.                         MOV     StoreAX,AX
  1918.                         MOV     AX,40:[01ch]
  1919.                         MOV     40:[01ah],AX
  1920.                         MOV     AX,StoreAX
  1921.  
  1922. ;                        MOV     AX,040h
  1923. ;                        MOV     ES,AX
  1924. ;                        MOV     DS,AX
  1925. ;                        MOV     DI,01ah
  1926. ;                        MOV     SI,01ch
  1927. ;                        MOVSW
  1928.  
  1929.                         CLC
  1930.  
  1931. ; Call original interrupt routine
  1932.  
  1933. ;                        CALL    OldInt9Address  ; Call normal interrupt routine
  1934.  
  1935.                         IRET
  1936. ;                        RET     2       ; Return from TSR
  1937.  
  1938. NewInt9Handler          ENDP
  1939.  
  1940. ;---------------------------------------------------------------------
  1941. ;                        JMP     StartPrint
  1942. ;CharacterTable          DB        "0123456789ABCDEF"
  1943. ;StartPrint:             MOV     AL,RandomNumber[0]
  1944. ;                        MOV     CX,04h
  1945. ;Looper1:                SHR     AL,1
  1946. ;                        LOOP    Looper1
  1947. ;                        LEA     SI,CharacterTable
  1948. ;                        MOV     AH,0
  1949. ;                        ADD     SI,AX
  1950. ;                        CLD
  1951. ;                        LODSB
  1952. ;                        MOV     DL,AL
  1953. ;                        MOV     AH,2
  1954. ;                        INT     21h
  1955. ;                        MOV     AL,RandomNumber[0]
  1956. ;                        AND     AL,0fh
  1957. ;                        LEA     SI,CharacterTable
  1958. ;                        MOV     AH,0
  1959. ;                        ADD     SI,AX
  1960. ;                        CLD
  1961. ;                        LODSB
  1962. ;                        MOV     DL,AL
  1963. ;                        MOV     AH,2
  1964. ;                        INT     21h
  1965. ;                        MOV     DL,00dh
  1966. ;                        MOV     AH,2
  1967. ;                        INT     21h
  1968. ;---------------------------------------------------------------------
  1969.  
  1970. ;----------------------------------------------------------------------------------------------------------------------------------
  1971. ; Draw Bunkers
  1972. ;----------------------------------------------------------------------------------------------------------------------------------
  1973.  
  1974. DrawBunkers             PROC    NEAR
  1975.                         Assume  CS:CODE_SEG,DS:CODE_SEG
  1976.  
  1977.                         MOV     BunkerXL,70
  1978.                         MOV     BunkerYL,100
  1979.                         CALL    DrawBunker
  1980.  
  1981.                         MOV     BunkerXL,122
  1982.                         MOV     BunkerYL,100
  1983.                         CALL    DrawBunker
  1984.  
  1985.                         MOV     BunkerXL,174
  1986.                         MOV     BunkerYL,100
  1987.                         CALL    DrawBunker
  1988.  
  1989.                         MOV     BunkerXL,226
  1990.                         MOV     BunkerYL,100
  1991.                         CALL    DrawBunker
  1992.  
  1993.                         RET
  1994.  
  1995. DrawBunkers             ENDP
  1996.  
  1997. ; Draw Single Bunker
  1998.  
  1999. DrawBunker              PROC    NEAR
  2000.                         Assume  CS:CODE_SEG,DS:CODE_SEG
  2001.  
  2002.                         LEA     AX,BunkerLeftTop    ; Get address of sprite
  2003.                         MOV     BX,BunkerXL         ; Get X position to draw sprite at
  2004.                         MOV     DL,BunkerYL         ; Get Y position to draw sprite at
  2005.                         MOV     DH,2                ; Get color to draw sprite
  2006.                         CALL    DrawSprite          ; Draw sprite
  2007.  
  2008.                         ADD     BunkerYL,7
  2009.  
  2010.                         LEA     AX,BunkerLeftMiddle ; Get address of sprite
  2011.                         MOV     BX,BunkerXL         ; Get X position to draw sprite at
  2012.                         MOV     DL,BunkerYL         ; Get Y position to draw sprite at
  2013.                         MOV     DH,2                ; Get color to draw sprite
  2014.                         CALL    DrawSprite          ; Draw sprite
  2015.  
  2016.                         ADD     BunkerYL,7
  2017.  
  2018.                         LEA     AX,BunkerLeftBottom ; Get address of sprite
  2019.                         MOV     BX,BunkerXL         ; Get X position to draw sprite at
  2020.                         MOV     DL,BunkerYL         ; Get Y position to draw sprite at
  2021.                         MOV     DH,2                ; Get color to draw sprite
  2022.                         CALL    DrawSprite          ; Draw sprite
  2023.  
  2024.                         ADD     BunkerXL,16
  2025.                         SUB     BunkerYL,14
  2026.  
  2027.                         LEA     AX,BunkerRightTop   ; Get address of sprite
  2028.                         MOV     BX,BunkerXL         ; Get X position to draw sprite at
  2029.                         MOV     DL,BunkerYL         ; Get Y position to draw sprite at
  2030.                         MOV     DH,2                ; Get color to draw sprite
  2031.                         CALL    DrawSprite          ; Draw sprite
  2032.  
  2033.                         ADD     BunkerYL,7
  2034.  
  2035.                         LEA     AX,BunkerRightMiddle; Get address of sprite
  2036.                         MOV     BX,BunkerXL         ; Get X position to draw sprite at
  2037.                         MOV     DL,BunkerYL         ; Get Y position to draw sprite at
  2038.                         MOV     DH,2                ; Get color to draw sprite
  2039.                         CALL    DrawSprite          ; Draw sprite
  2040.  
  2041.                         ADD     BunkerYL,7
  2042.  
  2043.                         LEA     AX,BunkerRightBottom; Get address of sprite
  2044.                         MOV     BX,BunkerXL         ; Get X position to draw sprite at
  2045.                         MOV     DL,BunkerYL         ; Get Y position to draw sprite at
  2046.                         MOV     DH,2                ; Get color to draw sprite
  2047.                         CALL    DrawSprite          ; Draw sprite
  2048.  
  2049.                         RET                     ; Done drawing, return to caller
  2050.  
  2051. BunkerXL                DW      0
  2052. BunkerYL                DB      0
  2053.  
  2054. DrawBunker              ENDP
  2055.  
  2056. ;----------------------------------------------------------------------------------------------------------------------------------
  2057. ; Draw Invaders
  2058. ;----------------------------------------------------------------------------------------------------------------------------------
  2059.  
  2060. DrawInvaders            PROC    NEAR
  2061.                         Assume  CS:CODE_SEG,DS:CODE_SEG
  2062.  
  2063.                         MOV     AX,InvadersX
  2064.                         MOV     InvadersXL,AX
  2065.                         MOV     AL,InvadersY
  2066.                         MOV     InvadersYL,AL
  2067.                         LEA     SI,InvadersToggle ; Setup source pointer to sprite data
  2068.  
  2069.                         MOV     ColorL,010h
  2070.                         TEST    Frame,80h
  2071.                         JZ      FrameIsZero1
  2072.                         LEA     AX,TopInvader2
  2073.                         JMP     Skip1
  2074. FrameIsZero1:           LEA     AX,TopInvader1
  2075. Skip1:                  MOV     SpriteAddressL,AX
  2076.                         CLD                     ; Make sure we increment SI
  2077.                         LODSW                   ; Get 2 bytes from invaders alive toggles
  2078.                         MOV     Temporary2L,SI
  2079.                         CALL    DrawInvaderRow
  2080.  
  2081.                         MOV     ColorL,020h
  2082.                         TEST    Frame,80h
  2083.                         JZ      FrameIsZero2
  2084.                         LEA     AX,MiddleInvader2
  2085.                         JMP     Skip2
  2086. FrameIsZero2:           LEA     AX,MiddleInvader1
  2087. Skip2:                  MOV     SpriteAddressL,AX
  2088.                         MOV     SI,Temporary2L
  2089.                         CLD                     ; Make sure we increment SI
  2090.                         LODSW                   ; Get 2 bytes from invaders alive toggles
  2091.                         MOV     Temporary2L,SI
  2092.                         CALL    DrawInvaderRow
  2093.  
  2094.                         MOV     ColorL,030h
  2095.                         TEST    Frame,80h
  2096.                         JZ      FrameIsZero3
  2097.                         LEA     AX,MiddleInvader1
  2098.                         JMP     Skip3
  2099. FrameIsZero3:           LEA     AX,MiddleInvader2
  2100. Skip3:                  MOV     SpriteAddressL,AX
  2101.                         MOV     SI,Temporary2L
  2102.                         CLD                     ; Make sure we increment SI
  2103.                         LODSW                   ; Get 2 bytes from invaders alive toggles
  2104.                         MOV     Temporary2L,SI
  2105.                         CALL    DrawInvaderRow
  2106.  
  2107.                         MOV     ColorL,040h
  2108.                         TEST    Frame,80h
  2109.                         JZ      FrameIsZero4
  2110.                         LEA     AX,BottomInvader2
  2111.                         JMP     Skip4
  2112. FrameIsZero4:           LEA     AX,BottomInvader1
  2113. Skip4:                  MOV     SpriteAddressL,AX
  2114.                         MOV     SI,Temporary2L
  2115.                         CLD                     ; Make sure we increment SI
  2116.                         LODSW                   ; Get 2 bytes from invaders alive toggles
  2117.                         MOV     Temporary2L,SI
  2118.                         CALL    DrawInvaderRow
  2119.  
  2120.                         MOV     ColorL,050h
  2121.                         MOV     SI,Temporary2L
  2122.                         CLD                     ; Make sure we increment SI
  2123.                         LODSW                   ; Get 2 bytes from invaders alive toggles
  2124.                         MOV     Temporary2L,SI
  2125.                         CALL    DrawInvaderRow
  2126.  
  2127.                         MOV     Collision,0     ; No collision detection on invaders - Causes problems when invaders get to bunkers
  2128.  
  2129.                         RET                     ; Done drawing, return to caller
  2130.  
  2131. InvadersXL              DW      0
  2132. InvadersYL              DB      0
  2133. Temporary2L             DW      0
  2134.  
  2135. DrawInvaders            ENDP
  2136.  
  2137. ; Draw Row of Invaders
  2138.  
  2139. DrawInvaderRow          PROC    NEAR
  2140.                         Assume  CS:CODE_SEG,DS:CODE_SEG
  2141.  
  2142.                         SHL     AX,1
  2143.                         MOV     CounterL,11
  2144. DrawRow:                TEST    AX,8000h        ; Check left most bit
  2145.                         JZ      BitIsZero1      ; Jump if bit is 0
  2146.                         MOV     Temporary1L,AX
  2147.                         MOV     AX,SpriteAddressL   ; Get address of sprite
  2148.                         MOV     BX,InvadersXL       ; Get X position to draw sprite at
  2149.                         SUB     BX,200
  2150.                         MOV     DL,InvadersYL       ; Get Y position to draw sprite at
  2151.                         MOV     DH,ColorL           ; Get color to draw sprite
  2152.                         CALL    DrawSprite          ; Draw sprite
  2153.                         MOV     AX,Temporary1L
  2154. BitIsZero1:             SHL     AX,1            ; Shift data left for next bit
  2155.                         ADD     InvadersXL,16
  2156.                         DEC     CounterL
  2157.                         INC     ColorL
  2158.                         JNZ     DrawRow
  2159.  
  2160.                         ADD     InvadersYL,10
  2161.                         MOV     AX,InvadersX
  2162.                         MOV     InvadersXL,AX
  2163.  
  2164.                         RET                     ; Done drawing, return to caller
  2165.  
  2166. CounterL                DB      0
  2167. SpriteAddressL          DW      0
  2168. ColorL                  DB      0
  2169. Temporary1L             DW      0
  2170.  
  2171. DrawInvaderRow          ENDP
  2172.  
  2173. ;----------------------------------------------------------------------------------------------------------------------------------
  2174. ; Erase Invaders
  2175. ;----------------------------------------------------------------------------------------------------------------------------------
  2176.  
  2177. EraseInvaders           PROC    NEAR
  2178.                         Assume  CS:CODE_SEG,DS:CODE_SEG
  2179.  
  2180.                         MOV     AX,InvadersX
  2181.                         MOV     InvadersXL,AX
  2182.                         MOV     AL,InvadersY
  2183.                         MOV     InvadersYL,AL
  2184.                         LEA     SI,InvadersToggle ; Setup source pointer to sprite data
  2185.  
  2186.                         TEST    Frame,80h
  2187.                         JZ      FrameIsZeroA
  2188.                         LEA     AX,TopInvader2
  2189.                         JMP     SkipA
  2190. FrameIsZeroA:           LEA     AX,TopInvader1
  2191. SkipA:                  MOV     SpriteAddressL,AX
  2192.                         CLD                     ; Make sure we increment SI
  2193.                         LODSW                   ; Get 2 bytes from invaders alive toggles
  2194.                         MOV     Temporary2L,SI
  2195.                         CALL    EraseInvaderRow
  2196.  
  2197.                         TEST    Frame,80h
  2198.                         JZ      FrameIsZeroB
  2199.                         LEA     AX,MiddleInvader2
  2200.                         JMP     SkipB
  2201. FrameIsZeroB:           LEA     AX,MiddleInvader1
  2202. SkipB:                  MOV     SpriteAddressL,AX
  2203.                         MOV     SI,Temporary2L
  2204.                         CLD                     ; Make sure we increment SI
  2205.                         LODSW                   ; Get 2 bytes from invaders alive toggles
  2206.                         MOV     Temporary2L,SI
  2207.                         CALL    EraseInvaderRow
  2208.  
  2209.                         TEST    Frame,80h
  2210.                         JZ      FrameIsZeroC
  2211.                         LEA     AX,MiddleInvader1
  2212.                         JMP     SkipC
  2213. FrameIsZeroC:           LEA     AX,MiddleInvader2
  2214. SkipC:                  MOV     SpriteAddressL,AX
  2215.                         MOV     SI,Temporary2L
  2216.                         CLD                     ; Make sure we increment SI
  2217.                         LODSW                   ; Get 2 bytes from invaders alive toggles
  2218.                         MOV     Temporary2L,SI
  2219.                         CALL    EraseInvaderRow
  2220.  
  2221.                         TEST    Frame,80h
  2222.                         JZ      FrameIsZeroD
  2223.                         LEA     AX,BottomInvader2
  2224.                         JMP     SkipD
  2225. FrameIsZeroD:           LEA     AX,BottomInvader1
  2226. SkipD:                  MOV     SpriteAddressL,AX
  2227.                         MOV     SI,Temporary2L
  2228.                         CLD                     ; Make sure we increment SI
  2229.                         LODSW                   ; Get 2 bytes from invaders alive toggles
  2230.                         MOV     Temporary2L,SI
  2231.                         CALL    EraseInvaderRow
  2232.  
  2233.                         MOV     SI,Temporary2L
  2234.                         CLD                     ; Make sure we increment SI
  2235.                         LODSW                   ; Get 2 bytes from invaders alive toggles
  2236.                         MOV     Temporary2L,SI
  2237.                         CALL    EraseInvaderRow
  2238.  
  2239.                         RET                     ; Done drawing, return to caller
  2240.  
  2241. EraseInvaders           ENDP
  2242.  
  2243. ; Erase Row of Invaders
  2244.  
  2245. EraseInvaderRow         PROC    NEAR
  2246.                         Assume  CS:CODE_SEG,DS:CODE_SEG
  2247.  
  2248.                         SHL     AX,1
  2249.                         MOV     CounterL,11
  2250. DrawRowA:               TEST    AX,8000h        ; Check left most bit
  2251.                         JZ      BitIsZeroA      ; Jump if bit is 0
  2252.                         MOV     Temporary1L,AX
  2253.                         MOV     AX,SpriteAddressL   ; Get address of sprite
  2254.                         MOV     BX,InvadersXL       ; Get X position to draw sprite at
  2255.                         SUB     BX,200
  2256.                         MOV     DL,InvadersYL       ; Get Y position to draw sprite at
  2257.                         CALL    EraseSprite         ; Draw sprite
  2258.                         MOV     AX,Temporary1L
  2259. BitIsZeroA:             SHL     AX,1            ; Shift data left for next bit
  2260.                         ADD     InvadersXL,16
  2261.                         DEC     CounterL
  2262.                         JNZ     DrawRowA
  2263.  
  2264.                         ADD     InvadersYL,10
  2265.                         MOV     AX,InvadersX
  2266.                         MOV     InvadersXL,AX
  2267.  
  2268.                         RET                     ; Done drawing, return to caller
  2269.  
  2270. EraseInvaderRow         ENDP
  2271.  
  2272. ;----------------------------------------------------------------------------------------------------------------------------------
  2273. ; Draw Logo Layer
  2274. ;----------------------------------------------------------------------------------------------------------------------------------
  2275.  
  2276. DrawLogoLayer           PROC    NEAR
  2277.                         Assume  CS:CODE_SEG,DS:CODE_SEG
  2278.  
  2279.                         MOV     SI,AX           ; Setup source pointer to sprite data
  2280.                         MOV     AL,DL           ; Get Y position of sprite in AL
  2281.                         MOV     AH,0            ; Zero high byte of AX for following shifts
  2282.                         SHL     AX,1            ; Calculate Y position * 320 (find address of row)
  2283.                         SHL     AX,1            ; Y Position shifted left 6 times + Y Position shifted left 8 times
  2284.                         SHL     AX,1
  2285.                         SHL     AX,1
  2286.                         SHL     AX,1
  2287.                         SHL     AX,1
  2288.                         MOV     CX,AX
  2289.                         SHL     CX,1
  2290.                         SHL     CX,1
  2291.                         ADD     AX,CX
  2292.                         ADD     AX,BX           ; Add X position to address
  2293.                         MOV     DI,AX           ; Store address in destination register
  2294.                         MOV     AX,0a000h       ; Get segment of video memory
  2295.                         MOV     ES,AX           ; Store it in destination segment register
  2296.  
  2297.                         MOV     Row,5
  2298.  
  2299. DoNextRow:              MOV     Column,11
  2300.  
  2301. DoNextSprite:           MOV     DL,7            ; Do 7 lines of sprite
  2302.                         CLD                     ; Make sure we increment SI and DI
  2303. DrawLinesZ:             LODSW                   ; Get 2 bytes from sprite data (16 bits = 1 line of sprite image)
  2304.                         MOV     BX,AX           ; Transfer data to an unused register
  2305.                         MOV     CX,16           ; Scan all 16 bits
  2306. DoLineZ:                TEST    BX,8000h        ; Check left most bit
  2307.                         JZ      BitIsZeroZ      ; Jump if bit is 0
  2308.                         MOV     AL,DH           ; Bit is 1, get color of sprite
  2309.                         STOSB                   ; And draw the pixel on the screen
  2310.                         JMP     SkipZ           ; Skip the bit is 0 stuff
  2311. BitIsZeroZ:             INC     DI              ; Bit was 0, increment destination register
  2312. SkipZ:                  SHL     BX,1            ; Shift data left for next bit
  2313.                         LOOP    DoLineZ         ; Keep going until no more bits to check
  2314.                         ADD     DI,304          ; Increment address to next screen line (320 - 16 bits)
  2315.                         DEC     DL              ; Decrease line count
  2316.                         JNZ     DrawLinesZ      ; Draw lines until no more lines left to draw
  2317.  
  2318.                         SUB     DI,2224         ; Do next sprite in row
  2319.                         DEC     Column
  2320.                         CMP     Column,0
  2321.                         JNZ     DoNextSprite
  2322.  
  2323.                         ADD     DI,2064         ; Do next sprite in row
  2324.                         DEC     Row
  2325.                         CMP     Row,0
  2326.                         JNZ     DoNextRow
  2327.  
  2328.                         RET                     ; Done drawing, return to caller
  2329.  
  2330. Column                  DB      0
  2331. Row                     DB      0
  2332.  
  2333. DrawLogoLayer           ENDP
  2334.  
  2335. ;----------------------------------------------------------------------------------------------------------------------------------
  2336. ; Draw Sprite
  2337. ;----------------------------------------------------------------------------------------------------------------------------------
  2338.  
  2339. DrawSprite              PROC    NEAR
  2340.                         Assume  CS:CODE_SEG,DS:CODE_SEG
  2341.  
  2342.                         MOV     SI,AX           ; Setup source pointer to sprite data
  2343.                         MOV     AL,DL           ; Get Y position of sprite in AL
  2344.                         MOV     AH,0            ; Zero high byte of AX for following shifts
  2345.                         SHL     AX,1            ; Calculate Y position * 320 (find address of row)
  2346.                         SHL     AX,1            ; Y Position shifted left 6 times + Y Position shifted left 8 times
  2347.                         SHL     AX,1
  2348.                         SHL     AX,1
  2349.                         SHL     AX,1
  2350.                         SHL     AX,1
  2351.                         MOV     CX,AX
  2352.                         SHL     CX,1
  2353.                         SHL     CX,1
  2354.                         ADD     AX,CX
  2355.                         LEA     CX,VideoBuffer  ; Get address of video buffer
  2356.                         ADD     AX,CX           ; Add offset to video buffer
  2357.                         ADD     AX,BX           ; Add X position to address
  2358.                         MOV     DI,AX           ; Store address in destination register
  2359.                         MOV     AX,CS           ; Get segment of video memory
  2360.                         MOV     ES,AX           ; Store it in destination segment register
  2361.  
  2362.                         MOV     DL,7            ; Do 7 lines
  2363.                         CLD                     ; Make sure we increment SI and DI
  2364. DrawLines:              LODSW                   ; Get 2 bytes from sprite data (16 bits = 1 line of sprite image)
  2365.                         MOV     BX,AX           ; Transfer data to an unused register
  2366.                         MOV     CX,16           ; Scan all 16 bits
  2367. DoLine:                 TEST    BX,8000h        ; Check left most bit
  2368.                         JZ      BitIsZero       ; Jump if bit is 0
  2369.                         CMP     Collision,0
  2370.                         JNZ     NoCollision
  2371.                         MOV     AL,ES:[DI]
  2372.                         CMP     AL,0
  2373.                         JZ      NoCollision
  2374.                         MOV     Collision,AL
  2375. NoCollision:            MOV     AL,DH           ; Bit is 1, get color of sprite
  2376.                         STOSB                   ; And draw the pixel on the screen
  2377.                         JMP     Skip            ; Skip the bit is 0 stuff
  2378. BitIsZero:              INC     DI              ; Bit was 0, increment destination register
  2379. Skip:                   SHL     BX,1            ; Shift data left for next bit
  2380.                         LOOP    DoLine          ; Keep going until no more bits to check
  2381.                         ADD     DI,304          ; Increment address to next screen line (320 - 16 bits)
  2382.                         DEC     DL              ; Decrease line count
  2383.                         JNZ     DrawLines       ; Draw lines until no more lines left to draw
  2384.  
  2385.                         RET                     ; Done drawing, return to caller
  2386.  
  2387. DrawSprite              ENDP
  2388.  
  2389. ;----------------------------------------------------------------------------------------------------------------------------------
  2390. ; Erase Sprite
  2391. ;----------------------------------------------------------------------------------------------------------------------------------
  2392.  
  2393. EraseSprite             PROC    NEAR
  2394.                         Assume  CS:CODE_SEG,DS:CODE_SEG
  2395.  
  2396.                         MOV     SI,AX           ; Setup source pointer to sprite data
  2397.                         MOV     AL,DL           ; Get Y position of sprite in AL
  2398.                         MOV     AH,0            ; Zero high byte of AX for following shifts
  2399.                         SHL     AX,1            ; Calculate Y position * 320 (find address of row)
  2400.                         SHL     AX,1            ; Y Position shifted left 6 times + Y Position shifted left 8 times
  2401.                         SHL     AX,1
  2402.                         SHL     AX,1
  2403.                         SHL     AX,1
  2404.                         SHL     AX,1
  2405.                         MOV     CX,AX
  2406.                         SHL     CX,1
  2407.                         SHL     CX,1
  2408.                         ADD     AX,CX
  2409.                         LEA     CX,VideoBuffer  ; Get address of video buffer
  2410.                         ADD     AX,CX           ; Add offset to video buffer
  2411.                         ADD     AX,BX           ; Add X position to address
  2412.                         MOV     DI,AX           ; Store address in destination register
  2413.                         MOV     AX,CS           ; Get segment of video memory
  2414.                         MOV     ES,AX           ; Store it in destination segment register
  2415.  
  2416.                         MOV     DL,7            ; Do 7 lines
  2417.                         CLD                     ; Make sure we increment SI and DI
  2418. DrawLines2:             LODSW                   ; Get 2 bytes from sprite data (16 bits = 1 line of sprite image)
  2419.                         MOV     BX,AX           ; Transfer data to an unused register
  2420.                         MOV     CX,16           ; Scan all 16 bits
  2421. DoLine2:                TEST    BX,8000h        ; Check left most bit
  2422.                         JZ      BitIsZero2      ; Jump if bit is 0
  2423.                         MOV     AL,0            ; Bit is 1, get color of sprite
  2424.                         STOSB                   ; And draw the pixel on the screen
  2425.                         JMP     SkipAA          ; Skip the bit is 0 stuff
  2426. BitIsZero2:             INC     DI              ; Bit was 0, increment destination register
  2427. SkipAA:                 SHL     BX,1            ; Shift data left for next bit
  2428.                         LOOP    DoLine2         ; Keep going until no more bits to check
  2429.                         ADD     DI,304          ; Increment address to next screen line (320 - 16 bits)
  2430.                         DEC     DL              ; Decrease line count
  2431.                         JNZ     DrawLines2      ; Draw lines until no more lines left to draw
  2432.  
  2433.                         RET                     ; Done drawing, return to caller
  2434.  
  2435. EraseSprite             ENDP
  2436.  
  2437. ;----------------------------------------------------------------------------------------------------------------------------------
  2438. ; Sprite data
  2439. ;----------------------------------------------------------------------------------------------------------------------------------
  2440.  
  2441. TopInvader1             DW      0c00h,1e00h,2d00h,3f00h,1200h,2100h,1200h
  2442. TopInvader2             DW      0c00h,1e00h,2d00h,3f00h,1200h,2100h,4080h
  2443.  
  2444. MiddleInvader1          DW      2100h,9e40h,0ad40h,7f80h,3f00h,2100h,4080h
  2445. MiddleInvader2          DW      2100h,1e00h,2d00h,7f80h,0bf40h,0a140h,1200h
  2446.  
  2447. BottomInvader1          DW      01e00h,7f80h,0ccc0h,0ffc0h,2100h,4c80h,2100h
  2448. BottomInvader2          DW      01e00h,7f80h,0ccc0h,0ffc0h,2100h,4c80h,8040h
  2449.  
  2450. TwistedMissile1         DW      0000h,0000h,0000h,0800h,0400h,0800h,0400h
  2451. TwistedMissile2         DW      0000h,0000h,0000h,0400h,0800h,0400h,0800h
  2452.  
  2453. UFO                     DW      0ff0h,0ff0h,0ffffh,0ffffh,0ffffh,7ffeh,3ffch
  2454.  
  2455. PlayersShip             DW      0400h,0e00h,7fc0h,0ffe0h,0ffe0h,0ffe0h,0000h
  2456.  
  2457. StraightMissile         DW      0000h,0000h,0000h,0400h,0400h,0400h,0400h
  2458.  
  2459. BunkerLeftTop           DW      0fffh,1fffh,3fffh,7fffh,0ffffh,0ffffh,0ffffh
  2460. BunkerLeftMiddle        DW      0ffffh,0ffffh,0ffffh,0ffffh,0ffffh,0ffffh,0ffffh
  2461. BunkerLeftBottom        DW      0ff81h,0fe00h,0fc00h,0f800h,0f800h,0f000h,0000h
  2462. BunkerRightTop          DW      0f000h,0f800h,0fc00h,0fe00h,0ff00h,0ff00h,0ff00h
  2463. BunkerRightMiddle       DW      0ff00h,0ff00h,0ff00h,0ff00h,0ff00h,0ff00h,0ff00h
  2464. BunkerRightBottom       DW      0ff00h,7f00h,3f00h,1f00h,1f00h,0f00h,0000h
  2465.  
  2466. SCO                     DW      71c7h,8a28h,8208h,7208h,0a08h,8a28h,71c7h
  2467. ORE                     DW      3cf8h,0a280h,0a280h,0bcf0h,0a280h,0a280h,22f8h
  2468.  
  2469. Zero                    DW      3800h,4400h,4c00h,5400h,6400h,4400h,3800h
  2470. One                     DW      1000h,3000h,1000h,1000h,1000h,1000h,3800h
  2471. Two                     DW      3800h,4400h,0400h,1800h,2000h,4000h,7c00h
  2472. Three                   DW      3800h,4400h,0400h,1800h,0400h,4400h,3800h
  2473. Four                    DW      4400h,4400h,4400h,7c00h,0400h,0400h,0400h
  2474. Five                    DW      7c00h,4000h,4000h,7800h,0400h,4400h,3800h
  2475. Six                     DW      3800h,4400h,4000h,7800h,4400h,4400h,3800h
  2476. Seven                   DW      7c00h,0400h,0800h,1000h,1000h,1000h,1000h
  2477. Eight                   DW      3800h,4400h,4400h,3800h,4400h,4400h,3800h
  2478. Nine                    DW      3800h,4400h,4400h,3c00h,0400h,4400h,3800h
  2479.  
  2480. Equal                   DW      0000h,0000h,7c00h,0000h,7c00h,0000h,0000h
  2481. Period                  DW      0000h,0000h,0000h,0000h,0000h,0000h,1000h
  2482. CopyrightSymbol         DW      1e00h,2100h,4c80h,4880h,4c80h,2100h,1e00h
  2483.  
  2484. LetterA                 DW      3800h,4400h,4400h,7c00h,4400h,4400h,4400h
  2485. LetterB                 DW      7800h,4400h,4400h,7800h,4400h,4400h,7800h
  2486. LetterC                 DW      3800h,4400h,4000h,4000h,4000h,4400h,3800h
  2487. LetterD                 DW      7800h,4400h,4400h,4400h,4400h,4400h,7800h
  2488. LetterE                 DW      7c00h,4000h,4000h,7800h,4000h,4000h,7c00h
  2489. LetterF                 DW      7c00h,4000h,4000h,7800h,4000h,4000h,4000h
  2490. LetterG                 DW      3800h,4400h,4000h,5c00h,4400h,4400h,3800h
  2491. LetterH                 DW      4400h,4400h,4400h,7c00h,4400h,4400h,4400h
  2492. LetterI                 DW      7c00h,1000h,1000h,1000h,1000h,1000h,7c00h
  2493. LetterJ                 DW      0400h,0400h,0400h,0400h,0400h,4400h,3800h
  2494. LetterK                 DW      4400h,4800h,5000h,6000h,5000h,4800h,4400h
  2495. LetterL                 DW      4000h,4000h,4000h,4000h,4000h,4000h,7c00h
  2496. LetterM                 DW      4400h,6c00h,5400h,4400h,4400h,4400h,4400h
  2497. LetterN                 DW      4400h,6400h,5400h,4c00h,4400h,4400h,4400h
  2498. LetterO                 DW      3800h,4400h,4400h,4400h,4400h,4400h,3800h
  2499. LetterP                 DW      7800h,4400h,4400h,7800h,4000h,4000h,4000h
  2500. LetterQ                 DW      3800h,4400h,4400h,4400h,4400h,4c00h,3c00h
  2501. LetterR                 DW      7800h,4400h,4400h,7800h,4400h,4400h,4400h
  2502. LetterS                 DW      3800h,4400h,4000h,3800h,0400h,4400h,3800h
  2503. LetterT                 DW      7c00h,1000h,1000h,1000h,1000h,1000h,1000h
  2504. LetterU                 DW      4400h,4400h,4400h,4400h,4400h,4400h,3800h
  2505. LetterV                 DW      4400h,4400h,4400h,4400h,4400h,2800h,1000h
  2506. LetterW                 DW      4400h,4400h,4400h,4400h,5400h,6c00h,4400h
  2507. LetterX                 DW      4400h,4400h,2800h,1000h,2800h,4400h,4400h
  2508. LetterY                 DW      4400h,4400h,2800h,1000h,1000h,1000h,1000h
  2509. LetterZ                 DW      7c00h,0400h,0800h,1000h,2000h,4000h,7c00h
  2510.  
  2511. LogoOutline             DW      00000h,00000h,00000h,00000h,00000h,00000h,00000h
  2512.                         DW      00000h,00000h,00000h,00000h,00000h,00000h,00000h
  2513.                         DW      00000h,007ffh,01800h,02000h,04000h,040ffh,0403fh
  2514.                         DW      00000h,0e3ffh,01400h,00c00h,00400h,00607h,0fa03h
  2515.                         DW      00000h,0f80fh,00610h,00120h,000a0h,0c0e0h,0c0c1h
  2516.                         DW      00000h,0fc00h,00200h,00101h,00102h,00082h,08084h
  2517.                         DW      00000h,01fffh,06000h,08000h,00060h,000a0h,0011fh
  2518.                         DW      00000h,003ffh,08400h,04800h,04800h,0500fh,0900fh
  2519.                         DW      00000h,0ff80h,00040h,00040h,00080h,0ff00h,0c000h
  2520.                         DW      00000h,00000h,00000h,00000h,00000h,00000h,00000h
  2521.                         DW      00000h,00000h,00000h,00000h,00000h,00000h,00000h
  2522.  
  2523.                         DW      00000h,00000h,00000h,00000h,00000h,00000h,00000h
  2524.                         DW      00000h,00000h,00000h,00000h,00000h,00000h,00000h
  2525.                         DW      02000h,01c00h,003fch,00fc3h,0103eh,01000h,00800h
  2526.                         DW      0e200h,01900h,00503h,00301h,00281h,00280h,00440h
  2527.                         DW      00181h,00682h,0f903h,00100h,00200h,08207h,04408h
  2528.                         DW      08044h,04048h,0c028h,00028h,00018h,0e018h,0100ch
  2529.                         DW      00100h,00200h,00200h,0047eh,00381h,00001h,00003h
  2530.                         DW      02000h,02000h,0403fh,04020h,0803fh,08000h,00000h
  2531.                         DW      02000h,02000h,0c000h,00000h,0f000h,00800h,00800h
  2532.                         DW      00000h,00000h,00000h,00000h,00000h,00000h,00000h
  2533.                         DW      00000h,00000h,00000h,00000h,00000h,00000h,00000h
  2534.  
  2535.                         DW      00000h,00000h,00000h,01fe0h,02011h,02009h,01009h
  2536.                         DW      00000h,00000h,00000h,0fc0fh,00310h,000d0h,00038h
  2537.                         DW      00700h,000ffh,00000h,0f1feh,00a01h,00600h,00300h
  2538.                         DW      03840h,0c03fh,00000h,00fe0h,01010h,09010h,05010h
  2539.                         DW      04408h,083f0h,00000h,07fe0h,08010h,08008h,08004h
  2540.                         DW      0100bh,00ff0h,00000h,00fffh,01000h,01000h,01000h
  2541.                         DW      0000dh,0fff0h,00000h,0f80fh,00610h,00110h,00090h
  2542.                         DW      00000h,0ffffh,00000h,0fff8h,00005h,00005h,0000ah
  2543.                         DW      01000h,0e000h,00000h,0ffffh,00000h,00000h,00000h
  2544.                         DW      00000h,00000h,00000h,0803fh,060c0h,01100h,00a00h
  2545.                         DW      00000h,00000h,00000h,0ff00h,00080h,00040h,00040h
  2546.  
  2547.                         DW      01005h,00804h,00802h,00402h,00401h,00201h,00200h
  2548.                         DW      00008h,0800ch,08003h,08000h,080c0h,04070h,0c04ch
  2549.                         DW      00280h,00140h,00140h,000a0h,00090h,00048h,00044h
  2550.                         DW      02809h,02809h,01809h,00c0ah,0040ah,00406h,00206h
  2551.                         DW      00002h,00002h,00001h,00600h,00500h,00780h,00000h
  2552.                         DW      0100fh,01009h,0100ah,0900ah,0900ah,0500ch,0300ch
  2553.                         DW      000a0h,000a0h,000a0h,000a0h,000c0h,000c0h,000c0h
  2554.                         DW      03ff2h,03f04h,00084h,00084h,0ff08h,08008h,0ffc8h
  2555.                         DW      001c0h,001c0h,00000h,00000h,003c0h,00240h,00440h
  2556.                         DW      00a07h,00a07h,03100h,040e0h,0201ch,017e6h,00818h
  2557.                         DW      0e040h,09f80h,07000h,00800h,00400h,00400h,00400h
  2558.  
  2559.                         DW      00100h,00100h,00080h,0007fh,00000h,00000h,00000h
  2560.                         DW      0a023h,06020h,06010h,09fe0h,00000h,00000h,00000h
  2561.                         DW      00022h,0c021h,03010h,00fe0h,00000h,00000h,00000h
  2562.                         DW      00004h,00004h,0c004h,03ffbh,00000h,00000h,00000h
  2563.                         DW      00000h,003e0h,00420h,0f81fh,00000h,00000h,00000h
  2564.                         DW      03000h,01000h,01000h,0efffh,00000h,00000h,00000h
  2565.                         DW      00140h,00680h,01880h,0e07fh,00000h,00000h,00000h
  2566.                         DW      00030h,00030h,00050h,0ff8fh,00000h,00000h,00000h
  2567.                         DW      00420h,00410h,00810h,0f00fh,00000h,00000h,00000h
  2568.                         DW      00800h,00800h,00c00h,0f3ffh,00000h,00000h,00000h
  2569.                         DW      00400h,00800h,07000h,08000h,00000h,00000h,00000h
  2570.  
  2571. LogoLetters             DW      00000h,00000h,00000h,00000h,00000h,00000h,00000h
  2572.                         DW      00000h,00000h,00000h,00000h,00000h,00000h,00000h
  2573.                         DW      00000h,00000h,007ffh,01fffh,03fffh,03f00h,03fc0h
  2574.                         DW      00000h,00000h,0e3ffh,0f3ffh,0fbffh,0f9f8h,001fch
  2575.                         DW      00000h,00000h,0f80fh,0fe1fh,0ff1fh,03f3fh,03f3eh
  2576.                         DW      00000h,00000h,0fc00h,0fe00h,0fe01h,0ff01h,07f03h
  2577.                         DW      00000h,00000h,01fffh,07fffh,0ff9fh,0ff1fh,0fe00h
  2578.                         DW      00000h,00000h,003ffh,087ffh,087ffh,08ff0h,00ff0h
  2579.                         DW      00000h,00000h,0ff80h,0ff80h,0ff00h,00000h,00000h
  2580.                         DW      00000h,00000h,00000h,00000h,00000h,00000h,00000h
  2581.                         DW      00000h,00000h,00000h,00000h,00000h,00000h,00000h
  2582.  
  2583.                         DW      00000h,00000h,00000h,00000h,00000h,00000h,00000h
  2584.                         DW      00000h,00000h,00000h,00000h,00000h,00000h,00000h
  2585.                         DW      01fffh,003ffh,00003h,00000h,00fc1h,00fffh,007ffh
  2586.                         DW      001ffh,0e0ffh,0f8fch,0fcfeh,0fc7eh,0fc7fh,0f83fh
  2587.                         DW      0fe7eh,0f87ch,000fch,000ffh,001ffh,001f8h,083f0h
  2588.                         DW      07f83h,03f87h,03fc7h,0ffc7h,0ffe7h,01fe7h,00ff3h
  2589.                         DW      0fe00h,0fc00h,0fc00h,0f800h,0fc7eh,0fffeh,0fffch
  2590.                         DW      01fffh,01fffh,03fc0h,03fc0h,07fc0h,07fffh,0ffffh
  2591.                         DW      0c000h,0c000h,00000h,00000h,00000h,0f000h,0f000h
  2592.                         DW      00000h,00000h,00000h,00000h,00000h,00000h,00000h
  2593.                         DW      00000h,00000h,00000h,00000h,00000h,00000h,00000h
  2594.  
  2595.                         DW      00000h,00000h,00000h,00000h,01fe0h,01ff0h,00ff0h
  2596.                         DW      00000h,00000h,00000h,00000h,0fc0fh,0ff0fh,0ffc7h
  2597.                         DW      000ffh,00000h,00000h,00000h,0f1feh,0f9ffh,0fcffh
  2598.                         DW      0c03fh,00000h,00000h,00000h,00fe0h,00fe0h,08fe0h
  2599.                         DW      083f0h,00000h,00000h,00000h,07fe0h,07ff0h,07ff8h
  2600.                         DW      00ff0h,00000h,00000h,00000h,00fffh,00fffh,00fffh
  2601.                         DW      0fff0h,00000h,00000h,00000h,0f80fh,0fe0fh,0ff0fh
  2602.                         DW      0ffffh,00000h,00000h,00000h,0fff8h,0fff8h,0fff1h
  2603.                         DW      0e000h,00000h,00000h,00000h,0ffffh,0ffffh,0ffffh
  2604.                         DW      00000h,00000h,00000h,00000h,0803fh,0e0ffh,0f1ffh
  2605.                         DW      00000h,00000h,00000h,00000h,0ff00h,0ff80h,0ff80h
  2606.  
  2607.                         DW      00ff8h,007f8h,007fch,003fch,003feh,001feh,001ffh
  2608.                         DW      0fff7h,07ff3h,07ffch,07fffh,07f3fh,03f8fh,03f83h
  2609.                         DW      0fc7fh,0fe3fh,0fe3fh,0ff1fh,0ff0fh,0ff87h,0ff83h
  2610.                         DW      0c7f0h,0c7f0h,0e7f0h,0f3f1h,0fbf1h,0fbf9h,0fdf9h
  2611.                         DW      0fffch,0fffch,0fffeh,0f9ffh,0f8ffh,0f87fh,0ffffh
  2612.                         DW      00ff0h,00ff0h,00ff1h,00ff1h,00ff1h,08ff3h,0cff3h
  2613.                         DW      0ff1fh,0ff1fh,0ff1fh,0ff1fh,0ff3fh,0ff3fh,0ff3fh
  2614.                         DW      0c001h,0c003h,0ff03h,0ff03h,00007h,00007h,00007h
  2615.                         DW      0fe3fh,0fe3fh,0ffffh,0ffffh,0fc3fh,0fc3fh,0f83fh
  2616.                         DW      0f1f8h,0f1f8h,0c0ffh,0801fh,0c003h,0e001h,0f7e7h
  2617.                         DW      01f80h,00000h,08000h,0f000h,0f800h,0f800h,0f800h
  2618.  
  2619.                         DW      000ffh,000ffh,0007fh,00000h,00000h,00000h,00000h
  2620.                         DW      01fc0h,09fc0h,09fe0h,00000h,00000h,00000h,00000h
  2621.                         DW      0ffc1h,03fc0h,00fe0h,00000h,00000h,00000h,00000h
  2622.                         DW      0fffbh,0fffbh,03ffbh,00000h,00000h,00000h,00000h
  2623.                         DW      0ffffh,0f81fh,0f81fh,00000h,00000h,00000h,00000h
  2624.                         DW      0cfffh,0efffh,0efffh,00000h,00000h,00000h,00000h
  2625.                         DW      0fe3fh,0f87fh,0e07fh,00000h,00000h,00000h,00000h
  2626.                         DW      0ffcfh,0ffcfh,0ff8fh,00000h,00000h,00000h,00000h
  2627.                         DW      0f81fh,0f80fh,0f00fh,00000h,00000h,00000h,00000h
  2628.                         DW      0f7ffh,0f7ffh,0f3ffh,00000h,00000h,00000h,00000h
  2629.                         DW      0f800h,0f000h,08000h,00000h,00000h,00000h,00000h
  2630.  
  2631. LogoShadow              DW      00000h,00000h,00000h,00000h,00000h,00000h,00000h
  2632.                         DW      00000h,00000h,00000h,00000h,00000h,00000h,00000h
  2633.                         DW      01fffh,07800h,0e000h,0c000h,08000h,00000h,00000h
  2634.                         DW      087ffh,00400h,00000h,00000h,00000h,00000h,00000h
  2635.                         DW      0f00fh,00410h,00000h,00000h,00000h,00000h,00000h
  2636.                         DW      0fc00h,00200h,00000h,00000h,00000h,00000h,00000h
  2637.                         DW      00fffh,02000h,08000h,00000h,00000h,00000h,00000h
  2638.                         DW      080ffh,0c000h,04000h,00000h,00000h,00000h,00000h
  2639.                         DW      0ffe0h,00060h,00000h,00000h,00000h,00000h,03000h
  2640.                         DW      00000h,00000h,00000h,00000h,00000h,00000h,00000h
  2641.                         DW      00000h,00000h,00000h,00000h,00000h,00000h,00000h
  2642.  
  2643.                         DW      00000h,00000h,00000h,00000h,00000h,00000h,00000h
  2644.                         DW      00000h,00000h,00000h,00000h,00000h,00000h,00000h
  2645.                         DW      00000h,00000h,03c00h,0303ch,00000h,00000h,00000h
  2646.                         DW      00000h,00000h,00000h,00000h,00000h,00000h,00000h
  2647.                         DW      00000h,00001h,00000h,00000h,00000h,00000h,00000h
  2648.                         DW      00000h,08000h,00000h,00000h,00000h,00000h,00000h
  2649.                         DW      00000h,00000h,0003fh,00381h,00000h,00000h,00000h
  2650.                         DW      00000h,00000h,00000h,0001fh,00000h,00000h,00000h
  2651.                         DW      00000h,00000h,00000h,0fc00h,00c00h,00000h,00000h
  2652.                         DW      00000h,00000h,00000h,00000h,00000h,00000h,00000h
  2653.                         DW      00000h,00000h,00000h,00000h,00000h,00000h,00000h
  2654.  
  2655.                         DW      00000h,00000h,0ff03h,0e003h,04002h,04002h,02000h
  2656.                         DW      00000h,00000h,0f03fh,00030h,00000h,00000h,00000h
  2657.                         DW      00000h,00000h,0c3fch,00200h,00000h,00000h,00000h
  2658.                         DW      00000h,00000h,01fc0h,01000h,00000h,00000h,00000h
  2659.                         DW      00000h,00000h,07fe0h,00010h,00008h,00004h,00000h
  2660.                         DW      00000h,00000h,00fffh,00000h,00000h,00000h,00000h
  2661.                         DW      00000h,00000h,0f807h,00600h,00100h,00000h,00000h
  2662.                         DW      00000h,00000h,0fffch,00004h,00000h,00000h,00000h
  2663.                         DW      00000h,00000h,03fffh,00000h,00000h,00000h,00000h
  2664.                         DW      00000h,00000h,0e007h,07800h,01c00h,00c00h,00400h
  2665.                         DW      00000h,00000h,0ffe0h,000f0h,00070h,00030h,00000h
  2666.  
  2667.                         DW      02000h,01001h,01001h,00800h,00800h,00400h,00400h
  2668.                         DW      00000h,00000h,00000h,00000h,00000h,00000h,00000h
  2669.                         DW      00000h,00000h,00000h,00000h,00000h,00000h,00000h
  2670.                         DW      00000h,00000h,00000h,00000h,00000h,00000h,00000h
  2671.                         DW      00000h,00001h,00000h,00000h,00200h,00000h,00000h
  2672.                         DW      00000h,00000h,00000h,00000h,04000h,00000h,00000h
  2673.                         DW      00000h,00000h,00000h,00000h,00000h,00000h,00000h
  2674.                         DW      00000h,00080h,00000h,00000h,00000h,07fe0h,00020h
  2675.                         DW      00000h,00000h,00000h,00000h,00000h,00000h,00200h
  2676.                         DW      00000h,00000h,00000h,03800h,01ce0h,00818h,00000h
  2677.                         DW      00000h,06000h,00f00h,00700h,00300h,00300h,00200h
  2678.  
  2679.                         DW      00200h,00000h,00000h,00000h,00000h,00000h,00000h
  2680.                         DW      04000h,00000h,00000h,00000h,00000h,00000h,00000h
  2681.                         DW      00000h,00000h,00000h,00000h,00000h,00000h,00000h
  2682.                         DW      00000h,00000h,00000h,00000h,00000h,00000h,00000h
  2683.                         DW      00000h,00000h,00000h,00000h,00000h,00000h,00000h
  2684.                         DW      00000h,00000h,00000h,00000h,00000h,00000h,00000h
  2685.                         DW      00000h,00000h,00000h,00000h,00000h,00000h,00000h
  2686.                         DW      00000h,00000h,00000h,00000h,00000h,00000h,00000h
  2687.                         DW      00000h,00000h,00000h,00000h,00000h,00000h,00000h
  2688.                         DW      00000h,00000h,00000h,00000h,00000h,00000h,00000h
  2689.                         DW      00000h,00000h,00000h,00000h,00000h,00000h,00000h
  2690.  
  2691. ;----------------------------------------------------------------------------------------------------------------------------------
  2692. ; Variables
  2693. ;----------------------------------------------------------------------------------------------------------------------------------
  2694.  
  2695. GameStart               DB      0
  2696. Frame                   DB      0
  2697. InvadersX               DW      275
  2698. InvadersY               DB      30
  2699. InvadersToggle          DW      07ff0h,07ff0h,07ff0h,07ff0h,07ff0h
  2700. PlayerX                 DW      154
  2701. LeftToggle              DB      0
  2702. RightToggle             DB      0
  2703. FireToggle              DB      0
  2704. ExitToggle              DB      0
  2705. SoundToggle             DB      0
  2706. KeyPress                DB      0
  2707. Sound                   DB      080h
  2708. NextLevelToggle         DB      0
  2709. MissileX                DW      0
  2710. MissileY                DB      0
  2711. UFOX                    DW      0
  2712. BombX                   DW      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  2713. BombY                   DB      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  2714. BombType                DB      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  2715. BombFreq                DW      010h
  2716. MoveCount               DB      1
  2717. InvaderSpeed            DB      55
  2718. Direction               DB      0
  2719. Reversing               DB      0
  2720. Collision               DB      0
  2721. Score                   DB      48,48,48,48,48
  2722. FirstFrame              DB      0
  2723. Lives                   DB      51
  2724. BombMove                DB      2
  2725. BombSpeed               DB      2
  2726. PlayerDead              DB      0
  2727. GameOverToggle          DB      0
  2728. InvadersTitle           DB      "S  P  A  C  E     I  N  V  A  D  E  R  S",0
  2729. Copyright               DB      "COPYRIGHT (  1995 BY PAUL S. REID",0
  2730. Rights                  DB      "ALL RIGHTS RESERVED.",0
  2731. UFOScore                DB      "=   100 POINTS",0
  2732. Row1Score               DB      "=    25 POINTS",0
  2733. Row2Score               DB      "=    20 POINTS",0
  2734. Row3Score               DB      "=    15 POINTS",0
  2735. Row4Score               DB      "=    10 POINTS",0
  2736. Row5Score               DB      "=     5 POINTS",0
  2737. StartDocs               DB      "PRESS ANY KEY TO START GAME",0
  2738. ExitDocs                DB      "PRESS ESC AT ANY TIME TO EXIT TO DOS",0
  2739. Dedication              DB      "...DEDICATED TO MY WIFE DEB...",0
  2740. ThankYou                DB      "THANKS TO BRENT KYLE AND TOM SWAN",0
  2741. SoundTog                DB      "PRESS S TO TOGGLE SOUND AT ANY TIME",0
  2742. PlayKeys                DB      "LEFT AND RIGHT CURSOR TO MOVE. CTRL TO FIRE",0
  2743. Distribution            DB      ".THIS GAME AND SOURCE CODE ARE FREELY DISTRIBUTABLE.",0
  2744. GameOverMsg             DB      "G  A  M  E      O  V  E  R",0
  2745. GetReady                DB      "G  E  T      R  E  A  D  Y",0
  2746. TempStore               DW      0
  2747. Palette                 DB      00,00,00    ; Background
  2748.                         DB      21,63,63    ; Player's Ship
  2749.                         DB      63,21,21    ; Bunker
  2750.                         DB      63,21,21    ; UFO
  2751.                         DB      63,63,63    ; Missiles
  2752.                         DB      21,63,21    ; Status Letters
  2753.                         DB      63,63,00    ; Bombs
  2754.                         DB      63,63,63    ; DOS text (just for diagnostic printing if required)
  2755.                         DB      12,00,21    ; Top and bottom border backgrounds
  2756.                         DB      33,00,42    ; Logo shadow color
  2757.                         DB      00,00,00    ; Logo outline color
  2758.                         DB      63,63,00    ; Logo letters color
  2759.                         DB      41,41,41    ; Logo stars
  2760.                         DB      00,00,00
  2761.                         DB      00,00,00
  2762.                         DB      00,00,00
  2763.                         DB      21,63,21    ; Row 1 invader 1
  2764.                         DB      21,63,21    ; Row 1 invader 2
  2765.                         DB      21,63,21    ; Row 1 invader 3
  2766.                         DB      21,63,21    ; Row 1 invader 4
  2767.                         DB      21,63,21    ; Row 1 invader 5
  2768.                         DB      21,63,21    ; Row 1 invader 6
  2769.                         DB      21,63,21    ; Row 1 invader 7
  2770.                         DB      21,63,21    ; Row 1 invader 8
  2771.                         DB      21,63,21    ; Row 1 invader 9
  2772.                         DB      21,63,21    ; Row 1 invader 10
  2773.                         DB      21,63,21    ; Row 1 invader 11
  2774.                         DB      00,00,00
  2775.                         DB      00,00,00
  2776.                         DB      00,00,00
  2777.                         DB      00,00,00
  2778.                         DB      00,00,00
  2779.                         DB      21,63,21    ; Row 2 invader 1
  2780.                         DB      21,63,21    ; Row 2 invader 2
  2781.                         DB      21,63,21    ; Row 2 invader 3
  2782.                         DB      21,63,21    ; Row 2 invader 4
  2783.                         DB      21,63,21    ; Row 2 invader 5
  2784.                         DB      21,63,21    ; Row 2 invader 6
  2785.                         DB      21,63,21    ; Row 2 invader 7
  2786.                         DB      21,63,21    ; Row 2 invader 8
  2787.                         DB      21,63,21    ; Row 2 invader 9
  2788.                         DB      21,63,21    ; Row 2 invader 10
  2789.                         DB      21,63,21    ; Row 2 invader 11
  2790.                         DB      00,00,00
  2791.                         DB      00,00,00
  2792.                         DB      00,00,00
  2793.                         DB      00,00,00
  2794.                         DB      00,00,00
  2795.                         DB      21,63,63    ; Row 3 invader 1
  2796.                         DB      21,63,63    ; Row 3 invader 2
  2797.                         DB      21,63,63    ; Row 3 invader 3
  2798.                         DB      21,63,63    ; Row 3 invader 4
  2799.                         DB      21,63,63    ; Row 3 invader 5
  2800.                         DB      21,63,63    ; Row 3 invader 6
  2801.                         DB      21,63,63    ; Row 3 invader 7
  2802.                         DB      21,63,63    ; Row 3 invader 8
  2803.                         DB      21,63,63    ; Row 3 invader 9
  2804.                         DB      21,63,63    ; Row 3 invader 10
  2805.                         DB      21,63,63    ; Row 3 invader 11
  2806.                         DB      00,00,00
  2807.                         DB      00,00,00
  2808.                         DB      00,00,00
  2809.                         DB      00,00,00
  2810.                         DB      00,00,00
  2811.                         DB      21,63,63    ; Row 4 invader 1
  2812.                         DB      21,63,63    ; Row 4 invader 2
  2813.                         DB      21,63,63    ; Row 4 invader 3
  2814.                         DB      21,63,63    ; Row 4 invader 4
  2815.                         DB      21,63,63    ; Row 4 invader 5
  2816.                         DB      21,63,63    ; Row 4 invader 6
  2817.                         DB      21,63,63    ; Row 4 invader 7
  2818.                         DB      21,63,63    ; Row 4 invader 8
  2819.                         DB      21,63,63    ; Row 4 invader 9
  2820.                         DB      21,63,63    ; Row 4 invader 10
  2821.                         DB      21,63,63    ; Row 4 invader 11
  2822.                         DB      00,00,00
  2823.                         DB      00,00,00
  2824.                         DB      00,00,00
  2825.                         DB      00,00,00
  2826.                         DB      00,00,00
  2827.                         DB      63,21,63    ; Row 5 invader 1
  2828.                         DB      63,21,63    ; Row 5 invader 2
  2829.                         DB      63,21,63    ; Row 5 invader 3
  2830.                         DB      63,21,63    ; Row 5 invader 4
  2831.                         DB      63,21,63    ; Row 5 invader 5
  2832.                         DB      63,21,63    ; Row 5 invader 6
  2833.                         DB      63,21,63    ; Row 5 invader 7
  2834.                         DB      63,21,63    ; Row 5 invader 8
  2835.                         DB      63,21,63    ; Row 5 invader 9
  2836.                         DB      63,21,63    ; Row 5 invader 10
  2837.                         DB      63,21,63    ; Row 5 invader 11
  2838.  
  2839. VideoBuffer             DB      0
  2840.  
  2841. CODE_SEG                ENDS
  2842.  
  2843.                         END     BEGIN
  2844.