This commit is contained in:
Denis Molony 2017-01-09 20:21:02 +11:00
parent 1e1df8e633
commit 218f612877
2 changed files with 85 additions and 104 deletions

View File

@ -7,45 +7,45 @@ import com.bytezone.diskbrowser.utilities.HexFormatter;
public class DoubleHiResImage extends HiResImage public class DoubleHiResImage extends HiResImage
{ {
// private static final int BLACK = 0x000000;
// private static final int MAGENTA = 0xFF00FF;
// private static final int BROWN = 0x994C00;
// private static final int ORANGE = 0xFF9933;
// private static final int DARK_GREEN = 0x006600;
// private static final int GRAY = 0xA0A0A0;
// private static final int GREEN = 0x00CC00;
// private static final int YELLOW = 0xFFFF33;
// private static final int DARK_BLUE = 0x0066CC;
// private static final int PURPLE = 0xCC00CC;
// private static final int PINK = 0xFFCCE5;
// private static final int MEDIUM_BLUE = 0x3399FF;
// private static final int LIGHT_BLUE = 0x99CCFF;
// private static final int AQUA = 0x99FFFF;
// private static final int WHITE = 0xFFFFFF;
// private static int[] palette =
// { BLACK, MAGENTA, BROWN, ORANGE, DARK_GREEN, GRAY, GREEN, YELLOW, DARK_BLUE, PURPLE,
// GRAY, PINK, MEDIUM_BLUE, LIGHT_BLUE, AQUA, WHITE };
private static final int BLACK = 0x000000; private static final int BLACK = 0x000000;
private static final int MAGENTA = 0x722640; private static final int MAGENTA = 0xFF00FF;
private static final int DARK_BLUE = 0x40337F; private static final int BROWN = 0x994C00;
private static final int PURPLE = 0xE434FE; private static final int ORANGE = 0xFF9933;
private static final int DARK_GREEN = 0x0E5940; private static final int DARK_GREEN = 0x006600;
private static final int GRAY = 0x808080; private static final int GRAY = 0xA0A0A0;
private static final int MEDIUM_BLUE = 0x1B9AEF; private static final int GREEN = 0x00CC00;
private static final int LIGHT_BLUE = 0xBFB3FF; private static final int YELLOW = 0xFFFF33;
private static final int BROWN = 0x404C00; private static final int DARK_BLUE = 0x0066CC;
private static final int ORANGE = 0xE46501; private static final int PURPLE = 0xCC00CC;
private static final int PINK = 0xF1A6BF; private static final int PINK = 0xFFCCE5;
private static final int GREEN = 0x1BCB01; private static final int MEDIUM_BLUE = 0x3399FF;
private static final int YELLOW = 0xBFCC80; private static final int LIGHT_BLUE = 0x99CCFF;
private static final int AQUA = 0x8DD9BF; private static final int AQUA = 0x99FFFF;
private static final int WHITE = 0xFFFFFF; private static final int WHITE = 0xFFFFFF;
private static int[] palette = private static int[] palette =
{ BLACK, MAGENTA, DARK_BLUE, PURPLE, DARK_GREEN, GRAY, MEDIUM_BLUE, LIGHT_BLUE, { BLACK, MAGENTA, BROWN, ORANGE, DARK_GREEN, GRAY, GREEN, YELLOW, DARK_BLUE, PURPLE,
BROWN, ORANGE, GRAY, PINK, GREEN, YELLOW, AQUA, WHITE }; GRAY, PINK, MEDIUM_BLUE, LIGHT_BLUE, AQUA, WHITE };
// private static final int BLACK = 0x000000;
// private static final int MAGENTA = 0x722640;
// private static final int DARK_BLUE = 0x40337F;
// private static final int PURPLE = 0xE434FE;
// private static final int DARK_GREEN = 0x0E5940;
// private static final int GRAY = 0x808080;
// private static final int MEDIUM_BLUE = 0x1B9AEF;
// private static final int LIGHT_BLUE = 0xBFB3FF;
// private static final int BROWN = 0x404C00;
// private static final int ORANGE = 0xE46501;
// private static final int PINK = 0xF1A6BF;
// private static final int GREEN = 0x1BCB01;
// private static final int YELLOW = 0xBFCC80;
// private static final int AQUA = 0x8DD9BF;
// private static final int WHITE = 0xFFFFFF;
//
// private static int[] palette =
// { BLACK, MAGENTA, DARK_BLUE, PURPLE, DARK_GREEN, GRAY, MEDIUM_BLUE, LIGHT_BLUE,
// BROWN, ORANGE, GRAY, PINK, GREEN, YELLOW, AQUA, WHITE };
private final byte[] auxBuffer; private final byte[] auxBuffer;
private DoubleScrunch doubleScrunch; private DoubleScrunch doubleScrunch;
@ -56,7 +56,6 @@ public class DoubleHiResImage extends HiResImage
super (name, buffer); super (name, buffer);
this.auxBuffer = auxBuffer; this.auxBuffer = auxBuffer;
createImage (); createImage ();
} }
@ -73,29 +72,6 @@ public class DoubleHiResImage extends HiResImage
this.buffer = doubleScrunch.primaryBuffer; this.buffer = doubleScrunch.primaryBuffer;
createImage (); createImage ();
// testes
if (false)
{
byte b = -1;
System.out.printf ("%02X %d%n", b, b);
if (b < 0)
System.out.println ("negative");
b = -122;
for (int i = 0; i < 10; i++)
{
--b;
System.out.printf ("%4d %02X%n", b, b);
}
System.out.println ();
b = (byte) 250;
for (int i = 0; i < 10; i++)
{
++b;
System.out.printf ("%4d %02X%n", b, b);
}
}
} }
@Override @Override
@ -168,8 +144,10 @@ public class DoubleHiResImage extends HiResImage
text.append ("Packed buffer:\n\n"); text.append ("Packed buffer:\n\n");
text.append (HexFormatter.format (packedBuffer)); text.append (HexFormatter.format (packedBuffer));
} }
text.append ("\n\nAuxilliary buffer:\n\n"); text.append ("\n\nAuxilliary buffer:\n\n");
text.append (HexFormatter.format (auxBuffer)); text.append (HexFormatter.format (auxBuffer));
text.append ("\n\nPrimary buffer:\n\n"); text.append ("\n\nPrimary buffer:\n\n");
text.append (HexFormatter.format (buffer)); text.append (HexFormatter.format (buffer));

