 |
These forums are now closed Please see the new forums
|
| View previous topic :: View next topic |
| Author |
Message |
fsafstrom

Joined: 26 Dec 2006 Posts: 155 Location: San Antonio, Texas
|
Posted: Apr Tue 24, 2007 10:11 pm Post subject: 24x24 LED Game of Life... |
|
|
I guess you are never a true geek until you have written a Game of Life program.
Just to stand out of all the other geeks, let's write it in 6502 Assembler on a computer most people never heard on and on top of that, add a homebrew hardware that took months to build.
It's quite simple, hook up a 6522 VIA and map it to address $C040.
See thread, http://www.brielcomputers.com/phpBB2/viewtopic.php?t=190
Get an old ATX power supply (since I had one lying around) and convert it to a poor mans Lab supply.
http://www.wikihow.com/Convert-a-Computer-ATX-Power-Supply-to-a-Lab-Power-Supply
Then order some 8x8 LED units from China for $23 and wait one month to get them.
During this time, order free samples from http://www.maxim-ic.com/, it took me 4 months to get 10 Max7219...
They won't send you 10 of these puppies at once so just keep ordering...
Then get a few more parts for around $30 and spend another month soldering...
At the end, you will have a beautiful 24x24 LED display...
Testing the display:
The setup running game of life:
The not-so-easy-to-debug side of the board:
Here is a short Video I put on Photobucket:
Want your own replica ?
Check it out here => http://www.brielcomputers.com/replica1.html
And the 6502 assembler for your Replica,
| Code: | ; Game of Life on a 24x24 LED.
; Rules taken from Wikipedia, http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life...
; The universe of the Game of Life is an infinite two-dimensional orthogonal grid of square cells,
; each of which is in one of two possible states, live or dead.
; Every cell interacts with its eight neighbours, which are the cells that are directly horizontally,
; vertically, or diagonally adjacent. At each step in time, the following transitions occur:
; 1. Any live cell with fewer than two live neighbours dies, as if by loneliness.
; 2. Any live cell with more than three live neighbours dies, as if by overcrowding.
; 3. Any live cell with two or three live neighbours lives, unchanged, to the next generation.
; 4. Any dead cell with exactly three live neighbours comes to life.
; The initial pattern constitutes the 'seed' of the system.
; The first generation is created by applying the above rules simultaneously to every cell in the seed--
; births and deaths happen simultaneously, and the discrete moment at which this happens is sometimes called a tick.
; (In other words, each generation is based entirely on the one before.)
; The rules continue to be applied repeatedly to create further generations.
; ========================================================================================
; My version has a 24x24 grid displayed on the screen.
; There is no editor so edit Grid1 and re-compile.
; Note that I have two grids 26x26 bytes, but I only use 24x24 bytes for game of life.
; This is to make the calculations simpler when calculating number of neighbours.
; I don't have to do any calculations for wrap around or anything like that.
; START @ $1000
.org $1000
VIA = $C040
VIA_IOB = VIA ; Input/Output register B
VIA_IOA = VIA+1 ; Input/Output register A
VIA_DDRB = VIA+2 ; Data Direction Port B
VIA_DDRA = VIA+3 ; Data Direction Port A
VIA_T1CL = VIA+4 ; T1 Low Order Counter
VIA_T1CH = VIA+5 ; T1 High Order Counter
VIA_T1LL = VIA+6 ; T1 Low Order Latches
VIA_T1LH = VIA+7 ; T1 High Order Latches
VIA_T2CL = VIA+8 ; T2 Low Order Counter
VIA_T2CH = VIA+9 ; T2 High Order Counter
VIA_SR = VIA+10 ; Shift Register
VIA_ACR = VIA+11 ; Auxiliary Control Register
VIA_PCR = VIA+12 ; Pheriperal Control Register
VIA_IFR = VIA+13 ; Interrupt Flag Register
VIA_IER = VIA+14 ; Interrupt Enable Register
VIA_IOA2 = VIA+15 ; Input/Output register A, No handshake
; VIA stuff
add = $30 ; Address in Max7219
dat = $31 ; Data for Address
units = $32 ; LED units.
count = $33 ; Counter
rows = $34 ; Rows
cols = $35 ; Columns
temp = $36 ; Temp Storage
LEDGridl = $37 ; Grid Pointer Low
LEDGridh = $38 ; Grid Pointer High
temp2 = $39 ; Temp Storage 2
; Game Of Life Stuff
tick = $40 ; Even use grid 1, Odd use grid 2
row_counter = $41 ; count the rows to print.
GridLow = $42 ; Grid pointer.
GridHi = $43
WorkGridLow = $44 ; Grid Pointer for work grid.
WorkGridHi = $45
cell_count = $46 ; Used to count cells.
moves = $47 ; Just a few moves
MAIN
LDA #$09 ; 9 UNITS, 24X24 ledS
STA units
JSR init_VIA ; Init VIA
JSR init_max7219 ; Inint Dispaly
LDA #$00
STA tick ; Start with grid 1
LDA #$00 ; 256 moves
STA moves
MainLoop
JSR LifeToLED ; Conver Lif grid to LED grid
JSR showGridData ; Display it
JSR next_tick ; Calcualte next move in the Game of Life Universe.
INC tick ; Next tick
JSR delay ; Small delay
DEC moves ; Are we done yet ?
BNE MainLoop ; Nope, continue.
RTS
delay LDY #$80 ; Loop 256*128 times...
LDX #$00
.dloop1 DEX
BNE .dloop1
DEY
BNE .dloop1
RTS
LifeToLED LDA tick ; Test which grid to print.
AND #$01
BNE .load_grid2
LDA #<Grid1 ; Load Grid1 to pointer.
STA GridLow
LDA #>Grid1
STA GridHi
BRA .grid_loaded
.load_grid2 LDA #<Grid2 ; Load Grid2 to pointer.
STA GridLow
LDA #>Grid2
STA GridHi
.grid_loaded CLC ; Clear carry so we can add 27 to the grid address.
LDA GridLow
ADC #27 ; Add 27 bytes, that means we are on the second row, second column.
STA GridLow
BCC .no_carry ; If we got a carry, we need to increase the High byte.
INC GridHi
.no_carry LDA #<GridData ; Pointer to LED Grid
STA LEDGridl
LDA #>GridData
STA LEDGridh
LDA #$08 ; Count 8 bit per byte.
STA count
LDY #0 ; Start at second row in grid, one byte in.
STY cols ; Since it's zero, set offset in LED grid as well.
LDX #24 ; We want to set 24 LEDs per row.
STX row_counter
.grid_loop2 LDA (GridLow),Y ; Get byte in current grid.
BEQ .setDead ; If, zero it's a dead cell.
SEC
JSR updateLedGrid
BRA .set_Done
.setDead CLC
JSR updateLedGrid
.set_Done INY ; Next byte.
DEX ; Count down column.
BNE .grid_loop2 ; Are we done with this row ?
CLC ; Clear carry so we can add 26 to the grid address.
LDA GridLow
ADC #26 ; Add 26 bytes, that means we are on the next row, second column.
STA GridLow
BCC .no_carry2 ; If we got a carry, we need to increase the High byte.
INC GridHi
.no_carry2 LDY #0 ; Reset Y
LDX #24 ; Reset column bytes
DEC row_counter
BNE .grid_loop2
RTS
updateLedGrid ROL temp ; Shift in LED.
DEC count ; 8 bits yet ?
BNE ulgdone
LDA #$08
STA count ; Reset counter
STY temp2 ; Save Y
LDY cols ; Load offset in LED grid.
LDA temp ; Get LED data
STA (LEDGridl),y ; Store it in grid.
INC cols ; Increase offset.
LDY temp2 ; Restore Y.
ulgdone RTS
next_tick LDA tick
AND #$01
BNE .load_grid2
LDA #<Grid1 ; Load Grid1 to pointer.
STA GridLow
LDA #>Grid1
STA GridHi
LDA #<Grid2 ; Load Grid2 to Work grid pointer.
STA WorkGridLow
LDA #>Grid2
STA WorkGridHi
BRA .grid_loaded
.load_grid2 LDA #<Grid2 ; Load Grid2 to pointer.
STA GridLow
LDA #>Grid2
STA GridHi
LDA #<Grid1 ; Load Grid1 to Work grid pointer.
STA WorkGridLow
LDA #>Grid1
STA WorkGridHi
.grid_loaded CLC ; We will count cells on Grid(Low/Hi) and put them on WorkGrid(Low/Hi).
LDA WorkGridLow
ADC #27 ; Add 27 bytes, that means we are on the second row, second column.
STA WorkGridLow
BCC .no_carry ; If we got a carry, we need to increase the High byte.
INC WorkGridHi
.no_carry LDX #24 ; We want to scan 24 rows
STX row_counter
grid_loop JSR count_hood ; Count neighbours.
LDY #0 ; Zero Y
LDA cell_count ; Get result
CMP #02 ; Two cells ?
BCC cell_dies ; Less than two, cell dies.
CMP #3 ; Three cells ?
BEQ cell_birth ; Three cells will come a life or stay alive, just put one there.
BCS cell_dies ; If more than 3 cells, it dies.
LDY #27 ; We have two cells alive, copy cell from Grid(Low/Hi).
LDA (GridLow),Y ; Got the cell
LDY #0 ; Form pos 27 on Grid(*) to WorkGrid(*).
STA (WorkGridLow),Y ; Store cell.
BRA cell_count_done ; Continue on...
cell_dies LDA #0 ; Cell dies, A = 0
STA (WorkGridLow),Y ; Store cell.
BRA cell_count_done ; Continue on...
cell_birth LDA #1 ; Cell was born, A = 1
STA (WorkGridLow),Y ; Store cell.
cell_count_done INC WorkGridLow ; Next position
BNE .no_inc1
INC WorkGridHi
.no_inc1 INC GridLow ; Next position
BNE .no_inc2
INC GridHi
.no_inc2 DEX ; Next col.
BNE grid_loop ; Row not done, continue.
LDX #24 ; Reset col counter.
INC WorkGridLow ; Next position, for each row we have to move Two spaces.
BNE .no_inc3
INC WorkGridHi
.no_inc3 INC GridLow ; Next position 1 Grid
BNE .no_inc4
INC GridHi
.no_inc4 INC WorkGridLow ; Next position 2 WorkGrid
BNE .no_inc5
INC WorkGridHi
.no_inc5 INC GridLow ; Next position 2 Grid
BNE .no_inc6
INC GridHi
.no_inc6 DEC row_counter ; Next row.
BNE grid_loop ; Row not done, continue.
RTS
count_hood LDY #0
STY cell_count ; Zero cell count.
LDA (GridLow),Y ; Y=0, neighbour top left.
BEQ .no_add1
INC cell_count
.no_add1 LDY #1
LDA (GridLow),Y ; Y=1, neighbour top middle.
BEQ .no_add2
INC cell_count
.no_add2 LDY #2
LDA (GridLow),Y ; Y=2, neighbour top right.
BEQ .no_add3
INC cell_count
.no_add3 LDY #26
LDA (GridLow),Y ; Y=26, neighbour to the left.
BEQ .no_add4
INC cell_count
.no_add4 LDY #28
LDA (GridLow),Y ; Y=28, neighbour to the right.
BEQ .no_add5
INC cell_count
.no_add5 LDY #52
LDA (GridLow),Y ; Y=52, neighbour to the bottom left.
BEQ .no_add6
INC cell_count
.no_add6 LDY #53
LDA (GridLow),Y ; Y=53, neighbour to the bottom middle.
BEQ .no_add7
INC cell_count
.no_add7 LDY #54
LDA (GridLow),Y ; Y=53, neighbour to the bottom middle.
BEQ .no_add8
INC cell_count
.no_add8 RTS
showGridData
LDA #<GridData
STA LEDGridl
LDA #>GridData
STA LEDGridh
LDY #1 ; Start with row 1
STY rows
LDY #8
sty count ; Count 8 rows
sgdloop1 LDX rows ; Row to X
STX add ; Store in address
STX temp ; Prepare to multiply by three
CLC
ROL temp
LDA rows
ADC temp
ADC #47
TAY ; Y=(row*3) + 47, this is 9:th chars row.
LDX #3 ; do three chars
STX temp2 ; three times = 9 chars.
.loop1 LDA (LEDGridl),y
STA dat
JSR SendData
DEY ; point to previous chars byte.
DEX ; Three chars ?
BNE .loop1
TYA
SEC
SBC #21
TAY ; Y = Y - 21, move back 3 chars and compensate for the three rows already done.
LDX #3 ; Three more chars to go.
DEC temp2 ; did we do all 9 chars ?
BNE .loop1
JSR LatchData
INC rows ; Next row
DEC count ; Did we do them all ?
BNE sgdloop1 ; Nope, recalculate etc...
RTS
init_VIA LDA #$FF ; Make port A output.
STA VIA_DDRA
LDA #$00 ; Make ports low.
STA VIA_IOA
LDA VIA_ACR ; Load ACR
AND #$E3 ; Zero bit 4,3,2.
ORA #$18 ; Shift out using Phi2
STA VIA_ACR
RTS
init_max7219 LDA #10 ; Intensity address
STA add
LDA #10 ; 10 out of 15
STA dat
JSR SendAllUnits
JSR LatchData
LDA #11 ; Scan limits (How many rows)
STA add
LDA #7 ; All 8 rows
STA dat
JSR SendAllUnits
JSR LatchData
LDA #9 ; Decode mode
STA add
LDA #0 ; No decoding, use all 8 bits as data
STA dat
JSR SendAllUnits
JSR LatchData
LDA #12 ; Shutdown register
STA add
LDA #1 ; No shutdown, normal operation
STA dat
JSR SendAllUnits
JSR LatchData
RTS
SendAllUnits LDY units ; Send same data to all units
sauloop JSR SendData
DEY
BNE sauloop
RTS
SendData LDA add ; Address for MAX7219
STA VIA_SR ; Shift it...
.wait1 LDA VIA_IFR ; Are we done yet ?
AND #$04
BEQ .wait1 ; Nope, continue...
LDA dat ; Data for MAX7219
STA VIA_SR ; Shift it...
.wait2 LDA VIA_IFR ; Are we done yet ?
AND #$04
BEQ .wait2 ; Nope, continue...
RTS
LatchData LDA #$01 ; Set Pin PA0 high
STA VIA_IOA ; This will load the data...
LDA #$00 ; Set Pin PA0 Low
STA VIA_IOA ; Done loading the data, ready for more...
RTS
GridData
.BYTE $7E, $00, $00 ; 1
.BYTE $7E, $00, $00 ; 2
.BYTE $66, $00, $00 ; 3
.BYTE $66, $3C, $00 ; 4
.BYTE $0C, $3C, $00 ; 5
.BYTE $0C, $66, $00 ; 6
.BYTE $18, $66, $00 ; 7
.BYTE $18, $66, $3C ; 8
.BYTE $18, $66, $3C ; 9
.BYTE $18, $3C, $66 ; 10
.BYTE $18, $3C, $66 ; 11
.BYTE $18, $66, $66 ; 12
.BYTE $18, $66, $66 ; 13
.BYTE $18, $66, $3E ; 14
.BYTE $00, $66, $3E ; 15
.BYTE $00, $3C, $06 ; 16
.BYTE $00, $3C, $06 ; 17
.BYTE $00, $00, $66 ; 18
.BYTE $00, $00, $66 ; 19
.BYTE $00, $00, $3C ; 20
.BYTE $00, $00, $3C ; 21
.BYTE $11, $00, $00 ; 22
.BYTE $00, $11, $00 ; 23
.BYTE $00, $00, $11 ; 24
; .org $1300 ; For Debug
Grid1 .BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 1
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 2
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 3
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 4
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 5
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 6
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 7
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 8
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 9
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 10
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 11
.BYTE 0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0 ; 12
.BYTE 0,0,0,0,0,0,0,0,0,1,0,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0 ; 13
.BYTE 0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0 ; 14
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 15
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 16
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 17
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 18
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 19
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 20
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 21
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 22
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 23
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 24
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 25
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 26
; .org $1600 ; For Debug
Grid2 .BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 1
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 2
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 3
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 4
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 5
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 6
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 7
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 8
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 9
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 10
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 11
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 12
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 13
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 14
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 15
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 16
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 17
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 18
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 19
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 20
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 21
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 22
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 23
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 24
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 25
.BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 26
|
Fixed bug in code 4/25, now it works better...
4/25 Added Video link.
4/26 Added link to Replica Home page.
Last edited by fsafstrom on Apr Thu 26, 2007 10:09 am; edited 3 times in total |
|
| Back to top |
|
 |
