diff --git a/gfx.asm b/gfx.asm index 413fb69..d2c995f 100755 --- a/gfx.asm +++ b/gfx.asm @@ -3,6 +3,8 @@ .import pusha .import popa + .import pushax + .import popax .export _mode_text .export _gfx_init @@ -103,8 +105,9 @@ init_end: ;void __fastcall__ gfx_fill( uint8_t color ) ; Fills the screen with the given color _gfx_fill: -; TODO SWITCH PAGES !! + ; TODO SWITCH PAGES !! ;saving the context + ;WARNING context us not saved properly: ptr+1 not saved! TAX LDA tmp1 JSR pusha @@ -176,28 +179,32 @@ fill_end: ;void __fastcall__ gfx_pixel( uint8_t color, uint8_t coord_x, uint8_t coord_y ) ; Draws a pixel at the given coordinates on the Page_Future _gfx_pixel: + ;aliases + coord_y := tmp3 ;saving the context - TAX + PHA LDA tmp3 JSR pusha LDA tmp2 JSR pusha - ;LDA tmp1 - ;JSR pusha + LDA tmp1 + JSR pusha LDA ptr1 - JSR pusha + LDX ptr1+1 + JSR pushax LDA ptr2 - JSR pusha - TXA + LDX ptr2+1 + JSR pushax + PLA - STA tmp3 ;coord_y + STA coord_y ;coord_y ; Modify the color depending on the pixel's line parity AND #1 BEQ even odd: ; pixel is on an odd line LDA #$0F ;To or with the other nybble when writting the pixel STA tmp1 - LDY #(1+4) ;there were 4 pushes to save registers + LDY #(1+7) ;there were 7 pushes to save registers LDA (sp),Y ;color ASL ;shift the color to put it on high nybble ASL @@ -208,7 +215,7 @@ odd: ; pixel is on an odd line even: ; pixel is on an even line LDA #$F0 ;To or with the other nybble when writting the pixel STA tmp1 - LDY #(1+4) ;there were 4 pushes to save registers + LDY #(1+7) ;there were 7 pushes to save registers LDA (sp),Y ;color oddeven: STA tmp2 @@ -222,7 +229,7 @@ oddeven: STA ptr1+1 ; get the line adress and store it in ptr2 - LDA tmp3 + LDA coord_y LSR ASL TAY @@ -233,7 +240,7 @@ oddeven: STA ptr2+1 ; get coord_x - LDY #4 ;there were 4 pushes to save registers + LDY #7 ;there were 4 pushes to save registers LDA (sp),Y ; draw TAY @@ -243,12 +250,14 @@ oddeven: STA (ptr2),Y ;restoring the context - JSR popa + JSR popax STA ptr2 - JSR popa + STX ptr2+1 + JSR popax STA ptr1 - ;JSR popa - ;STA tmp1 + STX ptr1+1 + JSR popa + STA tmp1 JSR popa STA tmp2 JSR popa diff --git a/gol_apple2.c b/gol_apple2.c index 77dc3d2..f19ed6d 100755 --- a/gol_apple2.c +++ b/gol_apple2.c @@ -22,7 +22,7 @@ void toggle_cell( const uint8_t x, const uint8_t y ); /* toggles the cell at the void run( void ); /* runs the simulation */ void __fastcall__ update( void ); /* updates the simulation */ -void __fastcall__ update_asm( void ); /* updates the simulation */ +void __fastcall__ update_wip( void ); /* updates the simulation */ uint8_t __fastcall__ count_neighbours( uint8_t* cell ); /* counts nb neighbours of the cell */ @@ -231,16 +231,17 @@ void toggle_cell( const uint8_t x, const uint8_t y ) void run( void ) { + #define PRINTF_LINE 21u char str_nb_iteration [5]; uint16_t nb_iterations = 2u; KeyPressed = NO_KEY; - gotoxy( 0u, 23 ); - printf("Iteration:1 (R)eset (E)ditor (Q)uit"); + gotoxy( 0u, PRINTF_LINE ); + printf("Iteration:1\n\n(R)eset (E)ditor (Q)uit"); while( KeyPressed == NO_KEY) { /* Evolving the cells */ - update( ); - gotoxy(10u, 23); + update_wip( ); + gotoxy(10u, PRINTF_LINE); printf( itoa(nb_iterations++, str_nb_iteration, 10) ); /* Testing key pressed */ if( kbhit() ) { diff --git a/gol_apple2_optimized.asm b/gol_apple2_optimized.asm index 115d32d..47220d3 100755 --- a/gol_apple2_optimized.asm +++ b/gol_apple2_optimized.asm @@ -2,18 +2,26 @@ .include "apple2.inc" .include "zeropage.inc" + .import _memcpy .import popa + .import popax + .import pusha + .import pushax + .import _gfx_pixel + .import _get_color .export _init_asm .export _count_neighbours .export _update_wip - .define NB_LINES 40 .define NB_COLUMNS 40 .define JUMP_BEGINNING_NEXT_LINE NB_LINES - 2 - + .define ALIVE 1 + .define DEAD 0 + .define BLACK 0 + .define CELLS_SIZE 1600 ; ****************** @@ -42,22 +50,22 @@ cell := ptr4 ADC (cell),Y ;next row - STA tmp1 + STA tmp4 TYA ADC #JUMP_BEGINNING_NEXT_LINE TAY - LDA tmp1 + LDA tmp4 ADC (cell),Y INY INY ADC (cell),Y ;next row - STA tmp1 + STA tmp4 TYA ADC #JUMP_BEGINNING_NEXT_LINE TAY - LDA tmp1 + LDA tmp4 ADC (cell),Y INY ADC (cell),Y @@ -139,6 +147,17 @@ _update_wip: cell_curr := ptr1 cell_neighbourhoud_line := ptr2 cell_future_line := ptr3 +nb_neighbours := tmp1 + + LDA ptr1 + LDX ptr1+1 + JSR pushax + LDA ptr2 + LDX ptr2+1 + JSR pushax + LDA ptr3 + LDX ptr3+1 + JSR pushax ;preambule ; cell_neighbourhoud = Cells @@ -147,27 +166,121 @@ cell_future_line := ptr3 add_16 cell_line, cell_neighbourhoud, #NB_LINES+1, #0 ; cell_future = Cells_Future + NB_LINES + 1u add_16 cell_future, Cells_Future, #NB_LINES+1, #0 + ; loop : for( y = 1u; y < NB_LINES - 1u; ++y ) LDY #1 loop_y: - CPY #NB_LINES-1 - BEQ end_y + ;those macros don't touch Y copy_16 cell_curr, cell_line copy_16 cell_neighbourhoud_line, cell_neighbourhoud copy_16 cell_future_line, cell_future - ;PAS BESOIN DE CES POINTEURS: ADRESSE DE BASE + X ??? + STY tmp3 + CPY #NB_LINES-1 + BEQ end_y + + ; loop : for( x = 1u; x < NB_COLUMNS - 1u; ++x ) + LDX #1 loop_x: - CPX #NB_LINES-1 - BEQ end_x + CPX #NB_COLUMNS-1 + BEQ end_x - ;TODO + ; uint8_t nb_neighbours = count_neighbours( cell_neighbourhoud_line ) + STX tmp2 + LDA cell_neighbourhoud_line + LDX cell_neighbourhoud_line+1 + JSR _count_neighbours ; nb_neighbours in A + STA nb_neighbours + JMP tst_alive +next_x: + add_16 cell_curr, cell_curr, #NB_LINES, #0 + add_16 cell_neighbourhoud_line, cell_neighbourhoud_line, #NB_LINES, #0 + add_16 cell_future_line, cell_future_line, #NB_LINES, #0 + ; next X + LDX tmp2 INX - CLC - BCC loop_x + JMP loop_x end_x: + add_16 cell_line, cell_line, #1, #0 + add_16 cell_neighbourhoud, cell_neighbourhoud, #1, #0 + add_16 cell_future, cell_future, #1, #0 + ; next Y + LDY tmp3 INY - CLC - BCC loop_y + JMP loop_y end_y: + + JMP end_update ; This jump allows conditional branching + ; tst_dead section in the following (optimization) + +; *** TIP */ +; those should be placed inside loop_x (search for JMP tst_alive) +; they are placed here not to overflow the 8 bit range of conditional branching +tst_dead: + LDY #0 + LDA (cell_curr),Y + CMP #DEAD + BNE next_x + LDA nb_neighbours + CMP #3 + BNE next_x + ; a cell is born + LDA #ALIVE + STA (cell_future_line),Y + JSR _get_color ;random color in A + JSR pusha + LDA tmp2 + JSR pusha + LDA tmp3 + JSR _gfx_pixel + JMP next_x + +tst_alive: + LDY #0 + LDA (cell_curr),Y + CMP #ALIVE + BNE tst_dead + LDA nb_neighbours + CLC + ADC #$FE + BCC kill_cell ; if nb_neighbours < 2 + LDA nb_neighbours + CLC + ADC #$FC ; no need to CLC again as prev tst failed + BCC tst_dead ; if nb_neighbours <= 3 +kill_cell: + LDA #DEAD + STA (cell_future_line),Y + JSR pusha ; #DEAD == #BLACK COLOR + LDA tmp2 + JSR pusha + LDA tmp3 + JSR _gfx_pixel + JMP next_x + +end_update: + + ; Cells_Future -> Cells + LDA Cells + LDX Cells+1 + JSR pushax + LDA Cells_Future + LDX Cells_Future+1 + JSR pushax + LDA #CELLS_SIZE + JSR _memcpy + + JSR popax + STA ptr3 + STX ptr3+1 + JSR popax + STA ptr2 + STX ptr2+1 + JSR popax + STA ptr1 + STX ptr1+1 + RTS + +;*************** END OF UPDATE **************