Skip to content

Instantly share code, notes, and snippets.

@jblang
Last active February 23, 2018 00:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jblang/4a18b4d5b6daaddaf2b1e787f7248878 to your computer and use it in GitHub Desktop.
Save jblang/4a18b4d5b6daaddaf2b1e787f7248878 to your computer and use it in GitHub Desktop.
Z80 APA102 LED control via AY2149 GPIO port
; Control APA102 LEDs attached to the YM2149 sound chip's
; IO port A on pins 0 (data) and 1 (clock) by bit banging a shift register
; Yes, I have turned my RC2014 into the world's most Rube Goldbergesque Arduino
ymaddr equ 0d8h ; address port on YM2149
ymdata equ 0d0h ; data port on YM2149
mixer equ 7h ; mixer/IO control register
iodira equ 40h ; port A direction bit
iodirb equ 80h ; port B direction bit
porta equ 0eh ; GPIO port A data register
portb equ 0fh ; GPIO port B data register
numleds equ 2 ; number of LEDs attached
org 100h
init ld a, mixer ; make port A output
out (ymaddr), a
ld a, iodira
out (ymdata), a
ld a, porta ; select port A
out (ymaddr), a
ld a, 0 ; clear port A
out (ymdata), a
ld hl, colors ; output colors to 2 LEDs
ld a, numleds
call sendleds
ret
; colors to send to LEDs (4 bytes each)
; 111 + 5 bit brightness, 8 bit blue, 8 bit green, 8 bit red
colors db 0e7h, 00h, 0fh, 0ffh
db 0e7h, 0efh, 01fh, 00h
; send color bytes at HL to number of LEDs in A
sendleds
push bc
ld c, 0 ; output header (32 0 bits)
call shiftout
call shiftout
call shiftout
call shiftout
push af ; save LED count for later
nextled ld b, 4 ; output 4 contiguous bytes
nextbyte ld c, (hl) ; per LED starting at HL
call shiftout
inc hl
djnz nextbyte ; any more bytes left?
dec a
jr nz, nextled ; any more LEDs left?
; based on notes about end frame from apa102 arduino library
; https://github.com/pololu/apa102-arduino/blob/master/APA102.h#L91
ld c, 0ffh ; output 8 high bits
call shiftout
pop af ; restore LED count
srl a ; divide by 16
srl a
add 6 ; add 6
ld c, 0 ; output that many 0 bytes
nextbyte2 call shiftout
dec a
jr nz, nextbyte2
pop bc
ret
; shift out the byte in C
shiftout push af
push bc
ld b, 8 ; rotate through every bit in byte
nextbit xor a ; clear a
rlc c ; get msb from c in carry
adc 0 ; add carry to a (now it's 0 or 1)
out (ymdata), a ; output bit with clock low
or a, 2 ; raise clock
out (ymdata), a
djnz nextbit ; rinse and repeat
and a, 1 ; lower clock after last bit
out (ymdata), a
pop bc
pop af
ret
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment