back to project page

ROCK1 Disassembly

                   ********************************************************************************
                   * Stellar 7 for the Apple II, by Damon Slye                                    *
                   * Copyright 1983 Dynamix                                                       *
                   *                                                                              *
                   * Disassembly of "ROCK1".                                                      *
                   ********************************************************************************
                   * This has various math and graphics routines and some data tables.  There's a *
                   * lot of padding here to ensure page alignment.                                *
                   ********************************************************************************
                   * Disassembly by Andy McFadden, using 6502bench SourceGen v1.6.                *
                   * Last updated 2020/03/25                                                      *
                   ********************************************************************************
                   instr_DEC       .eq     $c6    {const}
                   instr_DEX       .eq     $ca    {const}
                   instr_INC       .eq     $e6    {const}
                   instr_INX       .eq     $e8    {const}
                   hpage           .eq     $32
                   VIEW_X_ADJ      .eq     $50    {addr/2}   ;translate viewport to screen coords
                   VIEW_Y_ADJ      .eq     $52    {addr/2}   ;translate viewport to screen coords
                   VIEW_LEFT       .eq     $54    {addr/2}   ;left edge of current viewport
                   VIEW_RIGHT      .eq     $56    {addr/2}   ;right edge of current viewport
                   VIEW_TOP        .eq     $58    {addr/2}   ;top edge of current viewport
                   VIEW_BOTTOM     .eq     $5a    {addr/2}   ;bottom edge of current viewport
                   UPDATE_DRAW_OBJECTS .eq $6010             ;updates and draws all active objects
                   RENDER_PAGE     .eq     $65f0             ;hi-res page to draw on (0=p1, 1=p2)
                   ERASE_VIEW_FLAG .eq     $65f1             ;bool 00/80: erase viewport before rendering
                   BLOCK_MOVEMENT0 .eq     $65f2             ;bool 00/80: don't move units when rendering page 0
                   BLOCK_MOVEMENT1 .eq     $65f3             ;bool 00/80: don't move units when rendering page 1
                   MESH_DATA_PTR   .eq     $65f4  {addr/2}   ;pointer to 3D mesh data
                   JMP_ADDR_CLEAR  .eq     $65f6  {addr/2}   ;ClearScreen or ClearViewport
                   JUMP_ADDR2      .eq     $65f8  {addr/2}   ;(initialized but not used)
                   JUMP_ADDR3      .eq     $65fa  {addr/2}   ;(initialized but not used)
                   SHOW_BKGND_FLAG .eq     $65fc             ;bool 00/80: show stars/mountains
                   HORIZON_BASELINE .eq    $65fd             ;adjusts star/mountain position
                   OBJ_ALIVE_FLAG  .eq     $6600  {addr/24}  ;bool 00/80: is object alive?
                   OBJ_TYPE        .eq     $6618  {addr/24}  ;object type, 0-63
                   OBJ_MAX_DIM     .eq     $6630  {addr/24}  ;largest dimension in mesh
                   OBJ_XC_LO       .eq     $6648  {addr/24}  ;object X coordinate, lo
                   OBJ_XC_HI       .eq     $6660  {addr/24}  ;object X coordinate, hi
                   OBJ_ZC_LO       .eq     $6678  {addr/24}  ;object Z coordinate, lo
                   OBJ_ZC_HI       .eq     $6690  {addr/24}  ;object Z coordinate, hi
                   OBJ_YC_LO       .eq     $66a8  {addr/24}  ;object Y coordinate, lo
                   OBJ_YC_HI       .eq     $66c0  {addr/24}  ;object Y coordinate, hi
                   OBJ_FACING      .eq     $66d8  {addr/24}  ;facing angle, 0-255
                   OBJ_XC_MOVE     .eq     $66f0  {addr/24}  ;add to obj XC each frame
                   OBJ_ZC_MOVE     .eq     $6708  {addr/24}  ;add to obj ZC each frame
                   OBJ_YC_MOVE     .eq     $6720  {addr/24}  ;add to obj YC each frame
                   OBJ_SPEED       .eq     $6738  {addr/24}  ;move fwd this much each frame
                   OBJ_FACING_ADJ  .eq     $6750  {addr/24}  ;offset facing for movement calc
                   OBJ_ROT_SPEED   .eq     $6768  {addr/24}  ;rotation speed, in angle256/frame
                   OBJ_IMMOB_FLAG  .eq     $6780  {addr/24}  ;bool 00/80: object is immobile
                   OBJ_VIS_FLAG    .eq     $6798  {addr/24}  ;bool 00/80: object is visible
                   VIEW_ACTV_FLAGS .eq     $67c0  {addr/4}   ;bool 00/80: is viewport N active
                   VIEW_SKIP_OBJS  .eq     $67c4  {addr/4}   ;viewer object (0-23), never shown
                   VIEW_ANGLE_ADJS .eq     $67c8  {addr/4}   ;angle adjustment, for left/right/rear view
                   VIEW_ZOOMS      .eq     $67cc  {addr/4}   ;camera zoom, 7=normal, 9=telephoto
                   VIEW_NEAR_VERT  .eq     $67d0  {addr/4}   ;near clip plane, applied to vertices
                   VIEW_NEAR_LO    .eq     $67d4  {addr/4}   ;near clip plane, applied to obj (low)
                   VIEW_NEAR_HI    .eq     $67d8  {addr/4}   ;near clip plane, applied to obj (hi)
                   VIEW_FAR_LO     .eq     $67dc  {addr/4}   ;far clip plane, applied to obj (low)
                   VIEW_FAR_HI     .eq     $67e0  {addr/4}   ;far clip plane, applied to obj (high)
                   VIEW_X_ADJS     .eq     $67e4  {addr/4}   ;viewport screen adjustments
                   VIEW_Y_ADJS     .eq     $67e8  {addr/4}   ;viewport screen adjustments
                   VIEW_LEFT_VALS  .eq     $67ec  {addr/4}   ;viewport bounds, left edge
                   VIEW_RIGHT_VALS .eq     $67f0  {addr/4}   ;viewport bounds, right edge
                   VIEW_TOP_VALS   .eq     $67f4  {addr/4}   ;viewport bounds, top edge
                   VIEW_BOTTOM_VALS .eq    $67f8  {addr/4}   ;viewport bounds, bottom edge
                   MESH_DATA       .eq     $6800             ;3D object mesh data
                   DRAW_MOUNTAINS  .eq     $7000             ;draw mountains (part of LEV#)
                   DRAW_STARS      .eq     $70b0             ;draw stars and horizon line (part of LEV#)
                   CLEAR_VIEWPORT  .eq     $7400             ;clear the viewport, page determined by A-reg
                   DRAW_HUD_ITEMS  .eq     $7e00             ;draw reticle, score, radar, shields/fuel
                   OBJ_MOVE_CLASS  .eq     $8418  {addr/24}  ;movement classes
                   SHOTS_VIS_FLAG  .eq     $8581             ;if nonzero, shots are visible on radar
                   UPDATE_SOUND    .eq     $a040             ;update sound effects
                   MIXCLR          .eq     $c052             ;RW display full screen

                                   .org    $0800
0800: 00 00 00 0a+                 .junk   16

                   ********************************************************************************
                   * Computes (val0 * 2^mult) / val1.  val0 may be signed.                        *
                   *                                                                              *
                   * Used for perspective calculations.  val0 is XC or YC, val1 is ZC, and the    *
                   * multiplier is 7 (128) for normal view, 9 (512) for zoom.  The result is the  *
                   * projected clip-space coordinate Px or Py.                                    *
                   *                                                                              *
                   * (If you include the mid-function page padding, this is 695 bytes long.)      *
                   *                                                                              *
                   * On entry:                                                                    *
                   *   $00/01: val0 (16-bit dividend, XC/YC)                                      *
                   *   $02/03: val1 (16-bit divisor, ZC)                                          *
                   *   $06: multiplier 2^N (e.g. pass 7 to multiply by 128)                       *
                   *                                                                              *
                   * On exit:                                                                     *
                   *   $00/01: quotient (16-bit)                                                  *
                   ********************************************************************************
                   ]dividend       .var    $00    {addr/2}   ;numerator
                   ]divisor        .var    $02    {addr/2}   ;denominator
                   ]val4           .var    $04    {addr/2}
                   ]mult2n         .var    $06    {addr/1}
                   ]tmp            .var    $09    {addr/1}

0810: a5 01        Divide16        lda     ]dividend+1       ;get high byte for sign flag
0812: 48                           pha                       ;save for later
0813: 10 0d                        bpl     :Pos              ;positive, branch
0815: 38                           sec                       ;negative, make it positive
0816: a9 00                        lda     #$00
0818: e5 00                        sbc     ]dividend
081a: 85 00                        sta     ]dividend
081c: a9 00                        lda     #$00
081e: e5 01                        sbc     ]dividend+1
0820: 85 01                        sta     ]dividend+1
0822: a6 06        :Pos            ldx     ]mult2n
0824: f0 12                        beq     :WasNeg
0826: a5 01                        lda     ]dividend+1       ;check sign flag again
0828: 30 0e                        bmi     :WasNeg
082a: 06 00        :ShiftLoop      asl     ]dividend         ;left-shift value until high bit set
082c: 2a                           rol     A                 ; to reduce iterations in divide code
082d: 30 04                        bmi     :ShiftDone
082f: ca                           dex                       ;reduce iterations
0830: d0 f8                        bne     :ShiftLoop        ;continue until we hit zero
0832: e8                           inx                       ;balance the next DEX
0833: ca           :ShiftDone      dex
0834: 86 06                        stx     ]mult2n           ;save updated multiplier
0836: 85 01                        sta     ]dividend+1       ; and numerator
0838: 20 00 09     :WasNeg         jsr     :DivideMain
083b: a6 06                        ldx     ]mult2n           ;are we done?
083d: f0 03                        beq     :DivideDone       ;yes
083f: 20 70 08                     jsr     :DivideFinish     ;no, apply finishing touches
0842: 68           :DivideDone     pla                       ;get original high byte
0843: 10 0d                        bpl     :Done             ;positive, we're done
0845: 38                           sec                       ;negative, flip arg1 back
0846: a9 00                        lda     #$00
0848: e5 00                        sbc     ]dividend
084a: 85 00                        sta     ]dividend
084c: a9 00                        lda     #$00
084e: e5 01                        sbc     ]dividend+1
0850: 85 01                        sta     ]dividend+1
0852: 60           :Done           rts

0853: 00 ff ff 00+                 .junk   29

0870: a5 03        :DivideFinish   lda     ]divisor+1
0872: d0 14                        bne     L0888
0874: a5 04                        lda     ]val4
0876: 0a           L0876           asl     A
0877: b0 04                        bcs     L087D
0879: c5 02                        cmp     ]divisor
087b: 90 03                        bcc     L0880
087d: e5 02        L087D           sbc     ]divisor
087f: 38                           sec
0880: 26 00        L0880           rol     ]dividend
0882: 26 01                        rol     ]dividend+1
0884: ca                           dex
0885: d0 ef                        bne     L0876
0887: 60                           rts

0888: 06 04        L0888           asl     ]val4
088a: 26 05                        rol     ]val4+1
088c: 90 0f                        bcc     L089D
088e: a5 04                        lda     ]val4
0890: e5 02                        sbc     ]divisor
0892: 85 04                        sta     ]val4
0894: a5 05                        lda     ]val4+1
0896: e5 03                        sbc     ]divisor+1
0898: 85 05                        sta     ]val4+1
089a: 38                           sec
089b: b0 10                        bcs     L08AD

089d: 38           L089D           sec
089e: a5 04                        lda     ]val4
08a0: e5 02                        sbc     ]divisor
08a2: a8                           tay
08a3: a5 05                        lda     ]val4+1
08a5: e5 03                        sbc     ]divisor+1
08a7: 90 04                        bcc     L08AD
08a9: 84 04                        sty     ]val4
08ab: 85 05                        sta     ]val4+1
08ad: 26 00        L08AD           rol     ]dividend
08af: 26 01                        rol     ]dividend+1
08b1: ca                           dex
08b2: d0 d4                        bne     L0888
08b4: 60                           rts

08b5: ff 00 00 ff+                 .align  $0100 (75 bytes)

                   ; Branch to a specific handler based on the input characteristics.
0900: a5 03        :DivideMain     lda     ]divisor+1        ;check high byte - denominator < 256?
0902: f0 17                        beq     :SmallDenom       ;yes, branch
0904: a5 01                        lda     ]dividend+1       ;small numerator?
0906: f0 04                        beq     :SmallNumBigDenom ;yes, branch
0908: c5 03                        cmp     ]divisor+1        ;is numerator high byte >= denominator?
090a: b0 1b                        bcs     :BigNumBigDen     ;yes, branch
                   ; The numerator is smaller than the denominator, so we know that the result will
                   ; be < 256.
                   :SmallNumBigDenom
090c: a5 01                        lda     ]dividend+1
090e: 85 05                        sta     ]val4+1
0910: a5 00                        lda     ]dividend
0912: 85 04                        sta     ]val4
0914: a9 00                        lda     #$00
0916: 85 01                        sta     ]dividend+1
0918: 85 00                        sta     ]dividend
091a: 60                           rts

                   ; Denominator is < 256.
091b: a5 01        :SmallDenom     lda     ]dividend+1       ;divisor+1 is zero...
091d: c5 02                        cmp     ]divisor          ;is numerator >= 256x divisor?
091f: 90 03                        bcc     :SmallDenom_jmp   ;no
0921: 4c 00 0a                     jmp     :HugeNumSmallDen  ;yes

0924: 4c 5a 0a     :SmallDenom_jmp jmp     :SmallDenom

                   ; Numerator is >= 256, denominator high byte is >= numerator high byte.
0927: a9 00        :BigNumBigDen   lda     #$00
0929: 85 09                        sta     ]tmp
092b: 06 00                        asl     ]dividend
092d: 26 01                        rol     ]dividend+1
092f: 26 09                        rol     ]tmp
0931: 38                           sec
0932: a5 01                        lda     ]dividend+1
0934: e5 02                        sbc     ]divisor
0936: a8                           tay
0937: a5 09                        lda     ]tmp
0939: e5 03                        sbc     ]divisor+1
093b: 90 04                        bcc     L0941
093d: 84 01                        sty     ]dividend+1
093f: 85 09                        sta     ]tmp
0941: 26 00        L0941           rol     ]dividend
0943: 26 01                        rol     ]dividend+1
0945: 26 09                        rol     ]tmp
0947: 38                           sec
0948: a5 01                        lda     ]dividend+1
094a: e5 02                        sbc     ]divisor
094c: a8                           tay
094d: a5 09                        lda     ]tmp
094f: e5 03                        sbc     ]divisor+1
0951: 90 04                        bcc     L0957
0953: 84 01                        sty     ]dividend+1
0955: 85 09                        sta     ]tmp
0957: 26 00        L0957           rol     ]dividend
0959: 26 01                        rol     ]dividend+1
095b: 26 09                        rol     ]tmp
095d: 38                           sec
095e: a5 01                        lda     ]dividend+1
0960: e5 02                        sbc     ]divisor
0962: a8                           tay
0963: a5 09                        lda     ]tmp
0965: e5 03                        sbc     ]divisor+1
0967: 90 04                        bcc     L096D
0969: 84 01                        sty     ]dividend+1
096b: 85 09                        sta     ]tmp
096d: 26 00        L096D           rol     ]dividend
096f: 26 01                        rol     ]dividend+1
0971: 26 09                        rol     ]tmp
0973: 38                           sec
0974: a5 01                        lda     ]dividend+1
0976: e5 02                        sbc     ]divisor
0978: a8                           tay
0979: a5 09                        lda     ]tmp
097b: e5 03                        sbc     ]divisor+1
097d: 90 04                        bcc     L0983
097f: 84 01                        sty     ]dividend+1
0981: 85 09                        sta     ]tmp
0983: 26 00        L0983           rol     ]dividend
0985: 26 01                        rol     ]dividend+1
0987: 26 09                        rol     ]tmp
0989: 38                           sec
098a: a5 01                        lda     ]dividend+1
098c: e5 02                        sbc     ]divisor
098e: a8                           tay
098f: a5 09                        lda     ]tmp
0991: e5 03                        sbc     ]divisor+1
0993: 90 04                        bcc     L0999
0995: 84 01                        sty     ]dividend+1
0997: 85 09                        sta     ]tmp
0999: 26 00        L0999           rol     ]dividend
099b: 26 01                        rol     ]dividend+1
099d: 26 09                        rol     ]tmp
099f: 38                           sec
09a0: a5 01                        lda     ]dividend+1
09a2: e5 02                        sbc     ]divisor
09a4: a8                           tay
09a5: a5 09                        lda     ]tmp
09a7: e5 03                        sbc     ]divisor+1
09a9: 90 04                        bcc     L09AF
09ab: 84 01                        sty     ]dividend+1
09ad: 85 09                        sta     ]tmp
09af: 26 00        L09AF           rol     ]dividend
09b1: 26 01                        rol     ]dividend+1
09b3: 26 09                        rol     ]tmp
09b5: 38                           sec
09b6: a5 01                        lda     ]dividend+1
09b8: e5 02                        sbc     ]divisor
09ba: a8                           tay
09bb: a5 09                        lda     ]tmp
09bd: e5 03                        sbc     ]divisor+1
09bf: 90 04                        bcc     L09C5
09c1: 84 01                        sty     ]dividend+1
09c3: 85 09                        sta     ]tmp
09c5: 26 00        L09C5           rol     ]dividend
09c7: 26 01                        rol     ]dividend+1
09c9: 26 09                        rol     ]tmp
09cb: 38                           sec
09cc: a5 01                        lda     ]dividend+1
09ce: e5 02                        sbc     ]divisor
09d0: a8                           tay
09d1: a5 09                        lda     ]tmp
09d3: e5 03                        sbc     ]divisor+1
09d5: 90 04                        bcc     L09DB
09d7: 84 01                        sty     ]dividend+1
09d9: 85 09                        sta     ]tmp
09db: 26 00        L09DB           rol     ]dividend
09dd: a5 09                        lda     ]tmp
09df: 85 05                        sta     ]val4+1
09e1: a5 01                        lda     ]dividend+1
09e3: 85 04                        sta     ]val4
09e5: a9 00                        lda     #$00
09e7: 85 01                        sta     ]dividend+1
09e9: 60                           rts

09ea: 00 00 ff ff+                 .align  $0100 (22 bytes)

                   ; Numerator is >= 256x the denominator.
                   :HugeNumSmallDen
