Color buffer initialized with random values

This commit is contained in:
Christophe Meneboeuf 2016-10-04 00:49:37 +02:00
parent 9687b85d0f
commit 3d08413c9c
9 changed files with 82 additions and 367 deletions

1
.gitignore vendored
View File

@ -3,4 +3,5 @@
*.o
*.map
*.dsk
*.bak
gol

View File

@ -5,12 +5,12 @@ LINUX_OUT := gol.out
APPLE2_CL := $(CC65_HOME)/bin/cl65
APPLE2_CC := $(CC65_HOME)/bin/cc65
APPLE2_SRC := gol_apple2.c gol_apple2_optimized.asm gfx.asm
APPLE2_SRC := gol_apple2.c gol_apple2_optimized.asm gfx.asm rnd_colors.asm
APPLE2_MAP := gol_apple2.map
APPLE2_CFLAGS := -Oirs -v -t apple2
APPLE2_OUT := gol.a2
all: linux apple2
all: apple2
linux: $(LINUX_SRC)
$(LINUX_CC) -o $(LINUX_OUT) $? $(LINUX_CFLAGS)

View File

@ -3,3 +3,4 @@ Time to 50 iterations
50ef808 : 111:94
555db95 : 38:51
d0f9aef : 15:43
9687b85 : 27:27

22
gfx.asm
View File

@ -107,11 +107,11 @@ _gfx_fill:
;saving the context
TAX
LDA tmp1
jsr pusha
JSR pusha
LDA ptr1
jsr pusha
JSR pusha
LDA ptr2
jsr pusha
JSR pusha
TXA
;duplicate nybble color
STA tmp1
@ -163,11 +163,11 @@ fill_end:
;displaying the page we filled
; TODO SWITCH PAGES !!
;restoring the context
jsr popa
JSR popa
STA ptr2
jsr popa
JSR popa
STA ptr1
jsr popa
JSR popa
STA tmp1
RTS
@ -179,15 +179,15 @@ _gfx_pixel:
;saving the context
TAX
LDA tmp3
jsr pusha
JSR pusha
LDA tmp2
jsr pusha
JSR pusha
;LDA tmp1
;jsr pusha
;JSR pusha
LDA ptr1
jsr pusha
JSR pusha
LDA ptr2
jsr pusha
JSR pusha
TXA
STA tmp3 ;coord_y

View File