fsafstrom

Joined: 26 Dec 2006 Posts: 155 Location: San Antonio, Texas
|
Posted: Apr Wed 25, 2007 12:06 am Post subject: |
|
|
I just had to take a break before I document how this thing works...
The 24x24 LED display is actually nine 8x8 LED units.
Each 8x8 unit is controlled by a MAX 7219 LED driver, if you look at the test I made, you can see how they are organized.
So that is basically LED unit 1-9 from top left to bottom right.
The Max 7219 keeps track of which LEDs I want to light up, so I only need to send the data once and then the chip will do the rest for me.
Each row (cathode) in the LED unit is connected to the digit section on the Max 7219 and each column (Anode) to the Segment section.
The Max 7219 accepts serial data so the chips are daisy chained together, however the clock and latch are parallel and goes to all chips in parallel.
Data basically flows from one chip to another so the most efficient way of sending data is to send 9 commands in a row and then latch it (tell the driver to use the data).
So when sending graphical data, you send 9 columns and then latch it.
Then row two, three and so on to row 8.
The VIA (6522) have a shift register so it's really doing a lot of work for me, all I need to do is load the shift register and tell it to send the data to the Max 7219.
Let me know if you have any questions or comments.
MAX 7219 Datasheet,
http://datasheets.maxim-ic.com/en/ds/MAX7219-MAX7221.pdf |
|
| Back to top |
|
 |
