commit
28bdb2e395
30
README.md
30
README.md
|
@ -259,7 +259,7 @@ Imports the sprite data and compresses it using lzo compression
|
||||||
|
|
||||||
### Console input and output
|
### Console input and output
|
||||||
|
|
||||||
The C64 does not use ASCII it uses a derivative called PETSCII. There are two fonts, one with uppercase and one with uppercase and lowercase characters. It also used CR (13) as line terminator instead of LF (10). The stdio and conio libaries can perform translations.
|
The C64 does not use ASCII it uses a derivative called PETSCII. There are two fonts, one with uppercase and one with uppercase and lowercase characters. It also used CR (13) as line terminator instead of LF (10). The stdio and conio libraries can perform translations.
|
||||||
|
|
||||||
The translation mode is selected in conio with the variable "giocharmap" and the function "iocharmap" which will also switch the font.
|
The translation mode is selected in conio with the variable "giocharmap" and the function "iocharmap" which will also switch the font.
|
||||||
|
|
||||||
|
@ -276,7 +276,7 @@ Screen codes can be generated similar using "s" or "S" prefix.
|
||||||
|
|
||||||
Input from the console will also be translated accordingly.
|
Input from the console will also be translated accordingly.
|
||||||
|
|
||||||
The character map for string and char constants can be changed with a pragma to match a custon character set or PETSCII.
|
The character map for string and char constants can be changed with a pragma to match a custom character set or PETSCII.
|
||||||
|
|
||||||
#pragma charmap(char, code [,count])
|
#pragma charmap(char, code [,count])
|
||||||
|
|
||||||
|
@ -308,7 +308,7 @@ Set optimizer options that are active for the functions after it
|
||||||
|
|
||||||
### Loop unrolling
|
### Loop unrolling
|
||||||
|
|
||||||
Loop unrolling on 6502 is hard to decide for the compiler. Memory is usually scarce, so it only does it in realy obvious cases (and in less obvious cases for O3). On the other hand unrolling is required to get good performance in e.g. scrolling code. Therefore the compiler offers an unrolling pragma, that can be used to specifiy the amount of unrolling either as a number or "full" for complete.
|
Loop unrolling on 6502 is hard to decide for the compiler. Memory is usually scarce, so it only does it in really obvious cases (and in less obvious cases for O3). On the other hand unrolling is required to get good performance in e.g. scrolling code. Therefore the compiler offers an unrolling pragma, that can be used to specify the amount of unrolling either as a number or "full" for complete.
|
||||||
|
|
||||||
The following code scrolls the screen to the left, and completely unrolls the inner vertical loop.
|
The following code scrolls the screen to the left, and completely unrolls the inner vertical loop.
|
||||||
|
|
||||||
|
@ -320,12 +320,12 @@ The following code scrolls the screen to the left, and completely unrolls the in
|
||||||
screen[y][x] = screen[y][x + 1];
|
screen[y][x] = screen[y][x + 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
Sometimes it is better to unroll the loop not in the order it normaly executes, but using page size chunks. When e.g. filling a C64 screen with a loop:
|
Sometimes it is better to unroll the loop not in the order it normally executes, but using page size chunks. When e.g. filling a C64 screen with a loop:
|
||||||
|
|
||||||
for(int i=0; i<1000; i++)
|
for(int i=0; i<1000; i++)
|
||||||
Screen[i] = ' ';
|
Screen[i] = ' ';
|
||||||
|
|
||||||
Unrolling this loop would not help, the index would still not fit into the 8 bit x or y register. Using a page level unroll, the compiler will unroll the loop into four stores, each 250 bytes appart, and use the y or x register for indexing:
|
Unrolling this loop would not help, the index would still not fit into the 8 bit x or y register. Using a page level unroll, the compiler will unroll the loop into four stores, each 250 bytes apart, and use the y or x register for indexing:
|
||||||
|
|
||||||
#pragma unroll(page)
|
#pragma unroll(page)
|
||||||
for(int i=0; i<1000; i++)
|
for(int i=0; i<1000; i++)
|
||||||
|
@ -441,7 +441,7 @@ This sample fills a single screen column with a given color, by generating 25 as
|
||||||
#undef ry
|
#undef ry
|
||||||
}
|
}
|
||||||
|
|
||||||
This sample initialy assigns the value 0 to the pre processor macro ry and increments it each time the loop body is replicated. The loop generates 25 copies of the body, each with a different value for ry.
|
This sample initially assigns the value 0 to the pre processor macro ry and increments it each time the loop body is replicated. The loop generates 25 copies of the body, each with a different value for ry.
|
||||||
|
|
||||||
|
|
||||||
### Linker control
|
### Linker control
|
||||||
|
@ -584,7 +584,7 @@ And for bank one
|
||||||
|
|
||||||
### Inline Assembler
|
### Inline Assembler
|
||||||
|
|
||||||
Inline assembler can be embedded inside of any functions, regardles of their compilation target of byte code or native.
|
Inline assembler can be embedded inside of any functions, regardless of their compilation target of byte code or native.
|
||||||
|
|
||||||
#### Accessing variables in assembler
|
#### Accessing variables in assembler
|
||||||
|
|
||||||
|
@ -708,19 +708,19 @@ Moves the BASIC ROM, Kernal ROM and the IO area out of the way and allows the us
|
||||||
|
|
||||||
#### Custom character set "charsetlo.c"
|
#### Custom character set "charsetlo.c"
|
||||||
|
|
||||||
Embedds a custom character set into the prg file at 0x2000..0x27ff and switches the character set base address in the VIC to this address. The code and data portion of the compiled program is split into two areas to make room for this fixed location data.
|
Embeds a custom character set into the prg file at 0x2000..0x27ff and switches the character set base address in the VIC to this address. The code and data portion of the compiled program is split into two areas to make room for this fixed location data.
|
||||||
|
|
||||||
#### Himem character set "charsethi.c"
|
#### Himem character set "charsethi.c"
|
||||||
|
|
||||||
Embedds a custom character set into the prg file at 0xc800..0xcfff and switches the character set base address in the VIC to this address.
|
Embeds a custom character set into the prg file at 0xc800..0xcfff and switches the character set base address in the VIC to this address.
|
||||||
|
|
||||||
#### Copy character set "charsetcopy.c"
|
#### Copy character set "charsetcopy.c"
|
||||||
|
|
||||||
Embedds a custom character set into the prg file at 0xc000..0xc7ff and copies it to 0xd000 on startup. This frees this area for stack and heap usage.
|
Embeds a custom character set into the prg file at 0xc000..0xc7ff and copies it to 0xd000 on startup. This frees this area for stack and heap usage.
|
||||||
|
|
||||||
#### Copy character set "charsetexpand.c"
|
#### Copy character set "charsetexpand.c"
|
||||||
|
|
||||||
Embedds a custom character set into the prg file at 0xc000..0xc7ff using lz comression and expands it to 0xd000 on startup. This frees this area for stack and heap usage.
|
Embeds a custom character set into the prg file at 0xc000..0xc7ff using lz compression and expands it to 0xd000 on startup. This frees this area for stack and heap usage.
|
||||||
|
|
||||||
#### Custom character set "charsetload.c"
|
#### Custom character set "charsetload.c"
|
||||||
|
|
||||||
|
@ -918,7 +918,7 @@ Expands a 2D 4x4 tile grid at any scroll speed. Uses a raster IRQ to limit the
|
||||||
|
|
||||||
### Moving image blocks "sprites"
|
### Moving image blocks "sprites"
|
||||||
|
|
||||||
Sprites are independed image blocks, such as players, missiles or enemies that can be shown on top of the background.
|
Sprites are independent image blocks, such as players, missiles or enemies that can be shown on top of the background.
|
||||||
|
|
||||||
#### Control a sprite with a joystick "joycontrol.c"
|
#### Control a sprite with a joystick "joycontrol.c"
|
||||||
|
|
||||||
|
@ -1071,7 +1071,7 @@ The intermediate code generator takes the declaration graph and converts it into
|
||||||
|
|
||||||
#### Intermediate Code Optimizer
|
#### Intermediate Code Optimizer
|
||||||
|
|
||||||
The intermediate code optimizer works on the intermediat code to perform machine agnostic optimizations, such as value forwarding, strength reduction or loop unrolling. It also tries to build evaluation trains to reduce the amount of temporaries required for execution.
|
The intermediate code optimizer works on the intermediate code to perform machine agnostic optimizations, such as value forwarding, strength reduction or loop unrolling. It also tries to build evaluation trains to reduce the amount of temporaries required for execution.
|
||||||
|
|
||||||
#### Native/Bytecode Generator
|
#### Native/Bytecode Generator
|
||||||
|
|
||||||
|
@ -1087,7 +1087,7 @@ This stage translates the symbolic assembler / bytecode into binary and makes it
|
||||||
|
|
||||||
#### Linker
|
#### Linker
|
||||||
|
|
||||||
The linker determines all objects that are referenced and discards objects that are not. It then places the objects into their sections and spreads the sections over the regions. Then all references between the objects are resolved. Finaly the prg or crt file is written.
|
The linker determines all objects that are referenced and discards objects that are not. It then places the objects into their sections and spreads the sections over the regions. Then all references between the objects are resolved. Finally the prg or crt file is written.
|
||||||
|
|
||||||
#### Listing generator
|
#### Listing generator
|
||||||
|
|
||||||
|
@ -1172,7 +1172,7 @@ The sum of the array elements is only needed when the condition is false:
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
In this case, the evaluation of the sum is moved into an artifical else case:
|
In this case, the evaluation of the sum is moved into an artificial else case:
|
||||||
|
|
||||||
test:
|
test:
|
||||||
090e LDA P0
|
090e LDA P0
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef FIXMATH_H
|
#ifndef FIXMATH_H
|
||||||
#define FIXMATH_H
|
#define FIXMATH_H
|
||||||
|
|
||||||
// Multiply two unsinged 16bit numbers and return a 32bit result
|
// Multiply two unsigned 16bit numbers and return a 32bit result
|
||||||
__native unsigned long lmul16u(unsigned x, unsigned y);
|
__native unsigned long lmul16u(unsigned x, unsigned y);
|
||||||
|
|
||||||
// Multiply two signed 16bit numbers and return a signed 32bit result
|
// Multiply two signed 16bit numbers and return a signed 32bit result
|
||||||
|
|
|
@ -94,7 +94,7 @@ int main(void)
|
||||||
ppu.scroll = 0x00;
|
ppu.scroll = 0x00;
|
||||||
ppu.oamaddr = 0x00;
|
ppu.oamaddr = 0x00;
|
||||||
|
|
||||||
// detech PAL or NTSC based on Blarg code.
|
// detect PAL or NTSC based on Blarg code.
|
||||||
|
|
||||||
ppu_wait_nmi();
|
ppu_wait_nmi();
|
||||||
|
|
||||||
|
|
|
@ -256,7 +256,7 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec)
|
||||||
Declaration* dec = procDec->mBase->mParams;
|
Declaration* dec = procDec->mBase->mParams;
|
||||||
while (dec)
|
while (dec)
|
||||||
{
|
{
|
||||||
// Check for paramter crossing boundary
|
// Check for parameter crossing boundary
|
||||||
if (nbase + nparams < numfpzero && nbase + nparams + dec->mBase->mSize > numfpzero)
|
if (nbase + nparams < numfpzero && nbase + nparams + dec->mBase->mSize > numfpzero)
|
||||||
{
|
{
|
||||||
npalign = numfpzero - (nbase + nparams);
|
npalign = numfpzero - (nbase + nparams);
|
||||||
|
|
|
@ -9547,7 +9547,7 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
|
||||||
|
|
||||||
if (nins && t >= 0)
|
if (nins && t >= 0)
|
||||||
{
|
{
|
||||||
// Check self destruction of source operaand
|
// Check self destruction of source operand
|
||||||
int l = 0;
|
int l = 0;
|
||||||
while (l < nins->mNumOperands && t != nins->mSrc[l].mTemp)
|
while (l < nins->mNumOperands && t != nins->mSrc[l].mTemp)
|
||||||
l++;
|
l++;
|
||||||
|
@ -14985,13 +14985,13 @@ void InterCodeProcedure::BuildDataFlowSets(void)
|
||||||
mEntryBlock->BuildLocalTempSets(numTemps);
|
mEntryBlock->BuildLocalTempSets(numTemps);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Build set of globaly provided temporaries
|
// Build set of globally provided temporaries
|
||||||
//
|
//
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
mEntryBlock->BuildGlobalProvidedTempSet(NumberSet(numTemps), NumberSet(numTemps));
|
mEntryBlock->BuildGlobalProvidedTempSet(NumberSet(numTemps), NumberSet(numTemps));
|
||||||
|
|
||||||
//
|
//
|
||||||
// Build set of globaly required temporaries, might need
|
// Build set of globally required temporaries, might need
|
||||||
// multiple iterations until it stabilizes
|
// multiple iterations until it stabilizes
|
||||||
//
|
//
|
||||||
NumberSet totalRequired(numTemps);
|
NumberSet totalRequired(numTemps);
|
||||||
|
@ -15018,7 +15018,7 @@ void InterCodeProcedure::RenameTemporaries(void)
|
||||||
numRename = 0;
|
numRename = 0;
|
||||||
|
|
||||||
//
|
//
|
||||||
// First localy rename all temporaries
|
// First locally rename all temporaries
|
||||||
//
|
//
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
mEntryBlock->LocalRenameRegister(mRenameTable, numRename);
|
mEntryBlock->LocalRenameRegister(mRenameTable, numRename);
|
||||||
|
@ -15173,7 +15173,7 @@ void InterCodeProcedure::TempForwarding(bool reverse, bool checkloops)
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Now remove needless temporary moves, that apear due to
|
// Now remove needless temporary moves, that appear due to
|
||||||
// stack evaluation
|
// stack evaluation
|
||||||
//
|
//
|
||||||
mTempForwardingTable.SetSize(numTemps);
|
mTempForwardingTable.SetSize(numTemps);
|
||||||
|
@ -15774,7 +15774,7 @@ void InterCodeProcedure::Close(void)
|
||||||
DisassembleDebug("machine value forwarding");
|
DisassembleDebug("machine value forwarding");
|
||||||
|
|
||||||
//
|
//
|
||||||
// Now remove needless temporary moves, that apear due to
|
// Now remove needless temporary moves, that appear due to
|
||||||
// stack evaluation
|
// stack evaluation
|
||||||
//
|
//
|
||||||
mTempForwardingTable.Reset();
|
mTempForwardingTable.Reset();
|
||||||
|
|
|
@ -913,7 +913,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro
|
||||||
vr = Dereference(proc, texp, block, vr, 1);
|
vr = Dereference(proc, texp, block, vr, 1);
|
||||||
|
|
||||||
if (vr.mReference != 1)
|
if (vr.mReference != 1)
|
||||||
mErrors->Error(exp->mLeft->mLocation, EERR_NOT_AN_LVALUE, "Not an adressable expression");
|
mErrors->Error(exp->mLeft->mLocation, EERR_NOT_AN_LVALUE, "Not an addressable expression");
|
||||||
|
|
||||||
if (vp.mTemp != vr.mTemp)
|
if (vp.mTemp != vr.mTemp)
|
||||||
{
|
{
|
||||||
|
@ -1339,7 +1339,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
if (vl.mReference != 1)
|
if (vl.mReference != 1)
|
||||||
mErrors->Error(exp->mLeft->mLocation, EERR_NOT_AN_LVALUE, "Not a left hand expression");
|
mErrors->Error(exp->mLeft->mLocation, EERR_NOT_AN_LVALUE, "Not a left hand expression");
|
||||||
if (vr.mReference != 1)
|
if (vr.mReference != 1)
|
||||||
mErrors->Error(exp->mLeft->mLocation, EERR_NOT_AN_LVALUE, "Not an adressable expression");
|
mErrors->Error(exp->mLeft->mLocation, EERR_NOT_AN_LVALUE, "Not an addressable expression");
|
||||||
|
|
||||||
if (vr.mTemp != vl.mTemp)
|
if (vr.mTemp != vl.mTemp)
|
||||||
{
|
{
|
||||||
|
@ -2566,7 +2566,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
vr = Dereference(proc, texp, block, vr, 1);
|
vr = Dereference(proc, texp, block, vr, 1);
|
||||||
|
|
||||||
if (vr.mReference != 1)
|
if (vr.mReference != 1)
|
||||||
mErrors->Error(exp->mLeft->mLocation, EERR_NOT_AN_LVALUE, "Not an adressable expression");
|
mErrors->Error(exp->mLeft->mLocation, EERR_NOT_AN_LVALUE, "Not an addressable expression");
|
||||||
|
|
||||||
if (vp.mTemp != vr.mTemp)
|
if (vp.mTemp != vr.mTemp)
|
||||||
{
|
{
|
||||||
|
|
|
@ -23885,7 +23885,7 @@ bool NativeCodeBasicBlock::MoveLoadIndirectBypassYUp(int at)
|
||||||
// ldy #imm
|
// ldy #imm
|
||||||
// lda (t0), y
|
// lda (t0), y
|
||||||
|
|
||||||
// move up, and keep A in Y for the intervall
|
// move up, and keep A in Y for the interval
|
||||||
|
|
||||||
int j = at - 1;
|
int j = at - 1;
|
||||||
while (j >= 3)
|
while (j >= 3)
|
||||||
|
@ -32183,7 +32183,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// shorten x/y register livetime
|
// shorten x/y register lifetime
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
//
|
//
|
||||||
|
@ -39773,7 +39773,7 @@ void NativeCodeProcedure::Optimize(void)
|
||||||
#if 1
|
#if 1
|
||||||
if (cnt > 190)
|
if (cnt > 190)
|
||||||
{
|
{
|
||||||
printf("Opps\n");
|
printf("Oops\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -39900,13 +39900,13 @@ void NativeCodeProcedure::BuildDataFlowSets(void)
|
||||||
mBlocks[0]->BuildLocalRegSets();
|
mBlocks[0]->BuildLocalRegSets();
|
||||||
|
|
||||||
//
|
//
|
||||||
// Build set of globaly provided temporaries
|
// Build set of globally provided temporaries
|
||||||
//
|
//
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
mBlocks[0]->BuildGlobalProvidedRegSet(NumberSet(NUM_REGS));
|
mBlocks[0]->BuildGlobalProvidedRegSet(NumberSet(NUM_REGS));
|
||||||
|
|
||||||
//
|
//
|
||||||
// Build set of globaly required temporaries, might need
|
// Build set of globally required temporaries, might need
|
||||||
// multiple iterations until it stabilizes
|
// multiple iterations until it stabilizes
|
||||||
//
|
//
|
||||||
NumberSet totalRequired(NUM_REGS);
|
NumberSet totalRequired(NUM_REGS);
|
||||||
|
@ -40535,7 +40535,7 @@ NativeCodeGenerator::Runtime& NativeCodeGenerator::ResolveRuntime(const Ident* i
|
||||||
i++;
|
i++;
|
||||||
Location loc;
|
Location loc;
|
||||||
if (i == mRuntime.Size() || !mRuntime[i].mLinkerObject)
|
if (i == mRuntime.Size() || !mRuntime[i].mLinkerObject)
|
||||||
mErrors->Error(loc, EERR_RUNTIME_CODE, "Undefied runtime function", ident->mString);
|
mErrors->Error(loc, EERR_RUNTIME_CODE, "Undefined runtime function", ident->mString);
|
||||||
return mRuntime[i];
|
return mRuntime[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -739,7 +739,7 @@ Expression* Parser::ParseInitExpression(Declaration* dtype)
|
||||||
if (dtype->mIdent)
|
if (dtype->mIdent)
|
||||||
mErrors->Error(mScanner->mLocation, EERR_UNDEFINED_OBJECT, "Constant for undefined type", dtype->mIdent);
|
mErrors->Error(mScanner->mLocation, EERR_UNDEFINED_OBJECT, "Constant for undefined type", dtype->mIdent);
|
||||||
else
|
else
|
||||||
mErrors->Error(mScanner->mLocation, EERR_UNDEFINED_OBJECT, "Constant for undefined annonymous type");
|
mErrors->Error(mScanner->mLocation, EERR_UNDEFINED_OBJECT, "Constant for undefined anonymous type");
|
||||||
}
|
}
|
||||||
if (ConsumeTokenIf(TK_OPEN_BRACE))
|
if (ConsumeTokenIf(TK_OPEN_BRACE))
|
||||||
{
|
{
|
||||||
|
|
|
@ -447,7 +447,7 @@ int main2(int argc, const char** argv)
|
||||||
{
|
{
|
||||||
if (!d64->WriteFile(dataFiles[i], dataFileCompressed[i]))
|
if (!d64->WriteFile(dataFiles[i], dataFileCompressed[i]))
|
||||||
{
|
{
|
||||||
printf("Could not embedd disk file %s\n", dataFiles[i]);
|
printf("Could not embed disk file %s\n", dataFiles[i]);
|
||||||
return 20;
|
return 20;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#define Color ((char *)0xc800)
|
#define Color ((char *)0xc800)
|
||||||
#define Color2 ((char *)0xd800)
|
#define Color2 ((char *)0xd800)
|
||||||
|
|
||||||
// Bit patters for eight different color pairs
|
// Bit patterns for eight different color pairs
|
||||||
char colors[] = {
|
char colors[] = {
|
||||||
0xff, 0xff,
|
0xff, 0xff,
|
||||||
0xee, 0xbb,
|
0xee, 0xbb,
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#define Color ((char *)0xc800)
|
#define Color ((char *)0xc800)
|
||||||
#define Color2 ((char *)0xd800)
|
#define Color2 ((char *)0xd800)
|
||||||
|
|
||||||
// Bit patters for eight different color pairs
|
// Bit patterns for eight different color pairs
|
||||||
char colors[] = {
|
char colors[] = {
|
||||||
0xff, 0xff,
|
0xff, 0xff,
|
||||||
0xee, 0xbb,
|
0xee, 0xbb,
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#define Color1 ((char *)0xc800)
|
#define Color1 ((char *)0xc800)
|
||||||
#define Color2 ((char *)0xd800)
|
#define Color2 ((char *)0xd800)
|
||||||
|
|
||||||
// Bit patters for two different color pairs and eight shades
|
// Bit patterns for two different color pairs and eight shades
|
||||||
byte colors[2][17] =
|
byte colors[2][17] =
|
||||||
{
|
{
|
||||||
{0x00,
|
{0x00,
|
||||||
|
|
|
@ -53,7 +53,7 @@ inline unsigned long ssquare(unsigned x)
|
||||||
sum -= (unsigned long)a2 << 8;
|
sum -= (unsigned long)a2 << 8;
|
||||||
sum -= (unsigned long)b2 << 8;
|
sum -= (unsigned long)b2 << 8;
|
||||||
|
|
||||||
// And finaly the complete result
|
// And finally the complete result
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,7 +116,7 @@ inline char fcolor(int xz, int yz)
|
||||||
|
|
||||||
for(int i=0; i<32; i++)
|
for(int i=0; i<32; i++)
|
||||||
{
|
{
|
||||||
// Build squares of real and imaginery component
|
// Build squares of real and imaginary component
|
||||||
long xx = sq(x), yy = sq(y), xxyy = sq(x + y);
|
long xx = sq(x), yy = sq(y), xxyy = sq(x + y);
|
||||||
|
|
||||||
// Use squares to check for exit condition of sure
|
// Use squares to check for exit condition of sure
|
||||||
|
|
|
@ -40,7 +40,7 @@ byte * const Sprites = (byte *)0xd800;
|
||||||
|
|
||||||
struct Board
|
struct Board
|
||||||
{
|
{
|
||||||
char fcols[48]; // Pieces in the 6x7 grid using 48 to have a multplier of 8
|
char fcols[48]; // Pieces in the 6x7 grid using 48 to have a multiplier of 8
|
||||||
char ffree[7]; // Number of free places in each column
|
char ffree[7]; // Number of free places in each column
|
||||||
} board;
|
} board;
|
||||||
|
|
||||||
|
@ -291,7 +291,7 @@ char frows[5][69];
|
||||||
|
|
||||||
#pragma align(fscore, 256)
|
#pragma align(fscore, 256)
|
||||||
|
|
||||||
// Tables for opening libary for computer move 1, 2, 3 and 4
|
// Tables for opening library for computer move 1, 2, 3 and 4
|
||||||
|
|
||||||
const char open1 = 3;
|
const char open1 = 3;
|
||||||
const char open2[4 * 7] =
|
const char open2[4 * 7] =
|
||||||
|
@ -438,7 +438,7 @@ void ai_init(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate the current board state for te player
|
// Evaluate the current board state for the player
|
||||||
|
|
||||||
int board_eval(bool player)
|
int board_eval(bool player)
|
||||||
{
|
{
|
||||||
|
|
|
@ -483,7 +483,7 @@ inline void shot_draw(char * dp, char i, char xp, char yp)
|
||||||
// We know there are only 20 shots
|
// We know there are only 20 shots
|
||||||
__assume(i < 20);
|
__assume(i < 20);
|
||||||
|
|
||||||
// Character code for background with overlayed shot
|
// Character code for background with overlaid shot
|
||||||
dp[xp] = i | 0xe0;
|
dp[xp] = i | 0xe0;
|
||||||
|
|
||||||
// Source and target character code
|
// Source and target character code
|
||||||
|
@ -523,7 +523,7 @@ void shot_add(int sx, char sy, sbyte dx)
|
||||||
s->ry = ry;
|
s->ry = ry;
|
||||||
s->dx = dx;
|
s->dx = dx;
|
||||||
|
|
||||||
// Horizontal start postion based on player sprite
|
// Horizontal start position based on player sprite
|
||||||
if (dx < 0)
|
if (dx < 0)
|
||||||
{
|
{
|
||||||
char x = (sx) >> 3;
|
char x = (sx) >> 3;
|
||||||
|
@ -669,7 +669,7 @@ void tiles_draw(unsigned x)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Intitialize player
|
// Initialize player
|
||||||
void player_init(void)
|
void player_init(void)
|
||||||
{
|
{
|
||||||
// Set up start position and direction
|
// Set up start position and direction
|
||||||
|
@ -830,7 +830,7 @@ void enemies_move(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Spwan one new enemy outside screen
|
// Spawn one new enemy outside screen
|
||||||
void enemies_spawn(void)
|
void enemies_spawn(void)
|
||||||
{
|
{
|
||||||
// Seed for enemy
|
// Seed for enemy
|
||||||
|
|
|
@ -52,7 +52,7 @@ bool FlipIndex;
|
||||||
// Position and direction inside the maze
|
// Position and direction inside the maze
|
||||||
sbyte px = 1, py = 3, dx = 1, dy = 0;
|
sbyte px = 1, py = 3, dx = 1, dy = 0;
|
||||||
|
|
||||||
// Distance of blocks to the side, relative to the center ot the screen
|
// Distance of blocks to the side, relative to the center of the screen
|
||||||
// for full and half step
|
// for full and half step
|
||||||
static const char zxdist0[] = {18, 6, 4, 3, 2, 1, 0};
|
static const char zxdist0[] = {18, 6, 4, 3, 2, 1, 0};
|
||||||
static const char zxdist1[] = { 9, 5, 3, 2, 1, 0, 0};
|
static const char zxdist1[] = { 9, 5, 3, 2, 1, 0, 0};
|
||||||
|
|
|
@ -74,7 +74,7 @@ char nmissiles;
|
||||||
Missile icbms[16];
|
Missile icbms[16];
|
||||||
// First free and first used ICBM
|
// First free and first used ICBM
|
||||||
Missile * ifree, * iused;
|
Missile * ifree, * iused;
|
||||||
// Speed and number of ICBMs still incomming
|
// Speed and number of ICBMs still incoming
|
||||||
char icbmspeed, icbmcount;
|
char icbmspeed, icbmcount;
|
||||||
|
|
||||||
// Cities not yet destroyed
|
// Cities not yet destroyed
|
||||||
|
@ -95,7 +95,7 @@ void status_init(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expand an 8x8 charactor to 16x16 on screen
|
// Expand an 8x8 character to 16x16 on screen
|
||||||
void char_put(char cx, char cy, char c, char color)
|
void char_put(char cx, char cy, char c, char color)
|
||||||
{
|
{
|
||||||
// Get pointer to glyph data
|
// Get pointer to glyph data
|
||||||
|
@ -387,7 +387,7 @@ void missile_animate(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize incomming ICBM list
|
// Initialize incoming ICBM list
|
||||||
void icbm_init(void)
|
void icbm_init(void)
|
||||||
{
|
{
|
||||||
iused = nullptr;
|
iused = nullptr;
|
||||||
|
@ -697,7 +697,7 @@ void game_play(void)
|
||||||
// Check if fire request
|
// Check if fire request
|
||||||
if (CrossP)
|
if (CrossP)
|
||||||
{
|
{
|
||||||
// Find lauch site
|
// Find launch site
|
||||||
int sx = 160;
|
int sx = 160;
|
||||||
if (CrossX < 120)
|
if (CrossX < 120)
|
||||||
sx = 24;
|
sx = 24;
|
||||||
|
@ -729,7 +729,7 @@ void game_play(void)
|
||||||
// Launch ICBM
|
// Launch ICBM
|
||||||
icbm_start((rand() & 0xff) + 32, 0, cx, 184);
|
icbm_start((rand() & 0xff) + 32, 0, cx, 184);
|
||||||
|
|
||||||
// Next lauch time
|
// Next launch time
|
||||||
TheGame.count = 8 + (rand() & 63);
|
TheGame.count = 8 + (rand() & 63);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -761,7 +761,7 @@ void game_loop(void)
|
||||||
case GS_PLAYING:
|
case GS_PLAYING:
|
||||||
game_play();
|
game_play();
|
||||||
|
|
||||||
// Check for level and game end coditions
|
// Check for level and game end conditions
|
||||||
if (!icbmcount && !iused && !eused)
|
if (!icbmcount && !iused && !eused)
|
||||||
game_state(GS_BONUS);
|
game_state(GS_BONUS);
|
||||||
else if (ncities == 0)
|
else if (ncities == 0)
|
||||||
|
|
|
@ -37,7 +37,7 @@ int main(void)
|
||||||
// Install the trampoline
|
// Install the trampoline
|
||||||
mmap_trampoline();
|
mmap_trampoline();
|
||||||
|
|
||||||
// make all of RAM visibile to the CPU
|
// make all of RAM visible to the CPU
|
||||||
mmap_set(MMAP_RAM);
|
mmap_set(MMAP_RAM);
|
||||||
|
|
||||||
// copy the font
|
// copy the font
|
||||||
|
|
|
@ -39,7 +39,7 @@ int main(void)
|
||||||
// Install the trampoline
|
// Install the trampoline
|
||||||
mmap_trampoline();
|
mmap_trampoline();
|
||||||
|
|
||||||
// make all of RAM visibile to the CPU
|
// make all of RAM visible to the CPU
|
||||||
mmap_set(MMAP_RAM);
|
mmap_set(MMAP_RAM);
|
||||||
|
|
||||||
// expand the font
|
// expand the font
|
||||||
|
|
|
@ -28,7 +28,7 @@ static char * Hirows[25];
|
||||||
static const char setmask[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
|
static const char setmask[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
|
||||||
static const char clrmask[8] = {0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe};
|
static const char clrmask[8] = {0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe};
|
||||||
|
|
||||||
// Set a pixel at the given coordiate
|
// Set a pixel at the given coordinate
|
||||||
void pix_set(unsigned px, unsigned py)
|
void pix_set(unsigned px, unsigned py)
|
||||||
{
|
{
|
||||||
// Give the compiler a hand
|
// Give the compiler a hand
|
||||||
|
@ -42,7 +42,7 @@ void pix_set(unsigned px, unsigned py)
|
||||||
dp[py & 7] |= setmask[px & 7];
|
dp[py & 7] |= setmask[px & 7];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear a pixel at the given coordiate
|
// Clear a pixel at the given coordinate
|
||||||
void pix_clr(unsigned px, unsigned py)
|
void pix_clr(unsigned px, unsigned py)
|
||||||
{
|
{
|
||||||
__assume(px < 320);
|
__assume(px < 320);
|
||||||
|
|
|
@ -29,7 +29,7 @@ static char * Hirows[25];
|
||||||
static const char setmask[8] = {0xc0, 0xc0, 0x30, 0x30, 0x0c, 0x0c, 0x03, 0x03};
|
static const char setmask[8] = {0xc0, 0xc0, 0x30, 0x30, 0x0c, 0x0c, 0x03, 0x03};
|
||||||
static const char clrmask[8] = {0x3f, 0x3f, 0xcf, 0xcf, 0xf3, 0xf3, 0xfc, 0xfc};
|
static const char clrmask[8] = {0x3f, 0x3f, 0xcf, 0xcf, 0xf3, 0xf3, 0xfc, 0xfc};
|
||||||
|
|
||||||
// Set a pixel at the given coordiate
|
// Set a pixel at the given coordinate
|
||||||
void pix_set(unsigned px, unsigned py, char pat)
|
void pix_set(unsigned px, unsigned py, char pat)
|
||||||
{
|
{
|
||||||
__assume(px < 320);
|
__assume(px < 320);
|
||||||
|
@ -43,7 +43,7 @@ void pix_set(unsigned px, unsigned py, char pat)
|
||||||
dp[ly + 1] = dp[ly + 0] |= setmask[px & 7] & pat;
|
dp[ly + 1] = dp[ly + 0] |= setmask[px & 7] & pat;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear a pixel at the given coordiate
|
// Clear a pixel at the given coordinate
|
||||||
void pix_clr(unsigned px, unsigned py)
|
void pix_clr(unsigned px, unsigned py)
|
||||||
{
|
{
|
||||||
__assume(px < 320);
|
__assume(px < 320);
|
||||||
|
|
|
@ -30,7 +30,7 @@ static char * Hirows[25];
|
||||||
static const char setmask[4] = {0xc0, 0x30, 0x0c, 0x03};
|
static const char setmask[4] = {0xc0, 0x30, 0x0c, 0x03};
|
||||||
static const char clrmask[4] = {0x3f, 0xcf, 0xf3, 0xfc};
|
static const char clrmask[4] = {0x3f, 0xcf, 0xf3, 0xfc};
|
||||||
|
|
||||||
// Set a pixel at the given coordiate
|
// Set a pixel at the given coordinate
|
||||||
void pix_set(char px, char py, char pat)
|
void pix_set(char px, char py, char pat)
|
||||||
{
|
{
|
||||||
__assume(px < 160);
|
__assume(px < 160);
|
||||||
|
@ -44,7 +44,7 @@ void pix_set(char px, char py, char pat)
|
||||||
dp[ly + 1] = dp[ly + 0] |= setmask[px & 3] & pat;
|
dp[ly + 1] = dp[ly + 0] |= setmask[px & 3] & pat;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear a pixel at the given coordiate
|
// Clear a pixel at the given coordinate
|
||||||
void pix_clr(char px, char py)
|
void pix_clr(char px, char py)
|
||||||
{
|
{
|
||||||
__assume(px < 160);
|
__assume(px < 160);
|
||||||
|
|
|
@ -371,7 +371,7 @@ int main(void)
|
||||||
|
|
||||||
char gridX = 0, gridY = 0;
|
char gridX = 0, gridY = 0;
|
||||||
|
|
||||||
// Inital drwaing of the screen
|
// Initial drawing of the screen
|
||||||
char * dp = Screen, * cp = Color;
|
char * dp = Screen, * cp = Color;
|
||||||
for(char y=0; y<25; y++)
|
for(char y=0; y<25; y++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -124,7 +124,7 @@ void expandrow3(char * dp, const char * grid, char ly)
|
||||||
dp[39] = quad[2][gi];
|
dp[39] = quad[2][gi];
|
||||||
}
|
}
|
||||||
|
|
||||||
// expand the visibile portion of the screen at the
|
// expand the visible portion of the screen at the
|
||||||
// given char offset into the tiles
|
// given char offset into the tiles
|
||||||
void expand(char * dp, const char * grid, char px, char py)
|
void expand(char * dp, const char * grid, char px, char py)
|
||||||
{
|
{
|
||||||
|
|
|
@ -15,7 +15,7 @@ int main(void)
|
||||||
// Copy the sprite data
|
// Copy the sprite data
|
||||||
memcpy(SpriteData, spdata, 128);
|
memcpy(SpriteData, spdata, 128);
|
||||||
|
|
||||||
// Initalize the sprite system
|
// Initialize the sprite system
|
||||||
spr_init((char*)0x0400);
|
spr_init((char*)0x0400);
|
||||||
|
|
||||||
// Center screen position
|
// Center screen position
|
||||||
|
|
|
@ -46,7 +46,7 @@ int main(void)
|
||||||
// initialize sprite multiplexer
|
// initialize sprite multiplexer
|
||||||
vspr_init(Screen);
|
vspr_init(Screen);
|
||||||
|
|
||||||
// initalize sprites
|
// initialize sprites
|
||||||
for(int i=0; i<16; i++)
|
for(int i=0; i<16; i++)
|
||||||
{
|
{
|
||||||
vspr_set(i, 30 + 16 * i, 220 - 8 * i, (unsigned)&(spriteset[0]) / 64 + i, (i & 7) + 8);
|
vspr_set(i, 30 + 16 * i, 220 - 8 * i, (unsigned)&(spriteset[0]) / 64 + i, (i & 7) + 8);
|
||||||
|
|
|
@ -70,7 +70,7 @@ int main(void)
|
||||||
// initialize sprite multiplexer
|
// initialize sprite multiplexer
|
||||||
vspr_init(Screen);
|
vspr_init(Screen);
|
||||||
|
|
||||||
// initalize sprites
|
// initialize sprites
|
||||||
for(char i=0; i<32; i++)
|
for(char i=0; i<32; i++)
|
||||||
{
|
{
|
||||||
vspr_set(i, 30 + 8 * i, 220 - 4 * i, (unsigned)&(spriteset[0]) / 64 + (i & 15), (i & 7) + 8);
|
vspr_set(i, 30 + 8 * i, 220 - 4 * i, (unsigned)&(spriteset[0]) / 64 + (i & 15), (i & 7) + 8);
|
||||||
|
|
|
@ -163,7 +163,7 @@ int main(void)
|
||||||
rirq_call(spmux + i, 2, setspr);
|
rirq_call(spmux + i, 2, setspr);
|
||||||
|
|
||||||
// Place raster interrupt 16 lines before sprite start to
|
// Place raster interrupt 16 lines before sprite start to
|
||||||
// give it enough time for procesing
|
// give it enough time for processing
|
||||||
rirq_set(i, 36 + 25 * i, spmux + i);
|
rirq_set(i, 36 + 25 * i, spmux + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue