* DEMONSTRATE 12 SOFTWARE SPRITES
* HEIGHT=6 PIXELS, WIDTH=8 PIXELS

* SOFTWARE SPRITES, HIGH RESOLUTION!
* DONE BY FRANKENSTEIN

* ENGLISH COMMENTS VERSION OF
* SOFSHOW4.SRC FOR NIR DARY

          ORG $A800

FONT      EQU $E000

SINUS     EQU $0600
SINLEN    EQU $5A

SCRMEM    EQU $B000

LOTAB     EQU $6000
HITAB     EQU LOTAB+$100

* 8 SHIFT MASKS FOR EACH SPRITE!!
SPRITE0   EQU 0
SPRITE1   EQU AM
SPRITE2   EQU SPRITE1+AM
SPRITE3   EQU SPRITE2+AM
SPRITE4   EQU SPRITE3+AM
SPRITE5   EQU SPRITE4+AM
SPRITE6   EQU SPRITE5+AM
SPRITE7   EQU SPRITE6+AM

* CONST.
WD        EQU 2               ;WIDTH
HG        EQU 6               ;HEIGHT
AM        EQU WD*HG ;WD*HG
WS        EQU 32              ;W.SCREEN
TS        EQU 12              ;TOT.SPRTS
SH        EQU AM*8            ;SHIFT BUF

SH0       EQU $2000
SH1       EQU SH0+SH
SH2       EQU SH1+SH
SH3       EQU SH2+SH
SH4       EQU SH3+SH
SH5       EQU SH4+SH
SH6       EQU SH5+SH
SH7       EQU SH6+SH
SH8       EQU SH7+SH
SH9       EQU SH8+SH
SHA       EQU SH9+SH
SHB       EQU SHA+SH

BUFADR0   EQU SHB+SH
BUFADR1   EQU BUFADR0+AM
BUFADR2   EQU BUFADR1+AM
BUFADR3   EQU BUFADR2+AM
BUFADR4   EQU BUFADR3+AM
BUFADR5   EQU BUFADR4+AM
BUFADR6   EQU BUFADR5+AM
BUFADR7   EQU BUFADR6+AM
BUFADR8   EQU BUFADR7+AM
BUFADR9   EQU BUFADR8+AM
BUFADRA   EQU BUFADR9+AM
BUFADRB   EQU BUFADRA+AM

* VAR. ZERO PAGE
SCREEN    EQU $F4             (AND $F5)
BUFFER    EQU $F6             (AND $F7)

COUNT     EQU $F8
DUMMY     EQU $F9
SPNR      EQU $FA

* MAKE SCANLINE ADR. TAB.

          JSR SCANTAB

* MAKE 8 SHIFTED SHAPES

          JSR MAKE

* THE FIRST STORE IS VERY USEFULL!

          JSR STORE

* INIT. SCREEN DISPLAY

          LDA #33
          STA 559

          LDA #0
          STA 710

          LDA #DL:L
          STA $230
          LDA #DL:H
          STA $231

          LDA #1
          STA $220
WAIT      LDA $220
          BNE WAIT

          LDA #0
          STA $D20E
          STA $D40E

LOOP      LDA $D40B
          CMP #70
          BNE LOOP

*         LDA #14
*         STA $D01A

* THE MAIN SOFTY SPRITE ROUTINE!

          JSR RESTORE
          JSR NEWXY
          JSR STORE
          JSR PUT

*         LDA #0
*         STA $D01A
          JMP LOOP

* CALCULATE ALL NEW X AND Y POSITIONS
* AND STORE THEM!

NEWXY     LDX #0              ;SPNR

NOGMAL    DEC XPVEC,X
          LDA XPVEC,X
          CMP #255
          BNE DEZENOT
          LDA #SINLEN-1
          STA XPVEC,X
DEZENOT   TAY
          LDA SINUS,Y
          CLC
          ADC #60
          STA XPTAB,X

          INC YPVEC,X
          LDA YPVEC,X
          CMP #SINLEN
          BNE NEWELJU
          LDA #0
          STA YPVEC,X