cheese1113
Joined: 13 Nov 2005 Posts: 91 Location: Reedley, CA
|
Posted: Apr Wed 25, 2007 12:21 pm Post subject: |
|
|
That is awesome! I think that there is potential for games with this set up!! _________________ Max Wooden |
|
| Back to top |
|
 |
fsafstrom

Joined: 26 Dec 2006 Posts: 155 Location: San Antonio, Texas
|
Posted: Apr Wed 25, 2007 3:14 pm Post subject: |
|
|
Yes, there will soon be a LED Pong game, maybe with a SID 6581 for sound effects or a SoundGin...
IF I can get the SoundGin to work that is, they don't seem to work to well on solderless breadboards...  |
|
| Back to top |
|
 |
cheese1113
Joined: 13 Nov 2005 Posts: 91 Location: Reedley, CA
|
|
| Back to top |
|
 |
fsafstrom

Joined: 26 Dec 2006 Posts: 155 Location: San Antonio, Texas
|
Posted: Apr Wed 25, 2007 9:10 pm Post subject: |
|
|
I actually sent the link to Hack a day...
I'm glad they picked it up.
Here is a short Video I put on Photobucket:
 |
|
| Back to top |
|
 |
ethan
Joined: 02 May 2007 Posts: 1
|
Posted: May Wed 02, 2007 12:21 pm Post subject: |
|
|
Very nice. I can probably figure it out the hard way by inspecting the code, but how did you attach the 6522 to the array of 7219s? I'm guessing CB2 is data-in to the first 7219, but what are the other pin assignments?
Thanks and congrats on this. I need to track down a pile of LED matrices. I already have a few 7219s on hand.
-ethan |
|
| Back to top |
|
 |
