rain/RAIN.s

780 lines
19 KiB
ArmAsm

DSK RAIN
**************************************************
* A simple simulation of random raindrops falling,
* hitting a puddle and splashing. Use K and I
* to increase/decrease the amount of falling rain.
**************************************************
* Variables
**************************************************
ROW EQU $FA ; row/col in text screen
COLUMN EQU $FB
CHAR EQU $FC ; char/pixel to plot
PROGRESS EQU $FD ; write to main or alt
PLOTROW EQU $FE ; row/col in text page
PLOTCOLUMN EQU $FF
RNDSEED EQU $EA ; +eb +ec
UPPERLIMIT EQU $ED ; threshold for random raindrops
**************************************************
* Apple Standard Memory Locations
**************************************************
CLRLORES EQU $F832
LORES EQU $C050
TXTSET EQU $C051
MIXCLR EQU $C052
MIXSET EQU $C053
TXTPAGE1 EQU $C054
TXTPAGE2 EQU $C055
KEY EQU $C000
C80STOREOFF EQU $C000
C80STOREON EQU $C001
STROBE EQU $C010
SPEAKER EQU $C030
VBL EQU $C02E
RDVBLBAR EQU $C019 ;not VBL (VBL signal low
WAIT EQU $FCA8
RAMWRTAUX EQU $C005
RAMWRTMAIN EQU $C004
SETAN3 EQU $C05E ;Set annunciator-3 output to 0
SET80VID EQU $C00D ;enable 80-column display mode (WR-only)
HOME EQU $FC58 ; clear the text screen
CH EQU $24 ; cursor Horiz
CV EQU $25 ; cursor Vert
VTAB EQU $FC22 ; Sets the cursor vertical position (from CV)
COUT EQU $FDED ; Calls the output routine whose address is stored in CSW,
; normally COUTI
STROUT EQU $DB3A ;Y=String ptr high, A=String ptr low
ALTTEXT EQU $C055
ALTTEXTOFF EQU $C054
ROMINIT EQU $FB2F
ROMSETKBD EQU $FE89
ROMSETVID EQU $FE93
ALTCHAR EQU $C00F ; enables alternative character set - mousetext
BLINK EQU $F3
SPEED EQU $F1
**************************************************
* START - sets up various fiddly zero page bits
**************************************************
ORG $2000 ; PROGRAM DATA STARTS AT $2000
JSR ROMSETVID ;Init char output hook at $36/$37
JSR ROMSETKBD ;Init key input hook at $38/$39
JSR ROMINIT ;GR/HGR off, Text page 1
LDA #$01
STA SPEED ; string/char output speed
STA ALTCHAR ; enable mousetext
STA PROGRESS ; which page do we write to
LDA #$00
STA BLINK ; blinking text? no thanks.
STA LORES ; low res graphics mode
JSR CLRLORES ; clear screen
DRAWBOARD JSR HOME
STA ALTTEXTOFF ; display main text page
JSR RNDINIT ; *should* cycle the random seed.
INC PROGRESS
LDA #$F7
STA UPPERLIMIT
**************************************************
* blanks the screen, sets the "puddle" to dk blue
**************************************************
; FOR EACH ROW/COLUMN
LDA #$18 ; X = 24
STA PLOTROW
ROWLOOP2 ; (ROW 20 to 0)
DEC PLOTROW
; start columnloop (COLUMN 0 to 40)
LDA #$28
STA PLOTCOLUMN
COLUMNLOOP2 DEC PLOTCOLUMN
LDA PLOTROW ; last 4 lines, #$22
CMP #$14 ; > 20
BCC PLOTZERO
LDA #$22 ; last 4 lines, #$22
JMP PLOTLINE
PLOTZERO LDA #$0 ; set all pixels to 00
PLOTLINE STA CHAR
JSR PLOTCHAR ; plot 00
INC PROGRESS
JSR PLOTCHAR ; plot 00 to alt
INC PROGRESS
LDA PLOTCOLUMN ; last COLUMN?
BNE COLUMNLOOP2 ; loop
; /columnloop2
LDA PLOTROW ; last ROW?
BNE ROWLOOP2 ; loop
; /rowloop2
; draw raindrop
; DK blue = 2
; MD blue = 6
; LT blue = 7
; white = F
; black = 0
; grey = 5
; drop:
; == F7 76 02
; fast drop:
; == 27 60 20
; F7 -> 76 -> 02
; 27 -> 60 -> 20
**************************************************
* MAIN LOOP
* waits for keyboard input, moves cursor, etc
**************************************************
MAIN
MAINLOOP LDA KEY ; check for keydown
; CMP #$A0 ; space bar pause?
; BEQ GOTSPACE
CMP #$D2 ; R
BEQ GOTRESET
CMP #$9B ; ESC
BEQ END ; exit on ESC?
CMP #$C9 ; I
BEQ GOTUP
CMP #$CB ; K
BEQ GOTDOWN
; CMP #$CA ; J shift the falling drops left/right to
; BEQ GOTLEFT ; simulate wind?
; CMP #$CC ; L
; BEQ GOTRIGHT
JSR NEXTSCREEN ; animate one frame per loop
BNE MAINLOOP ; loop until a key
GOTUP STA STROBE
DEC UPPERLIMIT
JMP MAINLOOP ; back to waiting for a key
GOTDOWN STA STROBE
INC UPPERLIMIT
JMP MAINLOOP ; back to waiting for a key
;GOTLEFT STA STROBE
; STA ALTTEXTOFF
; JMP MAINLOOP ; back to waiting for a key
;
;GOTRIGHT STA STROBE
; STA ALTTEXT
; JMP MAINLOOP ; back to waiting for a key
;
;GOTSPACE JSR SPACE
; JMP MAINLOOP ; back to waiting for a key
GOTRESET STA STROBE
STA ALTTEXTOFF
JMP DRAWBOARD
END STA STROBE
STA ALTTEXTOFF
STA TXTSET
JSR HOME
RTS ; END
;SPACE STA STROBE ;
; JSR NEXTSCREEN ; animate
; RTS
;/GOTSPACE
**************************************************
* subroutines
*
**************************************************
**************************************************
* main animation loop - checks each pixel for non-zero values
**************************************************
NEXTSCREEN ; FOR EACH ROW/COLUMN
LDA #$14 ; X = 20
STA PLOTROW
ROWLOOP ; (ROW 20 to 0)
DEC PLOTROW
; start columnloop (COLUMN 0 to 40)
LDA #$28
STA PLOTCOLUMN
COLUMNLOOP DEC PLOTCOLUMN
JSR GETCHAR
BEQ ZEROFOUND
JSR EXPAND ; do the thing
ZEROFOUND LDA PLOTCOLUMN ; last COLUMN?
BNE COLUMNLOOP ; loop
;/columnloop
LDA PLOTROW ; last ROW?
BEQ ROWONE ; top of the screen, do some random raindrops
BNE ROWLOOP ; loop
;/rowloop
ROWONE ; row == 0, if RND > upperlimit, draw start of a new drop
LDA #$28
STA PLOTCOLUMN
COLUMNLOOP3 DEC PLOTCOLUMN ; next column
DODROPS JSR RND ; grab a random number
CMP UPPERLIMIT ; drop threshold
BCC NODROP ; less than limit, no drop
LDA PLOTCOLUMN
ROR ; on an odd/even column
BCS LGDROP ; small/fast drops on even, large slow on odd
SMALLDROP LDA #$27
JMP STOREDROP
LGDROP LDA #$F7 ; draw a drop
STOREDROP STA CHAR
INC PROGRESS
JSR PLOTCHAR
INC PROGRESS
JMP NODROP
JSR GETCHAR
BEQ NODROP
JSR EXPAND ; found a non-zero pixel, process it
NODROP LDA PLOTCOLUMN ; last COLUMN?
BNE COLUMNLOOP3 ; loop on each column for top row
;/columnloop2
INC PROGRESS ; every other refresh, show alt page, normal page
ROR PROGRESS ; lowest bit into carry
BCC ALTSCREEN ; carry set on odd, not on even
STA ALTTEXTOFF
JMP NORMSCREEN
ALTSCREEN STA ALTTEXT
NORMSCREEN ROL PROGRESS
RTS
;/NEXTSCREEN
**************************************************
* process raindrop animations.
**************************************************
DOSPLASH JSR SPLASH ; made it to the bottom of the screen
RTS ; show the splash animation
EXPAND
; found CHAR in A
; drop:
; == F7 76 02
; 27 -> 60 -> 20
; bottom up
CMP #$F7 ; if it's F7, plot 76, inc row, plot F7,
BNE SMDROP0 ; not F7, skip
INC PROGRESS
STA CHAR ; puts found character (F7) into CHAR
INC PLOTROW ; down 1
LDA PLOTROW
CMP #$15 ; lower than row 20?
JSR PLOTCHAR ; plot F7
DROP1 DEC PLOTROW ; back up
LDA #$76
STA CHAR
JSR PLOTCHAR ; plot 76
INC PROGRESS
LDA PLOTROW
CMP #$13 ; lower than row 20?
BEQ DOSPLASH
JMP DROPDONE
SMDROP0 CMP #$27
BNE DROP2
INC PROGRESS
STA CHAR ; puts found character (27) into CHAR
INC PLOTROW ; down 1
INC PLOTROW ; down 1
LDA PLOTROW
CMP #$14 ; lower than row 20?
BCS SMDROP1 ; if > 20 skip over
JSR PLOTCHAR ; plot 27 down 2 px
SMDROP1 DEC PLOTROW ; back up
DEC PLOTROW ; back up
LDA #$20 ; plot 20 down 0 px
STA CHAR
JSR PLOTCHAR ; plot 20
INC PROGRESS
JMP DROPDONE
DROP2 CMP #$76 ; if it's 76, plot 02
BNE SMDROP2 ; not 76, skip
INC PROGRESS
LDA #$02
STA CHAR
JSR PLOTCHAR
INC PROGRESS
LDA PLOTROW ; if we're at row 20ish
CMP #$13 ; should have triggered the splash
BEQ UNDOSPLASH ; undo the first splash frame
JMP DROPDONE
UNDOSPLASH JSR UNSPLASH
RTS
SMDROP2 CMP #$60 ; if it's 60, plot 60 down 2 px
BNE DROP3 ; not 60, skip
INC PLOTROW ; down 1
INC PLOTROW ; down 1
INC PROGRESS
STA CHAR
JSR PLOTCHAR
INC PROGRESS
DEC PLOTROW
DEC PLOTROW
LDA #$0 ; erase behind
JSR PLOTCHAR
JMP DROPDONE
DROP3 CMP #$02 ; if it's 02, erase behind it
BNE SMDROP3
LDA #$0
STA CHAR
JSR PLOTCHAR
INC PROGRESS
JSR PLOTCHAR
INC PROGRESS
LDA PLOTROW ; if we're at row 20ish
CMP #$13 ; should have triggered the splash
BEQ UNDOSPLASH ; undo the second splash frame
JMP DROPDONE
SMDROP3 CMP #$20 ; if it's 20, erase behind it
BNE DROPDONE
LDA #$0
STA CHAR
JSR PLOTCHAR
INC PROGRESS
JSR PLOTCHAR
INC PROGRESS
DROPDONE RTS
**************************************************
* prints one CHAR at PLOTROW,PLOTCOLUMN - clobbers A,Y
**************************************************
PLOTCHAR
LDY PLOTROW
TYA
CMP #$18
BCS OUTOFBOUNDS ; stop plotting if dimensions are outside screen
;LDA PROGRESS ; even or odd frame
ROR PROGRESS
BCC PLOTCHARALT ; every other frame, write to alt text page
LDA LoLineTableL,Y
STA $0
LDA LoLineTableH,Y
STA $1 ; now word/pointer at $0+$1 points to line
JMP LOADCHAR
PLOTCHARALT LDA AltLineTableL,Y
STA $0
LDA AltLineTableH,Y
STA $1 ; now word/pointer at $0+$1 points to line
LOADCHAR ROL PROGRESS ; return progress state for next ROR
LDY PLOTCOLUMN
TYA
CMP #$28
BCS OUTOFBOUNDS ; stop plotting if dimensions are outside screen
LDA CHAR ; this would be a byte with two pixels
STA ($0),Y
OUTOFBOUNDS RTS
;/PLOTCHAR
**************************************************
* GETS one CHAR at PLOTROW,PLOTCOLUMN - value returns in Accumulator
**************************************************
GETCHAR
LDY PLOTROW
ROR PROGRESS
BCC GETCHARALT ; every other frame, write to alt text page
LDA LoLineTableL,Y
STA $0
LDA LoLineTableH,Y
JMP STORECHAR
GETCHARALT LDA AltLineTableL,Y
STA $0
LDA AltLineTableH,Y
STORECHAR STA $1 ; now word/pointer at $0+$1 points to line
LDY PLOTCOLUMN
ROL PROGRESS ; return progress state for next ROR
LDA ($0),Y ; byte at row,col is now in accumulator
RTS
;/GETCHAR
**************************************************
* CLICKS and BEEPS
**************************************************
CLICK LDX #$06
CLICKLOOP LDA #$10 ; SLIGHT DELAY
JSR WAIT
LDA SPEAKER
DEX
BNE CLICKLOOP
RTS
;/CLICK
BEEP LDX #$30
BEEPLOOP LDA #$08 ; short DELAY
JSR WAIT
LDA SPEAKER
DEX
BNE BEEPLOOP
RTS
;/BEEP
BONK LDX #$50
BONKLOOP LDA #$20 ; longer DELAY
JSR WAIT
LDA SPEAKER
DEX
BNE BONKLOOP
RTS
;/BONK
**************************************************
* DATASOFT RND 6502
* BY JAMES GARON
* 10/02/86
* Thanks to John Brooks for this. I modified it slightly.
**************************************************
RNDINIT
LDA $C030 ; #$AB
STA RNDSEED
LDA $4E ; #$55
STA RNDSEED+1
LDA PROGRESS ; #$7E
STA RNDSEED+2
RTS
* RESULT IN ACC
RND LDA RNDSEED
ROL RNDSEED
EOR RNDSEED
ROR RNDSEED
INC RNDSEED+1
BNE RND10
LDA RNDSEED+2
INC RNDSEED+2
RND10 ADC RNDSEED+1
BVC RND20
INC RNDSEED+1
BNE RND20
LDA RNDSEED+2
INC RNDSEED+2
RND20 STA RNDSEED
RTS
**************************************************
* Draws the two frames of the splash animation when
* a drop reaches the bottom of the screen
**************************************************
; TO DO: if progress is odd, splash further down?
SPLASH LDA PLOTROW
STA ROW
LDA PLOTCOLUMN
STA COLUMN
INC PLOTROW
;DROPDOWN ROL PROGRESS
INC PROGRESS ; draw on next frame
DECCOL DEC PLOTCOLUMN ; decrement 3 columns
DEC PLOTCOLUMN ; decrement 3 columns
DEC PLOTCOLUMN ; decrement 3 columns
LDX #$06 ; for 6 to 0 in Y
SPLASHTOP LDA SPLASH1,X ; load SPLASH1,Y
STA CHAR ; store CHAR
JSR PLOTCHAR
INC PLOTCOLUMN ; INC PLOTCOLUMN
DEX ; next Y
BPL SPLASHTOP ; x!=0, return
INC PLOTROW ; INC ROW
LDX #$06 ; for 6 to 0 in Y
SPLASHBOTTOM LDA SPLASH2,X ; load SPLASH2,Y
STA CHAR ; store CHAR
DEC PLOTCOLUMN ; DEC PLOTCOLUMN
JSR PLOTCHAR
DEX
BPL SPLASHBOTTOM ; next Y
DEC PLOTROW
INC PROGRESS ; draw on current frame
SPLASHF2 LDX #$06 ; for 6 to 0 in Y
SPLASHTOPF2 LDA SPLASH3,X ; load SPLASH1,Y
STA CHAR ; store CHAR
JSR PLOTCHAR
INC PLOTCOLUMN ; INC PLOTCOLUMN
DEX ; next Y
BPL SPLASHTOPF2 ; x!=0, return
INC PLOTROW ; INC ROW
LDX #$06 ; for 6 to 0 in Y
SPLASHBOTTOMF2 LDA SPLASH4,X ; load SPLASH2,Y
STA CHAR ; store CHAR
DEC PLOTCOLUMN ; DEC PLOTCOLUMN
JSR PLOTCHAR
DEX
BPL SPLASHBOTTOMF2 ; next Y
LDA ROW ; reset to row/column for next pass
STA PLOTROW
LDA COLUMN
STA PLOTCOLUMN
RTS
UNSPLASH LDA PLOTROW
STA ROW
LDA PLOTCOLUMN
STA COLUMN
INC PLOTROW
;DROPDOWN2 ROL PROGRESS
INC PROGRESS
; JSR CLICK
DECCOL2 DEC PLOTCOLUMN ; decrement 3 columns
DEC PLOTCOLUMN ; decrement 3 columns
DEC PLOTCOLUMN ; decrement 3 columns
LDX #$06 ; for 6 to 0 in Y
UNDOSPLASHTOP LDA #$22 ; load SPLASH1,Y
STA CHAR ; store CHAR
JSR PLOTCHAR
INC PLOTCOLUMN ; INC PLOTCOLUMN
DEX ; next Y
BPL UNDOSPLASHTOP ; x!=0, return
INC PLOTROW ; INC ROW
LDX #$06 ; for 6 to 0 in Y
INC PROGRESS
UNDOSPLASHBOTTOM
LDA #$22 ; load SPLASH2,Y
STA CHAR ; store CHAR
DEC PLOTCOLUMN ; DEC PLOTCOLUMN
JSR PLOTCHAR
DEX
BPL UNDOSPLASHBOTTOM ; next Y
LDA ROW ; reset to row/column for next pass
STA PLOTROW
LDA COLUMN
STA PLOTCOLUMN
RTS
**************************************************
* Data Tables
*
**************************************************
SPLASH1 HEX 62,22,72,F2,72,22,62
SPLASH2 HEX 26,62,67,67,67,62,26
SPLASH3 HEX 22,72,22,22,22,72,22
SPLASH4 HEX 22,22,26,26,26,22,22
**************************************************
* Lores/Text lines
* Thanks to Dagen Brock for this.
**************************************************
Lo01 equ $400
Lo02 equ $480
Lo03 equ $500
Lo04 equ $580
Lo05 equ $600
Lo06 equ $680
Lo07 equ $700
Lo08 equ $780
Lo09 equ $428
Lo10 equ $4a8
Lo11 equ $528
Lo12 equ $5a8
Lo13 equ $628
Lo14 equ $6a8
Lo15 equ $728
Lo16 equ $7a8
Lo17 equ $450
Lo18 equ $4d0
Lo19 equ $550
Lo20 equ $5d0
* the "plus four" lines
Lo21 equ $650
Lo22 equ $6d0
Lo23 equ $750
Lo24 equ $7d0
Alt01 equ $800
Alt02 equ $880
Alt03 equ $900
Alt04 equ $980
Alt05 equ $A00
Alt06 equ $A80
Alt07 equ $B00
Alt08 equ $B80
Alt09 equ $828
Alt10 equ $8a8
Alt11 equ $928
Alt12 equ $9a8
Alt13 equ $A28
Alt14 equ $Aa8
Alt15 equ $B28
Alt16 equ $Ba8
Alt17 equ $850
Alt18 equ $8d0
Alt19 equ $950
Alt20 equ $9d0
* the "plus four" lines
Alt21 equ $A50
Alt22 equ $Ad0
Alt23 equ $B50
Alt24 equ $Bd0
LoLineTable da Lo01,Lo02,Lo03,Lo04
da Lo05,Lo06,Lo07,Lo08
da Lo09,Lo10,Lo11,Lo12
da Lo13,Lo14,Lo15,Lo16
da Lo17,Lo18,Lo19,Lo20
da Lo21,Lo22,Lo23,Lo24
AltLineTable da Alt01,Alt02,Alt03,Alt04
da Alt05,Alt06,Alt07,Alt08
da Alt09,Alt10,Alt11,Alt12
da Alt13,Alt14,Alt15,Alt16
da Alt17,Alt18,Alt19,Alt20
da Alt21,Alt22,Alt23,Alt24
** Here we split the table for an optimization
** We can directly get our line numbers now
** Without using ASL
LoLineTableH db >Lo01,>Lo02,>Lo03
db >Lo04,>Lo05,>Lo06
db >Lo07,>Lo08,>Lo09
db >Lo10,>Lo11,>Lo12
db >Lo13,>Lo14,>Lo15
db >Lo16,>Lo17,>Lo18
db >Lo19,>Lo20,>Lo21
db >Lo22,>Lo23,>Lo24
LoLineTableL db <Lo01,<Lo02,<Lo03
db <Lo04,<Lo05,<Lo06
db <Lo07,<Lo08,<Lo09
db <Lo10,<Lo11,<Lo12
db <Lo13,<Lo14,<Lo15
db <Lo16,<Lo17,<Lo18
db <Lo19,<Lo20,<Lo21
db <Lo22,<Lo23,<Lo24
AltLineTableH db >Alt01,>Alt02,>Alt03
db >Alt04,>Alt05,>Alt06
db >Alt07,>Alt08,>Alt09
db >Alt10,>Alt11,>Alt12
db >Alt13,>Alt14,>Alt15
db >Alt16,>Alt17,>Alt18
db >Alt19,>Alt20,>Alt21
db >Alt22,>Alt23,>Alt24
AltLineTableL db <Alt01,<Alt02,<Alt03
db <Alt04,<Alt05,<Alt06
db <Alt07,<Alt08,<Alt09
db <Alt10,<Alt11,<Alt12
db <Alt13,<Alt14,<Alt15
db <Alt16,<Alt17,<Alt18
db <Alt19,<Alt20,<Alt21
db <Alt22,<Alt23,<Alt24