xrick2gs/bin/blit/source/blit.c

349 lines
6.6 KiB
C

/*
#--------------------------------------------------------
# $File: blit.c,v $
#--------------------------------------------------------
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include "bctypes.h"
#include "blit.h"
#include "rawdata.h"
RAWDATA* gResult = NULL;
void AddString(RAWDATA* pRaw, char* pString)
{
size_t len = strlen(pString);
size_t newlen = len+pRaw->size;
pRaw->data = (unsigned char*) realloc(pRaw->data, newlen);
memcpy(pRaw->data + pRaw->size, pString, len);
pRaw->size = newlen;
}
int AddLine(char*pLabel,char*pInst,char*pExp,int val,int clocks)
{
if (gResult)
{
char temp[256];
char pArg[256];
memset(pArg,0,256);
sprintf(pArg,pExp,val);
sprintf(temp, "%8s %3s %s\n", pLabel,pInst,pArg);
AddString(gResult, temp);
}
return clocks;
}
//
// Call it with A = 0
// And the S set to the DPage Table in memory
//
void CompileBlockTRB(RAWDATA *result, int x, int width)
{
int clocks = 0;
//clocks += AddLine("","TCD"," ; Set DP ",0,2);
//clocks += AddLine("","TXA"," ; Zero out A", 0,2);
clocks += AddLine("","PLD"," ; Set DP", 0,4);
for (int y = 0; y < 8; ++y)
{
int p = y * 160;
//for (int xs = x; xs < (x+width) ; xs+=4)
for (int xs = 0; xs < 320; xs+=4)
{
int xbyte = (xs>>1) + p;
if ((0 == (xbyte&0xFF)) && y)
{
clocks += AddLine("","PLD"," ; Set DP", 0,4);
//clocks += AddLine("","TDC"," ; Set DP ",0,2);
//clocks += AddLine("","ADC","#$100",0,3);
//clocks += AddLine("","TCD"," ; Set DP ",0,2);
//clocks += AddLine("","TXA"," ; Zero out A", 0,2);
}
if ((xs>=x)&&(xs<(x+width)))
{
clocks += AddLine("","TRB","$%02X",xbyte&0xFF,7);
}
}
}
// clocks += AddLine("","RTL"," ;%d cycles",clocks+6,6);
clocks += AddLine("","JMP","BRET ;%d cycles",clocks+3,3);
}
RAWDATA* CompileTRB()
{
RAWDATA* result = (RAWDATA*)malloc(sizeof(RAWDATA));
memset(result, 0, sizeof(RAWDATA));
char temp_label[256];
gResult = result;
int screen_width = 320;
int width = 320;
int pixel_step = 8; // x position granularity
int pixel_block = 8; // min width
while (width >= pixel_block)
{
for (int x = 0; x <= (screen_width - width); x+=pixel_step)
{
printf(temp_label,"blit%d_%d\n", x, width);
sprintf(temp_label,"blit%d_%d\n", x, width);
AddString(result, temp_label);
CompileBlockTRB(result, x, width);
}
width -= pixel_block;
}
return result;
}
//A = ADC(A,delta,C);
int ADC(int A, int delta, int* C)
{
u32 uA = A &0xFFFF;
u32 uD = delta&0xFFFF;
int result = A + delta + *C;
u32 uResult = uA+uD+*C;
*C = (uResult>>16) & 1;
return result;
}
/*
lda #$2000
tcd
lda #$20FF
tcs
pei $fe
pei $fc
pei $f8
....
....
pei $02
pei $00
inc
tcd
adc #$FF
tcs
..........
For regions less than the page width, go line by line
call with X
*/
void CompileBlockPEI_fwd(RAWDATA *result, int x, int width)
{
int clocks = 0;
int A = 0; // What's in the accumulator
int C = 0;
clocks += AddLine("","TCD"," ; Set DP $%04X",A,2);
clocks += AddLine("","ADC","#%d",((x+width)>>1)-1,3);
A+=((x+width)>>1)-1;
int S=A;
clocks += AddLine("","TCS"," ; Set S $%04X",A,2);
int dp = 0;
for (int y = 0; y < 8; ++y)
{
int p = y * 160;
for (int xs = 316; xs >= 0; xs-=4)
{
int xbyte = (xs>>1) + p;
if ((xs>=x)&&(xs<(x+width)))
{
if ((dp & 0xFF00) != (xbyte & 0xFF00))
{
int delta = (xbyte&0xFF00) - (A+C); //(dp & 0xFF00);
A = ADC(A,delta,&C);
clocks += AddLine("","ADC","#%d",delta,3);
clocks += AddLine("","TCD"," ; Set DP $%04X",A,2);
}
clocks += AddLine("", "PEI", "$%02X", xbyte & 0xFF, 6);
dp = xbyte;
}
}
if (y < 7)
{
S+=160;
int delta = S - (A+C);
A = ADC(A,delta,&C);
clocks += AddLine("", "ADC", "#%d", delta, 3);
clocks += AddLine("","TCS"," ; Set S $%04X",A,2);
}
}
// clocks += AddLine("","RTL"," ;%d cycles",clocks+6,6);
clocks += AddLine("","JMP","BRET ;%d cycles",clocks+3,3);
}
void CompileBlockPEI(RAWDATA *result, int x, int width)
{
int clocks = 0;
int A = 0x400; // What's in the accumulator
int C = 0;
clocks += AddLine("","TCD"," ; Set DP $%04X",A,2);
clocks += AddLine("","ADC","#%d",(7*160)-(1024)+((x+width)>>1)-1,3);
A+=(7*160)-(1024)+((x+width)>>1)-1;
int S=A;
clocks += AddLine("","TCS"," ; Set S $%04X",A,2);
int dp = 0x400;
for (int y = 7; y >= 0; --y)
{
int p = y * 160;
for (int xs = 316; xs >= 0; xs-=4)
{
int xbyte = (xs>>1) + p;
if ((xs>=x)&&(xs<(x+width)))
{
if ((dp & 0xFF00) != (xbyte & 0xFF00))
{
int delta = (xbyte&0xFF00) - (A+C); //(dp & 0xFF00);
A = ADC(A,delta,&C);
clocks += AddLine("","ADC","#%d",delta,3);
clocks += AddLine("","TCD"," ; Set DP $%04X",A,2);
}
clocks += AddLine("", "PEI", "$%02X", xbyte & 0xFF, 6);
dp = xbyte;
}
}
if (y > 0)
{
S-=160;
int delta = S - (A+C);
A = ADC(A,delta,&C);
clocks += AddLine("", "ADC", "#%d", delta, 3);
clocks += AddLine("","TCS"," ; Set S $%04X",A,2);
}
}
// clocks += AddLine("","RTL"," ;%d cycles",clocks+6,6);
clocks += AddLine("","JMP","BRET ;%d cycles",clocks+3,3);
}
RAWDATA* CompilePEI()
{
RAWDATA* result = (RAWDATA*)malloc(sizeof(RAWDATA));
memset(result, 0, sizeof(RAWDATA));
char temp_label[256];
gResult = result;
int screen_width = 320;
int width = 320;
int pixel_step = 8; // x position granularity
int pixel_block = 8; // min width
while (width >= pixel_block)
{
for (int x = 0; x <= (screen_width - width); x+=pixel_step)
{
printf(temp_label,"blit%d_%d\n", x, width);
sprintf(temp_label,"blit%d_%d\n", x, width);
AddString(result, temp_label);
CompileBlockPEI(result, x, width);
}
width -= pixel_block;
}
return result;
}
static void _usage()
{
printf("blit v%s\n\n", VERSION);
printf("Usage: blit\n"
"Written by Jason Andersen\n"
"Copyright (c) 2018 Jason Andersen.\n"
"Unauthorized use prohibited\n");
exit(1);
} // usage
//
// Parse command line options
//
int main(int argc, char **argv)
{
// Check Arguments
while (--argc > 0 && (*++argv)[0] == '-')
{
*argv+=1;
if (strcmp("v", *argv) == 0)
{
printf("blit v%s\n", VERSION);
exit(0);
}
*argv+= strlen(*argv); // skip rest of string
}
if (argc) _usage();
RAWDATA* pBlitTRB = CompileTRB();
saveRaw(pBlitTRB, "trb.txt");
RAWDATA* pBlitPEI = CompilePEI();
saveRaw(pBlitPEI, "pei.txt");
printf("\nblit - Processing complete.\n");
exit(0);
} // main
// eof - blit.c