leddisplay/libraries/FastLED/extras/FastLED6502.s65
2018-10-13 22:34:06 +02:00

633 lines
12 KiB
Text

/////////////////////////////////
//
// FastLED6502
// by Mark Kriegsman
//
// Device driver and animation
// library for connecting addressable
// LED strips to an Apple II.
// The full "FastLED" library is
// available for Arduino and related
// microcontrollers.
//
/////////////////////////////////
//
// HOST COMPATIBILITY:
// Apples with 16-pin DIP "game ports"
// are fully supported; Apples with only
// 9-pin "game ports" are NOT supported.
//
// Apple ][ fully supported
// Apple ][+ fully supported
// Apple //e fully supported
//
// Apple //c and //c+ NOT supported
// as they lack the required 16-pin
// DIP game port for digital I/O.
//
// Apple //gs:
// motherboard game port IS supported
// back panel connector NOT supported
// See Notes section below.
//
// C64, PET, VIC-20, Atari400/800,
// NES, SYM, KIM-1, and other 6502
// systems are NOT supported at this
// time, but porting should be
// relatively easy for someone familiar
// with each target platform.
//
//
// LED STRIP COMPATIBILITY:
// In general, "four-wire" (clocked)
// LED strips can be supported, but
// "three-wire" (clockless) LED strips
// cannot be supported.
//
// APA102 tested & working
// Adafruit DotStar tested & working
// LPD8806 should work (untested)
// WS2801 should work (untested)
//
// WS2811/WS2812/NeoPixel can NOT work
// due to timing incompatibilities,
// namely that the 1MHz Apple is far
// too slow to drive them correctly.
//
//
// USAGE - HARDWARE:
// Connect an external power source to
// +5 and GND on the LED strip.
// Connect GND on the LED strip to GND
// on the game port connector (pin 8)
// Connect DATA IN on the LED strip to
// pin 12, 13, or 14 on the game port.
// Connect CLOCK IN on the LED strip to
// pin 5 (preferred), 12, 13, or 14 on
// the game port. Note: Apple //gs users
// cannot use pin 5.
//
//
// USAGE - SOFTWARE:
// At build time provide definitions for
// CHIPSET, DATA_PIN, CLOCK_PIN,
// NUM_LEDS, & BRIGHTNESS.
// Inside "Setup":
// Store LED count into
// FastLED_NumPixels,
// Store brightness into
// FastLED_Brightness
// Inside "Loop":
// Update the leds array, found in
// ledsR, ledsG, and ledsB
// Call FastLED_Show
// Jump back to top of "Loop"
//
//
// REFERENCE:
// FastLED_Show:
// display led array on LED strip
// FastLED_FillBlack:
// fill led array to black
// FastLED_FillSolid_RGB_AXY:
// fill led array with RGB color
// FastLED_FillSolid_Hue_X:
// fill led array with solid HSV Hue
// FastLED_Random8:
// return a pseudorandom number in A
// FastLED_FillRainbow_XY:
// fill led array with HSV rainbow
// starting at hue X, incrementing by
// huedelta Y each pixel.
// FastLED_SetHue_XY:
// set pixel Y to HSV hue X
// FastLED_Beat8:
// takes a speed increment in A, and
// returns a triangle wave in A.
//
//
// NOTES:
// For speed and size, there IS some
// self-modifying code in this
// library, so it cannot be burned
// into ROM without modification.
// Brightness control only works on
// APA102 at this point.
// Pin 15 is currently used as a
// 'frame start' signal for protocol
// diagnostics - makes frames more
// visible with an oscilloscope.
// If Pin 5 is specified for the CLOCK
// output pin, FastLED6502 will
// automatically use the high speed
// C040STROBE signal for clock. Note
// that the Apple //gs lacks this
// signal, even on the motherboard
// game port.
// The Apple joystick/mouse port on the
// rear of the //c, //c+, and //gs
// can NOT be used for LED connections
// because it lacks the necessary
// digital output pins.
// This library can drive 100 LED pixels
// at more than 30 frames per second.
//
//
// VERSION HISTORY
// 2015-02-07 - first version, by MEK
// assembled with xa65
// www.floodgap.com/retrotech/xa/
/////////////////////////////////
//
// ENTRY POINT
//
FastLED_Entry
jsr FastLED_FillBlack
jmp Setup
/////////////////////////////////
//
// FASTLED6502 GLOBALS
//
FastLED_NumPixels .byt NUM_LEDS
FastLED_Brightness .byt BRIGHTNESS
FastLED_RandomState .byt 17
FastLED_BeatState .byt 0
/////////////////////////////////
//
// API FUNCTIONS
//
FastLED_FillBlack
lda FastLED_NumPixels
pha
lda #255
sta FastLED_NumPixels
lda #0
tax
tay
jsr FastLED_FillSolid_RGB_AXY
jsr FastLED_Show
pla
sta FastLED_NumPixels
rts
FastLED_FillRainbow_XY
sty rbHueDelta
ldy #0
FR1
lda FastLED_RainbowR,x
sta ledsR,y
lda FastLED_RainbowG,x
sta ledsG,y
lda FastLED_RainbowB,x
sta ledsB,y
txa
clc
adc rbHueDelta
tax
iny
cpy FastLED_NumPixels
bne FR1
rts
rbHueDelta .byt 0
FastLED_SetHue_XY
lda FastLED_RainbowR,x
sta ledsR,y
lda FastLED_RainbowG,x
sta ledsG,y
lda FastLED_RainbowB,x
sta ledsB,y
rts
FastLED_FillSolid_RGB_AXY
sta ledsR
stx ledsG
sty ledsB
ldy #0
FillSolidRGBAXY1
lda ledsR
sta ledsR,y
lda ledsG
sta ledsG,y
lda ledsB
sta ledsB,y
iny
cpy FastLED_NumPixels
bne FillSolidRGBAXY1
rts
FastLED_FillSolid_Hue_X
ldy #0
FillSolidHX1
lda FastLED_RainbowR,x
sta ledsR,y
lda FastLED_RainbowG,x
sta ledsG,y
lda FastLED_RainbowB,x
sta ledsB,y
iny
cpy FastLED_NumPixels
bne FillSolidHX1
rts
; NOTE: USES SELF-MODIFYING CODE
FastLED_Random8
inc Random8GetLo
bne Random8Get
inc Random8GetHi
bne Random8Get
lda #$F8
sta Random8GetHi
lda #03
sta Random8GetLo
Random8Get
Random8GetLo = Random8Get + 1
Random8GetHi = Random8Get + 2
lda $F803
adc FastLED_RandomState
sta FastLED_RandomState
rts
FastLED_Beat8
clc
adc FastLED_BeatState
sta FastLED_BeatState
bit FastLED_BeatState
bmi FastLED_Beat8Neg
asl
rts
FastLED_Beat8Neg
lda #$ff
sec
sbc FastLED_BeatState
sbc FastLED_BeatState
rts
FastLED_Show
jmp CHIPSET
/////////////////////////////////
//
// HARDWARE INTERFACING
//
PINOFF_BASE = PIN15OFF
PINON_BASE = PIN15ON
#define PINON(P) PINON_BASE+((15-P)*2)
#define PINOFF(P) PINOFF_BASE+((15-P)*2)
DATAOFF = PINOFF(DATA_PIN)
DATAON = PINON(DATA_PIN)
CLKOFF = PINOFF(CLOCK_PIN)
CLKON = PINON(CLOCK_PIN)
// Special handling if CLOCK_PIN
// is 5: the C040STROBE line.
#if CLOCK_PIN = 5
#define CLOCK_ON bit PIN5STROBE
#define CLOCK_OFF
#else
#define CLOCK_ON bit CLKON
#define CLOCK_OFF bit CLKOFF
#endif
FRAMEON = PINON(15)
FRAMEOFF = PINOFF(15)
/////////////////////////////////
APA102
bit FRAMEON
jsr FastLED_Send00
jsr FastLED_Send00
jsr FastLED_Send00
jsr FastLED_Send00
lda FastLED_Brightness
lsr
lsr
lsr
ora #$E0
tax
ldy FastLED_NumPixels
APA102PX
txa
jsr FastLED_SendA
lda ledsB,y
jsr FastLED_SendA
lda ledsG,y
jsr FastLED_SendA
lda ledsR,y
jsr FastLED_SendA
dey
bne APA102PX
lda FastLED_NumPixels
lsr
lsr
lsr
lsr
lsr
lsr
tay
iny
APA102CL
jsr FastLED_SendFF
jsr FastLED_Send00
jsr FastLED_Send00
jsr FastLED_Send00
dey
bne APA102CL
bit FRAMEOFF
rts
/////////////////////////////////
LPD8806
bit FRAMEON
ldy FastLED_NumPixels
LPD8806PX
lda ledsG,y
lsr
ora #$80
jsr FastLED_SendA
lda ledsR,y
lsr
ora #$80
jsr FastLED_SendA
lda ledsB,y
lsr
ora #$80
jsr FastLED_SendA
dey
bne LPD8806PX
bit FRAMEOFF
rts
/////////////////////////////////
WS2801
bit FRAMEON
ldy FastLED_NumPixels
WS2801PX
lda ledsG,y
jsr FastLED_SendA
lda ledsR,y
jsr FastLED_SendA
lda ledsB,y
jsr FastLED_SendA
dey
bne WS2801PX
bit FRAMEOFF
rts
/////////////////////////////////
FastLED_SendFF
bit DATAON
jmp FastLED_SendXX
;
FastLED_Send00
bit DATAOFF
;
FastLED_SendXX
CLOCK_ON
CLOCK_OFF
CLOCK_ON
CLOCK_OFF
CLOCK_ON
CLOCK_OFF
CLOCK_ON
CLOCK_OFF
CLOCK_ON
CLOCK_OFF
CLOCK_ON
CLOCK_OFF
CLOCK_ON
CLOCK_OFF
CLOCK_ON
CLOCK_OFF
rts
FastLED_SendA
cmp #0
beq FastLED_Send00
cmp #$FF
beq FastLED_SendFF
asl
bcc S0x0
S0x1 bit DATAON
bcs S0xK
S0x0 bit DATAOFF
S0xK CLOCK_ON
CLOCK_OFF
asl
bcc S1x0
S1x1 bit DATAON
bcs S1xK
S1x0 bit DATAOFF
S1xK CLOCK_ON
CLOCK_OFF
asl
bcc S2x0
S2x1 bit DATAON
bcs S2xK
S2x0 bit DATAOFF
S2xK CLOCK_ON
CLOCK_OFF
asl
bcc S3x0
S3x1 bit DATAON
bcs S3xK
S3x0 bit DATAOFF
S3xK CLOCK_ON
CLOCK_OFF
asl
bcc S4x0
S4x1 bit DATAON
bcs S4xK
S4x0 bit DATAOFF
S4xK CLOCK_ON
CLOCK_OFF
asl
bcc S5x0
S5x1 bit DATAON
bcs S5xK
S5x0 bit DATAOFF
S5xK CLOCK_ON
CLOCK_OFF
asl
bcc S6x0
S6x1 bit DATAON
bcs S6xK
S6x0 bit DATAOFF
S6xK CLOCK_ON
CLOCK_OFF
asl
bcc S7x0
S7x1 bit DATAON
bcs S7xK
S7x0 bit DATAOFF
S7xK CLOCK_ON
CLOCK_OFF
rts
/////////////////////////////////
//
// Force page allignment for speed
// for leds array and Rainbow table
//
.dsb 256-(* & $FF),0
/////////////////////////////////
//
// LED ARRAY
//
ledsR .dsb 256,0
ledsG .dsb 256,0
ledsB .dsb 256,0
/////////////////////////////////
//
// HSV RAINBOW DEFINITION
//
// Generated directly from FastLED.
//
FastLED_RainbowR
.byt $FF,$FD,$FA,$F8,$F5,$F2,$F0,$ED
.byt $EA,$E8,$E5,$E2,$E0,$DD,$DA,$D8
.byt $D5,$D2,$D0,$CD,$CA,$C8,$C5,$C2
.byt $C0,$BD,$BA,$B8,$B5,$B2,$B0,$AD
.byt $AB,$AB,$AB,$AB,$AB,$AB,$AB,$AB
.byt $AB,$AB,$AB,$AB,$AB,$AB,$AB,$AB
.byt $AB,$AB,$AB,$AB,$AB,$AB,$AB,$AB
.byt $AB,$AB,$AB,$AB,$AB,$AB,$AB,$AB
.byt $AB,$A6,$A1,$9C,$96,$91,$8C,$86
.byt $81,$7C,$76,$71,$6C,$66,$61,$5C
.byt $56,$51,$4C,$47,$41,$3C,$37,$31
.byt $2C,$27,$21,$1C,$17,$11,$0C,$07
.byt $00,$00,$00,$00,$00,$00,$00,$00
.byt $00,$00,$00,$00,$00,$00,$00,$00
.byt $00,$00,$00,$00,$00,$00,$00,$00
.byt $00,$00,$00,$00,$00,$00,$00,$00
.byt $00,$00,$00,$00,$00,$00,$00,$00
.byt $00,$00,$00,$00,$00,$00,$00,$00
.byt $00,$00,$00,$00,$00,$00,$00,$00
.byt $00,$00,$00,$00,$00,$00,$00,$00
.byt $00,$02,$05,$07,$0A,$0D,$0F,$12
.byt $15,$17,$1A,$1D,$1F,$22,$25,$27
.byt $2A,$2D,$2F,$32,$35,$37,$3A,$3D
.byt $3F,$42,$45,$47,$4A,$4D,$4F,$52
.byt $55,$57,$5A,$5C,$5F,$62,$64,$67
.byt $6A,$6C,$6F,$72,$74,$77,$7A,$7C
.byt $7F,$82,$84,$87,$8A,$8C,$8F,$92
.byt $94,$97,$9A,$9C,$9F,$A2,$A4,$A7
.byt $AB,$AD,$B0,$B2,$B5,$B8,$BA,$BD
.byt $C0,$C2,$C5,$C8,$CA,$CD,$D0,$D2
.byt $D5,$D8,$DA,$DD,$E0,$E2,$E5,$E8
.byt $EA,$ED,$F0,$F2,$F5,$F8,$FA,$FD
FastLED_RainbowG
.byt $00,$02,$05,$07,$0A,$0D,$0F,$12
.byt $15,$17,$1A,$1D,$1F,$22,$25,$27
.byt $2A,$2D,$2F,$32,$35,$37,$3A,$3D
.byt $3F,$42,$45,$47,$4A,$4D,$4F,$52
.byt $55,$57,$5A,$5C,$5F,$62,$64,$67
.byt $6A,$6C,$6F,$72,$74,$77,$7A,$7C
.byt $7F,$82,$84,$87,$8A,$8C,$8F,$92
.byt $94,$97,$9A,$9C,$9F,$A2,$A4,$A7
.byt $AB,$AD,$B0,$B2,$B5,$B8,$BA,$BD
.byt $C0,$C2,$C5,$C8,$CA,$CD,$D0,$D2
.byt $D5,$D8,$DA,$DD,$E0,$E2,$E5,$E8
.byt $EA,$ED,$F0,$F2,$F5,$F8,$FA,$FD
.byt $FF,$FD,$FA,$F8,$F5,$F2,$F0,$ED
.byt $EA,$E8,$E5,$E2,$E0,$DD,$DA,$D8
.byt $D5,$D2,$D0,$CD,$CA,$C8,$C5,$C2
.byt $C0,$BD,$BA,$B8,$B5,$B2,$B0,$AD
.byt $AB,$A6,$A1,$9C,$96,$91,$8C,$86
.byt $81,$7C,$76,$71,$6C,$66,$61,$5C
.byt $56,$51,$4C,$47,$41,$3C,$37,$31
.byt $2C,$27,$21,$1C,$17,$11,$0C,$07
.byt $00,$00,$00,$00,$00,$00,$00,$00
.byt $00,$00,$00,$00,$00,$00,$00,$00
.byt $00,$00,$00,$00,$00,$00,$00,$00
.byt $00,$00,$00,$00,$00,$00,$00,$00
.byt $00,$00,$00,$00,$00,$00,$00,$00
.byt $00,$00,$00,$00,$00,$00,$00,$00
.byt $00,$00,$00,$00,$00,$00,$00,$00
.byt $00,$00,$00,$00,$00,$00,$00,$00
.byt $00,$00,$00,$00,$00,$00,$00,$00
.byt $00,$00,$00,$00,$00,$00,$00,$00
.byt $00,$00,$00,$00,$00,$00,$00,$00
.byt $00,$00,$00,$00,$00,$00,$00,$00
FastLED_RainbowB
.byt $00,$00,$00,$00,$00,$00,$00,$00
.byt $00,$00,$00,$00,$00,$00,$00,$00
.byt $00,$00,$00,$00,$00,$00,$00,$00
.byt $00,$00,$00,$00,$00,$00,$00,$00
.byt $00,$00,$00,$00,$00,$00,$00,$00
.byt $00,$00,$00,$00,$00,$00,$00,$00
.byt $00,$00,$00,$00,$00,$00,$00,$00
.byt $00,$00,$00,$00,$00,$00,$00,$00
.byt $00,$00,$00,$00,$00,$00,$00,$00
.byt $00,$00,$00,$00,$00,$00,$00,$00
.byt $00,$00,$00,$00,$00,$00,$00,$00
.byt $00,$00,$00,$00,$00,$00,$00,$00
.byt $00,$02,$05,$07,$0A,$0D,$0F,$12
.byt $15,$17,$1A,$1D,$1F,$22,$25,$27
.byt $2A,$2D,$2F,$32,$35,$37,$3A,$3D
.byt $3F,$42,$45,$47,$4A,$4D,$4F,$52
.byt $55,$5A,$5F,$64,$6A,$6F,$74,$7A
.byt $7F,$84,$8A,$8F,$94,$9A,$9F,$A4
.byt $AA,$AF,$B4,$B9,$BF,$C4,$C9,$CF
.byt $D4,$D9,$DF,$E4,$E9,$EF,$F4,$F9
.byt $FF,$FD,$FA,$F8,$F5,$F2,$F0,$ED
.byt $EA,$E8,$E5,$E2,$E0,$DD,$DA,$D8
.byt $D5,$D2,$D0,$CD,$CA,$C8,$C5,$C2
.byt $C0,$BD,$BA,$B8,$B5,$B2,$B0,$AD
.byt $AB,$A9,$A6,$A4,$A1,$9E,$9C,$99
.byt $96,$94,$91,$8E,$8C,$89,$86,$84
.byt $81,$7E,$7C,$79,$76,$74,$71,$6E
.byt $6C,$69,$66,$64,$61,$5E,$5C,$59
.byt $55,$53,$50,$4E,$4B,$48,$46,$43
.byt $40,$3E,$3B,$38,$36,$33,$30,$2E
.byt $2B,$28,$26,$23,$20,$1E,$1B,$18
.byt $16,$13,$10,$0E,$0B,$08,$06,$03