;*************************** AMUS Program Label ******************************
; Filename: BUGS.LIT                                        Date: 9/10/90
; Category: GAME         Hash Code:                      Version: 1.0
; Initials: DECO         Name: ROB NEWMAN
; Company: DECO-CHEM,INC.                          Telephone #: 2192593787
; Related Files: NONE
; Min. Op. Sys.: AMOS                          Expertise Level: INT
; Special: Best on AM62 or >. 19200 baud
; Description: Shoot'em Up game. Kill the nasty bugs.
;
;
;*****************************************************************************
;*; Updated on 10-Sep-90 at 11:41 AM by ; edit time: 9:19:35
;*; Created on 06-Sep-90 at 8:38 AM by ; edit time: 0:07:29
;
;   This is my first assembly program over 20 lines.
;   I down-loaded Dave Pallmens `Space Invaders' and studied the code.
;   I also down-loaded all of the aa?.txt text files on assembly.
;   With these in hand, I created `BUGS'.
;   The code may not be well structured, but it's a start.
;   I commented most commands, so some else might be able to learn a
;   little assembly. ( I wouldn't use my code for reference,
;   like I said, this is my FIRST major assembly program.)
;
;             Good Luck, I hope `BUGS' is enjoyable for you.
;
;   p.s. when you shoot your walls, they are erased from the screen, but not
;        from memory. I was going to take care of that, but its a nice little
;        touch to confuse the player.
;


       OBJNAM  BUGS.LIT

       VMAJOR=1
       VMINOR=0

       SEARCH  SYS
       SEARCH  SYSSYM
       SEARCH  TRM

       MEM=A5

       WIDTH=80.

       .OFINI
       .OFDEF  BVER1,1                 ; version of bug to draw
       .OFDEF  BVER2,1
       .OFDEF  SCORE,4                 ; score
       .OFDEF  MSLINC,1                ; missle delay increment
       .OFDEF  BUG1,1                  ; bug1 location
       .OFDEF  BDIR1,1                 ; bug1 direction
       .OFDEF  BUG2,1                  ; bug2 location
       .OFDEF  BDIR2,1                 ; bug2 direction
       .OFDEF  MSLCNT,1                ;
       .OFDEF  AXIS,1                  ; vertical location of gun
       .OFDEF  MAXIS,1                 ; vertical location of gun
       .OFDEF  ROW,1                   ; print tab
       .OFDEF  COL,1                   ; print tab
       .OFDEF  POS,1
       .OFDEF  MROW,1                  ; missle row
       .OFDEF  MCOL,1                  ; missle column
       .OFDEF  LIVES,3                 ; waffers left
       .OFDEF  LLOC1,1                 ; left walls 1
       .OFDEF  RLOC1,1                 ; right walls 1
       .OFDEF  LLOC2,1                 ; left walls 2
       .OFDEF  RLOC2,1                 ; right walls 2
       .OFDEF  BCNT1,2
       .OFDEF  BCNT2,2
       .OFDEF  DLY,1                   ; delay loop
       .OFDEF  BLIVS,1                 ; # bugs in wave
       .OFDEF  NUMBUG,1                ; number of bugs to start with
       .OFDEF  DLYINC,1                ;
;       .OFDEF  DLYTIM,1
       .OFSIZ  MEMSIZ

DEFINE  CURSOR  ROW,COL
       CLRW    D1
       MOVB    ROW,D1
       ROLW    D1,#8.
       ADDB    COL,D1
       TCRT
       ENDM

DEFINE  TCALL   CODE
       MOVW    #-1_8.+CODE'.,D1
       TCRT
       ENDM

DEFINE  CLS=TCALL 0                     ;
DEFINE  ON=TCALL 28
DEFINE  OFF=TCALL 29

START:  PHDR    -1,0,PH$REE!PH$REU
       GETIMP  MEMSIZ,MEM
       CTRLC   FINISH

CHECK:
       LIN
       BEQ     NEW
       JMP     HELP

NEW:    MOVB    #4,LIVES(MEM)
       MOVB    #10.,NUMBUG(MEM)
       MOVB    NUMBUG(MEM),BLIVS(MEM)
       MOVB    #5.,DLYINC(MEM)
SETUP:  CLRB    AXIS(MEM)
       CLRB    MAXIS(MEM)
       MOVB    #200.,MSLINC(MEM)
       MOVB    MSLINC(MEM),MSLCNT(MEM)
       CLRB    BUG1(MEM)
       SETB    BDIR1(MEM)
       CLRB    BUG2(MEM)
       CLRB    BDIR2(MEM)
       MOVB    #35.,LLOC1(MEM)
       MOVB    #47.,RLOC1(MEM)
       MOVB    #35.,LLOC2(MEM)
       MOVB    #47.,RLOC2(MEM)
       MOVB    #999.,BCNT1(MEM)
       MOVB    #999.,BCNT2(MEM)
       MOVB    DLYINC(MEM),DLY(MEM)

TERM:   JOBIDX  A0
       MOV     JOBTRM(A0),A1
       ORW     #T$IMI!T$ECS,T.STS(A1)
       OFF

NEWSET:
       CLRB    MROW(MEM)
       CLS
       TYPE    <Waffers:>
       CURSOR  #12.,#1
       TYPE    <============================================================================>
       CURSOR  #11.,#43
       TYPE    <[[[[[#]]]]]>
       CURSOR  #13.,#43
       TYPE    <[[[[[#]]]]]>
       CURSOR  #24.,#1
       CURSOR  #1.,#14
       CLR     D0
       MOVB    LIVES(MEM),D0           ; get # of lives an put in d0
10$:    TYPESP  #                       ; print loop of extra men
       SOB     D0,10$                  ; if more men, loop to 10$
       CALL    DISCOR

BASE:   MOVB    #41.,POS(MEM)           ; set laser base to column 41
       CALL    BOTDRW                  ; draw laser subroutine

MAIN:   CTRLC   FINISH
       CALL    CHKCMD                  ; check for keyboard
       CALL    MISSIL                  ; move missle
       DECB    DLY(MEM)
       BNE     10$
       CALL    MOVBUG                  ; call move bug
       CALL    MOVBG2
       MOVB    DLYINC(MEM),DLY(MEM)
10$:    JMP     MAIN

MOVBUG:
       TSTB    BUG1(MEM)               ; is bug1 active
       BNE     BUGCNT                  ; yes - branch
       TSTB    BDIR1(MEM)
       BEQ     10$
       MOVB    #5.,BUG1(MEM)
       CALL    DRWBUG
       RTN
10$:
       MOVB    #75.,BUG1(MEM)          ; no - display new bug
       CALL    DRWBUG                  ; draw bug
       RTN                             ; return
BUGCNT:
       DECB    BCNT1(MEM)              ; deincrement bug display count
       BEQ     10$                     ; is count = 0
       RTN                             ; no - return
10$:
       MOVB    #999.,BCNT1(MEM)                ; yes - reset counter
       TSTB    BDIR1(MEM)              ; is bugdir = 0 (left)
       BEQ     BUGLFT                  ; yes - branch
BUGRHT:
       INCB    BUG1(MEM)               ; add 1 to bug1 position
       CMMB    BUG1(MEM),#WIDTH-5      ; is bug at right of screen
       BGT     20$                     ; yes - branch
       MOVB    BUG1(MEM),D3            ; move bug location
       CMPB    D3,#50                  ; is bug to center
       BEQ     30$
       CMMB    D3,LLOC1(MEM)           ; has bug hit wall
       BNE     10$                     ; no - branch
       CLRB    BDIR1(MEM)              ; set bugdir = 0 (left)
       INCB    LLOC1(MEM)
       JMP     BUGLFT                  ; branch
10$:
       CALL    DRWBUG                  ; draw new bug location
       RTN                             ; return
20$:    CALL    CLRBUG                  ; erase and
       CLRB    BUG1(MEM)               ; clear bug
       RTN                             ; return
30$:    JMP     CAUGHT

BUGLFT:
       DECB    BUG1(MEM)               ; sub 1 from bug1 position
       CMMB    BUG1(MEM),#5            ; is bug at left of screen
       BLT     20$                     ; yes - branch
       CMPB    BUG1(MEM),#52           ; is bug to center
       BEQ     30$
       CMMB    BUG1(MEM),RLOC1(MEM)    ; has bug hit wall
       BNE     10$                     ; no - branch
       SETB    BDIR1(MEM)              ; set bugdir = 0 (left)
       DECB    RLOC1(MEM)
       JMP     BUGRHT                  ; branch
10$:
       CALL    DRWBUG                  ; draw new bug location
       RTN                             ; return
20$:    CALL    CLRBUG                  ; erase and
       CLRB    BUG1(MEM)               ; clear bug
       RTN
30$:    JMP     CAUGHT

MOVBG2:
       TSTB    BUG2(MEM)               ; is bug1 active
       BNE     BGCNT2                  ; yes - branch
       TSTB    BDIR2(MEM)
       BEQ     10$
       MOVB    #5.,BUG2(MEM)
       CALL    DRWBG2
       RTN
10$:
       MOVB    #75.,BUG2(MEM)          ; no - display new bug
       CALL    DRWBG2                  ; draw bug
       RTN                             ; return
BGCNT2:
       DECB    BCNT2(MEM)              ; deincrement bug display count
       BEQ     10$                     ; is count = 0
       RTN                             ; no - return
10$:
       MOVB    #999.,BCNT2(MEM)                ; yes - reset counter
       TSTB    BDIR2(MEM)              ; is bugdir = 0 (left)
       BEQ     BGLFT2                  ; yes - branch
BGRHT2:
       INCB    BUG2(MEM)               ; add 1 to bug1 position
       CMMB    BUG2(MEM),#WIDTH-5      ; is bug at right of screen
       BGT     20$                     ; yes - branch
       MOVB    BUG2(MEM),D3            ; move bug location
       CMPB    D3,#50                  ; is bug to center
       BEQ     30$
       CMMB    D3,LLOC2(MEM)           ; has bug hit wall
       BNE     10$                     ; no - branch
       CLRB    BDIR2(MEM)              ; set bugdir = 0 (left)
       INCB    LLOC2(MEM)
       JMP     BGLFT2                  ; branch
10$:
       CALL    DRWBG2                  ; draw new bug location
       RTN                             ; return
20$:    CALL    CLRBG2                  ; erase and
       CLRB    BUG2(MEM)               ; clear bug
       RTN                             ; return
30$:    JMP     CAUGHT

BGLFT2:
       DECB    BUG2(MEM)               ; sub 1 from bug1 position
       CMMB    BUG2(MEM),#5            ; is bug at left of screen
       BLT     20$                     ; yes - branch
       CMPB    BUG2(MEM),#52           ; is bug to center
       BEQ     30$
       CMMB    BUG2(MEM),RLOC2(MEM)    ; has bug hit wall
       BNE     10$                     ; no - branch
       SETB    BDIR2(MEM)              ; set bugdir = 0 (left)
       DECB    RLOC2(MEM)
       JMP     BGRHT2                  ; branch
10$:
       CALL    DRWBG2                  ; draw new bug location
       RTN                             ; return
20$:    CALL    CLRBG2                  ; erase and
       CLRB    BUG2(MEM)               ; clear bug
       RTN
30$:    JMP     CAUGHT

CHKCMD: TCKI                            ; was a key hit
       BEQ     10$                     ; branch if yes
       RTN                             ; return if no
10$:    KBD     FINISH                  ; char into d1 (goto finish on ^c)
       CMPB    D1,#'H-'@               ; branch if ^h (left)
       BEQ     MOVLFT
       CMPB    D1,#'L-'@               ; branch if ^l (right)
       BEQ     MOVRHT
       CMPB    D1,#'K-'@               ; branch if ^k (up)
       BEQ     ONTOP
       CMPB    D1,#'J-'@               ; branch if ^j (down)
       BEQ     ONBOT
       CMPB    D1,#40                  ; branch if space-bar
       JEQ     FIRE
       RTN                             ; ignore char and return

ONTOP:
       MOVB    #1,AXIS(MEM)
       CALL    BOTCLR
       CALL    TOPDRW
       RTN
ONBOT:
       CLRB    AXIS(MEM)
       CALL    TOPCLR
       CALL    BOTDRW
       RTN

MOVLFT: CMPB    AXIS(MEM),#1
       BEQ     TOPLFT

BOTLFT: CMPB    POS(MEM),#5             ; is base at extreme left ?
       BLE     ONTOP                   ; yes - branch
       SUBB    #2,POS(MEM)             ; move 2 columns left
       CALL    BOTDRW
10$:    RTN

TOPLFT: CMPB    POS(MEM),#WIDTH-5       ; is base at extreme right?
       BGE     ONBOT                   ; yes - branch
       ADDB    #2,POS(MEM)             ; move 2 columns right
       CALL    TOPDRW
10$:    RTN

MOVRHT: CMPB    AXIS(MEM),#1
       BEQ     TOPRHT

BOTRHT: CMPB    POS(MEM),#WIDTH-5       ; is base at extreme right.
       BGE     ONTOP                   ; yes
       ADDB    #2,POS(MEM)             ; no, move 2 columns right
       CALL    BOTDRW
10$:    RTN

TOPRHT: CMPB    POS(MEM),#5             ; is base at extreme right.
       BLE     ONBOT                   ; yes
       SUBB    #2,POS(MEM)             ; no, move 2 columns right
       CALL    TOPDRW
10$:    RTN

FIRE:   TSTB    MROW(MEM)               ; missle in air.
       BEQ     10$                     ; no - branch
       RTN                             ; yes
10$:
       CMPB    AXIS(MEM),#1
       BEQ     FIRET

FIREB:
       CLRB    MAXIS(MEM)
       MOVB    #22.,MROW(MEM)          ; start missle at row 22
       MOVB    POS(MEM),MCOL(MEM)      ; set missle col. to base col.
       CALL    DRWMSL
       RTN

FIRET:
       MOVB    #1.,MAXIS(MEM)
       MOVB    #3.,MROW(MEM)           ; start missle at row 3
       MOVB    POS(MEM),MCOL(MEM)      ; set missle col. to base col.
       CALL    DRWMSL
       RTN

MISSIL:
       TSTB    MROW(MEM)               ; is m. on screen
       BEQ     UPRTN                   ;
       DECB    MSLCNT(MEM)
       BEQ     10$
       RTN
10$:
       MOVB    MSLINC(MEM),MSLCNT(MEM)
       CMPB    MAXIS(MEM),#1
       BEQ     MISDW

MISUP:
       CALL    CLRMSL                  ; erase m. from position
       DECB    MROW(MEM)               ; move m. 1 row up
       CMMB    MROW(MEM),#14           ; is m. at top
       BEQ     BUGCHK                  ; yes - check for bugs.
       CALL    DRWMSL                  ; no - draw m.
UPRTN:
       RTN

MISDW:
       CALL    CLRMSL                  ; erase m. from position
       INCB    MROW(MEM)               ; move m. 1 row down
       CMMB    MROW(MEM),#14           ; is m. at bottom
       BEQ     BUGCHK                  ; yes - check for bugs.
       CALL    DRWMSL                  ; no - draw m.
DWRTN:
       RTN

BUGCHK:
       CALL    MSLBUG
       CLRB    MROW(MEM)
       RTN
MSLBUG:
       TSTB    MROW(MEM)               ; is missle active
       BEQ     20$                     ; no - branch
       CLR     D2                      ; clear d2
       TSTB    MAXIS(MEM)              ; is missle on top or bottom
       BEQ     MSLBG1                  ; top - branch
       MOVB    BUG2(MEM),D2            ;
       SUBB    #2.,D2                  ; set location a of bug2
       MOVB    D2,D3                   ;
       ADDB    #2,D3                   ; set location b of bug2
       CMMB    MCOL(MEM),D2            ; is missle right of bug2
       BLT     20$                     ; yes - branch
       CMMB    MCOL(MEM),D3            ; is missle left of 2
       BGT     20$                     ; yes - branch
       CALL    HITBG2                  ; missle hit bug2
       SLEEP   #300.                   ; pause
       CALL    CLRBG2                  ; clear bug2 from screen
       CLR     D7                      ; move point value
       MOVW    #100.,D7                ; into d7
       ADD     D7,SCORE(MEM)           ; and add to score
       CALL    DISCOR                  ; display score
       CLRB    BUG2(MEM)               ; clear bug2 location
       CLRB    MROW(MEM)               ; clear missle location
       DECB    BLIVS(MEM)              ; sub 1 from # of bugs left in wave
       TSTB    BLIVS(MEM)              ; is wave cleared
       BEQ     ENDWAV                  ; yes - branch
       TSTB    BDIR2(MEM)              ; set new bug2 direction
       BEQ     10$                     ; "   "       "
       CLRB    BDIR2(MEM)              ; senew bug direction
       RTN                             ; return
10$:    SETB    BDIR2(MEM)              ;sett new bug direction
20$:    RTN

MSLBG1:
       TSTB    MROW(MEM)               ; is missle active
       BEQ     20$                     ; no - branch
       MOVB    BUG1(MEM),D2            ; set d2 = bug1 location
       SUBB    #2.,D2                  ; set bug location a
       MOVB    D2,D3                   ; set bug1
       ADDB    #2,D3                   ; location b
       CMMB    MCOL(MEM),D2            ; is missle left of bug
       BLT     20$                     ; yes - branch
       CMMB    MCOL(MEM),D3            ; is missle right of branch
       BGT     20$                     ; yes - branch
       CALL    HITBUG                  ; display hit
       SLEEP   #300.                   ; pausee
       CALL    CLRBUG                  ; clear bug
       CLR     D7                      ; move
       MOVW    #100.,D7                ; point value into d7
       ADD     D7,SCORE(MEM)           ; add to score
       CALL    DISCOR                  ; display score
       CLRB    BUG1(MEM)               ; clear bug1 location
       CLRB    MROW(MEM)               ; clear missle location
       DECB    BLIVS(MEM)              ; sub 1 from bug lives
       TSTB    BLIVS(MEM)              ; is the wave cleared
       BEQ     ENDWAV                  ; yes - branch
       TSTB    BDIR1(MEM)              ; set new
       BEQ     10$                     ; bug direction
       CLRB    BDIR1(MEM)
       RTN                             ; return
10$:    SETB    BDIR1(MEM)              ; set new bug direction
20$:    RTN

ENDWAV:
       CLS
       ADDB    #5.,NUMBUG(MEM)
       MOVB    NUMBUG(MEM),BLIVS(MEM)
       CLRB    BUG1(MEM)
       CLRB    BDIR1(MEM)
       CLRB    BUG2(MEM)
       CLRB    BDIR2(MEM)
       CURSOR  #15.,#36
       TYPECR  <You Have Cleared This Wave.>
       CURSOR  #16.,#36
       TYPECR  < You receive Bonus Points.>
       ADD     #500.,SCORE(MEM)
       SLEEP   #20000.
       CLS
;       TSTB    DLYTIM(MEM)             ; time to increment delay loop.
;       BEQ     10$                     ; no
       CMPB    DLYINC(MEM),#1.         ; is dlyinc already 1
       BEQ     10$                     ; yes - branch
       DECB    DLYINC(MEM)
;       CLRB    DLYTIM(MEM)
       JMP     20$
10$:
;       SETB    DLYTIM(MEM)
20$:    JMP     SETUP

CAUGHT:
       SLEEP   #5000.
       MOVB    LIVES(MEM),D3
       DECB    LIVES(MEM)
       MUL     D3,#2
       ADDB    #12,D3
       CURSOR  #1,D3
       TYPE    < >
       CALL    CLRBUG
       CALL    CLRBG2
       CURSOR  #13.,#43
       TYPE    <[[[[[#]]]]]>
       CURSOR  #11.,#43
       TYPE    <[[[[[#]]]]]>
       CLRB    BUG1(MEM)
       CLRB    BDIR1(MEM)
       MOVB    #35.,LLOC1(MEM)
       MOVB    #47.,RLOC1(MEM)
       CLRB    BUG2(MEM)
       CLRB    BDIR2(MEM)
       MOVB    #35.,LLOC2(MEM)
       MOVB    #47.,RLOC2(MEM)
       TSTB    MROW(MEM)
       BEQ     10$
       CLRB    MROW(MEM)
       CLRB    MCOL(MEM)
       CALL    CLRMSL
10$:    RTN
30$:    JMP     GAMOVR


GAMOVR:
       CURSOR  #18.,#36
       TYPE    <GAME OVER>
       JMP     FINISH

FINISH: JOBIDX  A0
       ANDW    #^C<J.CCC>,JOBSTS(A0)
       CURSOR  #23.,#1
       ON
       CRLF
       CLS
       EXIT

DRWMSL:
       CURSOR  MROW(MEM),MCOL(MEM)
       TYPE    *
       RTN

CLRMSL: CURSOR  MROW(MEM),MCOL(MEM)
       TYPE    < >
       RTN

BOTDRW: MOVB    POS(MEM),D7
       SUBB    #3,D7
       CURSOR  #23.,D7
       TYPE    <  +^+  >
       RTN

BOTCLR: MOVB    POS(MEM),D7
       SUBB    #3,D7
       CURSOR  #23.,D7
       TYPE    <       >
       RTN
TOPDRW: MOVB    POS(MEM),D7
       SUBB    #3,D7
       CURSOR  #2.,D7
       TYPE    <  +v+  >
       RTN
TOPCLR: MOVB    POS(MEM),D7
       SUBB    #3,D7
       CURSOR  #2.,D7
       TYPE    <       >
       RTN

DRWBUG:
       TSTB    BVER1(MEM)
       BEQ     10$
       MOVB    BUG1(MEM),D7
       SUBB    #3,D7
       CURSOR  #13.,D7
       TYPE    < #X# >
       CLRB    BVER1(MEM)
       RTN
10$:
       MOVB    BUG1(MEM),D7
       SUBB    #3,D7
       CURSOR  #13.,D7
       TYPE    < X#X >
       SETB    BVER1(MEM)
       RTN
CLRBUG:
       MOVB    BUG1(MEM),D7
       SUBB    #3,D7
       CURSOR  #13.,D7
       TYPE    <     >
       RTN
HITBUG:
       TTYI
       BYTE    7,0
       MOVB    BUG1(MEM),D7
       SUBB    #3,D7
       CURSOR  #13.,D7
       TYPE    < bang >
       RTN
DRWBG2:
       TSTB    BVER1(MEM)
       BEQ     10$
       MOVB    BUG2(MEM),D7
       SUBB    #3,D7
       CURSOR  #11.,D7
       TYPE    < |*\ >
       CLRB    BVER2(MEM)
       RTN
10$:
       MOVB    BUG2(MEM),D7
       SUBB    #3,D7
       CURSOR  #11.,D7
       TYPE    < \*| >
       SETB    BVER2(MEM)
       RTN

CLRBG2:
       MOVB    BUG2(MEM),D7
       SUBB    #3,D7
       CURSOR  #11.,D7
       TYPE    <     >
       RTN
HITBG2:
       MOVB    BUG2(MEM),D7
       SUBB    #3,D7
       CURSOR  #11.,D7
       TYPE    < bang >
       RTN
DISCOR:
       CURSOR  #1,#WIDTH-10.
       MOV     SCORE(MEM),D1
       DCVT    9.,OT$TRM!OT$ZER
       RTN
HELP:
       CLS
       TYPECR  <                                 BUGS>
       TYPECR  <                               -------->
       CURSOR  #5.,#1
       TYPECR  <   You must defend your waffers (cracker typecr food) from those nasty bugs.>
       TYPECR  <   Kill all bugs in each wave to receive an added bonus.>
       CURSOR  #9.,#1
       TYPECR  <         Up Arrow or CTRL-K = Position Fighter at top.>
       TYPECR  <         Down Arrow or CTRL-J = Position Fighter at bottom.>
       TYPECR  <         Left Arrow = Move Fighter Left if on bottom or vice versa for top.>
       TYPECR  <         Right Arrow = Move Fighter Right if on bottom or vice versa on top.>
       TYPECR  <         Space-Bar = Fire a Missle (Top or Bottom).>
       CURSOR  #15.,1
       TYPECR  < >
       TYPECR  <                     |*\ - Spider     =   100>
       TYPECR  <                     ##: - Centapede  =   5000>
       CURSOR  #23.,1
       TYPECR  <                     Hit Any Key>
10$:    TCKI
       BEQ     20$
       JMP     10$
20$:
       JMP     FINISH

       END