View File

@ -4,19 +4,21 @@ import com.bytezone.diskbrowser.utilities.CPU;
public class DoubleScrunch extends CPU public class DoubleScrunch extends CPU
{ {
private byte mem_71D0; private byte mem_71D0; // screen row index (X)
private byte mem_71D2; private byte mem_71D2; // screen column index
private byte mem_71D3; private byte mem_71D3; // byte to repeat
private byte mem_71D4; private byte mem_71D4; // # of bytes to store
private int src; // base address of packed buffer private int src; // base address of packed buffer
private int dst; // base address of main/aux memory private int dst; // base address of main/aux memory
private byte zp_00; private byte zp_00; // input buffer offset
private byte zp_01; private byte zp_01;
private byte zp_26;
private byte zp_26; // output buffer offset
private byte zp_27; private byte zp_27;
private byte zp_E6;
private byte zp_E6; // hi-res page ($20 or $40)
final byte[] auxBuffer = new byte[0x2000]; final byte[] auxBuffer = new byte[0x2000];
final byte[] primaryBuffer = new byte[0x2000]; final byte[] primaryBuffer = new byte[0x2000];
@ -31,21 +33,14 @@ public class DoubleScrunch extends CPU
void unscrunch (byte[] buffer) void unscrunch (byte[] buffer)
{ {
if (false)
{
ldx ((byte) 0x81);
calculateScreenAddress ();
return;
}
packedBuffer = buffer; packedBuffer = buffer;
src = 0x4000; // packed picture data src = 0x4000; // packed picture data
dst = 0x2000; // main/aux picture data dst = 0x2000; // main/aux picture data
zp_00 = 0x00; zp_00 = 0x00; // load address of packed buffer
zp_01 = 0x40; zp_01 = 0x40;
zp_E6 = 0x20; // hi-res page 1 zp_E6 = 0x20; // hi-res page 1
lda (zp_E6); lda (zp_E6);
@ -55,25 +50,29 @@ public class DoubleScrunch extends CPU
ldx ((byte) 0x01); ldx ((byte) 0x01);
mem_71D0 = stx (); mem_71D0 = stx ();
ldy ((byte) 0x00); ldy ((byte) 0x00);
mem_71D2 = sty (); mem_71D2 = sty (); // line offset = 0
zp_26 = sty (); zp_26 = sty (); // output index = 0
while (true) while (true)
{ {
// get the repetition counter (hi-bit is a flag to indicate copy/repeat)
lda (packedBuffer, indirectY (src, zp_00, zp_01)); // LDA ($00),Y) lda (packedBuffer, indirectY (src, zp_00, zp_01)); // LDA ($00),Y)
php (); php ();
// prepare address to get next transfer byte (done in copy/repeat routine)
zp_00 = inc (zp_00); zp_00 = inc (zp_00);
if (zero) if (zero)
zp_01 = inc (zp_01); zp_01 = inc (zp_01);
and ((byte) 0x7F); and ((byte) 0x7F); // remove copy/repeat flag
mem_71D4 = sta (); mem_71D4 = sta (); // save repetition counter
plp (); plp ();
if (negative ? blockB () : blockA ()) if (negative ? copyBytes () : repeatBytes ())
break; break;
// prepare address to get next repetition counter
zp_00 = inc (zp_00); zp_00 = inc (zp_00);
if (zero) if (zero)
zp_01 = inc (zp_01); zp_01 = inc (zp_01);
@ -81,50 +80,54 @@ public class DoubleScrunch extends CPU
} }
// $7144 // $7144
// repeat a single byte X times // copy a single byte $71D4 times
private boolean blockA () private boolean repeatBytes ()
{ {
// get the byte to store
lda (packedBuffer, indirectY (src, zp_00, zp_01)); // LDA ($00),Y) lda (packedBuffer, indirectY (src, zp_00, zp_01)); // LDA ($00),Y)
mem_71D3 = sta (); mem_71D3 = sta ();
do while (true)
{ {
lda (mem_71D3); lda (mem_71D3); // get the byte to store
storeByte (); storeByte (); // store it and decrement repetition counter
function_71B1 (); calculateScreenLine ();
if (carry) if (carry)
return true; // completely finished return true; // completely finished
calculateScreenAddress (); calculateNextScreenAddress ();
ldy (mem_71D4);
} while (!zero);
return false; // not finished ldy (mem_71D4); // check the repetition counter
if (zero)
return false; // not finished
}
} }
// $717D // $717D
// copy X single bytes // copy the next $71D4 bytes
private boolean blockB () private boolean copyBytes ()
{ {
while (true) while (true)
{ {
// get the byte to store
ldy ((byte) 0x00); ldy ((byte) 0x00);
lda (packedBuffer, indirectY (src, zp_00, zp_01)); // LDA ($00),Y) lda (packedBuffer, indirectY (src, zp_00, zp_01)); // LDA ($00),Y)
storeByte (); storeByte (); // store it and decrement repetition counter
function_71B1 (); calculateScreenLine ();
if (carry) if (carry)
return true; // completely finished return true; // completely finished
calculateScreenAddress (); calculateNextScreenAddress ();
ldy (mem_71D4); ldy (mem_71D4); // check the repetition counter
if (zero) if (zero)
return false; // not finished return false; // not finished
// prepare address for next read
zp_00 = inc (zp_00); zp_00 = inc (zp_00);
if (zero) if (zero)
zp_01 = inc (zp_01); zp_01 = inc (zp_01);
@ -134,7 +137,7 @@ public class DoubleScrunch extends CPU
private void storeByte () private void storeByte ()
{ {
mem_71D4 = dec (mem_71D4); // decrement counter mem_71D4 = dec (mem_71D4); // decrement counter
ldy (mem_71D2); // load byte to store ldy (mem_71D2); // line offset
php (); php ();
sei (); sei ();
@ -154,7 +157,7 @@ public class DoubleScrunch extends CPU
} }
// $70E8 // $70E8
private void calculateScreenAddress () private void calculateNextScreenAddress ()
{ {
txa (); txa ();
and ((byte) 0xC0); // clear bits 5-0 and ((byte) 0xC0); // clear bits 5-0
@ -186,12 +189,12 @@ public class DoubleScrunch extends CPU
} }
// $71B1 // $71B1
private void function_71B1 () private void calculateScreenLine ()
{ {
inx (); inx ();
inx (); inx ();
cpx ((byte) 0xC0); cpx ((byte) 0xC0);
if (!carry) // BCC $71CE (if X < 0xC0) if (!carry) // BCC $71CE
{ {
clc (); clc ();
return; return;
@ -206,7 +209,7 @@ public class DoubleScrunch extends CPU
return; return;
} }
mem_71D2 = inc (mem_71D2); mem_71D2 = inc (mem_71D2); // increment line offset
ldy (mem_71D2); ldy (mem_71D2);
cpy ((byte) 0x50); cpy ((byte) 0x50);
if (carry) // BCS $71CF if (carry) // BCS $71CF