0a00: a9 00                        lda     #$00
0a02: 06 01                        asl     ]dividend+1
0a04: 2a                           rol     A
0a05: c5 02                        cmp     ]divisor
0a07: 90 02                        bcc     L0A0B
0a09: e5 02                        sbc     ]divisor
0a0b: 26 01        L0A0B           rol     ]dividend+1
0a0d: 2a                           rol     A
0a0e: c5 02                        cmp     ]divisor
0a10: 90 02                        bcc     L0A14
0a12: e5 02                        sbc     ]divisor
0a14: 26 01        L0A14           rol     ]dividend+1
0a16: 2a                           rol     A
0a17: c5 02                        cmp     ]divisor
0a19: 90 02                        bcc     L0A1D
0a1b: e5 02                        sbc     ]divisor
0a1d: 26 01        L0A1D           rol     ]dividend+1
0a1f: 2a                           rol     A
0a20: c5 02                        cmp     ]divisor
0a22: 90 02                        bcc     L0A26
0a24: e5 02                        sbc     ]divisor
0a26: 26 01        L0A26           rol     ]dividend+1
0a28: 2a                           rol     A
0a29: c5 02                        cmp     ]divisor
0a2b: 90 02                        bcc     L0A2F
0a2d: e5 02                        sbc     ]divisor
0a2f: 26 01        L0A2F           rol     ]dividend+1
0a31: 2a                           rol     A
0a32: c5 02                        cmp     ]divisor
0a34: 90 02                        bcc     L0A38
0a36: e5 02                        sbc     ]divisor
0a38: 26 01        L0A38           rol     ]dividend+1
0a3a: 2a                           rol     A
0a3b: c5 02                        cmp     ]divisor
0a3d: 90 02                        bcc     L0A41
0a3f: e5 02                        sbc     ]divisor
0a41: 26 01        L0A41           rol     ]dividend+1
0a43: 2a                           rol     A
0a44: c5 02                        cmp     ]divisor
0a46: 90 02                        bcc     L0A4A
0a48: e5 02                        sbc     ]divisor
0a4a: 26 01        L0A4A           rol     ]dividend+1
0a4c: a6 01                        ldx     ]dividend+1
0a4e: 86 08                        stx     $08
0a50: 85 01                        sta     ]dividend+1
0a52: 20 5a 0a                     jsr     :SmallDenom
0a55: a5 08                        lda     $08
0a57: 85 01                        sta     ]dividend+1
0a59: 60                           rts

                   ; Numerator could be anything, denominator is < 256.
0a5a: a5 01        :SmallDenom     lda     ]dividend+1
0a5c: 06 00                        asl     ]dividend
0a5e: 2a                           rol     A
0a5f: b0 04                        bcs     L0A65
0a61: c5 02                        cmp     ]divisor
0a63: 90 03                        bcc     L0A68
0a65: e5 02        L0A65           sbc     ]divisor
0a67: 38                           sec
0a68: 26 00        L0A68           rol     ]dividend
0a6a: 2a                           rol     A
0a6b: b0 04                        bcs     L0A71
0a6d: c5 02                        cmp     ]divisor
0a6f: 90 03                        bcc     L0A74
0a71: e5 02        L0A71           sbc     ]divisor
0a73: 38                           sec
0a74: 26 00        L0A74           rol     ]dividend
0a76: 2a                           rol     A
0a77: b0 04                        bcs     L0A7D
0a79: c5 02                        cmp     ]divisor
0a7b: 90 03                        bcc     L0A80
0a7d: e5 02        L0A7D           sbc     ]divisor
0a7f: 38                           sec
0a80: 26 00        L0A80           rol     ]dividend
0a82: 2a                           rol     A
0a83: b0 04                        bcs     L0A89
0a85: c5 02                        cmp     ]divisor
0a87: 90 03                        bcc     L0A8C
0a89: e5 02        L0A89           sbc     ]divisor
0a8b: 38                           sec
0a8c: 26 00        L0A8C           rol     ]dividend
0a8e: 2a                           rol     A
0a8f: b0 04                        bcs     L0A95
0a91: c5 02                        cmp     ]divisor
0a93: 90 03                        bcc     L0A98
0a95: e5 02        L0A95           sbc     ]divisor
0a97: 38                           sec
0a98: 26 00        L0A98           rol     ]dividend
0a9a: 2a                           rol     A
0a9b: b0 04                        bcs     L0AA1
0a9d: c5 02                        cmp     ]divisor
0a9f: 90 03                        bcc     L0AA4
0aa1: e5 02        L0AA1           sbc     ]divisor
0aa3: 38                           sec
0aa4: 26 00        L0AA4           rol     ]dividend
0aa6: 2a                           rol     A
0aa7: b0 04                        bcs     L0AAD
0aa9: c5 02                        cmp     ]divisor
0aab: 90 03                        bcc     L0AB0
0aad: e5 02        L0AAD           sbc     ]divisor
0aaf: 38                           sec
0ab0: 26 00        L0AB0           rol     ]dividend
0ab2: 2a                           rol     A
0ab3: b0 04                        bcs     L0AB9
0ab5: c5 02                        cmp     ]divisor
0ab7: 90 03                        bcc     L0ABC
0ab9: e5 02        L0AB9           sbc     ]divisor
0abb: 38                           sec
0abc: 26 00        L0ABC           rol     ]dividend
0abe: 85 04                        sta     ]val4
0ac0: a9 00                        lda     #$00
0ac2: 85 05                        sta     ]val4+1
0ac4: 85 01                        sta     ]dividend+1
0ac6: 60                           rts

0ac7: 00 ff ff 00+                 .align  $0100 (57 bytes)

                   ********************************************************************************
                   * Rotates a pair of coordinates about a perpendicular axis (e.g. X,Z about Y). *
                   *                                                                              *
                   * Computes newX = X * cos(theta) - Z * sin(theta)                              *
                   *          newZ = X * sin(theta) + Z * cos(theta)                              *
                   *                                                                              *
                   * The math uses a right-handed coordinate system.  The angle expresses a full  *
                   * circle in 256 units.  An angle of 64 would rotate 90 degrees counter-        *
                   * clockwise.                                                                   *
                   *                                                                              *
                   * Called from ROCK2.                                                           *
                   *                                                                              *
                   * On entry:                                                                    *
                   *   $00/01: X coordinate (signed 16-bit)                                       *
                   *   $02/03: Z coordinate (signed 16-bit)                                       *
                   *   A-reg: angle (0-255)                                                       *
                   *                                                                              *
                   * On exit:                                                                     *
                   *   $04/05: rotated X coordinate (signed 16-bit)                               *
                   *   $06/07: rotated Z coordinate (signed 16-bit)                               *
                   ********************************************************************************
                   • Clear variables
                   ]xc             .var    $00    {addr/2}
                   ]zc             .var    $02    {addr/2}
                   ]rot_xc         .var    $04    {addr/2}
                   ]rot_zc         .var    $06    {addr/2}
                   ]sin_theta      .var    $08    {addr/1}
                   ]cos_theta      .var    $09    {addr/1}

0b00: a8           RotateCoords    tay                       ;preserve A-reg
0b01: 29 3f                        and     #$3f              ;check low 6 bits (test for 90-degree angles)
0b03: f0 56                        beq     :TrivialAngle     ;zero, branch
0b05: b9 00 0f                     lda     rotate_tab,y      ;get cos(theta)
0b08: 85 09                        sta     ]cos_theta
0b0a: 18                           clc
0b0b: 98                           tya
0b0c: 69 c0                        adc     #$c0              ;sine is 1/4 out of phase
0b0e: a8                           tay
0b0f: b9 00 0f                     lda     rotate_tab,y      ;get sin(theta)
0b12: 85 08                        sta     ]sin_theta
                   ; compute rotated XC
0b14: a5 09                        lda     ]cos_theta
0b16: a6 00                        ldx     ]xc
0b18: a4 01                        ldy     ]xc+1
0b1a: 20 00 0c                     jsr     Multiply16_8      ;compute XC * cos(theta)
0b1d: 85 05                        sta     ]rot_xc+1
0b1f: 84 04                        sty     ]rot_xc
0b21: a5 08                        lda     ]sin_theta        ;flip the sign bit on the sine value
0b23: 49 80                        eor     #$80              ; (high bit is a signal to the multiplication
0b25: a6 02                        ldx     ]zc               ; function; sign-extension not required)
0b27: a4 03                        ldy     ]zc+1
0b29: 20 00 0c                     jsr     Multiply16_8      ;compute YC * sin(theta)
0b2c: aa                           tax                       ;rotXC = XC * cos(theta) - YC * sin(theta)
0b2d: 18                           clc
0b2e: 98                           tya
0b2f: 65 04                        adc     ]rot_xc
0b31: 85 04                        sta     ]rot_xc
0b33: 8a                           txa
0b34: 65 05                        adc     ]rot_xc+1
0b36: 85 05                        sta     ]rot_xc+1
                   ; compute rotated YC
0b38: a5 08                        lda     ]sin_theta
0b3a: a6 00                        ldx     ]xc
0b3c: a4 01                        ldy     ]xc+1
0b3e: 20 00 0c                     jsr     Multiply16_8      ;compute XC * sin(theta)
0b41: 85 07                        sta     ]rot_zc+1
0b43: 84 06                        sty     ]rot_zc
0b45: a5 09                        lda     ]cos_theta
0b47: a6 02                        ldx     ]zc
0b49: a4 03                        ldy     ]zc+1
0b4b: 20 00 0c                     jsr     Multiply16_8      ;compute YC * cos(theta)
0b4e: aa                           tax                       ;rotYC = XC * sin(theta) + YC * cos(theta)
0b4f: 18                           clc
0b50: 98                           tya
0b51: 65 06                        adc     ]rot_zc
0b53: 85 06                        sta     ]rot_zc
0b55: 8a                           txa
0b56: 65 07                        adc     ]rot_zc+1
0b58: 85 07                        sta     ]rot_zc+1
0b5a: 60                           rts

0b5b: 98           :TrivialAngle   tya                       ;check full acc
0b5c: d0 11                        bne     :AngleNotZero     ;not zero, branch
0b5e: a5 00                        lda     ]xc               ;angle=0, just copy input args to output
0b60: 85 04                        sta     ]rot_xc
0b62: a5 01                        lda     ]xc+1
0b64: 85 05                        sta     ]rot_xc+1
0b66: a5 02                        lda     ]zc
0b68: 85 06                        sta     ]rot_zc
0b6a: a5 03                        lda     ]zc+1
0b6c: 85 07                        sta     ]rot_zc+1
0b6e: 60                           rts

0b6f: 30 16        :AngleNotZero   bmi     :AngleNeg         ;if negative, branch
0b71: 38                           sec                       ;angle=64, ccw 90 degrees
0b72: a9 00                        lda     #$00              ;rotated XC = -YC
0b74: e5 02                        sbc     ]zc
0b76: 85 04                        sta     ]rot_xc
0b78: a9 00                        lda     #$00
0b7a: e5 03                        sbc     ]zc+1
0b7c: 85 05                        sta     ]rot_xc+1
0b7e: a5 00                        lda     ]xc               ;rotated YC = XC
0b80: 85 06                        sta     ]rot_zc
0b82: a5 01                        lda     ]xc+1
0b84: 85 07                        sta     ]rot_zc+1
0b86: 60                           rts

0b87: 29 40        :AngleNeg       and     #$40              ;check bit 6
0b89: d0 1b                        bne     :Angle192
0b8b: 38                           sec                       ;angle=128, ccw 180deg
0b8c: a9 00                        lda     #$00              ;rotated XC = -XC
0b8e: e5 00                        sbc     ]xc
0b90: 85 04                        sta     ]rot_xc
0b92: a9 00                        lda     #$00
0b94: e5 01                        sbc     ]xc+1
0b96: 85 05                        sta     ]rot_xc+1
0b98: 38                           sec                       ;rotated YC = -YC
0b99: a9 00                        lda     #$00
0b9b: e5 02                        sbc     ]zc
0b9d: 85 06                        sta     ]rot_zc
0b9f: a9 00                        lda     #$00
0ba1: e5 03                        sbc     ]zc+1
0ba3: 85 07                        sta     ]rot_zc+1
0ba5: 60                           rts

0ba6: a5 02        :Angle192       lda     ]zc               ;angle=192, ccw 270deg
0ba8: 85 04                        sta     ]rot_xc           ;rotated XC = YC
0baa: a5 03                        lda     ]zc+1
0bac: 85 05                        sta     ]rot_xc+1
0bae: 38                           sec                       ;rotated YC = -XC
0baf: a9 00                        lda     #$00
0bb1: e5 00                        sbc     ]xc
0bb3: 85 06                        sta     ]rot_zc
0bb5: a9 00                        lda     #$00
0bb7: e5 01                        sbc     ]xc+1
0bb9: 85 07                        sta     ]rot_zc+1
0bbb: 60                           rts

                   ; This looks like a couple of functions, one of which runs into $c00, but the
                   ; code isn't referenced and it never tripped in a debugger.
0bbc: 03 a2 00 a5+                 .align  $0100 (68 bytes)

                   ********************************************************************************
                   * Multiplies a signed 16-bit value by a an 8-bit value.                        *
                   *                                                                              *
                   * Used for rotations.  Only called within ROCK1.                               *
                   *                                                                              *
                   * The caller handles 90-degree rotations, so A-reg will never be zero.         *
                   *                                                                              *
                   * On entry:                                                                    *
                   *   X-reg: low part of first value                                             *
                   *   Y-reg: high part of first value                                            *
                   *   A-reg: second value; set high bit for negative                             *
                   *   flags must be set for Y-reg contents (so load that last)                   *
                   *                                                                              *
                   * On exit:                                                                     *
                   *   Y-reg: low part of result                                                  *
                   *   A-reg: high part of result                                                 *
                   ********************************************************************************
                   • Clear variables
                   ]tmp1           .var    $0a    {addr/1}
                   ]tmp2           .var    $0b    {addr/1}
                   ]tmp3           .var    $0c    {addr/1}
                   ]result_lo      .var    $0d    {addr/1}

0c00: 10 14        Multiply16_8    bpl     :PosVal           ;value is positive, branch
0c02: 49 80                        eor     #$80              ;value negative, clear high bit
0c04: 4a                           lsr     A
0c05: 85 0c                        sta     ]tmp3
0c07: 8a                           txa                       ;negate first value
0c08: 49 ff                        eor     #$ff
0c0a: 85 0a                        sta     ]tmp1
0c0c: 98                           tya
0c0d: 49 ff                        eor     #$ff
0c0f: 85 0b                        sta     ]tmp2
0c11: 4c 27 0c                     jmp     :Common           ;branch skips DEX/DEY below

0c14: 98           :Zero           tya                       ;set A-reg=0
0c15: 60                           rts                       ; and bail

0c16: e0 00        :PosVal         cpx     #$00              ;is low part zero?
0c18: d0 05                        bne     L0C1F             ;no
0c1a: c0 00                        cpy     #$00              ;is high part zero?
0c1c: f0 f6                        beq     :Zero             ;yes, result is zero
0c1e: 88                           dey
0c1f: ca           L0C1F           dex
0c20: 86 0a                        stx     ]tmp1
0c22: 84 0b                        sty     ]tmp2
0c24: 4a                           lsr     A
0c25: 85 0c                        sta     ]tmp3
0c27: a9 00        :Common         lda     #$00
0c29: 85 0d                        sta     ]result_lo
0c2b: 90 0a                        bcc     L0C37
0c2d: a8                           tay
0c2e: a5 0d                        lda     ]result_lo
0c30: 65 0a                        adc     ]tmp1
0c32: 85 0d                        sta     ]result_lo
0c34: 98                           tya
0c35: 65 0b                        adc     ]tmp2
0c37: 6a           L0C37           ror     A
0c38: 66 0d                        ror     ]result_lo
0c3a: 66 0c                        ror     ]tmp3
0c3c: 90 0a                        bcc     L0C48
0c3e: a8                           tay
0c3f: a5 0d                        lda     ]result_lo
0c41: 65 0a                        adc     ]tmp1
0c43: 85 0d                        sta     ]result_lo
0c45: 98                           tya
0c46: 65 0b                        adc     ]tmp2
0c48: 6a           L0C48           ror     A
0c49: 66 0d                        ror     ]result_lo
0c4b: 66 0c                        ror     ]tmp3
0c4d: 90 0a                        bcc     L0C59
0c4f: a8                           tay
0c50: a5 0d                        lda     ]result_lo
0c52: 65 0a                        adc     ]tmp1
0c54: 85 0d                        sta     ]result_lo
0c56: 98                           tya
0c57: 65 0b                        adc     ]tmp2
0c59: 6a           L0C59           ror     A
0c5a: 66 0d                        ror     ]result_lo
0c5c: 66 0c                        ror     ]tmp3
0c5e: 90 0a                        bcc     L0C6A
0c60: a8                           tay
0c61: a5 0d                        lda     ]result_lo
0c63: 65 0a                        adc     ]tmp1
0c65: 85 0d                        sta     ]result_lo
0c67: 98                           tya
0c68: 65 0b                        adc     ]tmp2
0c6a: 6a           L0C6A           ror     A
0c6b: 66 0d                        ror     ]result_lo
0c6d: 66 0c                        ror     ]tmp3
0c6f: 90 0a                        bcc     L0C7B
0c71: a8                           tay
0c72: a5 0d                        lda     ]result_lo
0c74: 65 0a                        adc     ]tmp1
0c76: 85 0d                        sta     ]result_lo
0c78: 98                           tya
0c79: 65 0b                        adc     ]tmp2
0c7b: 6a           L0C7B           ror     A
0c7c: 66 0d                        ror     ]result_lo
0c7e: 66 0c                        ror     ]tmp3
0c80: 90 0a                        bcc     L0C8C
0c82: a8                           tay
0c83: a5 0d                        lda     ]result_lo
0c85: 65 0a                        adc     ]tmp1
0c87: 85 0d                        sta     ]result_lo
0c89: 98                           tya
0c8a: 65 0b                        adc     ]tmp2
0c8c: 6a           L0C8C           ror     A
0c8d: 66 0d                        ror     ]result_lo
0c8f: 66 0c                        ror     ]tmp3
0c91: 90 0a                        bcc     L0C9D
0c93: a8                           tay
0c94: a5 0d                        lda     ]result_lo
0c96: 65 0a                        adc     ]tmp1
0c98: 85 0d                        sta     ]result_lo
0c9a: 98                           tya
0c9b: 65 0b                        adc     ]tmp2
0c9d: 6a           L0C9D           ror     A
0c9e: 66 0d                        ror     ]result_lo
0ca0: 66 0c                        ror     ]tmp3
0ca2: 90 0e                        bcc     L0CB2
0ca4: aa                           tax
0ca5: a5 0d                        lda     ]result_lo
0ca7: 49 ff                        eor     #$ff
0ca9: 69 00                        adc     #$00
0cab: a8                           tay
0cac: 8a                           txa
0cad: 49 ff                        eor     #$ff
0caf: 69 00                        adc     #$00
0cb1: 60                           rts

0cb2: a4 0d        L0CB2           ldy     ]result_lo
0cb4: 60                           rts

0cb5: ff 00 00 ff+                 .junk   27
                   ; 
                   ; Scaled coordinates for radar display.  Signed 8-bit values.  Drawn by ROCK2 at
                   ; $7e6c.
                   ; 
                   ; The radar is 28x28.  Objects may be outside that range, and won't be shown.
0cd0: ff ff 00 00+ radar_xcoords   .junk   24
0ce8: ff ff 00 00+ radar_ycoords   .junk   24

                   ********************************************************************************
                   * Rotates the coordinate (X,0) about a perpendicular axis (let's say Y).  Used *
                   * for object movement calculations and mesh transformation.                    *
                   *                                                                              *
                   * On entry:                                                                    *
                   *   $00: X coordinate (8-bit value; seems to be 0-127)                         *
                   *   A-reg: angle (0-255)                                                       *
                   *                                                                              *
                   * On exit:                                                                     *
                   *   $22/23: rotated X coordinate (signed 16-bit)                               *
                   *   $24/25: rotated Z coordinate (signed 16-bit)                               *
                   *                                                                              *
                   * The return values seem to be -128 < val < 128, which makes sense given the   *
                   * input value range, so the high byte is redundant.                            *
                   ********************************************************************************
                   • Clear variables
                   ]xc             .var    $00    {addr/1}
                   ]val1           .var    $01    {addr/1}
                   ]val2           .var    $02    {addr/1}
                   ]rot_xc         .var    $22    {addr/2}
                   ]rot_yc         .var    $24    {addr/2}

