diff --git a/graphics/hgr/lines/lines.s b/graphics/hgr/lines/lines.s index 172bd103..678f4ced 100644 --- a/graphics/hgr/lines/lines.s +++ b/graphics/hgr/lines/lines.s @@ -5,8 +5,11 @@ ; based on pseudo-code from ; https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm +; goal: ROM is 120 bytes 43c3/44a4/4599 + ; 361 bytes / D799/D23A/CE55 -- first working code ; 346 bytes / D7D6/D17C/CCE7 -- make X2 always > X1 +; 347 bytes / D718/D0C6/CC39 -- make D_SY self modifying code ; D0+ used by HGR routines @@ -32,7 +35,7 @@ B_DX_H = $F7 B_DY_L = $F8 B_DY_H = $F9 ;B_SX = $FA -B_SY = $FB +;B_SY = $FB B_ERR_L = $FC B_ERR_H = $FD COUNT = $FE @@ -254,7 +257,7 @@ yneg: sta B_DY_H yis_neg: - sty B_SY + sty b_sy_smc+1 ; B_SY ; err = dx+dy @@ -380,7 +383,8 @@ doit: ; y1 = y1 + sy clc lda B_Y1 - adc B_SY +b_sy_smc: + adc #0 sta B_Y1 skip_y: diff --git a/graphics/hgr/vgi-doom/Makefile b/graphics/hgr/vgi-doom/Makefile new file mode 100644 index 00000000..a7a876d2 --- /dev/null +++ b/graphics/hgr/vgi-doom/Makefile @@ -0,0 +1,50 @@ +include ../../../Makefile.inc + +DOS33 = ../../../utils/dos33fs-utils/dos33 +TOKENIZE = ../../../utils/asoft_basic-utils/tokenize_asoft +LINKERSCRIPTS = ../../../linker_scripts +EMPTYDISK = ../../../empty_disk/empty.dsk +MAKEVGI = ./make_vgi_asm + +all: vgi_doom.dsk make_vgi_asm + +vgi_doom.dsk: HELLO VGI-DOOM + cp $(EMPTYDISK) vgi_doom.dsk + $(DOS33) -y vgi_doom.dsk SAVE A HELLO + $(DOS33) -y vgi_doom.dsk BSAVE -a 0x4000 VGI-DOOM + +### + +HELLO: hello.bas + $(TOKENIZE) < hello.bas > HELLO + +### + +VGI-DOOM: doom_vgi.o + ld65 -o VGI-DOOM doom_vgi.o -C $(LINKERSCRIPTS)/apple2_4000.inc + +doom_vgi.o: doom.data \ + doom_vgi.s vgi_clearscreen.s vgi_rectangle.s vgi_circles.s vgi_lines.s \ + vgi_triangles.s + ca65 -o doom_vgi.o doom_vgi.s -l doom_vgi.lst + +### + +doom.data: make_vgi_asm doom.vgi + echo "doom_data:" > doom.data + ./make_vgi_asm < doom.vgi >> doom.data + +### + +make_vgi_asm: make_vgi_asm.o + $(CC) -o make_vgi_asm make_vgi_asm.o $(LFLAGS) + +make_vgi_asm.o: make_vgi_asm.c + $(CC) $(CFLAGS) -c make_vgi_asm.c + + +### + +clean: + rm -f *~ *.o *.lst HELLO VGI-MYST VGI-DOOM COLOR-TEST \ + make_vgi_asm make_color_test *.data diff --git a/graphics/hgr/vgi/doom.vgi b/graphics/hgr/vgi-doom/doom.vgi similarity index 100% rename from graphics/hgr/vgi/doom.vgi rename to graphics/hgr/vgi-doom/doom.vgi diff --git a/graphics/hgr/vgi/doom_e1m1.pt3 b/graphics/hgr/vgi-doom/doom_e1m1.pt3 similarity index 100% rename from graphics/hgr/vgi/doom_e1m1.pt3 rename to graphics/hgr/vgi-doom/doom_e1m1.pt3 diff --git a/graphics/hgr/vgi/doom_vgi.s b/graphics/hgr/vgi-doom/doom_vgi.s similarity index 100% rename from graphics/hgr/vgi/doom_vgi.s rename to graphics/hgr/vgi-doom/doom_vgi.s diff --git a/graphics/hgr/vgi-doom/hardware.inc b/graphics/hgr/vgi-doom/hardware.inc new file mode 100644 index 00000000..1a16c6ff --- /dev/null +++ b/graphics/hgr/vgi-doom/hardware.inc @@ -0,0 +1,71 @@ +; HARDWARE LOCATIONS + +KEYPRESS = $C000 +KEYRESET = $C010 + +; SOFT SWITCHES +CLR80COL = $C000 ; PAGE0/PAGE1 normal +SET80COL = $C001 ; PAGE0/PAGE1 switches PAGE0 in Aux instead +EIGHTYCOLOFF = $C00C +EIGHTYCOLON = $C00D +TBCOLOR = $C022 ; IIgs text foreground / background colors +NEWVIDEO = $C029 ; IIgs graphics modes +SPEAKER = $C030 +CLOCKCTL = $C034 ; bits 0-3 are IIgs border color +SET_GR = $C050 +SET_TEXT = $C051 +FULLGR = $C052 +TEXTGR = $C053 +PAGE0 = $C054 +PAGE1 = $C055 +LORES = $C056 ; Enable LORES graphics +HIRES = $C057 ; Enable HIRES graphics +AN3 = $C05E ; Annunciator 3 + +PADDLE_BUTTON0 = $C061 +PADDLE_BUTTON1 = $C062 +PADDL0 = $C064 +PTRIG = $C070 + +; BASIC ROUTINES + + +NORMAL = $F273 +HGR2 = $F3D8 ; clear PAGE2 to 0 +HGR = $F3E2 ; set hires page1 and clear $2000-$3fff +BKGND0 = $F3F4 ; clear current page to A +HPOSN = $F411 ; (Y,X),(A) (values stores in HGRX,XH,Y) +HPLOT0 = $F457 ; plot at (Y,X), (A) +COLOR_SHIFT = $F47E +HLINRL = $F530 ; (X,A),(Y) +HGLIN = $F53A ; line to (X,A),(Y) +COLORTBL = $F6F6 + + +; MONITOR ROUTINES + +HLINE = $F819 ; HLINE Y,$2C at A +VLINE = $F828 ; VLINE A,$2D at Y +CLRSCR = $F832 ; Clear low-res screen +CLRTOP = $F836 ; clear only top of low-res screen +SETCOL = $F864 ; COLOR=A +ROM_TEXT2COPY = $F962 ; iigs +TEXT = $FB36 +SETGR = $FB40 ; init lores and clear screen +TABV = $FB5B ; VTAB to A +ROM_MACHINEID = $FBB3 ; iigs +BELL = $FBDD ; ring the bell +BASCALC = $FBC1 ; +VTAB = $FC22 ; VTAB to CV +HOME = $FC58 ; Clear the text screen +WAIT = $FCA8 ; delay 1/2(26+27A+5A^2) us +GETLN = $FD6A +GETLN1 = $FD6F +CROUT1 = $FD8B +SETINV = $FE80 ; INVERSE +SETNORM = $FE84 ; NORMAL +COUT = $FDED ; output A to screen +COUT1 = $FDF0 ; output A to screen + + + diff --git a/graphics/hgr/vgi-doom/hello.bas b/graphics/hgr/vgi-doom/hello.bas new file mode 100644 index 00000000..cb8ceb18 --- /dev/null +++ b/graphics/hgr/vgi-doom/hello.bas @@ -0,0 +1,5 @@ +5 HOME +10 PRINT CHR$(4);"CATALOG" +40 PRINT:PRINT "FOR THE DOOM DEMO" +50 PRINT "TYPE: BRUN VGI-DOOM" + diff --git a/graphics/hgr/vgi/interrupt_handler.s b/graphics/hgr/vgi-doom/interrupt_handler.s similarity index 100% rename from graphics/hgr/vgi/interrupt_handler.s rename to graphics/hgr/vgi-doom/interrupt_handler.s diff --git a/graphics/hgr/vgi-doom/make_vgi_asm.c b/graphics/hgr/vgi-doom/make_vgi_asm.c new file mode 100644 index 00000000..66641e6f --- /dev/null +++ b/graphics/hgr/vgi-doom/make_vgi_asm.c @@ -0,0 +1,457 @@ +#include +#include +#include + +#define MODE_ASM 0 +#define MODE_BIN 1 + +#define VGI_CLEARSCREEN 0 +#define VGI_RECTANGLE 1 +#define VGI_CIRCLE 2 +#define VGI_FILLED_CIRCLE 3 +#define VGI_POINT 4 +#define VGI_LINETO 5 +#define VGI_DITHER_RECTANGLE 6 +#define VGI_VERT_TRIANGLE 7 +#define VGI_HORIZ_TRIANGLE 8 +#define VGI_VSTRIPE_RECTANGLE 9 +#define VGI_LINE 10 +#define VGI_LINE_FAR 11 +#define VGI_END 15 + +/* non-encoded pseudo-values */ +#define VGI_VERT_TRIANGLE_SKIP 128+7 + + +static int output_bytes(int mode, unsigned char *bytes, int count) { + + int i; + + if (mode==MODE_ASM) { + printf(".byte "); + for(i=0;i1) { + if ((argv[1][0]=='-') && (argv[1][1]=='b')) { + mode=MODE_BIN; + } + } + + while(1) { + + type=0; + + ptr=fgets(buffer,1024,stdin); + if (ptr==NULL) break; + + if (buffer[0]==';') continue; + + if (isalpha(buffer[0])) { + if (!strncmp(buffer,"CLS",3)) { + type=VGI_CLEARSCREEN; + } + if (!strncmp(buffer,"RECT",4)) { + type=VGI_RECTANGLE; + } + if (!strncmp(buffer,"CIRC",4)) { + type=VGI_CIRCLE; + } + if (!strncmp(buffer,"FCIRC",5)) { + type=VGI_FILLED_CIRCLE; + } + if (!strncmp(buffer,"POINT",5)) { + type=VGI_POINT; + } + if (!strncmp(buffer,"LINETO",6)) { + type=VGI_LINETO; + } + else if (!strncmp(buffer,"LINEF",5)) { + type=VGI_LINE_FAR; + } + else if (!strncmp(buffer,"LINE",4)) { + type=VGI_LINE; + } + if (!strncmp(buffer,"DRECT",5)) { + type=VGI_DITHER_RECTANGLE; + } + if (!strncmp(buffer,"VTRISK",6)) { + type=VGI_VERT_TRIANGLE_SKIP; + } else if (!strncmp(buffer,"VTRI",4)) { + type=VGI_VERT_TRIANGLE; + } + if (!strncmp(buffer,"HTRI",4)) { + type=VGI_HORIZ_TRIANGLE; + } + if (!strncmp(buffer,"VSTRP",5)) { + type=VGI_VSTRIPE_RECTANGLE; + } + if (!strncmp(buffer,"END",3)) { + type=VGI_END; + } + } + else { + sscanf(buffer,"%i",&type); + } + + switch(type) { + case VGI_CLEARSCREEN: /* clear screen */ + sscanf(buffer,"%*s %i",&color1); +// printf(".byte $%02X,",(type<<4)|2); +// printf("$%02X\n",color1); + output[0]=(type<<4)|2; + output[1]=color1; + output_bytes(mode,output,2); + size+=2; + break; + + case VGI_RECTANGLE: /* compact rectangle */ + sscanf(buffer,"%*s %i %i %i %i %i %i", + &color1,&color2, + &x1,&y1,&x2,&y2); +// printf(".byte $%02X,",(type<<4)|6); +// printf("$%02X,",(color1<<4)|color2); +// printf("$%02X,",x1); +// printf("$%02X,",y1); +// printf("$%02X,",x2-x1); +// printf("$%02X\n",y2-y1); + output[0]=(type<<4)|6; + output[1]=(color1<<4)|color2; + output[2]=x1; + output[3]=y1; + output[4]=x2-x1; + output[5]=y2-y1; + output_bytes(mode,output,6); + size+=6; + break; + + case VGI_CIRCLE: /* circle */ + sscanf(buffer,"%*s %i %i %i %i", + &color1, + &x1,&y1,&r); +// printf(".byte $%02X,",(type<<4)|5); +// printf("$%02X,",color1); +// printf("$%02X,",x1); +// printf("$%02X,",y1); +// printf("$%02X\n",r); + output[0]=(type<<4)|5; + output[1]=color1; + output[2]=x1; + output[3]=y1; + output[4]=r; + output_bytes(mode,output,5); + size+=5; + break; + + case VGI_FILLED_CIRCLE: /* filled circle */ + sscanf(buffer,"%*s %i %i %i %i", + &color1, + &x1,&y1,&r); +// printf(".byte $%02X,",(type<<4)|5); +// printf("$%02X,",color1); +// printf("$%02X,",x1); +// printf("$%02X,",y1); +// printf("$%02X\n",r); + output[0]=(type<<4)|5; + output[1]=color1; + output[2]=x1; + output[3]=y1; + output[4]=r; + output_bytes(mode,output,5); + size+=5; + break; + + case VGI_POINT: /* point */ + sscanf(buffer,"%*s %i %i %i", + &color1, + &x1,&y1); +// printf(".byte $%02X,",(type<<4)|4); + + lastx=x1; + lasty=y1; + lastcolor=color1; + + if (x1>255) { + x1=x1&0xff; + color1|=128; + } +// printf("$%02X,",color1); +// printf("$%02X,",x1); +// printf("$%02X\n",y1); + output[0]=(type<<4)|4; + output[1]=color1; + output[2]=x1; + output[3]=y1; + output_bytes(mode,output,4); + size+=4; + break; + + case VGI_LINETO: /* line to */ + sscanf(buffer,"%*s %i %i", + &x1,&y1); +// printf(".byte $%02X,",(type<<4)|3); +// printf("$%02X,",x1); +// printf("$%02X\n",y1); + + tempx=lastx; + tempcolor=lastcolor; + + if (lastx>255) { + tempx=tempx&0xff; + tempcolor=tempcolor|128; + } + + if (x1>255) { + output[0]=(VGI_LINE_FAR<<4)|6; + output[1]=tempcolor; + output[2]=tempx; + output[3]=lasty; + output[4]=(x1&0xff); + output[5]=y1; + output_bytes(mode,output,6); + size+=6; +#if 0 + fprintf(stderr,"ADJUSTING %d %d %d %d %d %d\n", + output[0], + output[1], + output[2], + output[3], + output[4], + output[5]); +#endif + } + else { + output[0]=(type<<4)|3; + output[1]=x1; + output[2]=y1; + output_bytes(mode,output,3); + size+=3; + } + lastx=x1; + lasty=y1; + + break; + + case VGI_DITHER_RECTANGLE: /* dithered rectangle */ + sscanf(buffer,"%*s %i %i %i %i %i %i", + &color1,&color2, + &x1,&y1,&x2,&y2); +// printf(".byte $%02X,",(type<<4)|7); +// printf("$%02X,",color1); +// printf("$%02X,",x1); +// printf("$%02X,",y1); +// printf("$%02X,",x2-x1); +// printf("$%02X,",y2-y1); +// printf("$%02X\n",color2); + output[0]=(type<<4)|7; + output[1]=color1; + output[2]=x1; + output[3]=y1; + output[4]=x2-x1; + output[5]=y2-y1; + output[6]=color2; + output_bytes(mode,output,7); + size+=7; + break; + + case VGI_VERT_TRIANGLE: /* vertical triangle */ + sscanf(buffer,"%*s %i %i %i %i %i %i", + &color1, + &x1,&y1,&xl,&xr,&yb); +// printf(".byte $%02X,",(type<<4)|7); +// printf("$%02X,",(1<<4)|color1); /* skip=1 */ +// printf("$%02X,",x1); +// printf("$%02X,",y1); +// printf("$%02X,",xl); +// printf("$%02X,",xr); +// printf("$%02X\n",yb); + output[0]=(type<<4)|7; + output[1]=(1<<4)|color1; + output[2]=x1; + output[3]=y1; + output[4]=xl; + output[5]=xr; + output[6]=yb; + output_bytes(mode,output,7); + size+=7; + break; + + case VGI_VERT_TRIANGLE_SKIP: /* vertical triangle w skip*/ + sscanf(buffer,"%*s %i %i %i %i %i %i %i", + &color1, + &x1,&y1,&xl,&xr,&yb,&skip); +// printf(".byte $%02X,",(VGI_VERT_TRIANGLE<<4)|7); +// printf("$%02X,",(skip<<4)|color1); +// printf("$%02X,",x1); +// printf("$%02X,",y1); +// printf("$%02X,",xl); +// printf("$%02X,",xr); +// printf("$%02X\n",yb); + output[0]=(VGI_VERT_TRIANGLE<<4)|7; + output[1]=(skip<<4)|color1; + output[2]=x1; + output[3]=y1; + output[4]=xl; + output[5]=xr; + output[6]=yb; + output_bytes(mode,output,7); + size+=7; + break; + + case VGI_HORIZ_TRIANGLE: /* horizontal triangle */ + sscanf(buffer,"%*s %i %i %i %i %i %i", + &color1, + &x1,&y1,&yt,&yb,&xr); +// printf(".byte $%02X,",(type<<4)|7); +// printf("$%02X,",color1); +// printf("$%02X,",x1); +// printf("$%02X,",y1); +// printf("$%02X,",yt); +// printf("$%02X,",yb); +// printf("$%02X\n",xr); + output[0]=(type<<4)|7; + output[1]=color1; + output[2]=x1; + output[3]=y1; + output[4]=yt; + output[5]=yb; + output[6]=xr; + output_bytes(mode,output,7); + size+=7; + break; + + case VGI_VSTRIPE_RECTANGLE: /* vstriped rectangle */ + sscanf(buffer,"%*s %i %i %i %i %i %i", + &color1,&color2, + &x1,&y1,&x2,&y2); +// printf(".byte $%02X,",(type<<4)|7); +// printf("$%02X,",color1); +// printf("$%02X,",x1); +// printf("$%02X,",y1); +// printf("$%02X,",x2-x1); +// printf("$%02X,",y2-y1); +// printf("$%02X\n",color2); + output[0]=(type<<4)|7; + output[1]=color1; + output[2]=x1; + output[3]=y1; + output[4]=x2-x1; + output[5]=y2-y1; + output[6]=color2; + output_bytes(mode,output,7); + size+=7; + break; + + case VGI_LINE: /* line */ + case VGI_LINE_FAR: /* line far */ + sscanf(buffer,"%*s %i %i %i %i %i", + &color1, + &x1,&y1,&x2,&y2); +// printf(".byte $%02X,",(type<<4)|6); + + lastx=x2; + lasty=y2; + lastcolor=color1; + + if (x1>255) { + x1=x1&0xff; + color1|=128; + } +// printf("$%02X,",color1); +// printf("$%02X,",x1); +// printf("$%02X,",y1); +// printf("$%02X,",x2); +// printf("$%02X\n",y2); + if (x2>255) { + type=VGI_LINE_FAR; + x2=x2&0xff; + } + + output[0]=(type<<4)|6; + output[1]=color1; + output[2]=x1; + output[3]=y1; + output[4]=x2; + output[5]=y2; + output_bytes(mode,output,6); + size+=6; + break; + +#if 0 + sscanf(buffer,"%*s %i %i %i %i %i", + &color1, + &x1,&y1,&x2,&y2); +// printf(".byte $%02X,",(type<<4)|6); + if (x1>255) { + x1=x1&0xff; + color1|=128; + } + if (x2<256) { + fprintf(stderr,"Error! X2 too small %d on line %d\n",x2,line); + } + x2=x2&0xff; +// printf("$%02X,",color1); +// printf("$%02X,",x1); +// printf("$%02X,",y1); +// printf("$%02X,",x2); +// printf("$%02X\n",y2); + output[0]=(type<<4)|6; + output[1]=color1; + output[2]=x1; + output[3]=y1; + output[4]=x2; + output[5]=y2; + output_bytes(mode,output,6); + size+=6; + break; +#endif + + case VGI_END: /* end */ +// printf(".byte $FF\n"); + output[0]=0xff; + output_bytes(mode,output,1); + size+=1; + break; + + default: + fprintf(stderr,"Unknown type %i line %d\n", + type,line); + break; + } + + line++; + + } + + printf("\n"); + + fprintf(stderr,"Size is %d bytes\n",size); + return 0; +} diff --git a/graphics/hgr/vgi/pt3_lib_core.s b/graphics/hgr/vgi-doom/pt3_lib_core.s similarity index 100% rename from graphics/hgr/vgi/pt3_lib_core.s rename to graphics/hgr/vgi-doom/pt3_lib_core.s diff --git a/graphics/hgr/vgi/pt3_lib_detect_model.s b/graphics/hgr/vgi-doom/pt3_lib_detect_model.s similarity index 100% rename from graphics/hgr/vgi/pt3_lib_detect_model.s rename to graphics/hgr/vgi-doom/pt3_lib_detect_model.s diff --git a/graphics/hgr/vgi/pt3_lib_init.s b/graphics/hgr/vgi-doom/pt3_lib_init.s similarity index 100% rename from graphics/hgr/vgi/pt3_lib_init.s rename to graphics/hgr/vgi-doom/pt3_lib_init.s diff --git a/graphics/hgr/vgi/pt3_lib_irq_handler.s b/graphics/hgr/vgi-doom/pt3_lib_irq_handler.s similarity index 100% rename from graphics/hgr/vgi/pt3_lib_irq_handler.s rename to graphics/hgr/vgi-doom/pt3_lib_irq_handler.s diff --git a/graphics/hgr/vgi/pt3_lib_mockingboard_detect.s b/graphics/hgr/vgi-doom/pt3_lib_mockingboard_detect.s similarity index 100% rename from graphics/hgr/vgi/pt3_lib_mockingboard_detect.s rename to graphics/hgr/vgi-doom/pt3_lib_mockingboard_detect.s diff --git a/graphics/hgr/vgi/pt3_lib_mockingboard_setup.s b/graphics/hgr/vgi-doom/pt3_lib_mockingboard_setup.s similarity index 100% rename from graphics/hgr/vgi/pt3_lib_mockingboard_setup.s rename to graphics/hgr/vgi-doom/pt3_lib_mockingboard_setup.s diff --git a/graphics/hgr/vgi-doom/vgi_circles.s b/graphics/hgr/vgi-doom/vgi_circles.s new file mode 100644 index 00000000..ffc038bc --- /dev/null +++ b/graphics/hgr/vgi-doom/vgi_circles.s @@ -0,0 +1,303 @@ +; VGI_Circles + + +XX = TEMP0 +MINUSXX = TEMP1 +YY = TEMP2 +MINUSYY = TEMP3 +D = TEMP4 +COUNT = TEMP5 + + ;======================== + ; VGI circle + ;======================== + + VGI_CCOLOR = P0 + VGI_CX = P1 + VGI_CY = P2 + VGI_CR = P3 + +vgi_circle: + ldx VGI_CCOLOR + lda COLORTBL,X + sta HGR_COLOR + + ;=============================== + ; draw circle + ;=============================== + ; draw circle at (CX,CY) of radius R + ; signed 8-bit math so problems if R > 64? + + ; XX=0 YY=R + ; D=3-2*R + ; GOTO6 + + lda #0 + sta XX + + lda VGI_CR + sta YY + + lda #3 + sec + sbc VGI_CR + sbc VGI_CR + sta D + + jmp do_plots + +circle_loop: + ; X=X+1 + + inc XX + + ; IF D>0 THEN Y=Y-1:D=D+4*(X-Y)+10 + lda D + bmi else + + dec YY + + lda XX + sec + sbc YY + asl + asl + clc + adc D + adc #10 + jmp store_D + +else: + ; ELSE D=D+4*X+6 + lda XX + asl + asl + clc + adc D + adc #6 +store_D: + sta D + +do_plots: + ; setup constants + + lda XX + eor #$FF + sta MINUSXX + inc MINUSXX + + lda YY + eor #$FF + sta MINUSYY + inc MINUSYY + + ; HPLOT CX+X,CY+Y + ; HPLOT CX-X,CY+Y + ; HPLOT CX+X,CY-Y + ; HPLOT CX-X,CY-Y + ; HPLOT CX+Y,CY+X + ; HPLOT CX-Y,CY+X + ; HPLOT CX+Y,CY-X + ; HPLOT CX-Y,CY-X + + ; calc X co-ord + + lda #7 + sta COUNT +pos_loop: + lda COUNT + and #$4 + lsr + tay + + lda COUNT + lsr + bcc xnoc + iny +xnoc: + lda VGI_CX + clc + adc XX,Y + tax + + ; calc y co-ord + + lda COUNT + lsr + eor #$2 + tay + + lda VGI_CY + clc + adc XX,Y + + ldy #0 + + jsr HPLOT0 ; plot at (Y,X), (A) + + dec COUNT + bpl pos_loop + + + ; IFY>=XTHEN4 + lda YY + cmp XX + bcs circle_loop + + jmp vgi_loop + + + + + ;======================== + ; VGI circle + ;======================== + ; VGI_CCOLOR = P0 + ; VGI_CX = P1 + ; VGI_CY = P2 + ; VGI_CR = P3 + +vgi_filled_circle: + ldx VGI_CCOLOR + lda COLORTBL,X + sta HGR_COLOR + + ;=============================== + ; draw filled circle + ;=============================== + ; draw filled circle at (CX,CY) of radius R + ; signed 8-bit math so problems if R > 64? + + + ; XX=0 YY=R + ; D=3-2*R + ; GOTO6 + + lda #0 + sta XX + + lda VGI_CR + sta YY + + lda #3 + sec + sbc VGI_CR + sbc VGI_CR + sta D + + jmp do_filled_plots + +filled_circle_loop: + ; X=X+1 + + inc XX + + ; IF D>0 THEN Y=Y-1:D=D+4*(X-Y)+10 + lda D + bmi filled_else + + dec YY + + lda XX + sec + sbc YY + asl + asl + clc + adc D + adc #10 + jmp store_filled_D + +filled_else: + ; ELSE D=D+4*X+6 + lda XX + asl + asl + clc + adc D + adc #6 +store_filled_D: + sta D + +do_filled_plots: + ; setup constants + + lda XX + eor #$FF + sta MINUSXX + inc MINUSXX + + lda YY + eor #$FF + sta MINUSYY + inc MINUSYY + + ; HPLOT CX+X,CY+Y + ; HPLOT CX-X,CY+Y + ; HPLOT CX+X,CY-Y + ; HPLOT CX-X,CY-Y + ; HPLOT CX+Y,CY+X + ; HPLOT CX-Y,CY+X + ; HPLOT CX+Y,CY-X + ; HPLOT CX-Y,CY-X + + + + + lda #3 + sta COUNT +filled_pos_loop: + + ; calc left side + + ; calc X co-ord + + lda COUNT + ora #$1 + eor #$2 + tay + lda VGI_CX + clc + adc XX,Y + tax + + ; calc y co-ord + + ldy COUNT + lda VGI_CY + clc + adc XX,Y + + ldy #0 + +; pha ; save Y value for later + + jsr HPLOT0 ; plot at (Y,X), (A) + + + ; calc right side + lda COUNT + and #$2 + eor #$2 + tay + lda XX,Y + asl + + ldy #0 + ldx #0 + + jsr HLINRL ; plot relative (X,A), (Y) + ; so in our case (0,XX*2),0 + + + + dec COUNT + bpl filled_pos_loop + + + ; IFY>=XTHEN4 + lda YY + cmp XX + bcs filled_circle_loop + + jmp vgi_loop diff --git a/graphics/hgr/vgi-doom/vgi_clearscreen.s b/graphics/hgr/vgi-doom/vgi_clearscreen.s new file mode 100644 index 00000000..e56b982d --- /dev/null +++ b/graphics/hgr/vgi-doom/vgi_clearscreen.s @@ -0,0 +1,7 @@ + +vgi_clearscreen: + + lda P0 + jsr BKGND0 + + jmp vgi_loop ; return diff --git a/graphics/hgr/vgi-doom/vgi_common.s b/graphics/hgr/vgi-doom/vgi_common.s new file mode 100644 index 00000000..1de53856 --- /dev/null +++ b/graphics/hgr/vgi-doom/vgi_common.s @@ -0,0 +1,72 @@ +; VGI library + +VGI_MAXLEN = 7 + + ;================================== + ; play_vgi + ;================================== +play_vgi: + +vgi_loop: + + ldy #0 +data_smc: + lda (VGIL),Y + sta VGI_BUFFER,Y + iny + cpy #VGI_MAXLEN + bne data_smc + + lda VGI_TYPE + and #$f + + clc + adc VGIL + sta VGIL + bcc no_oflo + inc VGIH +no_oflo: + + lda VGI_TYPE + lsr + lsr + lsr + lsr + + ; look up action in jump table + asl + tax + lda vgi_rts_table+1,X + pha + lda vgi_rts_table,X + pha + rts ; "jump" to subroutine + +vgi_rts_table: + .word vgi_clearscreen-1 ; 0 = clearscreen + .word vgi_simple_rectangle-1 ; 1 = simple rectangle + .word vgi_circle-1 ; 2 = plain circle + .word vgi_filled_circle-1 ; 3 = filled circle + .word vgi_point-1 ; 4 = dot + .word vgi_lineto-1 ; 5 = line to + .word vgi_dithered_rectangle-1 ; 6 = dithered rectangle + .word vgi_vertical_triangle-1 ; 7 = vertical triangle + .word vgi_horizontal_triangle-1 ; 8 = horizontal triangle + .word vgi_vstripe_rectangle-1 ; 9 = vstripe rectangle + .word vgi_line-1 ;10 = line + .word vgi_line_far-1 ;11 = line far + .word all_done-1 + .word all_done-1 + .word all_done-1 + .word all_done-1 ; 15 = done + +all_done: + rts + + +.include "vgi_clearscreen.s" +.include "vgi_circles.s" +.include "vgi_rectangle.s" +.include "vgi_lines.s" +.include "vgi_triangles.s" + diff --git a/graphics/hgr/vgi-doom/vgi_lines.s b/graphics/hgr/vgi-doom/vgi_lines.s new file mode 100644 index 00000000..4417becd --- /dev/null +++ b/graphics/hgr/vgi-doom/vgi_lines.s @@ -0,0 +1,95 @@ +; VGI Lines + + ;======================== + ; VGI point + ;======================== +vgi_point: + jsr vgi_point_common + jmp vgi_loop + + + ;======================== + ; VGI point common + ;======================== + + VGI_PCOLOR = P0 ; if high bit set, then PX=PX+256 + VGI_PX = P1 + VGI_PY = P2 + +vgi_point_common: + ldy #0 + + lda VGI_PCOLOR + bpl vgi_point_color + iny +vgi_point_color: + and #$7f + tax + lda COLORTBL,X + sta HGR_COLOR + + ldx VGI_PX + lda VGI_PY + + jsr HPLOT0 ; plot at (Y,X), (A) + + rts + + + + + ;======================== + ; VGI line to + ;======================== + VGI_LX = P0 + VGI_LY = P1 + +vgi_lineto: + ldx #0 + ldy VGI_LY + lda VGI_LX + + jsr HGLIN ; line to (X,A),(Y) + + jmp vgi_loop + + + ;======================== + ; VGI LINE + ;======================== +; VGI_LX = P0 +; VGI_LY = P1 + VGI_LX2 = P3 + VGI_LY2 = P4 + +vgi_line: + jsr vgi_point_common + + ldx #0 + ldy VGI_LY2 + lda VGI_LX2 + + jsr HGLIN ; line to (X,A),(Y) + + jmp vgi_loop + + ;======================== + ; VGI LINE FAR + ;======================== + ; assume second x-coord is > 256 +; VGI_LX = P0 +; VGI_LY = P1 +; VGI_LX2 = P3 +; VGI_LY2 = P4 + +vgi_line_far: + jsr vgi_point_common + + ldx #1 + ldy VGI_LY2 + lda VGI_LX2 + + jsr HGLIN ; line to (X,A),(Y) + + jmp vgi_loop + diff --git a/graphics/hgr/vgi-doom/vgi_rectangle.s b/graphics/hgr/vgi-doom/vgi_rectangle.s new file mode 100644 index 00000000..eea8de2f --- /dev/null +++ b/graphics/hgr/vgi-doom/vgi_rectangle.s @@ -0,0 +1,462 @@ +; VGI Rectangle + +; VGI Rectangle test + +COLOR_MODE = TEMP0 +OTHER_MASK = TEMP1 +XRUN = TEMP2 + +div7_table = $9000 +mod7_table = $9100 + +USE_FAST = 1 + + + +.if (USE_FAST=0) + + ; slow + ;================================= + ; Simple Rectangle + ;================================= + VGI_RCOLOR = P0 + VGI_RX1 = P1 + VGI_RY1 = P2 + VGI_RXRUN = P3 + VGI_RYRUN = P4 + +vgi_simple_rectangle: + +simple_rectangle_loop: + + lda VGI_RCOLOR + + asl ; nibble swap by david galloway + adc #$80 + rol + asl + adc #$80 + rol + + sta VGI_RCOLOR + + and #$f + tax + + lda COLORTBL,X + sta HGR_COLOR + + ldx VGI_RX1 ; X1 into X + lda VGI_RY1 ; Y1 into A + ldy #0 ; always 0 + jsr HPOSN ; (Y,X),(A) (values stores in HGRX,XH,Y) + + + lda VGI_RXRUN ; XRUN into A + ldx #0 ; always 0 + ldy #0 ; relative Y is 0 + jsr HLINRL ; (X,A),(Y) + + inc VGI_RY1 + dec VGI_RYRUN + bne simple_rectangle_loop + + jmp vgi_loop + + + + ;================================= + ; Dithered Rectangle + ;================================= +; VGI_RCOLOR = P0 +; VGI_RX1 = P1 +; VGI_RY1 = P2 +; VGI_RXRUN = P3 +; VGI_RYRUN = P4 + VGI_RCOLOR2 = P5 + +vgi_dithered_rectangle: + +dithered_rectangle_loop: + lda COUNT + and #$1 + beq even_color +odd_color: + lda VGI_RCOLOR + jmp save_color +even_color: + lda VGI_RCOLOR2 +save_color: + sta HGR_COLOR + + inc COUNT + + ldx VGI_RX1 ; X1 into X + lda VGI_RY1 ; Y1 into A + ldy #0 ; always 0 + jsr HPOSN ; (Y,X),(A) (values stores in HGRX,XH,Y) + + + lda VGI_RXRUN ; XRUN into A + ldx #0 ; always 0 + ldy #0 ; relative Y is 0 + jsr HLINRL ; (X,A),(Y) + + inc VGI_RY1 + dec VGI_RYRUN + bne dithered_rectangle_loop + + jmp vgi_loop + + + +.else + + + + + ; FAST + ;================================= + ; Simple Rectangle + ;================================= + VGI_RCOLOR = P0 + VGI_RX1 = P1 + VGI_RY1 = P2 + VGI_RXRUN = P3 + VGI_RYRUN = P4 + VGI_RCOLOR2 = P5 ; only for dither + + ;================================== + ; VGI Simple Rectangle + ;================================== + +vgi_simple_rectangle: + lda #0 + sta COLOR_MODE + +simple_rectangle_loop: + + lda COLOR_MODE + beq simple_colors + bmi striped_colors + bpl handle_dither + + +simple_colors: + + lda VGI_RCOLOR + + asl ; nibble swap by david galloway + adc #$80 + rol + asl + adc #$80 + rol + + sta VGI_RCOLOR + + and #$f + tax + + lda COLORTBL,X + sta HGR_COLOR + jmp done_colors + +handle_dither: + + lda COUNT + and #$1 + beq deven_color +dodd_color: + lda VGI_RCOLOR + jmp dsave_color +deven_color: + lda VGI_RCOLOR2 +dsave_color: + sta HGR_COLOR + + inc COUNT + jmp done_colors +striped_colors: + + ; don't need to do anything here? + +done_colors: + + ; get ROW into (GBASL) + + ldx VGI_RX1 ; X1 into X + lda VGI_RY1 ; Y1 into A + ldy #0 ; always 0 + jsr HPOSN ; (Y,X),(A) (values stores in HGRX,XH,Y) + + ; Y is already the RX1/7 + + ; adjust color if in striped mode + lda COLOR_MODE + bpl not_striped + + jsr swap_colors + +not_striped: + + ; copy the XRUN + + lda VGI_RXRUN + sta XRUN + + inc XRUN ; needed because we compare with beq/bne + + + ; check if narrow corner case where begin and end same block + ; if RX%7 + XRUN < 8 + + ldx VGI_RX1 + lda mod7_table,X + clc + adc XRUN + cmp #8 + bcs not_corner + +corner: + ; want to use MASK of left_mask, MOD7 and 7-XRUN + + lda mod7_table,X + tax + + lda (GBASL),Y + eor HGR_BITS + and left_masks,X + ldx XRUN + and right_masks,X + eor (GBASL),Y + sta (GBASL),Y + + jmp done_row ; that's all + +not_corner: + + ; see if not starting on boundary + ldx VGI_RX1 + lda mod7_table,X + beq draw_run + + ; handle not full left border + + tax + lda (GBASL),Y + eor HGR_BITS + and left_masks,X + eor (GBASL),Y + sta (GBASL),Y + + iny ; move to next + + ; adjust RUN length by 7- mod7 + txa ; load mod7 + eor #$ff + sec + adc #7 + eor #$ff + sec + adc XRUN + sta XRUN + +; lda HGR_BITS ; cycle colors for next +; jsr COLOR_SHIFT + + jsr swap_colors + +;no_shift: + + ; draw common +draw_run: + lda XRUN + cmp #7 + bcc draw_right ; blt + + lda HGR_BITS ; get color + sta (GBASL),Y ; store out +; jsr COLOR_SHIFT ; shift colors + + iny ; move to next block + + jsr swap_colors + + lda XRUN ; take 7 off the run + sec + sbc #7 + sta XRUN + + jmp draw_run + + ; draw rightmost +draw_right: + + beq done_row + +; lda HGR_BITS +; jsr COLOR_SHIFT + + ; see if not starting on boundary + ldx XRUN + tax + + lda (GBASL),Y + eor HGR_BITS + and right_masks,X + eor (GBASL),Y + sta (GBASL),Y + +done_row: + + inc VGI_RY1 + dec VGI_RYRUN + ;bne simple_rectangle_loop + beq done_done + jmp simple_rectangle_loop + +done_done: + jmp vgi_loop + + + + ;========================== + ; swap colors + ;========================== +swap_colors: + + lda COLOR_MODE + bmi swap_colors_striped + + lda HGR_BITS ; get color + jsr COLOR_SHIFT ; shift colors + + rts + +swap_colors_striped: + + tya + and #1 + bne swap_odd + + lda VGI_RCOLOR + jmp swap_done + +swap_odd: + lda VGI_RCOLOR2 +swap_done: + sta HGR_BITS + + rts + + + + + + + + + ;================================= + ; Dithered Rectangle + ;================================= +; VGI_RCOLOR = P0 +; VGI_RX1 = P1 +; VGI_RY1 = P2 +; VGI_RXRUN = P3 +; VGI_RYRUN = P4 +; VGI_RCOLOR2 = P5 + +vgi_dithered_rectangle: + lda #1 + sta COLOR_MODE + + lda #0 + sta COUNT + + jmp simple_rectangle_loop + + + ;================================= + ; Vertical Striped Rectangle + ;================================= +; VGI_RCOLOR = P0 +; VGI_RX1 = P1 +; VGI_RY1 = P2 +; VGI_RXRUN = P3 +; VGI_RYRUN = P4 +; VGI_RCOLOR2 = P5 + +vgi_vstripe_rectangle: + lda #128 + sta COLOR_MODE + + lda #0 + sta COUNT + + jmp simple_rectangle_loop + + +.endif + + + + + + + ;===================== + ; make /7 %7 tables + ;===================== + +vgi_init: + +vgi_make_tables: + + ldy #0 + lda #0 + ldx #0 +div7_loop: + sta div7_table,Y + + inx + cpx #7 + bne div7_not7 + + clc + adc #1 + ldx #0 +div7_not7: + iny + bne div7_loop + + + ldy #0 + lda #0 +mod7_loop: + sta mod7_table,Y + clc + adc #1 + cmp #7 + bne mod7_not7 + lda #0 +mod7_not7: + iny + bne mod7_loop + + rts + +left_masks: + .byte $FF,$FE,$FC,$F8, $F0,$E0,$C0 + +right_masks: + .byte $81,$83,$87, $8F,$9F,$BF,$FF + + + + + + + + + + diff --git a/graphics/hgr/vgi-doom/vgi_triangles.s b/graphics/hgr/vgi-doom/vgi_triangles.s new file mode 100644 index 00000000..259b8b6f --- /dev/null +++ b/graphics/hgr/vgi-doom/vgi_triangles.s @@ -0,0 +1,96 @@ +; VGI Triangles + +SKIP = TEMP0 + + ;======================== + ; VGI vertical triangle + ;======================== + + VGI_TCOLOR = P0 + VGI_VX = P1 + VGI_VY = P2 + VGI_TXL = P3 + VGI_TXR = P4 + VGI_TYB = P5 + +vgi_vertical_triangle: + lda VGI_TCOLOR + lsr + lsr + lsr + lsr + sta SKIP + + lda VGI_TCOLOR + and #$f + tax + lda COLORTBL,X + sta HGR_COLOR + +vtri_loop: + ldy #0 + ldx VGI_VX + lda VGI_VY + + jsr HPLOT0 ; plot at (Y,X), (A) + + + ldx #0 + ldy VGI_TYB + lda VGI_TXL + + jsr HGLIN ; line to (X,A),(Y) + + lda VGI_TXL + clc + adc SKIP + sta VGI_TXL +; inc VGI_TXL +; lda VGI_TXL + cmp VGI_TXR + bcc vtri_loop + +done_vtri: + jmp vgi_loop ; bra + + + + ;======================== + ; VGI horizontal triangle + ;======================== + +; VGI_TCOLOR = P0 +; VGI_VX = P1 +; VGI_VY = P2 + VGI_THYT = P3 + VGI_THYB = P4 + VGI_THXR = P5 + +vgi_horizontal_triangle: + + ldx VGI_TCOLOR + lda COLORTBL,X + sta HGR_COLOR + +htri_loop: + ldy #0 + ldx VGI_VX + lda VGI_VY + + jsr HPLOT0 ; plot at (Y,X), (A) + + + ldx #0 + ldy VGI_THYT + lda VGI_THXR + + jsr HGLIN ; line to (X,A),(Y) + + inc VGI_THYT + lda VGI_THYT + cmp VGI_THYB + bcc htri_loop + +done_htri: + jmp vgi_loop + diff --git a/graphics/hgr/vgi-doom/zp.inc b/graphics/hgr/vgi-doom/zp.inc new file mode 100644 index 00000000..01509898 --- /dev/null +++ b/graphics/hgr/vgi-doom/zp.inc @@ -0,0 +1,76 @@ +; zero page + +TEMP0 = $10 +TEMP1 = $11 +TEMP2 = $12 +TEMP3 = $13 +TEMP4 = $14 +TEMP5 = $15 + +;; Zero page addresses + +HGR_BITS = $1C + +GBASL = $26 +GBASH = $27 + +ORNAMENT_L = $60 +ORNAMENT_H = $61 +SAMPLE_L = $62 +SAMPLE_H = $63 + +LOOP = $64 +MB_ADDR_L = $65 +MB_ADDR_H = $66 +MB_VALUE = $67 +DONE_PLAYING = $68 +DONE_SONG = $69 +PT3_TEMP = $6A +APPLEII_MODEL = $6B + +AY_REGISTERS = $50 +A_FINE_TONE = $50 +A_COARSE_TONE = $51 +B_FINE_TONE = $52 +B_COARSE_TONE = $53 +C_FINE_TONE = $54 +C_COARSE_TONE = $55 +NOISE = $56 +ENABLE = $57 +PT3_MIXER_VAL = $57 +A_VOLUME = $58 +B_VOLUME = $59 +C_VOLUME = $5A +ENVELOPE_FINE = $5B +ENVELOPE_COARSE = $5C +ENVELOPE_SHAPE = $5D + +PATTERN_L = $5E +PATTERN_H = $5F + + + +HGR_X = $E0 +HGR_XH = $E1 +HGR_Y = $E2 +HGR_COLOR = $E4 +HGR_PAGE = $E6 + +VGI_BUFFER = $F0 +VGI_TYPE = $F0 +P0 = $F1 +P1 = $F2 +P2 = $F3 +P3 = $F4 +P4 = $F5 +P5 = $F6 +P6 = $F7 +VGIL = $F8 +VGIH = $F9 + +OUTL = $FC +OUTH = $FD + +COLOR1 = $FE +COLOR2 = $FF + diff --git a/graphics/hgr/vgi/Makefile b/graphics/hgr/vgi/Makefile index 05eaac92..15acafe0 100644 --- a/graphics/hgr/vgi/Makefile +++ b/graphics/hgr/vgi/Makefile @@ -8,11 +8,10 @@ MAKEVGI = ./make_vgi_asm all: vgi_myst.dsk make_vgi_asm make_color_test -vgi_myst.dsk: HELLO VGI-MYST VGI-DOOM COLOR-TEST VGI-TEST +vgi_myst.dsk: HELLO VGI-MYST COLOR-TEST VGI-TEST cp $(EMPTYDISK) vgi_myst.dsk $(DOS33) -y vgi_myst.dsk SAVE A HELLO $(DOS33) -y vgi_myst.dsk BSAVE -a 0xC00 VGI-MYST - $(DOS33) -y vgi_myst.dsk BSAVE -a 0x4000 VGI-DOOM $(DOS33) -y vgi_myst.dsk BSAVE -a 0x4000 COLOR-TEST $(DOS33) -y vgi_myst.dsk BSAVE -a 0x4000 VGI-TEST @@ -45,16 +44,6 @@ test_vgi.o: new.data \ ### -VGI-DOOM: doom_vgi.o - ld65 -o VGI-DOOM doom_vgi.o -C $(LINKERSCRIPTS)/apple2_4000.inc - -doom_vgi.o: doom.data \ - doom_vgi.s vgi_clearscreen.s vgi_rectangle.s vgi_circles.s vgi_lines.s \ - vgi_triangles.s - ca65 -o doom_vgi.o doom_vgi.s -l doom_vgi.lst - -### - COLOR-TEST: color_test.o ld65 -o COLOR-TEST color_test.o -C $(LINKERSCRIPTS)/apple2_4000.inc @@ -65,11 +54,6 @@ color_test.o: color_test.data \ -### - -doom.data: make_vgi_asm doom.vgi - echo "doom_data:" > doom.data - ./make_vgi_asm < doom.vgi >> doom.data ###