NEWELJU   TAY
          LDA SINUS,Y
          LSR
          STA YPTAB,X
          INX
          CPX #TS             ;NR.OF
          BNE NOGMAL          ;SPRITES

          RTS

* CREATE A TABLE WITH ALL BEGIN
* ADDRESSES FROM ALL THE SCANLINES

SCANTAB   LDX #0              ;LINE 0

          LDA #SCRMEM:L
          STA BUFFER
          LDA #SCRMEM:H
          STA BUFFER+1

NO256     LDA BUFFER
          STA LOTAB,X
          LDA BUFFER+1
          STA HITAB,X

          LDA BUFFER
          CLC
          ADC #WS
          STA BUFFER
          LDA BUFFER+1
          ADC #0
          STA BUFFER+1

          INX
          BNE NO256

          RTS

* ALL SCREENS TO THE BUFFER PLEASE!

STORE     LDA #0
          STA SPNR

ALLES1    JSR SCTOBUF

          INC SPNR
          LDA SPNR
          CMP #TS             ;NR.OF
          BNE ALLES1          ;SPRITES

          RTS

* ALL BUFFERS TO THE SCREEN PLEASE!

RESTORE   LDA #0
          STA SPNR

ALLES2    JSR BUFTOSC

          INC SPNR
          LDA SPNR
          CMP #TS             ;NR.OF
          BNE ALLES2          ;SPRITES

          RTS

* ALL SPRITES TO THE SCREEN PLEASE!

PUT       LDA #0
          STA SPNR

ALLES3    JSR PLOTIT

          INC SPNR
          LDA SPNR
          CMP #TS             ;NR.OF
          BNE ALLES3          ;SPRITES

          RTS

* THIS ROUTINE FILLS THE BUFFER OF
* SPNR (WITH HELP OF THE X AND Y
* POSITIONS OF SPRITE SPNR) WITH
* THE RIGHT PIECE OF SCREEN!
* IT SAVES THE SCREEN ADDRESSES
* WHERE THE DATA CAME FROM IN OLDTAB!

SCTOBUF   LDA SPNR
          TAX
          TAY

          LDA BUFTABL,X
          STA BUFFER
          LDA BUFTABH,X
          STA BUFFER+1

          LDA XPTAB,X         ;X POS.
          LSR
          LSR
          LSR
          STA XPLUS+1

          LDA YPTAB,X         ;Y POS.
          TAX
          LDA LOTAB,X         ;Y ADR.LO
          CLC
XPLUS     ADC #0              ;+(X/8)
          STA SCREEN
          STA OLDTABL,Y
          LDA HITAB,X         ;Y ADR.HI
          ADC #0
          STA SCREEN+1
          STA OLDTABH,Y

          LDX #0

NEXLIN    LDY #0

BREDER    LDA (SCREEN),Y
          STA (BUFFER),Y
          INY
          CPY #WD             ;WIDTH OF
          BNE BREDER          ;SPRITE

          LDA BUFFER
          CLC
          ADC #WD             ;WIDTH OF
          STA BUFFER          ;SPRITE
          LDA BUFFER+1
          ADC #0
          STA BUFFER+1

          LDA SCREEN
          CLC
          ADC #WS             ;WIDTH OF
          STA SCREEN          ;SCREEN
          LDA SCREEN+1
          ADC #0
          STA SCREEN+1

          INX
          CPX #HG             ;HEIGHT OF
          BNE NEXLIN          ;SPRITE

          RTS

* THIS ROUTINE RESTORES THE SCREEN
* WITH HELP OF THE SAVED ADDRESSES
* AND THE DATA IN THE BUFFERS!

BUFTOSC   LDA SPNR
          TAX

          LDA BUFTABL,X
          STA BUFFER
          LDA BUFTABH,X
          STA BUFFER+1

          LDA OLDTABL,X
          STA SCREEN
          LDA OLDTABH,X
          STA SCREEN+1

          LDX #0

NEXLIN2   LDY #0

