Prince-of-Persia-Apple-II

A running-jumping-swordfighting game Jordan Mechner made on the Apple II from 1985-89
Log | Files | Refs | README | LICENSE

HIRES.S (26169B)


      1 * hires
      2 org = $ee00
      3  tr on
      4  lst off
      5 *-------------------------------
      6 *
      7 *  PRINCE OF PERSIA
      8 *  Copyright 1989 Jordan Mechner
      9 *
     10 *-------------------------------
     11  org org
     12 
     13  jmp boot3
     14  jmp cls
     15  jmp lay
     16  jmp fastlay
     17  jmp layrsave
     18 
     19  jmp lrcls
     20  jmp fastmask
     21  jmp fastblack
     22  jmp peel
     23  jmp getwidth
     24 
     25  jmp copyscrnMM
     26  jmp copyscrnAA
     27  jmp SETFASTAUX
     28  jmp SETFASTMAIN
     29  jmp copyscrnMA
     30 
     31  jmp copyscrnAM
     32  jmp INVERTY
     33 
     34 *-------------------------------
     35  put hrparams
     36 
     37 *-------------------------------
     38 boot3 = $f880 ;stage 3 boot
     39 
     40 peelbuf1 = $d000
     41 peelbuf2 = $d600
     42 
     43 * Local vars
     44 
     45 locals = $f0
     46 locals2 = $18
     47 
     48  dum locals
     49 
     50 BASE ds 2
     51 IMSAVE ds 2
     52 XSAVE ds 1
     53 YSAVE ds 1
     54 WIDTH ds 1
     55 HEIGHT ds 1
     56 TOPEDGE ds 1
     57 OFFLEFT ds 1
     58 OFFRIGHT ds 1
     59 YREG ds 1
     60 CARRY ds 1
     61 
     62  dum locals2
     63 index
     64 ztemp
     65 AMASK ds 1
     66 BMASK ds 1
     67 VISWIDTH ds 1
     68 RMOST ds 1
     69 carryim ds 1
     70 imbyte ds 1
     71 
     72  dend
     73 
     74 * OPACITY codes
     75 
     76 and = 0
     77 ora = 1
     78 sta = 2
     79 eor = 3 ;OR/shift/XOR
     80 mask = 4 ;mask/OR
     81 
     82 *-------------------------------
     83 *
     84 * Assume hires routines are called from auxmem
     85 * (Exit with RAMRD, RAMWRT, ALTZP on)
     86 *
     87 *-------------------------------
     88 
     89 cls jsr mainmem
     90  jsr CLS
     91  jmp auxmem
     92 
     93 lay jsr mainmem
     94  jsr LAY
     95  jmp auxmem
     96 
     97 fastlay
     98  jsr FASTLAY
     99  jmp auxmem
    100 
    101 layrsave jsr mainmem
    102  jsr LAYRSAVE
    103  jmp auxmem
    104 
    105 lrcls jsr mainmem
    106  jsr LRCLS
    107  jmp auxmem
    108 
    109 fastmask
    110   jsr FASTMASK
    111  jmp auxmem
    112 
    113 fastblack jsr mainmem
    114  jsr FASTBLACK
    115  jmp auxmem
    116 
    117 peel
    118  jsr PEEL
    119  jmp auxmem
    120 
    121 getwidth jsr mainmem
    122  jsr GETWIDTH
    123  jmp auxmem
    124 
    125 copyscrnMM
    126  jsr mainmem ;r/w main
    127 ]copyscrn jsr COPYSCRN
    128  jmp auxmem
    129 
    130 copyscrnAA
    131  jsr auxmem ;r/w aux
    132  jmp ]copyscrn
    133 
    134 copyscrnMA
    135  sta $c002 ;read main
    136  sta $c005 ;write aux
    137  jmp ]copyscrn
    138 
    139 copyscrnAM
    140  sta $c003 ;read aux
    141  sta $c004 ;write main
    142  jmp ]copyscrn
    143 
    144 *-------------------------------
    145 mainmem sta $c004 ;RAMWRT off
    146  sta $c002 ;RAMRD off
    147  rts
    148 
    149 auxmem sta $c005 ;RAMWRT on
    150  sta $c003 ;RAMRD on
    151  rts
    152 
    153 *-------------------------------
    154 *
    155 *  Parameters passed to hires routines:
    156 *
    157 *  PAGE        $00 = hires page 1, $20 = hires page 2
    158 *  XCO         Screen X-coord (0=left, 39=right)
    159 *  YCO         Screen Y-coord (0=top, 191=bottom)
    160 *  OFFSET      # of bits to shift image right (0-6)
    161 *  IMAGE       Image # in table (1-127)
    162 *  TABLE       Starting address of image table (2 bytes)
    163 *  BANK        Memory bank of table (2 = main, 3 = aux)
    164 *  OPACITY     Bits 0-6:
    165 *                0    AND
    166 *                1    OR
    167 *                2    STA
    168 *                3    special XOR (OR/shift/XOR)
    169 *                4    mask/OR
    170 *              Bit 7: 0 = normal, 1 = mirror
    171 *  LEFTCUT     Left edge of usable screen area
    172 *                (0 for full screen)
    173 *  RIGHTCUT    Right edge +1 of usable screen area
    174 *                (40 for full screen)
    175 *  TOPCUT      Top edge of usable screen area
    176 *                (0 for full screen)
    177 *  BOTCUT      Bottom edge +1 of usable screen area
    178 *                (192 for full screen)
    179 *
    180 *-------------------------------
    181 *
    182 *  Image table format:
    183 *
    184 *  Byte 0:    width (# of bytes)
    185 *  Byte 1:    height (# of lines)
    186 *  Byte 2-n:  image bytes (read left-right, top-bottom)
    187 *
    188 *-------------------------------
    189 *
    190 *  To preserve the background behind an animated character,
    191 *  call LAYERSAVE before LAYing down each character image.
    192 *  Afterwards, call PEEL to "peel off" the character &
    193 *  restore the original background.
    194 *
    195 *  Peel buffer stores background images sequentially, in
    196 *  normal image table format, & is cleared after every frame.
    197 *
    198 *-------------------------------
    199 *
    200 *  C L S
    201 *
    202 *  Clear hi-res screen to black2
    203 *
    204 *-------------------------------
    205 
    206 CLS lda PAGE ;00 = page 1; 20 = page 2
    207  clc
    208  adc #$20
    209  sta :loop+2
    210  adc #$10
    211  sta :smod+2
    212 
    213  lda #$80 ;black2
    214 
    215  ldx #$10
    216 
    217  ldy #0
    218 
    219 :loop sta $2000,y
    220 :smod sta $3000,y
    221  iny
    222  bne :loop
    223 
    224  inc :loop+2
    225  inc :smod+2
    226 
    227  dex
    228  bne :loop
    229 
    230  rts
    231 
    232 *-------------------------------
    233 *
    234 *  L O - R E S   C L S
    235 *
    236 *  Clear lo-res/text screen (page 1)
    237 *
    238 *  In: A = color
    239 *
    240 *-------------------------------
    241 
    242 LRCLS LDY #$F7
    243 :2 STA $400,Y
    244  STA $500,Y
    245  STA $600,Y
    246  STA $700,Y
    247  DEY
    248  CPY #$7F
    249  BNE :3
    250  LDY #$77
    251 :3 CPY #$FF
    252  BNE :2
    253  RTS
    254 
    255 *-------------------------------
    256 *
    257 *  S E T   I M A G E
    258 *
    259 *  In: TABLE (2 bytes), IMAGE (image #)
    260 *  Out: IMAGE = image start address (2 bytes)
    261 *
    262 *-------------------------------
    263 
    264 setimage lda IMAGE
    265  asl
    266  sec
    267  sbc #1
    268 
    269  tay
    270  lda (TABLE),y
    271  sta IMAGE
    272 
    273  iny
    274  lda (TABLE),y
    275  sta IMAGE+1
    276 
    277  rts
    278 
    279 *-------------------------------
    280 *
    281 *  G E T   W I D T H
    282 *
    283 *  In: BANK, TABLE, IMAGE
    284 *  Out: A = width, X = height
    285 *
    286 *-------------------------------
    287 GETWIDTH
    288  lda BANK
    289  sta :RAMRD+1
    290 
    291 :RAMRD sta $c003
    292 
    293  jsr setimage
    294 
    295  ldy #1
    296  lda (IMAGE),y ;height
    297  tax
    298 
    299  dey
    300  lda (IMAGE),y ;width
    301  rts
    302 
    303 *-------------------------------
    304 *
    305 *  P R E P R E P
    306 *
    307 *  In: IMAGE, XCO, YCO
    308 *
    309 *-------------------------------
    310 
    311 PREPREP
    312 
    313 * Save IMAGE, XCO, YCO
    314 
    315  LDA IMAGE
    316  STA IMSAVE
    317  LDA XCO
    318  STA XSAVE
    319  LDA YCO
    320  STA YSAVE
    321 
    322 * Get image data start address
    323 
    324  lda BANK
    325  sta :RAMRD+1
    326 
    327 :RAMRD sta $c003
    328 
    329  jsr setimage
    330 
    331 * Read first two bytes (width, height) of image table
    332 
    333  LDY #0
    334  LDA (IMAGE),Y
    335  STA WIDTH
    336 
    337  INY
    338  LDA (IMAGE),Y
    339  STA HEIGHT
    340 
    341  LDA IMAGE
    342  CLC
    343  ADC #2
    344  STA IMAGE
    345  BCC :3
    346  INC IMAGE+1
    347 
    348 :3 sta $c002 ;RAMRD off (read mainmem)
    349 
    350 ]rts rts
    351 
    352 *-------------------------------
    353 *
    354 *  C R O P
    355 *
    356 *  In:  Results of PREPREP (XCO, YCO, HEIGHT, WIDTH)
    357 *       Screen area cutoffs (LEFTCUT, RIGHTCUT, TOPCUT, BOTCUT)
    358 *
    359 *  Out:
    360 *
    361 *  TOPEDGE   Top line -1
    362 *  VISWIDTH  Width, in bytes, of visible (onscreen) portion
    363 *               of image
    364 *  XCO       X-coord of leftmost visible byte of image
    365 *               (must be 0-39)
    366 *  YCO       Y-coord of lowest visible line of image
    367 *               (must be 0-191)
    368 *  OFFLEFT   # of bytes off left edge
    369 *  OFFRIGHT  # of bytes off right edge (including carry byte)
    370 *  RMOST     # of bytes off right edge (excluding carry byte)
    371 *
    372 *  Return - if entire image is offscreen, else +
    373 *
    374 *-------------------------------
    375 CROP
    376 
    377 * (1) Crop top & bottom
    378 
    379  lda YCO
    380  cmp BOTCUT
    381  bcs :botoff ;Bottom o.s.
    382 
    383 * Bottom is onscreen--check top
    384 
    385  sec
    386  sbc HEIGHT ;top line -1
    387  cmp #191
    388  bcc :topok ;Top is onscreen
    389 
    390  lda TOPCUT ;Top is offscreen
    391  sec
    392  sbc #1
    393  sta TOPEDGE
    394  jmp :done
    395 
    396 :topok sta TOPEDGE ;Top line -1 (0-191)
    397 
    398  lda TOPCUT ;top line of image area (forced mask)
    399  beq :done ;no top cutoff
    400 
    401  sec
    402  sbc #1
    403  cmp TOPEDGE
    404  bcc :done
    405 
    406  sta TOPEDGE
    407  bcs :done
    408 
    409 * Bottom is o.s.--advance IMAGE pointer past o.s. portion
    410 
    411 :botoff ;A = YCO
    412  sec
    413  sbc HEIGHT
    414  clc
    415  adc #1 ;top line
    416  cmp BOTCUT
    417  bcs :cancel ;Entire shape is o.s.
    418  sec
    419  sbc #1
    420  sta TOPEDGE ;top line -1
    421 
    422  ldx YCO
    423 :loop
    424  lda IMAGE
    425  clc
    426  adc WIDTH
    427  sta IMAGE
    428  bcc :1
    429  inc IMAGE+1
    430 :1
    431  dex
    432  cpx BOTCUT
    433  bcs :loop
    434 
    435  stx YCO
    436 
    437 * (2) Crop sides
    438 
    439 :done
    440  lda XCO
    441  bmi :leftoff
    442  cmp LEFTCUT
    443  bcs :leftok ;XCO >= LEFTCUT
    444 
    445 * XCO < LEFTCUT: left edge is offscreen
    446 
    447 :leftoff
    448  lda LEFTCUT
    449  sec
    450  sbc XCO
    451  sta OFFLEFT ;Width of o.s. portion
    452 
    453  lda WIDTH
    454  sec
    455  sbc OFFLEFT
    456  bmi :cancel ;Entire image is o.s. -- skip it
    457  sta VISWIDTH ;Width of onscreen portion (can be 0)
    458 
    459  lda LEFTCUT
    460  sta XCO
    461 
    462 * Assume image is <=40 bytes wide --> right edge is onscreen
    463 
    464  lda #0
    465  sta OFFRIGHT
    466  sta RMOST
    467  rts
    468 
    469 * Left edge is onscreen; what about right edge?
    470 
    471 :leftok ;A = XCO
    472  cmp RIGHTCUT ;normally 40
    473  bcs :cancel ;Entire image is o.s. - skip it
    474 
    475  clc
    476  adc WIDTH ;rightmost byte +1
    477  cmp RIGHTCUT
    478  bcc :bothok ;Entire image is onscreen
    479 
    480  sec
    481  sbc RIGHTCUT
    482  sta RMOST ;Width of o.s. portion
    483 
    484  clc
    485  adc #1
    486  sta OFFRIGHT ;+1
    487 
    488  lda RIGHTCUT
    489  sec
    490  sbc XCO
    491  sta VISWIDTH ;Width of onscreen portion
    492 
    493  lda #0
    494  sta OFFLEFT
    495  rts
    496 
    497 :bothok lda WIDTH
    498  sta VISWIDTH
    499 
    500  lda #0
    501  sta OFFLEFT
    502  sta OFFRIGHT
    503  sta RMOST
    504  rts
    505 
    506 :cancel lda #-1 ;Entire image is o.s. - skip it
    507 ]rts rts
    508 
    509 *-------------------------------
    510 *
    511 * Shift offset 1 bit right or left
    512 * (for special XOR)
    513 *
    514 * In/out: X = offset
    515 *
    516 *-------------------------------
    517 shiftoffset
    518  cpx #6
    519  bcs :left
    520 
    521  inx
    522  rts
    523 
    524 :left dex
    525 ]rts rts
    526 
    527 *-------------------------------
    528 *
    529 *  L A Y E R S A V E
    530 *
    531 *  In:  Same as for LAY, plus PEELBUF (2 bytes)
    532 *  Out: PEELBUF (updated), PEELIMG (2 bytes), PEELXCO, PEELYCO
    533 *
    534 *  PEELIMG is 2-byte pointer to beginning of image table.
    535 *  (Hi byte = 0 means no image has been stored.)
    536 *
    537 *  PEELBUF is 2-byte pointer to first available byte in
    538 *  peel buffer.
    539 *
    540 *-------------------------------
    541 
    542 LAYRSAVE
    543  jsr PREPREP
    544 
    545  lda OPACITY
    546  bpl :normal
    547 
    548  LDA XCO
    549  SEC
    550  SBC WIDTH
    551  STA XCO
    552 
    553 :normal
    554  inc WIDTH ;extra byte to cover shift right
    555 
    556  jsr CROP
    557  bmi SKIPIT
    558 
    559  lda PEELBUF ;PEELBUF: 2-byte pointer to 1st
    560  sta PEELIMG ;available byte in peel buffer
    561  lda PEELBUF+1
    562  sta PEELIMG+1
    563 
    564  lda XCO
    565  sta PEELXCO
    566  sta :smXCO+1
    567 
    568  lda YCO
    569  sta PEELYCO
    570 
    571  lda PAGE ;spend 7 cycles now --
    572  sta :smPAGE+1 ;save 1 in loop
    573 
    574  ldy #0
    575 
    576  lda VISWIDTH
    577  beq SKIPIT
    578  sta (PEELBUF),y
    579  sta :smWIDTH+1
    580 
    581  sec
    582  sbc #1
    583  sta :smSTART+1
    584 
    585 * Continue
    586 
    587 :cont iny
    588 
    589  LDA YCO
    590  SEC
    591  SBC TOPEDGE
    592  STA (PEELBUF),y ;Height of onscreen portion ("VISHEIGHT")
    593 
    594  LDA PEELBUF
    595  CLC
    596  ADC #2
    597  STA PEELBUF
    598  BCC :ok
    599  INC PEELBUF+1
    600 :ok
    601 
    602 * Like FASTLAY in reverse
    603 
    604  ldx YCO
    605 
    606 :loop LDA YLO,X
    607  CLC
    608 :smXCO ADC #0 ;XCO
    609  STA :smBASE+1
    610 
    611  LDA YHI,X
    612 :smPAGE ADC #0 ;PAGE
    613  STA :smBASE+2
    614 
    615 :smSTART ldy #0 ;VISWIDTH-1
    616 
    617 :inloop
    618 :smBASE lda $2000,y
    619  STA (PEELBUF),Y
    620 
    621  dey
    622  bpl :inloop
    623 
    624 :smWIDTH LDA #0 ;VISWIDTH
    625  ADC PEELBUF ;assume cc
    626  STA PEELBUF
    627  BCC :2
    628  INC PEELBUF+1
    629 :2
    630  DEX
    631  CPX TOPEDGE
    632  BNE :loop
    633 
    634  JMP DONE
    635 
    636 SKIPIT lda #0
    637  sta PEELIMG+1 ;signal that peelbuf is empty
    638 
    639  JMP DONE
    640 
    641 *-------------------------------
    642 *
    643 *  L A Y
    644 *
    645 *  General routine to lay down an image on hi-res screen
    646 *  (Handles edge-clipping, bit-shifting, & mirroring)
    647 *
    648 *  Calls one of the following routines:
    649 *
    650 *    LayGen    General (OR, AND, STA)
    651 *    LayMask   Mask & OR
    652 *    LayXOR    Special XOR
    653 *
    654 *  Transfers control to MLAY if image is to be mirrored
    655 *
    656 *-------------------------------
    657 
    658 LAY
    659  lda OPACITY
    660  bpl :notmirr
    661 
    662  and #$7f
    663  sta OPACITY
    664  jmp MLAY
    665 
    666 :notmirr cmp #eor
    667  bne :1
    668  jmp LayXOR
    669 
    670 :1 cmp #mask
    671  bcc :2
    672  jmp LayMask
    673 
    674 :2 jmp LayGen
    675 
    676 *-------------------------------
    677 *
    678 *   General (AND/OR/STORE)
    679 *
    680 *-------------------------------
    681 LayGen
    682  jsr PREPREP
    683 
    684  jsr CROP
    685  bpl :cont
    686  jmp DONE
    687 :cont
    688  lda BANK
    689  sta :RAMRD1+1
    690  sta :RAMRD2+1
    691 
    692  LDX OFFSET
    693 
    694  LDA SHIFTL,X
    695  STA :91+1
    696  LDA SHIFTH,X
    697  STA :91+2
    698 
    699  LDA CARRYL,X
    700  STA :90+1
    701  STA :92+1
    702  LDA CARRYH,X
    703  STA :90+2
    704  STA :92+2
    705 
    706  LDA AMASKS,X
    707  STA :AMASK+1
    708  LDA BMASKS,X
    709  STA :BMASK+1
    710 
    711  LDX OPACITY
    712  LDA OPCODE,X
    713  STA :80
    714  STA :81
    715 
    716 * Preparation completed -- Lay down shape
    717 
    718  LDY YCO
    719 
    720 :nextline
    721  LDA YLO,Y
    722  CLC
    723  ADC XCO
    724  STA BASE
    725 
    726  LDA YHI,Y
    727  ADC PAGE
    728  STA BASE+1
    729 
    730  LDY OFFLEFT
    731  BEQ :2
    732 
    733 * (a) Left edge of image is offscreen
    734 * Take initial carry byte from image table
    735 
    736  DEY
    737 
    738 :RAMRD1 sta $c003 ;aux/main
    739  lda (IMAGE),y
    740  sta $c002 ;main
    741 
    742  TAX
    743 :90 LDA $FFFF,X ;CARRYn
    744  STA CARRY
    745 
    746  LDA IMAGE
    747  CLC
    748  ADC OFFLEFT
    749  STA IMAGE
    750  BCC :1
    751  INC IMAGE+1
    752 :1
    753  LDY #0
    754 
    755  LDA VISWIDTH
    756  STA WIDTH
    757  BNE :3
    758  BEQ :4 ;Zero width
    759 
    760 * (b) Left edge of image is onscreen
    761 * Take initial carry byte from screen
    762 
    763 :2 LDA (BASE),Y
    764 :AMASK AND #0
    765  STA CARRY
    766 
    767 * Lay line down left-to-right fast as you can
    768 
    769 :3
    770 :RAMRD2 sta $c003 ;aux/main
    771  lda (IMAGE),y
    772  sta $c002 ;main
    773 
    774  TAX
    775 :91 LDA $FFFF,X ;SHIFTn
    776  ORA CARRY ;Combine with carryover from previous byte
    777 
    778 :80 STA (BASE),Y ;STA/ORA/AND/EOR depending on OPACITY
    779  STA (BASE),Y
    780 
    781 :92 LDA $FFFF,X ;CARRYn
    782  STA CARRY ;Carry over to next byte
    783 
    784  INY
    785  CPY VISWIDTH
    786  BCC :3
    787 
    788 *  Extra byte on right (carryover)
    789 
    790  LDA OFFRIGHT
    791  BNE :5 ;Rightmost byte is offscreen
    792 
    793 :4 LDA (BASE),Y
    794 
    795 :BMASK AND #0
    796  ORA CARRY
    797 :81 STA (BASE),Y
    798  STA (BASE),Y
    799 
    800 *  Next line up
    801 
    802 :5 LDA WIDTH
    803  CLC
    804  ADC IMAGE
    805  STA IMAGE
    806  BCC :6
    807  INC IMAGE+1
    808 
    809 :6 DEC YCO
    810  LDY YCO
    811  CPY TOPEDGE
    812  BNE :nextline
    813 
    814 *  Restore parameters
    815 
    816 DONE LDA IMSAVE
    817  STA IMAGE
    818 
    819  LDA XSAVE
    820  STA XCO
    821  LDA YSAVE
    822  STA YCO
    823 
    824  RTS
    825 
    826 *-------------------------------
    827 *
    828 *  Mask, then OR
    829 *
    830 *-------------------------------
    831 ]done jmp DONE
    832 
    833 LayMask
    834  ldx OPACITY ;4 = mask, 5 = visible mask
    835  lda OPCODE,x ;4 = and, 5 = sta
    836  sta :masksm1
    837  sta :masksm2
    838 
    839  jsr PREPREP
    840 
    841  jsr CROP
    842  bmi ]done
    843 
    844  lda BANK
    845  sta :RAMRD1+1
    846  sta :RAMRD2+1
    847 
    848  LDX OFFSET
    849 
    850  LDA SHIFTL,X
    851  STA :91+1
    852  sta :93+1
    853 
    854  LDA SHIFTH,X
    855  STA :91+2
    856  sta :93+2
    857 
    858  LDA CARRYL,X
    859  STA :90+1
    860  STA :92+1
    861  sta :94+1
    862  sta :96+1
    863 
    864  LDA CARRYH,X
    865  STA :90+2
    866  STA :92+2
    867  sta :94+2
    868  sta :96+2
    869 
    870  LDA AMASKS,X
    871  STA :AMASK+1
    872 
    873  LDA BMASKS,X
    874  STA :BMASK+1
    875 
    876  LDY YCO
    877 
    878 :nextline
    879  LDA YLO,Y
    880  CLC
    881  ADC XCO
    882  STA BASE
    883 
    884  LDA YHI,Y
    885  ADC PAGE
    886  STA BASE+1
    887 
    888  LDY OFFLEFT
    889  BEQ :2
    890 
    891 * (a) Left edge of image is offscreen
    892 * Take initial carry byte from image table
    893 
    894  dey
    895 
    896 :RAMRD1 sta $c003
    897  lda (IMAGE),y
    898 ; eor #$ff ;TEMP
    899 ; ora #$80 ;TEMP
    900  sta $c002
    901 
    902  tax
    903 :96 lda $FFFF,x ;CARRYn
    904  sta carryim
    905 
    906  lda MASKTAB-$80,x
    907  tax
    908 :90 lda $FFFF,x ;CARRYn
    909  sta CARRY
    910 
    911  LDA IMAGE
    912  CLC
    913  ADC OFFLEFT
    914  STA IMAGE
    915  BCC :1
    916  INC IMAGE+1
    917 :1
    918  ldy #0
    919 
    920  LDA VISWIDTH
    921  STA WIDTH
    922  BNE :inloop
    923  BEQ :4 ;Zero width
    924 
    925 * (b) Left edge of image is onscreen
    926 * Take initial carry byte from screen
    927 
    928 :2
    929 :AMASK lda #0 ;AMASK
    930  sta CARRY
    931 
    932  and (BASE),y
    933  sta carryim
    934 
    935 * Lay line down left-to-right fast as you can
    936 
    937 :inloop
    938 
    939 :RAMRD2 sta $c003
    940  lda (IMAGE),y
    941 ; eor #$ff ;TEMP
    942 ; ora #$80 ;TEMP
    943  sta $c002
    944 
    945  tax
    946 
    947 :93 lda $FFFF,x ;SHIFTn
    948  ora carryim
    949  sta imbyte ;shifted image byte
    950 
    951 :94 lda $FFFF,x ;CARRYn
    952  sta carryim
    953 
    954  lda MASKTAB-$80,x
    955  tax
    956 
    957 :91 lda $FFFF,x ;SHIFTn
    958  ora CARRY
    959 :masksm1 and (BASE),y ;AND with mask byte
    960  ora imbyte ;OR with original image byte
    961  sta (BASE),y
    962 
    963 :92 lda $FFFF,x ;CARRYn
    964  sta CARRY ;Carry over to next byte
    965 
    966  iny
    967  cpy VISWIDTH
    968  bcc :inloop
    969 
    970 *  Extra byte on right (carryover)
    971 
    972  lda OFFRIGHT
    973  bne :5 ;Rightmost byte is offscreen
    974 
    975 :4
    976 :BMASK lda #0 ;BMASK
    977  ora CARRY
    978 :masksm2 and (BASE),y
    979  ora carryim
    980  sta (BASE),y
    981 
    982 *  Next line up
    983 
    984 :5 LDA WIDTH
    985  CLC
    986  ADC IMAGE
    987  STA IMAGE
    988  BCC :6
    989  INC IMAGE+1
    990 
    991 :6 DEC YCO
    992  LDY YCO
    993  CPY TOPEDGE
    994  beq :done
    995 
    996  jmp :nextline
    997 
    998 :done jmp DONE
    999 
   1000 *-------------------------------
   1001 *
   1002 *  Special XOR
   1003 *
   1004 *  (OR, then shift 1 bit and XOR)
   1005 *
   1006 *-------------------------------
   1007 
   1008 LayXOR
   1009  JSR PREPREP
   1010 
   1011  jsr CROP
   1012  bpl :cont
   1013  jmp DONE
   1014 :cont
   1015  lda BANK
   1016  sta :RAMRD1+1
   1017  sta :RAMRD2+1
   1018 
   1019  LDX OFFSET
   1020 
   1021  LDA SHIFTL,X
   1022  STA :91+1
   1023  LDA SHIFTH,X
   1024  STA :91+2
   1025 
   1026  LDA CARRYL,X
   1027  STA :90+1
   1028  STA :92+1
   1029  LDA CARRYH,X
   1030  STA :90+2
   1031  STA :92+2
   1032 
   1033  jsr shiftoffset ;shift 1 bit right
   1034 
   1035  lda SHIFTL,x
   1036  sta :s1+1
   1037  lda SHIFTH,x
   1038  sta :s1+2
   1039 
   1040  lda CARRYL,x
   1041  sta :c1+1
   1042  sta :c2+1
   1043  lda CARRYH,x
   1044  sta :c1+2
   1045  sta :c2+2
   1046 
   1047  LDA AMASKS,X
   1048  STA :AMASK+1
   1049 
   1050 * Omit opcode setting
   1051 
   1052  LDY YCO
   1053 
   1054 :0 LDA YLO,Y
   1055  CLC
   1056  ADC XCO
   1057  STA BASE
   1058 
   1059  LDA YHI,Y
   1060  ADC PAGE
   1061  STA BASE+1
   1062 
   1063  LDY OFFLEFT
   1064  BEQ :2
   1065 
   1066 *  (a) Left edge offscreen
   1067 *  Take CARRY from off left edge
   1068 
   1069  DEY
   1070 
   1071 :RAMRD1 sta $c003
   1072  lda (IMAGE),y
   1073  sta $c002
   1074 
   1075  TAX
   1076 :c2 lda $FFFF,x ;CARRYn+1
   1077  sta carryim
   1078 
   1079 :90 LDA $FFFF,X ;CARRYn
   1080  STA CARRY
   1081 
   1082  LDA IMAGE
   1083  CLC
   1084  ADC OFFLEFT
   1085  STA IMAGE
   1086  BCC :1
   1087  INC IMAGE+1
   1088 
   1089 :1 LDY #0
   1090 
   1091  LDA VISWIDTH
   1092  STA WIDTH
   1093  BNE :inloop
   1094  BEQ :4 ;Zero width
   1095 
   1096 * (b) Left edge onscreen
   1097 * Start a new line at left edge
   1098 
   1099 :2 lda (BASE),y
   1100 :AMASK and #0 ;AMASK
   1101  sta CARRY
   1102 
   1103  lda #0 ;0 XOR X == X
   1104  sta carryim
   1105 
   1106 * Lay line down left-to-right fast as you can
   1107 
   1108 :inloop
   1109 
   1110 :RAMRD2 sta $c003
   1111  lda (IMAGE),y
   1112  sta $c002
   1113 
   1114  tax
   1115 
   1116 :s1 lda $FFFF,x ;SHIFTn+1
   1117  ora carryim
   1118  sta imbyte
   1119 
   1120 :c1 lda $FFFF,x ;CARRYn+1
   1121  sta carryim
   1122 
   1123 :91 lda $FFFF,x ;SHIFTn
   1124  ora CARRY ;Combine with carryover from previous byte
   1125 
   1126  ora (BASE),y
   1127  eor imbyte
   1128 
   1129  ora #$80 ;set hibit
   1130  sta (BASE),y
   1131 
   1132 :92 LDA $FFFF,X ;CARRYn
   1133  STA CARRY ;Carry over to next byte
   1134 
   1135  INY
   1136  CPY VISWIDTH
   1137  BCC :inloop
   1138 
   1139 *  Extra byte on right (carryover)
   1140 
   1141  LDA OFFRIGHT
   1142  BNE :5 ;Rightmost byte is offscreen
   1143 
   1144 :4 lda CARRY ;0's in unused part of byte
   1145 
   1146  ora (BASE),y
   1147  eor carryim
   1148 
   1149  ora #$80
   1150  sta (BASE),y
   1151 
   1152 *  Next line up
   1153 
   1154 :5 LDA WIDTH
   1155  CLC
   1156  ADC IMAGE
   1157  STA IMAGE
   1158  BCC :6
   1159  INC IMAGE+1
   1160 
   1161 :6 DEC YCO
   1162  LDY YCO
   1163  CPY TOPEDGE
   1164  beq :done
   1165 
   1166  jmp :0
   1167 
   1168 *  Restore parameters
   1169 
   1170 :done jmp DONE
   1171 
   1172 *-------------------------------
   1173 *
   1174 *  M I R R O R    L A Y
   1175 *
   1176 *  Called by LAY
   1177 *
   1178 *  Specified starting byte (XCO, YCO) is image's bottom
   1179 *  right corner, not bottom left; bytes are read off image
   1180 *  table R-L, T-B and mirrored before printing.
   1181 *
   1182 *  In:  A = OPACITY, sans bit 7
   1183 *
   1184 *-------------------------------
   1185 
   1186 MLAY ;A = OPACITY
   1187  cmp #eor
   1188  bne :1
   1189  jmp MLayXOR
   1190 
   1191 :1 cmp #mask
   1192  bcc :2
   1193  jmp MLayMask
   1194 
   1195 :2 jmp MLayGen
   1196 
   1197 *-------------------------------
   1198 *
   1199 *  General (AND/OR/STORE)
   1200 *
   1201 *-------------------------------
   1202 MLayGen
   1203  JSR PREPREP
   1204 
   1205  LDA XCO
   1206  SEC
   1207  SBC WIDTH
   1208  STA XCO
   1209 
   1210  jsr CROP
   1211  bpl :cont
   1212  jmp DONE
   1213 :cont
   1214  lda BANK
   1215  sta :RAMRD1+1
   1216  sta :RAMRD2+1
   1217 
   1218  LDX OFFSET
   1219 
   1220  LDA SHIFTL,X
   1221  STA :91+1
   1222  LDA SHIFTH,X
   1223  STA :91+2
   1224 
   1225  LDA CARRYL,X
   1226  STA :90+1
   1227  STA :92+1
   1228  LDA CARRYH,X
   1229  STA :90+2
   1230  STA :92+2
   1231 
   1232  LDA AMASKS,X
   1233  STA AMASK
   1234  LDA BMASKS,X
   1235  STA BMASK
   1236 
   1237  LDX OPACITY
   1238  LDA OPCODE,X
   1239  STA :80
   1240  STA :81
   1241 
   1242 * Lay on
   1243 
   1244  LDY YCO
   1245 
   1246 :0 LDA YLO,Y
   1247  STA BASE
   1248 
   1249  LDA YHI,Y
   1250  CLC
   1251  ADC PAGE
   1252  STA BASE+1
   1253 
   1254  LDY OFFLEFT
   1255  BEQ :2
   1256 
   1257 * Take CARRY from off left edge
   1258 
   1259  LDY VISWIDTH
   1260 
   1261 :RAMRD1 sta $c003
   1262  lda (IMAGE),y
   1263  sta $c002
   1264 
   1265  TAX
   1266 
   1267  LDA MIRROR-$80,X
   1268  TAX
   1269 
   1270 :90 LDA $FFFF,X ;CARRYn
   1271  STA CARRY
   1272 
   1273 :1 DEY
   1274  BPL :3
   1275  BMI :4
   1276 
   1277 * Start a new line at left edge
   1278 
   1279 :2 LDY XCO
   1280  LDA (BASE),Y
   1281  AND AMASK
   1282  STA CARRY
   1283 
   1284  LDY WIDTH
   1285  DEY
   1286 
   1287 * Lay line down left-to-right fast as you can
   1288 
   1289 :3 STY YREG
   1290 
   1291 :RAMRD2 sta $c003
   1292  lda (IMAGE),y
   1293  sta $c002
   1294 
   1295  TAX
   1296 
   1297  LDA MIRROR-$80,X
   1298  TAX
   1299 
   1300 :91 LDA $FFFF,X ;SHIFTn
   1301  ORA CARRY ;Combine with carryover from previous byte
   1302 
   1303  LDY XCO
   1304 :80 STA (BASE),Y ;STA/ORA/AND/EOR depending on OPACITY
   1305  STA (BASE),Y
   1306 
   1307 :92 LDA $FFFF,X ;CARRYn
   1308  STA CARRY ;Carry over to next byte
   1309 
   1310  INC BASE
   1311 
   1312  LDY YREG
   1313  CPY RMOST
   1314  BEQ :7
   1315 
   1316  DEY
   1317  BPL :3
   1318 
   1319 *  Extra byte on right (carryover)
   1320 
   1321 :7 LDA OFFRIGHT
   1322  BNE :5 ;Rightmost byte is offscreen
   1323 
   1324 :4 LDY XCO
   1325  LDA (BASE),Y
   1326 
   1327  AND BMASK
   1328  ORA CARRY
   1329 :81 STA (BASE),Y
   1330  STA (BASE),Y
   1331 
   1332 *  Next line up
   1333 
   1334 :5 LDA WIDTH
   1335  CLC
   1336  ADC IMAGE
   1337  STA IMAGE
   1338  BCC :6
   1339  INC IMAGE+1
   1340 
   1341 :6 DEC YCO
   1342  LDY YCO
   1343  CPY TOPEDGE
   1344 
   1345  beq :done
   1346  jmp :0
   1347 
   1348 :done JMP DONE
   1349 
   1350 *-------------------------------
   1351 *
   1352 *  Mask, then OR
   1353 *
   1354 *-------------------------------
   1355 
   1356 MLayMask
   1357  ldx OPACITY ;4 = mask, 5 = visible mask
   1358  lda OPCODE,x ;4 = and, 5 = sta
   1359  sta :masksm1
   1360  sta :masksm2
   1361 
   1362  JSR PREPREP
   1363 
   1364  LDA XCO
   1365  SEC
   1366  SBC WIDTH
   1367  STA XCO
   1368 
   1369  jsr CROP
   1370  bpl :cont
   1371  jmp DONE
   1372 :cont
   1373  lda BANK
   1374  sta :RAMRD1+1
   1375  sta :RAMRD2+1
   1376 
   1377  LDX OFFSET
   1378 
   1379  LDA SHIFTL,X
   1380  STA :91+1
   1381  sta :93+1
   1382 
   1383  LDA SHIFTH,X
   1384  STA :91+2
   1385  sta :93+2
   1386 
   1387  LDA CARRYL,X
   1388  STA :90+1
   1389  STA :92+1
   1390  sta :94+1
   1391  sta :96+1
   1392 
   1393  LDA CARRYH,X
   1394  STA :90+2
   1395  STA :92+2
   1396  sta :94+2
   1397  sta :96+2
   1398 
   1399  LDA AMASKS,X
   1400  STA :AMASK+1
   1401  LDA BMASKS,X
   1402  STA :BMASK+1
   1403 
   1404 * Lay on
   1405 
   1406  LDY YCO
   1407 
   1408 :0 LDA YLO,Y
   1409  STA BASE
   1410 
   1411  LDA YHI,Y
   1412  CLC
   1413  ADC PAGE
   1414  STA BASE+1
   1415 
   1416  LDY OFFLEFT
   1417  BEQ :2
   1418 
   1419 * (a) Left edge offscreen
   1420 * Take CARRY from off left edge
   1421 
   1422  LDY VISWIDTH
   1423 
   1424 :RAMRD1 sta $c003
   1425  lda (IMAGE),y
   1426 ; eor #$ff ;TEMP
   1427 ; ora #$80 ;TEMP
   1428  sta $c002
   1429 
   1430  TAX
   1431  LDA MIRROR-$80,X
   1432  TAX
   1433 
   1434 :96 lda $FFFF,x ;CARRYn
   1435  sta carryim
   1436 
   1437  lda MASKTAB-$80,x
   1438  tax
   1439 :90 LDA $FFFF,X ;CARRYn
   1440  STA CARRY
   1441 
   1442 :1 DEY
   1443  BPL :3
   1444  BMI :4
   1445 
   1446 * (b) Left edge onscreen
   1447 * Start a new line at left edge
   1448 
   1449 :2 LDY XCO
   1450 :AMASK lda #0 ;AMASK
   1451  sta CARRY
   1452 
   1453  and (BASE),y
   1454  sta carryim
   1455 
   1456  LDY WIDTH
   1457  DEY
   1458 
   1459 * Lay line down left-to-right fast as you can
   1460 
   1461 :3 STY YREG
   1462 
   1463 :RAMRD2 sta $c003
   1464  lda (IMAGE),y
   1465 ; eor #$ff ;TEMP
   1466 ; ora #$80 ;TEMP
   1467  sta $c002
   1468 
   1469  TAX
   1470  LDA MIRROR-$80,X
   1471  TAX
   1472 
   1473 :93 lda $FFFF,x ;SHIFTn
   1474  ora carryim
   1475  sta imbyte
   1476 
   1477 :94 lda $FFFF,x ;CARRYn
   1478  sta carryim
   1479 
   1480  lda MASKTAB-$80,x
   1481  tax
   1482 
   1483 :91 LDA $FFFF,X ;SHIFTn
   1484  ORA CARRY ;Combine with carryover from previous byte
   1485 
   1486  LDY XCO
   1487 :masksm1 and (BASE),y
   1488  ora imbyte
   1489  STA (BASE),Y
   1490 
   1491 :92 LDA $FFFF,X ;CARRYn
   1492  STA CARRY ;Carry over to next byte
   1493 
   1494  INC BASE
   1495 
   1496  LDY YREG
   1497  CPY RMOST
   1498  BEQ :7
   1499 
   1500  DEY
   1501  BPL :3
   1502 
   1503 *  Extra byte on right (carryover)
   1504 
   1505 :7 LDA OFFRIGHT
   1506  BNE :5 ;Rightmost byte is offscreen
   1507 
   1508 :4 LDY XCO
   1509  LDA (BASE),Y
   1510 
   1511 :BMASK AND #0 ;BMASK
   1512  ORA CARRY
   1513 :masksm2 and (BASE),y
   1514  ora carryim
   1515  STA (BASE),Y
   1516 
   1517 *  Next line up
   1518 
   1519 :5 LDA WIDTH
   1520  CLC
   1521  ADC IMAGE
   1522  STA IMAGE
   1523  BCC :6
   1524  INC IMAGE+1
   1525 
   1526 :6 DEC YCO
   1527  LDY YCO
   1528  CPY TOPEDGE
   1529  beq :done
   1530 
   1531  jmp :0
   1532 
   1533 :done jmp DONE
   1534 
   1535 *-------------------------------
   1536 *
   1537 *  Special XOR
   1538 *
   1539 *-------------------------------
   1540 
   1541 MLayXOR
   1542  JSR PREPREP
   1543 
   1544  LDA XCO
   1545  SEC
   1546  SBC WIDTH
   1547  STA XCO
   1548 
   1549  jsr CROP
   1550  bpl :cont
   1551  jmp DONE
   1552 :cont
   1553  lda BANK
   1554  sta :RAMRD1+1
   1555  sta :RAMRD2+1
   1556 
   1557  LDX OFFSET
   1558 
   1559  LDA SHIFTL,X
   1560  STA :91+1
   1561  LDA SHIFTH,X
   1562  STA :91+2
   1563 
   1564  LDA CARRYL,X
   1565  STA :90+1
   1566  STA :92+1
   1567  LDA CARRYH,X
   1568  STA :90+2
   1569  STA :92+2
   1570 
   1571  jsr shiftoffset
   1572 
   1573  lda SHIFTL,x
   1574  sta :s1+1
   1575  lda SHIFTH,x
   1576  sta :s1+2
   1577 
   1578  lda CARRYL,x
   1579  sta :c1+1
   1580  sta :c2+1
   1581  lda CARRYH,x
   1582  sta :c1+2
   1583  sta :c2+2
   1584 
   1585  LDA AMASKS,X
   1586  STA :AMASK+1
   1587 
   1588 * Lay on
   1589 
   1590  LDY YCO
   1591 
   1592 :0 LDA YLO,Y
   1593  STA BASE
   1594 
   1595  LDA YHI,Y
   1596  CLC
   1597  ADC PAGE
   1598  STA BASE+1
   1599 
   1600  LDY OFFLEFT
   1601  BEQ :2
   1602 
   1603 * (a) Left edge offscreen
   1604 * Take CARRY from off left edge
   1605 
   1606  LDY VISWIDTH
   1607 
   1608 :RAMRD1 sta $c003
   1609  lda (IMAGE),y
   1610  sta $c002
   1611 
   1612  TAX
   1613  LDA MIRROR-$80,X
   1614  TAX
   1615 
   1616 :c2 lda $FFFF,x ;CARRYn+1
   1617  sta carryim
   1618 
   1619 :90 LDA $FFFF,X ;CARRYn
   1620  STA CARRY
   1621 
   1622 :1 DEY
   1623  BPL :3
   1624  BMI :4
   1625 
   1626 * (b) Left edge onscreen
   1627 * Start a new line at left edge
   1628 
   1629 :2 ldy XCO
   1630 :AMASK lda #0 ;AMASK
   1631  and (BASE),y
   1632  sta CARRY
   1633 
   1634  lda #0
   1635  sta carryim
   1636 
   1637  LDY WIDTH
   1638  DEY
   1639 
   1640 * Lay line down left-to-right fast as you can
   1641 
   1642 :3 STY YREG
   1643 
   1644 :RAMRD2 sta $c003
   1645  lda (IMAGE),y
   1646  sta $c002
   1647 
   1648  TAX
   1649 
   1650  LDA MIRROR-$80,X
   1651  TAX
   1652 
   1653 :s1 lda $FFFF,x ;SHIFTn
   1654  ora carryim
   1655  sta imbyte
   1656 
   1657 :c1 lda $FFFF,x ;CARRYn
   1658  sta carryim
   1659 
   1660 :91 LDA $FFFF,X ;SHIFTn
   1661  ORA CARRY ;Combine with carryover from previous byte
   1662 
   1663  LDY XCO
   1664 
   1665  ora (BASE),y
   1666  eor imbyte
   1667 
   1668  ora #$80
   1669  sta (BASE),Y
   1670 
   1671 :92 LDA $FFFF,X ;CARRYn
   1672  STA CARRY ;Carry over to next byte
   1673 
   1674  INC BASE
   1675 
   1676  LDY YREG
   1677  CPY RMOST
   1678  BEQ :7
   1679 
   1680  DEY
   1681  BPL :3
   1682 
   1683 *  Extra byte on right (carryover)
   1684 
   1685 :7 LDA OFFRIGHT
   1686  BNE :5 ;Rightmost byte is offscreen
   1687 
   1688 :4 LDY XCO
   1689 
   1690  lda CARRY
   1691 
   1692  ora (BASE),Y
   1693  eor carryim
   1694 
   1695  ora #$80
   1696  STA (BASE),Y
   1697 
   1698 *  Next line up
   1699 
   1700 :5 LDA WIDTH
   1701  CLC
   1702  ADC IMAGE
   1703  STA IMAGE
   1704  BCC :6
   1705  INC IMAGE+1
   1706 
   1707 :6 DEC YCO
   1708  LDY YCO
   1709  CPY TOPEDGE
   1710  beq :done
   1711 
   1712  jmp :0
   1713 
   1714 :done JMP DONE
   1715 
   1716 *-------------------------------
   1717 *
   1718 * Peel
   1719 *
   1720 *-------------------------------
   1721 PEEL
   1722  sta $c004
   1723 ]ramrd1 sta $c003
   1724 
   1725  jmp fastlaySTA
   1726 
   1727 *-------------------------------
   1728 *
   1729 *  F A S T L A Y
   1730 *
   1731 *  Streamlined LAY routine
   1732 *
   1733 *  No offset - no clipping - no mirroring - no masking -
   1734 *  no EOR - trashes IMAGE - may crash if overtaxed -
   1735 *  but it's fast.
   1736 *
   1737 *  10/3/88: OK for images to protrude PARTLY off top
   1738 *
   1739 *-------------------------------
   1740 FASTLAY
   1741  sta $c004 ;RAMWRT main
   1742 ]ramrd2 sta $c003 ;RAMRD aux
   1743 
   1744  jsr setimage
   1745 
   1746  ldx OPACITY ;hi bit off!
   1747  cpx #sta
   1748  beq fastlaySTA
   1749 
   1750  lda OPCODE,x
   1751  sta  :smod
   1752 
   1753  lda PAGE
   1754  sta :smPAGE+1
   1755 
   1756  lda XCO
   1757  sta  :smXCO+1
   1758 
   1759  ldy #0
   1760  lda (IMAGE),y
   1761  sta :smWIDTH+1
   1762 
   1763  sec
   1764  sbc #1
   1765  sta :smSTART+1
   1766 
   1767  lda YCO
   1768  tax
   1769  iny
   1770  sbc (IMAGE),y
   1771  bcs :ok
   1772  lda #-1 ;limited Y-clipping
   1773 :ok sta  :smTOP+1
   1774 
   1775  lda IMAGE
   1776  clc
   1777  adc #2
   1778  sta IMAGE
   1779  bcc :1
   1780  inc IMAGE+1
   1781 :1
   1782 
   1783 :outloop
   1784  lda YLO,x
   1785  clc
   1786 :smXCO adc #0
   1787  sta BASE
   1788 
   1789  lda YHI,x
   1790 :smPAGE adc #$20
   1791  sta BASE+1
   1792 
   1793 :smSTART ldy #3
   1794 
   1795 :inloop
   1796 ]ramrd3 sta $c003 ;RAMRD aux
   1797 
   1798  lda (IMAGE),y
   1799 
   1800  sta $c002 ;RAMRD main
   1801 
   1802 :smod ora (BASE),y
   1803  sta (BASE),y
   1804 
   1805  dey
   1806  bpl :inloop
   1807 
   1808 :smWIDTH lda #4
   1809  adc IMAGE ;assume cc
   1810  sta IMAGE
   1811  bcc :2
   1812  inc IMAGE+1
   1813 :2
   1814  dex
   1815 :smTOP cpx #$ff
   1816  bne :outloop
   1817 
   1818  rts
   1819 
   1820 *-------------------------------
   1821 *
   1822 *  Still more streamlined version of FASTLAY (STA only)
   1823 *
   1824 *-------------------------------
   1825 fastlaySTA
   1826  lda PAGE
   1827  sta :smPAGE+1
   1828 
   1829  lda XCO
   1830  sta  :smXCO+1
   1831 
   1832  ldy #0
   1833  lda (IMAGE),y
   1834  sta :smWIDTH+1
   1835 
   1836  sec
   1837  sbc #1
   1838  sta :smSTART+1
   1839 
   1840  lda YCO
   1841  tax
   1842  iny
   1843  sbc (IMAGE),y
   1844  bcs :ok
   1845  lda #-1 ;limited Y-clipping
   1846 :ok sta  :smTOP+1
   1847 
   1848  lda IMAGE
   1849  clc
   1850  adc #2
   1851  sta IMAGE
   1852  bcc :1
   1853  inc IMAGE+1
   1854 :1
   1855 
   1856 :outloop
   1857  lda YLO,x
   1858  clc
   1859 :smXCO adc #0
   1860  sta :smod+1
   1861 
   1862  lda YHI,x
   1863 :smPAGE adc #$20
   1864  sta :smod+2
   1865 
   1866 :smSTART ldy #3
   1867 
   1868 :inloop
   1869  lda (IMAGE),y
   1870 :smod sta $2000,y ;BASE
   1871 
   1872  dey
   1873  bpl :inloop
   1874 
   1875 :smWIDTH lda #4
   1876  adc IMAGE ;cc
   1877  sta IMAGE
   1878  bcc :2
   1879  inc IMAGE+1
   1880 :2
   1881  dex
   1882 :smTOP cpx #$ff
   1883  bne :outloop
   1884 
   1885  rts
   1886 
   1887 *-------------------------------
   1888 *
   1889 *  F A S T M A S K
   1890 *
   1891 *-------------------------------
   1892 FASTMASK
   1893  sta $c004 ;RAMWRT main
   1894 ]ramrd4 sta $c003 ;RAMRD aux
   1895 
   1896  jsr setimage
   1897 
   1898  lda PAGE
   1899  sta :smPAGE+1
   1900 
   1901  lda XCO
   1902  sta  :smXCO+1
   1903 
   1904  ldy #0
   1905  lda (IMAGE),y
   1906  sta :smWIDTH+1
   1907 
   1908  sec
   1909  sbc #1
   1910  sta :smSTART+1
   1911 
   1912  lda YCO
   1913  tax
   1914  iny
   1915  sbc (IMAGE),y
   1916  bcs :ok
   1917  lda #-1 ;limited Y-clipping
   1918 :ok sta  :smTOP+1
   1919 
   1920  lda IMAGE
   1921  clc
   1922  adc #2
   1923  sta IMAGE
   1924  bcc :1
   1925  inc IMAGE+1
   1926 :1
   1927 
   1928 :outloop
   1929  stx index
   1930 
   1931  lda YLO,x
   1932  clc
   1933 :smXCO adc #0
   1934  sta BASE
   1935 
   1936  lda YHI,x
   1937 :smPAGE adc #$20
   1938  sta BASE+1
   1939 
   1940 :smSTART ldy #3
   1941 
   1942 :inloop
   1943 ]ramrd5 sta $c003 ;RAMRD aux
   1944 
   1945  lda (IMAGE),y
   1946 
   1947  sta $c002 ;RAMRD main
   1948 
   1949  tax
   1950  lda MASKTAB-$80,X
   1951 
   1952  and (BASE),Y
   1953  sta (BASE),y
   1954 
   1955  dey
   1956  bpl :inloop
   1957 
   1958 :smWIDTH lda #4
   1959  adc IMAGE ;cc
   1960  sta IMAGE
   1961  bcc :2
   1962  inc IMAGE+1
   1963 :2
   1964  ldx index
   1965  dex
   1966 :smTOP cpx #$ff
   1967  bne :outloop
   1968 
   1969  rts
   1970 
   1971 *-------------------------------
   1972 *
   1973 *  S E T F A S T   M A I N / A U X
   1974 *
   1975 *  Modify FASTLAY routines to expect image tables to
   1976 *  be in main/auxmem.  SETFAST need be called only once
   1977 *  (e.g., when switching between game & builder).
   1978 *
   1979 *-------------------------------
   1980 SETFASTMAIN
   1981  lda #$02 ;RAMRD main
   1982 ]setfast
   1983  sta ]ramrd1+1
   1984  sta ]ramrd2+1
   1985  sta ]ramrd3+1
   1986  sta ]ramrd4+1
   1987  sta ]ramrd5+1
   1988  rts
   1989 
   1990 SETFASTAUX
   1991  lda #$03 ;RAMRD aux
   1992  bne ]setfast
   1993 
   1994 *-------------------------------
   1995 *
   1996 *  F A S T B L A C K
   1997 *
   1998 *  Wipe a rectangular area to black2
   1999 *
   2000 *  Width/height passed in IMAGE/IMAGE+1
   2001 *  (width in bytes, height in pixels)
   2002 *
   2003 *-------------------------------
   2004 
   2005 FASTBLACK
   2006  lda color
   2007  sta :smCOLOR+1
   2008 
   2009  lda PAGE
   2010  sta :smPAGE+1
   2011 
   2012  lda XCO
   2013  sta  :smXCO+1
   2014 
   2015  lda width
   2016  sec
   2017  sbc #1
   2018  sta :smSTART+1
   2019 
   2020  lda YCO
   2021  tax
   2022  sbc height ;cs
   2023  sta :smTOP+1
   2024 
   2025 :outloop
   2026  lda YLO,x
   2027  clc
   2028 :smXCO adc #0
   2029  sta :smod+1
   2030 
   2031  lda YHI,x
   2032 :smPAGE adc #$20
   2033  sta :smod+2
   2034 
   2035 :smCOLOR lda #$80
   2036 
   2037 :smSTART ldy #3
   2038 
   2039 :inloop
   2040 :smod sta $2000,y ;BASE
   2041  dey
   2042  bpl :inloop
   2043 
   2044  dex
   2045 :smTOP cpx #$ff
   2046  bne :outloop
   2047 
   2048  rts
   2049 
   2050 *-------------------------------
   2051 *
   2052 *  C O P Y   S C R E E N
   2053 *
   2054 *  Copy $2000 bytes
   2055 *
   2056 *  In: IMAGE+1 = dest scrn, IMAGE = org scrn
   2057 *      (use hi byte of actual memory address)
   2058 *
   2059 *-------------------------------
   2060 COPYSCRN
   2061  lda IMAGE+1
   2062  sta :dst1+2
   2063  clc
   2064  adc #$10
   2065  sta :dst2+2
   2066 
   2067  lda IMAGE
   2068  sta :org1+2
   2069  adc #$10
   2070  sta :org2+2
   2071 
   2072  ldx #$10
   2073 
   2074  ldy #0
   2075 :loop
   2076 :org1 lda $2000,y
   2077 :dst1 sta $4000,y
   2078 
   2079 :org2 lda $3000,y
   2080 :dst2 sta $5000,y
   2081 
   2082  iny
   2083  bne :loop
   2084 
   2085  inc :org1+2
   2086  inc :org2+2
   2087  inc :dst1+2
   2088  inc :dst2+2
   2089 
   2090  dex
   2091  bne :loop
   2092 
   2093  rts
   2094 
   2095 *-------------------------------
   2096 * Invert Y-tables
   2097 *-------------------------------
   2098 INVERTY
   2099  ldx #191 ;low line
   2100  ldy #0 ;high line
   2101 
   2102 * Switch low & high lines
   2103 
   2104 :loop lda YLO,x
   2105  pha
   2106  lda YLO,y
   2107  sta YLO,x
   2108  pla
   2109  sta YLO,y
   2110 
   2111  lda YHI,x
   2112  pha
   2113  lda YHI,y
   2114  sta YHI,x
   2115  pla
   2116  sta YHI,y
   2117 
   2118 * Move 1 line closer to ctr
   2119 
   2120  dex
   2121  iny
   2122  cpy #96
   2123  bcc :loop
   2124 ]rts rts
   2125 
   2126 *-------------------------------
   2127  lst
   2128  ds 1
   2129  usr $a9,1,$0000,*-org
   2130  lst off