fsafstrom

Joined: 26 Dec 2006 Posts: 155 Location: San Antonio, Texas
|
Posted: May Wed 02, 2007 2:14 pm Post subject: |
|
|
Hi Ethan,
The Load data (pin 12) on Max 7219 is connected to PA0 (pin 2) on the 6522.
Clock (pin 13) on Max 7219 is connected to CB1 (pin 18 ) on the 6522.
Data In (pin 1) on Max 7219 is connected to CB2 (pin 19) on the 6522.
The VIA (6522) is setup with port A as output and for the shift register to shift out at the pace of Phi2.
| Code: | init_VIA LDA #$FF ; Make port A output.
STA VIA_DDRA
LDA #$00 ; Make ports low.
STA VIA_IOA
LDA VIA_ACR ; Load ACR
AND #$E3 ; Zero bit 4,3,2.
ORA #$18 ; Shift out using Phi2
STA VIA_ACR
RTS
|
To send (or shift out) data, simply store the value you want to shift out in VIA_SR.
Then wait for bit 2 to be set in the VIA_IFR, that means the shift out is done.
| Code: | SendData LDA add ; Address for MAX7219
STA VIA_SR ; Shift it...
.wait1 LDA VIA_IFR ; Are we done yet ?
AND #$04
BEQ .wait1 ; Nope, continue...
|
Then latch the data by setting the Load pin high and then low again.
| Code: | LatchData LDA #$01 ; Set Pin PA0 high
STA VIA_IOA ; This will load the data...
LDA #$00 ; Set Pin PA0 Low
STA VIA_IOA ; Done loading the data, ready for more...
RTS
|
That's it, have fun...
/Bamse |
|
| Back to top |
|
 |