0d00: a6 00        RotateInt8      ldx     ]xc               ;is coordinate value zero?
0d02: d0 09                        bne     :NotZero          ;no, do the work
0d04: 86 22                        stx     ]rot_xc           ;yes, result is zero
0d06: 86 23                        stx     ]rot_xc+1
0d08: 86 24                        stx     ]rot_yc
0d0a: 86 25                        stx     ]rot_yc+1
0d0c: 60                           rts

0d0d: a8           :NotZero        tay                       ;preserve angle
0d0e: 29 3f                        and     #$3f              ;check for simple case
0d10: d0 03                        bne     :NotTrivial       ;nonzero, do it the hard way
0d12: 4c b3 0d                     jmp     :SimpleAngle      ;yes

                   ; Calculate the X coordinate.
0d15: b9 00 0f     :NotTrivial     lda     rotate_tab,y      ;get cos(theta)
0d18: ca                           dex                       ;X-reg = XC - 1
0d19: 86 01                        stx     ]val1             ;save as multiplier part
0d1b: 4a                           lsr     A                 ;get low bit of cosine
0d1c: 85 02                        sta     ]val2             ;high byte of 8.8 result
0d1e: a9 00                        lda     #$00              ;low byte of 8.8 result
0d20: 90 02                        bcc     L0D24
0d22: 65 01                        adc     ]val1
0d24: 6a           L0D24           ror     A
0d25: 66 02                        ror     ]val2
0d27: 90 02                        bcc     L0D2B
0d29: 65 01                        adc     ]val1
0d2b: 6a           L0D2B           ror     A
0d2c: 66 02                        ror     ]val2
0d2e: 90 02                        bcc     L0D32
0d30: 65 01                        adc     ]val1
0d32: 6a           L0D32           ror     A
0d33: 66 02                        ror     ]val2
0d35: 90 02                        bcc     L0D39
0d37: 65 01                        adc     ]val1
0d39: 6a           L0D39           ror     A
0d3a: 66 02                        ror     ]val2
0d3c: 90 02                        bcc     L0D40
0d3e: 65 01                        adc     ]val1
0d40: 6a           L0D40           ror     A
0d41: 66 02                        ror     ]val2
0d43: 90 02                        bcc     L0D47
0d45: 65 01                        adc     ]val1
0d47: 6a           L0D47           ror     A
0d48: 66 02                        ror     ]val2
0d4a: 90 02                        bcc     L0D4E
0d4c: 65 01                        adc     ]val1
0d4e: 6a           L0D4E           ror     A
0d4f: 66 02                        ror     ]val2
0d51: a2 00                        ldx     #$00
0d53: 90 07                        bcc     L0D5C
0d55: 49 ff                        eor     #$ff
0d57: 69 00                        adc     #$00
0d59: f0 01                        beq     L0D5C
0d5b: ca                           dex
0d5c: 85 22        L0D5C           sta     ]rot_xc           ;rotated XC = X * cos(theta)
0d5e: 86 23                        stx     ]rot_xc+1
                   ; Now calculate the Y coordinate.
0d60: a6 00                        ldx     ]xc
0d62: 98                           tya
0d63: 18                           clc
0d64: 69 c0                        adc     #$c0              ;sine is offset by 1/4 phase
0d66: a8                           tay
0d67: b9 00 0f                     lda     rotate_tab,y      ;get sin(theta)
0d6a: ca                           dex                       ;X-reg = XC - 1
0d6b: 86 01                        stx     ]val1
0d6d: 4a                           lsr     A
0d6e: 85 02                        sta     ]val2
0d70: a9 00                        lda     #$00
0d72: 90 02                        bcc     L0D76
0d74: 65 01                        adc     ]val1
0d76: 6a           L0D76           ror     A
0d77: 66 02                        ror     ]val2
0d79: 90 02                        bcc     L0D7D
0d7b: 65 01                        adc     ]val1
0d7d: 6a           L0D7D           ror     A
0d7e: 66 02                        ror     ]val2
0d80: 90 02                        bcc     L0D84
0d82: 65 01                        adc     ]val1
0d84: 6a           L0D84           ror     A
0d85: 66 02                        ror     ]val2
0d87: 90 02                        bcc     L0D8B
0d89: 65 01                        adc     ]val1
0d8b: 6a           L0D8B           ror     A
0d8c: 66 02                        ror     ]val2
0d8e: 90 02                        bcc     L0D92
0d90: 65 01                        adc     ]val1
0d92: 6a           L0D92           ror     A
0d93: 66 02                        ror     ]val2
0d95: 90 02                        bcc     L0D99
0d97: 65 01                        adc     ]val1
0d99: 6a           L0D99           ror     A
0d9a: 66 02                        ror     ]val2
0d9c: 90 02                        bcc     L0DA0
0d9e: 65 01                        adc     ]val1
0da0: 6a           L0DA0           ror     A
0da1: 66 02                        ror     ]val2
0da3: a2 00                        ldx     #$00
0da5: 90 07                        bcc     L0DAE             ;last bit was clear, branch
0da7: 49 ff                        eor     #$ff              ;negate low byte
0da9: 69 00                        adc     #$00              ;note carry is set
0dab: f0 01                        beq     L0DAE
0dad: ca                           dex
0dae: 85 24        L0DAE           sta     ]rot_yc           ;rotated YC = X * sin(theta)
0db0: 86 25                        stx     ]rot_yc+1
0db2: 60                           rts

0db3: 98           :SimpleAngle    tya                       ;check full angle
0db4: d0 0d                        bne     :AngleNotZero
0db6: a2 00                        ldx     #$00              ;angle=0
0db8: 86 24                        stx     ]rot_yc           ;rotated YC = 0
0dba: 86 25                        stx     ]rot_yc+1
0dbc: a5 00                        lda     ]xc               ;rotated XC = XC
0dbe: 85 22                        sta     ]rot_xc
0dc0: 86 23                        stx     ]rot_xc+1
0dc2: 60                           rts

0dc3: 30 0d        :AngleNotZero   bmi     :AngleNeg
0dc5: a2 00                        ldx     #$00              ;rotated XC = 0
0dc7: 86 22                        stx     ]rot_xc
0dc9: 86 23                        stx     ]rot_xc+1
0dcb: a5 00                        lda     ]xc               ;rotated YC = XC
0dcd: 85 24                        sta     ]rot_yc
0dcf: 86 25                        stx     ]rot_yc+1
0dd1: 60                           rts

0dd2: 29 40        :AngleNeg       and     #$40              ;bit 6 set?
0dd4: d0 10                        bne     :Angle192         ;yes
0dd6: a2 00                        ldx     #$00              ;rotated YC = 0
0dd8: 86 24                        stx     ]rot_yc
0dda: 86 25                        stx     ]rot_yc+1
0ddc: 38                           sec                       ;rotated XC = -XC
0ddd: 8a                           txa
0dde: e5 00                        sbc     ]xc
0de0: 85 22                        sta     ]rot_xc
0de2: ca                           dex
0de3: 86 23                        stx     ]rot_xc+1
0de5: 60                           rts

0de6: a2 00        :Angle192       ldx     #$00              ;rotated XC = 0
0de8: 86 22                        stx     ]rot_xc
0dea: 86 23                        stx     ]rot_xc+1
0dec: 38                           sec                       ;rotated YC = -XC
0ded: 8a                           txa
0dee: e5 00                        sbc     ]xc
0df0: 85 24                        sta     ]rot_yc
0df2: ca                           dex
0df3: 86 25                        stx     ]rot_yc+1
0df5: 60                           rts

0df6: 00 00 ff ff+                 .junk   10
                   ; 
                   ; This holds the result of projecting 3D vertices into 16-bit clip-space
                   ; coordinates.
0e00: ff ff 00 00+ clip_coord_xlo  .junk   64
0e40: ff ff 00 00+ clip_coord_xhi  .junk   64
0e80: ff ff 00 00+ clip_coord_ylo  .junk   64
0ec0: ff ff 00 00+ clip_coord_yhi  .junk   64
                   ; 
                   ; Sine/cosine values for rotation calculation (256 entries).  cos(N) starts at
                   ; offset 0, sin(N) is at +192.  Angle represents a counter-clockwise rotation.
                   ; 
                   ; Values are signed 8-bit.
                   ; 
                   ; The entries at 0/64/128/192 aren't used, as the 90-degree angles are special-
                   ; cased in the code.
0f00: ff 7f 7f 7f+ rotate_tab      .bulk   $ff,$7f,$7f,$7f,$7f,$7f,$7f,$7e,$7e,$7d,$7c,$7b,$7a,$7a,$79,$77
                                    +      $76,$75,$74,$72,$71,$6f,$6e,$6c,$6a,$69,$67,$65,$63,$61,$5f,$5d
                                    +      $5b,$58,$56,$54,$51,$4f,$4c,$4a,$47,$44,$42,$3f,$3c,$3a,$37,$34
                                    +      $31,$2e,$2b,$28,$25,$22,$1f,$1c,$19,$16,$13,$10,$0d,$09,$06,$03
                                    +      $ff,$83,$86,$89,$8d,$90,$93,$96,$99,$9c,$9f,$a2,$a5,$a8,$ab,$ae
                                    +      $b1,$b4,$b7,$ba,$bc,$bf,$c2,$c4,$c7,$ca,$cc,$cf,$d1,$d4,$d6,$d8
                                    +      $db,$dd,$df,$e1,$e3,$e5,$e7,$e9,$ea,$ec,$ee,$ef,$f1,$f2,$f4,$f5
                                    +      $f6,$f7,$f9,$fa,$fa,$fb,$fc,$fd,$fe,$fe,$ff,$ff,$ff,$ff,$ff,$ff
                                    +      $ff,$ff,$ff,$ff,$ff,$ff,$ff,$fe,$fe,$fd,$fc,$fb,$fa,$fa,$f9,$f7
                                    +      $f6,$f5,$f4,$f2,$f1,$ef,$ee,$ec,$ea,$e9,$e7,$e5,$e3,$e1,$df,$dd
                                    +      $db,$d8,$d6,$d4,$d1,$cf,$cc,$ca,$c7,$c4,$c2,$bf,$bc,$ba,$b7,$b4
                                    +      $b1,$ae,$ab,$a8,$a5,$a2,$9f,$9c,$99,$96,$93,$90,$8d,$89,$86,$83
                                    +      $ff,$03,$06,$09,$0d,$10,$13,$16,$19,$1c,$1f,$22,$25,$28,$2b,$2e
                                    +      $31,$34,$37,$3a,$3c,$3f,$42,$44,$47,$4a,$4c,$4f,$51,$54,$56,$58
                                    +      $5b,$5d,$5f,$61,$63,$65,$67,$69,$6a,$6c,$6e,$6f,$71,$72,$74,$75
                                    +      $76,$77,$79,$7a,$7a,$7b,$7c,$7d,$7e,$7e,$7f,$7f,$7f,$7f,$7f,$7f

                   ********************************************************************************
                   * Draws a line on the hi-res screen.                                           *
                   *                                                                              *
                   * Called internally (post clip) and from ROCK2.                                *
                   *                                                                              *
                   * On entry:                                                                    *
                   *   $00/01: x0,y0                                                              *
                   *   $02/03: x1,y1                                                              *
                   ********************************************************************************
                   ]x0             .var    $00    {addr/1}
                   ]y0             .var    $01    {addr/1}
                   ]x1             .var    $02    {addr/1}
                   ]y1             .var    $03    {addr/1}
                   ]pixel_index    .var    $04    {addr/1}
                   ]end_pixel_index .var   $05    {addr/1}
                   ]delta_x        .var    $07    {addr/1}
                   ]delta_y        .var    $08    {addr/1}
                   ]div_result     .var    $09    {addr/2}
                   ]y_direction    .var    $0f    {addr/1}

1000: 38           DrawLine        sec                       ;compute deltaX
1001: a5 02                        lda     ]x1
1003: e5 00                        sbc     ]x0
1005: d0 30                        bne     :NotVert          ;nonzero, branch
1007: a5 03                        lda     ]y1               ;compute deltaY
1009: e5 01                        sbc     ]y0
100b: d0 0f                        bne     :Vert             ;nonzero, branch to vertical line handler
100d: a4 00                        ldy     ]x0               ;both zero, draw a point
100f: b9 00 17                     lda     div7_tab,y
1012: 85 00                        sta     ]x0               ;col
1014: b9 00 18                     lda     mod7_tab,y
1017: 85 04                        sta     ]pixel_index      ;pixel index (0-7)
1019: 4c cd 14                     jmp     DrawPoint         ;draw and bail

101c: b0 0a        :Vert           bcs     :Y0OnTop          ;branch if y1 > y0
101e: a5 01                        lda     ]y0               ;flip y0/y1 so y0 is on top
1020: 48                           pha
1021: a5 03                        lda     ]y1
1023: 85 01                        sta     ]y0
1025: 68                           pla
1026: 85 03                        sta     ]y1
1028: a4 00        :Y0OnTop        ldy     ]x0               ;prep for vertical line
102a: b9 00 17                     lda     div7_tab,y
102d: 85 00                        sta     ]x0               ;col
102f: b9 00 18                     lda     mod7_tab,y
1032: 85 04                        sta     ]pixel_index      ;pixel index (0-7)
1034: 4c 9e 14                     jmp     DrawVerticalLine

1037: 85 07        :NotVert        sta     ]delta_x
1039: b0 1b                        bcs     :X0OnLeft         ;if x1 > x0, branch
103b: 49 ff                        eor     #$ff              ;deltaX = -deltaX
103d: 18                           clc
103e: 69 01                        adc     #$01
1040: 85 07                        sta     ]delta_x
1042: a5 00                        lda     ]x0               ;flip x0/x1 and y0/y1 so x0 is on the left
1044: 48                           pha
1045: a5 02                        lda     ]x1
1047: 85 00                        sta     ]x0
1049: 68                           pla
104a: 85 02                        sta     ]x1
104c: a5 01                        lda     ]y0
104e: 48                           pha
104f: a5 03                        lda     ]y1
1051: 85 01                        sta     ]y0
1053: 68                           pla
1054: 85 03                        sta     ]y1
1056: 38           :X0OnLeft       sec                       ;compute deltaY
1057: a5 03                        lda     ]y1
1059: e5 01                        sbc     ]y0
105b: d0 1b                        bne     :NotHoriz         ;branch if not horizontal
105d: a4 02                        ldy     ]x1               ;prep for horizontal line
105f: b9 00 17                     lda     div7_tab,y
1062: 85 02                        sta     ]x1               ;last byte
1064: b9 00 18                     lda     mod7_tab,y
1067: 85 05                        sta     ]end_pixel_index  ;last pixel index
1069: a4 00                        ldy     ]x0
106b: b9 00 17                     lda     div7_tab,y
106e: 85 00                        sta     ]x0               ;first byte
1070: b9 00 18                     lda     mod7_tab,y
1073: 85 04                        sta     ]pixel_index      ;first pixel index
1075: 4c 00 14                     jmp     DrawHorizontal

1078: a2 00        :NotHoriz       ldx     #$00              ;set Y direction to 0 (pos) or 1 (neg)
107a: b0 07                        bcs     :PosDeltaY        ;if deltaY positive, branch
107c: a2 01                        ldx     #$01              ;set deltaY = -deltaY
107e: 49 ff                        eor     #$ff
1080: 18                           clc
1081: 69 01                        adc     #$01
1083: 85 08        :PosDeltaY      sta     ]delta_y
1085: 86 0f                        stx     ]y_direction
1087: 20 40 a0                     jsr     UPDATE_SOUND
108a: a5 07                        lda     ]delta_x          ;compare deltas
108c: c5 08                        cmp     ]delta_y
108e: 90 35                        bcc     :VertDom          ;deltaX < deltaY, vertically dominant
1090: a5 07                        lda     ]delta_x          ;handle horizontally-dominant line
1092: a6 08                        ldx     ]delta_y
1094: 20 00 11                     jsr     CalcLineSlope     ;compute deltaX / (deltaY+1)
1097: a4 02                        ldy     ]x1
1099: b9 00 17                     lda     div7_tab,y
109c: 85 02                        sta     ]x1               ;replace end coord with end col
109e: b9 00 18                     lda     mod7_tab,y
10a1: 85 05                        sta     ]end_pixel_index  ;and end pixel index
10a3: a4 00                        ldy     ]x0
10a5: b9 00 17                     lda     div7_tab,y
10a8: 85 00                        sta     ]x0               ;replace start coord with start col
10aa: b9 00 18                     lda     mod7_tab,y
10ad: 85 04                        sta     ]pixel_index      ;and start pixel index
10af: 20 40 a0                     jsr     UPDATE_SOUND
10b2: a5 0a                        lda     ]div_result+1     ;check integer part of quotient
10b4: c9 03                        cmp     #$03              ;>= 3?
10b6: b0 03                        bcs     :MedLong          ;yes, branch
10b8: 4c 00 12                     jmp     DrawHorizShortRun

10bb: c9 07        :MedLong        cmp     #$07              ;>= 7?
10bd: b0 03                        bcs     :LongRun
10bf: 4c 00 13                     jmp     DrawHorizMedRun

10c2: 4c 7c 13     :LongRun        jmp     DrawHorizLongRun

10c5: a5 08        :VertDom        lda     ]delta_y          ;compute deltaY / (deltaX+1)
10c7: a6 07                        ldx     ]delta_x
10c9: 20 00 11                     jsr     CalcLineSlope
10cc: a4 00                        ldy     ]x0
10ce: b9 00 17                     lda     div7_tab,y
10d1: 85 00                        sta     ]x0
10d3: b9 00 18                     lda     mod7_tab,y
10d6: 85 04                        sta     ]pixel_index
10d8: 20 40 a0                     jsr     UPDATE_SOUND
10db: 4c 41 14                     jmp     DrawVertDom

