diff --git a/graphics/gr/dots/Makefile b/graphics/gr/dots/Makefile new file mode 100644 index 00000000..bc3d47f7 --- /dev/null +++ b/graphics/gr/dots/Makefile @@ -0,0 +1,34 @@ +include ../../../Makefile.inc + +LINKER_DIR = ../../../linker_scripts/ + +EMPTY_DISK = ../../../empty_disk/empty.dsk +DOS33 = ../../../utils/dos33fs-utils/dos33 +TOKENIZE = ../../../utils/asoft_basic-utils/tokenize_asoft + +all: dots.dsk + +dots.dsk: HELLO DOTS + cp $(EMPTY_DISK) dots.dsk + $(DOS33) -y dots.dsk SAVE A HELLO + $(DOS33) -y dots.dsk BSAVE -a 0xc00 DOTS + +### + +HELLO: hello.bas + $(TOKENIZE) < hello.bas > HELLO + +#### + +DOTS: dots.o + ld65 -o DOTS dots.o -C $(LINKER_DIR)/apple2_c00.inc + +dots.o: dots.s + ca65 -o dots.o dots.s -l dots.lst + + +#### + +clean: + rm -f *~ *.o *.lst HELLO DOTS + diff --git a/graphics/gr/dots/dots.s b/graphics/gr/dots/dots.s new file mode 100644 index 00000000..1e40434f --- /dev/null +++ b/graphics/gr/dots/dots.s @@ -0,0 +1,241 @@ +; dots +; based on Second Reality Dots code + +; zero-page +GBASL = $26 +GBASH = $27 +MASK = $2E +COLOR = $30 + +DRAW_PAGE = $E0 + +OUTL = $FC +OUTH = $FD +INL = $FE +INH = $FF + +; soft-switches +FULLGR = $C052 +PAGE1 = $C054 +PAGE2 = $C055 + +; ROM routines +PLOT = $F800 ;; PLOT AT Y,A +SETGR = $FB40 + +WAIT = $FCA8 ;; delay 1/2(26+27A+5A^2) us + +dots: + jsr SETGR + bit FULLGR + +init_vars: + + lda #0 + sta DRAW_PAGE + + ;=============================== + ; setup + + lda #dot_data + sta INH + +main_loop: + + ; FIXME: draw once offscreen and do a fast copy +draw_background: + + ldx #11 +draw_sky_outer_loop: + lda gr_offsets_l,X + sta GBASL + lda gr_offsets_h,X + clc + adc DRAW_PAGE + sta GBASH + + lda #0 + ldy #39 +draw_sky_inner_loop: + sta (GBASL),Y + dey + bpl draw_sky_inner_loop + + dex + bpl draw_sky_outer_loop + + ldx #23 +draw_ground_outer_loop: + lda gr_offsets_l,X + sta GBASL + lda gr_offsets_h,X + clc + adc DRAW_PAGE + sta GBASH + + lda #$55 ; grey + ldy #39 +draw_ground_inner_loop: + sta (GBASL),Y + dey + bpl draw_ground_inner_loop + + dex + cpx #11 + bne draw_ground_outer_loop + + jmp decode_loop + + + + ;=============================== +decode_next: + inc INL + bne decode_loop + inc INH + +decode_loop: + ldy #0 + lda (INL),Y + + cmp #$FF + bne check_shadow + + jmp done + +check_shadow: + cmp #$FE + bne check_balls + + lda #$00 + sta COLOR + beq done_frame + +check_balls: + cmp #$FD + bne check_row + + lda #$66 + sta COLOR + bne decode_next + +check_row: + tax + and #$C0 + bne check_dot_both + + ; row value + txa + and #$1F + tax + lda gr_offsets_l,X + sta OUTL + lda gr_offsets_h,X + clc + adc DRAW_PAGE + sta OUTH + bne decode_next + +check_dot_both: + cmp #$C0 + bne check_dot_top +draw_dot_both: + txa + and #$3f + tay + lda COLOR + sta (OUTL),Y + jmp decode_next + + ;================== + +check_dot_top: + cmp #$80 + bne check_dot_bottom +draw_dot_top: + txa + and #$3f + tay + + lda COLOR + and #$0F + sta MASK + + lda (OUTL),Y + and #$F0 + ora MASK + sta (OUTL),Y + jmp decode_next + +check_dot_bottom: +draw_dot_bottom: + txa + and #$3f + tay + + lda COLOR + and #$F0 + sta MASK + + lda (OUTL),Y + and #$0F + ora MASK + + sta (OUTL),Y + jmp decode_next + +done_frame: + inc INL + bne done_frame_noinc + inc INH +done_frame_noinc: + + ; switch pages + + lda DRAW_PAGE + beq switch_to_draw_page2 + + bit PAGE2 + lda #0 + beq done_switch_page + +switch_to_draw_page2: + bit PAGE1 + lda #$4 +done_switch_page: + sta DRAW_PAGE + + + + + + ; delay 143000us + + ; delay 1/2(26+27A+5A^2) us + ; ~236 + + lda #236 + jsr WAIT + + jmp draw_background + + +done: + jmp done + + +gr_offsets_h: + .byte >$400,>$480,>$500,>$580,>$600,>$680,>$700,>$780 + .byte >$428,>$4a8,>$528,>$5a8,>$628,>$6a8,>$728,>$7a8 + .byte >$450,>$4d0,>$550,>$5d0,>$650,>$6d0,>$750,>$7d0 + + +gr_offsets_l: + .byte <$400,<$480,<$500,<$580,<$600,<$680,<$700,<$780 + .byte <$428,<$4a8,<$528,<$5a8,<$628,<$6a8,<$728,<$7a8 + .byte <$450,<$4d0,<$550,<$5d0,<$650,<$6d0,<$750,<$7d0 + +dot_data: +.incbin "out2.128.7fps",0,36000 diff --git a/graphics/gr/dots/hello.bas b/graphics/gr/dots/hello.bas new file mode 100644 index 00000000..0e3aae36 --- /dev/null +++ b/graphics/gr/dots/hello.bas @@ -0,0 +1,2 @@ +5 HOME +40 PRINT CHR$(4)"CATALOG" diff --git a/linker_scripts/apple2_c00_nodos.inc b/linker_scripts/apple2_c00_nodos.inc new file mode 100644 index 00000000..a624f73c --- /dev/null +++ b/linker_scripts/apple2_c00_nodos.inc @@ -0,0 +1,12 @@ +MEMORY { + ZP: start = $00, size = $1A, type = rw; + RAM: start = $C00, size = $B400, file = %O; +} + +SEGMENTS { +CODE: load = RAM, type = ro, align = $100; +RODATA: load = RAM, type = ro; +DATA: load = RAM, type = rw; +BSS: load = RAM, type = bss, define = yes; +ZEROPAGE: load = ZP, type = zp; +} diff --git a/utils/gr-sim/dots/Makefile b/utils/gr-sim/dots/Makefile index 592b347d..10588591 100644 --- a/utils/gr-sim/dots/Makefile +++ b/utils/gr-sim/dots/Makefile @@ -4,18 +4,27 @@ CFLAGS = -O2 -Wall -g SDL_LIBS= `sdl-config --libs` SDL_INCLUDE= `sdl-config --cflags` -all: dots dots_dump dots_play dots_minimal dots_6502 +all: dots dots_dump dots_play dots_play2 dots_minimal dots_6502 ### -dots_play: dots_play.o vga_emulator.o 8086_emulator.o ../gr-sim.a - $(CC) -o dots_play dots_play.o vga_emulator.o 8086_emulator.o ../gr-sim.a $(LFLAGS) $(SDL_LIBS) +dots_play: dots_play.o ../gr-sim.a + $(CC) -o dots_play dots_play.o ../gr-sim.a $(LFLAGS) $(SDL_LIBS) -dots_play.o: dots_play.c vga_emulator.h +dots_play.o: dots_play.c $(CC) $(CFLAGS) $(SDL_INCLUDE) -c dots_play.c ### +dots_play2: dots_play2.o ../gr-sim.a + $(CC) -o dots_play2 dots_play2.o ../gr-sim.a $(LFLAGS) $(SDL_LIBS) + +dots_play2.o: dots_play2.c + $(CC) $(CFLAGS) $(SDL_INCLUDE) -c dots_play2.c + + +### + dots_dump: dots_dump.o vga_emulator.o 8086_emulator.o ../gr-sim.a $(CC) -o dots_dump dots_dump.o vga_emulator.o 8086_emulator.o ../gr-sim.a $(LFLAGS) $(SDL_LIBS) @@ -61,4 +70,4 @@ vga_emulator.o: vga_emulator.c vga_emulator.h ### clean: - rm -f *~ *.o dots dots_dump dots_play dots_minimal dots_6502 + rm -f *~ *.o dots dots_dump dots_play dots_minimal dots_6502 dots_play2 diff --git a/utils/gr-sim/dots/dots_dump.c b/utils/gr-sim/dots/dots_dump.c index 674da32d..b28698ab 100644 --- a/utils/gr-sim/dots/dots_dump.c +++ b/utils/gr-sim/dots/dots_dump.c @@ -17,9 +17,9 @@ #define BOTTOM 8000 -#define SKIP 4 +#define SKIP 2 -#define FRAME_SKIP 10 +#define FRAME_SKIP 7 static int write_frame=-1; @@ -932,6 +932,7 @@ int main(int argc,char **argv) { if (write_frame==0) { +#if 0 int new_row=1; /* Shadow */ @@ -970,6 +971,212 @@ int main(int argc,char **argv) { } } +#endif + + int new_row=1; + + /* Shadow */ + buffer[0]=0xfe; + fwrite(buffer,1,sizeof(char),output); + for(yy=0;yy<24;yy++) { + new_row=1; + for(xx=0;xx<40;xx++) { + /* cases: */ + /* shadow ball action */ + /* top bottom top bottom */ + /* 0 0 0 0 none */ + /* 0 0 0 1 none */ + /* 0 0 1 0 none */ + /* 0 0 1 1 none */ + /* 0 1 0 0 bot 1 */ + /* 0 1 0 1 none */ + /* 0 1 1 0 both 4 */ + /* 0 1 1 1 none */ + /* 1 0 0 0 top 2 */ + /* 1 0 0 1 both 5 */ + /* 1 0 1 0 none */ + /* 1 0 1 1 none */ + /* 1 1 0 0 both 3 */ + /* 1 1 0 1 both 3 */ + /* 1 1 1 0 both 3 */ + /* 1 1 1 1 none */ + + /* case 1/4 */ + if ( (shadow[xx][yy*2]==0) && + (shadow[xx][(yy*2)+1]==1) ) { + + /* case 1 -- bottom */ + if ( (ball[xx][(yy*2)]==0) && + (ball[xx][(yy*2)+1]==0)) { + + if (new_row) { + buffer[0]=yy; + fwrite(buffer,1, + sizeof(char), + output); + new_row=0; + } + + buffer[0]=(xx|0x40); + fwrite(buffer,1,sizeof(char), + output); + + } + + /* case 4 -- both */ + if ( (ball[xx][(yy*2)]==1) && + (ball[xx][(yy*2)+1]==0) ) { + + if (new_row) { + buffer[0]=yy; + fwrite(buffer,1, + sizeof(char), + output); + new_row=0; + } + + buffer[0]=(xx|0xC0); + fwrite(buffer,1,sizeof(char), + output); + + } + + } + /* case 2/5 */ + else if ( (shadow[xx][yy*2]==1) && + (shadow[xx][(yy*2)+1]==0) ) { + + /* case 2 -- top */ + if ( (ball[xx][(yy*2)]==0) && + (ball[xx][(yy*2)+1]==0) ) { + + if (new_row) { + buffer[0]=yy; + fwrite(buffer,1, + sizeof(char), + output); + new_row=0; + } + + buffer[0]=(xx|0x80); + fwrite(buffer,1,sizeof(char), + output); + + } + + /* case 5 -- both */ + if ( (ball[xx][(yy*2)]==0) && + (ball[xx][(yy*2)+1]==1) ) { + + if (new_row) { + buffer[0]=yy; + fwrite(buffer,1, + sizeof(char), + output); + new_row=0; + } + + buffer[0]=(xx|0xC0); + fwrite(buffer,1,sizeof(char), + output); + + } + + } + /* case 3 */ + else if ( (shadow[xx][yy*2]==1) && + (shadow[xx][(yy*2)+1]==1) ) { + + /* case 2 -- top */ + if ( (ball[xx][(yy*2)]==1) && + (ball[xx][(yy*2)+1]==1) ) { + } + else { + if (new_row) { + buffer[0]=yy; + fwrite(buffer,1, + sizeof(char), + output); + new_row=0; + } + + buffer[0]=(xx|0xc0); + fwrite(buffer,1,sizeof(char), + output); + + } + + } + + + } + } + + /* Balls */ + buffer[0]=0xfd; + fwrite(buffer,1,sizeof(char),output); + for(yy=0;yy<24;yy++) { + new_row=1; + for(xx=0;xx<40;xx++) { + /* cases: */ + /* shadow ball action */ + /* top bottom top bottom */ + /* X X 0 0 none */ + /* X X 0 1 bot 1 */ + /* X X 1 0 top 2 */ + /* X X 1 1 both 3 */ + + /* case 1 -- bottom */ + if ( (ball[xx][(yy*2)]==0) && + (ball[xx][(yy*2)+1]==1)) { + + if (new_row) { + buffer[0]=yy; + fwrite(buffer,1,sizeof(char), + output); + new_row=0; + } + + buffer[0]=(xx|0x40); + fwrite(buffer,1,sizeof(char), + output); + + } + /* case 2 -- top */ + else if ( (ball[xx][(yy*2)]==1) && + (ball[xx][(yy*2)+1]==0) ) { + + if (new_row) { + buffer[0]=yy; + fwrite(buffer,1,sizeof(char), + output); + new_row=0; + } + + buffer[0]=(xx|0x80); + fwrite(buffer,1,sizeof(char), + output); + + } + /* case 3 */ + else if ( (ball[xx][(yy*2)]==1) && + (ball[xx][(yy*2)+1]==1) ) { + if (new_row) { + buffer[0]=yy; + fwrite(buffer,1,sizeof(char), + output); + new_row=0; + } + + buffer[0]=(xx|0xc0); + fwrite(buffer,1,sizeof(char), + output); + + } + + } + } + } diff --git a/utils/gr-sim/dots/dots_play2.c b/utils/gr-sim/dots/dots_play2.c new file mode 100644 index 00000000..638376c4 --- /dev/null +++ b/utils/gr-sim/dots/dots_play2.c @@ -0,0 +1,124 @@ +#include +#include +#include +#include + +#include "../gr-sim.h" +#include "../tfv_zp.h" + +int create_gr_files=0; + +int skip_factor=1; +int fps=10; + +int main(int argc, char **argv) { + + + int xx,yy,ch=0,i; + int current_row=0; + int frame=0; + int fd; + + if (argc>1) { + skip_factor=atoi(argv[1]); + } + printf("Only playing 1 of every %d frames\n",skip_factor); + + if (argc>2) { + fps=atoi(argv[2]); + } + printf("Playing at %d frames per second\n",fps); + + + grsim_init(); + + gr(); + + while(1) { + clear_screens(); + soft_switch(MIXCLR); + + ram[DRAW_PAGE]=0; + + color_equals(5); + for(yy=24;yy<48;yy++) hlin(0,0,40,yy); + + color_equals(0); + + /* skip frames */ + for(i=0;i<(skip_factor-1);i++) { + while(1) { + ch=getchar(); + if (ch==0xff) break; + + if (ch==0xfe) break; + } + if (ch==0xff) break; + } + + if (ch==0xff) break; + + /* parse loop */ + while(1) { + ch=getchar(); + if (ch==0xff) break; + + if (ch==0xfe) { + color_equals(0); + break; + } + if (ch==0xfd) { + color_equals(6); + continue; + } + + if ((ch&0xc0)==0) { + current_row=ch&0x1f; + continue; + } + + /* bottom */ + if ((ch&0x40)==0x40) { + xx=ch&0x3f; + plot(xx,(current_row*2)+1); + } + + /* top */ + if ((ch&0x80)==0x80) { + xx=ch&0x3f; + plot(xx,(current_row*2)); + } + + } + if (ch==0xff) break; + + usleep(1000000/fps); + + grsim_update(); + + if (create_gr_files) { + char filename[256]; + + sprintf(filename,"frame%03d.gr",frame); + fd=open(filename,O_WRONLY|O_CREAT,0660); + if (fd<0) { + fprintf(stderr,"Error opening!\n"); + return -1; + } + write(fd,&ram[0x400],1024); + close(fd); + } + + frame++; + +//again: + ch=grsim_input(); + if (ch==27) { + break; + } +// else if (ch==0) goto again; + + } + + return 0; +}