home *** CD-ROM | disk | FTP | other *** search
/ BUG 15 / BUGCD1998_06.ISO / zabava / invaders / invaders.asm < prev    next >
Assembly Source File  |  1998-05-13  |  138KB  |  2,957 lines

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