10de: 00 00 ff ff+                 .align  $0100 (34 bytes)

                   ********************************************************************************
                   * Compute A/(B+1), generating an 8.8 fixed-point result.  Both values must be  *
                   * positive.                                                                    *
                   *                                                                              *
                   * This is used to compute the run-slice length and error term, dividing deltaX *
                   * by deltaY or vice-versa (larger value on top).                               *
                   *                                                                              *
                   * Only used internally.  Loops are unrolled for speed.  Takes about 270        *
                   * cycles.                                                                      *
                   *                                                                              *
                   * This result is sometimes off by one, e.g. A=0D X=03 -> $0340 (correct), but  *
                   * A=17 X=0C -> $01C5 (should be $01C4).                                        *
                   *                                                                              *
                   * When deltaX==deltaY (diagonal line), the integer part of the quotient will   *
                   * be zero, but the fractional part will be large (e.g. 127/128 yields 00 FE).  *
                   * Every iteration will start with a slice length of zero, but adding FE sets   *
                   * the carry.  Because the hi-res screen is less than 255 lines high we never   *
                   * get to a point where updating the error term fails to set the carry flag, so *
                   * we always get a proper diagonal line.                                        *
                   *                                                                              *
                   * General line-drawing note: the canonical run-slice code uses A/B rather than *
                   * A/(B+1).  For a shallow line like (0,0) to (32,1), the mid-line step is      *
                   * created by the initial/final pixel count setup (which uses delta/2), but     *
                   * this code doesn't seem to do that.  (It might be instructive to do a pixel-  *
                   * by-pixel comparison of this vs. classic Bresenham.  If you watch the LEV1    *
                   * mountains while rotating, they look a bit off at the edges of the screen.)   *
                   *                                                                              *
                   * On entry:                                                                    *
                   *   A-reg: numerator                                                           *
                   *   X-reg: denominator                                                         *
                   *                                                                              *
                   * On exit:                                                                     *
                   *   $09/0a: 8.8 fixed-point result                                             *
                   ********************************************************************************
                   • Clear variables
                   ]result         .var    $09    {addr/2}
                   ]denom          .var    $0e    {addr/1}

1100: e8           CalcLineSlope   inx                       ;increment denominator
1101: 86 0e                        stx     ]denom
1103: 0a                           asl     A
1104: 85 0a                        sta     ]result+1
1106: a9 00                        lda     #$00
1108: 2a                           rol     A
1109: c5 0e                        cmp     ]denom
110b: 90 02                        bcc     L110F
110d: e5 0e                        sbc     ]denom
110f: 26 0a        L110F           rol     ]result+1
1111: 2a                           rol     A
1112: c5 0e                        cmp     ]denom
1114: 90 02                        bcc     L1118
1116: e5 0e                        sbc     ]denom
1118: 26 0a        L1118           rol     ]result+1
111a: 2a                           rol     A
111b: c5 0e                        cmp     ]denom
111d: 90 02                        bcc     L1121
111f: e5 0e                        sbc     ]denom
1121: 26 0a        L1121           rol     ]result+1
1123: 2a                           rol     A
1124: c5 0e                        cmp     ]denom
1126: 90 02                        bcc     L112A
1128: e5 0e                        sbc     ]denom
112a: 26 0a        L112A           rol     ]result+1
112c: 2a                           rol     A
112d: c5 0e                        cmp     ]denom
112f: 90 02                        bcc     L1133
1131: e5 0e                        sbc     ]denom
1133: 26 0a        L1133           rol     ]result+1
1135: 2a                           rol     A
1136: c5 0e                        cmp     ]denom
1138: 90 02                        bcc     L113C
113a: e5 0e                        sbc     ]denom
113c: 26 0a        L113C           rol     ]result+1
113e: 2a                           rol     A
113f: c5 0e                        cmp     ]denom
1141: 90 02                        bcc     L1145
1143: e5 0e                        sbc     ]denom
1145: 26 0a        L1145           rol     ]result+1
1147: 2a                           rol     A
1148: c5 0e                        cmp     ]denom
114a: 90 02                        bcc     L114E
114c: e5 0e                        sbc     ]denom
114e: 26 0a        L114E           rol     ]result+1         ;9th iteration, need to worry about 2nd byte
1150: 0a                           asl     A
1151: b0 04                        bcs     L1157
1153: c5 0e                        cmp     ]denom
1155: 90 03                        bcc     L115A
1157: e5 0e        L1157           sbc     ]denom
1159: 38                           sec
115a: 26 09        L115A           rol     ]result
115c: 0a                           asl     A
115d: b0 04                        bcs     L1163
115f: c5 0e                        cmp     ]denom
1161: 90 03                        bcc     L1166
1163: e5 0e        L1163           sbc     ]denom
1165: 38                           sec
1166: 26 09        L1166           rol     ]result
1168: 0a                           asl     A
1169: b0 04                        bcs     L116F
116b: c5 0e                        cmp     ]denom
116d: 90 03                        bcc     L1172
116f: e5 0e        L116F           sbc     ]denom
1171: 38                           sec
1172: 26 09        L1172           rol     ]result
1174: 0a                           asl     A
1175: b0 04                        bcs     L117B
1177: c5 0e                        cmp     ]denom
1179: 90 03                        bcc     L117E
117b: e5 0e        L117B           sbc     ]denom
117d: 38                           sec
117e: 26 09        L117E           rol     ]result
1180: 0a                           asl     A
1181: b0 04                        bcs     L1187
1183: c5 0e                        cmp     ]denom
1185: 90 03                        bcc     L118A
1187: e5 0e        L1187           sbc     ]denom
1189: 38                           sec
118a: 26 09        L118A           rol     ]result
118c: 0a                           asl     A
118d: b0 04                        bcs     L1193
118f: c5 0e                        cmp     ]denom
1191: 90 03                        bcc     L1196
1193: e5 0e        L1193           sbc     ]denom
1195: 38                           sec
1196: 26 09        L1196           rol     ]result
1198: 0a                           asl     A
1199: b0 04                        bcs     L119F
119b: c5 0e                        cmp     ]denom
119d: 90 03                        bcc     L11A2
119f: e5 0e        L119F           sbc     ]denom
11a1: 38                           sec
11a2: 26 09        L11A2           rol     ]result
11a4: 0a                           asl     A
11a5: b0 04                        bcs     L11AB
11a7: c5 0e                        cmp     ]denom
11a9: 90 03                        bcc     L11AE
11ab: e5 0e        L11AB           sbc     ]denom
11ad: 38                           sec
11ae: 26 09        L11AE           rol     ]result           ;low byte of result is zero?
11b0: c9 00                        cmp     #$00
11b2: f0 06                        beq     L11BA             ;yes, bail
11b4: e6 09                        inc     ]result           ;increment result (?)
11b6: d0 02                        bne     L11BA
11b8: e6 0a                        inc     ]result+1
11ba: 60           L11BA           rts

                   ; 
                   ; Hi-res pixel table.  Converts a pixel index (0-7) into a single pixel bit.
                   vis
11bb: 01 02 04 08+ hires_pixel     .bulk   $01,$02,$04,$08,$10,$20,$40

                   ; 
                   ; Hi-res pixel table.  Converts a pixel index into a set of bits that includes
                   ; the specified index, as well as all pixels to the right.  Used when drawing
                   ; horizontal or mostly-horizontal lines.
                   vis
                   hires_right_pixels
11c2: 7f 7e 7c 78+                 .bulk   $7f,$7e,$7c,$78,$70,$60,$40

                   ; 
                   ; Hi-res pixel table.  Converts a pixel index into a set of bits that includes
                   ; the specified index, as well as all pixels to the left.  Used when drawing
                   ; horizontal or mostly-horizontal lines.
                   vis
                   hires_left_pixels
11c9: 01 03 07 0f+                 .bulk   $01,$03,$07,$0f,$1f,$3f,$7f

                   ; 
                   ; Mask off bits while drawing multiple pixels in the line draw code.
                   vis
                   hires_partial_mask
11d0: 00 01 03 07+                 .bulk   $00,$01,$03,$07,$0f,$1f,$3f
11d7: 00 ff ff 00+                 .align  $0100 (41 bytes)

                   ; 
                   ; Draws a relatively steep horizontal line (1 <= deltaX/(deltaY+1) < 3), as well
                   ; as diagonal lines (deltaX==deltaY).
                   ; 
                   ; On entry:
                   ;   $00: start column (0-39)
                   ;   $01: start row (0-191)
                   ;   $02: end column (0-39)
                   ;   $04: start pixel index (0-6)
                   ;   $05: end pixel index (0-6)
                   ;   $09/0a: quotient from deltaX/(deltaY+1) (8.8)
                   ;   $0f: Y direction (0 or 1)
                   ;   $32: hpage ($20/$40)
                   ; 
                   • Clear variables
                   ]start_col      .var    $00    {addr/1}
                   ]start_row      .var    $01    {addr/1}
                   ]end_col        .var    $02    {addr/1}
                   ]start_pixel_index .var $04    {addr/1}
                   ]end_pixel_index .var   $05    {addr/1}
                   ]quotient       .var    $09    {addr/2}
                   ]pixel_mask     .var    $0c    {addr/1}
                   ]error_term     .var    $0d    {addr/1}
                   ]hptr           .var    $0e    {addr/2}

                   DrawHorizShortRun
1200: a6 0f                        ldx     ]hptr+1           ;get Y direction (0=pos, 1=neg)
1202: bd ae 12                     lda     inc_or_dec,x      ;modify instructions
1205: 8d 4b 12                     sta     :_IncOrDec1
1208: 8d 89 12                     sta     :_IncOrDec2
120b: a5 32                        lda     hpage
120d: 8d 53 12                     sta     :_OrPage1+1
1210: 8d 91 12                     sta     :_OrPage2+1
1213: a6 01                        ldx     ]start_row        ;get address of hi-res line
1215: 1d 00 16                     ora     hires_addr_hi,x
1218: 85 0f                        sta     ]hptr+1
121a: bd 00 15                     lda     hires_addr_lo,x
121d: 85 0e                        sta     ]hptr
121f: a6 04                        ldx     ]start_pixel_index ;get initial pixel mask
1221: bd bb 11                     lda     hires_pixel,x
1224: 85 0c                        sta     ]pixel_mask
1226: a6 09                        ldx     ]quotient         ;init error term with fractional part of quotient
1228: 86 0d                        stx     ]error_term
122a: a6 0a                        ldx     ]quotient+1       ;integer part is number of pixels
122c: e8                           inx                       ;start with a "long" slice
122d: a4 00                        ldy     ]start_col
122f: b1 0e                        lda     (]hptr),y
1231: c4 02                        cpy     ]end_col          ;reached end column?
1233: 90 0f                        bcc     :LoopEntry        ;no, branch
1235: a5 05                        lda     ]end_pixel_index
1237: e5 04                        sbc     ]start_pixel_index
1239: 85 05                        sta     ]end_pixel_index
123b: b1 0e                        lda     (]hptr),y         ;get screen byte to blend with
123d: 4c 7e 12                     jmp     :LastByte

1240: 06 0c        :Loop           asl     ]pixel_mask       ;shift mask to next pixel
1242: 30 27                        bmi     :NextByte         ;reached end of byte, branch
1244: 05 0c        :LoopEntry      ora     ]pixel_mask       ;set pixel
1246: ca                           dex                       ;more to do in this run?
1247: d0 f7                        bne     :Loop             ;yes, loop
1249: 91 0e                        sta     (]hptr),y         ;store pixels
124b: e6 01        :_IncOrDec1     inc     ]start_row        ;advance to next row (up or down)
124d: a6 01                        ldx     ]start_row
124f: bd 00 16                     lda     hires_addr_hi,x   ;update pointer
1252: 09 00        :_OrPage1       ora     #$00
1254: 85 0f                        sta     ]hptr+1
1256: bd 00 15                     lda     hires_addr_lo,x
1259: 85 0e                        sta     ]hptr
125b: a5 0d                        lda     ]error_term       ;update error term
125d: 65 09                        adc     ]quotient
125f: 85 0d                        sta     ]error_term
1261: b1 0e                        lda     (]hptr),y
1263: a6 0a                        ldx     ]quotient+1       ;reset slice counter
1265: 90 d9                        bcc     :Loop             ;ADC didn't roll over, do short slice
1267: e8                           inx                       ;make it a long slice
1268: 4c 40 12                     jmp     :Loop

126b: 91 0e        :NextByte       sta     (]hptr),y         ;store what we have
126d: a9 01                        lda     #$01              ;reset to leftmost pixel
126f: 85 0c                        sta     ]pixel_mask
1271: c8                           iny                       ;advance to next byte
1272: b1 0e                        lda     (]hptr),y         ;get screen byte
1274: c4 02                        cpy     ]end_col          ;are we on the last column?
1276: 90 cc                        bcc     :LoopEntry        ;no, back to the loop
1278: 18                           clc                       ;?
1279: 4c 7e 12                     jmp     :LastByte

127c: 06 0c        :FinishLoop     asl     ]pixel_mask
127e: 05 0c        :LastByte       ora     ]pixel_mask       ;set pending bit
1280: c6 05                        dec     ]end_pixel_index  ;done with pixels in this byte?
1282: 30 25                        bmi     :Done             ;yes, store and exit
1284: ca                           dex                       ;more in this run?
1285: d0 f5                        bne     :FinishLoop       ;yes, loop
1287: 91 0e                        sta     (]hptr),y         ;store it
1289: e6 01        :_IncOrDec2     inc     ]start_row        ;advance to next row
128b: a6 01                        ldx     ]start_row
128d: bd 00 16                     lda     hires_addr_hi,x
1290: 09 00        :_OrPage2       ora     #$00
1292: 85 0f                        sta     ]hptr+1
1294: bd 00 15                     lda     hires_addr_lo,x
1297: 85 0e                        sta     ]hptr
1299: a5 0d                        lda     ]error_term       ;update error term
129b: 65 09                        adc     ]quotient
129d: 85 0d                        sta     ]error_term
129f: b1 0e                        lda     (]hptr),y         ;get screen pixels
12a1: a6 0a                        ldx     ]quotient+1       ;reset slice counter
12a3: 90 d7                        bcc     :FinishLoop       ;ADC didn't roll over, do short slice
12a5: e8                           inx                       ;do one extra iteration
12a6: 4c 7c 12                     jmp     :FinishLoop

12a9: 91 0e        :Done           sta     (]hptr),y         ;write pending bits
12ab: 4c 40 a0                     jmp     UPDATE_SOUND

12ae: e6           inc_or_dec      .dd1    instr_INC
12af: c6                           .dd1    instr_DEC
12b0: ff ff 00 00+                 .align  $0100 (80 bytes)

                   ; 
                   ; Draws a moderately steep horizontal line (3 <= deltaX/(deltaY+1) < 6).
                   ; 
                   ; On entry:
                   ;   $00: start column (0-39)
                   ;   $01: start row (0-191)
                   ;   $02: end column (0-39)
                   ;   $04: start pixel index (0-6)
                   ;   $05: end pixel index (0-6)
                   ;   $09/0a: quotient from deltaX/(deltaY+1) (8.8)
                   ;   $0f: Y direction (0 or 1)
                   ;   $32: hpage ($20/$40)
                   ; 
1300: a5 32        DrawHorizMedRun lda     hpage             ;set up self-modifying code
1302: 8d 23 13                     sta     :_OrPage+1
1305: a6 0f                        ldx     ]hptr+1
1307: bd ae 12                     lda     inc_or_dec,x
130a: 8d 1b 13                     sta     :_IncOrDec
130d: a4 00                        ldy     ]start_col        ;init
130f: a9 00                        lda     #$00
1311: 85 0d                        sta     ]error_term
1313: 18                           clc
1314: 4c 1d 13                     jmp     :LoopEntry

1317: 11 0e        :Loop           ora     (]hptr),y         ;blend pixels onto screen
1319: 91 0e                        sta     (]hptr),y
131b: e6 01        :_IncOrDec      inc     ]start_row        ;move to the next row
131d: a6 01        :LoopEntry      ldx     ]start_row        ;set up hi-res row addr
131f: bd 00 16                     lda     hires_addr_hi,x
1322: 09 00        :_OrPage        ora     #$00
1324: 85 0f                        sta     ]hptr+1
1326: bd 00 15                     lda     hires_addr_lo,x
1329: 85 0e                        sta     ]hptr
132b: a5 0d                        lda     ]error_term       ;update the error term
132d: 65 09                        adc     ]quotient         ;(carry is always clear before here)
132f: 85 0d                        sta     ]error_term
1331: a5 0a                        lda     ]quotient+1       ;get base run length
1333: 65 04                        adc     ]start_pixel_index ;add index of first pixel (+1 if error term rolled)
1335: c9 07                        cmp     #$07              ;does this fill or overflow the current byte?
1337: b0 1e                        bcs     :AcrossBytes      ;yes, branch
1339: a6 04                        ldx     ]start_pixel_index ;no; get original start in X-reg
133b: 85 04                        sta     ]start_pixel_index ;save next index
133d: bd c2 11                     lda     hires_right_pixels,x ;A-reg = pixels set from start to end of byte
1340: a6 04                        ldx     ]start_pixel_index ;get index of last pixel
1342: 3d d0 11                     and     hires_partial_mask,x ;mask off pixels past this slice
1345: c4 02                        cpy     ]end_col          ;reached last column?
1347: 90 ce                        bcc     :Loop             ;not yet; blend pixels and continue
1349: e4 05                        cpx     ]end_pixel_index  ;reached last pixel?
134b: 90 ca                        bcc     :Loop             ;not yet; blend pixels and continue
134d: 11 0e                        ora     (]hptr),y         ;blend what we have
134f: 1d bb 11                     ora     hires_pixel,x     ;add in final pixel
1352: 91 0e                        sta     (]hptr),y         ;update display
1354: 4c 40 a0                     jmp     UPDATE_SOUND      ;done drawing

1357: a6 04        :AcrossBytes    ldx     ]start_pixel_index ;X-reg = starting pixel index
1359: e9 07                        sbc     #$07              ;pixel index %= 7
135b: 85 04                        sta     ]start_pixel_index
135d: bd c2 11                     lda     hires_right_pixels,x ;get the pixels to set for the first byte
1360: 11 0e                        ora     (]hptr),y         ;blend with display
1362: 91 0e                        sta     (]hptr),y
1364: a6 04                        ldx     ]start_pixel_index ;get pixel mask for second byte
1366: bd d0 11                     lda     hires_partial_mask,x ;(note this is zero if start_pixel_index is 0)
1369: c8                           iny                       ;move to the next byte
136a: c4 02                        cpy     ]end_col          ;reached last column?
136c: 90 a9                        bcc     :Loop             ;not yet, blend pixels and continue
136e: e4 05                        cpx     ]end_pixel_index  ;reached last pixel?
1370: 90 a5                        bcc     :Loop             ;not yet, blend pixels and continue
1372: 11 0e                        ora     (]hptr),y         ;last byte, blend what we have
1374: 1d bb 11                     ora     hires_pixel,x     ;add in the final pixel
1377: 91 0e                        sta     (]hptr),y         ;update display
1379: 4c 40 a0                     jmp     UPDATE_SOUND

                   ; 
                   ; Draws a shallow horizontal line (7 <= deltaX/(deltaY+1)).
                   ; 
                   ; On entry:
                   ;   $00: start column (0-39)
                   ;   $01: start row (0-191)
                   ;   $02: end column (0-39)
                   ;   $04: start pixel index (0-6)
                   ;   $05: end pixel index (0-6)
                   ;   $09/0a: quotient from deltaX/(deltaY+1) (8.8)
                   ;   $0f: Y direction (0 or 1)
                   ;   $32: hpage ($20/$40)
                   ; 
                   DrawHorizLongRun
137c: a5 32                        lda     hpage             ;set up self-modifying code
137e: 8d 9b 13                     sta     :_OrPage+1
1381: a6 0f                        ldx     ]hptr+1
1383: bd ae 12                     lda     inc_or_dec,x
1386: 8d 93 13                     sta     :_IncOrDec
1389: a4 00                        ldy     ]start_col        ;init
138b: a9 00                        lda     #$00
138d: 85 0d                        sta     ]error_term
138f: 18                           clc
1390: 4c 95 13                     jmp     :LoopEntry

