Browse Source

Merge remote-tracking branch 'origin' into kart

feature/2015
Stefan Kinzel 11 years ago
parent
commit
9d25fc30e4
  1. 6
      README.md
  2. 7
      config.in
  3. 10
      defaults.mk
  4. 2
      ld_scripts/avr51.x
  5. 231
      ld_scripts/avr6.x
  6. 9
      profiles/FFM-Jochen
  7. 23
      profiles/FFM-LedBrett
  8. 127
      profiles/LoL-Shield_Leonardo
  9. 127
      profiles/LoL-Shield_Mega2560
  10. 127
      profiles/LoL-Shield_Uno-Duemilanove-Diavolino
  11. 17
      profiles/borg-16
  12. 19
      profiles/borg-ancient
  13. 17
      profiles/borg-andre
  14. 20
      profiles/borg-ls
  15. 30
      profiles/borgjacke
  16. 7
      src/animations/blackhole.c
  17. 3
      src/animations/config.in
  18. 78
      src/animations/ltn_ant.c
  19. 20
      src/animations/mherweg.c
  20. 31
      src/animations/moire.c
  21. 78
      src/animations/program.c
  22. 4
      src/borg_hw/Makefile
  23. 923
      src/borg_hw/borg_hw_lolshield.c
  24. 5
      src/borg_hw/config.in
  25. 8
      src/borg_hw/config_lolshield.in
  26. 10
      src/games/breakout/playfield.c
  27. 2
      src/games/breakout/rebound.h
  28. 98
      src/games/snake/snake_game.c
  29. 3
      src/games/tetris/variant_fp.c
  30. 26
      src/games/tetris/view.c
  31. 6
      src/joystick/Makefile
  32. 112
      src/joystick/config.in
  33. 70
      src/joystick/joystick.h
  34. 89
      src/joystick/lolshield_joystick.c
  35. 2
      src/joystick/null_joystick.c
  36. 9
      src/random/Makefile
  37. 12
      src/random/noekeon.c
  38. 12
      src/scrolltext/font_small6.c
  39. 44
      src/util.c

6
README.md