logjam
Joined: 15 May 2007 Posts: 14
|
|
| Back to top |
|
 |
fsafstrom

Joined: 26 Dec 2006 Posts: 155 Location: San Antonio, Texas
|
Posted: May Tue 15, 2007 9:20 pm Post subject: |
|
|
Now that's an LED display...
I'm not sure I dare to ask, but how many LED's is in that display ? |
|
| Back to top |
|
 |
logjam
Joined: 15 May 2007 Posts: 14
|
Posted: May Tue 15, 2007 11:25 pm Post subject: |
|
|
19,008. It is 192x99, or 24x9 characters of 8x11 pixels.
I thought I'd be able to refresh 30 rows when I made the boards. I did some tests with my LEDs and found that I could only do a little over 10. I decided to refresh 11 rows at once since that is how many rows are in one character. The display will be refreshed as 1728x11.
I'm thinking about a different display of about 64x48. This display would display greyscale data. I took some movies I had and converted them to 64x48 greyscale. You have to squint to see them, but it was pretty good!
64x48 greyscale is 3072 bytes per frame. 4 bits of gray scale might be enough, so we could get 1536 bytes per frame.
It would be fun to use the Apple 1 as a source for the streaming video. It would take 15-30k per second so the 6502 would have no time to do anything but receive frames... |
|
| Back to top |
|
 |