1393: e6 01        :_IncOrDec      inc     ]start_row        ;move to next row
1395: a6 01        :LoopEntry      ldx     ]start_row        ;set up hi-res row addr
1397: bd 00 16                     lda     hires_addr_hi,x
139a: 09 00        :_OrPage        ora     #$00
139c: 85 0f                        sta     ]hptr+1
139e: bd 00 15                     lda     hires_addr_lo,x
13a1: 85 0e                        sta     ]hptr
13a3: a5 0d                        lda     ]error_term       ;update error term
13a5: 65 09                        adc     ]quotient         ;(carry is always clear to here)
13a7: 85 0d                        sta     ]error_term
13a9: a5 0a                        lda     ]quotient+1       ;get base run length (7+)
13ab: 65 04                        adc     ]start_pixel_index ;add index of first pixel (0-6)
13ad: aa                           tax                       ; (+1 if error term rolled)
13ae: bd 00 17                     lda     div7_tab,x        ;divide by 7
13b1: 65 00                        adc     ]start_col        ;add to start column
13b3: 85 00                        sta     ]start_col        ;this is the column where the next slice starts
13b5: bd 00 18                     lda     mod7_tab,x        ;compute mod 7 to get pixel index of next slice start
13b8: a6 04                        ldx     ]start_pixel_index ;grab the current start pixel index
13ba: 85 04                        sta     ]start_pixel_index ;save start index of next slice
13bc: bd c2 11                     lda     hires_right_pixels,x ;get the partial pixels for the first byte
13bf: 11 0e                        ora     (]hptr),y         ;we know it's 7+, so nothing to mask
13c1: 91 0e                        sta     (]hptr),y         ;blend with display and store
13c3: c8                           iny                       ;move to next column
13c4: c4 00                        cpy     ]start_col        ;reached start of next slice?
13c6: b0 09                        bcs     :SliceEnd         ;yes, branch
13c8: a9 7f                        lda     #$7f              ;no, light up all 7 pixels
13ca: 91 0e        :FastLoop       sta     (]hptr),y         ;update display
13cc: c8                           iny
13cd: c4 00                        cpy     ]start_col        ;continue until we reach start of next slice
13cf: 90 f9                        bcc     :FastLoop
13d1: a6 04        :SliceEnd       ldx     ]start_pixel_index ;get the index of the next slice
13d3: bd c9 11                     lda     hires_left_pixels,x ;set the pixels to the left of it
13d6: 11 0e                        ora     (]hptr),y         ;blend with display
13d8: 91 0e                        sta     (]hptr),y
13da: c4 02                        cpy     ]end_col          ;done yet? (next slice is full byte, just check col)
13dc: 90 b5                        bcc     :_IncOrDec        ;no, continue
13de: 4c 40 a0                     jmp     UPDATE_SOUND

13e1: ff 00 00 ff+                 .align  $0100 (31 bytes)

                   ; 
                   ; Draws a horizontal line, from x0,yc to x1,yc (inclusive coordinates).
                   ; 
                   ; On entry:
                   ;   $00: start column (0-39)
                   ;   $01: row (0-191)
                   ;   $02: end column (0-39)
                   ;   $04: start pixel index (0-6)
                   ;   $05: end pixel index (0-6)
                   ;   $32: hi-res page ($20/$40)
                   ; 
                   • Clear variables
                   ]start_col      .var    $00    {addr/1}
                   ]row            .var    $01    {addr/1}
                   ]end_col        .var    $02    {addr/1}
                   ]start_pixel_index .var $04    {addr/1}
                   ]end_pixel_index .var   $05    {addr/1}
                   ]hptr           .var    $0e    {addr/2}

1400: a6 01        DrawHorizontal  ldx     ]row              ;set up hires addr
1402: bd 00 16                     lda     hires_addr_hi,x
1405: 05 32                        ora     hpage
1407: 85 0f                        sta     ]hptr+1
1409: bd 00 15                     lda     hires_addr_lo,x
140c: 85 0e                        sta     ]hptr
140e: a6 04                        ldx     ]start_pixel_index ;get start index
1410: bd c2 11                     lda     hires_right_pixels,x ;get set of bits for left edge
1413: a4 00                        ldy     ]start_col        ;column for left edge
1415: c4 02                        cpy     ]end_col          ;are we ending here?
1417: f0 1c                        beq     :SingleByte       ;yes, handle single-byte case
1419: 11 0e                        ora     (]hptr),y         ;no, blend with screen contents
141b: 91 0e                        sta     (]hptr),y
141d: a9 7f                        lda     #$7f              ;write full bytes
141f: 4c 24 14                     jmp     :LoopEntry

1422: 91 0e        :Loop           sta     (]hptr),y
1424: c8           :LoopEntry      iny
1425: c4 02                        cpy     ]end_col          ;reached end?
1427: 90 f9                        bcc     :Loop             ;not yet
1429: a6 05                        ldx     ]end_pixel_index  ;get last pixel index
142b: bd c9 11                     lda     hires_left_pixels,x ;get pixels
142e: 11 0e                        ora     (]hptr),y         ;blend with screen contents
1430: 91 0e                        sta     (]hptr),y
1432: 4c 40 a0                     jmp     UPDATE_SOUND

1435: a6 05        :SingleByte     ldx     ]end_pixel_index  ;mask with right-side bits
1437: 3d c9 11                     and     hires_left_pixels,x
143a: 11 0e                        ora     (]hptr),y         ;blend with screen contents
143c: 91 0e                        sta     (]hptr),y
143e: 4c 40 a0                     jmp     UPDATE_SOUND

                   ; 
                   ; Draws a vertically-dominant line.
                   ; 
                   ; On entry:
                   ;   $00: start column (0-39)
                   ;   $01: start row (0-191)
                   ;   $03: end row (0-191)
                   ;   $04: start pixel index (0-6)
                   ;   $09: quotient from line slope calculation
                   ;   $0f: Y direction (0=down, 1=up)
                   ;   $32: hi-res page ($20/$40)
                   ; 
                   • Clear variables
                   ]start_col      .var    $00    {addr/1}
                   ]start_row      .var    $01    {addr/1}
                   ]end_row        .var    $03    {addr/1}
                   ]start_pixel_index .var $04    {addr/1}
                   ]quotient       .var    $09    {addr/2}
                   ]err_hi         .var    $0b    {addr/1}
                   ]pixel_mask     .var    $0c    {addr/1}
                   ]error_term     .var    $0d    {addr/1}
                   ]y_direction    .var    $0f    {addr/1}

1441: a6 0f        DrawVertDom     ldx     ]y_direction      ;self-modify up vs. down
1443: bd 9c 14                     lda     :inx_dex,x
1446: 8d 65 14                     sta     :_InxDex
1449: a6 04                        ldx     ]start_pixel_index
144b: bd bb 11                     lda     hires_pixel,x     ;get initial pixel mask
144e: 85 0c                        sta     ]pixel_mask
1450: a5 32                        lda     hpage
1452: 8d 6a 14                     sta     :_Page+1
1455: a6 09                        ldx     ]quotient         ;init error term
1457: 86 0d                        stx     ]error_term
1459: a6 0a                        ldx     ]quotient+1
145b: e8                           inx
145c: 86 0b                        stx     ]err_hi
145e: a4 00                        ldy     ]start_col        ;init X-reg / Y-reg
1460: a6 01                        ldx     ]start_row
1462: 4c 66 14                     jmp     :Start            ;jump into it

                   ]hptr           .var    $0e    {addr/2}

1465: e8           :_InxDex        inx
1466: bd 00 16     :Start          lda     hires_addr_hi,x   ;set hi-res row address
1469: 09 00        :_Page          ora     #$00
146b: 85 0f                        sta     ]hptr+1
146d: bd 00 15                     lda     hires_addr_lo,x
1470: 85 0e                        sta     ]hptr
1472: b1 0e                        lda     (]hptr),y         ;blend pixel
1474: 05 0c                        ora     ]pixel_mask
1476: 91 0e                        sta     (]hptr),y
1478: c6 0b                        dec     ]err_hi           ;update error term hi
147a: d0 e9                        bne     :_InxDex          ;quick loop if we're in a run
147c: 06 0c                        asl     ]pixel_mask       ;move pixel right
147e: 30 14                        bmi     :NewByte          ;branch if we reached end of byte
1480: 18           :UpdateErr      clc                       ;update full error term
1481: a5 0d                        lda     ]error_term
1483: 65 09                        adc     ]quotient
1485: 85 0d                        sta     ]error_term
1487: a5 0a                        lda     ]quotient+1
1489: 69 00                        adc     #$00
148b: 85 0b                        sta     ]err_hi
148d: e4 03                        cpx     ]end_row
148f: d0 d4                        bne     :_InxDex
1491: 4c 40 a0                     jmp     UPDATE_SOUND

1494: a9 01        :NewByte        lda     #$01              ;restart with left pixel
1496: 85 0c                        sta     ]pixel_mask
1498: c8                           iny                       ;move right one byte
1499: 4c 80 14                     jmp     :UpdateErr

149c: e8           :inx_dex        .dd1    instr_INX
149d: ca                           .dd1    instr_DEX

                   ; 
                   ; Draws a vertical line, from xc,y0 to xc,y1 (exclusive end coord).
                   ; 
                   ; The caller guarantees that y0 < y1.
                   ; 
                   ; On entry:
                   ;   $00: start column (0-39)
                   ;   $01: start row (0-191)
                   ;   $03: end row (0-191)
                   ;   $04: pixel index
                   ; 
                   ]start_col      .var    $00    {addr/1}
                   ]start_row      .var    $01    {addr/1}
                   ]end_row        .var    $03    {addr/1}
                   ]pixel_index    .var    $04    {addr/1}

                   DrawVerticalLine
149e: 20 40 a0                     jsr     UPDATE_SOUND
14a1: a6 04                        ldx     ]pixel_index      ;set up pixel mask
14a3: bd bb 11                     lda     hires_pixel,x
14a6: 8d c3 14                     sta     :_pixel_mask+1
14a9: a5 32                        lda     hpage
14ab: 8d b8 14                     sta     :_ora_page+1
14ae: a4 00                        ldy     ]start_col        ;load byte offset into Y-reg
14b0: a6 01                        ldx     ]start_row
14b2: ca                           dex                       ;balance following INX
14b3: e8           :Loop           inx
14b4: bd 00 16                     lda     hires_addr_hi,x   ;get hi-res row address
14b7: 09 00        :_ora_page      ora     #$00
14b9: 85 0f                        sta     ]hptr+1
14bb: bd 00 15                     lda     hires_addr_lo,x
14be: 85 0e                        sta     ]hptr
14c0: b1 0e                        lda     (]hptr),y
14c2: 09 00        :_pixel_mask    ora     #$00              ;blend with contents
14c4: 91 0e                        sta     (]hptr),y         ;update screen
14c6: e4 03                        cpx     ]end_row          ;reached the end?
14c8: 90 e9                        bcc     :Loop             ;not yet
14ca: 4c 40 a0                     jmp     UPDATE_SOUND

                   ; 
                   ; Plots a single point on the hi-res screen.  Called when x0==x1 and y0==y1.
                   ; 
                   ; On entry:
                   ;   $00: column (0-39)
                   ;   $01: row (0-191)
                   ;   $04: pixel index (0-6)
                   ;   $32: hi-res page
                   ; 
                   • Clear variables
                   ]col            .var    $00    {addr/1}
                   ]row            .var    $01    {addr/1}
                   ]bit            .var    $04    {addr/1}
                   ]hptr           .var    $0e    {addr/2}

14cd: a6 01        DrawPoint       ldx     ]row
14cf: bd 00 16                     lda     hires_addr_hi,x
14d2: 05 32                        ora     hpage
14d4: 85 0f                        sta     ]hptr+1
14d6: bd 00 15                     lda     hires_addr_lo,x
14d9: 85 0e                        sta     ]hptr
14db: a6 04                        ldx     ]bit
14dd: bd bb 11                     lda     hires_pixel,x
14e0: a4 00                        ldy     ]col
14e2: 11 0e                        ora     (]hptr),y
14e4: 91 0e                        sta     (]hptr),y
14e6: 4c 40 a0                     jmp     UPDATE_SOUND

14e9: ff 00 00 ff+                 .align  $0100 (23 bytes)
                   ; 
                   ; Hi-res row address tables.
1500: 00 00 00 00+ hires_addr_lo   .bulk   $00,$00,$00,$00,$00,$00,$00,$00,$80,$80,$80,$80,$80,$80,$80,$80
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$80,$80,$80,$80,$80,$80,$80,$80
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$80,$80,$80,$80,$80,$80,$80,$80
                                    +      $00,$00,$00,$00,$00,$00,$00,$00,$80,$80,$80,$80,$80,$80,$80,$80
                                    +      $28,$28,$28,$28,$28,$28,$28,$28,$a8,$a8,$a8,$a8,$a8,$a8,$a8,$a8
                                    +      $28,$28,$28,$28,$28,$28,$28,$28,$a8,$a8,$a8,$a8,$a8,$a8,$a8,$a8
                                    +      $28,$28,$28,$28,$28,$28,$28,$28,$a8,$a8,$a8,$a8,$a8,$a8,$a8,$a8
                                    +      $28,$28,$28,$28,$28,$28,$28,$28,$a8,$a8,$a8,$a8,$a8,$a8,$a8,$a8
                                    +      $50,$50,$50,$50,$50,$50,$50,$50,$d0,$d0,$d0,$d0,$d0,$d0,$d0,$d0
                                    +      $50,$50,$50,$50,$50,$50,$50,$50,$d0,$d0,$d0,$d0,$d0,$d0,$d0,$d0
                                    +      $50,$50,$50,$50,$50,$50,$50,$50,$d0,$d0,$d0,$d0,$d0,$d0,$d0,$d0
                                    +      $50,$50,$50,$50,$50,$50,$50,$50,$d0,$d0,$d0,$d0,$d0,$d0,$d0,$d0
15c0: 00 00 00 00+                 .align  $0100 (64 bytes)
1600: 00 04 08 0c+ hires_addr_hi   .bulk   $00,$04,$08,$0c,$10,$14,$18,$1c,$00,$04,$08,$0c,$10,$14,$18,$1c
                                    +      $01,$05,$09,$0d,$11,$15,$19,$1d,$01,$05,$09,$0d,$11,$15,$19,$1d
                                    +      $02,$06,$0a,$0e,$12,$16,$1a,$1e,$02,$06,$0a,$0e,$12,$16,$1a,$1e
                                    +      $03,$07,$0b,$0f,$13,$17,$1b,$1f,$03,$07,$0b,$0f,$13,$17,$1b,$1f
                                    +      $00,$04,$08,$0c,$10,$14,$18,$1c,$00,$04,$08,$0c,$10,$14,$18,$1c
                                    +      $01,$05,$09,$0d,$11,$15,$19,$1d,$01,$05,$09,$0d,$11,$15,$19,$1d
                                    +      $02,$06,$0a,$0e,$12,$16,$1a,$1e,$02,$06,$0a,$0e,$12,$16,$1a,$1e
                                    +      $03,$07,$0b,$0f,$13,$17,$1b,$1f,$03,$07,$0b,$0f,$13,$17,$1b,$1f
                                    +      $00,$04,$08,$0c,$10,$14,$18,$1c,$00,$04,$08,$0c,$10,$14,$18,$1c
                                    +      $01,$05,$09,$0d,$11,$15,$19,$1d,$01,$05,$09,$0d,$11,$15,$19,$1d
                                    +      $02,$06,$0a,$0e,$12,$16,$1a,$1e,$02,$06,$0a,$0e,$12,$16,$1a,$1e
                                    +      $03,$07,$0b,$0f,$13,$17,$1b,$1f,$03,$07,$0b,$0f,$13,$17,$1b,$1f
16c0: 00 00 00 00+                 .align  $0100 (64 bytes)
                   ; 
                   ; Division by 7.
1700: 00 00 00 00+ div7_tab        .bulk   $00,$00,$00,$00,$00,$00,$00,$01,$01,$01,$01,$01,$01,$01,$02,$02
                                    +      $02,$02,$02,$02,$02,$03,$03,$03,$03,$03,$03,$03,$04,$04,$04,$04
                                    +      $04,$04,$04,$05,$05,$05,$05,$05,$05,$05,$06,$06,$06,$06,$06,$06
                                    +      $06,$07,$07,$07,$07,$07,$07,$07,$08,$08,$08,$08,$08,$08,$08,$09
                                    +      $09,$09,$09,$09,$09,$09,$0a,$0a,$0a,$0a,$0a,$0a,$0a,$0b,$0b,$0b
                                    +      $0b,$0b,$0b,$0b,$0c,$0c,$0c,$0c,$0c,$0c,$0c,$0d,$0d,$0d,$0d,$0d
                                    +      $0d,$0d,$0e,$0e,$0e,$0e,$0e,$0e,$0e,$0f,$0f,$0f,$0f,$0f,$0f,$0f
                                    +      $10,$10,$10,$10,$10,$10,$10,$11,$11,$11,$11,$11,$11,$11,$12,$12
                                    +      $12,$12,$12,$12,$12,$13,$13,$13,$13,$13,$13,$13,$14,$14,$14,$14
                                    +      $14,$14,$14,$15,$15,$15,$15,$15,$15,$15,$16,$16,$16,$16,$16,$16
                                    +      $16,$17,$17,$17,$17,$17,$17,$17,$18,$18,$18,$18,$18,$18,$18,$19
                                    +      $19,$19,$19,$19,$19,$19,$1a,$1a,$1a,$1a,$1a,$1a,$1a,$1b,$1b,$1b
                                    +      $1b,$1b,$1b,$1b,$1c,$1c,$1c,$1c,$1c,$1c,$1c,$1d,$1d,$1d,$1d,$1d
                                    +      $1d,$1d,$1e,$1e,$1e,$1e,$1e,$1e,$1e,$1f,$1f,$1f,$1f,$1f,$1f,$1f
                                    +      $20,$20,$20,$20,$20,$20,$20,$21,$21,$21,$21,$21,$21,$21,$22,$22
                                    +      $22,$22,$22,$22,$22,$23,$23,$23,$23,$23,$23,$23,$24,$24,$24,$24
                   ; 
                   ; Modulo 7.