BREDER2   LDA (BUFFER),Y
          STA (SCREEN),Y
          INY
          CPY #WD             ;WIDTH
          BNE BREDER2         ;SPRITE

          LDA BUFFER
          CLC
          ADC #WD             ;WIDTH
          STA BUFFER          ;SPRITE
          LDA BUFFER+1
          ADC #0
          STA BUFFER+1

          LDA SCREEN
          CLC
          ADC #WS             ;WIDTH
          STA SCREEN          ;SCREEN
          LDA SCREEN+1
          ADC #0
          STA SCREEN+1

          INX
          CPX #HG             ;HEIGHT
          BNE NEXLIN2         ;SPRITE

          RTS

* THE FOLLOWING ROUTINE USES THE
* ADDRESSES FROM OLDTAB TO PUT
* THERE THE REST OF X/8 SPRITES!

PLOTIT    LDA SPNR
          TAX
          LDA OLDTABL,X
          STA SCREEN
          LDA OLDTABH,X
          STA SCREEN+1

          LDA XPTAB,X         ;X POS.
          AND #%00000111
          TAY
          LDA SHFTABL,X       ;LO SPRITE
          CLC
          ADC SPRTAB,Y
          STA BUFFER
          LDA SHFTABH,X       ;HI SPRITE
          ADC #0
          STA BUFFER+1

          LDX #0

NEXLIN3   LDY #0

BREDER3   LDA (BUFFER),Y
          ORA (SCREEN),Y
          STA (SCREEN),Y
          INY
          CPY #WD             ;WIDTH
          BNE BREDER3         ;SPRITE

          LDA BUFFER
          CLC
          ADC #WD             ;WIDTH
          STA BUFFER          ;SPRITE
          LDA BUFFER+1
          ADC #0
          STA BUFFER+1

          LDA SCREEN
          CLC
          ADC #WS             ;WIDTH
          STA SCREEN          ;SCREEN
          LDA SCREEN+1
          ADC #0
          STA SCREEN+1

          INX
          CPX #HG             ;HEIGHT
          BNE NEXLIN3         ;SPRITE

          RTS

* POINTER TABLES

SHFTABL   DFB SH0:L
          DFB SH1:L
          DFB SH2:L
          DFB SH3:L
          DFB SH4:L
          DFB SH5:L
          DFB SH6:L
          DFB SH7:L
          DFB SH8:L
          DFB SH9:L
          DFB SHA:L
          DFB SHB:L

SHFTABH   DFB SH0:H
          DFB SH1:H
          DFB SH2:H
          DFB SH3:H
          DFB SH4:H
          DFB SH5:H
          DFB SH6:H
          DFB SH7:H
          DFB SH8:H
          DFB SH9:H
          DFB SHA:H
          DFB SHB:H

* LO POINTER TABLE FOR 8 SHIFTS!

SPRTAB    DFB SPRITE0:L
          DFB SPRITE1:L
          DFB SPRITE2:L
          DFB SPRITE3:L
          DFB SPRITE4:L
          DFB SPRITE5:L
          DFB SPRITE6:L
          DFB SPRITE7:L

* BUFFER ADDRESS TABLES

BUFTABL   DFB BUFADR0:L
          DFB BUFADR1:L
          DFB BUFADR2:L
          DFB BUFADR3:L
          DFB BUFADR4:L
          DFB BUFADR5:L
          DFB BUFADR6:L
          DFB BUFADR7:L
          DFB BUFADR8:L
          DFB BUFADR9:L
          DFB BUFADRA:L
          DFB BUFADRB:L

BUFTABH   DFB BUFADR0:H
          DFB BUFADR1:H
          DFB BUFADR2:H
          DFB BUFADR3:H
          DFB BUFADR4:H
          DFB BUFADR5:H
          DFB BUFADR6:H
          DFB BUFADR7:H
          DFB BUFADR8:H
          DFB BUFADR9:H
          DFB BUFADRA:H
          DFB BUFADRB:H

* OLD SCREEN ADDRESS TABLES

OLDTABL   DFB 0,0,0,0,0,0,0,0,0,0,0,0
OLDTABH   DFB 0,0,0,0,0,0,0,0,0,0,0,0