fsafstrom

Joined: 26 Dec 2006 Posts: 155 Location: San Antonio, Texas
|
Posted: May Wed 16, 2007 11:06 am Post subject: |
|
|
Very impressive...
What kind of hardware do you use to drive the LED's ?
The MAX7219 "only" handles 8x8 LED's so my guess would be some kind of custom hardware...
By the way, I calculated my power requirement to be 3 Amps for the 575 LED's with full intensity.
For 19008 LED's that would translate into 100 Amps for the whole board...
On the other hand, I never measured the actual consumption so I could be way off... |
|
| Back to top |
|
 |
logjam
Joined: 15 May 2007 Posts: 14
|
|
| Back to top |
|
 |
logjam
Joined: 15 May 2007 Posts: 14
|
Posted: May Thu 17, 2007 3:06 am Post subject: |
|
|
| That Root.sch I posted is for 64 columns. There are 1728 columns total. There are an estimated 8,000 solder joints in the driver boards. I am not looking forward to that. |
|
| Back to top |
|
 |
fsafstrom

Joined: 26 Dec 2006 Posts: 155 Location: San Antonio, Texas
|
Posted: Nov Wed 28, 2007 9:00 am Post subject: |
|
|
I saw that this thread passed 10 000 views, kewl...
Let's hope that at least one or two people got interested enough in the Replica to buy one...  |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|