1800: 00 01 02 03+ mod7_tab        .bulk   $00,$01,$02,$03,$04,$05,$06,$00,$01,$02,$03,$04,$05,$06,$00,$01
                                    +      $02,$03,$04,$05,$06,$00,$01,$02,$03,$04,$05,$06,$00,$01,$02,$03
                                    +      $04,$05,$06,$00,$01,$02,$03,$04,$05,$06,$00,$01,$02,$03,$04,$05
                                    +      $06,$00,$01,$02,$03,$04,$05,$06,$00,$01,$02,$03,$04,$05,$06,$00
                                    +      $01,$02,$03,$04,$05,$06,$00,$01,$02,$03,$04,$05,$06,$00,$01,$02
                                    +      $03,$04,$05,$06,$00,$01,$02,$03,$04,$05,$06,$00,$01,$02,$03,$04
                                    +      $05,$06,$00,$01,$02,$03,$04,$05,$06,$00,$01,$02,$03,$04,$05,$06
                                    +      $00,$01,$02,$03,$04,$05,$06,$00,$01,$02,$03,$04,$05,$06,$00,$01
                                    +      $02,$03,$04,$05,$06,$00,$01,$02,$03,$04,$05,$06,$00,$01,$02,$03
                                    +      $04,$05,$06,$00,$01,$02,$03,$04,$05,$06,$00,$01,$02,$03,$04,$05
                                    +      $06,$00,$01,$02,$03,$04,$05,$06,$00,$01,$02,$03,$04,$05,$06,$00
                                    +      $01,$02,$03,$04,$05,$06,$00,$01,$02,$03,$04,$05,$06,$00,$01,$02
                                    +      $03,$04,$05,$06,$00,$01,$02,$03,$04,$05,$06,$00,$01,$02,$03,$04
                                    +      $05,$06,$00,$01,$02,$03,$04,$05,$06,$00,$01,$02,$03,$04,$05,$06
                                    +      $00,$01,$02,$03,$04,$05,$06,$00,$01,$02,$03,$04,$05,$06,$00,$01
                                    +      $02,$03,$04,$05,$06,$00,$01,$02,$03,$04,$05,$06,$00,$01,$02,$03

                   ********************************************************************************
                   * Clips a line to the viewport and draws it.  Coordinates are signed clip-     *
                   * space coordinates (0,0 is center of viewport, positive values are up and to  *
                   * the right).                                                                  *
                   *                                                                              *
                   * Called from ROCK2.                                                           *
                   *                                                                              *
                   * On entry:                                                                    *
                   *   $10/11: x0 (16-bit signed)                                                 *
                   *   $12/13: y0                                                                 *
                   *   $14/15: x1                                                                 *
                   *   $16/17: y1                                                                 *
                   *                                                                              *
                   *   $50: viewport offset for X coord (8-bit device coords)                     *
                   *   $52: viewport offset for Y coord                                           *
                   *                                                                              *
                   *   $54/55: viewport left edge (16-bit signed device coords)                   *
                   *   $56/57: viewport right edge                                                *
                   *   $58/59: viewport top edge                                                  *
                   *   $5a/5b: viewport bottom edge                                               *
                   *                                                                              *
                   * During the mission briefing, the viewport is set to (-90,41),(91,-58)        *
                   * (181x99).  During the game, it's set to (-112,74),(111,-82) (224x157).  Note *
                   * those are centered horizontally but not vertically -- there's more space     *
                   * below the horizon line than above.                                           *
                   *                                                                              *
                   * The viewport-to-screen adjustment translates the coordinates so the top-left *
                   * corner is at 7,33.  The adjustment is (132,54) in the mission briefing, and  *
                   * 119/107 in-game.                                                             *
                   ********************************************************************************
                   • Clear variables
                   ]clip_x0        .var    $00    {addr/1}
                   ]clip_y0        .var    $01    {addr/1}
                   ]clip_x1        .var    $02    {addr/1}
                   ]clip_y1        .var    $03    {addr/1}
                   ]x0             .var    $10    {addr/2}
                   ]y0             .var    $12    {addr/2}
                   ]x1             .var    $14    {addr/2}
                   ]y1             .var    $16    {addr/2}
                   ]outcode0       .var    $18    {addr/1}
                   ]outcode1       .var    $19    {addr/1}
                   ]muldiv_val     .var    $1b    {addr/1}
                   ]delta2         .var    $1c    {addr/1}
                   ]tmp            .var    $1d    {addr/1}

1900: a6 14        ClipDrawLine    ldx     ]x1               ;see if abs(x1-x0) < 256
1902: e4 10                        cpx     ]x0               ;set carry as if we subtracted low part
1904: a5 15                        lda     ]x1+1             ;subtract high part
1906: e5 11                        sbc     ]x0+1
1908: f0 08                        beq     :CheckY           ;0 <= x1-x0 < 256, continue
190a: c9 ff                        cmp     #$ff              ;is -256 < x1-x0 < 0?
190c: d0 16                        bne     :Bail             ;no, bail
190e: e4 10                        cpx     ]x0               ;diff exactly 256?
1910: f0 12                        beq     :Bail             ;yes, bail
1912: a6 16        :CheckY         ldx     ]y1               ;now see if abs(y1-y0) < 256
1914: e4 12                        cpx     ]y0
1916: a5 17                        lda     ]y1+1
1918: e5 13                        sbc     ]y0+1
191a: f0 09                        beq     :CoordsClose
191c: c9 ff                        cmp     #$ff
191e: d0 04                        bne     :Bail
1920: e4 12                        cpx     ]y0
1922: d0 01                        bne     :CoordsClose
1924: 60           :Bail           rts

                   ; Compute Cohen-Sutherland outcodes.  Each byte has the form LRTB0000, with a
                   ; bit being set if the point is past the left, right, top, or bottom edges.  If
                   ; the point is entirely within the viewport, the outcode would be zero.  This
                   ; provides a fast path for trivial acceptance and trivial rejection.
                   ; 
                   ; cf. https://en.wikipedia.org/wiki/Cohen%E2%80%93Sutherland_algorithm
                   ; 
                   ; The computations here initially set bits to 0 when the coord is out of bounds,
                   ; rather than 1.  The bits are inverted at the end.
                   ; 
                   ; Start by checking x1,y1.
1925: a5 16        :CoordsClose    lda     ]y1               ;compute (y1 - bottom)
1927: c5 5a                        cmp     VIEW_BOTTOM       ;set carry as if we subtracted low bytes
1929: a5 17                        lda     ]y1+1             ;now do the high byte
192b: e5 5b                        sbc     VIEW_BOTTOM+1     ;carry clear if we needed to borrow
192d: 6a                           ror     A                 ;put the carry in the high bit
192e: 45 17                        eor     ]y1+1             ;flip it if y1 is negative
1930: 45 5b                        eor     VIEW_BOTTOM+1     ;flip it if bottom is negative
1932: 0a                           asl     A                 ;put hi bit in carry
1933: 66 19                        ror     ]outcode1         ;roll into outcode (this is "off bottom" flag)
1935: 38                           sec                       ;set carry for "skip bottom" branch
1936: 10 0e                        bpl     :SkipBottom1      ;if we're past bottom, no need to check top
1938: a5 58                        lda     VIEW_TOP          ;compute (top - y1)
193a: c5 16                        cmp     ]y1
193c: a5 59                        lda     VIEW_TOP+1
193e: e5 17                        sbc     ]y1+1
1940: 6a                           ror     A
1941: 45 59                        eor     VIEW_TOP+1
1943: 45 17                        eor     ]y1+1
1945: 0a                           asl     A
1946: 66 19        :SkipBottom1    ror     ]outcode1         ;roll "off top" flag into outcode
1948: a5 56                        lda     VIEW_RIGHT        ;compute (right - x1)
194a: c5 14                        cmp     ]x1
194c: a5 57                        lda     VIEW_RIGHT+1
194e: e5 15                        sbc     ]x1+1
1950: 6a                           ror     A
1951: 45 57                        eor     VIEW_RIGHT+1
1953: 45 15                        eor     ]x1+1
1955: 0a                           asl     A
1956: 66 19                        ror     ]outcode1
1958: 38                           sec
1959: 10 0e                        bpl     :SkipLeft1        ;off right edge, don't need to check left
195b: a5 14                        lda     ]x1               ;compute (x1 - left)
195d: c5 54                        cmp     VIEW_LEFT
195f: a5 15                        lda     ]x1+1
1961: e5 55                        sbc     VIEW_LEFT+1
1963: 6a                           ror     A
1964: 45 15                        eor     ]x1+1
1966: 45 55                        eor     VIEW_LEFT+1
1968: 0a                           asl     A
1969: a5 19        :SkipLeft1      lda     ]outcode1
196b: 6a                           ror     A
196c: 29 f0                        and     #$f0              ;remove uninitialized bits
196e: 49 f0                        eor     #$f0              ;invert meaning of bits
1970: 85 19                        sta     ]outcode1         ;save
                   ; Now check x0,y0.
                   ; 
                   ; After we fix x0,y0 for one edge (e.g. left) we need to come back here to see
                   ; if we need to fix it for another edge (e.g. top).
1972: a5 12        :ReCheck0       lda     ]y0               ;compute (y0 - bottom)
1974: c5 5a                        cmp     VIEW_BOTTOM
1976: a5 13                        lda     ]y0+1
1978: e5 5b                        sbc     VIEW_BOTTOM+1
197a: 6a                           ror     A
197b: 45 13                        eor     ]y0+1
197d: 45 5b                        eor     VIEW_BOTTOM+1
197f: 0a                           asl     A
1980: 66 18                        ror     ]outcode0
1982: 38                           sec
1983: 10 0e                        bpl     :SkipTop0
1985: a5 58                        lda     VIEW_TOP          ;compute (top - y0)
1987: c5 12                        cmp     ]y0
1989: a5 59                        lda     VIEW_TOP+1
198b: e5 13                        sbc     ]y0+1
198d: 6a                           ror     A
198e: 45 59                        eor     VIEW_TOP+1
1990: 45 13                        eor     ]y0+1
1992: 0a                           asl     A
1993: 66 18        :SkipTop0       ror     ]outcode0
1995: a5 56                        lda     VIEW_RIGHT        ;compute (right - x0)
1997: c5 10                        cmp     ]x0
1999: a5 57                        lda     VIEW_RIGHT+1
199b: e5 11                        sbc     ]x0+1
199d: 6a                           ror     A
199e: 45 57                        eor     VIEW_RIGHT+1
19a0: 45 11                        eor     ]x0+1
19a2: 0a                           asl     A
19a3: 66 18                        ror     ]outcode0
19a5: 38                           sec
19a6: 10 0e                        bpl     :SkipLeft0
19a8: a5 10                        lda     ]x0               ;compute (x0 - left)
19aa: c5 54                        cmp     VIEW_LEFT
19ac: a5 11                        lda     ]x0+1
19ae: e5 55                        sbc     VIEW_LEFT+1
19b0: 6a                           ror     A
19b1: 45 11                        eor     ]x0+1
19b3: 45 55                        eor     VIEW_LEFT+1
19b5: 0a                           asl     A
19b6: a5 18        :SkipLeft0      lda     ]outcode0
19b8: 6a                           ror     A
19b9: 29 f0                        and     #$f0              ;remove uninitialized bits
19bb: 49 f0                        eor     #$f0              ;invert meaning of bits
19bd: 85 18                        sta     ]outcode0         ;save
                   ; Trivial rejection: if both outcodes have the same bit set, then both
                   ; coordinates are outside the same edge (e.g. they're both off the top).
19bf: 25 19                        and     ]outcode1         ;any bits in common?
19c1: f0 01                        beq     :CanClip          ;no, it's clippable
19c3: 60                           rts                       ;yes, reject

                   ; Check to see if we have anything more to do.
19c4: a5 18        :CanClip        lda     ]outcode0         ;are any of the outcode bits set?
19c6: 05 19                        ora     ]outcode1
19c8: d0 1f                        bne     :SwapMaybe        ;yes, perform clip on x0,y0
19ca: 18                           clc                       ;we're done; translate clip-space coordinates
19cb: a5 50                        lda     VIEW_X_ADJ        ; to screen coords
19cd: 65 10                        adc     ]x0
19cf: 85 00                        sta     ]clip_x0
19d1: 38                           sec
19d2: a5 52                        lda     VIEW_Y_ADJ
19d4: e5 12                        sbc     ]y0
19d6: 85 01                        sta     ]clip_y0
19d8: 18                           clc
19d9: a5 50                        lda     VIEW_X_ADJ
19db: 65 14                        adc     ]x1
19dd: 85 02                        sta     ]clip_x1
19df: 38                           sec
19e0: a5 52                        lda     VIEW_Y_ADJ
19e2: e5 16                        sbc     ]y1
19e4: 85 03                        sta     ]clip_y1
19e6: 4c 00 10                     jmp     DrawLine          ;draw it

19e9: a5 18        :SwapMaybe      lda     ]outcode0         ;is x0 outside the viewport?
19eb: d0 2a                        bne     :NoSwap           ;yes, work on that
                   ; We always update x0,y0, so when the initial x0,y0 is in the viewport we swap
                   ; coordinates to work on the other pair.
19ed: a6 18                        ldx     ]outcode0
19ef: a5 19                        lda     ]outcode1
19f1: 85 18                        sta     ]outcode0
19f3: 86 19                        stx     ]outcode1
19f5: a6 10                        ldx     ]x0               ;swap x0 with x1
19f7: a5 14                        lda     ]x1
19f9: 85 10                        sta     ]x0
19fb: 86 14                        stx     ]x1
19fd: a6 11                        ldx     ]x0+1
19ff: a5 15                        lda     ]x1+1
1a01: 85 11                        sta     ]x0+1
1a03: 86 15                        stx     ]x1+1
1a05: a6 12                        ldx     ]y0               ;swap y0 with y1
1a07: a5 16                        lda     ]y1
1a09: 85 12                        sta     ]y0
1a0b: 86 16                        stx     ]y1
1a0d: a6 13                        ldx     ]y0+1
1a0f: a5 17                        lda     ]y1+1
1a11: 85 13                        sta     ]y0+1
1a13: 86 17                        stx     ]y1+1
1a15: a5 18                        lda     ]outcode0
1a17: 0a           :NoSwap         asl     A                 ;x/LRTB0000 -> L/RTB00000
1a18: 90 49                        bcc     :LeftOkay
                   ; Adjust x0,y0 so it's inside left edge.
                   ; 
                   ;   x = view_left
                   ;   y = y0 + (y1 - y0) * (view_left - x0) / (x1 - x0)
                   ; 
                   ; At the start of the function we established that abs(x1-x0) is < 256, so we
                   ; can ignore the high bytes when computing (x1-x0).
1a1a: 38                           sec                       ;compute x1 - x0
1a1b: a5 14                        lda     ]x1               ;(treated as unsigned by muldiv?)
1a1d: e5 10                        sbc     ]x0
1a1f: 85 1c                        sta     ]delta2
1a21: 38                           sec                       ;compute view_left - x0
1a22: a5 54                        lda     VIEW_LEFT         ;should be positive, since we know x0 < left
1a24: e5 10                        sbc     ]x0
1a26: aa                           tax
1a27: 38                           sec                       ;compute y1 - y0, 16-bit
1a28: a5 16                        lda     ]y1               ;do the low part
1a2a: e5 12                        sbc     ]y0
1a2c: a8                           tay                       ;tuck it into Y-reg
1a2d: a5 17                        lda     ]y1+1             ;do the high part
1a2f: e5 13                        sbc     ]y0+1
1a31: 85 1d                        sta     ]tmp              ;save it
1a33: 0a                           asl     A                 ;check the high bit
1a34: 98                           tya                       ;restore the low part
1a35: 90 04                        bcc     :IsPos            ;high part positive, branch
1a37: 49 ff                        eor     #$ff              ;high negative, invert the low part
1a39: 69 00                        adc     #$00              ; so we're working with a positive value
1a3b: 20 43 1b     :IsPos          jsr     ClipMulDiv        ;compute A * B / C
1a3e: a2 00                        ldx     #$00
1a40: a5 1b                        lda     ]muldiv_val       ;get the result
1a42: 06 1d                        asl     ]tmp              ;was (y1-y0) negative?
1a44: 90 07                        bcc     :IsPosR           ;no, keep going
1a46: 49 ff                        eor     #$ff              ;make result negative
1a48: 69 00                        adc     #$00
1a4a: f0 01                        beq     :IsPosR           ;result was zero, don't DEX
1a4c: ca                           dex
1a4d: 18           :IsPosR         clc                       ;set Y = y0 + [muldiv]
1a4e: 65 12                        adc     ]y0
1a50: a8                           tay                       ;? why not STA y0?
1a51: 8a                           txa                       ;put $00 or $ff in X-reg based on result sign
1a52: 65 13                        adc     ]y0+1             ;add high byte
1a54: 84 12                        sty     ]y0               ;save new y0
1a56: 85 13                        sta     ]y0+1
1a58: a5 54                        lda     VIEW_LEFT         ;x0 = viewport left edge
1a5a: 85 10                        sta     ]x0
1a5c: a5 55                        lda     VIEW_LEFT+1
1a5e: 85 11                        sta     ]x0+1
1a60: 4c 72 19                     jmp     :ReCheck0

1a63: 0a           :LeftOkay       asl     A                 ;L/RTB00000 -> R/TB000000
1a64: 90 49                        bcc     :RightOkay
                   ; Adjust x0,y0 so it's inside right edge.
                   ; 
                   ;   x = view_right
                   ;   standard: y = y0 + (y1 - y0) * (view_right - x0) / (x1 - x0)
                   ;   this: y = y1 + (y0 - y1) * (view_right - x1) / (x0 - x1)
1a66: 38                           sec
1a67: a5 10                        lda     ]x0
1a69: e5 14                        sbc     ]x1
1a6b: 85 1c                        sta     ]delta2
1a6d: 38                           sec
1a6e: a5 56                        lda     VIEW_RIGHT
1a70: e5 14                        sbc     ]x1
1a72: aa                           tax
1a73: 38                           sec
1a74: a5 12                        lda     ]y0
1a76: e5 16                        sbc     ]y1
1a78: a8                           tay
1a79: a5 13                        lda     ]y0+1
1a7b: e5 17                        sbc     ]y1+1
1a7d: 85 1d                        sta     ]tmp
1a7f: 0a                           asl     A
1a80: 98                           tya
1a81: 90 04                        bcc     L1A87
1a83: 49 ff                        eor     #$ff
1a85: 69 00                        adc     #$00
1a87: 20 43 1b     L1A87           jsr     ClipMulDiv
1a8a: a2 00                        ldx     #$00
1a8c: a5 1b                        lda     ]muldiv_val
1a8e: 06 1d                        asl     ]tmp
1a90: 90 07                        bcc     L1A99
1a92: 49 ff                        eor     #$ff
1a94: 69 00                        adc     #$00
1a96: f0 01                        beq     L1A99
1a98: ca                           dex
1a99: 18           L1A99           clc
1a9a: 65 16                        adc     ]y1
1a9c: a8                           tay
1a9d: 8a                           txa
1a9e: 65 17                        adc     ]y1+1
1aa0: 84 12                        sty     ]y0
1aa2: 85 13                        sta     ]y0+1
1aa4: a5 56                        lda     VIEW_RIGHT
1aa6: 85 10                        sta     ]x0
1aa8: a5 57                        lda     VIEW_RIGHT+1
1aaa: 85 11                        sta     ]x0+1
1aac: 4c 72 19                     jmp     :ReCheck0

1aaf: 10 49        :RightOkay      bpl     :TopOkay          ;R/TB000000 -> T/B0000000
                   ; Adjust x0,y0 so it's inside top edge.
                   ; 
                   ;   standard: x = x0 + (x1 - x0) * (view_top - y0) / (y1 - y0)
                   ;   this: x = x1 + (x0 - x1) * (view_top - y1) / (y0 - y1)
                   ;   y = view_top