* THE NEW X POSITIONS!
XPVEC     DFB 0,5,10,15
          DFB 20,25,30,35
          DFB 40,45,50,55

XPTAB     DFB 0,5,10,15,20,25,30,35
          DFB 40,45,50,55

* THE NEW Y POSITIONS!
YPTAB     DFB 0,0,0,0,0,0,0,0
          DFB 0,0,0,0

YPVEC     DFB 0,5,10,15
          DFB 20,25,30,35
          DFB 40,45,50,55

* DISPLAY LIST!
DL        DFB 112,112,112,112
          DFB 112,112,112,0,0
          DFB $4F
          DFW SCRMEM
          DFB 15,15,15,15,15,15,15
          DFB 15,15,15,15,15,15,15,15
          DFB 15,15,15,15,15,15,15,15
          DFB 15,15,15,15,15,15,15,15
          DFB 15,15,15,15,15,15,15,15
          DFB 15,15,15,15,15,15,15,15
          DFB 15,15,15,15,15,15,15,15
          DFB 15,15,15,15,15,15,15,15
          DFB 15,15,15,15,15,15,15,15
*         DFB 15,15,15,15,15,15,15,15
*         DFB 15,15,15,15,15,15,15,15
*         DFB 15,15,15,15,15,15,15,15
*         DFB 15,15,15,15,15,15,15,15
*         DFB 15,15,15,15,15,15,15,15
*         DFB 15,15,15,15,15,15,15,15
*         DFB 15,15,15,15,15,15,15,15
          DFB $41
          DFW DL

* CREATE FOR EACH SPRITE A BUFFER
* WHICH CONTAINS 8 SHIFTS OF THAT
* SPRITE!

MAKE      LDA #0
          STA SPNR

ALETRS    TAX
          LDA SHFTABL,X
          STA BUFFER
          STA SCREEN
          LDA SHFTABH,X
          STA BUFFER+1
          STA SCREEN+1

          LDA DEMO,X

* CALCULATE THE ADDRESS OF THE BIT
* IMAGE FROM A CERTAIN CHARACTER

CALCFNT   PHA
          CLC
          ASL
          ASL
          ASL
          STA BYTE+1
          PLA
          AND #%11100000
          LSR
          LSR
          LSR
          LSR
          LSR
          ADC #FONT/256
          STA BYTE+2

          LDY #0
          LDX #1

BYTE      LDA $FFFF,X
          STA (BUFFER),Y
          INY
          LDA #0              ;CLEAR
          STA (BUFFER),Y
          INY
          INX
          CPX #7
          BNE BYTE

* CREATE 8 IMAGES FROM A SPRITE
* BY SHIFTING IT 1 PIXEL TO THE
* RIGHT!

          LDA #0
          STA COUNT

* TARGET IS ALWAYS 1*AM AHEAD!

          LDA SCREEN
          CLC
          ADC #AM
          STA BUFFER
          LDA SCREEN+1
          ADC #0
          STA BUFFER+1

NXSHFT    LDX #0

NXLINE    LDY #0
          STY DUMMY

NXBYTE    CLC
          LDA (SCREEN),Y
          ROR
          ORA DUMMY
          STA (BUFFER),Y
          ROR DUMMY
          INY
          CPY #WD
          BNE NXBYTE

          LDA SCREEN
          CLC
          ADC #WD
          STA SCREEN
          LDA SCREEN+1
          ADC #0
          STA SCREEN+1

          LDA BUFFER
          CLC
          ADC #WD
          STA BUFFER
          LDA BUFFER+1
          ADC #0
          STA BUFFER+1

          INX
          CPX #HG
          BNE NXLINE

          INC COUNT
          LDA COUNT
          CMP #7
          BNE NXSHFT

          INC SPNR
          LDA SPNR
          CMP #TS
          BEQ BRAAF
          JMP ALETRS

BRAAF     RTS

* 12 CHARACTERS!
DEMO      ASC %FRANKENSTEIN"

* CHARACTER COUNTER!
LETCNT    DFB 0