@ -7,8 +7,10 @@ Firmware for AVR based two-dimensional LED matrices, especially the
Main platform is the [Borg16](http://www.das-labor.org/wiki/Borg16) construction
kit. Other supported platforms are the
[LED Brett](http://www.hackerspace-ffm.de/wiki/index.php?title=LedBrett)
projector from [Hackerspace FFM](http://www.hackerspace-ffm.de) or the
[ELO Ping-Pong Board](http://www.elo-web.de/elo/mikrocontroller-und-programmierung/ping-pong/das-franzis-pingpong).
projector from [Hackerspace FFM](http://www.hackerspace-ffm.de), the
[ELO Ping-Pong Board](http://www.elo-web.de/elo/mikrocontroller-und-programmierung/ping-pong/das-franzis-pingpong)
or the [LoL Shield](http://jimmieprodgers.com/kits/lolshield/) from Jimmie P.
Rodgers.
![Small Borg16](/doc/img/Borg16-small.jpg)
![Glow Lamp Borg](/doc/img/Glow_Lamp_Borg.jpg)

7
config.in

@ -7,12 +7,19 @@ comment "General Setup"
choice 'Target MCU' \
"ATmega8 atmega8 \
ATmega16 atmega16 \
ATmega168 atmega168 \
ATmega168P atmega168p \
ATmega32 atmega32 \
ATmega32U4 atmega32u4 \
ATmega328 atmega328 \
ATmega328p atmega328p \
ATmega644 atmega644 \
ATmega644p atmega644p \
ATmega1280 atmega1280 \
ATmega1284 atmega1284 \
ATmega1284p atmega1284p \
ATmega2560 atmega2560 \
ATmega8515 atmega8515" \
'ATmega32' MCU

10
defaults.mk

@ -104,10 +104,14 @@ include $(MAKETOPDIR)/.config
CPPFLAGS += -DF_CPU=$(FREQ)UL -mmcu=$(MCU)
# flags for the linker, choose appropriate linker script
ifeq ($(findstring atmega128,$(MCU)),atmega128)
LDFLAGS += -T ld_scripts/avr51.x -Wl,-Map,image.map -mmcu=$(MCU)
ifeq ($(findstring atmega256,$(MCU)),atmega256)
LDFLAGS += -T ld_scripts/avr6.x -Wl,-Map,image.map -mmcu=$(MCU)
else
LDFLAGS += -T ld_scripts/avr5.x -Wl,-Map,image.map -mmcu=$(MCU)
ifeq ($(findstring atmega128,$(MCU)),atmega128)
LDFLAGS += -T ld_scripts/avr51.x -Wl,-Map,image.map -mmcu=$(MCU)
else
LDFLAGS += -T ld_scripts/avr5.x -Wl,-Map,image.map -mmcu=$(MCU)
endif
endif
endif # MAKECMDGOALS!=menuconfig

2
ld_scripts/avr51.x

@ -4,7 +4,7 @@ OUTPUT_ARCH(avr:51)
MEMORY
{
text (rx) : ORIGIN = 0, LENGTH = 128K
data (rw!x) : ORIGIN = 0x800060, LENGTH = 0xffa0
data (rw!x) : ORIGIN = 0x800100, LENGTH = 0xff00
eeprom (rw!x) : ORIGIN = 0x810000, LENGTH = 64K
fuse (rw!x) : ORIGIN = 0x820000, LENGTH = 1K
lock (rw!x) : ORIGIN = 0x830000, LENGTH = 1K

231
ld_scripts/avr6.x

@ -0,0 +1,231 @@
/* Default linker script, for normal executables */
OUTPUT_FORMAT("elf32-avr","elf32-avr","elf32-avr")
OUTPUT_ARCH(avr:6)
MEMORY
{
text (rx) : ORIGIN = 0, LENGTH = 1024K
data (rw!x) : ORIGIN = 0x800200, LENGTH = 0xfe00
eeprom (rw!x) : ORIGIN = 0x810000, LENGTH = 64K
fuse (rw!x) : ORIGIN = 0x820000, LENGTH = 1K
lock (rw!x) : ORIGIN = 0x830000, LENGTH = 1K
signature (rw!x) : ORIGIN = 0x840000, LENGTH = 1K
}
SECTIONS
{
/* Read-only sections, merged into text segment: */
.hash : { *(.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.gnu.version : { *(.gnu.version) }
.gnu.version_d : { *(.gnu.version_d) }
.gnu.version_r : { *(.gnu.version_r) }
.rel.init : { *(.rel.init) }
.rela.init : { *(.rela.init) }
.rel.text :
{
*(.rel.text)
*(.rel.text.*)
*(.rel.gnu.linkonce.t*)
}
.rela.text :
{
*(.rela.text)
*(.rela.text.*)
*(.rela.gnu.linkonce.t*)
}
.rel.fini : { *(.rel.fini) }
.rela.fini : { *(.rela.fini) }
.rel.rodata :
{
*(.rel.rodata)
*(.rel.rodata.*)
*(.rel.gnu.linkonce.r*)
}
.rela.rodata :
{
*(.rela.rodata)
*(.rela.rodata.*)
*(.rela.gnu.linkonce.r*)
}
.rel.data :
{
*(.rel.data)
*(.rel.data.*)
*(.rel.gnu.linkonce.d*)
}
.rela.data :
{
*(.rela.data)
*(.rela.data.*)
*(.rela.gnu.linkonce.d*)
}
.rel.ctors : { *(.rel.ctors) }
.rela.ctors : { *(.rela.ctors) }
.rel.dtors : { *(.rel.dtors) }
.rela.dtors : { *(.rela.dtors) }
.rel.got : { *(.rel.got) }
.rela.got : { *(.rela.got) }
.rel.bss : { *(.rel.bss) }
.rela.bss : { *(.rela.bss) }
.rel.plt : { *(.rel.plt) }
.rela.plt : { *(.rela.plt) }
/* Internal text space or external memory. */
.text :
{
*(.vectors)
KEEP(*(.vectors))
/* For data that needs to reside in the lower 64k of progmem. */
*(.progmem.gcc*)
*(.progmem*)
. = ALIGN(2);
__trampolines_start = . ;
/* The jump trampolines for the 16-bit limited relocs will reside here. */
*(.trampolines)
*(.trampolines*)
__trampolines_end = . ;
/* For future tablejump instruction arrays for 3 byte pc devices.
We don't relax jump/call instructions within these sections. */
*(.jumptables)
*(.jumptables*)
/* For code that needs to reside in the lower 128k progmem. */
*(.lowtext)
*(.lowtext*)
__ctors_start = . ;
*(.ctors)
__ctors_end = . ;
__dtors_start = . ;
*(.dtors)
__dtors_end = . ;
KEEP(SORT(*)(.ctors))
KEEP(SORT(*)(.dtors))
/* From this point on, we don't bother about wether the insns are
below or above the 16 bits boundary. */
*(.init0) /* Start here after reset. */
KEEP (*(.init0))
*(.init1)
KEEP (*(.init1))
*(.init2) /* Clear __zero_reg__, set up stack pointer. */
KEEP (*(.init2))
*(.init3)
KEEP (*(.init3))
*(.init4) /* Initialize data and BSS. */
KEEP (*(.init4))
*(.init5)
KEEP (*(.init5))
*(.init6) /* C++ constructors. */
KEEP (*(.init6))
*(.init7)
KEEP (*(.init7))
*(.init8)
KEEP (*(.init8))
*(.init9) /* Call main(). */
KEEP (*(.init9))
*(.text)
. = ALIGN(2);
*(.text.*)
. = ALIGN(2);
*(.fini9) /* _exit() starts here. */
KEEP (*(.fini9))
*(.fini8)
KEEP (*(.fini8))
*(.fini7)
KEEP (*(.fini7))
*(.fini6) /* C++ destructors. */
KEEP (*(.fini6))
*(.fini5)
KEEP (*(.fini5))
*(.fini4)
KEEP (*(.fini4))
*(.fini3)
KEEP (*(.fini3))
*(.fini2)
KEEP (*(.fini2))
*(.fini1)
KEEP (*(.fini1))
*(.fini0) /* Infinite loop after program termination. */
KEEP (*(.fini0))
_etext = . ;
} > text
.data : AT (ADDR (.text) + SIZEOF (.text))
{
PROVIDE (__data_start = .) ;
*(.data)
*(.data*)
*(.rodata) /* We need to include .rodata here if gcc is used */
*(.rodata*) /* with -fdata-sections. */
*(.gnu.linkonce.d*)
PROVIDE (_game_descriptors_start__ = .) ;
*(.game_descriptors)
PROVIDE (_game_descriptors_end__ = .) ;
. = ALIGN(2);
_edata = . ;
PROVIDE (__data_end = .) ;
} > data
.bss SIZEOF(.data) + ADDR(.data) :
{
PROVIDE (__bss_start = .) ;
*(.bss)
*(.bss*)
*(COMMON)
PROVIDE (__bss_end = .) ;
} > data
__data_load_start = LOADADDR(.data);
__data_load_end = __data_load_start + SIZEOF(.data);
/* Global data not cleared after reset. */
.noinit SIZEOF(.bss) + ADDR(.bss) :
{
PROVIDE (__noinit_start = .) ;
*(.noinit*)
PROVIDE (__noinit_end = .) ;
_end = . ;
PROVIDE (__heap_start = .) ;
} > data
.eeprom :
{
*(.eeprom*)
__eeprom_end = . ;
} > eeprom
.fuse :
{
KEEP(*(.fuse))
KEEP(*(.lfuse))
KEEP(*(.hfuse))
KEEP(*(.efuse))
} > fuse
.lock :
{
KEEP(*(.lock*))
} > lock
.signature :
{
KEEP(*(.signature*))
} > signature
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info) *(.gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
}

9
profiles/FFM-Jochen

@ -37,7 +37,12 @@ SCROLL_X_SPEED=10
SCROLL_Y_SPEED=20
SCROLLTEXT_TEXT="</#COMMODORE C64 - All your base are belong to us!!!"
# RFM12_SUPPORT is not set
#
# Joystick Support
#
# JOYSTICK_SUPPORT is not set
JOYSTICK_CHOICE="JOY_PARALLEL"
# CAN_SUPPORT is not set
# MENU_SUPPORT is not set
@ -60,7 +65,8 @@ ANIMATION_SPIRAL=y
SPIRAL_DELAY=5
# ANIMATION_JOERN1 is not set
ANIMATION_SNAKE=y
SNAKE_CYCLE_DELAY=40
SNAKE_GAME_DELAY=200
SNAKE_ANIM_DELAY=40
SNAKE_TERMINATION_DELAY=30
SNAKE_MAX_LENGTH=64
SNAKE_MAX_APPLES=10
@ -83,6 +89,7 @@ GOL_DELAY=10
GOL_CYCLES=360
# ANIMATION_BREAKOUT is not set
# ANIMATION_MHERWEG is not set
# ANIMATION_MOIRE is not set
# ANIMATION_LTN_ANT is not set
# ANIMATION_TIME is not set
TIME_MASTER_ADDR=0x00

23
profiles/FFM-LedBrett

@ -33,10 +33,16 @@ SCROLL_X_SPEED=20
SCROLL_Y_SPEED=20
SCROLLTEXT_TEXT="</#www.hackerspace-ffm.de"
# RFM12_SUPPORT is not set
#
# Joystick Support
#
JOYSTICK_SUPPORT=y
# PARALLEL_JOYSTICK_SUPPORT is not set
# NES_PAD_SUPPORT is not set
# RFM12_JOYSTICK_SUPPORT is not set
JOYSTICK_CHOICE=JOY_LEDBRETT
#
# Joystick Settings
#
HC165_JOYSTICK_SUPPORT=y
HC165_JOYSTICK_PORT_LOAD=PORTD
HC165_JOYSTICK_BIT_LOAD=2
@ -62,7 +68,8 @@ ANIMATION_SPIRAL=y
SPIRAL_DELAY=5
# ANIMATION_JOERN1 is not set
# ANIMATION_SNAKE is not set
SNAKE_CYCLE_DELAY=100
SNAKE_GAME_DELAY=200
SNAKE_ANIM_DELAY=100
SNAKE_TERMINATION_DELAY=60
SNAKE_MAX_LENGTH=64
SNAKE_MAX_APPLES=10
@ -85,6 +92,7 @@ GOL_DELAY=100
GOL_CYCLES=360
# ANIMATION_BREAKOUT is not set
# ANIMATION_MHERWEG is not set
# ANIMATION_MOIRE is not set
# ANIMATION_LTN_ANT is not set
# ANIMATION_TIME is not set
TIME_MASTER_ADDR=0x00
@ -94,9 +102,16 @@ ANIMATION_BMSCROLLER=y
ANIMATION_AMPHIBIAN=y
# ANIMATION_LOGO_OOS is not set
# ANIMATION_FAIRYDUST is not set
#
# Fixed-point math patterns
#
ANIMATION_PLASMA=y
FP_PLASMA_DELAY=1
ANIMATION_PSYCHEDELIC=y
FP_PSYCHO_DELAY=15
ANIMATION_BLACKHOLE=y
# ANIMATION_SQUARES is not set
ANIMATION_TESTS=y
ANIMATION_OFF=y

127
profiles/LoL-Shield_Leonardo

@ -0,0 +1,127 @@
#
# Automatically generated by make menuconfig: don't edit
#
#
# General Setup
#
MCU=atmega32u4
FREQ=16000000
#
# Borg Hardware
#
NUM_ROWS=9
NUM_COLS=14
NUMPLANE=3
BORG_HW=HW_LOLSHIELD
#
# lolshield setup
#
USER_TIMER0_FOR_WAIT=1
BRIGHTNESS=127
#
# Features
#
RANDOM_SUPPORT=y
# LAP_TIME_EXTENSION is not set
SCROLLTEXT_SUPPORT=y
SCROLLTEXT_FONT=FONT_C64
SCROLLTEXT_BUFFER_SIZE=128
SCROLL_X_SPEED=20
SCROLL_Y_SPEED=20
SCROLLTEXT_TEXT="</#Borgware 2D"
# RFM12_SUPPORT is not set
#
# Joystick Support
#
JOYSTICK_SUPPORT=y
JOYSTICK_CHOICE=JOY_LOLSHIELD
LOLSHIELD_JOYSTICK_SUPPORT=y
# CAN_SUPPORT is not set
MENU_SUPPORT=y
#
# Games
#
GAME_TETRIS_CORE=y
GAME_TETRIS=y
# GAME_BASTET is not set
# GAME_TETRIS_FP is not set
# GAME_SPACE_INVADERS is not set
GAME_SNAKE=y
GAME_BREAKOUT=y
#
# Animations
#
ANIMATION_SCROLLTEXT=y
ANIMATION_SPIRAL=y
SPIRAL_DELAY=5
ANIMATION_JOERN1=y
ANIMATION_SNAKE=y
SNAKE_GAME_DELAY=200
SNAKE_ANIM_DELAY=100
SNAKE_TERMINATION_DELAY=60
SNAKE_MAX_LENGTH=64
SNAKE_MAX_APPLES=10
ANIMATION_CHECKERBOARD=y
ANIMATION_FIRE=y
FIRE_S=30
FIRE_N=5
FIRE_DIV=44
FIRE_DELAY=50
FIRE_CYCLES=800
ANIMATION_MATRIX=y
MATRIX_STREAMER_NUM=30
MATRIX_CYCLES=500
MATRIX_DELAY=60
ANIMATION_RANDOM_BRIGHT=y
ANIMATION_STONEFLY=y
# ANIMATION_FLYINGDOTS is not set
ANIMATION_GAMEOFLIFE=y
GOL_DELAY=100
GOL_CYCLES=360
ANIMATION_BREAKOUT=y
# ANIMATION_MHERWEG is not set
ANIMATION_MOIRE=y
# ANIMATION_LTN_ANT is not set
# ANIMATION_TIME is not set
TIME_MASTER_ADDR=00
TIME_UPDATE_TIMEOUT=50
ANIMATION_BMSCROLLER=y
# ANIMATION_LABORLOGO is not set
# ANIMATION_AMPHIBIAN is not set
# ANIMATION_LOGO_OOS is not set
ANIMATION_FAIRYDUST=y
#
# Fixed-point math patterns
#
ANIMATION_PLASMA=y
FP_PLASMA_DELAY=10
ANIMATION_PSYCHEDELIC=y
FP_PSYCHO_DELAY=25
ANIMATION_BLACKHOLE=y
ANIMATION_SQUARES=y
# ANIMATION_TESTS is not set
# ANIMATION_OFF is not set
#
# small Animations
#
# SMALLANIMATION_ROWWALK is not set
SMALLANIMATION_ROWWALK_SPEED=50
SMALLANIMATION_ROWWALK_COUNT=10
# SMALLANIMATION_COLWALK is not set
SMALLANIMATION_COLWALK_SPEED=50
SMALLANIMATION_COLWALK_COUNT=10
# SMALLANIMATION_ROWBOUNCE is not set
SMALLANIMATION_ROWBOUNCE_SPEED=50
SMALLANIMATION_ROWBOUNCE_COUNT=10
# SMALLANIMATION_COLBOUNCE is not set
SMALLANIMATION_COLBOUNCE_SPEED=50
SMALLANIMATION_COLBOUNCE_COUNT=10

127
profiles/LoL-Shield_Mega2560

@ -0,0 +1,127 @@
#
# Automatically generated by make menuconfig: don't edit
#
#
# General Setup
#
MCU=atmega2560
FREQ=16000000
#
# Borg Hardware
#
NUM_ROWS=9
NUM_COLS=14
NUMPLANE=3
BORG_HW=HW_LOLSHIELD
#
# lolshield setup
#
USER_TIMER0_FOR_WAIT=1
BRIGHTNESS=127
#
# Features
#
RANDOM_SUPPORT=y
# LAP_TIME_EXTENSION is not set
SCROLLTEXT_SUPPORT=y
SCROLLTEXT_FONT=FONT_C64
SCROLLTEXT_BUFFER_SIZE=128
SCROLL_X_SPEED=20
SCROLL_Y_SPEED=20
SCROLLTEXT_TEXT="</#Borgware 2D"
# RFM12_SUPPORT is not set
#
# Joystick Support
#
JOYSTICK_SUPPORT=y
JOYSTICK_CHOICE=JOY_LOLSHIELD
LOLSHIELD_JOYSTICK_SUPPORT=y
# CAN_SUPPORT is not set
MENU_SUPPORT=y
#
# Games
#
GAME_TETRIS_CORE=y
GAME_TETRIS=y
GAME_BASTET=y
# GAME_TETRIS_FP is not set
GAME_SPACE_INVADERS=y
GAME_SNAKE=y
GAME_BREAKOUT=y
#
# Animations
#
ANIMATION_SCROLLTEXT=y
ANIMATION_SPIRAL=y
SPIRAL_DELAY=5
ANIMATION_JOERN1=y
ANIMATION_SNAKE=y
SNAKE_GAME_DELAY=200
SNAKE_ANIM_DELAY=100
SNAKE_TERMINATION_DELAY=60
SNAKE_MAX_LENGTH=64
SNAKE_MAX_APPLES=10
ANIMATION_CHECKERBOARD=y
ANIMATION_FIRE=y
FIRE_S=30
FIRE_N=5
FIRE_DIV=44
FIRE_DELAY=50
FIRE_CYCLES=800
ANIMATION_MATRIX=y
MATRIX_STREAMER_NUM=30
MATRIX_CYCLES=500
MATRIX_DELAY=60
ANIMATION_RANDOM_BRIGHT=y
ANIMATION_STONEFLY=y
ANIMATION_FLYINGDOTS=y
ANIMATION_GAMEOFLIFE=y
GOL_DELAY=100
GOL_CYCLES=360
ANIMATION_BREAKOUT=y
# ANIMATION_MHERWEG is not set
ANIMATION_MOIRE=y
ANIMATION_LTN_ANT=y
# ANIMATION_TIME is not set
TIME_MASTER_ADDR=00
TIME_UPDATE_TIMEOUT=50
ANIMATION_BMSCROLLER=y
# ANIMATION_LABORLOGO is not set
ANIMATION_AMPHIBIAN=y
# ANIMATION_LOGO_OOS is not set
ANIMATION_FAIRYDUST=y
#
# Fixed-point math patterns
#
ANIMATION_PLASMA=y
FP_PLASMA_DELAY=10
ANIMATION_PSYCHEDELIC=y
FP_PSYCHO_DELAY=25
ANIMATION_BLACKHOLE=y
ANIMATION_SQUARES=y
ANIMATION_TESTS=y
ANIMATION_OFF=y
#
# small Animations
#
# SMALLANIMATION_ROWWALK is not set
SMALLANIMATION_ROWWALK_SPEED=50
SMALLANIMATION_ROWWALK_COUNT=10
# SMALLANIMATION_COLWALK is not set
SMALLANIMATION_COLWALK_SPEED=50
SMALLANIMATION_COLWALK_COUNT=10
# SMALLANIMATION_ROWBOUNCE is not set
SMALLANIMATION_ROWBOUNCE_SPEED=50
SMALLANIMATION_ROWBOUNCE_COUNT=10
# SMALLANIMATION_COLBOUNCE is not set
SMALLANIMATION_COLBOUNCE_SPEED=50
SMALLANIMATION_COLBOUNCE_COUNT=10

127
profiles/LoL-Shield_Uno-Duemilanove-Diavolino

@ -0,0 +1,127 @@
#
# Automatically generated by make menuconfig: don't edit
#
#
# General Setup
#
MCU=atmega328p
FREQ=16000000
#
# Borg Hardware
#
NUM_ROWS=9
NUM_COLS=14
NUMPLANE=3
BORG_HW=HW_LOLSHIELD
#
# lolshield setup
#
USER_TIMER0_FOR_WAIT=1
BRIGHTNESS=127
#
# Features
#
RANDOM_SUPPORT=y
# LAP_TIME_EXTENSION is not set
SCROLLTEXT_SUPPORT=y
SCROLLTEXT_FONT=FONT_C64
SCROLLTEXT_BUFFER_SIZE=128
SCROLL_X_SPEED=20
SCROLL_Y_SPEED=20
SCROLLTEXT_TEXT="</#Borgware 2D"
# RFM12_SUPPORT is not set
#
# Joystick Support
#
JOYSTICK_SUPPORT=y
JOYSTICK_CHOICE=JOY_LOLSHIELD
LOLSHIELD_JOYSTICK_SUPPORT=y
# CAN_SUPPORT is not set
MENU_SUPPORT=y
#
# Games
#
GAME_TETRIS_CORE=y
GAME_TETRIS=y
# GAME_BASTET is not set
# GAME_TETRIS_FP is not set
# GAME_SPACE_INVADERS is not set
GAME_SNAKE=y
GAME_BREAKOUT=y
#
# Animations
#
ANIMATION_SCROLLTEXT=y
ANIMATION_SPIRAL=y
SPIRAL_DELAY=5
ANIMATION_JOERN1=y
ANIMATION_SNAKE=y
SNAKE_GAME_DELAY=200
SNAKE_ANIM_DELAY=100
SNAKE_TERMINATION_DELAY=60
SNAKE_MAX_LENGTH=64
SNAKE_MAX_APPLES=10
ANIMATION_CHECKERBOARD=y
ANIMATION_FIRE=y
FIRE_S=30
FIRE_N=5
FIRE_DIV=44
FIRE_DELAY=50
FIRE_CYCLES=800
ANIMATION_MATRIX=y
MATRIX_STREAMER_NUM=30
MATRIX_CYCLES=500
MATRIX_DELAY=60
ANIMATION_RANDOM_BRIGHT=y
ANIMATION_STONEFLY=y
ANIMATION_FLYINGDOTS=y
ANIMATION_GAMEOFLIFE=y
GOL_DELAY=100
GOL_CYCLES=360
ANIMATION_BREAKOUT=y
# ANIMATION_MHERWEG is not set
ANIMATION_MOIRE=y
ANIMATION_LTN_ANT=y
# ANIMATION_TIME is not set
TIME_MASTER_ADDR=00
TIME_UPDATE_TIMEOUT=50
ANIMATION_BMSCROLLER=y
# ANIMATION_LABORLOGO is not set
ANIMATION_AMPHIBIAN=y
# ANIMATION_LOGO_OOS is not set
ANIMATION_FAIRYDUST=y
#
# Fixed-point math patterns
#
ANIMATION_PLASMA=y
FP_PLASMA_DELAY=10
ANIMATION_PSYCHEDELIC=y
FP_PSYCHO_DELAY=25
ANIMATION_BLACKHOLE=y
ANIMATION_SQUARES=y
# ANIMATION_TESTS is not set
# ANIMATION_OFF is not set
#
# small Animations
#
# SMALLANIMATION_ROWWALK is not set
SMALLANIMATION_ROWWALK_SPEED=50
SMALLANIMATION_ROWWALK_COUNT=10
# SMALLANIMATION_COLWALK is not set
SMALLANIMATION_COLWALK_SPEED=50
SMALLANIMATION_COLWALK_COUNT=10
# SMALLANIMATION_ROWBOUNCE is not set
SMALLANIMATION_ROWBOUNCE_SPEED=50
SMALLANIMATION_ROWBOUNCE_COUNT=10
# SMALLANIMATION_COLBOUNCE is not set
SMALLANIMATION_COLBOUNCE_SPEED=50
SMALLANIMATION_COLBOUNCE_COUNT=10

17
profiles/borg-16

@ -42,7 +42,16 @@ SCROLL_X_SPEED=20
SCROLL_Y_SPEED=20
SCROLLTEXT_TEXT="</#www.das-labor.org"
# RFM12_SUPPORT is not set
#
# Joystick Support
#
JOYSTICK_SUPPORT=y
JOYSTICK_CHOICE=JOY_PARALLEL
#
# Joystick Settings
#
PARALLEL_JOYSTICK_SUPPORT=y
JOYSTICK_PIN_UP=PINB
JOYSTICK_BIT_UP=0
@ -54,8 +63,6 @@ JOYSTICK_PIN_RIGHT=PINB
JOYSTICK_BIT_RIGHT=3
JOYSTICK_PIN_FIRE=PIND
JOYSTICK_BIT_FIRE=3
# NES_PAD_SUPPORT is not set
# RFM12_JOYSTICK_SUPPORT is not set
# CAN_SUPPORT is not set
MENU_SUPPORT=y
@ -78,7 +85,8 @@ ANIMATION_SPIRAL=y
SPIRAL_DELAY=5
ANIMATION_JOERN1=y
ANIMATION_SNAKE=y
SNAKE_CYCLE_DELAY=100
SNAKE_GAME_DELAY=200
SNAKE_ANIM_DELAY=100
SNAKE_TERMINATION_DELAY=60
SNAKE_MAX_LENGTH=64
SNAKE_MAX_APPLES=10
@ -101,6 +109,7 @@ GOL_DELAY=100
GOL_CYCLES=360
# ANIMATION_BREAKOUT is not set
# ANIMATION_MHERWEG is not set
# ANIMATION_MOIRE is not set
# ANIMATION_LTN_ANT is not set
# ANIMATION_TIME is not set
TIME_MASTER_ADDR=0x00
@ -114,12 +123,12 @@ ANIMATION_FAIRYDUST=y
#
# Fixed-point math patterns
#
FP_DOUBLE_BUFFERING=y
ANIMATION_PLASMA=y
FP_PLASMA_DELAY=1
ANIMATION_PSYCHEDELIC=y
FP_PSYCHO_DELAY=15
# ANIMATION_BLACKHOLE is not set
# ANIMATION_SQUARES is not set
ANIMATION_TESTS=y
ANIMATION_OFF=y

19
profiles/borg-ancient

@ -33,6 +33,11 @@ SCROLLTEXT_BUFFER_SIZE=128
SCROLL_X_SPEED=20
SCROLL_Y_SPEED=20
SCROLLTEXT_TEXT="</#LABOR BORG - WIDERSTAND IST ZWECKLOS"
# RFM12_SUPPORT is not set
#
# Joystick Support
#
# JOYSTICK_SUPPORT is not set
# CAN_SUPPORT is not set
# MENU_SUPPORT is not set
@ -56,7 +61,8 @@ ANIMATION_SPIRAL=y
SPIRAL_DELAY=20
ANIMATION_JOERN1=y
ANIMATION_SNAKE=y
SNAKE_CYCLE_DELAY=100
SNAKE_GAME_DELAY=200
SNAKE_ANIM_DELAY=100
SNAKE_TERMINATION_DELAY=60
SNAKE_MAX_LENGTH=64
SNAKE_MAX_APPLES=10
@ -79,6 +85,7 @@ GOL_DELAY=100
GOL_CYCLES=360
# ANIMATION_BREAKOUT is not set
# ANIMATION_MHERWEG is not set
# ANIMATION_MOIRE is not set
# ANIMATION_LTN_ANT is not set
# ANIMATION_TIME is not set
TIME_MASTER_ADDR=00
@ -87,9 +94,17 @@ TIME_UPDATE_TIMEOUT=50
# ANIMATION_LABORLOGO is not set
# ANIMATION_AMPHIBIAN is not set
# ANIMATION_LOGO_OOS is not set
# ANIMATION_LOGO_28C3 is not set
# ANIMATION_FAIRYDUST is not set
#
# Fixed-point math patterns
#
ANIMATION_PLASMA=y
FP_PLASMA_DELAY=1
ANIMATION_PSYCHEDELIC=y
FP_PSYCHO_DELAY=15
# ANIMATION_BLACKHOLE is not set
# ANIMATION_SQUARES is not set
# ANIMATION_TESTS is not set
# ANIMATION_OFF is not set

17
profiles/borg-andre

@ -39,7 +39,16 @@ SCROLL_X_SPEED=20
SCROLL_Y_SPEED=20
SCROLLTEXT_TEXT="</#www.das-labor.org"
# RFM12_SUPPORT is not set
#
# Joystick Support
#
JOYSTICK_SUPPORT=y
JOYSTICK_CHOICE=JOY_PARALLEL
#
# Joystick Settings
#
PARALLEL_JOYSTICK_SUPPORT=y
JOYSTICK_PIN_UP=PINB
JOYSTICK_BIT_UP=0
@ -51,8 +60,6 @@ JOYSTICK_PIN_RIGHT=PINB
JOYSTICK_BIT_RIGHT=3
JOYSTICK_PIN_FIRE=PIND
JOYSTICK_BIT_FIRE=3
# NES_PAD_SUPPORT is not set
# RFM12_JOYSTICK_SUPPORT is not set
# CAN_SUPPORT is not set
MENU_SUPPORT=y
@ -75,7 +82,8 @@ ANIMATION_SPIRAL=y
SPIRAL_DELAY=5
ANIMATION_JOERN1=y
ANIMATION_SNAKE=y
SNAKE_CYCLE_DELAY=100
SNAKE_GAME_DELAY=200
SNAKE_ANIM_DELAY=100
SNAKE_TERMINATION_DELAY=60
SNAKE_MAX_LENGTH=64
SNAKE_MAX_APPLES=10
@ -98,6 +106,7 @@ GOL_DELAY=100
GOL_CYCLES=360
ANIMATION_BREAKOUT=y
# ANIMATION_MHERWEG is not set
ANIMATION_MOIRE=y
ANIMATION_LTN_ANT=y
# ANIMATION_TIME is not set
TIME_MASTER_ADDR=00
@ -111,12 +120,12 @@ ANIMATION_FAIRYDUST=y
#
# Fixed-point math patterns
#
FP_DOUBLE_BUFFERING=y
ANIMATION_PLASMA=y
FP_PLASMA_DELAY=1
ANIMATION_PSYCHEDELIC=y
FP_PSYCHO_DELAY=15
ANIMATION_BLACKHOLE=y
ANIMATION_SQUARES=y
# ANIMATION_TESTS is not set
# ANIMATION_OFF is not set

20
profiles/borg-ls

@ -36,7 +36,13 @@ SCROLLTEXT_BUFFER_SIZE=128
SCROLL_X_SPEED=10
SCROLL_Y_SPEED=30
SCROLLTEXT_TEXT=">5+:<5|90>6:<6|78>:p10d50/#Labor#<5;>5|30<6;>6|40<6;p10+d50/# Borg#2d50-+/#Widerstand#ist#d50-b20p15#ZWECKLOS !"
# RFM12_SUPPORT is not set
#
# Joystick Support
#
# JOYSTICK_SUPPORT is not set
JOYSTICK_CHOICE="JOY_PARALLEL"
CAN_SUPPORT=y
SPI_HARDWARE=y
SPI_PORTIDX=1
@ -68,7 +74,8 @@ ANIMATION_SPIRAL=y
SPIRAL_DELAY=5
ANIMATION_JOERN1=y
ANIMATION_SNAKE=y
SNAKE_CYCLE_DELAY=50
SNAKE_GAME_DELAY=200
SNAKE_ANIM_DELAY=50
SNAKE_TERMINATION_DELAY=60
SNAKE_MAX_LENGTH=64
SNAKE_MAX_APPLES=10
@ -91,6 +98,7 @@ GOL_DELAY=12
GOL_CYCLES=180
# ANIMATION_BREAKOUT is not set
# ANIMATION_MHERWEG is not set
# ANIMATION_MOIRE is not set
# ANIMATION_LTN_ANT is not set
ANIMATION_TIME=y
TIME_MASTER_ADDR=00
@ -99,9 +107,17 @@ TIME_UPDATE_TIMEOUT=50
# ANIMATION_LABORLOGO is not set
# ANIMATION_AMPHIBIAN is not set
# ANIMATION_LOGO_OOS is not set
# ANIMATION_LOGO_28C3 is not set
# ANIMATION_FAIRYDUST is not set
#
# Fixed-point math patterns
#
# ANIMATION_PLASMA is not set
FP_PLASMA_DELAY=1
# ANIMATION_PSYCHEDELIC is not set
FP_PSYCHO_DELAY=15
# ANIMATION_BLACKHOLE is not set
# ANIMATION_SQUARES is not set
ANIMATION_TESTS=y
ANIMATION_OFF=y

30
profiles/borgjacke

@ -49,9 +49,12 @@ BIT_MISO=6
BIT_SCK=7
PORT_SS=PORTB
BIT_SS=4
#
# Joystick Support
#
JOYSTICK_SUPPORT=y
# PARALLEL_JOYSTICK_SUPPORT is not set
# NES_PAD_SUPPORT is not set
JOYSTICK_CHOICE=JOY_RFM12
RFM12_JOYSTICK_SUPPORT=y
# CAN_SUPPORT is not set
MENU_SUPPORT=y
@ -65,7 +68,7 @@ GAME_TETRIS=y
# GAME_TETRIS_FP is not set
GAME_SPACE_INVADERS=y
GAME_SNAKE=y
# GAME_BREAKOUT is not set
GAME_BREAKOUT=y
#
# Animations
@ -75,7 +78,8 @@ ANIMATION_SPIRAL=y
SPIRAL_DELAY=5
ANIMATION_JOERN1=y
ANIMATION_SNAKE=y
SNAKE_CYCLE_DELAY=100
SNAKE_GAME_DELAY=200
SNAKE_ANIM_DELAY=100
SNAKE_TERMINATION_DELAY=60
SNAKE_MAX_LENGTH=64
SNAKE_MAX_APPLES=10
@ -91,14 +95,15 @@ MATRIX_STREAMER_NUM=30
MATRIX_CYCLES=500
MATRIX_DELAY=60
ANIMATION_RANDOM_BRIGHT=y
# ANIMATION_STONEFLY is not set
# ANIMATION_FLYINGDOTS is not set
ANIMATION_STONEFLY=y
ANIMATION_FLYINGDOTS=y
ANIMATION_GAMEOFLIFE=y
GOL_DELAY=100
GOL_CYCLES=360
# ANIMATION_BREAKOUT is not set
ANIMATION_BREAKOUT=y
# ANIMATION_MHERWEG is not set
# ANIMATION_LTN_ANT is not set
ANIMATION_MOIRE=y
ANIMATION_LTN_ANT=y
# ANIMATION_TIME is not set
TIME_MASTER_ADDR=0x00
TIME_UPDATE_TIMEOUT=23
@ -107,9 +112,16 @@ ANIMATION_LABORLOGO=y
# ANIMATION_AMPHIBIAN is not set
# ANIMATION_LOGO_OOS is not set
# ANIMATION_FAIRYDUST is not set
#
# Fixed-point math patterns
#
ANIMATION_PLASMA=y
FP_PLASMA_DELAY=1
ANIMATION_PSYCHEDELIC=y
# ANIMATION_BLACKHOLE is not set
FP_PSYCHO_DELAY=15
ANIMATION_BLACKHOLE=y
ANIMATION_SQUARES=y
ANIMATION_TESTS=y
ANIMATION_OFF=y

7
src/animations/blackhole.c

@ -54,7 +54,8 @@ static signed char cos_i(unsigned char const angle) {
#define NUM_CIRCLE 7
#define W (NUM_COLS * 4)
#define H (NUM_ROWS * 4)
/**
* Draws a black hole like pattern (viewed from different perspectives).
@ -71,8 +72,8 @@ void blackhole(void) {
for (signed char j = 0; j < 64; j += 8) {
signed char a = (j & 0x08) ? 0 : 4;
pixel p;
p.x = (64 + cos_i(angle + j + a) * helpRadius / 64) >> 3;
p.y = (64 + sin_i(angle + add + j + a) * helpRadius / 64) >> 3;
p.x = (W + cos_i(angle + j + a) * helpRadius / W) / 8u;
p.y = (H + sin_i(angle + add + j + a) * helpRadius / H) / 8u;
if ((p.x < NUM_COLS) && (p.y < NUM_ROWS)) {
setpixel(p, 3);
}

3
src/animations/config.in

@ -9,7 +9,8 @@ comment "Animations"
bool "Joern1" ANIMATION_JOERN1
dep_bool_menu "Snake" ANIMATION_SNAKE $RANDOM_SUPPORT
int "Snake Round Delay" SNAKE_CYCLE_DELAY 100
int "Snake Game Round Delay" SNAKE_GAME_DELAY 200
int "Snake Anim Round Delay" SNAKE_ANIM_DELAY 100
int "Snake Termination Delay" SNAKE_TERMINATION_DELAY 60
uint "Snake Max Length" SNAKE_MAX_LENGTH 64
int "Snake Max Apples" SNAKE_MAX_APPLES 10

78
src/animations/ltn_ant.c

@ -35,73 +35,51 @@
#define NX (UNUM_COLS - 1u)
#define NY (UNUM_ROWS - 1u)
#if UNUM_ROWS == UNUM_COLS
static coord_t const dcomp[] = {0, P, NX};
#define xdcomp dcomp
#define ydcomp dcomp
#else
static coord_t const xdcomp[] = {0, P, NX};
static coord_t const ydcomp[] = {0, P, NY};
#endif
static coord_t const xdcomp[] = {0, NX, 0, P};
static coord_t const ydcomp[] = {P, 0, NY, 0};
typedef struct ant_s {
coord_t x, y; /* current postion */
coord_t ox, oy; /* previous position, used to dim out old pixels */
unsigned char vector_index; /* index to one of (0,1),(1,0),(0,-1),(-1,0) */
} ant_t;
void ltn_ant() {
clear_screen(0);
struct {
coord_t x, y;
coord_t ox, oy; /* Used to set old pixels to brightness 2 */
coord_t dx, dy; /* Vector can only be (0,1),(1,0),(0,-1),(-1,0) */
} ant;
unsigned char temp;
unsigned int cycles = 500;
ant_t ant;
/* Random start position and direction */
ant.x = random8() % UNUM_COLS;
ant.y = random8() % UNUM_ROWS;
unsigned int cycles = 500;
/* Make sure we do have a valid vector */
ant.dx = xdcomp[random8() % 3];
do {
ant.dy = ydcomp[random8() % 3];
} while(ant.dx == ant.dy);
/* random start position and direction */
ant.x = ant.ox = random8() % UNUM_COLS;
ant.y = ant.oy = random8() % UNUM_ROWS;
ant.ox = ant.x;
ant.oy = ant.y;
/* make sure we have a valid vector */
ant.vector_index = random8() % 4u;
while(cycles != 0) {
/* If the pixel is not set turn it on */
while(cycles--) {
/* if the pixel is turned off turn it on */
if(get_pixel((pixel) {ant.x, ant.y}) == 0) {
setpixel((pixel) {ant.x, ant.y}, 3);
temp = ant.dx;
ant.dx = ant.dy;
ant.dy = -temp; /* Turn 90 degrees to the right */
/* Lets the last pixel be darker than the latest */
if((ant.ox != ant.x) || (ant.oy != ant.y))
setpixel((pixel) {ant.ox, ant.oy}, 2);
setpixel((pixel) {ant.x, ant.y}, NUMPLANE);
ant.vector_index = (ant.vector_index + 3u) % 4u; // turn left
/* dim the previous pixel */
setpixel((pixel){ant.ox, ant.oy}, NUMPLANE - 1);
/* memorize this position */
ant.ox = ant.x;
ant.oy = ant.y;
/* if the pixel is turned on turn it off */
} else {
setpixel((pixel) {ant.x, ant.y}, 0);
temp = ant.dy;
ant.dy = ant.dx;
ant.dx = -temp; /* Turn 90 degrees to the left */
ant.vector_index = (ant.vector_index + 1u) % 4u; // turn right
}
wait(100);
/* move to next pixel, playing field is modeled after a torus */
ant.x = (ant.x + xdcomp[ant.vector_index]) % UNUM_COLS;
ant.y = (ant.y + ydcomp[ant.vector_index]) % UNUM_ROWS;
/* Playing field is modeled after a torus */
ant.x = (coord_t)(ant.x + ant.dx) % UNUM_COLS;
ant.y = (coord_t)(ant.y + ant.dy) % UNUM_ROWS;
cycles--;
wait(100);
}
wait(300);
}

20
src/animations/mherweg.c

@ -126,21 +126,29 @@ static void movinglines()
*/
static void rectangle1()
{
// define a sane maximum expansion
#if NUM_COLS < NUM_ROWS
# define RECT_SIZE NUM_COLS
#else
# define RECT_SIZE NUM_ROWS
#endif
// we want a centered square
unsigned char const xcenter = NUM_COLS / 2, ycenter = NUM_ROWS / 2;
// it should be as big as the borg's height
unsigned char size = NUM_ROWS;
#define RECT_OFFSET_X ((UNUM_COLS - RECT_SIZE) / 2u)
#define RECT_OFFSET_Y ((UNUM_ROWS - RECT_SIZE) / 2u)
unsigned char size = RECT_SIZE;
// darkest color as a starting point for the gradient
unsigned char color = 0;
unsigned char color = 1;
// wait about 500 ms between each frame
int const delay = 500;
// create a gradient by drawing shrinking rectangles on top of each other
clear_screen(0);
for (unsigned char x = 8; x > 0; x--)
for (unsigned char pos = 0; pos < (RECT_SIZE / 2); ++pos)
{
// draw the rectangle and wait for a moment
filled_rectangle((pixel){(xcenter - x), (ycenter - x)},
filled_rectangle((pixel){pos + RECT_OFFSET_X, pos + RECT_OFFSET_Y},
size, size, color);
wait(delay);

31
src/animations/moire.c

@ -25,8 +25,12 @@
void moire(void)
{
// add rotating color map
#if NUMPLANE == 3
#if NUMPLANE == 3 && NUM_COLS == 16 && NUM_ROWS == 16
static unsigned char const gradient[] = {0, 1, 2, 3, 2, 1};
# define WRAP 6u
#elif NUMPLANE == 3 && NUM_COLS == 14 && NUM_ROWS == 9
static unsigned char const gradient[] = {0, 1, 1, 2, 2, 3, 3, 2, 2, 1, 1};
# define WRAP 11u
#else
static unsigned char gradient[NUMPLANE * 2u] = {0};
for (unsigned char i = 1; i <= NUMPLANE; ++i)
@ -34,6 +38,7 @@ void moire(void)
gradient[i] = i;
gradient[(NUMPLANE * 2) - i] = i;
}
# define WRAP (2u * NUMPLANE)
#endif
unsigned int cycles = 30000;
@ -45,25 +50,25 @@ void moire(void)
// walk around the border; do that by mapping a linear increasing value
// to appropriate screen coordinates
// first pixel is between top right and top left corner
if (pos < NUM_COLS)
// pixel is between top right and top left corner
if (pos < (NUM_COLS - 1))
{
p1.x = pos;
p1.x = pos + 1;
}
// first pixel is between top left and bottom left corner
else if (pos < (NUM_COLS + NUM_ROWS - 1))
// pixel is between top left and bottom left corner
else if (pos < (NUM_COLS + NUM_ROWS - 2))
{
p1.y = pos - (NUM_COLS - 1);
p1.y = pos - (NUM_COLS - 2);
}
// first pixel is between bottom left and bottom right corner
else if (pos < (2 * NUM_COLS + NUM_ROWS - 2))
// pixel is between bottom left and bottom right corner
else if (pos < (2 * NUM_COLS + NUM_ROWS - 3))
{
p1.x = 2 * NUM_COLS + NUM_ROWS - 3 - pos;
p1.x = 2 * NUM_COLS + NUM_ROWS - 4 - pos;
}
// first pixel is between bottom right and top left corner
// pixel is between bottom right and top left corner
else
{
p1.y = 3 * NUM_COLS + NUM_ROWS - 4 - pos;
p1.y = 2 * NUM_COLS + 2 * NUM_ROWS - 5 - pos;
}
// second pixel in opposite direction
@ -81,7 +86,7 @@ void moire(void)
wait(40);
}
// ensure the color index keeps within bounds
color_index %= (2u * NUMPLANE);
color_index %= WRAP;
}
}

78
src/animations/program.c

@ -47,45 +47,32 @@ void test_palette2(){
#ifdef ANIMATION_SPIRAL
static void walk(cursor_t* cur, unsigned char steps, int delay){
unsigned char x;
for(x=steps;x--;){
set_cursor(cur, next_pixel(cur->pos, cur->dir));
wait(delay);
}
}
void spiral(int delay){
void spiral(int delay) {
clear_screen(0);
cursor_t cur;
cur.dir = right;
cur.mode = set;
set_cursor (&cur, (pixel){NUM_COLS-1,0});
unsigned char clearbit=0;
while(clearbit == 0){
clearbit = 1;
while (!get_next_pixel(cur.pos, cur.dir)){
clearbit = 0;
walk(&cur, 1, delay);
static signed char const PROGMEM delta[5] = { 0, -1, 0, 1, 0 };
unsigned char length[2] = { NUM_ROWS, NUM_COLS - 1 };
unsigned char x = NUM_COLS - 1, y = NUM_ROWS, i = 0;
while (length[i & 0x01]) {
for (unsigned char j = 0; j < length[i & 0x01]; ++j) {
x += pgm_read_byte(&delta[i]);
y += pgm_read_byte(&delta[i + 1]);
setpixel((pixel){x, y}, NUMPLANE);
wait(delay);
}
cur.dir = direction_r(cur.dir);
length[i++ & 0x01]--;
i %= 4;
}
cur.mode = clear;
set_cursor(&cur, (pixel){(NUM_COLS/2)-1,(NUM_ROWS/2)-1});
for(clearbit=0;clearbit==0;){
if( get_next_pixel(cur.pos, direction_r(cur.dir)) ){
cur.dir = direction_r(cur.dir);
}
if( get_next_pixel(cur.pos, cur.dir) == 1 ){
walk(&cur , 1, delay);
}else{
clearbit = 1;
i = (i + 2u) % 4u;
while (length[0] <= NUM_ROWS && length[1] < NUM_COLS) {
for (unsigned char j = 0; j < length[i & 0x01]; ++j) {
setpixel((pixel){x, y}, 0);
x += pgm_read_byte(&delta[i]);
y += pgm_read_byte(&delta[i + 1]);
wait(delay);
}
length[(i += 3) & 0x01]++;
i %= 4;
}
}
#endif
@ -179,17 +166,18 @@ void fire()
* void random_bright(void)
* by Daniel Otte
*/
void random_bright(unsigned cycles){
uint8_t t,x,y;
while(cycles--){
for(y=0; y<NUM_ROWS; ++y)
for(x=0; x<NUM_COLS/4; ++x){
t=random8();
setpixel((pixel){x*4+0, y}, 0x3&(t>>0));
setpixel((pixel){x*4+1, y}, 0x3&(t>>2));
setpixel((pixel){x*4+2, y}, 0x3&(t>>4));
setpixel((pixel){x*4+3, y}, 0x3&(t>>6));
void random_bright(unsigned int cycles) {
while (cycles--) {
for (unsigned char p = NUMPLANE; p--;) {
for (unsigned char y = NUM_ROWS; y--;) {
for (unsigned char x = LINEBYTES; x--;) {
if (p < (NUMPLANE - 1)) {
pixmap[p][y][x] |= pixmap[p + 1][y][x];
}
pixmap[p][y][x] = random8();
}
}
}
wait(200);
}
}

4
src/borg_hw/Makefile

@ -27,6 +27,10 @@ ifeq ($(BORG_HW),HW_BORG_MH)
SRC = borg_hw_borg_mh.c
endif
ifeq ($(BORG_HW),HW_LOLSHIELD)
SRC = borg_hw_lolshield.c
endif
ifeq ($(BORG_HW),HW_BORG_LSJO)
SRC = borg_hw_borg_lsjo.c
endif

923
src/borg_hw/borg_hw_lolshield.c

@ -0,0 +1,923 @@
/**
* @file borg_hw_lolshield.c
* @brief Driver for Jimmie Rodgers' LoL Shield
* @author Christian Kroll
* @author Jimmie Rodgers
* @date 2014
* @copyright GNU Public License 2 or later
* @see http://jimmieprodgers.com/kits/lolshield/
*
* This driver is partly based on Jimmie Rodger's LoL Shield Library which
* is available at https://code.google.com/p/lolshield/ (parts of the file
* "Charliplexing.cpp" have been incorporated into this file).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "../config.h"
#include "../makros.h"
#include <stdint.h>
#include <avr/interrupt.h>
#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/pgmspace.h>
#if NUMPLANE >= 8
# include <math.h>
#endif
#include "borg_hw.h"
// buffer which holds the currently shown frame
unsigned char pixmap[NUMPLANE][NUM_ROWS][LINEBYTES];
// Number of ticks of the prescaled timer per cycle per frame, based on the
// CPU clock speed and the desired frame rate.
#define FRAMERATE 80UL
#define TICKS (F_CPU + 6 * (FRAMERATE << SLOWSCALERSHIFT)) / (12 * (FRAMERATE << SLOWSCALERSHIFT))
#define CUTOFF(scaler) ((128 * 12 - 6) * FRAMERATE * scaler)
#if defined (__AVR_ATmega168__) || defined (__AVR_ATmega48__) || defined (__AVR_ATmega88__) || defined (__AVR_ATmega328P__) || defined (__AVR_ATmega1280__) || defined (__AVR_ATmega2560__) || defined (__AVR_ATmega8__)
# if F_CPU < CUTOFF(8)
# define FASTPRESCALER (_BV(CS20)) // 1
# define SLOWPRESCALER (_BV(CS21)) // 8
# define FASTSCALERSHIFT 3
# define SLOWSCALERSHIFT 3
# elif F_CPU < CUTOFF(32)
# define FASTPRESCALER (_BV(CS21)) // 8
# define SLOWPRESCALER (_BV(CS21) | _BV(CS20)) // 32
# define FASTSCALERSHIFT 2
# define SLOWSCALERSHIFT 5
# elif F_CPU < CUTOFF(64)
# define FASTPRESCALER (_BV(CS21)) // 8
# define SLOWPRESCALER (_BV(CS22)) // 64
# define FASTSCALERSHIFT 3
# define SLOWSCALERSHIFT 6
# elif F_CPU < CUTOFF(128)
# define FASTPRESCALER (_BV(CS21) | _BV(CS20)) // 32
# define SLOWPRESCALER (_BV(CS22) | _BV(CS20)) // 128
# define FASTSCALERSHIFT 2
# define SLOWSCALERSHIFT 7
# elif F_CPU < CUTOFF(256)
# define FASTPRESCALER (_BV(CS21) | _BV(CS20)) // 32
# define SLOWPRESCALER (_BV(CS22) | _BV(CS21)) // 256
# define FASTSCALERSHIFT 3
# define SLOWSCALERSHIFT 8
# elif F_CPU < CUTOFF(1024)
# define FASTPRESCALER (_BV(CS22) | _BV(CS20)) // 128
# define SLOWPRESCALER (_BV(CS22) | _BV(CS21) | _BV(CS20)) // 1024
# define FASTSCALERSHIFT 3
# define SLOWSCALERSHIFT 10
# else
# error frame rate is too low
# endif
#elif defined (__AVR_ATmega32U4__)
# if F_CPU < CUTOFF(8)
# define FASTPRESCALER (_BV(WGM12) | _BV(CS10)) // 1
# define SLOWPRESCALER (_BV(WGM12) | _BV(CS11)) // 8
# define FASTSCALERSHIFT 3
# define SLOWSCALERSHIFT 3
# elif F_CPU < CUTOFF(64)
# define FASTPRESCALER (_BV(WGM12) | _BV(CS11)) // 8
# define SLOWPRESCALER (_BV(WGM12) | _BV(CS11) | _BV(CS10)) // 64
# define FASTSCALERSHIFT 3
# define SLOWSCALERSHIFT 6
# elif F_CPU < CUTOFF(256)
# define FASTPRESCALER (_BV(WGM12) | _BV(CS11) | _BV(CS10)) // 64
# define SLOWPRESCALER (_BV(WGM12) | _BV(CS12)) // 256
# define FASTSCALERSHIFT 2
# define SLOWSCALERSHIFT 8
# elif F_CPU < CUTOFF(1024)
# define FASTPRESCALER (_BV(WGM12) | _BV(CS12)) // 256
# define SLOWPRESCALER (_BV(WGM12) | _BV(CS12) | _BV(CS10)) // 1024
# define FASTSCALERSHIFT 2
# define SLOWSCALERSHIFT 10
# else
# error frame rate is too low
# endif
#else
# error no support for this chip
#endif
#ifndef BRIGHTNESS
# define BRIGHTNESS 127 /* full brightness by default */
#elif BRIGHTNESS < 0 || BRIGHTNESS > 127
# error BRIGHTNESS must be between 0 and 127
#endif
#define BRIGHTNESSPERCENT ((BRIGHTNESS * BRIGHTNESS + 8ul) / 16ul)
#define M (TICKS << FASTSCALERSHIFT) * BRIGHTNESSPERCENT /*10b*/
#define C(x) ((M * (unsigned long)(x * 1024) + (1 << 19)) >> 20) /*10b+10b-20b=0b*/
#if NUMPLANE < 8
uint8_t const prescaler[NUMPLANE + 1] = {
FASTPRESCALER,
# if NUMPLANE >= 2
FASTPRESCALER,
# endif
# if NUMPLANE >= 3
FASTPRESCALER,
# endif
# if NUMPLANE >= 4
FASTPRESCALER,
# endif
# if NUMPLANE >= 5
FASTPRESCALER,
# endif
# if NUMPLANE >= 6
FASTPRESCALER,
# endif
# if NUMPLANE >= 7
FASTPRESCALER,
# endif
SLOWPRESCALER
};
#else
uint8_t prescaler[NUMPLANE + 1] = {0};
#endif
uint8_t counts[NUMPLANE + 1] = {0};
/**
* Set the overall brightness of the screen from 0 (off) to 127 (full on).
*/
static void setBrightness()
{
/* ---- This needs review! Please review. -- thilo */
// set up page counts
uint8_t i;
// NOTE: The argument of C() is calculated as follows:
// pow((double)x / (double)NUMPLANE, 1.8) with 0 <= x <= NUMPLANE
// Changing the scale of 1.8 invalidates any tables above!
#if NUMPLANE < 8
int const temp_counts[NUMPLANE + 1] = {
0.000000000000000000000000000,
# if NUMPLANE == 2
C(0.287174588749258719033719),
# elif NUMPLANE == 3
C(0.138414548846168578011273),
C(0.481987453865643789008288),
# elif NUMPLANE == 4
C(0.082469244423305887448095),
C(0.287174588749258719033719),
C(0.595813410589956848895099),
# elif NUMPLANE == 5
C(0.055189186458448592775827),
C(0.192179909437029006191722),
C(0.398723883569384374148115),
C(0.669209313658414961523135),
# elif NUMPLANE == 6
C(0.039749141141812646682574),
C(0.138414548846168578011273),
C(0.287174588749258719033719),
C(0.481987453865643789008288),
C(0.720234228706005730202833),
# elif NUMPLANE == 7
C(0.030117819624378608378557),
C(0.104876339357015443964904),
C(0.217591430058779483625031),
C(0.365200625214741059210155),
C(0.545719579451565794947498),
C(0.757697368024318751444923),
# endif
C(1.000000000000000000000000),
};
#else
# warning "NUMPLANE >= 8 links floating point stuff into the image"
// NOTE: Changing "scale" invalidates any tables above!
const float scale = 1.8f;
int temp_counts[NUMPLANE + 1] = {0};
for (i = 1; i < (NUMPLANE + 1); i++) {
temp_counts[i] = C(pow(i / (float)(NUMPLANE), scale));
}
#endif
// Compute on time for each of the pages
// Use the fast timer; slow timer is only useful for < 3 shades.
for (i = 0; i < NUMPLANE; i++) {
int interval = temp_counts[i + 1] - temp_counts[i];
counts[i] = 256 - (interval ? interval : 1);
#if NUMPLANE >= 8
prescaler[i] = FASTPRESCALER;
#endif
}
// Compute off time
int interval = TICKS - (temp_counts[i] >> FASTSCALERSHIFT);
counts[i] = 256 - (interval ? interval : 1);
#if NUMPLANE >= 8
prescaler[i] = SLOWPRESCALER;
#endif
}
/**
* Distributes the framebuffer content among current cycle pins.
* @param cycle The cycle whose pattern should to be composed.
* @param plane The plane ("page" in LoL Shield lingo) to be drawn.
*/
static void compose_cycle(uint8_t const cycle, uint8_t plane) {
// pointer to corresponding bitmap
uint8_t *const p = &pixmap[plane][0][0];
#if defined (__AVR_ATmega1280__) || defined (__AVR_ATmega2560__)
# ifdef __AVR_ATmega1280__
# warning "BEWARE: Borgware-2D has not been tested on Arduino Mega 1280!"
# endif
// Set sink pin to Vcc/source, turning off current.
static uint8_t sink_b = 0, sink_e = 0, sink_g = 0, sink_h = 0;
PINB = sink_b;
PINE = sink_e;
PING = sink_g;
PINH = sink_h;
DDRB &= ~0xf0;
DDRE &= ~0x38;
DDRG &= ~0x20;
DDRH &= ~0x78;
static uint8_t const PROGMEM sink_b_cycle[] =
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x40, 0x80};
static uint8_t const PROGMEM sink_e_cycle[] =
{0x10, 0x20, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
static uint8_t const PROGMEM sink_g_cycle[] =
{0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
static uint8_t const PROGMEM sink_h_cycle[] =
{0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00};
uint8_t pins_b = sink_b = pgm_read_byte(&sink_b_cycle[cycle]);
uint8_t pins_e = sink_e = pgm_read_byte(&sink_e_cycle[cycle]);
uint8_t pins_g = sink_g = pgm_read_byte(&sink_g_cycle[cycle]);
uint8_t pins_h = sink_h = pgm_read_byte(&sink_h_cycle[cycle]);
// convert framebuffer to LoL Shield cycles on Arduino Mega 1280/2560
// (I could have done this with a lookup table, but that would be slower as
// non-constant bit shifts are quite expensive on AVR)
// NOTE: (0,0) is UPPER RIGHT in the Borgware realm
if (plane < NUMPLANE) {
switch(cycle) {
case 0:
pins_b |= (0x02u & p[ 0]) << 6; // x= 1, y= 0, mapped pin D13
pins_b |= (0x02u & p[ 2]) << 5; // x= 1, y= 1, mapped pin D12
pins_b |= (0x02u & p[ 4]) << 4; // x= 1, y= 2, mapped pin D11
pins_b |= (0x02u & p[ 6]) << 3; // x= 1, y= 3, mapped pin D10
pins_e |= (0x02u & p[16]) << 2; // x= 1, y= 8, mapped pin D5
pins_h |= (0x02u & p[ 8]) << 5; // x= 1, y= 4, mapped pin D9
pins_h |= (0x02u & p[10]) << 4; // x= 1, y= 5, mapped pin D8
pins_h |= (0x02u & p[12]) << 3; // x= 1, y= 6, mapped pin D7
pins_h |= (0x02u & p[14]) << 2; // x= 1, y= 7, mapped pin D6
break;
case 1:
pins_b |= (0x08u & p[ 0]) << 4; // x= 3, y= 0, mapped pin D13
pins_b |= (0x08u & p[ 2]) << 3; // x= 3, y= 1, mapped pin D12
pins_b |= (0x08u & p[ 4]) << 2; // x= 3, y= 2, mapped pin D11
pins_b |= (0x08u & p[ 6]) << 1; // x= 3, y= 3, mapped pin D10
pins_e |= (0x08u & p[16]); // x= 3, y= 8, mapped pin D5
pins_h |= (0x08u & p[ 8]) << 3; // x= 3, y= 4, mapped pin D9
pins_h |= (0x08u & p[10]) << 2; // x= 3, y= 5, mapped pin D8
pins_h |= (0x08u & p[12]) << 1; // x= 3, y= 6, mapped pin D7
pins_h |= (0x08u & p[14]); // x= 3, y= 7, mapped pin D6
break;
case 2:
pins_b |= (0x20u & p[ 0]) << 2; // x= 5, y= 0, mapped pin D13
pins_b |= (0x20u & p[ 2]) << 1; // x= 5, y= 1, mapped pin D12
pins_b |= (0x20u & p[ 4]); // x= 5, y= 2, mapped pin D11
pins_b |= (0x20u & p[ 6]) >> 1; // x= 5, y= 3, mapped pin D10
pins_e |= (0x20u & p[16]) >> 2; // x= 5, y= 8, mapped pin D5
pins_h |= (0x20u & p[ 8]) << 1; // x= 5, y= 4, mapped pin D9
pins_h |= (0x20u & p[10]); // x= 5, y= 5, mapped pin D8
pins_h |= (0x20u & p[12]) >> 1; // x= 5, y= 6, mapped pin D7
pins_h |= (0x20u & p[14]) >> 2; // x= 5, y= 7, mapped pin D6
break;
case 3:
pins_b |= (0x20u & p[ 1]) << 2; // x=13, y= 0, mapped pin D13
pins_b |= (0x20u & p[ 3]) << 1; // x=13, y= 1, mapped pin D12
pins_b |= (0x20u & p[ 5]); // x=13, y= 2, mapped pin D11
pins_b |= (0x20u & p[ 7]) >> 1; // x=13, y= 3, mapped pin D10
pins_e |= (0x01u & p[16]) << 4; // x= 0, y= 8, mapped pin D2
pins_e |= (0x04u & p[16]) << 3; // x= 2, y= 8, mapped pin D3
pins_g |= (0x10u & p[16]) << 1; // x= 4, y= 8, mapped pin D4
pins_h |= (0x20u & p[ 9]) << 1; // x=13, y= 4, mapped pin D9
pins_h |= (0x20u & p[11]); // x=13, y= 5, mapped pin D8
pins_h |= (0x20u & p[13]) >> 1; // x=13, y= 6, mapped pin D7
pins_h |= (0x20u & p[15]) >> 2; // x=13, y= 7, mapped pin D6
break;
case 4:
pins_b |= (0x10u & p[ 1]) << 3; // x=12, y= 0, mapped pin D13
pins_b |= (0x10u & p[ 3]) << 2; // x=12, y= 1, mapped pin D12
pins_b |= (0x10u & p[ 5]) << 1; // x=12, y= 2, mapped pin D11
pins_b |= (0x10u & p[ 7]); // x=12, y= 3, mapped pin D10
pins_e |= (0x01u & p[14]) << 4; // x= 0, y= 7, mapped pin D2
pins_e |= (0x04u & p[14]) << 3; // x= 2, y= 7, mapped pin D3
pins_e |= (0x20u & p[17]) >> 2; // x=13, y= 8, mapped pin D5
pins_g |= (0x10u & p[14]) << 1; // x= 4, y= 7, mapped pin D4
pins_h |= (0x10u & p[ 9]) << 2; // x=12, y= 4, mapped pin D9
pins_h |= (0x10u & p[11]) << 1; // x=12, y= 5, mapped pin D8
pins_h |= (0x10u & p[13]); // x=12, y= 6, mapped pin D7
break;
case 5:
pins_b |= (0x08u & p[ 1]) << 4; // x=11, y= 0, mapped pin D13
pins_b |= (0x08u & p[ 3]) << 3; // x=11, y= 1, mapped pin D12
pins_b |= (0x08u & p[ 5]) << 2; // x=11, y= 2, mapped pin D11
pins_b |= (0x08u & p[ 7]) << 1; // x=11, y= 3, mapped pin D10
pins_e |= (0x01u & p[12]) << 4; // x= 0, y= 6, mapped pin D2
pins_e |= (0x04u & p[12]) << 3; // x= 2, y= 6, mapped pin D3
pins_e |= (0x10u & p[17]) >> 1; // x=12, y= 8, mapped pin D5
pins_g |= (0x10u & p[12]) << 1; // x= 4, y= 6, mapped pin D4
pins_h |= (0x08u & p[ 9]) << 3; // x=11, y= 4, mapped pin D9
pins_h |= (0x08u & p[11]) << 2; // x=11, y= 5, mapped pin D8
pins_h |= (0x10u & p[15]) >> 1; // x=12, y= 7, mapped pin D6
break;
case 6:
pins_b |= (0x04u & p[ 1]) << 5; // x=10, y= 0, mapped pin D13
pins_b |= (0x04u & p[ 3]) << 4; // x=10, y= 1, mapped pin D12
pins_b |= (0x04u & p[ 5]) << 3; // x=10, y= 2, mapped pin D11
pins_b |= (0x04u & p[ 7]) << 2; // x=10, y= 3, mapped pin D10
pins_e |= (0x01u & p[10]) << 4; // x= 0, y= 5, mapped pin D2
pins_e |= (0x04u & p[10]) << 3; // x= 2, y= 5, mapped pin D3
pins_e |= (0x08u & p[17]); // x=11, y= 8, mapped pin D5
pins_g |= (0x10u & p[10]) << 1; // x= 4, y= 5, mapped pin D4
pins_h |= (0x04u & p[ 9]) << 4; // x=10, y= 4, mapped pin D9
pins_h |= (0x08u & p[13]) << 1; // x=11, y= 6, mapped pin D7
pins_h |= (0x08u & p[15]); // x=11, y= 7, mapped pin D6
break;
case 7:
pins_b |= (0x02u & p[ 1]) << 6; // x= 9, y= 0, mapped pin D13
pins_b |= (0x02u & p[ 3]) << 5; // x= 9, y= 1, mapped pin D12
pins_b |= (0x02u & p[ 5]) << 4; // x= 9, y= 2, mapped pin D11
pins_b |= (0x02u & p[ 7]) << 3; // x= 9, y= 3, mapped pin D10
pins_e |= (0x01u & p[ 8]) << 4; // x= 0, y= 4, mapped pin D2
pins_e |= (0x04u & p[ 8]) << 3; // x= 2, y= 4, mapped pin D3
pins_e |= (0x04u & p[17]) << 1; // x=10, y= 8, mapped pin D5
pins_g |= (0x10u & p[ 8]) << 1; // x= 4, y= 4, mapped pin D4
pins_h |= (0x04u & p[11]) << 3; // x=10, y= 5, mapped pin D8
pins_h |= (0x04u & p[13]) << 2; // x=10, y= 6, mapped pin D7
pins_h |= (0x04u & p[15]) << 1; // x=10, y= 7, mapped pin D6
break;
case 8:
pins_b |= (0x01u & p[ 1]) << 7; // x= 8, y= 0, mapped pin D13
pins_b |= (0x01u & p[ 3]) << 6; // x= 8, y= 1, mapped pin D12
pins_b |= (0x01u & p[ 5]) << 5; // x= 8, y= 2, mapped pin D11
pins_e |= (0x01u & p[ 6]) << 4; // x= 0, y= 3, mapped pin D2
pins_e |= (0x02u & p[17]) << 2; // x= 9, y= 8, mapped pin D5
pins_e |= (0x04u & p[ 6]) << 3; // x= 2, y= 3, mapped pin D3
pins_g |= (0x10u & p[ 6]) << 1; // x= 4, y= 3, mapped pin D4
pins_h |= (0x02u & p[ 9]) << 5; // x= 9, y= 4, mapped pin D9
pins_h |= (0x02u & p[11]) << 4; // x= 9, y= 5, mapped pin D8
pins_h |= (0x02u & p[13]) << 3; // x= 9, y= 6, mapped pin D7
pins_h |= (0x02u & p[15]) << 2; // x= 9, y= 7, mapped pin D6
break;
case 9:
pins_b |= (0x01u & p[ 7]) << 4; // x= 8, y= 3, mapped pin D10
pins_b |= (0x80u & p[ 0]); // x= 7, y= 0, mapped pin D13
pins_b |= (0x80u & p[ 2]) >> 1; // x= 7, y= 1, mapped pin D12
pins_e |= (0x01u & p[ 4]) << 4; // x= 0, y= 2, mapped pin D2
pins_e |= (0x01u & p[17]) << 3; // x= 8, y= 8, mapped pin D5
pins_e |= (0x04u & p[ 4]) << 3; // x= 2, y= 2, mapped pin D3
pins_g |= (0x10u & p[ 4]) << 1; // x= 4, y= 2, mapped pin D4
pins_h |= (0x01u & p[ 9]) << 6; // x= 8, y= 4, mapped pin D9
pins_h |= (0x01u & p[11]) << 5; // x= 8, y= 5, mapped pin D8
pins_h |= (0x01u & p[13]) << 4; // x= 8, y= 6, mapped pin D7
pins_h |= (0x01u & p[15]) << 3; // x= 8, y= 7, mapped pin D6
break;
case 10:
pins_b |= (0x40u & p[ 0]) << 1; // x= 6, y= 0, mapped pin D13
pins_b |= (0x80u & p[ 4]) >> 2; // x= 7, y= 2, mapped pin D11
pins_b |= (0x80u & p[ 6]) >> 3; // x= 7, y= 3, mapped pin D10
pins_e |= (0x01u & p[ 2]) << 4; // x= 0, y= 1, mapped pin D2
pins_e |= (0x04u & p[ 2]) << 3; // x= 2, y= 1, mapped pin D3
pins_e |= (0x80u & p[16]) >> 4; // x= 7, y= 8, mapped pin D5
pins_g |= (0x10u & p[ 2]) << 1; // x= 4, y= 1, mapped pin D4
pins_h |= (0x80u & p[ 8]) >> 1; // x= 7, y= 4, mapped pin D9
pins_h |= (0x80u & p[10]) >> 2; // x= 7, y= 5, mapped pin D8
pins_h |= (0x80u & p[12]) >> 3; // x= 7, y= 6, mapped pin D7
pins_h |= (0x80u & p[14]) >> 4; // x= 7, y= 7, mapped pin D6
break;
case 11:
pins_b |= (0x40u & p[ 2]); // x= 6, y= 1, mapped pin D12
pins_b |= (0x40u & p[ 4]) >> 1; // x= 6, y= 2, mapped pin D11
pins_b |= (0x40u & p[ 6]) >> 2; // x= 6, y= 3, mapped pin D10
pins_e |= (0x01u & p[ 0]) << 4; // x= 0, y= 0, mapped pin D2
pins_e |= (0x04u & p[ 0]) << 3; // x= 2, y= 0, mapped pin D3
pins_e |= (0x40u & p[16]) >> 3; // x= 6, y= 8, mapped pin D5
pins_g |= (0x10u & p[ 0]) << 1; // x= 4, y= 0, mapped pin D4
pins_h |= (0x40u & p[ 8]); // x= 6, y= 4, mapped pin D9
pins_h |= (0x40u & p[10]) >> 1; // x= 6, y= 5, mapped pin D8
pins_h |= (0x40u & p[12]) >> 2; // x= 6, y= 6, mapped pin D7
pins_h |= (0x40u & p[14]) >> 3; // x= 6, y= 7, mapped pin D6
break;
}
}
// Enable pullups (by toggling) on new output pins.
PINB = PORTB ^ pins_b;
PINE = PORTE ^ pins_e;
PING = PORTG ^ pins_g;
PINH = PORTH ^ pins_h;
// Set pins to output mode; pullups become Vcc/source.
DDRB |= pins_b;
DDRE |= pins_e;
DDRG |= pins_g;
DDRH |= pins_h;
// Set sink pin to GND/sink, turning on current.
PINB = sink_b;
PINE = sink_e;
PING = sink_g;
PINH = sink_h;
#elif defined (__AVR_ATmega32U4__)
// Set sink pin to Vcc/source, turning off current.
static uint8_t sink_b = 0, sink_c = 0, sink_d = 0, sink_e = 0;
PINB = sink_b;
PINC = sink_c;
PIND = sink_d;
PINE = sink_e;
DDRB &= ~0xF0;
DDRC &= ~0xC0;
DDRD &= ~0xD3;
DDRE &= ~0x40;
static uint8_t const PROGMEM sink_b_cycle[] =
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00};
static uint8_t const PROGMEM sink_c_cycle[] =
{0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80};
static uint8_t const PROGMEM sink_d_cycle[] =
{0x02, 0x01, 0x10, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00};
static uint8_t const PROGMEM sink_e_cycle[] =
{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t pins_b = sink_b = pgm_read_byte(&sink_b_cycle[cycle]);
uint8_t pins_c = sink_c = pgm_read_byte(&sink_c_cycle[cycle]);
uint8_t pins_d = sink_d = pgm_read_byte(&sink_d_cycle[cycle]);
uint8_t pins_e = sink_e = pgm_read_byte(&sink_e_cycle[cycle]);
// convert Borgware-2D framebuffer to LoL Shield cycles on Arduino Leonardo
// (I could have done this with a lookup table, but that would be slower as
// non-constant bit shifts are quite expensive on AVR)
// NOTE: (0,0) is UPPER RIGHT in the Borgware realm
if (plane < NUMPLANE) {
switch(cycle) {
case 0:
pins_b |= (0x02u & p[ 4]) << 6; // x= 1, y= 2, mapped pin D11
pins_b |= (0x02u & p[ 6]) << 5; // x= 1, y= 3, mapped pin D10
pins_b |= (0x02u & p[ 8]) << 4; // x= 1, y= 4, mapped pin D9
pins_b |= (0x02u & p[10]) << 3; // x= 1, y= 5, mapped pin D8
pins_c |= (0x02u & p[ 0]) << 6; // x= 1, y= 0, mapped pin D13
pins_c |= (0x02u & p[16]) << 5; // x= 1, y= 8, mapped pin D5
pins_d |= (0x02u & p[ 2]) << 5; // x= 1, y= 1, mapped pin D12
pins_d |= (0x02u & p[14]) << 6; // x= 1, y= 7, mapped pin D6
pins_e |= (0x02u & p[12]) << 5; // x= 1, y= 6, mapped pin D7
break;
case 1:
pins_b |= (0x08u & p[ 4]) << 4; // x= 3, y= 2, mapped pin D11
pins_b |= (0x08u & p[ 6]) << 3; // x= 3, y= 3, mapped pin D10
pins_b |= (0x08u & p[ 8]) << 2; // x= 3, y= 4, mapped pin D9
pins_b |= (0x08u & p[10]) << 1; // x= 3, y= 5, mapped pin D8
pins_c |= (0x08u & p[ 0]) << 4; // x= 3, y= 0, mapped pin D13
pins_c |= (0x08u & p[16]) << 3; // x= 3, y= 8, mapped pin D5
pins_d |= (0x08u & p[ 2]) << 3; // x= 3, y= 1, mapped pin D12
pins_d |= (0x08u & p[14]) << 4; // x= 3, y= 7, mapped pin D6
pins_e |= (0x08u & p[12]) << 3; // x= 3, y= 6, mapped pin D7
break;
case 2:
pins_b |= (0x20u & p[ 4]) << 2; // x= 5, y= 2, mapped pin D11
pins_b |= (0x20u & p[ 6]) << 1; // x= 5, y= 3, mapped pin D10
pins_b |= (0x20u & p[ 8]); // x= 5, y= 4, mapped pin D9
pins_b |= (0x20u & p[10]) >> 1; // x= 5, y= 5, mapped pin D8
pins_c |= (0x20u & p[ 0]) << 2; // x= 5, y= 0, mapped pin D13
pins_c |= (0x20u & p[16]) << 1; // x= 5, y= 8, mapped pin D5
pins_d |= (0x20u & p[ 2]) << 1; // x= 5, y= 1, mapped pin D12
pins_d |= (0x20u & p[14]) << 2; // x= 5, y= 7, mapped pin D6
pins_e |= (0x20u & p[12]) << 1; // x= 5, y= 6, mapped pin D7
break;
case 3:
pins_b |= (0x20u & p[ 5]) << 2; // x=13, y= 2, mapped pin D11
pins_b |= (0x20u & p[ 7]) << 1; // x=13, y= 3, mapped pin D10
pins_b |= (0x20u & p[ 9]); // x=13, y= 4, mapped pin D9
pins_b |= (0x20u & p[11]) >> 1; // x=13, y= 5, mapped pin D8
pins_c |= (0x20u & p[ 1]) << 2; // x=13, y= 0, mapped pin D13
pins_d |= (0x01u & p[16]) << 1; // x= 0, y= 8, mapped pin D2
pins_d |= (0x04u & p[16]) >> 2; // x= 2, y= 8, mapped pin D3
pins_d |= (0x10u & p[16]); // x= 4, y= 8, mapped pin D4
pins_d |= (0x20u & p[ 3]) << 1; // x=13, y= 1, mapped pin D12
pins_d |= (0x20u & p[15]) << 2; // x=13, y= 7, mapped pin D6
pins_e |= (0x20u & p[13]) << 1; // x=13, y= 6, mapped pin D7
break;
case 4:
pins_b |= (0x10u & p[ 5]) << 3; // x=12, y= 2, mapped pin D11
pins_b |= (0x10u & p[ 7]) << 2; // x=12, y= 3, mapped pin D10
pins_b |= (0x10u & p[ 9]) << 1; // x=12, y= 4, mapped pin D9
pins_b |= (0x10u & p[11]); // x=12, y= 5, mapped pin D8
pins_c |= (0x10u & p[ 1]) << 3; // x=12, y= 0, mapped pin D13
pins_c |= (0x20u & p[17]) << 1; // x=13, y= 8, mapped pin D5
pins_d |= (0x01u & p[14]) << 1; // x= 0, y= 7, mapped pin D2
pins_d |= (0x04u & p[14]) >> 2; // x= 2, y= 7, mapped pin D3
pins_d |= (0x10u & p[ 3]) << 2; // x=12, y= 1, mapped pin D12
pins_d |= (0x10u & p[14]); // x= 4, y= 7, mapped pin D4
pins_e |= (0x10u & p[13]) << 2; // x=12, y= 6, mapped pin D7
break;
case 5:
pins_b |= (0x08u & p[ 5]) << 4; // x=11, y= 2, mapped pin D11
pins_b |= (0x08u & p[ 7]) << 3; // x=11, y= 3, mapped pin D10
pins_b |= (0x08u & p[ 9]) << 2; // x=11, y= 4, mapped pin D9
pins_b |= (0x08u & p[11]) << 1; // x=11, y= 5, mapped pin D8
pins_c |= (0x08u & p[ 1]) << 4; // x=11, y= 0, mapped pin D13
pins_c |= (0x10u & p[17]) << 2; // x=12, y= 8, mapped pin D5
pins_d |= (0x01u & p[12]) << 1; // x= 0, y= 6, mapped pin D2
pins_d |= (0x04u & p[12]) >> 2; // x= 2, y= 6, mapped pin D3
pins_d |= (0x08u & p[ 3]) << 3; // x=11, y= 1, mapped pin D12
pins_d |= (0x10u & p[12]); // x= 4, y= 6, mapped pin D4
pins_d |= (0x10u & p[15]) << 3; // x=12, y= 7, mapped pin D6
break;
case 6:
pins_b |= (0x04u & p[ 5]) << 5; // x=10, y= 2, mapped pin D11
pins_b |= (0x04u & p[ 7]) << 4; // x=10, y= 3, mapped pin D10
pins_b |= (0x04u & p[ 9]) << 3; // x=10, y= 4, mapped pin D9
pins_c |= (0x04u & p[ 1]) << 5; // x=10, y= 0, mapped pin D13
pins_c |= (0x08u & p[17]) << 3; // x=11, y= 8, mapped pin D5
pins_d |= (0x01u & p[10]) << 1; // x= 0, y= 5, mapped pin D2
pins_d |= (0x04u & p[ 3]) << 4; // x=10, y= 1, mapped pin D12
pins_d |= (0x04u & p[10]) >> 2; // x= 2, y= 5, mapped pin D3
pins_d |= (0x08u & p[15]) << 4; // x=11, y= 7, mapped pin D6
pins_d |= (0x10u & p[10]); // x= 4, y= 5, mapped pin D4
pins_e |= (0x08u & p[13]) << 3; // x=11, y= 6, mapped pin D7
break;
case 7:
pins_b |= (0x02u & p[ 5]) << 6; // x= 9, y= 2, mapped pin D11
pins_b |= (0x02u & p[ 7]) << 5; // x= 9, y= 3, mapped pin D10
pins_b |= (0x04u & p[11]) << 2; // x=10, y= 5, mapped pin D8
pins_c |= (0x02u & p[ 1]) << 6; // x= 9, y= 0, mapped pin D13
pins_c |= (0x04u & p[17]) << 4; // x=10, y= 8, mapped pin D5
pins_d |= (0x01u & p[ 8]) << 1; // x= 0, y= 4, mapped pin D2
pins_d |= (0x02u & p[ 3]) << 5; // x= 9, y= 1, mapped pin D12
pins_d |= (0x04u & p[ 8]) >> 2; // x= 2, y= 4, mapped pin D3
pins_d |= (0x04u & p[15]) << 5; // x=10, y= 7, mapped pin D6
pins_d |= (0x10u & p[ 8]); // x= 4, y= 4, mapped pin D4
pins_e |= (0x04u & p[13]) << 4; // x=10, y= 6, mapped pin D7
break;
case 8:
pins_b |= (0x01u & p[ 5]) << 7; // x= 8, y= 2, mapped pin D11
pins_b |= (0x02u & p[ 9]) << 4; // x= 9, y= 4, mapped pin D9
pins_b |= (0x02u & p[11]) << 3; // x= 9, y= 5, mapped pin D8
pins_c |= (0x01u & p[ 1]) << 7; // x= 8, y= 0, mapped pin D13
pins_c |= (0x02u & p[17]) << 5; // x= 9, y= 8, mapped pin D5
pins_d |= (0x01u & p[ 3]) << 6; // x= 8, y= 1, mapped pin D12
pins_d |= (0x01u & p[ 6]) << 1; // x= 0, y= 3, mapped pin D2
pins_d |= (0x02u & p[15]) << 6; // x= 9, y= 7, mapped pin D6
pins_d |= (0x04u & p[ 6]) >> 2; // x= 2, y= 3, mapped pin D3
pins_d |= (0x10u & p[ 6]); // x= 4, y= 3, mapped pin D4
pins_e |= (0x02u & p[13]) << 5; // x= 9, y= 6, mapped pin D7
break;
case 9:
pins_b |= (0x01u & p[ 7]) << 6; // x= 8, y= 3, mapped pin D10
pins_b |= (0x01u & p[ 9]) << 5; // x= 8, y= 4, mapped pin D9
pins_b |= (0x01u & p[11]) << 4; // x= 8, y= 5, mapped pin D8
pins_c |= (0x01u & p[17]) << 6; // x= 8, y= 8, mapped pin D5
pins_c |= (0x80u & p[ 0]); // x= 7, y= 0, mapped pin D13
pins_d |= (0x01u & p[ 4]) << 1; // x= 0, y= 2, mapped pin D2
pins_d |= (0x01u & p[15]) << 7; // x= 8, y= 7, mapped pin D6
pins_d |= (0x04u & p[ 4]) >> 2; // x= 2, y= 2, mapped pin D3
pins_d |= (0x10u & p[ 4]); // x= 4, y= 2, mapped pin D4
pins_d |= (0x80u & p[ 2]) >> 1; // x= 7, y= 1, mapped pin D12
pins_e |= (0x01u & p[13]) << 6; // x= 8, y= 6, mapped pin D7
break;
case 10:
pins_b |= (0x80u & p[ 4]); // x= 7, y= 2, mapped pin D11
pins_b |= (0x80u & p[ 6]) >> 1; // x= 7, y= 3, mapped pin D10
pins_b |= (0x80u & p[ 8]) >> 2; // x= 7, y= 4, mapped pin D9
pins_b |= (0x80u & p[10]) >> 3; // x= 7, y= 5, mapped pin D8
pins_c |= (0x40u & p[ 0]) << 1; // x= 6, y= 0, mapped pin D13
pins_c |= (0x80u & p[16]) >> 1; // x= 7, y= 8, mapped pin D5
pins_d |= (0x01u & p[ 2]) << 1; // x= 0, y= 1, mapped pin D2
pins_d |= (0x04u & p[ 2]) >> 2; // x= 2, y= 1, mapped pin D3
pins_d |= (0x10u & p[ 2]); // x= 4, y= 1, mapped pin D4
pins_d |= (0x80u & p[14]); // x= 7, y= 7, mapped pin D6
pins_e |= (0x80u & p[12]) >> 1; // x= 7, y= 6, mapped pin D7
break;
case 11:
pins_b |= (0x40u & p[ 4]) << 1; // x= 6, y= 2, mapped pin D11
pins_b |= (0x40u & p[ 6]); // x= 6, y= 3, mapped pin D10
pins_b |= (0x40u & p[ 8]) >> 1; // x= 6, y= 4, mapped pin D9
pins_b |= (0x40u & p[10]) >> 2; // x= 6, y= 5, mapped pin D8
pins_c |= (0x40u & p[16]); // x= 6, y= 8, mapped pin D5
pins_d |= (0x01u & p[ 0]) << 1; // x= 0, y= 0, mapped pin D2
pins_d |= (0x04u & p[ 0]) >> 2; // x= 2, y= 0, mapped pin D3
pins_d |= (0x10u & p[ 0]); // x= 4, y= 0, mapped pin D4
pins_d |= (0x40u & p[ 2]); // x= 6, y= 1, mapped pin D12
pins_d |= (0x40u & p[14]) << 1; // x= 6, y= 7, mapped pin D6
pins_e |= (0x40u & p[12]); // x= 6, y= 6, mapped pin D7
break;
}
}
// Enable pullups (by toggling) on new output pins.
PINB = PORTB ^ pins_b;
PINC = PORTC ^ pins_c;
PIND = PORTD ^ pins_d;
PINE = PORTE ^ pins_e;
// Set pins to output mode; pullups become Vcc/source.
DDRB |= pins_b;
DDRC |= pins_c;
DDRD |= pins_d;
DDRE |= pins_e;
// Set sink pin to GND/sink, turning on current.
PINB = sink_b;
PINC = sink_c;
PIND = sink_d;
PINE = sink_e;
#else
// Set sink pin to Vcc/source, turning off current.
static uint8_t sink_b = 0, sink_d = 0;
PIND = sink_d;
PINB = sink_b;
// Set pins to input mode; Vcc/source become pullups.
DDRD = 0;
DDRB = 0;
static uint8_t const PROGMEM sink_d_cycle[] =
{0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
static uint8_t const PROGMEM sink_b_cycle[] =
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20};
uint8_t pins_d = sink_d = pgm_read_byte(&sink_d_cycle[cycle]);
uint8_t pins_b = sink_b = pgm_read_byte(&sink_b_cycle[cycle]);
// convert Borgware-2D framebuffer to LoL Shield cycles on Diavolino
// (I could have done this with a lookup table, but that would be slower as
// non-constant bit shifts are quite expensive on AVR)
// NOTE: (0,0) is UPPER RIGHT in the Borgware realm
if (plane < NUMPLANE) {
switch(cycle) {
case 0:
pins_b |= (0x02u & p[ 0]) << 4; // x= 1, y= 0, mapped pin D13
pins_b |= (0x02u & p[ 2]) << 3; // x= 1, y= 1, mapped pin D12
pins_b |= (0x02u & p[ 4]) << 2; // x= 1, y= 2, mapped pin D11
pins_b |= (0x02u & p[ 6]) << 1; // x= 1, y= 3, mapped pin D10
pins_b |= (0x02u & p[ 8]); // x= 1, y= 4, mapped pin D9
pins_b |= (0x02u & p[10]) >> 1; // x= 1, y= 5, mapped pin D8
pins_d |= (0x02u & p[12]) << 6; // x= 1, y= 6, mapped pin D7
pins_d |= (0x02u & p[14]) << 5; // x= 1, y= 7, mapped pin D6
pins_d |= (0x02u & p[16]) << 4; // x= 1, y= 8, mapped pin D5
break;
case 1:
pins_b |= (0x08u & p[ 0]) << 2; // x= 3, y= 0, mapped pin D13
pins_b |= (0x08u & p[ 2]) << 1; // x= 3, y= 1, mapped pin D12
pins_b |= (0x08u & p[ 4]); // x= 3, y= 2, mapped pin D11
pins_b |= (0x08u & p[ 6]) >> 1; // x= 3, y= 3, mapped pin D10
pins_b |= (0x08u & p[ 8]) >> 2; // x= 3, y= 4, mapped pin D9
pins_b |= (0x08u & p[10]) >> 3; // x= 3, y= 5, mapped pin D8
pins_d |= (0x08u & p[12]) << 4; // x= 3, y= 6, mapped pin D7
pins_d |= (0x08u & p[14]) << 3; // x= 3, y= 7, mapped pin D6
pins_d |= (0x08u & p[16]) << 2; // x= 3, y= 8, mapped pin D5
break;
case 2:
pins_b |= (0x20u & p[ 0]); // x= 5, y= 0, mapped pin D13
pins_b |= (0x20u & p[ 2]) >> 1; // x= 5, y= 1, mapped pin D12
pins_b |= (0x20u & p[ 4]) >> 2; // x= 5, y= 2, mapped pin D11
pins_b |= (0x20u & p[ 6]) >> 3; // x= 5, y= 3, mapped pin D10
pins_b |= (0x20u & p[ 8]) >> 4; // x= 5, y= 4, mapped pin D9
pins_b |= (0x20u & p[10]) >> 5; // x= 5, y= 5, mapped pin D8
pins_d |= (0x20u & p[12]) << 2; // x= 5, y= 6, mapped pin D7
pins_d |= (0x20u & p[14]) << 1; // x= 5, y= 7, mapped pin D6
pins_d |= (0x20u & p[16]); // x= 5, y= 8, mapped pin D5
break;
case 3:
pins_b |= (0x20u & p[ 1]); // x=13, y= 0, mapped pin D13
pins_b |= (0x20u & p[ 3]) >> 1; // x=13, y= 1, mapped pin D12
pins_b |= (0x20u & p[ 5]) >> 2; // x=13, y= 2, mapped pin D11
pins_b |= (0x20u & p[ 7]) >> 3; // x=13, y= 3, mapped pin D10
pins_b |= (0x20u & p[ 9]) >> 4; // x=13, y= 4, mapped pin D9
pins_b |= (0x20u & p[11]) >> 5; // x=13, y= 5, mapped pin D8
pins_d |= (0x01u & p[16]) << 2; // x= 0, y= 8, mapped pin D2
pins_d |= (0x04u & p[16]) << 1; // x= 2, y= 8, mapped pin D3
pins_d |= (0x10u & p[16]); // x= 4, y= 8, mapped pin D4
pins_d |= (0x20u & p[13]) << 2; // x=13, y= 6, mapped pin D7
pins_d |= (0x20u & p[15]) << 1; // x=13, y= 7, mapped pin D6
break;
case 4:
pins_b |= (0x10u & p[ 1]) << 1; // x=12, y= 0, mapped pin D13
pins_b |= (0x10u & p[ 3]); // x=12, y= 1, mapped pin D12
pins_b |= (0x10u & p[ 5]) >> 1; // x=12, y= 2, mapped pin D11
pins_b |= (0x10u & p[ 7]) >> 2; // x=12, y= 3, mapped pin D10
pins_b |= (0x10u & p[ 9]) >> 3; // x=12, y= 4, mapped pin D9
pins_b |= (0x10u & p[11]) >> 4; // x=12, y= 5, mapped pin D8
pins_d |= (0x01u & p[14]) << 2; // x= 0, y= 7, mapped pin D2
pins_d |= (0x04u & p[14]) << 1; // x= 2, y= 7, mapped pin D3
pins_d |= (0x10u & p[13]) << 3; // x=12, y= 6, mapped pin D7
pins_d |= (0x10u & p[14]); // x= 4, y= 7, mapped pin D4
pins_d |= (0x20u & p[17]); // x=13, y= 8, mapped pin D5
break;
case 5:
pins_b |= (0x08u & p[ 1]) << 2; // x=11, y= 0, mapped pin D13
pins_b |= (0x08u & p[ 3]) << 1; // x=11, y= 1, mapped pin D12
pins_b |= (0x08u & p[ 5]); // x=11, y= 2, mapped pin D11
pins_b |= (0x08u & p[ 7]) >> 1; // x=11, y= 3, mapped pin D10
pins_b |= (0x08u & p[ 9]) >> 2; // x=11, y= 4, mapped pin D9
pins_b |= (0x08u & p[11]) >> 3; // x=11, y= 5, mapped pin D8
pins_d |= (0x01u & p[12]) << 2; // x= 0, y= 6, mapped pin D2
pins_d |= (0x04u & p[12]) << 1; // x= 2, y= 6, mapped pin D3
pins_d |= (0x10u & p[12]); // x= 4, y= 6, mapped pin D4
pins_d |= (0x10u & p[15]) << 2; // x=12, y= 7, mapped pin D6
pins_d |= (0x10u & p[17]) << 1; // x=12, y= 8, mapped pin D5
break;
case 6:
pins_b |= (0x04u & p[ 1]) << 3; // x=10, y= 0, mapped pin D13
pins_b |= (0x04u & p[ 3]) << 2; // x=10, y= 1, mapped pin D12
pins_b |= (0x04u & p[ 5]) << 1; // x=10, y= 2, mapped pin D11
pins_b |= (0x04u & p[ 7]); // x=10, y= 3, mapped pin D10
pins_b |= (0x04u & p[ 9]) >> 1; // x=10, y= 4, mapped pin D9
pins_d |= (0x01u & p[10]) << 2; // x= 0, y= 5, mapped pin D2
pins_d |= (0x04u & p[10]) << 1; // x= 2, y= 5, mapped pin D3
pins_d |= (0x08u & p[13]) << 4; // x=11, y= 6, mapped pin D7
pins_d |= (0x08u & p[15]) << 3; // x=11, y= 7, mapped pin D6
pins_d |= (0x08u & p[17]) << 2; // x=11, y= 8, mapped pin D5
pins_d |= (0x10u & p[10]); // x= 4, y= 5, mapped pin D4
break;
case 7:
pins_b |= (0x02u & p[ 1]) << 4; // x= 9, y= 0, mapped pin D13
pins_b |= (0x02u & p[ 3]) << 3; // x= 9, y= 1, mapped pin D12
pins_b |= (0x02u & p[ 5]) << 2; // x= 9, y= 2, mapped pin D11
pins_b |= (0x02u & p[ 7]) << 1; // x= 9, y= 3, mapped pin D10
pins_b |= (0x04u & p[11]) >> 2; // x=10, y= 5, mapped pin D8
pins_d |= (0x01u & p[ 8]) << 2; // x= 0, y= 4, mapped pin D2
pins_d |= (0x04u & p[ 8]) << 1; // x= 2, y= 4, mapped pin D3
pins_d |= (0x04u & p[13]) << 5; // x=10, y= 6, mapped pin D7
pins_d |= (0x04u & p[15]) << 4; // x=10, y= 7, mapped pin D6
pins_d |= (0x04u & p[17]) << 3; // x=10, y= 8, mapped pin D5
pins_d |= (0x10u & p[ 8]); // x= 4, y= 4, mapped pin D4
break;
case 8:
pins_b |= (0x01u & p[ 1]) << 5; // x= 8, y= 0, mapped pin D13
pins_b |= (0x01u & p[ 3]) << 4; // x= 8, y= 1, mapped pin D12
pins_b |= (0x01u & p[ 5]) << 3; // x= 8, y= 2, mapped pin D11
pins_b |= (0x02u & p[ 9]); // x= 9, y= 4, mapped pin D9
pins_b |= (0x02u & p[11]) >> 1; // x= 9, y= 5, mapped pin D8
pins_d |= (0x01u & p[ 6]) << 2; // x= 0, y= 3, mapped pin D2
pins_d |= (0x02u & p[13]) << 6; // x= 9, y= 6, mapped pin D7
pins_d |= (0x02u & p[15]) << 5; // x= 9, y= 7, mapped pin D6
pins_d |= (0x02u & p[17]) << 4; // x= 9, y= 8, mapped pin D5
pins_d |= (0x04u & p[ 6]) << 1; // x= 2, y= 3, mapped pin D3
pins_d |= (0x10u & p[ 6]); // x= 4, y= 3, mapped pin D4
break;
case 9:
pins_b |= (0x01u & p[ 7]) << 2; // x= 8, y= 3, mapped pin D10
pins_b |= (0x01u & p[ 9]) << 1; // x= 8, y= 4, mapped pin D9
pins_b |= (0x01u & p[11]); // x= 8, y= 5, mapped pin D8
pins_b |= (0x80u & p[ 0]) >> 2; // x= 7, y= 0, mapped pin D13
pins_b |= (0x80u & p[ 2]) >> 3; // x= 7, y= 1, mapped pin D12
pins_d |= (0x01u & p[ 4]) << 2; // x= 0, y= 2, mapped pin D2
pins_d |= (0x01u & p[13]) << 7; // x= 8, y= 6, mapped pin D7
pins_d |= (0x01u & p[15]) << 6; // x= 8, y= 7, mapped pin D6
pins_d |= (0x01u & p[17]) << 5; // x= 8, y= 8, mapped pin D5
pins_d |= (0x04u & p[ 4]) << 1; // x= 2, y= 2, mapped pin D3
pins_d |= (0x10u & p[ 4]); // x= 4, y= 2, mapped pin D4
break;
case 10:
pins_b |= (0x40u & p[ 0]) >> 1; // x= 6, y= 0, mapped pin D13
pins_b |= (0x80u & p[ 4]) >> 4; // x= 7, y= 2, mapped pin D11
pins_b |= (0x80u & p[ 6]) >> 5; // x= 7, y= 3, mapped pin D10
pins_b |= (0x80u & p[ 8]) >> 6; // x= 7, y= 4, mapped pin D9
pins_b |= (0x80u & p[10]) >> 7; // x= 7, y= 5, mapped pin D8
pins_d |= (0x01u & p[ 2]) << 2; // x= 0, y= 1, mapped pin D2
pins_d |= (0x04u & p[ 2]) << 1; // x= 2, y= 1, mapped pin D3
pins_d |= (0x10u & p[ 2]); // x= 4, y= 1, mapped pin D4
pins_d |= (0x80u & p[12]); // x= 7, y= 6, mapped pin D7
pins_d |= (0x80u & p[14]) >> 1; // x= 7, y= 7, mapped pin D6
pins_d |= (0x80u & p[16]) >> 2; // x= 7, y= 8, mapped pin D5
break;
case 11:
pins_b |= (0x40u & p[ 2]) >> 2; // x= 6, y= 1, mapped pin D12
pins_b |= (0x40u & p[ 4]) >> 3; // x= 6, y= 2, mapped pin D11
pins_b |= (0x40u & p[ 6]) >> 4; // x= 6, y= 3, mapped pin D10
pins_b |= (0x40u & p[ 8]) >> 5; // x= 6, y= 4, mapped pin D9
pins_b |= (0x40u & p[10]) >> 6; // x= 6, y= 5, mapped pin D8
pins_d |= (0x01u & p[ 0]) << 2; // x= 0, y= 0, mapped pin D2
pins_d |= (0x04u & p[ 0]) << 1; // x= 2, y= 0, mapped pin D3
pins_d |= (0x10u & p[ 0]); // x= 4, y= 0, mapped pin D4
pins_d |= (0x40u & p[12]) << 1; // x= 6, y= 6, mapped pin D7
pins_d |= (0x40u & p[14]); // x= 6, y= 7, mapped pin D6
pins_d |= (0x40u & p[16]) >> 1; // x= 6, y= 8, mapped pin D5
break;
}
}
// Enable pullups on new output pins.
PORTD = pins_d;
PORTB = pins_b;
// Set pins to output mode; pullups become Vcc/source.
DDRD = pins_d;
DDRB = pins_b;
// Set sink pin to GND/sink, turning on current.
PIND = sink_d;
PINB = sink_b;
#endif
}
#if !defined (__AVR_ATmega32U4__)
ISR(TIMER2_OVF_vect) {
#else
ISR(TIMER1_COMPA_vect) {
#endif
// For each cycle, we have potential planes to display. Once every plane has
// been displayed, then we move on to the next cycle.
// NOTE: a "cycle" is a subset of LEDs that can be driven at once.
// 12 Cycles of Matrix
static uint8_t cycle = 0;
// planes to display
// NOTE: a "plane" in the Borgware is the same as a "page" in Jimmie's lib
static uint8_t plane = 0;
#if defined (__AVR_ATmega168__) || defined (__AVR_ATmega48__) || defined (__AVR_ATmega88__) || defined (__AVR_ATmega328P__) || defined (__AVR_ATmega1280__) || defined (__AVR_ATmega2560__)
TCCR2B = prescaler[plane];
#elif defined (__AVR_ATmega8__) || defined (__AVR_ATmega128__)
TCCR2 = prescaler[page];
#elif defined (__AVR_ATmega32U4__)
TCCR1B = prescaler[plane];
#endif
#if !defined (__AVR_ATmega32U4__)
TCNT2 = counts[plane];
#else
TCNT1 = counts[plane];
#endif
// distribute framebuffer contents among current cycle pins
compose_cycle(cycle, plane++);
if (plane >= (NUMPLANE + 1)) {
plane = 0;
cycle++;
if (cycle >= 12) {
cycle = 0;
}
}
wdt_reset();
}
void borg_hw_init() {
#if defined (__AVR_ATmega168__) || defined (__AVR_ATmega48__) || defined (__AVR_ATmega88__) || defined (__AVR_ATmega328P__) || defined (__AVR_ATmega1280__) || defined (__AVR_ATmega2560__)
TIMSK2 &= ~(_BV(TOIE2) | _BV(OCIE2A));
TCCR2A &= ~(_BV(WGM21) | _BV(WGM20));
TCCR2B &= ~_BV(WGM22);
ASSR &= ~_BV(AS2);
#elif defined (__AVR_ATmega8__)
TIMSK &= ~(_BV(TOIE2) | _BV(OCIE2));
TCCR2 &= ~(_BV(WGM21) | _BV(WGM20));
ASSR &= ~_BV(AS2);
#elif defined (__AVR_ATmega128__)
TIMSK &= ~(_BV(TOIE2) | _BV(OCIE2));
TCCR2 &= ~(_BV(WGM21) | _BV(WGM20));
#elif defined (__AVR_ATmega32U4__)
// The only 8bit timer on the Leonardo is used by default, so we use the 16bit Timer1
// in CTC mode with a compare value of 256 to achieve the same behaviour.
TIMSK1 &= ~(_BV(TOIE1) | _BV(OCIE1A));
TCCR1A &= ~(_BV(WGM10) | _BV(WGM11));
OCR1A = 256;
#endif
setBrightness();
// Then start the display
#if defined (__AVR_ATmega168__) || defined (__AVR_ATmega48__) || defined (__AVR_ATmega88__) || defined (__AVR_ATmega328P__) || defined (__AVR_ATmega1280__) || defined (__AVR_ATmega2560__)
TIMSK2 |= _BV(TOIE2);
TCCR2B = FASTPRESCALER;
#elif defined (__AVR_ATmega8__) || defined (__AVR_ATmega128__)
TIMSK |= _BV(TOIE2);
TCCR2 = FASTPRESCALER;
#elif defined (__AVR_ATmega32U4__)
// Enable output compare match interrupt
TIMSK1 |= _BV(OCIE1A);
TCCR1B = FASTPRESCALER;
#endif
// interrupt ASAP
#if !defined (__AVR_ATmega32U4__)
TCNT2 = 255;
#else
TCNT1 = 255;
#endif
// activate watchdog timer
wdt_reset();
wdt_enable(WDTO_15MS); // 15ms watchdog
}

5
src/borg_hw/config.in

@ -14,6 +14,7 @@ choice 'Hardware Driver' \
Andre-Borg HW_BORG_ANDRE \
Laufschrift-Borg HW_BORG_LS \
Laufschrift-Borg-MH HW_BORG_MH \
LoL-Shield HW_LOLSHIELD \
FFM-Jochen HW_BORG_LSJO \
FFM-LedBrett HW_LEDBRETT \
Borg-Mini HW_BORG_MINI \
@ -45,6 +46,10 @@ if [ "$BORG_HW" == "HW_BORG_MH" ] ; then
source src/borg_hw/config_borg_mh.in
fi
if [ "$BORG_HW" == "HW_LOLSHIELD" ] ; then
source src/borg_hw/config_lolshield.in
fi
if [ "$BORG_HW" == "HW_BORG_LSJO" ] ; then
source src/borg_hw/config_borg_lsjo.in
fi

8
src/borg_hw/config_lolshield.in

@ -0,0 +1,8 @@
mainmenu_option next_comment
comment "lolshield setup"
define_int USER_TIMER0_FOR_WAIT 1
uint "Brightness (0-127)" BRIGHTNESS 127
endmenu

10
src/games/breakout/playfield.c

@ -67,7 +67,7 @@ static void brick_damage (int8_t in_x, int8_t in_y)
void playfield_set (uint8_t in_x, uint8_t in_y, game_field_t in_field)
{
if (in_x >= NUM_ROWS || in_y >= NUM_COLS)
if (in_x >= NUM_COLS || in_y >= NUM_ROWS)
{
return;
}
@ -78,10 +78,10 @@ int8_t check_bounce (int8_t in_x, int8_t in_y)
{
int8_t ov = 0;
/* overflow check */
if (in_x >= NUM_ROWS || in_x < 0)
if (in_x >= NUM_COLS || in_x < 0)
ov |= BOUNCE_X;
if (in_y >= NUM_COLS || in_y < 0)
if (in_y >= NUM_ROWS || in_y < 0)
ov |= BOUNCE_Y;
if (ov)
@ -119,9 +119,9 @@ void playfield_draw ()
{
uint8_t x,y;
for (x=0;x<NUM_ROWS;x++)
for (x=0;x<NUM_COLS;x++)
{
for (y=0;y<NUM_COLS;y++)
for (y=0;y<NUM_ROWS;y++)
{
draw_single_field (x,y, (*playfield)[x][y]);
}

2
src/games/breakout/rebound.h

@ -30,7 +30,7 @@ inline static uint8_t rebound_getpos ()
inline static void rebound_init()
{
rbpos = (NUM_ROWS / 2) - (REBOUND_SIZE / 2);
rbpos = (NUM_COLS / 2) - (REBOUND_SIZE / 2);
rebound_draw();
}

98
src/games/snake/snake_game.c

@ -51,9 +51,14 @@ game_descriptor_t snake_game_descriptor __attribute__((section(".game_descriptor
#define SNAKE_MAX_APPLES 10
#endif
#if !defined SNAKE_CYCLE_DELAY || defined DOXYGEN
#if !defined SNAKE_GAME_DELAY || defined DOXYGEN
/** Delay (in ms) between every state change. */
#define SNAKE_CYCLE_DELAY 100
#define SNAKE_GAME_DELAY 200
#endif
#if !defined SNAKE_ANIM_DELAY || defined DOXYGEN
/** Delay (in ms) between every state change. */
#define SNAKE_ANIM_DELAY 100
#endif
#if !defined SNAKE_TERMINATION_DELAY || defined DOXYGEN
@ -192,11 +197,21 @@ static snake_dir_t snake_queryJoystick(void)
*/
static void snake_initGameProtagonist(snake_protagonist_t *pprotSnake)
{
pprotSnake->aSegments[0] = (pixel){NUM_COLS / 2, NUM_ROWS / 2};
pprotSnake->aSegments[1] = (pixel){NUM_COLS / 2, NUM_ROWS / 2 - 1};
#if NUM_ROWS > NUM_COLS
pprotSnake->aSegments[0] =
(pixel){(NUM_COLS - 2) / 2 + 1, (NUM_ROWS - 2) / 2 + 1};
pprotSnake->aSegments[1] =
(pixel){(NUM_COLS - 2) / 2 + 1, (NUM_ROWS - 2) / 2};
pprotSnake->dir = SNAKE_DIR_DOWN;
#else
pprotSnake->aSegments[0] =
(pixel){(NUM_COLS - 2) / 2 + 1, (NUM_ROWS - 2) / 2 + 1};
pprotSnake->aSegments[1] =
(pixel){(NUM_COLS - 2) / 2 + 2, (NUM_ROWS - 2) / 2 + 1};
pprotSnake->dir = SNAKE_DIR_RIGHT;
#endif
pprotSnake->nTailIndex = 0;
pprotSnake->nHeadIndex = 1;
pprotSnake->dir = SNAKE_DIR_UP;
}
#ifdef GAME_SNAKE
@ -403,7 +418,7 @@ void snake_engine(uint8_t bDemoMode)
clear_screen(0);
snake_drawBorder();
for (uint8_t nAppleColor = 0; 1; nAppleColor ^= SNAKE_COLOR_APPLE)
for (uint8_t nTick = 0; 1; nTick ^= SNAKE_COLOR_APPLE)
{
// determine new direction
#if defined ANIMATION_SNAKE && defined GAME_SNAKE
@ -415,48 +430,66 @@ void snake_engine(uint8_t bDemoMode)
{
snake_userControl(&protSnake, &dirLast);
}
if (bDemoMode || nTick) {
#elif defined ANIMATION_SNAKE
snake_autoRoute(&protSnake, &apples);
{
#else
snake_userControl(&protSnake, &dirLast);
if (nTick) {
#endif
// actually move head
pixel pxOldHead = protSnake.aSegments[protSnake.nHeadIndex];
protSnake.nHeadIndex = (protSnake.nHeadIndex + 1u) % USNAKE_MAX_LENGTH;
protSnake.aSegments[protSnake.nHeadIndex] =
snake_nextDirection(pxOldHead, protSnake.dir);
// actually move head
pixel pxOldHead = protSnake.aSegments[protSnake.nHeadIndex];
protSnake.nHeadIndex = (protSnake.nHeadIndex + 1u) % USNAKE_MAX_LENGTH;
protSnake.aSegments[protSnake.nHeadIndex] =
snake_nextDirection(pxOldHead, protSnake.dir);
// look if we have found an apple
if (!snake_checkForApple(&apples,
protSnake.aSegments[protSnake.nHeadIndex]))
{
// quit game if we hit something which is not an apple
if (get_pixel(protSnake.aSegments[protSnake.nHeadIndex]))
// look if we have found an apple
if (!snake_checkForApple(&apples,
protSnake.aSegments[protSnake.nHeadIndex]))
{
snake_eliminateProtagonist(&protSnake);
return;
}
// quit game if we hit something which is not an apple
if (get_pixel(protSnake.aSegments[protSnake.nHeadIndex]))
{
snake_eliminateProtagonist(&protSnake);
return;
}
// remove last segment
clearpixel(protSnake.aSegments[protSnake.nTailIndex])
protSnake.nTailIndex =
(protSnake.nTailIndex + 1u) % USNAKE_MAX_LENGTH;
// remove last segment
clearpixel(protSnake.aSegments[protSnake.nTailIndex])
protSnake.nTailIndex =
(protSnake.nTailIndex + 1u) % USNAKE_MAX_LENGTH;
// new apples
snake_spawnApples(&apples);
// new apples
snake_spawnApples(&apples);
}
// draw new head
setpixel(protSnake.aSegments[protSnake.nHeadIndex],
SNAKE_COLOR_PROTAGONIST);
}
// draw new head
setpixel(protSnake.aSegments[protSnake.nHeadIndex],
SNAKE_COLOR_PROTAGONIST);
// draw apples
for (uint8_t i = apples.nAppleCount; i--;)
{
setpixel(apples.aApples[i], nAppleColor);
// nTick also serves as blinking color
setpixel(apples.aApples[i], nTick);
}
wait(SNAKE_CYCLE_DELAY);
#if defined ANIMATION_SNAKE && defined GAME_SNAKE
if (bDemoMode)
{
wait(SNAKE_ANIM_DELAY);
}
else
{
wait(SNAKE_GAME_DELAY / 2);
}
#elif defined ANIMATION_SNAKE
wait(SNAKE_ANIM_DELAY);
#else
wait(SNAKE_GAME_DELAY / 2);
#endif
}
}
@ -466,6 +499,9 @@ void snake_engine(uint8_t bDemoMode)
void snake_game(void)
{
snake_engine(0);
#if defined GAME_SNAKE && defined SCROLLTEXT_SUPPORT
scrolltext("</#Game Over!");
#endif
}
/*@}*/

3
src/games/tetris/variant_fp.c

@ -32,6 +32,9 @@
#include "variant_std.h"
#include "variant_fp.h"
#if (NUM_ROWS != NUM_COLS)
#error "First Person Tetris does not support non-square displays!"
#endif
/***************
* entry point *

26
src/games/tetris/view.c

@ -52,24 +52,15 @@
/** color of line counter */
#define TETRIS_VIEW_COLORCOUNTER 2
#ifdef GAME_TETRIS_FP
#if NUM_ROWS < NUM_COLS
#define VIEWCOLS NUM_ROWS
#define VIEWROWS NUM_ROWS
#elif NUM_ROWS > NUM_COLS
#define VIEWCOLS NUM_COLS
#define VIEWROWS NUM_COLS
#else
#define VIEWCOLS NUM_COLS
#define VIEWROWS NUM_ROWS
#endif
#if (NUM_ROWS < 16) && (NUM_COLS > NUM_ROWS) && (!defined GAME_TETRIS_FP)
# define VIEWCOLS NUM_ROWS
# define VIEWROWS NUM_COLS
# define VIEW_TILT
#else
#define VIEWCOLS NUM_COLS
#define VIEWROWS NUM_ROWS
# define VIEWCOLS NUM_COLS
# define VIEWROWS NUM_ROWS
#endif
#if VIEWROWS >= 20
#define TETRIS_VIEW_YOFFSET_DUMP ((VIEWROWS - 20) / 2)
#define TETRIS_VIEW_HEIGHT_DUMP 20
@ -127,6 +118,11 @@ static void tetris_view_setpixel(tetris_bearing_t nBearing,
uint8_t y,
uint8_t nColor)
{
#ifdef VIEW_TILT
// tilt counter clockwise
nBearing = (nBearing + 3) % 4u;
#endif
x = VIEWCOLS - 1 - x;
pixel px;

6
src/joystick/Makefile

@ -18,6 +18,12 @@ endif
ifeq ($(HC165_JOYSTICK_SUPPORT), y)
SRC = hc165_joystick.c
endif
ifeq ($(LOLSHIELD_JOYSTICK_SUPPORT), y)
SRC = lolshield_joystick.c
endif
ifeq ($(NULL_JOYSTICK_SUPPORT), y)
SRC = null_joystick.c
endif
include $(MAKETOPDIR)/rules.mk

112
src/joystick/config.in

@ -1,18 +1,36 @@
dep_bool_menu "joystick support" JOYSTICK_SUPPORT y
mainmenu_option next_comment
comment "Joystick Support"
if [ "$JOYSTICK_SUPPORT" = "y" ]; then
###################### Parallel joystick menu #################################
dep_bool_menu "parallel joystick support" PARALLEL_JOYSTICK_SUPPORT y
bool "Joystick Support" JOYSTICK_SUPPORT n
if [ "x$JOYSTICK_CHOICE" == "x" ] ; then
define_string JOYSTICK_CHOICE "JOY_PARALLEL"
fi
if [ "$PARALLEL_JOYSTICK_SUPPORT" = "y" ]; then
choice 'Pin up' \
if [ "$JOYSTICK_SUPPORT" = "y" ]; then
choice 'Joystick Type' \
"Atari-9-Pin JOY_PARALLEL \
NES-Game-Pad JOY_NES_PAD \
RFM12 JOY_RFM12 \
LED-Brett JOY_LEDBRETT \
LoL-Shield JOY_LOLSHIELD \
None JOY_NULL" \
'Atari-9-Pin' JOYSTICK_CHOICE
###################### parallel joystick menu #################################
if [ "$JOYSTICK_CHOICE" == "JOY_PARALLEL" ]; then
mainmenu_option next_comment
comment "Joystick Settings"
define_bool PARALLEL_JOYSTICK_SUPPORT y
choice 'Pin up' \
"PINA PINA \
PINB PINB \
PINC PINC \
PIND PIND" \
'PINB' JOYSTICK_PIN_UP
choice 'Bit up' \
choice 'Bit up' \
"Bit0 0 \
Bit1 1 \
Bit2 2 \
@ -23,14 +41,14 @@ if [ "$JOYSTICK_SUPPORT" = "y" ]; then
Bit7 7" \
'Bit0' JOYSTICK_BIT_UP
choice 'Pin down' \
choice 'Pin down' \
"PINA PINA \
PINB PINB \
PINC PINC \
PIND PIND" \
'PINB' JOYSTICK_PIN_DOWN
choice 'Bit down' \
choice 'Bit down' \
"Bit0 0 \
Bit1 1 \
Bit2 2 \
@ -41,14 +59,14 @@ if [ "$JOYSTICK_SUPPORT" = "y" ]; then
Bit7 7" \
'Bit1' JOYSTICK_BIT_DOWN
choice 'Pin left' \
choice 'Pin left' \
"PINA PINA \
PINB PINB \
PINC PINC \
PIND PIND" \
'PINB' JOYSTICK_PIN_LEFT
choice 'Bit left' \
choice 'Bit left' \
"Bit0 0 \
Bit1 1 \
Bit2 2 \
@ -59,14 +77,14 @@ if [ "$JOYSTICK_SUPPORT" = "y" ]; then
Bit7 7" \
'Bit2' JOYSTICK_BIT_LEFT
choice 'Pin right' \
choice 'Pin right' \
"PINA PINA \
PINB PINB \
PINC PINC \
PIND PIND" \
'PINB' JOYSTICK_PIN_RIGHT
choice 'Bit right' \
choice 'Bit right' \
"Bit0 0 \
Bit1 1 \
Bit2 2 \
@ -77,14 +95,14 @@ if [ "$JOYSTICK_SUPPORT" = "y" ]; then
Bit7 7" \
'Bit3' JOYSTICK_BIT_RIGHT
choice 'Pin fire' \
choice 'Pin fire' \
"PINA PINA \
PINB PINB \
PINC PINC \
PIND PIND" \
'PIND' JOYSTICK_PIN_FIRE
choice 'Bit fire' \
choice 'Bit fire' \
"Bit0 0 \
Bit1 1 \
Bit2 2 \
@ -94,37 +112,40 @@ if [ "$JOYSTICK_SUPPORT" = "y" ]; then
Bit6 6 \
Bit7 7" \
'Bit3' JOYSTICK_BIT_FIRE
fi
endmenu
endmenu
fi
###############################################################################
###################### NES-Pad menu #################################
dep_bool_menu "nes-pad support" NES_PAD_SUPPORT y
###################### NES-Pad menu ###########################################
if [ "$JOYSTICK_CHOICE" == "JOY_NES_PAD" ]; then
mainmenu_option next_comment
comment "Joystick Settings"
define_bool NES_PAD_SUPPORT y
if [ "$NES_PAD_SUPPORT" = "y" ]; then
choice 'Port clk' \
choice 'Port clk' \
"PORTA PORTA \
PORTB PORTB \
PORTC PORTC \
PORTD PORTD" \
'PORTB' NES_PAD_PORT_CLK
choice 'Port ds' \
choice 'Port ds' \
"PORTA PORTA \
PORTB PORTB \
PORTC PORTC \
PORTD PORTD" \
'PORTB' NES_PAD_PORT_PL
'PORTB' NES_PAD_PORT_PL
choice 'Pin pl' \
choice 'Pin pl' \
"PORTA PORTA \
PORTB PORTB \
PORTC PORTC \
PORTD PORTD" \
'PORTB' NES_PAD_PORT_DS
choice 'Bit clk' \
choice 'Bit clk' \
"Bit0 0 \
Bit1 1 \
Bit2 2 \
@ -135,7 +156,7 @@ if [ "$JOYSTICK_SUPPORT" = "y" ]; then
Bit7 7" \
'Bit0' NES_PAD_BIT_CLK
choice 'Bit pl' \
choice 'Bit pl' \
"Bit0 0 \
Bit1 1 \
Bit2 2 \
@ -146,7 +167,7 @@ if [ "$JOYSTICK_SUPPORT" = "y" ]; then
Bit7 7" \
'Bit1' NES_PAD_BIT_PL
choice 'Bit ds' \
choice 'Bit ds' \
"Bit0 0 \
Bit1 1 \
Bit2 2 \
@ -157,28 +178,31 @@ if [ "$JOYSTICK_SUPPORT" = "y" ]; then
Bit7 7" \
'Bit2' NES_PAD_BIT_DS
endmenu
fi
endmenu
###############################################################################
###################### RFM12 joystick menu ####################################
dep_bool_menu "RFM12 Joystick support" RFM12_JOYSTICK_SUPPORT y
endmenu
if [ "$JOYSTICK_CHOICE" == "JOY_RFM12" ]; then
define_bool RFM12_JOYSTICK_SUPPORT y
fi
###############################################################################
###################### 74HC165 joystick menu #################################
dep_bool_menu "74HC165 joystick support" HC165_JOYSTICK_SUPPORT y
if [ "$JOYSTICK_CHOICE" == "JOY_LEDBRETT" ]; then
mainmenu_option next_comment
comment "Joystick Settings"
define_bool HC165_JOYSTICK_SUPPORT y
if [ "$HC165_JOYSTICK_SUPPORT" = "y" ]; then
choice 'Port load' \
choice 'Port load' \
"PORTA PORTA \
PORTB PORTB \
PORTC PORTC \
PORTD PORTD" \
'PORTD' HC165_JOYSTICK_PORT_LOAD
choice 'Bit load' \
choice 'Bit load' \
"Bit0 0 \
Bit1 1 \
Bit2 2 \
@ -188,11 +212,23 @@ if [ "$JOYSTICK_SUPPORT" = "y" ]; then
Bit6 6 \
Bit7 7" \
'Bit2' HC165_JOYSTICK_BIT_LOAD
endmenu
fi
###############################################################################
endmenu
###################### LoL Shield joystick menu ###############################
if [ "$JOYSTICK_CHOICE" == "JOY_NULL" ]; then
define_bool NULL_JOYSTICK_SUPPORT y
fi
###############################################################################
###################### null joystick menu #####################################
if [ "$JOYSTICK_CHOICE" == "JOY_LOLSHIELD" ]; then
define_bool LOLSHIELD_JOYSTICK_SUPPORT y
fi
###############################################################################
fi
endmenu
endmenu

70
src/joystick/joystick.h

@ -1,6 +1,10 @@
#ifndef JOYSTICK_H
#define JOYSTICK_H
#ifdef __AVR__
# include <avr/io.h>
#endif
#include "../config.h"
extern unsigned char waitForFire;
@ -41,7 +45,71 @@ void joy_init();
# define JOYISFIRE (! ((1<<4) & hc165_joystick_val))
# else
# elif defined(NULL_JOYSTICK_SUPPORT)
# define JOYISUP (0)
# define JOYISDOWN (0)
# define JOYISLEFT (0)
# define JOYISRIGHT (0)
# define JOYISFIRE (0)
# elif defined (LOLSHIELD_JOYSTICK_SUPPORT)
# if defined (__AVR_ATmega48__) || \
defined (__AVR_ATmega48P__) || \
defined (__AVR_ATmega88__) || \
defined (__AVR_ATmega88P__) || \
defined (__AVR_ATmega168__) || \
defined (__AVR_ATmega168P__) || \
defined (__AVR_ATmega328__) || \
defined (__AVR_ATmega328P__)
/*
* A0 => PC0 => JOYISUP
* A1 => PC1 => JOYISDOWN
* A2 => PC2 => JOYISLEFT
* A3 => PC3 => JOYISRIGHT
* A4 => PC4 => NC (JOYIS2GND)
* A5 => PC5 => JOYISFIRE
*/
# define JOYISUP (!(PINC & _BV(PINC0)))
# define JOYISDOWN (!(PINC & _BV(PINC1)))
# define JOYISLEFT (!(PINC & _BV(PINC2)))
# define JOYISRIGHT (!(PINC & _BV(PINC3)))
# define JOYISFIRE (!(PINC & _BV(PINC5)))
# elif defined (__AVR_ATmega32U4__)
/*
* A0 => PF7 => JOYISUP
* A1 => PF6 => JOYISDOWN
* A2 => PF5 => JOYISLEFT
* A3 => PF4 => JOYISRIGHT
* A4 => PF1 => NC (JOYIS2GND)
* A5 => PF0 => JOYISFIRE
*/
# define JOYISUP (!(PINF & _BV(PINF7)))
# define JOYISDOWN (!(PINF & _BV(PINF6)))
# define JOYISLEFT (!(PINF & _BV(PINF5)))
# define JOYISRIGHT (!(PINF & _BV(PINF4)))
# define JOYISFIRE (!(PINF & _BV(PINF0)))
# elif defined (__AVR_ATmega1280__) || \
defined (__AVR_ATmega2560__)
/*
* A0 => PF0 => JOYISUP
* A1 => PF1 => JOYISDOWN
* A2 => PF2 => JOYISLEFT
* A3 => PF3 => JOYISRIGHT
* A4 => PF4 => NC (JOYIS2GND)
* A5 => PF5 => JOYISFIRE
*/
# define JOYISUP (!(PINF & _BV(PINF0)))
# define JOYISDOWN (!(PINF & _BV(PINF1)))
# define JOYISLEFT (!(PINF & _BV(PINF2)))
# define JOYISRIGHT (!(PINF & _BV(PINF3)))
# define JOYISFIRE (!(PINF & _BV(PINF5)))
# else
# error "Unsupported Arduino board!"
# endif
# elif defined (PARALLEL_JOYSTICK_SUPPORT)
# define JOYISUP (!(JOYSTICK_PIN_UP & (1<<JOYSTICK_BIT_UP )))
# define JOYISDOWN (!(JOYSTICK_PIN_DOWN & (1<<JOYSTICK_BIT_DOWN )))

89
src/joystick/lolshield_joystick.c

@ -0,0 +1,89 @@
/**
* @file lolshield_joystick.c
* @brief Driver for Jimmie Rodgers' LoL Shield
* @author Christian Kroll
* @date 2014
* @copyright GNU Public License 2 or later
* @see http://jimmieprodgers.com/kits/lolshield/
*
* This driver prepares the A0-A5 pins of an Ardunino device to serve as
* joystick input lines.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <avr/io.h>
void joy_init(){
#if defined (__AVR_ATmega48__) || \
defined (__AVR_ATmega48P__) || \
defined (__AVR_ATmega88__) || \
defined (__AVR_ATmega88P__) || \
defined (__AVR_ATmega168__) || \
defined (__AVR_ATmega168P__) || \
defined (__AVR_ATmega328__) || \
defined (__AVR_ATmega328P__)
/*
* A0 => PC0 => JOYISUP
* A1 => PC1 => JOYISDOWN
* A2 => PC2 => JOYISLEFT
* A3 => PC3 => JOYISRIGHT
* A4 => PC4 => NC (JOYIS2GND)
* A5 => PC5 => JOYISFIRE
*/
// set joystick pins to input
DDRC &= ~(_BV(PINC0) | _BV(PINC1) | _BV(PINC2) |
_BV(PINC3) | _BV(PINC4) | _BV(PINC5));
// activate pullups
PORTC |= _BV(PINC0) | _BV(PINC1) | _BV(PINC2) |
_BV(PINC3) | _BV(PINC4) | _BV(PINC5);
#elif defined (__AVR_ATmega32U4__)
/*
* A0 => PF7 => JOYISUP
* A1 => PF6 => JOYISDOWN
* A2 => PF5 => JOYISLEFT
* A3 => PF4 => JOYISRIGHT
* A4 => PF1 => NC (JOYIS2GND)
* A5 => PF0 => JOYISFIRE
*/
// set joystick pins to input
DDRF &= ~(_BV(PINF7) | _BV(PINF6) | _BV(PINF5) |
_BV(PINF4) | _BV(PINF1) | _BV(PINF0));
// activate pullups
PORTF |= _BV(PINF7) | _BV(PINF6) | _BV(PINF5) | _BV(PINF4) |
_BV(PINF1) | _BV(PINF0);
#elif defined (__AVR_ATmega1280__) || \
defined (__AVR_ATmega2560__)
/*
* A0 => PF0 => JOYISUP
* A1 => PF1 => JOYISDOWN
* A2 => PF2 => JOYISLEFT
* A3 => PF3 => JOYISRIGHT
* A4 => PF4 => NC (JOYIS2GND)
* A5 => PF5 => JOYISFIRE
*/
// set joystick pins to input
DDRF &= ~(_BV(PINF0) | _BV(PINF1) | _BV(PINF2) |
_BV(PINF3) | _BV(PINF4) | _BV(PINF5));
// activate pullups
PORTF |= _BV(PINF0) | _BV(PINF1) | _BV(PINF2) |
_BV(PINF3) | _BV(PINF4) | _BV(PINF5);
#else
# error "Unsupported Arduino board!"
#endif
}

2
src/joystick/null_joystick.c

@ -0,0 +1,2 @@
/* dummy */
void joy_init(){}

9
src/random/Makefile

@ -5,8 +5,13 @@ TARGET = objects_avr
include $(MAKETOPDIR)/defaults.mk
#for AVR
SRC = prng.c persistentCounter.c
ASRC = noekeon_asm.S memxor.S
ifeq ($(findstring atmega256,$(MCU)),atmega256)
# handmade assembler routines don't work on ATmega2560
SRC = prng.c persistentCounter.c noekeon.c memxor_c.c
else
SRC = prng.c persistentCounter.c
ASRC = noekeon_asm.S memxor.S
endif
#for simulator
SRC_SIM = prng.c persistentCounter.c noekeon.c memxor_c.c

12
src/random/noekeon.c

@ -39,7 +39,7 @@
#define RC_POS 0
static
void gamma(uint32_t* a){
void noekeon_gamma(uint32_t* a){
uint32_t tmp;
a[1] ^= ~((a[3]) | (a[2]));
@ -94,13 +94,13 @@ void noekeon_round(uint32_t* key, uint32_t* state, uint8_t const1, uint8_t const
theta(key, state);
((uint8_t*)state)[RC_POS] ^= const2;
pi1(state);
gamma(state);
noekeon_gamma(state);
pi2(state);
}
uint8_t rc_tab[]
uint8_t const rc_tab[]
#ifdef __AVR__
PROGMEM
PROGMEM
#endif
= {
/* 0x80, */
@ -146,7 +146,7 @@ void noekeon_enc(void* buffer, const void* key){
for(i=0; i<ROUND_NR; ++i){
noekeon_round((uint32_t*)keyb, (uint32_t*)buffer, rc, 0);
#ifdef __AVR__
rc = pgm_read_byte(rc_tab+i);
rc = pgm_read_byte(&rc_tab[i]);
#else
rc = rc_tab[i];
#endif
@ -177,7 +177,7 @@ void noekeon_dec(void* buffer, const void* key){
for(i=ROUND_NR-1; i>=0; --i){
#ifdef __AVR__
rc = pgm_read_byte(rc_tab+i);
rc = pgm_read_byte(&rc_tab[i]);
#else
rc = rc_tab[i];
#endif

12
src/scrolltext/font_small6.c

@ -1,6 +1,6 @@
#include "font.h"
unsigned int PROGMEM fontIndex_small6[] = {
unsigned int const PROGMEM fontIndex_small6[] = {
0, /* */
1, /* ! */
2, /* " */
@ -96,14 +96,14 @@ unsigned int PROGMEM fontIndex_small6[] = {
309, /* | */
310, /* } */
312, /* ~ */
316, /* ß */
321, /* ä */
324, /* ö */
328, /* ü */
316, /* */
321, /* */
324, /* */
328, /* */
331
};
unsigned char PROGMEM fontData_small6[] = {
unsigned char const PROGMEM fontData_small6[] = {
0x00, /* */
0x2f, /* # #### */
0x03, /* ## */

44
src/util.c

@ -21,24 +21,19 @@ extern jmp_buf newmode_jmpbuf;
void wait(int ms){
/* TCCR2: FOC2 WGM20 COM21 COM20 WGM21 CS22 CS21 CS20
CS22 CS21 CS20
0 0 0 stop
0 0 1 clk
0 1 0 clk/8
0 1 1 clk/32
1 0 0 clk/64
1 0 1 clk/128
1 1 0 clk/256
1 1 1 clk/1024
*/
//TCCR2 = 0x0D; //CTC Mode, clk/128
//OCR2 = (F_CPU/128000); //1000Hz
TCCR1B = (1<<WGM12) | 4;//CTC Mode, clk/256
OCR1A = (F_CPU/256000); //1000Hz
/* Always use Timer1 except for the Arduino/LoL Shield platform. */
#ifndef USER_TIMER0_FOR_WAIT
TCCR1B = _BV(WGM12) | _BV(CS12); //CTC Mode, clk/256
OCR1A = (F_CPU/256000); //1000Hz
/* Some Arduino/LoL Shield variants require Timer1 for multiplexing. Timer0, on
* the other hand, is free to use, which makes it a perfect candidate for our
* wait() function. */
#else
// disconnect OC0A and OC0B pins, turn on CTC mode, clk/256
TCCR0A = _BV(WGM01);
TCCR0B = _BV(CS02);
OCR0A = (F_CPU/256000); //1000Hz
#endif
for(;ms>0;ms--){
@ -60,9 +55,16 @@ void wait(int ms){
}
#endif
#if defined (__AVR_ATmega644P__) || defined (__AVR_ATmega644__) || defined (__AVR_ATmega328__) || (__AVR_ATmega1284P__) || defined (__AVR_ATmega1284__)
while(!(TIFR1&(1<<OCF1A))); //wait for compare match flag
TIFR1=(1<<OCF1A); //reset flag
#if defined (__AVR_ATmega1280__) || defined (__AVR_ATmega2560__) || defined (__AVR_ATmega32U4__) || defined (__AVR_ATmega644P__) || defined (__AVR_ATmega644__) || defined (__AVR_ATmega328__) || defined (__AVR_ATmega328P__) || (__AVR_ATmega1284P__) || defined (__AVR_ATmega1284__)
/* Timer1 for the masses */
# ifndef USER_TIMER0_FOR_WAIT
while(!(TIFR1 & _BV(OCF1A))); //wait for compare match flag
TIFR1 |= _BV(OCF1A); //reset flag
/* Timer0 for e.g. Arduino/LoL Shield */
# else
while(!(TIFR0 & _BV(OCF0A))); //wait for compare match flag
TIFR0 |= _BV(OCF0A); //reset flag
# endif
#else
while(!(TIFR&(1<<OCF1A))); //wait for compare match flag
TIFR=(1<<OCF1A); //reset flag

Loading…
Cancel
Save