1ab1: 38                           sec
1ab2: a5 12                        lda     ]y0
1ab4: e5 16                        sbc     ]y1
1ab6: 85 1c                        sta     ]delta2
1ab8: 38                           sec
1ab9: a5 58                        lda     VIEW_TOP
1abb: e5 16                        sbc     ]y1
1abd: aa                           tax
1abe: 38                           sec
1abf: a5 10                        lda     ]x0
1ac1: e5 14                        sbc     ]x1
1ac3: a8                           tay
1ac4: a5 11                        lda     ]x0+1
1ac6: e5 15                        sbc     ]x1+1
1ac8: 85 1d                        sta     ]tmp
1aca: 0a                           asl     A
1acb: 98                           tya
1acc: 90 04                        bcc     L1AD2
1ace: 49 ff                        eor     #$ff
1ad0: 69 00                        adc     #$00
1ad2: 20 43 1b     L1AD2           jsr     ClipMulDiv
1ad5: a2 00                        ldx     #$00
1ad7: a5 1b                        lda     ]muldiv_val
1ad9: 06 1d                        asl     ]tmp
1adb: 90 07                        bcc     L1AE4
1add: 49 ff                        eor     #$ff
1adf: 69 00                        adc     #$00
1ae1: f0 01                        beq     L1AE4
1ae3: ca                           dex
1ae4: 18           L1AE4           clc
1ae5: 65 14                        adc     ]x1
1ae7: a8                           tay
1ae8: 8a                           txa
1ae9: 65 15                        adc     ]x1+1
1aeb: 84 10                        sty     ]x0
1aed: 85 11                        sta     ]x0+1
1aef: a5 58                        lda     VIEW_TOP
1af1: 85 12                        sta     ]y0
1af3: a5 59                        lda     VIEW_TOP+1
1af5: 85 13                        sta     ]y0+1
1af7: 4c 72 19                     jmp     :ReCheck0

                   ; Adjust x0,y0 so it's inside bottom edge.
                   ; 
                   ;   x = x0 + (x1 - x0) * (view_bottom - y0) / (y1 - y0)
                   ;   y = view_bottom
1afa: 38           :TopOkay        sec                       ;must be off bottom (or we wouldn't be here)
1afb: a5 16                        lda     ]y1
1afd: e5 12                        sbc     ]y0
1aff: 85 1c                        sta     ]delta2
1b01: 38                           sec
1b02: a5 5a                        lda     VIEW_BOTTOM
1b04: e5 12                        sbc     ]y0
1b06: aa                           tax
1b07: 38                           sec
1b08: a5 14                        lda     ]x1
1b0a: e5 10                        sbc     ]x0
1b0c: a8                           tay
1b0d: a5 15                        lda     ]x1+1
1b0f: e5 11                        sbc     ]x0+1
1b11: 85 1d                        sta     ]tmp
1b13: 0a                           asl     A
1b14: 98                           tya
1b15: 90 04                        bcc     L1B1B
1b17: 49 ff                        eor     #$ff
1b19: 69 00                        adc     #$00
1b1b: 20 43 1b     L1B1B           jsr     ClipMulDiv
1b1e: a2 00                        ldx     #$00
1b20: a5 1b                        lda     ]muldiv_val
1b22: 06 1d                        asl     ]tmp
1b24: 90 07                        bcc     L1B2D
1b26: 49 ff                        eor     #$ff
1b28: 69 00                        adc     #$00
1b2a: f0 01                        beq     L1B2D
1b2c: ca                           dex
1b2d: 18           L1B2D           clc
1b2e: 65 10                        adc     ]x0
1b30: a8                           tay
1b31: 8a                           txa
1b32: 65 11                        adc     ]x0+1
1b34: 84 10                        sty     ]x0
1b36: 85 11                        sta     ]x0+1
1b38: a5 5a                        lda     VIEW_BOTTOM
1b3a: 85 12                        sta     ]y0
1b3c: a5 5b                        lda     VIEW_BOTTOM+1
1b3e: 85 13                        sta     ]y0+1
1b40: 4c 72 19                     jmp     :ReCheck0

                   ; 
                   ; Compute A * B / C.
                   ; 
                   ; Only used internally, for line clipping.  Takes about 240 cycles.
                   ; 
                   ; On entry:
                   ;   A-reg: value A (signed)
                   ;   X-reg: value B
                   ;   $1c: value C (signed?)
                   ; 
                   ; On exit:
                   ;   $1b: result
                   ; 
                   • Clear variables
                   ]result_part    .var    $1a    {addr/1}
                   ]result         .var    $1b    {addr/1}
                   ]value_c        .var    $1c    {addr/1}

1b43: e0 00        ClipMulDiv      cpx     #$00              ;check for multiply by zero
1b45: d0 03                        bne     :DoMult           ;no, do the full thing
1b47: 86 1b                        stx     ]result           ;set result to zero
1b49: 60                           rts

1b4a: ca           :DoMult         dex                       ;start with multiply A-reg * X-reg
1b4b: 86 1a                        stx     ]result_part
1b4d: 4a                           lsr     A
1b4e: 85 1b                        sta     ]result
1b50: a9 00                        lda     #$00
1b52: 90 02                        bcc     L1B56
1b54: 65 1a                        adc     ]result_part
1b56: 6a           L1B56           ror     A
1b57: 66 1b                        ror     ]result
1b59: 90 02                        bcc     L1B5D
1b5b: 65 1a                        adc     ]result_part
1b5d: 6a           L1B5D           ror     A
1b5e: 66 1b                        ror     ]result
1b60: 90 02                        bcc     L1B64
1b62: 65 1a                        adc     ]result_part
1b64: 6a           L1B64           ror     A
1b65: 66 1b                        ror     ]result
1b67: 90 02                        bcc     L1B6B
1b69: 65 1a                        adc     ]result_part
1b6b: 6a           L1B6B           ror     A
1b6c: 66 1b                        ror     ]result
1b6e: 90 02                        bcc     L1B72
1b70: 65 1a                        adc     ]result_part
1b72: 6a           L1B72           ror     A
1b73: 66 1b                        ror     ]result
1b75: 90 02                        bcc     L1B79
1b77: 65 1a                        adc     ]result_part
1b79: 6a           L1B79           ror     A
1b7a: 66 1b                        ror     ]result
1b7c: 90 02                        bcc     L1B80
1b7e: 65 1a                        adc     ]result_part
1b80: 6a           L1B80           ror     A
1b81: 66 1b                        ror     ]result
1b83: 90 02                        bcc     L1B87
1b85: 65 1a                        adc     ]result_part
1b87: 6a           L1B87           ror     A
1b88: 66 1b                        ror     ]result
1b8a: 06 1b                        asl     ]result
1b8c: 2a                           rol     A                 ;now divide by $1c
1b8d: b0 04                        bcs     L1B93
1b8f: c5 1c                        cmp     ]value_c
1b91: 90 03                        bcc     L1B96
1b93: e5 1c        L1B93           sbc     ]value_c
1b95: 38                           sec
1b96: 26 1b        L1B96           rol     ]result
1b98: 2a                           rol     A
1b99: b0 04                        bcs     L1B9F
1b9b: c5 1c                        cmp     ]value_c
1b9d: 90 03                        bcc     L1BA2
1b9f: e5 1c        L1B9F           sbc     ]value_c
1ba1: 38                           sec
1ba2: 26 1b        L1BA2           rol     ]result
1ba4: 2a                           rol     A
1ba5: b0 04                        bcs     L1BAB
1ba7: c5 1c                        cmp     ]value_c
1ba9: 90 03                        bcc     L1BAE
1bab: e5 1c        L1BAB           sbc     ]value_c
1bad: 38                           sec
1bae: 26 1b        L1BAE           rol     ]result
1bb0: 2a                           rol     A
1bb1: b0 04                        bcs     L1BB7
1bb3: c5 1c                        cmp     ]value_c
1bb5: 90 03                        bcc     L1BBA
1bb7: e5 1c        L1BB7           sbc     ]value_c
1bb9: 38                           sec
1bba: 26 1b        L1BBA           rol     ]result
1bbc: 2a                           rol     A
1bbd: b0 04                        bcs     L1BC3
1bbf: c5 1c                        cmp     ]value_c
1bc1: 90 03                        bcc     L1BC6
1bc3: e5 1c        L1BC3           sbc     ]value_c
1bc5: 38                           sec
1bc6: 26 1b        L1BC6           rol     ]result
1bc8: 2a                           rol     A
1bc9: b0 04                        bcs     L1BCF
1bcb: c5 1c                        cmp     ]value_c
1bcd: 90 03                        bcc     L1BD2
1bcf: e5 1c        L1BCF           sbc     ]value_c
1bd1: 38                           sec
1bd2: 26 1b        L1BD2           rol     ]result
1bd4: 2a                           rol     A
1bd5: b0 04                        bcs     L1BDB
1bd7: c5 1c                        cmp     ]value_c
1bd9: 90 03                        bcc     L1BDE
1bdb: e5 1c        L1BDB           sbc     ]value_c
1bdd: 38                           sec
1bde: 26 1b        L1BDE           rol     ]result
1be0: 2a                           rol     A
1be1: b0 04                        bcs     L1BE7
1be3: c5 1c                        cmp     ]value_c
1be5: 90 03                        bcc     L1BEA
1be7: e5 1c        L1BE7           sbc     ]value_c
1be9: 38                           sec
1bea: 26 1b        L1BEA           rol     ]result
1bec: 60                           rts

1bed: ff 01 00 ff+                 .align  $0100 (19 bytes)

                   ; 
                   ; Updates all objects, draws them, and draws the HUD items.
                   ; 
1c00: 20 10 60     UpdDrawObjHud   jsr     UPDATE_DRAW_OBJECTS
1c03: 20 32 1c                     jsr     StripFromRadar
1c06: a9 80                        lda     #$80
1c08: 4c 00 7e                     jmp     DRAW_HUD_ITEMS

1c0b: 00 ff ff 00+                 .junk   5

                   ********************************************************************************
                   * Copies hi-res page 2 to page 1.                                              *
                   ********************************************************************************
                   • Clear variables
                   ]dst_ptr        .var    $fc    {addr/2}
                   ]src_ptr        .var    $fe    {addr/2}

1c10: a9 00        CopyHires2to1   lda     #$00
1c12: 85 fe                        sta     ]src_ptr
1c14: 85 fc                        sta     ]dst_ptr
1c16: a9 5f                        lda     #$5f              ;5fxx - 40xx
1c18: 85 ff                        sta     ]src_ptr+1
1c1a: a9 3f                        lda     #$3f              ;3fxx - 20xx
1c1c: 85 fd                        sta     ]dst_ptr+1
1c1e: a0 00                        ldy     #$00
1c20: b1 fe        :Loop           lda     (]src_ptr),y
1c22: 91 fc                        sta     (]dst_ptr),y
1c24: 88                           dey
1c25: d0 f9                        bne     :Loop
1c27: c6 ff                        dec     ]src_ptr+1
1c29: c6 fd                        dec     ]dst_ptr+1
1c2b: a5 fd                        lda     ]dst_ptr+1        ;(could use X-reg here)
1c2d: c9 20                        cmp     #$20
1c2f: b0 ef                        bcs     :Loop
1c31: 60                           rts

                   ; 
                   ; Strips certain things out of the radar.
                   ; 
1c32: a9 00        StripFromRadar  lda     #$00
1c34: a0 17                        ldy     #23
1c36: be 18 84     :Loop           ldx     OBJ_MOVE_CLASS,y  ;get movement class
1c39: e0 09                        cpx     #$09
1c3b: f0 0d                        beq     :StripIt          ;never on radar
1c3d: 2c 81 85                     bit     SHOTS_VIS_FLAG    ;are shots visible?
1c40: 30 0e                        bmi     :NoStrip          ;yes, leave them
1c42: e0 08                        cpx     #$08              ;immovable (obstacle/fuelbay/warplink)?
1c44: f0 0a                        beq     :NoStrip          ;always visible
1c46: e0 05                        cpx     #$05              ;1-4 are visible
1c48: 90 06                        bcc     :NoStrip
1c4a: 99 d0 0c     :StripIt        sta     radar_xcoords,y   ;set coords to zero so we don't draw them
1c4d: 99 e8 0c                     sta     radar_ycoords,y
1c50: 88           :NoStrip        dey
1c51: d0 e3                        bne     :Loop
1c53: 60                           rts

1c54: ff ff 00 00+                 .junk   12

                   ********************************************************************************
                   * Initializes zero-page locations with the game viewport parameters.  This     *
                   * uses the same values that InitViewport0 at ROCK2 $87da does.                 *
                   *                                                                              *
                   * This is called when preparing for the warp-out animation.                    *
                   *                                                                              *
                   * On exit:                                                                     *
                   *   $50-5b: initialized with game viewport parameters                          *
                   *   $22-26: background render params initialized for player facing             *
                   ********************************************************************************
                   ]bk_horiz_pos   .var    $22    {addr/2}
                   ]bk_vert_pos    .var    $24    {addr/2}
                   ]horizon_adj    .var    $26    {addr/1}

1c60: a9 77        InitWarpView    lda     #119              ;center of viewport on screen
1c62: 85 50                        sta     VIEW_X_ADJ
1c64: a9 6b                        lda     #107
1c66: 85 52                        sta     VIEW_Y_ADJ
1c68: a9 90                        lda     #$90
1c6a: 85 54                        sta     VIEW_LEFT         ;-112
1c6c: a9 6f                        lda     #$6f
1c6e: 85 56                        sta     VIEW_RIGHT        ;+111
1c70: a9 4a                        lda     #$4a
1c72: 85 58                        sta     VIEW_TOP          ;+74
1c74: a9 ae                        lda     #$ae
1c76: 85 5a                        sta     VIEW_BOTTOM       ;-82
1c78: a9 00                        lda     #$00
1c7a: 85 51                        sta     VIEW_X_ADJ+1
1c7c: 85 53                        sta     VIEW_Y_ADJ+1
1c7e: 85 57                        sta     VIEW_RIGHT+1
1c80: 85 59                        sta     VIEW_TOP+1
1c82: a9 ff                        lda     #$ff
1c84: 85 55                        sta     VIEW_LEFT+1
1c86: 85 5b                        sta     VIEW_BOTTOM+1
                   ; Configure star/mountain rendering values.
1c88: a9 ff                        lda     #$ff              ;horizon adjustment = -1
1c8a: 85 26                        sta     ]horizon_adj
1c8c: a9 00                        lda     #$00              ;vertical position to zero
1c8e: 85 24                        sta     ]bk_vert_pos
1c90: 85 25                        sta     ]bk_vert_pos+1
1c92: 38                           sec
1c93: ed d8 66                     sbc     OBJ_FACING        ;player facing; invert it
1c96: 0a                           asl     A                 ;double it
1c97: 85 22                        sta     ]bk_horiz_pos     ;save as horizontal position
1c99: 26 23                        rol     ]bk_horiz_pos+1
1c9b: 60                           rts

1c9c: ff ff 01 00                  .junk   4

                   ********************************************************************************
                   * Updates the horizontal and vertical position for viewing the background.     *
                   * Clears the viewport, then draws the background stuff (stars, horizon line,   *
                   * mountains).  Called during the warp-out animation.                           *
                   *                                                                              *
                   * Called from ROCK2, at and around $89a4.                                      *
                   *                                                                              *
                   * On entry:                                                                    *
                   *   $22/23: background horizontal position (facing angle * 2)                  *
                   *   $24/25: background vertical position                                       *
                   *   $c1: amount to rotate                                                      *
                   *   $c3: amount to climb                                                       *
                   ********************************************************************************
                   ]rotate_amt     .var    $c1    {addr/1}
                   ]climb_rate     .var    $c3    {addr/1}

1ca0: ae f0 65     DrawWarpBkgnd   ldx     RENDER_PAGE       ;get page we're rendering on
1ca3: bd cd 1c                     lda     hpage_addr_hi,x   ;convert to high byte of address ($20/$40)
1ca6: 85 32                        sta     hpage
1ca8: 8a                           txa                       ;put 0/1 in A-reg
1ca9: 20 00 74                     jsr     CLEAR_VIEWPORT    ;clear the viewport area on the hi-res screen
1cac: 18                           clc
1cad: a5 22                        lda     ]bk_horiz_pos     ;get current horizontal position
1caf: 65 c1                        adc     ]rotate_amt       ;advance
1cb1: 85 22                        sta     ]bk_horiz_pos
1cb3: a9 00                        lda     #$00              ;repeat for high byte
1cb5: 65 23                        adc     ]bk_horiz_pos+1
1cb7: 48                           pha
1cb8: a5 c1                        lda     ]rotate_amt       ;get the rotation delta sign bit
1cba: 0a                           asl     A
1cbb: 68                           pla
1cbc: 69 00                        adc     #$00              ;add that in as well
1cbe: 85 23                        sta     ]bk_horiz_pos+1
1cc0: 18                           clc
1cc1: a5 24                        lda     ]bk_vert_pos      ;update the vertical position
1cc3: 65 c3                        adc     ]climb_rate
1cc5: 85 24                        sta     ]bk_vert_pos
1cc7: 20 00 70                     jsr     DRAW_MOUNTAINS    ;draw mountains
1cca: 4c b0 70                     jmp     DRAW_STARS        ;draw stars

1ccd: 20 40        hpage_addr_hi   .bulk   $20,$40
1ccf: 00 ff ff 00+                 .align  $0100 (49 bytes)

                   ********************************************************************************
                   * Clears the hi-res screen to black.                                           *
                   *                                                                              *
                   * Theoretically called from ROCK2 by indirect jump ($60f9).  I don't think     *
                   * this is actually used in the game -- the vector gets replaced with           *
                   * ClearViewport.                                                               *
                   *                                                                              *
                   * On entry:                                                                    *
                   *   A-reg: hi-res page (0=page1, 1=page2)                                      *
                   ********************************************************************************
1d00: a2 00        ClearScreen     ldx     #$00
1d02: c9 00                        cmp     #$00
1d04: d0 64                        bne     :Page2
1d06: 9d 00 27     :Page1          sta     $2700,x
1d09: 9d 00 26                     sta     $2600,x
1d0c: 9d 00 25                     sta     $2500,x
1d0f: 9d 00 24                     sta     $2400,x
1d12: 9d 00 23                     sta     $2300,x
1d15: 9d 00 22                     sta     $2200,x
1d18: 9d 00 21                     sta     $2100,x
1d1b: 9d 00 20                     sta     $2000,x
1d1e: 9d 00 2f                     sta     $2f00,x
1d21: 9d 00 2e                     sta     $2e00,x
1d24: 9d 00 2d                     sta     $2d00,x
1d27: 9d 00 2c                     sta     $2c00,x
1d2a: 9d 00 2b                     sta     $2b00,x
1d2d: 9d 00 2a                     sta     $2a00,x
1d30: 9d 00 29                     sta     $2900,x
1d33: 9d 00 28                     sta     $2800,x
1d36: 9d 00 37                     sta     $3700,x
1d39: 9d 00 36                     sta     $3600,x
1d3c: 9d 00 35                     sta     $3500,x
1d3f: 9d 00 34                     sta     $3400,x
1d42: 9d 00 33                     sta     $3300,x
1d45: 9d 00 32                     sta     $3200,x
1d48: 9d 00 31                     sta     $3100,x
1d4b: 9d 00 30                     sta     $3000,x
1d4e: 9d 00 3f                     sta     $3f00,x
1d51: 9d 00 3e                     sta     $3e00,x
1d54: 9d 00 3d                     sta     $3d00,x
1d57: 9d 00 3c                     sta     $3c00,x
1d5a: 9d 00 3b                     sta     $3b00,x
1d5d: 9d 00 3a                     sta     $3a00,x
1d60: 9d 00 39                     sta     $3900,x
1d63: 9d 00 38                     sta     $3800,x
1d66: e8                           inx
1d67: d0 9d                        bne     :Page1
1d69: 60                           rts

1d6a: a9 00        :Page2          lda     #$00
1d6c: 9d 00 47     :Loop2          sta     $4700,x
1d6f: 9d 00 46                     sta     $4600,x
1d72: 9d 00 45                     sta     $4500,x
1d75: 9d 00 44                     sta     $4400,x
1d78: 9d 00 43                     sta     $4300,x
1d7b: 9d 00 42                     sta     $4200,x
1d7e: 9d 00 41                     sta     $4100,x
1d81: 9d 00 40                     sta     $4000,x
1d84: 9d 00 4f                     sta     $4f00,x
1d87: 9d 00 4e                     sta     $4e00,x
1d8a: 9d 00 4d                     sta     $4d00,x
1d8d: 9d 00 4c                     sta     $4c00,x
1d90: 9d 00 4b                     sta     $4b00,x
1d93: 9d 00 4a                     sta     $4a00,x
1d96: 9d 00 49                     sta     $4900,x
1d99: 9d 00 48                     sta     $4800,x
1d9c: 9d 00 57                     sta     $5700,x
1d9f: 9d 00 56                     sta     $5600,x
1da2: 9d 00 55                     sta     $5500,x
1da5: 9d 00 54                     sta     $5400,x
1da8: 9d 00 53                     sta     $5300,x
1dab: 9d 00 52                     sta     $5200,x
1dae: 9d 00 51                     sta     $5100,x
1db1: 9d 00 50                     sta     $5000,x
1db4: 9d 00 5f                     sta     $5f00,x
1db7: 9d 00 5e                     sta     $5e00,x
1dba: 9d 00 5d                     sta     $5d00,x
1dbd: 9d 00 5c                     sta     $5c00,x
1dc0: 9d 00 5b                     sta     $5b00,x
1dc3: 9d 00 5a                     sta     $5a00,x
1dc6: 9d 00 59                     sta     $5900,x
1dc9: 9d 00 58                     sta     $5800,x
1dcc: e8                           inx
1dcd: d0 9d                        bne     :Loop2
1dcf: 60                           rts

                   ********************************************************************************
                   * Initializes an object slot.                                                  *
                   *                                                                              *
                   * Called from BRIEFING.                                                        *
                   *                                                                              *
                   * On entry:                                                                    *
                   *   A-reg: object type                                                         *
                   *   Y-reg: slot number                                                         *
                   ********************************************************************************
1dd0: 99 18 66     InitObjSlot     sta     OBJ_TYPE,y        ;set object type
1dd3: a9 00                        lda     #$00              ;zero in most of the rest
1dd5: 99 48 66                     sta     OBJ_XC_LO,y
1dd8: 99 60 66                     sta     OBJ_XC_HI,y
1ddb: 99 78 66                     sta     OBJ_ZC_LO,y
1dde: 99 90 66                     sta     OBJ_ZC_HI,y
1de1: 99 a8 66                     sta     OBJ_YC_LO,y
1de4: 99 c0 66                     sta     OBJ_YC_HI,y
1de7: 99 d8 66                     sta     OBJ_FACING,y
1dea: 99 f0 66                     sta     OBJ_XC_MOVE,y
1ded: 99 08 67                     sta     OBJ_ZC_MOVE,y
1df0: 99 20 67                     sta     OBJ_YC_MOVE,y
1df3: 99 38 67                     sta     OBJ_SPEED,y
1df6: 99 50 67                     sta     OBJ_FACING_ADJ,y
1df9: 99 68 67                     sta     OBJ_ROT_SPEED,y
1dfc: 99 80 67                     sta     OBJ_IMMOB_FLAG,y
1dff: a9 80                        lda     #$80              ;$80 in these three
1e01: 99 30 66                     sta     OBJ_MAX_DIM,y
1e04: 99 98 67                     sta     OBJ_VIS_FLAG,y
1e07: 99 00 66                     sta     OBJ_ALIVE_FLAG,y  ;(this was zeroed earlier)
1e0a: 60                           rts

                   ; 
                   ; Zeroes all of the "object alive" flags.
                   ; 
1e0b: a0 17        MarkAllInactive ldy     #23
1e0d: a9 00                        lda     #$00
1e0f: 99 00 66     :Loop           sta     OBJ_ALIVE_FLAG,y
1e12: 88                           dey
1e13: 10 fa                        bpl     :Loop
1e15: 60                           rts

                   ********************************************************************************
                   * Copies object state from one slot to another.                                *
                   *                                                                              *
                   * Called from ROCK2.                                                           *
                   *                                                                              *
                   * On entry:                                                                    *
                   *   X-reg: source slot                                                         *
                   *   Y-reg: dest slot                                                           *
                   ********************************************************************************
1e16: bd 00 66     CopyObjState    lda     OBJ_ALIVE_FLAG,x
1e19: 99 00 66                     sta     OBJ_ALIVE_FLAG,y
1e1c: bd 18 66                     lda     OBJ_TYPE,x
1e1f: 99 18 66                     sta     OBJ_TYPE,y
1e22: bd 30 66                     lda     OBJ_MAX_DIM,x
1e25: 99 30 66                     sta     OBJ_MAX_DIM,y
1e28: bd 48 66                     lda     OBJ_XC_LO,x
1e2b: 99 48 66                     sta     OBJ_XC_LO,y
1e2e: bd 60 66                     lda     OBJ_XC_HI,x
1e31: 99 60 66                     sta     OBJ_XC_HI,y
1e34: bd 78 66                     lda     OBJ_ZC_LO,x
1e37: 99 78 66                     sta     OBJ_ZC_LO,y
1e3a: bd 90 66                     lda     OBJ_ZC_HI,x
1e3d: 99 90 66                     sta     OBJ_ZC_HI,y
1e40: bd a8 66                     lda     OBJ_YC_LO,x
1e43: 99 a8 66                     sta     OBJ_YC_LO,y
1e46: bd c0 66                     lda     OBJ_YC_HI,x
1e49: 99 c0 66                     sta     OBJ_YC_HI,y
1e4c: bd d8 66                     lda     OBJ_FACING,x
1e4f: 99 d8 66                     sta     OBJ_FACING,y
1e52: bd f0 66                     lda     OBJ_XC_MOVE,x
1e55: 99 f0 66                     sta     OBJ_XC_MOVE,y
1e58: bd 08 67                     lda     OBJ_ZC_MOVE,x
1e5b: 99 08 67                     sta     OBJ_ZC_MOVE,y
1e5e: bd 20 67                     lda     OBJ_YC_MOVE,x
1e61: 99 20 67                     sta     OBJ_YC_MOVE,y
1e64: bd 38 67                     lda     OBJ_SPEED,x
1e67: 99 38 67                     sta     OBJ_SPEED,y
1e6a: bd 50 67                     lda     OBJ_FACING_ADJ,x
1e6d: 99 50 67                     sta     OBJ_FACING_ADJ,y
1e70: bd 68 67                     lda     OBJ_ROT_SPEED,x
1e73: 99 68 67                     sta     OBJ_ROT_SPEED,y
1e76: bd 80 67                     lda     OBJ_IMMOB_FLAG,x
1e79: 99 80 67                     sta     OBJ_IMMOB_FLAG,y
1e7c: bd 98 67                     lda     OBJ_VIS_FLAG,x
1e7f: 99 98 67                     sta     OBJ_VIS_FLAG,y
1e82: 60                           rts

                   ********************************************************************************
                   * Check to see if two objects collide.  Only tests X/Z.  Does a simple axis-   *
                   * aligned bounding box overlap test.                                           *
                   *                                                                              *
                   * The arena wraps around at the edges, so we need to use modulo arithmetic     *
                   * when checking the distance.                                                  *
                   *                                                                              *
                   * Called from ROCK2.                                                           *
                   *                                                                              *
                   * On entry:                                                                    *
                   *   X-reg: index of first object (0-23)                                        *
                   *   Y-reg: index of second object (0-23)                                       *
                   *                                                                              *
                   * On exit:                                                                     *
                   *   Carry flag set if the objects overlap                                      *
                   ********************************************************************************
                   • Clear variables
                   ]diff           .var    $00    {addr/2}
                   ]combined_dim   .var    $02    {addr/2}

1e83: 18           DetectCollision clc
1e84: bd 30 66                     lda     OBJ_MAX_DIM,x     ;compute the sum of their maximum dimensions
1e87: 79 30 66                     adc     OBJ_MAX_DIM,y
1e8a: 85 02                        sta     ]combined_dim
1e8c: a9 00                        lda     #$00
1e8e: 69 00                        adc     #$00
1e90: 85 03                        sta     ]combined_dim+1
1e92: 38                           sec
1e93: b9 48 66                     lda     OBJ_XC_LO,y       ;compute the distance between object centers
1e96: fd 48 66                     sbc     OBJ_XC_LO,x       ; along the X axis
1e99: 85 00                        sta     ]diff             ;values are +/- 4K, so [0000,0fff] or [f000,ffff]
1e9b: b9 60 66                     lda     OBJ_XC_HI,y       ;combined will be [0000,1ffe] or [e001,ffff]
1e9e: fd 60 66                     sbc     OBJ_XC_HI,x
1ea1: 29 1f                        and     #$1f              ;now [0000,1ffe] or [0001,1fff]
1ea3: 85 01                        sta     ]diff+1           ;save high part
1ea5: 29 10                        and     #$10              ;check bit 4
1ea7: f0 0e                        beq     :XPos             ;treat as positive
1ea9: 18                           clc                       ;treat as negative
1eaa: a5 00                        lda     ]diff             ;the value is flipped, not negated, so un-flip
1eac: 65 02                        adc     ]combined_dim
1eae: a5 01                        lda     ]diff+1
1eb0: 09 e0                        ora     #$e0              ;put the sign bits back
1eb2: 65 03                        adc     ]combined_dim+1
1eb4: b0 09                        bcs     :XClose           ;close, go check Z
1eb6: 60                           rts                       ;far, return

1eb7: a5 02        :XPos           lda     ]combined_dim     ;compare the distance to the object dimensions
1eb9: c5 00                        cmp     ]diff
1ebb: a5 03                        lda     ]combined_dim+1
1ebd: e5 01                        sbc     ]diff+1
1ebf: 90 2c        :XClose         bcc     :Return           ;bail if they're far apart
                   ; Repeat the process for the Z coordinate.
1ec1: b9 78 66                     lda     OBJ_ZC_LO,y
1ec4: fd 78 66                     sbc     OBJ_ZC_LO,x
1ec7: 85 00                        sta     ]diff
1ec9: b9 90 66                     lda     OBJ_ZC_HI,y
1ecc: fd 90 66                     sbc     OBJ_ZC_HI,x
1ecf: 29 1f                        and     #$1f
1ed1: 85 01                        sta     ]diff+1
1ed3: 29 10                        and     #$10
1ed5: f0 0e                        beq     :ZPos
1ed7: 18                           clc
1ed8: a5 00                        lda     ]diff
1eda: 65 02                        adc     ]combined_dim
1edc: a5 01                        lda     ]diff+1
1ede: 09 e0                        ora     #$e0
1ee0: 65 03                        adc     ]combined_dim+1
1ee2: b0 09                        bcs     :Return           ;close in X as well, collide
1ee4: 60                           rts

1ee5: a5 02        :ZPos           lda     ]combined_dim
1ee7: c5 00                        cmp     ]diff
1ee9: a5 03                        lda     ]combined_dim+1
1eeb: e5 01                        sbc     ]diff+1
1eed: 60           :Return         rts

1eee: 00 00 ff ff+                 .junk   15

                   ********************************************************************************
                   * Clears the object movement fields.                                           *
                   *                                                                              *
                   * Called from ROCK2 ($94ec,9789).                                              *
                   *                                                                              *
                   * On entry:                                                                    *
                   *   Y-reg: index ($00-17)                                                      *
                   *                                                                              *
                   * On exit:                                                                     *
                   *   A-reg: $00                                                                 *
                   *   X-reg and Y-reg preserved                                                  *
                   ********************************************************************************
1efd: a9 00        ClearObjMove    lda     #$00
1eff: 99 f0 66                     sta     OBJ_XC_MOVE,y
1f02: 99 08 67                     sta     OBJ_ZC_MOVE,y
1f05: 99 20 67                     sta     OBJ_YC_MOVE,y
1f08: 99 38 67                     sta     OBJ_SPEED,y
1f0b: 99 50 67                     sta     OBJ_FACING_ADJ,y
1f0e: 99 68 67                     sta     OBJ_ROT_SPEED,y
1f11: 60                           rts

                   ********************************************************************************
                   * Initializes one viewport slot.                                               *
                   *                                                                              *
                   * Called from ROCK2.                                                           *
                   *                                                                              *
                   * On entry:                                                                    *
                   *   Y-reg: index (0-3)                                                         *
                   ********************************************************************************
                   InitViewportSlot
1f12: a9 80                        lda     #$80
1f14: 99 c0 67                     sta     VIEW_ACTV_FLAGS,y ;mark as active
1f17: a9 00                        lda     #$00
1f19: 99 c4 67                     sta     VIEW_SKIP_OBJS,y  ;ignore player object
1f1c: a9 00                        lda     #$00
1f1e: 99 c8 67                     sta     VIEW_ANGLE_ADJS,y ;look straight ahead
1f21: a9 07                        lda     #$07
1f23: 99 cc 67                     sta     VIEW_ZOOMS,y      ;default zoom
1f26: a9 80                        lda     #$80
1f28: 99 d0 67                     sta     VIEW_NEAR_VERT,y
1f2b: a9 80                        lda     #$80
1f2d: 99 d4 67                     sta     VIEW_NEAR_LO,y
1f30: a9 00                        lda     #$00
1f32: 99 d8 67                     sta     VIEW_NEAR_HI,y
1f35: a9 00                        lda     #$00
1f37: 99 dc 67                     sta     VIEW_FAR_LO,y
1f3a: a9 10                        lda     #$10
1f3c: 99 e0 67                     sta     VIEW_FAR_HI,y
1f3f: a9 80                        lda     #128              ;default viewport center (256/2)
1f41: 99 e4 67                     sta     VIEW_X_ADJS,y
1f44: a9 60                        lda     #96               ;(192/2)
1f46: 99 e8 67                     sta     VIEW_Y_ADJS,y
1f49: a9 80                        lda     #$80              ;-128
1f4b: 99 ec 67                     sta     VIEW_LEFT_VALS,y
1f4e: a9 7f                        lda     #$7f              ;+127
1f50: 99 f0 67                     sta     VIEW_RIGHT_VALS,y
1f53: a9 60                        lda     #$60              ;+96
1f55: 99 f4 67                     sta     VIEW_TOP_VALS,y
1f58: a9 a1                        lda     #$a1              ;-95
1f5a: 99 f8 67                     sta     VIEW_BOTTOM_VALS,y
1f5d: 60                           rts

                   ; 
                   ; Zeroes out $67C0-67C3, marking all viewports as inactive.
                   ; 
                   DisableViewports
1f5e: a0 03                        ldy     #$03
1f60: a9 00                        lda     #$00
1f62: 99 c0 67     :Loop           sta     VIEW_ACTV_FLAGS,y
1f65: 88                           dey
1f66: 10 fa                        bpl     :Loop
1f68: 60                           rts

                   ********************************************************************************
                   * Initializes graphics engine state.  Clears viewports and object state slots. *
                   *                                                                              *
                   * Called from ROCK2 during initialization.                                     *
                   ********************************************************************************
1f69: a9 00        InitGfxEngine   lda     #$00              ;draw on page 1
1f6b: 8d f0 65                     sta     RENDER_PAGE
1f6e: a9 80                        lda     #$80              ;erase the viewport
1f70: 8d f1 65                     sta     ERASE_VIEW_FLAG
1f73: a9 00                        lda     #$00              ;clear the "nobody move" flags
1f75: 8d f2 65                     sta     BLOCK_MOVEMENT0
1f78: a9 00                        lda     #$00
1f7a: 8d f3 65                     sta     BLOCK_MOVEMENT1
1f7d: a9 00                        lda     #<MESH_DATA       ;set the pointer to the 3D mesh data
1f7f: 8d f4 65                     sta     MESH_DATA_PTR
1f82: a9 68                        lda     #>MESH_DATA
1f84: 8d f5 65                     sta     MESH_DATA_PTR+1
1f87: a9 00                        lda     #<ClearScreen     ;default viewport clear to full screen
1f89: 8d f6 65                     sta     JMP_ADDR_CLEAR
1f8c: a9 1d                        lda     #>ClearScreen
1f8e: 8d f7 65                     sta     JMP_ADDR_CLEAR+1
1f91: a9 c4                        lda     #<InitStateDone   ;default these to known RTS
1f93: 8d f8 65                     sta     JUMP_ADDR2
1f96: a9 1f                        lda     #>InitStateDone
1f98: 8d f9 65                     sta     JUMP_ADDR2+1
1f9b: a9 c4                        lda     #<InitStateDone
1f9d: 8d fa 65                     sta     JUMP_ADDR3
1fa0: a9 1f                        lda     #>InitStateDone
1fa2: 8d fb 65                     sta     JUMP_ADDR3+1
1fa5: a9 00                        lda     #$00
1fa7: 8d fc 65                     sta     SHOW_BKGND_FLAG   ;disable stars/mountains
1faa: a9 ff                        lda     #$ff              ;set horizon baseline to -1 (for mnts/stars)
1fac: 8d fd 65                     sta     HORIZON_BASELINE
1faf: 20 0b 1e                     jsr     MarkAllInactive   ;clear all of the "object is alive" flags
1fb2: a0 00                        ldy     #$00              ;zero out slot 0
1fb4: a9 00                        lda     #$00
1fb6: 20 d0 1d                     jsr     InitObjSlot
1fb9: 20 5e 1f                     jsr     DisableViewports  ;disable all viewport slots
1fbc: a0 00                        ldy     #$00
1fbe: 20 12 1f                     jsr     InitViewportSlot  ;init viewport slot 0
1fc1: 2c 52 c0                     bit     MIXCLR            ;make sure we're in full-screen mode
1fc4: 60           InitStateDone   rts

1fc5: ff 00 00 ff+                 .align  $0100 (59 bytes)

Symbol Table

ClearObjMove$1efd
clip_coord_xhi$0e40
clip_coord_xlo$0e00
clip_coord_yhi$0ec0
clip_coord_ylo$0e80
ClipDrawLine$1900
CopyHires2to1$1c10
CopyObjState$1e16
DetectCollision$1e83
div7_tab$1700
Divide16$0810
DrawLine$1000
DrawWarpBkgnd$1ca0
hires_addr_hi$1600
hires_addr_lo$1500
InitGfxEngine$1f69
InitObjSlot$1dd0
InitViewportSlot$1f12
InitWarpView$1c60
MarkAllInactive$1e0b
mod7_tab$1800
radar_xcoords$0cd0
radar_ycoords$0ce8
RotateCoords$0b00
RotateInt8$0d00
UpdDrawObjHud$1c00