@ -8,6 +8,7 @@
#include <conio.h>
#include "gfx.h"
#include "rnd_colors.h"
/******************* FUNCTION DEFINITIONS **************/
@ -65,7 +66,11 @@ int main( int argc, char** argv )
(void)argc;
(void)argv;
printf("PAUSE");
cgetc();
init_asm( (uint8_t*)Cells, (uint8_t*)Cells_Future );
init_rnd_color();
/* Running the state machine */
while( State != STATE_QUIT )
@ -118,6 +123,7 @@ void quit( void )
void init_display( void )
{
register uint8_t i;
clrscr();
gfx_init( LOWRES, SPLIT );
gfx_fill( BLACK );
for( i = 0u; i < NB_COLUMNS; ++i ) {

View File

@ -1,267 +0,0 @@
/* Standard headers */
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
/* Specific headers */
#include <conio.h>
/******************* FUNCTION DEFINITIONS **************/
void init_display( void ); /* Inits displayed playfield */
void draw_cells( void ); /* Draws the actual cells */
void editor( void ); /* lets the user draw some starting cells */
uint8_t toggle_cell( const uint8_t x, const uint8_t y ); /* toggles the cell at the given coordinates. \
Returns the cursor X position */
void run( void ); /* runs the simulation */
void __fastcall__ update( uint8_t* cells, uint8_t* cells_future ); /* updates the simulation */
void __fastcall__ update_asm( uint8_t* cells, uint8_t* cells_future ); /* updates the simulation */
uint8_t __fastcall__ count_neighbours( uint8_t* cell ); /* counts nb neighbours of the cell */
void quit( void );
/******************* CUSTOM TYPES AND VALUES DEFINITIONS ****************/
#define NB_LINES 23u
#define NB_COLUMNS 40u
#define ALIVE 1u
#define DEAD 0u
#define SPRITE_ALIVE '0'
#define SPRITE_DEAD ' '
#define STATE_INIT 0u
#define STATE_EDITOR 1u
#define STATE_RUN 2u
#define STATE_QUIT 3u
uint8_t State = STATE_INIT;
#define NO_KEY '\0'
char KeyPressed = NO_KEY;
/******************* STATIC GLOBAL VARIABLES ******************/
uint8_t Cells[ NB_COLUMNS ][ NB_LINES ];
uint8_t Cells_Future[ NB_COLUMNS ][ NB_LINES ];
uint8_t Cells_Initial[ NB_COLUMNS ][ NB_LINES ];
/******************** CODE ************************/
int main( int argc, char** argv )
{
(void)argc;
(void)argv;
/* Running the state machine */
while( State != STATE_QUIT )
{
switch (State) {
case STATE_INIT:
memset( Cells, DEAD, sizeof(Cells) );
init_display();
State = STATE_EDITOR;
break;
case STATE_EDITOR:
editor();
State = STATE_RUN;
break;
case STATE_RUN:
run();
if( KeyPressed == 'e' ) { /* Go back to editor */
State = STATE_EDITOR;
} else if( KeyPressed == 'r' ) { /* reset and rerun */
memcpy( Cells, Cells_Initial, sizeof(Cells) );
memcpy( Cells_Future, Cells_Initial, sizeof(Cells_Future) );
draw_cells();
} else if( KeyPressed == 'q' ) { /* quit */
State = STATE_QUIT;
}
break;
default:
printf("ERROR!");
State = STATE_QUIT;
break;
}
}
quit();
return 0;
}
void quit( void )
{
uint8_t x, y;
screensize (&x, &y);
gotoxy( 1u, y-1u );
printf("BYE BYE!");
exit(0);
}
void init_display( void )
{
clrscr();
chlinexy (1u, 0u, NB_COLUMNS-2u );
chlinexy (1u, NB_LINES-1u, NB_COLUMNS-2u );
cvlinexy (0u, 1u, NB_LINES-1u );
cvlinexy (NB_COLUMNS-1u, 1u, NB_LINES-1u );
cputcxy ( 0u, 0u, '+' );
cputcxy ( 0u , NB_LINES-1u,'+');
cputcxy ( NB_COLUMNS-1u, 0u,'+');
cputcxy ( NB_COLUMNS-1u, NB_LINES-1u,'+');
}
void draw_cells( void ) {
uint8_t x, y;
for( x = 1u; x < NB_COLUMNS - 1u; ++x )
{
for( y = 1u; y < NB_LINES - 1u; ++y )
{
if( Cells[x][y] == ALIVE ) {
cputcxy ( x, y, SPRITE_ALIVE );
} else {
cputcxy ( x, y, SPRITE_DEAD );
}
}
}
}
void editor( void )
{
#define KEY_LEFT 'j'
#define KEY_DOWN 'k'
#define KEY_UP 'i'
#define KEY_RIGHT 'l'
uint8_t quit, x, y;
gotoxy( 0u, NB_LINES );
printf("EDITOR (D)one");
x = NB_COLUMNS >> 1u;
y = NB_LINES >> 1u;
gotoxy(x,y);
quit = 0;
while ( quit == 0)
{
cursor(1);
KeyPressed = cgetc();
switch (KeyPressed) {
case KEY_LEFT:
if( x > 1u ) { gotoxy( --x, y ); }
break;
case KEY_DOWN:
if( y < NB_LINES-2u ) { gotoxy( x, ++y ); }
break;
case KEY_UP:
if( y > 1u ) { gotoxy( x, --y ); }
break;
case KEY_RIGHT:
if( x < NB_COLUMNS-2u ) { gotoxy( ++x, y ); }
break;
case ' ':
x = toggle_cell( x, y );
break;
case 'd':
quit = 1;
break;
}
}
/* Cells was updated by the calls to toggle() */
memcpy( Cells_Future, Cells, sizeof(Cells_Future) );
memcpy( Cells_Initial, Cells, sizeof(Cells_Initial) );
}
uint8_t toggle_cell( const uint8_t x, const uint8_t y )
{
char* cell;
if( x == 0u || x >= NB_COLUMNS-1u || y == 0u || y >= NB_LINES-1u ) { return x; }
cell = &Cells[x][y];
if( *cell == DEAD ) {
*cell = ALIVE;
cputc( SPRITE_ALIVE );
} else {
*cell = DEAD;
cputc( SPRITE_DEAD );
}
return wherex ();
}
void run( void )
{
char str_nb_iteration [5];
uint16_t nb_iterations = 2u;
KeyPressed = NO_KEY;
cursor(0);
//+ DEBUG
gotoxy(0,0);
printf("Cells:0x%x - Cells_future:0x%x",(uint16_t)(&Cells[0][0]),(uint16_t)(&Cells_Future[0][0]));
cgetc();
//- DEBUG
gotoxy( 0u, NB_LINES );
printf("Iteration:1 (R)eset (E)ditor (Q)uit");
while( KeyPressed == NO_KEY)
{
/* Evolving the cells */
update_asm( &Cells[0][0], &Cells_Future[0][0] );
/* Printing iterations */
gotoxy(10u, NB_LINES);
printf( itoa(nb_iterations++, str_nb_iteration, 10) );
/* Testing key pressed */
if( kbhit() ){
KeyPressed = cgetc();
break;
}
}
}
void __fastcall__ update( uint8_t* cells, uint8_t* cells_future )
{
uint8_t x, y;
uint8_t* cell_neighbourhoud = cells; // cell_neighbourhoud = &Cells[0][0];
uint8_t* cell = cell_neighbourhoud + NB_LINES + 1u; // cell = &Cells[1][1];
uint8_t* cell_future = cells_future + NB_LINES + 1u; // cell_future = &Cells_Future[1][1];
for( y = 1u; y < NB_LINES - 1u; ++y )
{
uint8_t* cell_line = cell;
uint8_t* cell_neighbourhoud_line = cell_neighbourhoud;
uint8_t* cell_future_line = cell_future;
for( x = 1u; x < NB_COLUMNS - 1u; ++x)
{
uint8_t nb_neighbours = count_neighbours( cell_neighbourhoud_line );
if( *cell_line == ALIVE && \
(nb_neighbours < 2u || nb_neighbours > 3u )
) {
*cell_future_line = DEAD;
cputcxy( x, y, SPRITE_DEAD );
}
else if( *cell_line == DEAD && nb_neighbours == 3u ) {
*cell_future_line = ALIVE;
cputcxy( x, y, SPRITE_ALIVE );
}
cell_line += NB_LINES;
cell_neighbourhoud_line += NB_LINES;
cell_future_line += NB_LINES;
}
++cell;
++cell_neighbourhoud;
++cell_future;
}
memcpy( cells, cells_future, sizeof(Cells) );
}

View File

@ -1,87 +0,0 @@
.include "apple2.inc"
.include "zeropage.inc"
.export _count_neighbours
.export _update_asm
.import _Cells
.import _Cells_Future
.define NB_LINES 23
.define NB_COLUMNS 40
.define JUMP_BEGINNING_NEXT_LINE NB_LINES - 2
; ******************
;void __fastcall__ update( uint8_t* cells, uint8_t* cells_future )
;cells_future in sreg
;cells in ptr1
;cells in neighbourhoud in ptr2
;current cell in ptr3
;future cell in ptr4
_update_asm:
;preambule
STA ptr1
STX ptr1+1
STA ptr2
STX ptr2+1
RTS
; ******************
;uint8_t __fastcall__ count_neighbours( uint8_t* cell )
;param: cell is in AX
_count_neighbours:
;ASSUMPTIONS:
; -> A and Y (offset to starting ptr) won't overflow!
;init
STA ptr1
STX ptr1+1
LDA #0
LDY #0
CLC
;acc 1st row
ADC (ptr1),Y
INY
ADC (ptr1),Y
INY
ADC (ptr1),Y
;next row
STA tmp1
TYA
ADC #JUMP_BEGINNING_NEXT_LINE
TAY
LDA tmp1
ADC (ptr1),Y
INY
INY
ADC (ptr1),Y
;next row
STA tmp1
TYA
ADC #JUMP_BEGINNING_NEXT_LINE
TAY
LDA tmp1
ADC (ptr1),Y
INY
ADC (ptr1),Y
INY
ADC (ptr1),Y
;return
TAX
LDX #0
RTS

55
rnd_colors.asm Executable file
View File

@ -0,0 +1,55 @@
.include "apple2.inc"
.include "zeropage.inc"
.import pusha
.import popa
.export _init_rnd_color
.BSS
Colors: .dword $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0
.dword $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0
.dword $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0
.dword $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0
.CODE
; void __fastcall__ init_rnd_color( void )
; Fills Colors with 8bits random values
; Code inspired by: http://www.codebase64.org/doku.php?id=base:small_fast_8-bit_prng
_init_rnd_color:
seed := tmp1
LDA tmp1
JSR pusha
LDA #123
STA seed
LDX #0
loop: ; for X = 0 to 255
LDA seed
BEQ doEor
ASL
BEQ noEor ;if the input was $80, skip the EOR
BCC noEor
doEor:
EOR #$2B
noEor:
STA seed
AND #$0F ; color is in lo-nybble
BEQ loop ; 0 (BLACK) not accepted
CMP #$0F
BEQ loop ; 0xF (WHITE) not accepted
STA Colors,X
INX ; next X
CPX #0
BEQ loop_end
CLC
BCC loop
loop_end:
JSR popa
STA tmp1
RTS

6
rnd_colors.h Executable file
View File

@ -0,0 +1,6 @@
#ifndef __RND_COLOTS__H_
#define __RND_COLOTS__H_
void init_rnd_color( void ); /* Inits a buffer of 256 random colors */
#endif