home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / BEERSRC.ZIP / GAMEASM.ASM < prev    next >
Encoding:
Assembly Source File  |  1993-12-27  |  27.5 KB  |  1,435 lines

  1.  
  2. ;---------------------------------------------------------;
  3. ;                                                         ;
  4. ;                                                         ;
  5. ;       Baller Game Driver module. [c] 1992 by            ;
  6. ;                   ALPHA - HELIX                         ;
  7. ;               written by Dany Schoch                    ;
  8. ;                                                         ;
  9. ;  This module is graphic mode independant. Just link     ;
  10. ;  in the proper LOW LEVEL GRAPHICS module and it works.  ;
  11. ;                                                         ;
  12. ;                                                         ;
  13. ;---------------------------------------------------------;
  14.  
  15.  
  16.  
  17.     IDEAL            ; Idealismus immer und ueberall.
  18.     P286N                   ; Unleash the power of the i286, hehe...
  19.     JUMPS            ; Easy conditional jumping.
  20.  
  21.     MODEL    compact, c
  22.  
  23. include "xmode.ash"
  24. include "sound.ash"
  25. include "baller.ash"
  26.  
  27.  
  28.  
  29.     dataseg
  30.  
  31.  
  32. ; Structure to save a complete position during the game.
  33. ; This is used to get back to a 'try again' point if the
  34. ; bottle broke.
  35. struc    lastposstrc
  36. score        dd    ?               ; Player's score.
  37. nattacks    dw    ?        ; Attacks to go.
  38. attack        dd    ?               ; ptr to attacks.
  39. nbigboss    dw    ?               ; N of Big Bosses to go.
  40. count        dw    ?               ; Frame counter.
  41. ends    lastposstrc
  42.  
  43. lastposition    lastposstrc    ?
  44. invincible    dw    ?        ; Is Eichli invincible?
  45. frameinc    dw    ?        ; Frame count increment step.
  46. nbigboss    dw    ?        ; Number of endlevel monsters that
  47.                     ;   must still be destroyed.
  48.  
  49. ; Variables used to draw the score.
  50. scoredigit    dw    ?        ; # of digits already drawn.
  51. scorepos    dw    ?               ; Current x position.
  52. playscore    dd    ?               ; Remaining score.
  53.  
  54. const10d    dw    10d                ; Faster Division.
  55.  
  56.  
  57.  
  58. ; Make number positive.
  59. ; NOTE: SIGN flag must be set to indicate negative number.
  60. macro    abs    x
  61. local    skip
  62.  
  63.     jns    skip
  64.     neg    x
  65. skip:
  66.  
  67. endm    abs
  68.  
  69.  
  70.     codeseg
  71.  
  72. ; copytoCS: Dies ist der zweite teil des witzes beschrieben in
  73. ;           'BEER.C'.
  74. int08cs    dd    ?            ; Addr of old int 08 routine.
  75. proc    copytoCS
  76.  
  77.     les    ax, [int08]
  78.     mov    [word cs:int08cs+00], ax
  79.     mov    [word cs:int08cs+02], es
  80.  
  81.     ret
  82.  
  83. endp    copytoCS
  84.  
  85.  
  86. ; defarm: Define a friendly object.
  87. ;          Arguments are: far pointer to a 'armstrc'.
  88. ;             x and y as a start location.
  89. proc    defarm    uses si, x:word, y:word, arm:far ptr
  90.  
  91.     mov    si, offset _arm
  92.     mov    cx, MAXARMS
  93. ; Get free arm slot.
  94. @@next:
  95.     cmp    [(aniarm ptr si).object], -1
  96.     je    @@found
  97.     add    si, size aniarm
  98.     loop    @@next
  99.     jmp    @@error
  100.  
  101. @@found:
  102.     les     bx, [arm]
  103.  
  104.     mov    ax, [es:(armstrc ptr bx).flags]
  105.     mov    [(aniarm ptr si).flags], ax
  106.     mov    ax, [es:(armstrc ptr bx).shot]
  107.     mov    [(aniarm ptr si).shot], ax
  108.     mov    ax, [es:(armstrc ptr bx).period]
  109.     mov    [(aniarm ptr si).period], ax
  110.     mov    [(aniarm ptr si).periodcnt], 0
  111.  
  112.     mov    bx, [es:(armstrc ptr bx).sprite]
  113.     shl    bx, 1
  114.     call    defobject, [bx + offset intindex], [x], [y], OBJ_HIGH
  115.     mov    [(aniarm ptr si).object], ax
  116.  
  117. @@error:
  118.  
  119.     ret
  120.  
  121. endp    defarm
  122.  
  123.  
  124. ; defshot: Define a shot.
  125. ; Arguments:
  126. ;    shot:    Which shot should we define?
  127. ;    x, y:    Define coordinates.
  128. ;    addr:      addr of shot, that defines this shot.
  129. proc    defshot    uses si, shot:word, x:word, y:word, addr:word
  130.  
  131.     mov    si, offset _shot
  132.     mov    cx, MAXSHOTS
  133. @@next:
  134.     cmp    [(anishot ptr si).object], -1
  135.     je    @@found
  136.     add    si, size anishot
  137.     loop    @@next
  138.     jmp    @@error
  139.  
  140. @@found:
  141.     mov    ax, 0
  142.     cmp    si, [addr]
  143.     ja    @@hold
  144.     mov    ax, 1
  145. @@hold:
  146.     mov    [(anishot ptr si).go], ax
  147.  
  148. ; Get pointer to shot struc in es:bx.
  149.     mov    bx, [shot]
  150.     shl    bx, 2
  151.     les    bx, [bx + offset ptrindex]
  152. ; Copy data.
  153.     lea    ax, [es:(shotstrc ptr bx).data]
  154.     mov    [word (anishot ptr si+00).data], ax
  155.     mov    [word (anishot ptr si+02).data], es
  156.     mov    ax, [es:(shotstrc ptr bx).power]
  157.     mov    [(anishot ptr si).power], ax
  158.     mov    ax, [es:(shotstrc ptr bx).speed]
  159.     mov    [(anishot ptr si).speed], ax
  160.  
  161.     mov    ax, [x]
  162.     add    ax, [es:(shotstrc ptr bx).shotx]
  163.     mov    dx, [y]
  164.     add    dx, [es:(shotstrc ptr bx).shoty]
  165.     mov    bx, [es:(shotstrc ptr bx).sprite]
  166.     shl    bx, 1
  167.     call    defobject, [bx + offset intindex], ax, dx, OBJ_LOW
  168.     mov    [(anishot ptr si).object], ax
  169.  
  170. @@error:
  171.     ret
  172.  
  173. endp    defshot
  174.  
  175.  
  176.  
  177. ; deffoe:
  178. ; This one defines any kind of foe. (Path-followers, Shots, ...).
  179.  
  180. proc    deffoe    uses si di, foe:word, x:word, y:word, x0:word, y0:word
  181.  
  182. ; Scan for a free enemy slot.
  183.  
  184.     mov    si, offset _foe
  185.     mov    cx, MAXFOES
  186. @@next:
  187.     cmp    [(anifoe ptr si).object], -1
  188.     je    @@found
  189.     add    si, size anifoe
  190.     loop    @@next
  191.     jmp    @@error
  192.  
  193. @@found:
  194.     mov    di, [foe]        ; es:di = ptr to a foestrc.
  195.     add    di, [lfoeofs]        ; Add offset into pointer array.
  196.     shl    di, 2
  197.     les    di, [di+offset ptrindex]
  198.  
  199. ; Copy flags and check type of foe.
  200.     mov    cx, [es:(foestrc ptr di).flags]
  201.     mov    [(anifoe ptr si).flags], cx
  202.     test    cx, FOE_STOPCOUNT
  203.     jz    @@m0
  204.     mov    [frameinc], 0
  205. @@m0:
  206.     test    cx, FOE_TRANSPARENT or FOE_INVINCIBLE
  207.     jnz    @@m1
  208. ; Foe can explode.
  209.     mov    ax, [es:(foestrc ptr di).shield]
  210.     mov    [(anifoe ptr si).shield], ax
  211.     mov    ax, [es:(foestrc ptr di).score]
  212.     mov    [(anifoe ptr si).score], ax
  213.     mov    ax, [es:(foestrc ptr di).expl]
  214.     mov    [(anifoe ptr si).expl], ax
  215. @@m1:
  216.     test    cx, FOE_PATH
  217.     jz    @@m2
  218. ; Foe follows a predefined path.
  219.     lea    bx, [es:(foestrc ptr di).path]
  220.     mov    [word (anifoe ptr si+00h).cpath], bx
  221.     mov    [word (anifoe ptr si+02h).cpath], es
  222. @@m2:
  223.     test    cx, FOE_LINE
  224.     jz    @@m3
  225. ; Foe uses a runtime defined path (line mode).
  226.     mov    ax, [es:(foestrc ptr di).speed]
  227.     mov    [(anifoe ptr si).speed], ax
  228. ; Calculate line draw variables z0, z1, dx, dy, dz.
  229.     mov    ax, [x0]            ; Destination
  230.     mov    dx, [y0]
  231.     test    cx, FOE_PATH
  232.     jnz    @@p0
  233.     push    es
  234.     call    getobjectpos, [_arm.object]
  235.     pop    es
  236. @@p0:
  237.     mov    bx, 1
  238.     sub    ax, [x]
  239.     jns    @@p1
  240.     neg    ax                ; Must be positive.
  241.     neg    bx
  242. @@p1:
  243.     mov    [(anifoe ptr si).dx], ax
  244.     mov    [(anifoe ptr si).z0], bx
  245.     mov    bx, 1
  246.     sub    dx, [y]
  247.     jns    @@p2
  248.     neg    dx
  249.     neg    bx
  250. @@p2:
  251.     mov    [(anifoe ptr si).dy], dx
  252.     mov    [(anifoe ptr si).z1], bx
  253.  
  254.     cmp    ax, dx
  255.     jg    @@p3
  256.     mov    ax, dx
  257. @@p3:
  258.     mov    [(anifoe ptr si).pixelcnt], ax
  259.     shr    ax, 1
  260.     mov    [(anifoe ptr si).dz], ax
  261. @@m3:
  262.  
  263.     mov    bx, [es:(foestrc ptr di).sprite]
  264.     add    bx, [lsprofs]
  265.     shl    bx, 1
  266.     call    defobject, [bx+offset intindex], [x], [y], OBJ_LOW
  267.     mov     [(anifoe ptr si).object], ax
  268.  
  269. @@error:
  270.     ret
  271.  
  272. endp    deffoe
  273.  
  274.  
  275. ; defexpl: Define an explosion.
  276. ;          Arguments: object of impact and # of explosion.
  277.  
  278. proc    defexpl    uses si di, obj:word, explosion:word
  279.  
  280.     mov    si, offset _expl
  281.     mov    cx, MAXEXPLS
  282. @@next:
  283.     cmp    [(aniexpl ptr si).object], -1
  284.     je    @@found
  285.     add    si, size aniexpl
  286.     loop    @@next
  287.     jmp    @@error
  288.  
  289. @@found:
  290.     mov    bx, [explosion]
  291.     add    bx, [lexplofs]
  292.     shl    bx, 2
  293.     les    bx, [bx + offset ptrindex]
  294.  
  295.     lea    di, [es:(explstrc ptr bx).data]
  296.     mov    [word (aniexpl ptr si+00h).data], di
  297.     mov    [word (aniexpl ptr si+02h).data], es
  298.  
  299.     mov    ax, [obj]
  300.     mov    [(aniexpl ptr si).object], ax
  301.     call    getobjectpos, ax
  302.     mov    [(aniexpl ptr si).x], ax
  303.     mov    [(aniexpl ptr si).y], dx
  304.     shr    bx, 1
  305.     add    [(aniexpl ptr si).x], bx
  306.     shr    cx, 1
  307.     add    [(aniexpl ptr si).y], cx
  308.  
  309. @@error:
  310.     ret
  311.  
  312. endp    defexpl
  313.  
  314.  
  315.  
  316. proc    a_arm    uses si di, x:word, y:word
  317.  
  318.     mov    si, offset _arm
  319.  
  320. ; Check whether main bottle is off the play field.
  321.  
  322.     mov    di, [(aniarm ptr si).object]
  323.     test    [invincible], 2
  324.     jz    @@m1
  325.     call    flash, di
  326. @@m1:
  327.     call    getobjectpos, di
  328.     add    ax, [x]
  329.     cmp    ax, [windowx0]
  330.     jge    @@ok1
  331.     sub    ax, [windowx0]
  332.     sub    [x], ax
  333.     jmp    @@ok2
  334. @@ok1:
  335.     add    ax, bx
  336.     cmp    ax, [windowx1]
  337.     jle    @@ok2
  338.     sub    ax, [windowx1]
  339.     sub    [x], ax
  340. @@ok2:
  341.     add    dx, [y]
  342.     cmp    dx, [windowy0]
  343.     jge    @@ok3
  344.     sub    dx, [windowy0]
  345.     sub    [y], dx
  346.     jmp    @@ok4
  347. @@ok3:
  348.     add    dx, cx
  349.     cmp    dx, [windowy1]
  350.     jle    @@ok4
  351.     sub    dx, [windowy1]
  352.     sub    [y], dx
  353. @@ok4:
  354.  
  355.     mov    di, MAXARMS
  356. @@next:
  357.     mov    ax, [(aniarm ptr si).object]
  358.     cmp    ax, -1
  359.     je    @@skip
  360.  
  361.     call    moveobjectdelta, ax, [x], [y]
  362.  
  363. @@skip:
  364.     add    si, size aniarm
  365.     dec    di
  366.     jnz    @@next
  367.  
  368. @@exit:
  369.     ret
  370.  
  371. endp    a_arm
  372.  
  373.  
  374. proc    a_shot    uses si di
  375.  
  376. local    x:word, y:word
  377.  
  378.     mov    si, offset _shot
  379.     mov    di, MAXSHOTS
  380. @@next:
  381.     cmp    [(anishot ptr si).object], -1
  382.     je    @@skip
  383.     cmp    [(anishot ptr si).go], 1
  384.     je    @@go
  385.     mov    [(anishot ptr si).go], 1
  386.     jmp    @@skip
  387. @@go:
  388.  
  389. @@nextcoord:
  390.     les    bx, [(anishot ptr si).data]
  391.     mov    ax, [word es:bx + 00h]        ; Read word of path array.
  392.     mov    dx, ax
  393.     and    dx, 0fff0h
  394.     cmp    dx, 8000h            ; Command ?
  395.     jne    @@notcommand
  396.  
  397. @@c1:
  398.     cmp    ax, SHOTEND
  399.     jne    @@c2
  400.     call    abandonobject, [(anishot ptr si).object]
  401.     mov    [(anishot ptr si).object], -1
  402.     jmp     @@skip
  403. @@c2:
  404.     cmp    ax, SHOTRELEASE
  405.     jne    @@c3
  406.     push    bx es
  407.     call    getobjectpos, [(anishot ptr si).object]
  408.     pop    es bx
  409.     call    defshot, [word es:bx + 02], ax, dx, si
  410.     add    [word (anishot ptr si).data], 4
  411.     jmp    @@nextcoord
  412. @@c3:
  413.     cmp    ax, SHOTHOMING
  414.     jne    @@c4
  415.     add    [word (anishot ptr si).data], 2    ; Increment ptr to new cmd.
  416.     call    getobjectpos, [(anishot ptr si).object]
  417.     mov    [x], ax
  418.     mov    [y], dx
  419.     jmp    a_shotline
  420. @@c4:
  421.     cmp    ax, SHOTREFLECT
  422.     jne    @@c5
  423.     add    [word (anishot ptr si).data], 2    ; Inc command ptr.
  424.     call    getobjectpos, [(anishot ptr si).object]
  425.     add    ax, [(anishot ptr si).dx]
  426.     cmp    ax, [windowx0]
  427.     jge    @@r1
  428. ; Shot reflects at left border.
  429.     neg    [(anishot ptr si).dx]        ; Change direction.
  430.     add    ax, [(anishot ptr si).dx]
  431.     add    ax, [(anishot ptr si).dx]
  432.     jmp    @@r3
  433. @@r1:
  434.     add    ax, bx
  435.     cmp    ax, [windowx1]
  436.     jle    @@r2
  437. ; Shot reflects at right border.
  438.     neg    [(anishot ptr si).dx]
  439.     add    ax, [(anishot ptr si).dx]
  440.     add    ax, [(anishot ptr si).dx]
  441. @@r2:
  442.     sub    ax, bx
  443. @@r3:
  444.     add    dx, [(anishot ptr si).dy]
  445.     cmp    dx, [windowy0]
  446.     jge    @@r4
  447. ; Shot reflects at top border.
  448.     neg    [(anishot ptr si).dy]        ; Change direction.
  449.     add    dx, [(anishot ptr si).dy]
  450.     add    dx, [(anishot ptr si).dy]
  451.     jmp    @@r6
  452. @@r4:
  453.     add    dx, cx
  454.     cmp    dx, [windowy1]
  455.     jle    @@r5
  456. ; Shot reflects at bottom border.
  457.     neg    [(anishot ptr si).dy]
  458.     add    dx, [(anishot ptr si).dy]
  459.     add    dx, [(anishot ptr si).dy]
  460. @@r5:
  461.     sub    dx, cx
  462. @@r6:
  463.     call    moveobject, [(anishot ptr si).object], ax, dx
  464.     jmp    @@inwindow
  465. @@c5:
  466.  
  467.  
  468. @@notcommand:
  469.     add    [word (anishot ptr si).data], 4
  470.     mov    [(anishot ptr si).dx], ax
  471.     mov    dx, [word es:bx+02]
  472.     mov    [(anishot ptr si).dy], dx
  473.     call    moveobjectdelta, [(anishot ptr si).object], ax, dx
  474.  
  475. a_shot_skip:
  476.     call    outofwindow, [(anishot ptr si).object]
  477.     or    ax, ax
  478.     jz    @@inwindow
  479.  
  480.     call    abandonobject, [(anishot ptr si).object]
  481.     mov    [(anishot ptr si).object], -1
  482.  
  483. @@inwindow:
  484. @@skip:
  485.     add    si, size anishot
  486.     dec    di
  487.     jnz    @@next
  488.  
  489.     ret
  490.  
  491. endp    a_shot
  492.  
  493.  
  494. proc    nolanguage a_shotline
  495.  
  496.     mov    bx, offset _foe
  497.     mov    cx, MAXFOES
  498. @@next:
  499.     cmp    [(anifoe ptr bx).object], -1
  500.     je    @@next2
  501.     test    [(anifoe ptr bx).flags], (FOE_INVINCIBLE or FOE_TRANSPARENT)
  502.     jz    @@found
  503. @@next2:
  504.     add    bx, size anifoe
  505.     loop    @@next
  506.     call    moveobjectdelta, [(anishot ptr si).object],\
  507.                  [(anishot ptr si).dx],\
  508.                  [(anishot ptr si).dy]
  509.     jmp    a_shot_skip
  510.  
  511. @@found:
  512.     call    getobjectpos, [(anifoe ptr bx).object]
  513.     shr    bx, 1
  514.     add    ax, bx                ; Get mid point of object.
  515.     shr    cx, 1
  516.     add    dx, cx
  517. ; What's done so far: We looked for a foe to shot at and pumped the
  518. ; target coordinates into (ax, dx).
  519.  
  520.     sub    ax, [x]
  521.     mov    bx, ax
  522.     abs    ax
  523.     sub    dx, [y]
  524.     mov    cx, dx
  525.     abs    dx
  526.  
  527.     cmp    ax, dx
  528.     jbe    @@y
  529.  
  530.     xor    dx, dx
  531.     div    [(anishot ptr si).speed]
  532.     inc    ax
  533.     xchg    ax, cx
  534.     cwd
  535.     idiv    cx
  536.  
  537.     mov    dx, ax
  538.     mov    ax, [(anishot ptr si).speed]
  539.     cmp    bx, 0
  540.     jge    @@p1
  541.     neg    ax
  542. @@p1:
  543. ; done for the moment: dxnew = ax, dynew = dx.
  544.     jmp    @@turncheck
  545.  
  546. @@y:
  547.     mov    ax, dx
  548.     xor    dx, dx
  549.     div    [(anishot ptr si).speed]
  550.     inc    ax
  551.     xchg    ax, bx
  552.     cwd
  553.     idiv    bx
  554.  
  555.     mov    dx, [(anishot ptr si).speed]
  556.     cmp    cx, 0
  557.     jge    @@p2
  558.     neg    dx
  559. @@p2:
  560. ; also done. dxnew = ax, dynew = dx.
  561.  
  562.  
  563. @@turncheck:
  564.     mov    bx, [(anishot ptr si).dx]
  565.     cmp    ax, bx
  566.     jg    @@p3
  567.     sub    bx, 2
  568. @@p3:
  569.     inc    bx
  570.  
  571.     mov    cx, [(anishot ptr si).dy]
  572.     cmp    dx, cx
  573.     jg    @@p4
  574.     sub    cx, 2
  575. @@p4:
  576.     inc    cx
  577.  
  578. ; Final deltax and deltay in ax and dx now.
  579.  
  580.     mov    [(anishot ptr si).dx], bx
  581.     mov    [(anishot ptr si).dy], cx
  582.  
  583.     call    moveobjectdelta, [(anishot ptr si).object], bx, cx
  584.  
  585.     jmp    a_shot_skip
  586.  
  587. endp    a_shotline
  588.  
  589.  
  590.  
  591.  
  592. ;------------------------------------------------------
  593. ;Function: a_foe
  594. ;
  595. ;Description: This proc interprets the next command of
  596. ;          each enemy in his path and performs proper
  597. ;          action.
  598. ;------------------------------------------------------
  599.  
  600. proc    a_foe    uses bp si
  601.  
  602.     mov    si, offset _foe
  603.     mov    bp, MAXFOES
  604. @@next:
  605.     push    si
  606.     cmp    [(anifoe ptr si).object], -1
  607.     je    @@skip
  608.  
  609.     test    [(anifoe ptr si).flags], FOE_LINE
  610.     jnz    a_foeline
  611.  
  612. @@nextcoord:
  613.     les    bx, [(anifoe ptr si).cpath]
  614.     mov    ax, [word es:bx + 00h]        ; Read word of path array.
  615.     mov    dx, ax
  616.     and    dx, 0fff0h
  617.     cmp    dx, 8000h            ; Command ?
  618.     jne    @@notcommand
  619.  
  620. ; Interpret the command given in ax.
  621.  
  622. @@c1:
  623.     cmp    ax, FOEENDPATH
  624.     jne    @@c2
  625. ; Object has reached end of path and must be destroyed.
  626.     call    abandonobject, [(anifoe ptr si).object]
  627.     mov    [(anifoe ptr si).object], -1
  628.     jmp    @@skip
  629. @@c2:
  630.     cmp    ax, FOECHANGESPRITE
  631.     jne    @@c3
  632. ; Object wants to change it's look.
  633.     mov    bx, [word es:bx + 02h]
  634.     add    bx, [lsprofs]
  635.     shl    bx, 1
  636.     call    changesprite, [(anifoe ptr si).object], [bx+offset intindex]
  637.     add    [word (anifoe ptr si).cpath], 4
  638.     jmp    @@nextcoord
  639. @@c3:
  640.     cmp    ax, FOERELEASEFOE
  641.     jne    @@c4
  642. ; Object releases another object.
  643.     push    bx es
  644.     call    getobjectpos, [(anifoe ptr si).object]
  645.     pop    es bx
  646.     add    ax, [word es:bx + 04h]
  647.     add    dx, [word es:bx + 06h]
  648.     call    deffoe, [word es:bx + 02], ax, dx
  649.     add    [word (anifoe ptr si).cpath], 8
  650.     jmp    @@nextcoord
  651. @@c4:
  652.     cmp    ax, FOECYCLEPATH
  653.     jne    @@c5
  654.     les    bx, [(anifoe ptr si).path]
  655.     mov    [word (anifoe ptr si + 00h).cpath], bx
  656.     mov    [word (anifoe ptr si + 02h).cpath], es
  657.     call    moveobject, [(anifoe ptr si).object],\
  658.                 [(anifoe ptr si).savex], [(anifoe ptr si).savey]
  659.     jmp    @@nextcoord
  660. @@c5:
  661.     cmp    ax, FOEMARK
  662.     jne    @@c6
  663.     add    bx, 2
  664.     mov    [word (anifoe ptr si+00h).path], bx
  665.     mov    [word (anifoe ptr si+02h).path], es
  666.     mov    [word (anifoe ptr si).cpath], bx
  667.     call    getobjectpos, [(anifoe ptr si).object]
  668.     mov    [(anifoe ptr si).savex], ax
  669.     mov    [(anifoe ptr si).savey], dx
  670.     jmp    @@nextcoord
  671. @@c6:
  672.     cmp    ax, FOESOUND
  673.     jne    @@c7
  674.     mov    bx, [word es:bx + 02h]
  675.     add    bx, [lsndofs]
  676.     shl    bx, 2
  677.     les    bx, [bx + offset ptrindex]
  678.     call    playsample, es bx
  679.     add    [word (anifoe ptr si).cpath], 4
  680.     jmp    @@nextcoord
  681. @@c7:
  682.     jmp    @@skip
  683.  
  684. @@notcommand:
  685.     add    [word (anifoe ptr si).cpath], 4
  686.     call    moveobjectdelta, [(anifoe ptr si).object], ax, [word es:bx + 02h]
  687.  
  688. a_foe_skip:
  689. @@skip:
  690.     pop    si
  691.     add    si, size anifoe
  692.     dec    bp
  693.     jnz    @@next
  694.  
  695.     ret
  696.  
  697. endp    a_foe
  698.  
  699.  
  700. proc    nolanguage a_foeline
  701.  
  702.     call    getobjectpos, [(anifoe ptr si).object]
  703.     mov    cx, [(anifoe ptr si).speed]
  704.     mov    bx, [(anifoe ptr si).dz]
  705. @@loop:
  706.     cmp    bx, [(anifoe ptr si).dx]
  707.     jge    @@m1
  708.     add    bx, [(anifoe ptr si).dy]
  709.     add    ax, [(anifoe ptr si).z0]
  710. @@m1:
  711.     cmp    bx, [(anifoe ptr si).dx]
  712.     jl    @@m2
  713.     sub    bx, [(anifoe ptr si).dx]
  714.     add    dx, [(anifoe ptr si).z1]
  715. @@m2:
  716.     test    [(anifoe ptr si).flags], FOE_PATH
  717.     jz    @@m3
  718.     dec    [(anifoe ptr si).pixelcnt]
  719.     jnz    @@m3
  720. ; Target coordinates have been reached.
  721.     and    [(anifoe ptr si).flags], not FOE_LINE
  722.     call    moveobject, [(anifoe ptr si).object], ax, dx
  723.     jmp    a_foe_skip
  724. @@m3:
  725.  
  726.     loop    @@loop
  727.  
  728.     mov    [(anifoe ptr si).dz], bx
  729.  
  730.     call    moveobject, [(anifoe ptr si).object], ax, dx
  731.  
  732.     call    outofwindow, [(anifoe ptr si).object]
  733.     or    ax, ax
  734.     jz    @@inwindow
  735.  
  736.     call    abandonobject, [(anifoe ptr si).object]
  737.     mov    [(anifoe ptr si).object], -1
  738.  
  739. @@inwindow:
  740.  
  741.     jmp    a_foe_skip
  742.  
  743. endp    a_foeline
  744.  
  745.  
  746.  
  747. proc    a_expl    uses bp si
  748.  
  749.     mov    si, offset _expl
  750.     mov    bp, MAXEXPLS
  751. @@next:
  752.     cmp    [(aniexpl ptr si).object], -1
  753.     je    @@skip
  754.  
  755. @@nextcommand:
  756.     les    bx, [(aniexpl ptr si).data]
  757.     add    [word (aniexpl ptr si).data], 2
  758.     mov    ax, [word es:bx]        ; Fetch command.
  759.  
  760.     cmp    ax, EXPLEND
  761.     jne    @@c1
  762.     mov    [(aniexpl ptr si).object], -1    ; Destroy explosion.
  763.     jmp    @@skip
  764. @@c1:
  765.     cmp    ax, EXPLNEW
  766.     jne    @@c2
  767.     mov    ax, [(aniexpl ptr si).x]
  768.     mov    dx, [(aniexpl ptr si).y]
  769.     add    ax, [word es:bx + 04h]
  770.     add    dx, [word es:bx + 06h]
  771.     mov    bx, [word es:bx + 02h]
  772.     add    bx, [lsprofs]
  773.     shl    bx, 1
  774.     call    defobject, [bx + offset intindex],\
  775.                ax, dx, OBJ_HIGH or OBJ_ONECYCLE
  776.     add    [word (aniexpl ptr si).data], 6
  777.     jmp    @@nextcommand
  778. @@c2:
  779.     cmp    ax, EXPLWAIT
  780.     jne    @@c3
  781.     jmp    @@skip
  782. @@c3:
  783.     cmp    ax, EXPLSOUND
  784.     jne    @@c4
  785.     mov    bx, [word es:bx + 02h]
  786.     add    bx, [lsndofs]
  787.     shl    bx, 2
  788.     les    bx, [bx + offset ptrindex]
  789.     call    playsample, es bx
  790.     add    [word (aniexpl ptr si).data], 2
  791.     jmp    @@nextcommand
  792. @@c4:
  793.     cmp    ax, EXPLREMOVEOBJ
  794.     jne    @@c5
  795.     call    abandonobject, [(aniexpl ptr si).object]
  796.     jmp    @@nextcommand
  797. @@c5:
  798.     cmp    ax, EXPLRELEASEFOE
  799.     jne    @@c6
  800.     mov    ax, [(aniexpl ptr si).x]
  801.     mov    dx, [(aniexpl ptr si).y]
  802.     add    ax, [word es:bx + 04h]
  803.     add    dx, [word es:bx + 06h]
  804.     call    deffoe, [word es:bx + 02], ax, dx
  805.     add    [word (aniexpl ptr si).data], 6
  806.     jmp    @@nextcommand
  807. @@c6:
  808.     cmp    ax, EXPLNEWPATH
  809.     jne    @@c7
  810.     mov    ax, [(aniexpl ptr si).x]
  811.     mov    dx, [(aniexpl ptr si).y]
  812.     add    ax, [word es:bx + 04h]
  813.     add    dx, [word es:bx + 06h]
  814.     call    deffoe, [word es:bx + 02h], ax, dx,\
  815.             [word es:bx + 08h], [word es:bx + 0ah]
  816.     add    [word (aniexpl ptr si).data], 0ah
  817.     jmp    @@nextcommand
  818. @@c7:
  819.  
  820. @@skip:
  821.     add    si, size aniexpl
  822.     dec    bp
  823.     jnz    @@next
  824.  
  825.     ret
  826.  
  827. endp    a_expl
  828.  
  829.  
  830.  
  831. ; foehit: manages bullet vs. enemy crashes.
  832. ;
  833. proc    foehit    uses bp si di
  834.  
  835.     mov    si, offset _foe
  836.     mov    cx, MAXFOES
  837.  
  838. @@next1:
  839.     push    cx
  840.  
  841.     cmp    [(anifoe ptr si).object], -1
  842.     je    @@skip1
  843.     test    [(anifoe ptr si).flags], FOE_TRANSPARENT
  844.     jnz    @@skip1
  845.  
  846.     mov    di, offset _shot
  847.     mov    bp, MAXSHOTS
  848.  
  849. @@next2:
  850.     cmp    [(anishot ptr di).object], -1
  851.     je    @@skip2
  852.  
  853.     call    crashtest, [(anifoe ptr si).object], [(anishot ptr di).object]
  854.     or    ax, ax
  855.     jz    @@nohit
  856.  
  857. ; Enemy pointed by si has been hit by shot pointed by di. (real great)
  858.  
  859.     test    [(anifoe ptr si).flags], FOE_INVINCIBLE
  860.     jz    @@goon
  861.     mov    [(anishot ptr di).power], 0    ; Kill shot.
  862.     jmp    @@foealive
  863.  
  864. @@goon:
  865.     call    flash, [(anifoe ptr si).object]
  866.  
  867.     mov    ax, [(anifoe ptr si).shield]    ; Power of foe.
  868.     mov    bx, [(anishot ptr di).power]    ; Power of shot.
  869.  
  870.     sub    [(anishot ptr di).power], ax
  871.     sub    [(anifoe ptr si).shield], bx
  872.     ja    @@foealive
  873.  
  874. ; Add score.
  875.     mov    dx, [(anifoe ptr si).score]
  876.     add    [word score+00], dx
  877.     adc    [word score+02], 0
  878.  
  879. ; Do explosion.
  880.     call    defexpl, [(anifoe ptr si).object], [(anifoe ptr si).expl]
  881.     mov    [(anifoe ptr si).object], -1
  882.  
  883.     mov    ax, [(anifoe ptr si).flags]
  884.     test    ax, FOE_ENDLEVEL        ; Was it a big boss ?
  885.     jz    @@m1
  886.     dec    [nbigboss]
  887.  
  888. @@m1:
  889.     test    ax, FOE_STOPCOUNT        ; Check for stopped counter.
  890.     jz    @@foealive
  891.     mov    [frameinc], 1
  892.  
  893. @@foealive:
  894.     cmp    [(anishot ptr di).power], 0
  895.     jg    @@shotalive
  896.     call    abandonobject, [(anishot ptr di).object]
  897.     mov    [(anishot ptr di).object], -1
  898.  
  899. @@shotalive:
  900.  
  901. @@nohit:
  902. @@skip2:
  903.     add    di, size anishot
  904.  
  905.     dec    bp
  906.     jnz    @@next2
  907.  
  908. @@skip1:
  909.     add    si, size anifoe
  910.  
  911.     pop    cx
  912.     loop    @@next1
  913.  
  914. @@exit:
  915.     ret
  916.  
  917. endp    foehit
  918.  
  919.  
  920.  
  921. ; armhit: checks whether the heroic bottle of cool fresh Eichhof
  922. ;         Lager has been hit by a nasty enemy beer.
  923. ;
  924. ; RETURNS: ax = 1 if hit.
  925.  
  926. proc    armhit    uses bp si di
  927.  
  928.     cmp    [invincible], 0
  929.     jne    @@nohit
  930.  
  931. ; First we check whether Eichli has been hit by a hostile shot.
  932.  
  933.     mov    si, offset _foe
  934.     mov    bp, MAXFOES
  935.  
  936.     mov    di, [_arm.object]
  937.  
  938. @@next1:
  939.     cmp    [(anifoe ptr si).object], -1
  940.     je    @@skip1
  941.  
  942.     call    crashtest, [(anifoe ptr si).object], di
  943.     or    ax, ax
  944.     jz    @@skip1
  945.  
  946. ; Eichli has been hit
  947. @@hit:
  948.     call    defexpl, di, 0        ; Do a beautiful explosion.
  949. ; Destroy all weapons.
  950.     mov    di, offset _arm
  951.     mov    si, MAXARMS
  952. @@next2:
  953.     mov    ax, [(aniarm ptr di).object]
  954.     mov    [(aniarm ptr di).object], -1
  955.     cmp    ax, -1
  956.     je    @@skip2
  957.     call    abandonobject, ax
  958. @@skip2:
  959.     add    di, size aniarm
  960.     dec    si
  961.     jnz    @@next2
  962.     mov    ax, 1            ; Indiacte destroyed Eichli.
  963.     jmp    @@exit
  964.  
  965. @@skip1:
  966.     add    si, size anifoe
  967.     dec    bp
  968.     jnz    @@next1
  969. @@nohit:
  970.     mov    ax, 0
  971. @@exit:
  972.     ret
  973.  
  974. endp    armhit
  975.  
  976.  
  977.  
  978. ; fire: Voll power aus allen Rohren.
  979. ;       al == TRUE  : es soll geschossen werden.
  980. ;       al == FALSE : Friede. Kein schuss soll fallen.
  981.  
  982. proc    fire    uses bp si
  983.  
  984.     mov    si, offset _arm
  985.     mov    bp, MAXARMS
  986.     cmp    al, FALSE
  987.     jne    @@fire
  988.  
  989. @@next1:
  990.     cmp    [(aniarm ptr si).object], -1
  991.     je    @@skip1
  992.     cmp    [(aniarm ptr si).periodcnt], 0    ; Gun already reloaded ?
  993.     je    @@skip1
  994.     dec    [(aniarm ptr si).periodcnt]    ; Decrement reload delay.
  995. @@skip1:
  996.     add    si, size aniarm
  997.     dec    bp
  998.     jnz    @@next1
  999.  
  1000.     jmp    @@exit
  1001.  
  1002. @@fire:
  1003.  
  1004. @@next2:
  1005.     cmp    [(aniarm ptr si).object], -1    ; Is weapon defined ?
  1006.     je    @@skip2
  1007.  
  1008.     sub    [(aniarm ptr si).periodcnt], 1    ; Ready to shot ?
  1009.     jnc    @@skip2
  1010.     mov    ax, [(aniarm ptr si).period]    ; Restore reload delay.
  1011.     mov    [(aniarm ptr si).periodcnt], ax
  1012.  
  1013.     call    getobjectpos, [(aniarm ptr si).object]
  1014.     call    defshot, [(aniarm ptr si).shot], ax, dx, 0ffffh
  1015.  
  1016. @@skip2:
  1017.     add    si, size aniarm
  1018.     dec    bp
  1019.     jnz    @@next2
  1020.  
  1021. @@exit:
  1022.     ret
  1023.  
  1024. endp    fire
  1025.  
  1026.  
  1027.  
  1028. ; keyboard: Translates the pressed keys into action.
  1029.  
  1030. proc    keyboard
  1031.  
  1032.  
  1033.     mov    bx, [key_fire]            ; Get defined 'FIRE' key.
  1034.     mov    al, [byte key + bx]             ; Is key pressed ?
  1035.     call    fire
  1036.  
  1037. @@ns:
  1038.     xor    ax, ax
  1039.     xor    dx, dx
  1040.  
  1041.     mov    bx, [key_left]
  1042.     cmp    [byte key + bx], TRUE        ; left
  1043.     jne    @@nl
  1044.     sub    ax, [shipspeed]
  1045.  
  1046. @@nl:
  1047.     mov    bx, [key_right]
  1048.     cmp    [byte key + bx], TRUE        ; right
  1049.     jne    @@nr
  1050.     add    ax, [shipspeed]
  1051.  
  1052. @@nr:
  1053.     mov    bx, [key_up]
  1054.     cmp    [byte key + bx], TRUE        ; up
  1055.     jne    @@nu
  1056.     sub    dx, [shipspeed]
  1057.  
  1058. @@nu:
  1059.     mov    bx, [key_down]
  1060.     cmp    [byte key + bx], TRUE        ; down
  1061.     jne    @@nd
  1062.     add    dx, [shipspeed]
  1063.  
  1064. @@nd:
  1065.     mov    bx, [key_pause]            ; Pause
  1066.     cmp    [byte key + bx], TRUE
  1067.     jne    @@np
  1068. @@wait1:
  1069.     cmp    [pressedkeys], 0        ; Keys must be released first.
  1070.     jne    @@wait1
  1071. @@wait2:
  1072.     cmp    [pressedkeys], 0        ; Wait for any key.
  1073.     je    @@wait2
  1074.     shl    [byte key + bx], 1
  1075.  
  1076. @@np:
  1077.  
  1078.     call    a_arm, ax, dx
  1079.  
  1080.     ret
  1081.  
  1082. endp    keyboard
  1083.  
  1084.  
  1085. ; dispscore
  1086. ; show player's current score.
  1087.  
  1088. proc    dispscore
  1089.  
  1090.     push    [windowy1]
  1091.     mov    [windowy1], YMAX        ; Remove clipping.
  1092.  
  1093. @@startover:
  1094.     mov    ax, [scoredigit]
  1095.     cmp    ax, 0
  1096.     jne    @@skip1
  1097.     les    bx, [score]            ; Revitalize everything.
  1098.     mov    [word playscore+00], bx
  1099.     mov    [word playscore+02], es
  1100.     mov     [scorepos], BARSCOREX
  1101.     jmp    @@disp
  1102. @@skip1:
  1103.     cmp    ax, 4
  1104.     jne    @@skip2
  1105.     sub    [scorepos], 4                 ; Jump over point.
  1106.     jmp    @@disp
  1107. @@skip2:
  1108.     cmp    ax, 16d
  1109.     jne    @@disp
  1110.     mov    [scoredigit], 0
  1111.     jmp    @@startover
  1112.  
  1113. @@disp:
  1114. ; First we clear the digit that should be drawn afterwards.
  1115. ; Note that we can't use removesprite to do this job, because
  1116. ; removesprite would delete a box with x-size as a multiple of four.
  1117. ; So we have to use a blank sprite (BARCLRDIGIT).
  1118.     call    putsprite, [barfonthandle], [scorepos], BARSCOREY, BARCLRDIGIT
  1119. ; Now we calculate the number to be drawn.
  1120.     mov    ax, [word playscore+02]    ; High word of remaining number.
  1121.     xor    dx, dx
  1122.     div    [const10d]        ; Divide by ten : remainder in dx.
  1123.     mov    cx, ax
  1124.     mov    ax, [word playscore+00]
  1125.     div    [const10d]        ; (remainder:low word)/10.
  1126. ; Each digit must be drawn twice, on page 0 and 1.
  1127. ; So we must check whether it have already been drawn once.
  1128.     test    [scoredigit], 1
  1129.     jz    @@notsave        ; Jump if first time we draw it.
  1130.     mov    [word playscore+00], ax ; Store new score.
  1131.     mov    [word playscore+02], cx
  1132.     call    putsprite, [barfonthandle], [scorepos], BARSCOREY, dx
  1133.     sub    [scorepos], BARSCORESPC ; Advance to next digit.
  1134.     jmp    @@ret
  1135. @@notsave:
  1136.     call    putsprite, [barfonthandle], [scorepos], BARSCOREY, dx
  1137.  
  1138. @@ret:
  1139.     inc    [scoredigit]
  1140.  
  1141.     pop    [windowy1]
  1142.     ret
  1143.  
  1144. endp    dispscore
  1145.  
  1146.  
  1147. proc    displifes uses si di
  1148.  
  1149.     push    [windowy1]
  1150.     mov    [windowy1], YMAX
  1151.  
  1152.     mov    si, 6
  1153.     mov    di, BARLIFEX
  1154.  
  1155. @@next1:
  1156.     call    putsprite, [barfonthandle], di, BARSCOREY, BARCLRDIGIT
  1157.     sub    di, 4
  1158.  
  1159.     dec    si
  1160.     jnz    @@next1
  1161.  
  1162.     mov    si, [lifes]
  1163.     cmp    si, 6
  1164.     jbe    @@ok
  1165.     mov    si, 6
  1166. @@ok:
  1167.     mov    di, BARLIFEX
  1168. @@next2:
  1169.     sub    si, 1            ; Requires carry detection.
  1170.     jc    @@done
  1171.  
  1172.     call    putsprite, [barfonthandle], di, BARSCOREY, BARLIFEDIGIT
  1173.     sub    di, 4
  1174.  
  1175.     jmp    @@next2
  1176.  
  1177. @@done:
  1178.     pop    [windowy1]
  1179.     ret
  1180.  
  1181. endp    displifes
  1182.  
  1183.  
  1184. ;
  1185. ; wait till the next timer tick occurs.
  1186. ;
  1187. proc    waitfortick
  1188.  
  1189. @@wait:
  1190.     cmp    [tick], TRUE
  1191.     jne    @@wait
  1192.     mov    [tick], FALSE
  1193.  
  1194.     ret
  1195.  
  1196. endp    waitfortick
  1197.  
  1198.  
  1199. ;
  1200. ; set a starting position of a level.
  1201. ;
  1202. proc    setplayposition,    nattacks:word, \
  1203.                 attack:far ptr, \
  1204.                 nbigb:word
  1205.  
  1206.     mov    ax, [nattacks]
  1207.     mov    [lastposition.nattacks], ax
  1208.     les    ax, [attack]
  1209.     mov     [word (lastposition + 00).attack], ax
  1210.     mov    [word (lastposition + 02).attack], es
  1211.     mov    ax, [nbigb]
  1212.     mov    [lastposition.nbigboss], ax
  1213.     les    ax, [score]
  1214.     mov    [word (lastposition+00).score], ax
  1215.     mov    [word (lastposition+02).score], es
  1216.  
  1217.     mov    [lastposition.count], 0
  1218.  
  1219.     ret
  1220.  
  1221. endp    setplayposition
  1222.  
  1223.  
  1224. proc    play    uses si di
  1225.  
  1226. local    terminate:word, nattacks:word
  1227.  
  1228.     les    ax, [lastposition.score]
  1229.     mov    [word score + 00], ax
  1230.     mov    [word score + 02], es
  1231.     mov    ax, [lastposition.nbigboss]
  1232.     mov    [nbigboss], ax
  1233.     mov    ax, [lastposition.nattacks]
  1234.     mov    [nattacks], ax
  1235.     mov    di, [lastposition.count]
  1236.     mov    si, [word (lastposition + 00).attack]
  1237.     mov    [frameinc], 1
  1238.     mov    [scoredigit], 0
  1239.  
  1240.     mov    [invincible], SHIELD_CTIME    ; First Eichli is invincible.
  1241.     mov    [terminate], 0        ; No reason to terminate.
  1242.  
  1243. @@next:
  1244.     cmp    [nattacks], 0
  1245.     je    @@skip
  1246.  
  1247.     mov    es, [word (lastposition + 02).attack]
  1248.  
  1249.     mov    ax, [es:(attackstrc ptr si).count]
  1250.     cmp    ax, di
  1251.     jne    @@skip
  1252.  
  1253.     mov    ax, [es:(attackstrc ptr si).foe]
  1254.     test    ax, A_COMMAND
  1255.     jz    @@nocommand
  1256.  
  1257.     cmp    ax, A_GOFIELD
  1258.     jne    @@c2
  1259.     call    gostarfield
  1260.     add    si, size attackstrc
  1261.     jmp    @@next
  1262. @@c2:
  1263.     cmp    ax, A_STOPFIELD
  1264.     jne    @@c3
  1265.     call    stopstarfield
  1266.     add    si, size attackstrc
  1267.     jmp    @@next
  1268. @@c3:
  1269.     cmp    ax, A_SOUND
  1270.     jne    @@c4
  1271.     mov    bx, [es:(attackstrc ptr si).x]
  1272.     add    bx, [lsndofs]
  1273.     shl    bx, 2
  1274.     les    bx, [bx + offset ptrindex]
  1275.     call    playsample, es bx
  1276.     add    si, size attackstrc
  1277.     jmp    @@next
  1278. @@c4:
  1279.     cmp    ax, A_MARK
  1280.     jne    @@c5
  1281.     mov    ax, [nattacks]
  1282.     mov    [lastposition.nattacks], ax
  1283.     mov     [word (lastposition + 00).attack], si
  1284.     mov    ax, [nbigboss]
  1285.     mov    [lastposition.nbigboss], ax
  1286.     mov    [lastposition.count], di
  1287.     les    ax, [score]
  1288.     mov    [word (lastposition+00).score], ax
  1289.     mov    [word (lastposition+02).score], es
  1290.     add    si, size attackstrc
  1291.     jmp    @@next
  1292. @@c5:
  1293. @@nocommand:
  1294.     call    deffoe, ax,\
  1295.             [es:(attackstrc ptr si).x],\
  1296.             [es:(attackstrc ptr si).y]
  1297.     dec    [nattacks]
  1298.     add    si, size attackstrc
  1299.     jmp    @@next
  1300.  
  1301. @@skip:
  1302.  
  1303. ; ESC key test.
  1304.     cmp    [byte key + KEYESC], TRUE
  1305.     jne    @@go_on
  1306.     mov    [lifes], -1        ; Request game abort.
  1307.     jmp    @@bottlehit
  1308.  
  1309. @@go_on:
  1310.     call    keyboard
  1311.     call    waitfortick
  1312.     call    updatescreen
  1313.     call    foehit
  1314.     cmp    [nbigboss], 0        ; Any Big Boss left ?
  1315.     jne    @@s3
  1316.     mov    [nbigboss], 1
  1317.     mov    [invincible], WIN_CTIME
  1318.     mov    [terminate], 1        ; All Endlevel monsters killed.
  1319. @@s3:
  1320.     test    [cheatlevel], CHEATCRASH; Fair-Play?
  1321.     jnz    @@s2
  1322.     call    armhit
  1323.     or    ax, ax
  1324.     jz    @@s2
  1325.     mov    [invincible], LOSE_CTIME
  1326.     mov    [terminate], 2        ; Eichli destroyed.
  1327. @@s2:
  1328.     call    dispscore
  1329.     call    a_shot
  1330.     call    a_foe
  1331.     call    a_expl
  1332.  
  1333.     add    di, [frameinc]        ; Inrement frame count.
  1334.  
  1335.     cmp    [invincible], 0
  1336.     je    @@next
  1337.     dec    [invincible]
  1338.     jnz    @@next
  1339.     mov    ax, [terminate]
  1340.     or    ax, ax
  1341.     jz    @@next
  1342.     cmp    ax, 1
  1343.     jne    @@bottlehit
  1344.  
  1345.     call    haltsound
  1346.     mov    ax, 1            ; next level
  1347.     jmp    @@exit
  1348.  
  1349. @@bottlehit:
  1350.     call    haltsound
  1351.     mov    ax, 0
  1352. @@exit:
  1353.     ret
  1354.  
  1355. endp    play
  1356.  
  1357.  
  1358. proc    nolanguage newint09    far
  1359.  
  1360.     push    ax bx ds
  1361.  
  1362.     in    al, 60h
  1363.     mov    bl, al
  1364.     in    al, 61h
  1365.     mov    ah, al
  1366.     or    al, 80h
  1367.     out    61h, al
  1368.     mov    al, ah
  1369.     out    61h, al
  1370.  
  1371.     mov    ax, DGROUP
  1372.     mov    ds, ax
  1373.  
  1374.     test    bl, 80h
  1375.     jz    @@press
  1376.     and    bx, 7fh
  1377.     cmp    [byte key + bx], FALSE
  1378.     je    @@skip1
  1379.     mov    [byte key + bx], FALSE
  1380.     dec    [pressedkeys]
  1381. @@skip1:
  1382.     jmp    short @@exit
  1383.  
  1384. @@press:
  1385.     and    bx, 7fh
  1386.     cmp    [byte key + bx], FALSE
  1387.     jne    @@skip2
  1388.     mov    [byte key + bx], TRUE
  1389.     inc    [pressedkeys]
  1390. @@skip2:
  1391.  
  1392. @@exit:
  1393.     mov    al, 20h
  1394.     out    20h, al
  1395.  
  1396. ; Check for Ctrl-Alt-Del
  1397.     cmp    [byte key+01dh], TRUE    ; Ctrl
  1398.     jne    @@e1
  1399.     cmp    [byte key+038h], TRUE    ; Alt
  1400.     jne    @@e1
  1401.     cmp    [byte key+053h], TRUE    ; Del
  1402.     jne    @@e1
  1403.  
  1404.     call    error, 0 0, -1        ; Do error with code -1.
  1405.  
  1406. @@e1:
  1407.     pop    ds bx ax
  1408.  
  1409.     iret
  1410.  
  1411. endp    newint09
  1412.  
  1413.  
  1414. proc    nolanguage newint08    far
  1415.  
  1416.     push    ax ds
  1417.  
  1418.     mov    ax, DGROUP
  1419.     mov    ds, ax
  1420.  
  1421.     mov    [tick], TRUE
  1422.  
  1423.     pop    ds ax
  1424.  
  1425.     jmp    [dword cs:int08cs]
  1426.  
  1427. endp    newint08
  1428.  
  1429.  
  1430.  
  1431.     end
  1432.  
  1433.  
  1434.  
  1435.