vgi-doom: split off to own directory

This commit is contained in:
Vince Weaver 2021-07-29 15:35:06 -04:00
parent f73271f20d
commit 1bd9028b9b
23 changed files with 1702 additions and 20 deletions

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,5 @@
5 HOME
10 PRINT CHR$(4);"CATALOG"
40 PRINT:PRINT "FOR THE DOOM DEMO"
50 PRINT "TYPE: BRUN VGI-DOOM"

View File

@ -0,0 +1,457 @@
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#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;i<count;i++) {
printf("$%02X",bytes[i]);
if (i<count-1) {
printf(",");
}
else {
printf("\n");
}
}
}
else {
fwrite(bytes,1,count,stdout);
}
return count;
}
int main(int argc, char **argv) {
char buffer[1024];
unsigned char output[1024];
char *ptr;
int type,color1,color2,x1,x2,y1,y2,r,xl,xr,yt,yb;
int line=1;
int size=0;
int skip=0;
int mode=MODE_ASM;
int lastx=0,lasty=0,lastcolor=0;
int tempx,tempcolor;
if (argc>1) {
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;
}

View File

@ -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

View File

@ -0,0 +1,7 @@
vgi_clearscreen:
lda P0
jsr BKGND0
jmp vgi_loop ; return

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
###