//
// Blitter core
//
-// by James L. Hammons
+// by James Hammons
+// (C) 2010 Underground Software
+//
+// JLH = James Hammons <jlhamm@acm.org>
+//
+// Who When What
+// --- ---------- -------------------------------------------------------------
+// JLH 01/16/2010 Created this log ;-)
+//
+
//
// I owe a debt of gratitude to Curt Vendel and to John Mathieson--to Curt
// for supplying the Oberon ASIC nets and to John for making them available
// to Curt. ;-) Without that excellent documentation which shows *exactly*
// what's going on inside the TOM chip, we'd all still be guessing as to how
// the wily blitter and other pieces of the Jaguar puzzle actually work.
+// Now how about those JERRY ASIC nets gentlemen...? [We have those now!] ;-)
//
-#include "jaguar.h"
#include "blitter.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "jaguar.h"
+#include "log.h"
+//#include "memory.h"
+
// Various conditional compilation goodies...
+//#define LOG_BLITS
+
//#define USE_ORIGINAL_BLITTER
//#define USE_MIDSUMMER_BLITTER
#define USE_MIDSUMMER_BLITTER_MKII
// Blitter registers (offsets from F02200)
-#define A1_BASE ((UINT32)0x00)
-#define A1_FLAGS ((UINT32)0x04)
-#define A1_CLIP ((UINT32)0x08) // Height and width values for clipping
-#define A1_PIXEL ((UINT32)0x0C) // Integer part of the pixel (Y.i and X.i)
-#define A1_STEP ((UINT32)0x10) // Integer part of the step
-#define A1_FSTEP ((UINT32)0x14) // Fractional part of the step
-#define A1_FPIXEL ((UINT32)0x18) // Fractional part of the pixel (Y.f and X.f)
-#define A1_INC ((UINT32)0x1C) // Integer part of the increment
-#define A1_FINC ((UINT32)0x20) // Fractional part of the increment
-#define A2_BASE ((UINT32)0x24)
-#define A2_FLAGS ((UINT32)0x28)
-#define A2_MASK ((UINT32)0x2C) // Modulo values for x and y (M.y and M.x)
-#define A2_PIXEL ((UINT32)0x30) // Integer part of the pixel (no fractional part for A2)
-#define A2_STEP ((UINT32)0x34) // Integer part of the step (no fractional part for A2)
-#define COMMAND ((UINT32)0x38)
-#define PIXLINECOUNTER ((UINT32)0x3C) // Inner & outer loop values
-#define SRCDATA ((UINT32)0x40)
-#define DSTDATA ((UINT32)0x48)
-#define DSTZ ((UINT32)0x50)
-#define SRCZINT ((UINT32)0x58)
-#define SRCZFRAC ((UINT32)0x60)
-#define PATTERNDATA ((UINT32)0x68)
-#define INTENSITYINC ((UINT32)0x70)
-#define ZINC ((UINT32)0x74)
-#define COLLISIONCTRL ((UINT32)0x78)
-#define PHRASEINT0 ((UINT32)0x7C)
-#define PHRASEINT1 ((UINT32)0x80)
-#define PHRASEINT2 ((UINT32)0x84)
-#define PHRASEINT3 ((UINT32)0x88)
-#define PHRASEZ0 ((UINT32)0x8C)
-#define PHRASEZ1 ((UINT32)0x90)
-#define PHRASEZ2 ((UINT32)0x94)
-#define PHRASEZ3 ((UINT32)0x98)
+#define A1_BASE ((uint32)0x00)
+#define A1_FLAGS ((uint32)0x04)
+#define A1_CLIP ((uint32)0x08) // Height and width values for clipping
+#define A1_PIXEL ((uint32)0x0C) // Integer part of the pixel (Y.i and X.i)
+#define A1_STEP ((uint32)0x10) // Integer part of the step
+#define A1_FSTEP ((uint32)0x14) // Fractional part of the step
+#define A1_FPIXEL ((uint32)0x18) // Fractional part of the pixel (Y.f and X.f)
+#define A1_INC ((uint32)0x1C) // Integer part of the increment
+#define A1_FINC ((uint32)0x20) // Fractional part of the increment
+#define A2_BASE ((uint32)0x24)
+#define A2_FLAGS ((uint32)0x28)
+#define A2_MASK ((uint32)0x2C) // Modulo values for x and y (M.y and M.x)
+#define A2_PIXEL ((uint32)0x30) // Integer part of the pixel (no fractional part for A2)
+#define A2_STEP ((uint32)0x34) // Integer part of the step (no fractional part for A2)
+#define COMMAND ((uint32)0x38)
+#define PIXLINECOUNTER ((uint32)0x3C) // Inner & outer loop values
+#define SRCDATA ((uint32)0x40)
+#define DSTDATA ((uint32)0x48)
+#define DSTZ ((uint32)0x50)
+#define SRCZINT ((uint32)0x58)
+#define SRCZFRAC ((uint32)0x60)
+#define PATTERNDATA ((uint32)0x68)
+#define INTENSITYINC ((uint32)0x70)
+#define ZINC ((uint32)0x74)
+#define COLLISIONCTRL ((uint32)0x78)
+#define PHRASEINT0 ((uint32)0x7C)
+#define PHRASEINT1 ((uint32)0x80)
+#define PHRASEINT2 ((uint32)0x84)
+#define PHRASEINT3 ((uint32)0x88)
+#define PHRASEZ0 ((uint32)0x8C)
+#define PHRASEZ1 ((uint32)0x90)
+#define PHRASEZ2 ((uint32)0x94)
+#define PHRASEZ3 ((uint32)0x98)
// Blitter command bits
//Put 'em back, once we fix the problem!!! [KO]
// 1 bpp pixel read
#define PIXEL_SHIFT_1(a) (((~a##_x) >> 16) & 7)
-#define PIXEL_OFFSET_1(a) (((((UINT32)a##_y >> 16) * a##_width / 8) + (((UINT32)a##_x >> 19) & ~7)) * (1 + a##_pitch) + (((UINT32)a##_x >> 19) & 7))
+#define PIXEL_OFFSET_1(a) (((((uint32)a##_y >> 16) * a##_width / 8) + (((uint32)a##_x >> 19) & ~7)) * (1 + a##_pitch) + (((uint32)a##_x >> 19) & 7))
#define READ_PIXEL_1(a) ((JaguarReadByte(a##_addr+PIXEL_OFFSET_1(a), BLITTER) >> PIXEL_SHIFT_1(a)) & 0x01)
//#define READ_PIXEL_1(a) ((JaguarReadByte(a##_addr+PIXEL_OFFSET_1(a)) >> PIXEL_SHIFT_1(a)) & 0x01)
// 2 bpp pixel read
#define PIXEL_SHIFT_2(a) (((~a##_x) >> 15) & 6)
-#define PIXEL_OFFSET_2(a) (((((UINT32)a##_y >> 16) * a##_width / 4) + (((UINT32)a##_x >> 18) & ~7)) * (1 + a##_pitch) + (((UINT32)a##_x >> 18) & 7))
+#define PIXEL_OFFSET_2(a) (((((uint32)a##_y >> 16) * a##_width / 4) + (((uint32)a##_x >> 18) & ~7)) * (1 + a##_pitch) + (((uint32)a##_x >> 18) & 7))
#define READ_PIXEL_2(a) ((JaguarReadByte(a##_addr+PIXEL_OFFSET_2(a), BLITTER) >> PIXEL_SHIFT_2(a)) & 0x03)
//#define READ_PIXEL_2(a) ((JaguarReadByte(a##_addr+PIXEL_OFFSET_2(a)) >> PIXEL_SHIFT_2(a)) & 0x03)
// 4 bpp pixel read
#define PIXEL_SHIFT_4(a) (((~a##_x) >> 14) & 4)
-#define PIXEL_OFFSET_4(a) (((((UINT32)a##_y >> 16) * (a##_width/2)) + (((UINT32)a##_x >> 17) & ~7)) * (1 + a##_pitch) + (((UINT32)a##_x >> 17) & 7))
+#define PIXEL_OFFSET_4(a) (((((uint32)a##_y >> 16) * (a##_width/2)) + (((uint32)a##_x >> 17) & ~7)) * (1 + a##_pitch) + (((uint32)a##_x >> 17) & 7))
#define READ_PIXEL_4(a) ((JaguarReadByte(a##_addr+PIXEL_OFFSET_4(a), BLITTER) >> PIXEL_SHIFT_4(a)) & 0x0f)
//#define READ_PIXEL_4(a) ((JaguarReadByte(a##_addr+PIXEL_OFFSET_4(a)) >> PIXEL_SHIFT_4(a)) & 0x0f)
// 8 bpp pixel read
-#define PIXEL_OFFSET_8(a) (((((UINT32)a##_y >> 16) * a##_width) + (((UINT32)a##_x >> 16) & ~7)) * (1 + a##_pitch) + (((UINT32)a##_x >> 16) & 7))
+#define PIXEL_OFFSET_8(a) (((((uint32)a##_y >> 16) * a##_width) + (((uint32)a##_x >> 16) & ~7)) * (1 + a##_pitch) + (((uint32)a##_x >> 16) & 7))
#define READ_PIXEL_8(a) (JaguarReadByte(a##_addr+PIXEL_OFFSET_8(a), BLITTER))
//#define READ_PIXEL_8(a) (JaguarReadByte(a##_addr+PIXEL_OFFSET_8(a)))
// 16 bpp pixel read
-#define PIXEL_OFFSET_16(a) (((((UINT32)a##_y >> 16) * a##_width) + (((UINT32)a##_x >> 16) & ~3)) * (1 + a##_pitch) + (((UINT32)a##_x >> 16) & 3))
+#define PIXEL_OFFSET_16(a) (((((uint32)a##_y >> 16) * a##_width) + (((uint32)a##_x >> 16) & ~3)) * (1 + a##_pitch) + (((uint32)a##_x >> 16) & 3))
#define READ_PIXEL_16(a) (JaguarReadWord(a##_addr+(PIXEL_OFFSET_16(a)<<1), BLITTER))
//#define READ_PIXEL_16(a) (JaguarReadWord(a##_addr+(PIXEL_OFFSET_16(a)<<1)))
// 32 bpp pixel read
-#define PIXEL_OFFSET_32(a) (((((UINT32)a##_y >> 16) * a##_width) + (((UINT32)a##_x >> 16) & ~1)) * (1 + a##_pitch) + (((UINT32)a##_x >> 16) & 1))
+#define PIXEL_OFFSET_32(a) (((((uint32)a##_y >> 16) * a##_width) + (((uint32)a##_x >> 16) & ~1)) * (1 + a##_pitch) + (((uint32)a##_x >> 16) & 1))
#define READ_PIXEL_32(a) (JaguarReadLong(a##_addr+(PIXEL_OFFSET_32(a)<<2), BLITTER))
//#define READ_PIXEL_32(a) (JaguarReadLong(a##_addr+(PIXEL_OFFSET_32(a)<<2)))
//#define WRITE_ZDATA_16(a,d) { JaguarWriteWord(a##_addr+(ZDATA_OFFSET_16(a)<<1), d); }
// z data write
-#define WRITE_ZDATA(a,f,d) WRITE_ZDATA_16(a,d);
+#define WRITE_ZDATA(a,f,d) WRITE_ZDATA_16(a,d);
// 1 bpp r data read
-#define READ_RDATA_1(r,a,p) ((p) ? ((REG(r+(((UINT32)a##_x >> 19) & 0x04))) >> (((UINT32)a##_x >> 16) & 0x1F)) & 0x0001 : (REG(r) & 0x0001))
+#define READ_RDATA_1(r,a,p) ((p) ? ((REG(r+(((uint32)a##_x >> 19) & 0x04))) >> (((uint32)a##_x >> 16) & 0x1F)) & 0x0001 : (REG(r) & 0x0001))
// 2 bpp r data read
-#define READ_RDATA_2(r,a,p) ((p) ? ((REG(r+(((UINT32)a##_x >> 18) & 0x04))) >> (((UINT32)a##_x >> 15) & 0x3E)) & 0x0003 : (REG(r) & 0x0003))
+#define READ_RDATA_2(r,a,p) ((p) ? ((REG(r+(((uint32)a##_x >> 18) & 0x04))) >> (((uint32)a##_x >> 15) & 0x3E)) & 0x0003 : (REG(r) & 0x0003))
// 4 bpp r data read
-#define READ_RDATA_4(r,a,p) ((p) ? ((REG(r+(((UINT32)a##_x >> 17) & 0x04))) >> (((UINT32)a##_x >> 14) & 0x28)) & 0x000F : (REG(r) & 0x000F))
+#define READ_RDATA_4(r,a,p) ((p) ? ((REG(r+(((uint32)a##_x >> 17) & 0x04))) >> (((uint32)a##_x >> 14) & 0x28)) & 0x000F : (REG(r) & 0x000F))
// 8 bpp r data read
-#define READ_RDATA_8(r,a,p) ((p) ? ((REG(r+(((UINT32)a##_x >> 16) & 0x04))) >> (((UINT32)a##_x >> 13) & 0x18)) & 0x00FF : (REG(r) & 0x00FF))
+#define READ_RDATA_8(r,a,p) ((p) ? ((REG(r+(((uint32)a##_x >> 16) & 0x04))) >> (((uint32)a##_x >> 13) & 0x18)) & 0x00FF : (REG(r) & 0x00FF))
// 16 bpp r data read
-#define READ_RDATA_16(r,a,p) ((p) ? ((REG(r+(((UINT32)a##_x >> 15) & 0x04))) >> (((UINT32)a##_x >> 12) & 0x10)) & 0xFFFF : (REG(r) & 0xFFFF))
+#define READ_RDATA_16(r,a,p) ((p) ? ((REG(r+(((uint32)a##_x >> 15) & 0x04))) >> (((uint32)a##_x >> 12) & 0x10)) & 0xFFFF : (REG(r) & 0xFFFF))
// 32 bpp r data read
-#define READ_RDATA_32(r,a,p) ((p) ? REG(r+(((UINT32)a##_x >> 14) & 0x04)) : REG(r))
+#define READ_RDATA_32(r,a,p) ((p) ? REG(r+(((uint32)a##_x >> 14) & 0x04)) : REG(r))
// register data read
#define READ_RDATA(r,a,f,p) (\
//#define WRITE_PIXEL_16(a,d) { JaguarWriteWord(a##_addr+(PIXEL_OFFSET_16(a)<<1), d); if (specialLog) WriteLog("Pixel write address: %08X\n", a##_addr+(PIXEL_OFFSET_16(a)<<1)); }
// 32 bpp pixel write
-#define WRITE_PIXEL_32(a,d) { JaguarWriteLong(a##_addr+(PIXEL_OFFSET_32(a)<<2), d, BLITTER); }
-//#define WRITE_PIXEL_32(a,d) { JaguarWriteLong(a##_addr+(PIXEL_OFFSET_32(a)<<2), d); }
+#define WRITE_PIXEL_32(a,d) { JaguarWriteLong(a##_addr+(PIXEL_OFFSET_32(a)<<2), d, BLITTER); }
+//#define WRITE_PIXEL_32(a,d) { JaguarWriteLong(a##_addr+(PIXEL_OFFSET_32(a)<<2), d); }
// pixel write
#define WRITE_PIXEL(a,f,d) {\
// as a floating point bit pattern being followed by a number of zeroes. So, e.g., 001101 translates to
// 1.01 (the "1." being implied) x (2 ^ 3) or 1010 -> 10 in base 10 (i.e., 1.01 with the decimal place
// being shifted to the right 3 places).
-/*static uint32 blitter_scanline_width[48] =
-{
+/*static uint32 blitter_scanline_width[48] =
+{
0, 0, 0, 0, // Note: This would really translate to 1, 1, 1, 1
2, 0, 0, 0,
4, 0, 6, 0,
{
/*
Blit! (0018FA70 <- 008DDC40) count: 2 x 13, A1/2_FLAGS: 00014218/00013C18 [cmd: 1401060C]
- CMD -> src: SRCENX dst: DSTEN misc: a1ctl: UPDA1 UPDA2 mode: ity: PATDSEL z-op: op: LFU_CLEAR ctrl: BCOMPEN BKGWREN
+ CMD -> src: SRCENX dst: DSTEN misc: a1ctl: UPDA1 UPDA2 mode: ity: PATDSEL z-op: op: LFU_CLEAR ctrl: BCOMPEN BKGWREN
A1 step values: -2 (X), 1 (Y)
A2 step values: -1 (X), 1 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
A1 -> pitch: 1 phrases, depth: 8bpp, z-off: 0, width: 320 (21), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
srczdata = READ_RDATA(SRCZINT, a2, REG(A2_FLAGS), a2_phrase_mode);
}
- // load dst data and Z
+ // load dst data and Z
if (DSTEN)
{
dstdata = READ_PIXEL(a1, REG(A1_FLAGS));
inhibit = 1;
}//*/
- if (GOURZ)
+ if (GOURZ)
srczdata = z_i[colour_index] >> 16;
// apply z comparator
if (Z_OP_INF && srczdata < dstzdata) inhibit = 1;
if (Z_OP_EQU && srczdata == dstzdata) inhibit = 1;
if (Z_OP_SUP && srczdata > dstzdata) inhibit = 1;
-
+
// apply data comparator
// Note: DCOMPEN only works in 8/16 bpp modes! !!! FIX !!!
// Does BCOMPEN only work in 1 bpp mode???
Interesting (Hover Strike--large letter):
Blit! (0018FA70 <- 008DDC40) count: 2 x 13, A1/2_FLAGS: 00014218/00013C18 [cmd: 1401060C]
- CMD -> src: SRCENX dst: DSTEN misc: a1ctl: UPDA1 UPDA2 mode: ity: PATDSEL z-op: op: LFU_CLEAR ctrl: BCOMPEN BKGWREN
+ CMD -> src: SRCENX dst: DSTEN misc: a1ctl: UPDA1 UPDA2 mode: ity: PATDSEL z-op: op: LFU_CLEAR ctrl: BCOMPEN BKGWREN
A1 step values: -2 (X), 1 (Y)
A2 step values: -1 (X), 1 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
A1 -> pitch: 1 phrases, depth: 8bpp, z-off: 0, width: 320 (21), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
A1 x/y: 100/12, A2 x/y: 106/0 Pattern: 000000F300000000
Blit! (0018FA70 <- 008DDC40) count: 8 x 13, A1/2_FLAGS: 00014218/00013C18 [cmd: 1401060C]
- CMD -> src: SRCENX dst: DSTEN misc: a1ctl: UPDA1 UPDA2 mode: ity: PATDSEL z-op: op: LFU_CLEAR ctrl: BCOMPEN BKGWREN
+ CMD -> src: SRCENX dst: DSTEN misc: a1ctl: UPDA1 UPDA2 mode: ity: PATDSEL z-op: op: LFU_CLEAR ctrl: BCOMPEN BKGWREN
A1 step values: -8 (X), 1 (Y)
A2 step values: -1 (X), 1 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
A1 -> pitch: 1 phrases, depth: 8bpp, z-off: 0, width: 320 (21), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
A1 x/y: 102/12, A2 x/y: 107/0 Pattern: 000000F300000000
Blit! (0018FA70 <- 008DDC40) count: 1 x 13, A1/2_FLAGS: 00014218/00013C18 [cmd: 1401060C]
- CMD -> src: SRCENX dst: DSTEN misc: a1ctl: UPDA1 UPDA2 mode: ity: PATDSEL z-op: op: LFU_CLEAR ctrl: BCOMPEN BKGWREN
+ CMD -> src: SRCENX dst: DSTEN misc: a1ctl: UPDA1 UPDA2 mode: ity: PATDSEL z-op: op: LFU_CLEAR ctrl: BCOMPEN BKGWREN
A1 step values: -1 (X), 1 (Y)
A2 step values: -1 (X), 1 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
A1 -> pitch: 1 phrases, depth: 8bpp, z-off: 0, width: 320 (21), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
A1 x/y: 118/12, A2 x/y: 70/0 Pattern: 000000F300000000
Blit! (0018FA70 <- 008DDC40) count: 8 x 13, A1/2_FLAGS: 00014218/00013C18 [cmd: 1401060C]
- CMD -> src: SRCENX dst: DSTEN misc: a1ctl: UPDA1 UPDA2 mode: ity: PATDSEL z-op: op: LFU_CLEAR ctrl: BCOMPEN BKGWREN
+ CMD -> src: SRCENX dst: DSTEN misc: a1ctl: UPDA1 UPDA2 mode: ity: PATDSEL z-op: op: LFU_CLEAR ctrl: BCOMPEN BKGWREN
A1 step values: -8 (X), 1 (Y)
A2 step values: -1 (X), 1 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
A1 -> pitch: 1 phrases, depth: 8bpp, z-off: 0, width: 320 (21), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
A1 x/y: 119/12, A2 x/y: 71/0 Pattern: 000000F300000000
Blit! (0018FA70 <- 008DDC40) count: 1 x 13, A1/2_FLAGS: 00014218/00013C18 [cmd: 1401060C]
- CMD -> src: SRCENX dst: DSTEN misc: a1ctl: UPDA1 UPDA2 mode: ity: PATDSEL z-op: op: LFU_CLEAR ctrl: BCOMPEN BKGWREN
+ CMD -> src: SRCENX dst: DSTEN misc: a1ctl: UPDA1 UPDA2 mode: ity: PATDSEL z-op: op: LFU_CLEAR ctrl: BCOMPEN BKGWREN
A1 step values: -1 (X), 1 (Y)
A2 step values: -1 (X), 1 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
A1 -> pitch: 1 phrases, depth: 8bpp, z-off: 0, width: 320 (21), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
A1 x/y: 127/12, A2 x/y: 66/0 Pattern: 000000F300000000
Blit! (0018FA70 <- 008DDC40) count: 8 x 13, A1/2_FLAGS: 00014218/00013C18 [cmd: 1401060C]
- CMD -> src: SRCENX dst: DSTEN misc: a1ctl: UPDA1 UPDA2 mode: ity: PATDSEL z-op: op: LFU_CLEAR ctrl: BCOMPEN BKGWREN
+ CMD -> src: SRCENX dst: DSTEN misc: a1ctl: UPDA1 UPDA2 mode: ity: PATDSEL z-op: op: LFU_CLEAR ctrl: BCOMPEN BKGWREN
A1 step values: -8 (X), 1 (Y)
A2 step values: -1 (X), 1 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
A1 -> pitch: 1 phrases, depth: 8bpp, z-off: 0, width: 320 (21), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
// compare source pixel with pattern pixel
/*
Blit! (000B8250 <- 0012C3A0) count: 16 x 1, A1/2_FLAGS: 00014420/00012000 [cmd: 05810001]
- CMD -> src: SRCEN dst: misc: a1ctl: mode: ity: PATDSEL z-op: op: LFU_REPLACE ctrl: BCOMPEN
+ CMD -> src: SRCEN dst: misc: a1ctl: mode: ity: PATDSEL z-op: op: LFU_REPLACE ctrl: BCOMPEN
A1 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 384 (22), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
A2 -> pitch: 1 phrases, depth: 1bpp, z-off: 0, width: 16 (10), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
x/y: 0/20
// compute the write data and store
if (!inhibit)
- {
+ {
// Houston, we have a problem...
// Look here, at PATDSEL and GOURD. If both are active (as they are on the BIOS intro), then there's
// a conflict! E.g.:
//Blit! (00100000 <- 000095D0) count: 3 x 1, A1/2_FLAGS: 00014220/00004020 [cmd: 00011008]
-// CMD -> src: dst: DSTEN misc: a1ctl: mode: GOURD ity: PATDSEL z-op: op: LFU_CLEAR ctrl:
+// CMD -> src: dst: DSTEN misc: a1ctl: mode: GOURD ity: PATDSEL z-op: op: LFU_CLEAR ctrl:
// A1 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 320 (21), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
// A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 256 (20), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
// A1 x/y: 90/171, A2 x/y: 808/0 Pattern: 776D770077007700
Hover Strike ADDDSEL blit:
Blit! (00098D90 <- 0081DDC0) count: 320 x 287, A1/2_FLAGS: 00004220/00004020 [cmd: 00020208]
- CMD -> src: dst: DSTEN misc: a1ctl: UPDA1 mode: ity: ADDDSEL z-op: op: LFU_CLEAR ctrl:
+ CMD -> src: dst: DSTEN misc: a1ctl: UPDA1 mode: ity: ADDDSEL z-op: op: LFU_CLEAR ctrl:
A1 step values: -320 (X), 1 (Y)
A1 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 256 (20), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
//According to JTRM, this is part of the four things the blitter does with the write data (the other
//three being PATDSEL, ADDDSEL, and LFU (default). I'm not sure which gets precedence, this or PATDSEL
//(see above blit example)...
- if (GOURD)
+ if (GOURD)
writedata = ((gd_c[colour_index]) << 8) | (gd_i[colour_index] >> 16);
- if (SRCSHADE)
+ if (SRCSHADE)
{
int intensity = srcdata & 0xFF;
int ia = gd_ia >> 16;
/*if (((REG(A1_FLAGS) >> 3) & 0x07) == 5)
{
uint32 offset = a1_addr+(PIXEL_OFFSET_32(a1)<<2);
-// (((((UINT32)a##_y >> 16) * a##_width) + (((UINT32)a##_x >> 16) & ~1)) * (1 + a##_pitch) + (((UINT32)a##_x >> 16) & 1))
+// (((((uint32)a##_y >> 16) * a##_width) + (((uint32)a##_x >> 16) & ~1)) * (1 + a##_pitch) + (((uint32)a##_x >> 16) & 1))
if ((offset >= 0x1FF020 && offset <= 0x1FF03F) || (offset >= 0x1FF820 && offset <= 0x1FF83F))
WriteLog("32bpp pixel write: A1 Phrase mode --> ");
}//*/
srczdata = READ_RDATA(SRCZINT, a1, REG(A1_FLAGS), a1_phrase_mode);
}
- // load dst data and Z
+ // load dst data and Z
if (DSTEN)
{
dstdata = READ_PIXEL(a2, REG(A2_FLAGS));
dstzdata = READ_RDATA(DSTZ, a2, REG(A2_FLAGS), a2_phrase_mode);
}
- if (GOURZ)
+ if (GOURZ)
srczdata = z_i[colour_index] >> 16;
// apply z comparator
if (Z_OP_INF && srczdata < dstzdata) inhibit = 1;
if (Z_OP_EQU && srczdata == dstzdata) inhibit = 1;
if (Z_OP_SUP && srczdata > dstzdata) inhibit = 1;
-
+
// apply data comparator
//NOTE: The bit comparator (BCOMPEN) is NOT the same at the data comparator!
if (DCOMPEN | BCOMPEN)
// if (a1_phrase_mode || a2_phrase_mode)
// inhibit = !inhibit;
}
-
+
if (CLIPA1)
{
inhibit |= (((a1_x >> 16) < a1_clip_x && (a1_x >> 16) >= 0
// compute the write data and store
if (!inhibit)
- {
+ {
if (PATDSEL)
{
// use pattern data for write data
writedata |= srcdata & dstdata;
}
- if (GOURD)
+ if (GOURD)
writedata = ((gd_c[colour_index]) << 8) | (gd_i[colour_index] >> 16);
- if (SRCSHADE)
+ if (SRCSHADE)
{
int intensity = srcdata & 0xFF;
int ia = gd_ia >> 16;
/*if (logGo)
{
uint32 offset = a2_addr+(PIXEL_OFFSET_16(a2)<<1);
-// (((((UINT32)a##_y >> 16) * a##_width) + (((UINT32)a##_x >> 16) & ~1)) * (1 + a##_pitch) + (((UINT32)a##_x >> 16) & 1))
+// (((((uint32)a##_y >> 16) * a##_width) + (((uint32)a##_x >> 16) & ~1)) * (1 + a##_pitch) + (((uint32)a##_x >> 16) & 1))
WriteLog("[%08X:%04X] ", offset, writedata);
}//*/
// write to the destination
; O
Blit! (00110000 <- 0010B2A8) count: 12 x 12, A1/2_FLAGS: 000042E2/00000020 [cmd: 09800609]
- CMD -> src: SRCEN dst: DSTEN misc: a1ctl: UPDA1 UPDA2 mode: ity: z-op: op: LFU_REPLACE ctrl: DCOMPEN
+ CMD -> src: SRCEN dst: DSTEN misc: a1ctl: UPDA1 UPDA2 mode: ity: z-op: op: LFU_REPLACE ctrl: DCOMPEN
A1 step values: -15 (X), 1 (Y)
A2 step values: -4 (X), 0 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
A1 -> pitch: 4 phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
a2_y += a2_step_y;//*/
#endif
}
-
- // write values back to registers
+
+ // write values back to registers
WREG(A1_PIXEL, (a1_y & 0xFFFF0000) | ((a1_x >> 16) & 0xFFFF));
WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xFFFF));
WREG(A2_PIXEL, (a2_y & 0xFFFF0000) | ((a2_x >> 16) & 0xFFFF));
a1_zoffs = (REG(A1_FLAGS) >> 6) & 7;
a2_zoffs = (REG(A2_FLAGS) >> 6) & 7;
-
+
xadd_a1_control = (REG(A1_FLAGS) >> 16) & 0x03;
xadd_a2_control = (REG(A2_FLAGS) >> 16) & 0x03;
// a1_width = blitter_scanline_width[((REG(A1_FLAGS) & 0x00007E00) >> 9)];
// According to JTRM, this must give a *whole number* of phrases in the current
// pixel size (this means the lookup above is WRONG)... !!! FIX !!!
- UINT32 m = (REG(A1_FLAGS) >> 9) & 0x03, e = (REG(A1_FLAGS) >> 11) & 0x0F;
+ uint32 m = (REG(A1_FLAGS) >> 9) & 0x03, e = (REG(A1_FLAGS) >> 11) & 0x0F;
a1_width = ((0x04 | m) << e) >> 2;//*/
a2_x = (REG(A2_PIXEL) & 0x0000FFFF) << 16;
// add pixelsize (1) to X
a1_xadd = 1 << 16;
break;
- case XADD0:
+ case XADD0:
// add zero (for those nice vertical lines)
a1_xadd = 0;
break;
// A1 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 128 (1C), addctl: XADDINC YADD1 XSIGNADD YSIGNADD
// A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 320 (21), addctl: XADD0 YADD1 XSIGNADD YSIGNADD
//if (YADD1_A1 && YADD1_A2 && xadd_a2_control == XADD0 && xadd_a1_control == XADDINC)// &&
-// UINT32 a1f = REG(A1_FLAGS), a2f = REG(A2_FLAGS);
+// uint32 a1f = REG(A1_FLAGS), a2f = REG(A2_FLAGS);
//Ok, so this ISN'T it... Prolly the XADDPHR code above that's doing it...
//if (REG(A1_FLAGS) == 0x00073820 && REG(A2_FLAGS) == 0x00064220 && cmd == 0x41802801)
// A1 x/y: 14368/7, A2 x/y: 150/36
// add pixelsize (1) to X
a2_xadd = 1 << 16;
break;
- case XADD0:
+ case XADD0:
// add zero (for those nice vertical lines)
a2_xadd = 0;
break;
| ((uint32)blitter_ram[SRCDATA + 0] << 8) | blitter_ram[SRCDATA + 1];
gouraud_add = REG(INTENSITYINC);
-
+
gd_ia = gouraud_add & 0x00FFFFFF;
if (gd_ia & 0x00800000)
gd_ia = 0xFF000000 | gd_ia;
WriteLog(" GOURZ = %i\n",GOURZ);
WriteLog(" GOURD = %i\n",GOURD);
WriteLog(" SRCSHADE= %i\n",SRCSHADE);
- }
+ }
#endif
//NOTE: Pitch is ignored!
//Black is short by 3, pink is short by 1...
/*
Blit! (00110000 <- 000BF010) count: 9 x 31, A1/2_FLAGS: 000042E2/00010020 [cmd: 00010200]
- CMD -> src: dst: misc: a1ctl: UPDA1 mode: ity: PATDSEL z-op: op: LFU_CLEAR ctrl:
+ CMD -> src: dst: misc: a1ctl: UPDA1 mode: ity: PATDSEL z-op: op: LFU_CLEAR ctrl:
A1 -> pitch: 4 phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
A1 x/y: 262/124, A2 x/y: 128/0
Blit! (00110000 <- 000BF010) count: 5 x 38, A1/2_FLAGS: 000042E2/00010020 [cmd: 00010200]
- CMD -> src: dst: misc: a1ctl: UPDA1 mode: ity: PATDSEL z-op: op: LFU_CLEAR ctrl:
+ CMD -> src: dst: misc: a1ctl: UPDA1 mode: ity: PATDSEL z-op: op: LFU_CLEAR ctrl:
A1 -> pitch: 4 phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
A1 x/y: 264/117, A2 x/y: 407/0
Blit! (00110000 <- 000BF010) count: 9 x 23, A1/2_FLAGS: 000042E2/00010020 [cmd: 00010200]
- CMD -> src: dst: misc: a1ctl: UPDA1 mode: ity: PATDSEL z-op: op: LFU_CLEAR ctrl:
+ CMD -> src: dst: misc: a1ctl: UPDA1 mode: ity: PATDSEL z-op: op: LFU_CLEAR ctrl:
A1 step values: -10 (X), 1 (Y)
A1 -> pitch: 4(2) phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
A2 -> pitch: 1(0) phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
A1 x/y: 262/132, A2 x/y: 129/0
Blit! (00110000 <- 000BF010) count: 5 x 27, A1/2_FLAGS: 000042E2/00010020 [cmd: 00010200]
- CMD -> src: dst: misc: a1ctl: UPDA1 mode: ity: PATDSEL z-op: op: LFU_CLEAR ctrl:
+ CMD -> src: dst: misc: a1ctl: UPDA1 mode: ity: PATDSEL z-op: op: LFU_CLEAR ctrl:
A1 step values: -8 (X), 1 (Y)
A1 -> pitch: 4(2) phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
A2 -> pitch: 1(0) phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
; This looks like the ship icon in the upper left corner...
Blit! (00110000 <- 0010B2A8) count: 11 x 12, A1/2_FLAGS: 000042E2/00000020 [cmd: 09800609]
- CMD -> src: SRCEN dst: DSTEN misc: a1ctl: UPDA1 UPDA2 mode: ity: z-op: op: LFU_REPLACE ctrl: DCOMPEN
+ CMD -> src: SRCEN dst: DSTEN misc: a1ctl: UPDA1 UPDA2 mode: ity: z-op: op: LFU_REPLACE ctrl: DCOMPEN
A1 step values: -12 (X), 1 (Y)
A2 step values: 0 (X), 0 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
A1 -> pitch: 4 phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
; D
Blit! (00110000 <- 0010B2A8) count: 12 x 12, A1/2_FLAGS: 000042E2/00000020 [cmd: 09800609]
- CMD -> src: SRCEN dst: DSTEN misc: a1ctl: UPDA1 UPDA2 mode: ity: z-op: op: LFU_REPLACE ctrl: DCOMPEN
+ CMD -> src: SRCEN dst: DSTEN misc: a1ctl: UPDA1 UPDA2 mode: ity: z-op: op: LFU_REPLACE ctrl: DCOMPEN
A1 step values: -14 (X), 1 (Y)
A2 step values: -4 (X), 0 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
A1 -> pitch: 4 phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
; E
Blit! (00110000 <- 0010B2A8) count: 12 x 12, A1/2_FLAGS: 000042E2/00000020 [cmd: 09800609]
- CMD -> src: SRCEN dst: DSTEN misc: a1ctl: UPDA1 UPDA2 mode: ity: z-op: op: LFU_REPLACE ctrl: DCOMPEN
+ CMD -> src: SRCEN dst: DSTEN misc: a1ctl: UPDA1 UPDA2 mode: ity: z-op: op: LFU_REPLACE ctrl: DCOMPEN
A1 step values: -13 (X), 1 (Y)
A2 step values: -4 (X), 0 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
A1 -> pitch: 4 phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
; M
Blit! (00110000 <- 0010B2A8) count: 12 x 12, A1/2_FLAGS: 000042E2/00000020 [cmd: 09800609]
- CMD -> src: SRCEN dst: DSTEN misc: a1ctl: UPDA1 UPDA2 mode: ity: z-op: op: LFU_REPLACE ctrl: DCOMPEN
+ CMD -> src: SRCEN dst: DSTEN misc: a1ctl: UPDA1 UPDA2 mode: ity: z-op: op: LFU_REPLACE ctrl: DCOMPEN
A1 step values: -12 (X), 1 (Y)
A2 step values: 0 (X), 0 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
A1 -> pitch: 4 phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
; O
Blit! (00110000 <- 0010B2A8) count: 12 x 12, A1/2_FLAGS: 000042E2/00000020 [cmd: 09800609]
- CMD -> src: SRCEN dst: DSTEN misc: a1ctl: UPDA1 UPDA2 mode: ity: z-op: op: LFU_REPLACE ctrl: DCOMPEN
+ CMD -> src: SRCEN dst: DSTEN misc: a1ctl: UPDA1 UPDA2 mode: ity: z-op: op: LFU_REPLACE ctrl: DCOMPEN
A1 step values: -15 (X), 1 (Y)
A2 step values: -4 (X), 0 (Y) [mask (unused): 00000000 - FFFFFFFF/FFFFFFFF]
A1 -> pitch: 4 phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
uint32 /*src = cmd & 0x07, dst = (cmd >> 3) & 0x07, misc = (cmd >> 6) & 0x03,
a1ctl = (cmd >> 8) & 0x07,*/ mode = (cmd >> 11) & 0x07/*, ity = (cmd >> 14) & 0x0F,
zop = (cmd >> 18) & 0x07, op = (cmd >> 21) & 0x0F, ctrl = (cmd >> 25) & 0x3F*/;
- UINT32 a1f = REG(A1_FLAGS), a2f = REG(A2_FLAGS);
+ uint32 a1f = REG(A1_FLAGS), a2f = REG(A2_FLAGS);
uint32 p1 = a1f & 0x07, p2 = a2f & 0x07,
d1 = (a1f >> 3) & 0x07, d2 = (a2f >> 3) & 0x07,
zo1 = (a1f >> 6) & 0x07, zo2 = (a2f >> 6) & 0x07,
w1 = (a1f >> 9) & 0x3F, w2 = (a2f >> 9) & 0x3F,
ac1 = (a1f >> 16) & 0x1F, ac2 = (a2f >> 16) & 0x1F;
- UINT32 iw1 = ((0x04 | (w1 & 0x03)) << ((w1 & 0x3C) >> 2)) >> 2;
- UINT32 iw2 = ((0x04 | (w2 & 0x03)) << ((w2 & 0x3C) >> 2)) >> 2;
+ uint32 iw1 = ((0x04 | (w1 & 0x03)) << ((w1 & 0x3C) >> 2)) >> 2;
+ uint32 iw2 = ((0x04 | (w2 & 0x03)) << ((w2 & 0x3C) >> 2)) >> 2;
WriteLog("Blit! (%08X %s %08X) count: %d x %d, A1/2_FLAGS: %08X/%08X [cmd: %08X]\n", a1_addr, (mode&0x01 ? "->" : "<-"), a2_addr, n_pixels, n_lines, a1f, a2f, cmd);
// WriteLog(" CMD -> src: %d, dst: %d, misc: %d, a1ctl: %d, mode: %d, ity: %1X, z-op: %d, op: %1X, ctrl: %02X\n", src, dst, misc, a1ctl, mode, ity, zop, op, ctrl);
********************** STUFF CUT ABOVE THIS LINE! ******************************
*******************************************************************************/
-void blitter_init(void)
+void BlitterInit(void)
{
- blitter_reset();
+ BlitterReset();
}
-void blitter_reset(void)
+void BlitterReset(void)
{
memset(blitter_ram, 0x00, 0xA0);
}
-void blitter_done(void)
+void BlitterDone(void)
{
WriteLog("BLIT: Done.\n");
}
// status register
//This isn't cycle accurate--how to fix? !!! FIX !!!
//Probably have to do some multi-threaded implementation or at least a reentrant safe implementation...
+//Real hardware returns $00000805, just like the JTRM says.
+ if (offset == (0x38 + 0))
+ return 0x00;
+ if (offset == (0x38 + 1))
+ return 0x00;
+ if (offset == (0x38 + 2))
+ return 0x08;
if (offset == (0x38 + 3))
- return 0x01; // always idle
+ return 0x05; // always idle/never stopped (collision detection ignored!)
-// CHECK HERE ONCE THIS FIX HAS BEEN TESTED: [ ]
+// CHECK HERE ONCE THIS FIX HAS BEEN TESTED: [X]
//Fix for AvP:
if (offset >= 0x04 && offset <= 0x07)
//This is it. I wonder if it just ignores the lower three bits?
case 0x81: blitter_ram[PATTERNDATA + 5] = data; break;
case 0x82: blitter_ram[SRCDATA + 4] = data; break;
case 0x83: blitter_ram[SRCDATA + 5] = data; break;
-
+
case 0x84: break;
case 0x85: blitter_ram[PATTERNDATA + 3] = data; break;
case 0x86: blitter_ram[SRCDATA + 2] = data; break;
case 0x87: blitter_ram[SRCDATA + 3] = data; break;
-
+
case 0x88: break;
case 0x89: blitter_ram[PATTERNDATA + 1] = data; break;
case 0x8A: blitter_ram[SRCDATA + 0] = data; break;
case 0x91: blitter_ram[SRCZINT + 5] = data; break;
case 0x92: blitter_ram[SRCZFRAC + 4] = data; break;
case 0x93: blitter_ram[SRCZFRAC + 5] = data; break;
-
+
case 0x94: blitter_ram[SRCZINT + 2] = data; break;
case 0x95: blitter_ram[SRCZINT + 3] = data; break;
case 0x96: blitter_ram[SRCZFRAC + 2] = data; break;
case 0x97: blitter_ram[SRCZFRAC + 3] = data; break;
-
+
case 0x98: blitter_ram[SRCZINT + 0] = data; break;
case 0x99: blitter_ram[SRCZINT + 1] = data; break;
case 0x9A: blitter_ram[SRCZFRAC + 0] = data; break;
void LogBlit(void)
{
- char * opStr[16] = { "LFU_CLEAR", "LFU_NSAND", "LFU_NSAD", "LFU_NOTS", "LFU_SAND", "LFU_NOTD", "LFU_N_SXORD", "LFU_NSORND",
+ const char * opStr[16] = { "LFU_CLEAR", "LFU_NSAND", "LFU_NSAD", "LFU_NOTS", "LFU_SAND", "LFU_NOTD", "LFU_N_SXORD", "LFU_NSORND",
"LFU_SAD", "LFU_XOR", "LFU_D", "LFU_NSORD", "LFU_REPLACE", "LFU_SORND", "LFU_SORD", "LFU_ONE" };
uint32 cmd = GET32(blitter_ram, 0x38);
- UINT32 m = (REG(A1_FLAGS) >> 9) & 0x03, e = (REG(A1_FLAGS) >> 11) & 0x0F;
- UINT32 a1_width = ((0x04 | m) << e) >> 2;
+ uint32 m = (REG(A1_FLAGS) >> 9) & 0x03, e = (REG(A1_FLAGS) >> 11) & 0x0F;
+ uint32 a1_width = ((0x04 | m) << e) >> 2;
m = (REG(A2_FLAGS) >> 9) & 0x03, e = (REG(A2_FLAGS) >> 11) & 0x0F;
- UINT32 a2_width = ((0x04 | m) << e) >> 2;
+ uint32 a2_width = ((0x04 | m) << e) >> 2;
WriteLog("Blit!\n");
WriteLog(" COMMAND = %08X\n", cmd);
WriteLog(" UPDA2 = %s\n", (UPDA2 ? "1" : "0"));
WriteLog(" DSTA2 = %s\n", (DSTA2 ? "1" : "0"));
WriteLog(" ZOP = %s %s %s\n", (Z_OP_INF ? "<" : ""), (Z_OP_EQU ? "=" : ""), (Z_OP_SUP ? ">" : ""));
- WriteLog("--LFUFUNC = %s\n", opStr[(cmd >> 21) & 0x0F]);
+ WriteLog("+-LFUFUNC = %s\n", opStr[(cmd >> 21) & 0x0F]);
WriteLog("| PATDSEL = %s (PD=%08X%08X)\n", (PATDSEL ? "1" : "0"), REG(PATTERNDATA), REG(PATTERNDATA + 4));
- WriteLog("--ADDDSEL = %s\n", (ADDDSEL ? "1" : "0"));
+ WriteLog("+-ADDDSEL = %s\n", (ADDDSEL ? "1" : "0"));
WriteLog(" CMPDST = %s\n", (CMPDST ? "1" : "0"));
WriteLog(" BCOMPEN = %s\n", (BCOMPEN ? "1" : "0"));
WriteLog(" DCOMPEN = %s\n", (DCOMPEN ? "1" : "0"));
void BlitterMidsummer(uint32 cmd)
{
+#ifdef LOG_BLITS
+ LogBlit();
+#endif
uint32 outer_loop, inner_loop, a1_addr, a2_addr;
int32 a1_x, a1_y, a2_x, a2_y, a1_width, a2_width;
uint8 a1_phrase_mode, a2_phrase_mode;
a2_addr = REG(A2_BASE) & 0xFFFFFFF8;
a1_x = (REG(A1_PIXEL) << 16) | (REG(A1_FPIXEL) & 0xFFFF);
a1_y = (REG(A1_PIXEL) & 0xFFFF0000) | (REG(A1_FPIXEL) >> 16);
- UINT32 m = (REG(A1_FLAGS) >> 9) & 0x03, e = (REG(A1_FLAGS) >> 11) & 0x0F;
+ uint32 m = (REG(A1_FLAGS) >> 9) & 0x03, e = (REG(A1_FLAGS) >> 11) & 0x0F;
a1_width = ((0x04 | m) << e) >> 2;//*/
a2_x = (REG(A2_PIXEL) & 0x0000FFFF) << 16;
a2_y = (REG(A2_PIXEL) & 0xFFFF0000);
//pointing at. Likewise, the pixel (if in BPP 1, 2 & 4, chopped) otherwise. It probably still
//transfers an entire phrase even in pixel mode.
//Odd thought: Does it expand, e.g., 1 BPP pixels into 32 BPP internally? Hmm...
-//No.
+//No.
/*
a1_addr = REG(A1_BASE) & 0xFFFFFFF8;
a2_addr = REG(A2_BASE) & 0xFFFFFFF8;
a1_width = ((0x04 | m) << e) >> 2;
a2_width = ((0x04 | m) << e) >> 2;
- // write values back to registers
+ // write values back to registers
WREG(A1_PIXEL, (a1_y & 0xFFFF0000) | ((a1_x >> 16) & 0xFFFF));
WREG(A1_FPIXEL, (a1_y << 16) | (a1_x & 0xFFFF));
WREG(A2_PIXEL, (a2_y & 0xFFFF0000) | ((a2_x >> 16) & 0xFFFF));
}
// Figure out what gets written...
-
+
if (PATDSEL)
{
writeData = GET64(blitter_ram, PATTERNDATA);
else // LFUFUNC is the default...
{
writeData = 0;
-
+
if (LFU_NAN)
writeData |= ~srcData & ~dstData;
if (LFU_NA)
a2_x += (blitter_ram[A2_FLAGS + 1] & 0x08 ? -1 << 16 : 1 << 16);
/* else if ((blitter_ram[A2_FLAGS + 1] & 0x03) == 2)
a2_x += 0 << 16; */
-
+
if (blitter_ram[A2_FLAGS + 1] & 0x04)
a2_y += (blitter_ram[A2_FLAGS + 1] & 0x10 ? -1 << 16 : 1 << 16);
goto a1update
*/
/*
-#define A1_PIXEL ((UINT32)0x0C) // Integer part of the pixel (Y.i and X.i)
-#define A1_STEP ((UINT32)0x10) // Integer part of the step
-#define A1_FSTEP ((UINT32)0x14) // Fractional part of the step
-#define A1_FPIXEL ((UINT32)0x18) // Fractional part of the pixel (Y.f and X.f)
+#define A1_PIXEL ((uint32)0x0C) // Integer part of the pixel (Y.i and X.i)
+#define A1_STEP ((uint32)0x10) // Integer part of the step
+#define A1_FSTEP ((uint32)0x14) // Fractional part of the step
+#define A1_FPIXEL ((uint32)0x18) // Fractional part of the pixel (Y.f and X.f)
*/
// This is all kinda murky. All we have are the Midsummer docs to give us any guidance,
}
#endif
-/*
-Here's a collection of various blits that aren't handled correctly yet...
-
-Spinning cube in Jaguar BIOS opening:
-
- COMMAND = 41802F41
- a1_base = 0015B000
- a1_flags = 00033020 (0 0 0 11 . 011000 000 100 . 00)
- pitch=0, pixSz=4, zOff=0, width=64, xCtrl=3
- a1_clip = 64, 64 (00400040)
- a1_pixel = 0, 65534 (FFFE0000)
- a1_step = -64, -1 (FFFFFFC0)
- a1_fstep = 0, 18161 (46F10000)
- a1_fpixel= 32768, 42497 (A6018000)
- a1_inc = 1, 0 (00000001)
- a1_finc = 0, 1926 (07860000)
- a2_base = 0014B000
- a2_flags = 00013820 (0 0 0 01 0 011100 000 100 . 00)
- pitch=0, pixSz=4, zOff=0, width=128, xCtrl=1
- a2_mask = 0, 0 (00000000)
- a2_pixel = 33, 55 (00370021)
- a2_step = -64, 1 (0001FFC0)
- count = 64 x 57
- SRCEN = 1
- SRCENZ = 0
- SRCENX = 0
- DSTEN = 0
- DSTENZ = 0
- DSTWRZ = 0
- CLIPA1 = 1
- UPDA1F = 1
- UPDA1 = 1
- UPDA2 = 1
- DSTA2 = 1
- ZOP =
---LFUFUNC = LFU_REPLACE
-| PATDSEL = 0 (PD=0000000000000000)
---ADDDSEL = 0
- CMPDST = 0
- BCOMPEN = 0
- DCOMPEN = 0
- TOPBEN = 0
- TOPNEN = 0
- BKGWREN = 0
- GOURD = 0 (II=00FCDC80, SD=FF00FF00FF00FF00)
- GOURZ = 1 (ZI=00000000, ZD=0000000000000000, SZ1=0000000000000000, SZ2=0000000000000000)
- SRCSHADE = 1
-*/
+//
+// Here's attempt #2--taken from the Oberon chip specs!
+//
#ifdef USE_MIDSUMMER_BLITTER_MKII
-// Here's attempt #2--taken from the Oberon chip specs!
void ADDRGEN(uint32 &, uint32 &, bool, bool,
uint16, uint16, uint32, uint8, uint8, uint8, uint8,
uint16 adda_x, uint16 adda_y, uint16 addb_x, uint16 addb_y, uint8 modx, bool suba_x, bool suba_y);
void DATA(uint64 &wdata, uint8 &dcomp, uint8 &zcomp, bool &nowrite,
bool big_pix, bool cmpdst, uint8 daddasel, uint8 daddbsel, uint8 daddmode, bool daddq_sel, uint8 data_sel,
- uint8 dbinh, uint8 dend, uint8 dstart, uint64 dstd, uint32 iinc, uint8 lfu_func, uint64 patd, bool patdadd,
+ uint8 dbinh, uint8 dend, uint8 dstart, uint64 dstd, uint32 iinc, uint8 lfu_func, uint64 &patd, bool patdadd,
bool phrase_mode, uint64 srcd, bool srcdread, bool srczread, bool srcz2add, uint8 zmode,
- bool bcompen, bool bkgwren, bool dcompen, uint8 icount, uint8 pixsize);
+ bool bcompen, bool bkgwren, bool dcompen, uint8 icount, uint8 pixsize,
+ uint64 &srcz, uint64 dstz, uint32 zinc);
void COMP_CTRL(uint8 &dbinh, bool &nowrite,
bool bcompen, bool big_pix, bool bkgwren, uint8 dcomp, bool dcompen, uint8 icount,
uint8 pixsize, bool phrase_mode, uint8 srcd, uint8 zcomp);
void BlitterMidsummer2(void)
{
+#ifdef LOG_BLITS
+ LogBlit();
+#endif
// Here's what the specs say the state machine does. Note that this can probably be
// greatly simplified (also, it's different from what John has in his Oberon docs):
//Will remove stuff that isn't in Jaguar I once fully described (stuff like texture won't
uint32 cmd = GET32(blitter_ram, COMMAND);
-// $01800005 has SRCENX, may have to investigate further...
-// $00011008 has GOURD & DSTEN.
-// $41802F41 has SRCSHADE, CLIPA1
logBlit = false;
if (
cmd != 0x00010200 && // PATDSEL
- cmd != 0x01800001
+ cmd != 0x01800001 // SRCEN LFUFUNC=C
&& cmd != 0x01800005
//Boot ROM ATARI letters:
&& cmd != 0x00011008 // DSTEN GOURD PATDSEL
//Static pic on title screen:
&& cmd != 0x01800601 // SRCEN UPDA1 UPDA2 LFUFUNC=C
//Turning letters on Cybermorph intro screen:
- && cmd != 0x09800F41 // SRCEN CLIP_A1 UPDA1 UPDA1F UPDA2 DSTA2 LFUFUNC=C DCOMPEN
+// && cmd != 0x09800F41 // SRCEN CLIP_A1 UPDA1 UPDA1F UPDA2 DSTA2 LFUFUNC=C DCOMPEN
&& cmd != 0x00113078 // DSTEN DSTENZ DSTWRZ CLIP_A1 GOURD GOURZ PATDSEL ZMODE=4
&& cmd != 0x09900F39 // SRCEN DSTEN DSTENZ DSTWRZ UPDA1 UPDA1F UPDA2 DSTA2 ZMODE=4 LFUFUNC=C DCOMPEN
&& cmd != 0x09800209 // SRCEN DSTEN UPDA1 LFUFUNC=C DCOMPEN
&& cmd != 0x00010000 // PATDSEL
//Hover Strike text:
&& cmd != 0x1401060C // SRCENX DSTEN UPDA1 UPDA2 PATDSEL BCOMPEN BKGWREN
+//Hover Strike 3D stuff
+ && cmd != 0x01902839 // SRCEN DSTEN DSTENZ DSTWRZ DSTA2 GOURZ ZMODE=4 LFUFUNC=C
+//Hover Strike darkening on intro to play (briefing) screen
+ && cmd != 0x00020208 // DSTEN UPDA1 ADDDSEL
//Trevor McFur stuff:
-//Various text...
-//Or is it? Look at some of these dimensions (phrase mode is OFF):
-//48 x 165, 64 x 265, 192 x 104, 48 x 392, 16 x 56, 32 x 168, 48 x 281, 80 x 448, 192 x 112,
-//96 x 72, 320 x 184, 256 x 200, 224 x 48
&& cmd != 0x05810601 // SRCEN UPDA1 UPDA2 PATDSEL BCOMPEN
&& cmd != 0x01800201 // SRCEN UPDA1 LFUFUNC=C
+//T2K:
+ && cmd != 0x00011000 // GOURD PATDSEL
+ && cmd != 0x00011040 // CLIP_A1 GOURD PATDSEL
+//Checkered flag:
+ && cmd != 0x01800000 // LFUFUNC=C
+ && cmd != 0x01800401 //
+ && cmd != 0x01800040 //
+ && cmd != 0x00020008 //
+// && cmd != 0x09800F41 // SRCEN CLIP_A1 UPDA1 UPDA1F UPDA2 DSTA2 LFUFUNC=C DCOMPEN
)
logBlit = true;//*/
+//logBlit = true;
+if (blit_start_log == 0) // Wait for the signal...
+ logBlit = false;//*/
/*
-TMcF unique blits:
-logBlit = F, cmd = 00010000 *
-logBlit = F, cmd = 01800601 *
-logBlit = F, cmd = 05810601
-logBlit = F, cmd = 01800201
+Some T2K unique blits:
logBlit = F, cmd = 00010200 *
+logBlit = F, cmd = 00011000
+logBlit = F, cmd = 00011040
+logBlit = F, cmd = 01800005 *
+logBlit = F, cmd = 09800741 *
+
+Hover Strike mission selection screen:
+Blit! (CMD = 01902839) // SRCEN DSTEN DSTENZ DSTWRZ DSTA2 GOURZ ZMODE=4 LFUFUNC=C
+
+Checkered Flag blits in the screw up zone:
+Blit! (CMD = 01800001) // SRCEN LFUFUNC=C
+Blit! (CMD = 01800000) // LFUFUNC=C
+Blit! (CMD = 00010000) // PATDSEL
+
+Wolfenstein 3D in the fuckup zone:
+Blit! (CMD = 01800000) // LFUFUNC=C
*/
//printf("logBlit = %s, cmd = %08X\n", (logBlit ? "T" : "F"), cmd);
//fflush(stdout);
+//logBlit = true;
+
+/*
+Blit! (CMD = 00011040)
+Flags: CLIP_A1 GOURD PATDSEL
+ count = 18 x 1
+ a1_base = 00100000, a2_base = 0081F6A8
+ a1_x = 00A7, a1_y = 0014, a1_frac_x = 0000, a1_frac_y = 0000, a2_x = 0001, a2_y = 0000
+ a1_step_x = FE80, a1_step_y = 0001, a1_stepf_x = 0000, a1_stepf_y = 0000, a2_step_x = FFF8, a2_step_y = 0001
+ a1_inc_x = 0001, a1_inc_y = 0000, a1_incf_x = 0000, a1_incf_y = 0000
+ a1_win_x = 0180, a1_win_y = 0118, a2_mask_x = 0000, a2_mask_y = 0000
+ a2_mask=F a1add=+phr/+0 a2add=+phr/+0
+ a1_pixsize = 4, a2_pixsize = 4
+*/
+//Testing T2K...
+/*logBlit = false;
+if (cmd == 0x00011040
+ && (GET16(blitter_ram, A1_PIXEL + 2) == 0x00A7) && (GET16(blitter_ram, A1_PIXEL + 0) == 0x0014)
+ && (GET16(blitter_ram, A2_PIXEL + 2) == 0x0001) && (GET16(blitter_ram, A2_PIXEL + 0) == 0x0000)
+ && (GET16(blitter_ram, PIXLINECOUNTER + 2) == 18))
+ logBlit = true;*/
// Line states passed in via the command register
#endif
// Lines that don't exist in Jaguar I (and will never be asserted)
-
+
bool polygon = false, datinit = false, a1_stepld = false, a2_stepld = false, ext_int = false;
bool istepadd = false, istepfadd = false, finneradd = false, inneradd = false;
bool zstepfadd = false, zstepadd = false;
uint8 pixsize = (dsta2 ? a2_pixsize : a1_pixsize); // From ACONTROL
+//Testing Trevor McFur--I *think* it's the circle on the lower RHS of the screen...
+/*logBlit = false;
+if (cmd == 0x05810601 && (GET16(blitter_ram, PIXLINECOUNTER + 2) == 96)
+ && (GET16(blitter_ram, PIXLINECOUNTER + 0) == 72))
+ logBlit = true;//*/
//Testing...
//if (cmd == 0x1401060C) patd = 0xFFFFFFFFFFFFFFFFLL;
//if (cmd == 0x1401060C) patd = 0x00000000000000FFLL;
; Pink altimeter bar
Blit! (00110000 <- 000BF010) count: 9 x 23, A1/2_FLAGS: 000042E2/00010020 [cmd: 00010200]
- CMD -> src: dst: misc: a1ctl: UPDA1 mode: ity: PATDSEL z-op: op: LFU_CLEAR ctrl:
+ CMD -> src: dst: misc: a1ctl: UPDA1 mode: ity: PATDSEL z-op: op: LFU_CLEAR ctrl:
A1 step values: -10 (X), 1 (Y)
A1 -> pitch: 4 phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
; Black altimeter bar
Blit! (00110000 <- 000BF010) count: 5 x 29, A1/2_FLAGS: 000042E2/00010020 [cmd: 00010200]
- CMD -> src: dst: misc: a1ctl: UPDA1 mode: ity: PATDSEL z-op: op: LFU_CLEAR ctrl:
+ CMD -> src: dst: misc: a1ctl: UPDA1 mode: ity: PATDSEL z-op: op: LFU_CLEAR ctrl:
A1 step values: -8 (X), 1 (Y)
A1 -> pitch: 4 phrases, depth: 16bpp, z-off: 3, width: 320 (21), addctl: XADDPHR YADD0 XSIGNADD YSIGNADD
A2 -> pitch: 1 phrases, depth: 16bpp, z-off: 0, width: 1 (00), addctl: XADDPIX YADD0 XSIGNADD YSIGNADD
*/
// Bugs in Jaguar I
-
+
a2addy = a1addy; // A2 channel Y add bit is tied to A1's
//if (logBlit && (ocount > 20)) logBlit = false;
(uint32)(srcz2 >> 32), (uint32)(srcz2 & 0xFFFFFFFF),
(uint32)(dstz >> 32), (uint32)(dstz & 0xFFFFFFFF), zinc, collision);
}
-#endif
+#endif
// Various state lines set up by user
fflush(stdout);
}
#endif
+//logBlit = false;
// Stopgap vars to simulate various lines
while (true)
{
// IDLE
-
+
if ((idle && !go) || (inner && outer0 && indone))
{
#ifdef VERBOSE_BLITTER_LOGGING
#endif
idlei = true;
- return;
+//Instead of a return, let's try breaking out of the loop...
+break;
+// return;
}
else
idlei = false;
-
+
// INNER LOOP ACTIVE
/*
Entering DWRITE state... (icount=0000, inc=4)
Now:
[in=F a1f=F a1=F zf=F z=F a2=F iif=F iii=F izf=F izi=F]
*/
-
+
if ((idle && go && !datinit)
|| (inner && !indone)
|| (inner && indone && !outer0 && !upda1f && !upda1 && notgzandp && !upda2 && !datinit)
}
else
inneri = false;
-
+
// A1 FRACTION UPDATE
-
+
if (inner && indone && !outer0 && upda1f)
{
a1fupdatei = true;
}
else
a2updatei = false;
-
+
// INITIALIZE INTENSITY FRACTION
-
+
if ((zupdate && !upda2 && datinit)
|| (a1update && !upda2 && datinit && notgzandp)
|| (inner && indone && !outer0 && !upda1f && !upda1 && notgzandp && !upda2 && datinit)
}
else
init_ifi = false;
-
+
// INITIALIZE INTENSITY INTEGER
-
+
if (init_if)
{
init_iii = true;
}
else
init_iii = false;
-
+
// INITIALIZE Z FRACTION
-
+
if (init_ii && gourz)
{
init_zfi = true;
}
else
init_zfi = false;
-
+
// INITIALIZE Z INTEGER
-
+
if (init_zf)
{
init_zii = true;
}
else
init_zii = false;
-
+
// Here we move the fooi into their foo counterparts in order to simulate the moving
// of data into the various FDSYNCs... Each time we loop we simulate one clock cycle...
bool dsta_addi = (dwritei && !dstwrz) || dzwritei;
bool gensrc = sreadxi || szreadxi || sreadi || szreadi;
- bool gendst = dreadi || szreadi || dwritei || dzwritei;
+ bool gendst = dreadi || dzreadi || dwritei || dzwritei;
bool gena2i = (gensrc && !dsta2) || (gendst && dsta2);
bool zaddr = szreadx || szread || dzread || dzwrite;
/* Data adder mode control
000 16-bit normal add
001 16-bit saturating add with carry
-010 8-bit saturating add with carry, carry into top byte is
+010 8-bit saturating add with carry, carry into top byte is
inhibited (YCrCb)
-011 8-bit saturating add with carry, carry into top byte and
+011 8-bit saturating add with carry, carry into top byte and
between top nybbles is inhibited (CRY)
100 16-bit normal add with carry
101 16-bit saturating add
110 8-bit saturating add, carry into top byte is inhibited
-111 8-bit saturating add, carry into top byte and between top
+111 8-bit saturating add, carry into top byte and between top
nybbles is inhibited
The first five are used for Gouraud calculations, the latter three
+ init_ii . /topnen . /topben . /ext_int
+ init_ii . topnen . topben . /ext_int
+ init_zi
-
+
Bit 1 = dwrite . gourd . atick[1] . /topben . /ext_int
+ istepadd . /topben . /ext_int
+ /gourd . /gourz . /topben
|| (init_ii && !topben && !ext_int) ? 0x02 : 0x00);
daddmode |= ((!gourd && !gourz) || shadeadd || (dwrite && gourd && ext_int)
|| (istepadd && ext_int) || (init_ii && ext_int) ? 0x04 : 0x00);
-/* Data add load controls
-Pattern fraction (dest data) is loaded on
+/* Data add load controls
+Pattern fraction (dest data) is loaded on
dwrite . gourd . atick[0]
+ istepfadd . /datinit
+ init_if
dwrite . gourd . atick[1]
+ istepadd . /datinit . /datinit
+ init_ii
-Source z1 is loaded on
+Source z1 is loaded on
dzwrite . gourz . atick[1]
+ zstepadd . /datinit . /datinit
+ init_zi
-Source z2 is loaded on
+Source z2 is loaded on
dzwrite . gourz . atick[0]
+ zstepfadd
+ init_zf
/* Generate source alignment shift
-------------------------------
-The source alignment shift for data move is the difference between
-the source and destination X pointers, multiplied by the pixel
-size. Only the low six bits of the pointers are of interest, as
-pixel sizes are always a power of 2 and window rows are always
-phrase aligned.
+The source alignment shift for data move is the difference between
+the source and destination X pointers, multiplied by the pixel
+size. Only the low six bits of the pointers are of interest, as
+pixel sizes are always a power of 2 and window rows are always
+phrase aligned.
When not in phrase mode, the top 3 bits of the shift value are
set to zero (2/26).
Source shifting is also used to extract bits for bit-to-byte
-expansion in phrase mode. This involves only the bottom three
+expansion in phrase mode. This involves only the bottom three
bits of the shift value, and is based on the offset within the
phrase of the destination X pointer, in pixels.
//ADDRGEN(srcAddr, pixAddr, gena2i, zaddr,
// a1_x, a1_y, a1_base, a1_pitch, a1_pixsize, a1_width, a1_zoffset,
// a2_x, a2_y, a2_base, a2_pitch, a2_pixsize, a2_width, a2_zoffset);
-srcd2 = srcd1;
-srcd1 = ((uint64)JaguarReadLong(address, BLITTER) << 32) | (uint64)JaguarReadLong(address + 4, BLITTER);
+ srcd2 = srcd1;
+ srcd1 = ((uint64)JaguarReadLong(address + 0, BLITTER) << 32)
+ | (uint64)JaguarReadLong(address + 4, BLITTER);
//Kludge to take pixel size into account...
+//Hmm. If we're not in phrase mode, this is most likely NOT going to be used...
+//Actually, it would be--because of BCOMPEN expansion, for example...
if (!phrase_mode)
{
- if (pixsize == 5)
- srcd1 >>= 32;
- else if (pixsize == 4)
- srcd1 >>= 48;
- else
+ if (bcompen)
srcd1 >>= 56;
-}
+ else
+ {
+ if (pixsize == 5)
+ srcd1 >>= 32;
+ else if (pixsize == 4)
+ srcd1 >>= 48;
+ else
+ srcd1 >>= 56;
+ }
+}//*/
#ifdef VERBOSE_BLITTER_LOGGING
if (logBlit)
{
#ifdef VERBOSE_BLITTER_LOGGING
if (logBlit)
{
-printf(" Entering SZREADX state...\n");
+printf(" Entering SZREADX state...");
fflush(stdout);
}
+#endif
+ srcz2 = srcz1;
+ srcz1 = ((uint64)JaguarReadLong(address, BLITTER) << 32) | (uint64)JaguarReadLong(address + 4, BLITTER);
+#ifdef VERBOSE_BLITTER_LOGGING
+if (logBlit)
+{
+ printf(" Src Z extra read address/pix address: %08X/%1X [%08X%08X]\n", address, pixAddr,
+ (uint32)(dstz >> 32), (uint32)(dstz & 0xFFFFFFFF));
+ fflush(stdout);
+}
#endif
}
//Kludge to take pixel size into account...
if (!phrase_mode)
{
- if (pixsize == 5)
- srcd1 >>= 32;
- else if (pixsize == 4)
- srcd1 >>= 48;
- else
+ if (bcompen)
srcd1 >>= 56;
+ else
+ {
+ if (pixsize == 5)
+ srcd1 >>= 32;
+ else if (pixsize == 4)
+ srcd1 >>= 48;
+ else
+ srcd1 >>= 56;
+ }
}
#ifdef VERBOSE_BLITTER_LOGGING
if (logBlit)
{
-printf(" Source read address/pix address: %08X/%1X [%08X%08X]\n", address, pixAddr,
+printf(" Source read address/pix address: %08X/%1X [%08X%08X]\n", address, pixAddr,
(uint32)(srcd1 >> 32), (uint32)(srcd1 & 0xFFFFFFFF));
fflush(stdout);
}
#ifdef VERBOSE_BLITTER_LOGGING
if (logBlit)
{
-printf(" Entering SZREAD state...\n");
+printf(" Entering SZREAD state...");
fflush(stdout);
}
+#endif
+ srcz2 = srcz1;
+ srcz1 = ((uint64)JaguarReadLong(address, BLITTER) << 32) | (uint64)JaguarReadLong(address + 4, BLITTER);
+//Kludge to take pixel size into account... I believe that it only has to take 16BPP mode into account. Not sure tho.
+if (!phrase_mode && pixsize == 4)
+ srcz1 >>= 48;
+
+#ifdef VERBOSE_BLITTER_LOGGING
+if (logBlit)
+{
+ printf(" Src Z read address/pix address: %08X/%1X [%08X%08X]\n", address, pixAddr,
+ (uint32)(dstz >> 32), (uint32)(dstz & 0xFFFFFFFF));
+ fflush(stdout);
+}
#endif
}
#ifdef VERBOSE_BLITTER_LOGGING
if (logBlit)
{
-printf(" Entering DREAD state...\n");
+printf(" Entering DREAD state...");
fflush(stdout);
}
#endif
#ifdef VERBOSE_BLITTER_LOGGING
if (logBlit)
{
-printf(" Dest read address/pix address: %08X/%1X [%08X%08X]\n", address, pixAddr,
+printf(" Dest read address/pix address: %08X/%1X [%08X%08X]\n", address, pixAddr,
(uint32)(dstd >> 32), (uint32)(dstd & 0xFFFFFFFF));
fflush(stdout);
}
}
#endif
dstz = ((uint64)JaguarReadLong(address, BLITTER) << 32) | (uint64)JaguarReadLong(address + 4, BLITTER);
+//Kludge to take pixel size into account... I believe that it only has to take 16BPP mode into account. Not sure tho.
+if (!phrase_mode && pixsize == 4)
+ dstz >>= 48;
+
#ifdef VERBOSE_BLITTER_LOGGING
if (logBlit)
{
#endif
}
+// These vars should probably go further up in the code... !!! FIX !!!
+// We can't preassign these unless they're static...
+//uint64 srcz = 0; // These are assigned to shut up stupid compiler warnings--dwrite is ALWAYS asserted
+//bool winhibit = false;
+uint64 srcz;
+bool winhibit;
//NOTE: SRCSHADE requires GOURZ to be set to work properly--another Jaguar I bug
if (dwrite)
{
#ifdef VERBOSE_BLITTER_LOGGING
if (logBlit)
{
-printf(" Entering DWRITE state...\n");
+printf(" Entering DWRITE state...");
fflush(stdout);
}
#endif
#ifdef VERBOSE_BLITTER_LOGGING
if (logBlit)
{
-printf(" Dest write address/pix address: %08X/%1X", address, pixAddr);
-printf(" [dstart=%X dend=%X pwidth=%X srcshift=%X]", dstart, dend, pwidth, srcshift);
-fflush(stdout);
-printf("[daas=%X dabs=%X dam=%X ds=%X daq=%s]", daddasel, daddbsel, daddmode, data_sel, (daddq_sel ? "T" : "F"));
-fflush(stdout);
+ printf(" Dest write address/pix address: %08X/%1X", address, pixAddr);
+ fflush(stdout);
}
#endif
if (srcshift == 0)
srcd = srcd1;
-//Temporary kludge, to see if the fractional pattern does anything...
-//This works, BTW
-if (patfadd)
+//NOTE: This only works with pixel sizes less than 8BPP...
+//DOUBLE NOTE: Still need to do regression testing to ensure that this doesn't break other stuff... !!! CHECK !!!
+if (!phrase_mode && srcshift != 0)
+ srcd = ((srcd2 & 0xFF) << (8 - srcshift)) | ((srcd1 & 0xFF) >> srcshift);
+
+//Z DATA() stuff done here... And it has to be done before any Z shifting...
+//Note that we need to have phrase mode start/end support here... (Not since we moved it from dzwrite...!)
+/*
+Here are a couple of Cybermorph blits with Z:
+$00113078 // DSTEN DSTENZ DSTWRZ CLIP_A1 GOURD GOURZ PATDSEL ZMODE=4
+$09900F39 // SRCEN DSTEN DSTENZ DSTWRZ UPDA1 UPDA1F UPDA2 DSTA2 ZMODE=4 LFUFUNC=C DCOMPEN
+
+We're having the same phrase mode overwrite problem we had with the pixels... !!! FIX !!!
+Odd. It's equating 0 with 0... Even though ZMODE is $04 (less than)!
+*/
+if (gourz)
{
+/*
+void ADDARRAY(uint16 * addq, uint8 daddasel, uint8 daddbsel, uint8 daddmode,
+ uint64 dstd, uint32 iinc, uint8 initcin[], uint64 initinc, uint16 initpix,
+ uint32 istep, uint64 patd, uint64 srcd, uint64 srcz1, uint64 srcz2,
+ uint32 zinc, uint32 zstep)
+*/
uint16 addq[4];
uint8 initcin[4] = { 0, 0, 0, 0 };
- ADDARRAY(addq, 4/*daddasel*/, 4/*daddbsel*/, 0/*daddmode*/, dstd, iinc, initcin, 0, 0, 0, patd, srcd, 0, 0, 0, 0);
- srcd1 = ((uint64)addq[3] << 48) | ((uint64)addq[2] << 32) | ((uint64)addq[1] << 16) | (uint64)addq[0];
+ ADDARRAY(addq, 7/*daddasel*/, 6/*daddbsel*/, 0/*daddmode*/, 0, 0, initcin, 0, 0, 0, 0, 0, srcz1, srcz2, zinc, 0);
+ srcz2 = ((uint64)addq[3] << 48) | ((uint64)addq[2] << 32) | ((uint64)addq[1] << 16) | (uint64)addq[0];
+ ADDARRAY(addq, 6/*daddasel*/, 7/*daddbsel*/, 1/*daddmode*/, 0, 0, initcin, 0, 0, 0, 0, 0, srcz1, srcz2, zinc, 0);
+ srcz1 = ((uint64)addq[3] << 48) | ((uint64)addq[2] << 32) | ((uint64)addq[1] << 16) | (uint64)addq[0];
+
+#if 0//def VERBOSE_BLITTER_LOGGING
+if (logBlit)
+{
+ printf("\n[srcz1=%08X%08X, srcz2=%08X%08X, zinc=%08X",
+ (uint32)(srcz1 >> 32), (uint32)(srcz1 & 0xFFFFFFFF),
+ (uint32)(srcz2 >> 32), (uint32)(srcz2 & 0xFFFFFFFF), zinc);
+ fflush(stdout);
+}
+#endif
}
-//Note that we still don't take atick[0] & [1] into account here, so this will skip half of the data needed... !!! FIX !!!
-//Not yet enumerated: dbinh, srcdread, srczread
+uint8 zSrcShift = srcshift & 0x30;
+srcz = (srcz2 << (64 - zSrcShift)) | (srcz1 >> zSrcShift);
+//bleh, ugly ugly ugly
+if (zSrcShift == 0)
+ srcz = srcz1;
+
+#if 0//def VERBOSE_BLITTER_LOGGING
+if (logBlit)
+{
+ printf(" srcz=%08X%08X]\n", (uint32)(srcz >> 32), (uint32)(srcz & 0xFFFFFFFF));
+ fflush(stdout);
+}
+#endif
//When in SRCSHADE mode, it adds the IINC to the read source (from LFU???)
//According to following line, it gets LFU mode. But does it feed the source into the LFU
//Seems to work... Not 100% sure tho.
//end try this
-bool winhibit;// = false;
+//Temporary kludge, to see if the fractional pattern does anything...
+//This works, BTW
+//But it seems to mess up in Cybermorph... the shading should be smooth but it isn't...
+//Seems the carry out is lost again... !!! FIX !!! [DONE--see below]
+if (patfadd)
+{
+ uint16 addq[4];
+ uint8 initcin[4] = { 0, 0, 0, 0 };
+ ADDARRAY(addq, 4/*daddasel*/, 4/*daddbsel*/, 0/*daddmode*/, dstd, iinc, initcin, 0, 0, 0, patd, srcd, 0, 0, 0, 0);
+ srcd1 = ((uint64)addq[3] << 48) | ((uint64)addq[2] << 32) | ((uint64)addq[1] << 16) | (uint64)addq[0];
+}
+
+//Note that we still don't take atick[0] & [1] into account here, so this will skip half of the data needed... !!! FIX !!!
+//Not yet enumerated: dbinh, srcdread, srczread
+//Also, should do srcshift on the z value in phrase mode... !!! FIX !!! [DONE]
+//As well as add a srcz variable we can set external to this state... !!! FIX !!! [DONE]
+
uint64 wdata;
uint8 dcomp, zcomp;
DATA(wdata, dcomp, zcomp, winhibit,
true, cmpdst, daddasel, daddbsel, daddmode, daddq_sel, data_sel, 0/*dbinh*/,
dend, dstart, dstd, iinc, lfufunc, patd, patdadd,
phrase_mode, srcd, false/*srcdread*/, false/*srczread*/, srcz2add, zmode,
- bcompen, bkgwren, dcompen, icount & 0x07, pixsize);
-// bool bcompen, bool bkgwren, bool dcompen, uint8 icount, uint8 pixsize)
+ bcompen, bkgwren, dcompen, icount & 0x07, pixsize,
+ srcz, dstz, zinc);
/*
Seems that the phrase mode writes with DCOMPEN and DSTEN are corrupting inside of DATA: !!! FIX !!!
It's fairly random as well. 7CFE -> 7DFE, 7FCA -> 78CA, 7FA4 -> 78A4, 7F88 -> 8F88
It could be related to an uninitialized variable, like the zmode bug...
+[DONE]
+It was a bug in the dech38el data--it returned $FF for ungated instead of $00...
Blit! (CMD = 09800609)
Flags: SRCEN DSTEN UPDA1 UPDA2 LFUFUNC=C DCOMPEN
Entering IDLE_INNER state...
*/
-if (patdadd)
- patd = wdata;
+//Why isn't this taken care of in DATA? Because, DATA is modifying its local copy instead of the one used here.
+//!!! FIX !!! [DONE]
+//if (patdadd)
+// patd = wdata;
//if (patfadd)
// srcd1 = wdata;
*/
//NOTE: There seems to be an off-by-one bug here in the clip_a1 section... !!! FIX !!!
// Actually, seems to be related to phrase mode writes...
+// Or is it? Could be related to non-15-bit compares as above?
if (clip_a1 && ((a1_x & 0x8000) || (a1_y & 0x8000) || (a1_x >= a1_win_x) || (a1_y >= a1_win_y)))
winhibit = true;
-/*if (dcompen)
-{
-//This is currently not correct for phrase mode. !!! FIX !!!
- if ((pixsize == 3 && (dcomp & 0x01))
- || (pixsize == 4 && (dcomp & 0x03)))
- winhibit = true;
-}*/
-
if (!winhibit)
{
if (phrase_mode)
else
JaguarWriteByte(address, wdata & 0x000000FF, BLITTER);
}
+}
#ifdef VERBOSE_BLITTER_LOGGING
if (logBlit)
{
- printf(" [%08X%08X]", (uint32)(wdata >> 32), (uint32)(wdata & 0xFFFFFFFF));
+ printf(" [%08X%08X]%s", (uint32)(wdata >> 32), (uint32)(wdata & 0xFFFFFFFF), (winhibit ? "[X]" : ""));
+ printf(" (icount=%04X, inc=%u)\n", icount, (uint16)inc);
+ printf(" [dstart=%X dend=%X pwidth=%X srcshift=%X]", dstart, dend, pwidth, srcshift);
+ printf("[daas=%X dabs=%X dam=%X ds=%X daq=%s]\n", daddasel, daddbsel, daddmode, data_sel, (daddq_sel ? "T" : "F"));
fflush(stdout);
}
#endif
-}
+ }
+ if (dzwrite)
+ {
+// OK, here's the big insight: When NOT in GOURZ mode, srcz1 & 2 function EXACTLY the same way that
+// srcd1 & 2 work--there's an implicit shift from srcz1 to srcz2 whenever srcz1 is read.
+// OTHERWISE, srcz1 is the integer for the computed Z and srcz2 is the fractional part.
+// Writes to srcz1 & 2 follow the same pattern as the other 64-bit registers--low 32 at the low address,
+// high 32 at the high address (little endian!).
+// NOTE: GOURZ is still not properly supported. Check patd/patf handling...
+// Phrase mode start/end masks are not properly supported either...
#ifdef VERBOSE_BLITTER_LOGGING
if (logBlit)
{
-printf(" (icount=%04X, inc=%u)\n", icount, (uint16)inc);
-fflush(stdout);
+ printf(" Entering DZWRITE state...");
+ printf(" Dest Z write address/pix address: %08X/%1X [%08X%08X]\n", address, pixAddr,
+ (uint32)(srcz >> 32), (uint32)(srcz & 0xFFFFFFFF));
+ fflush(stdout);
}
#endif
- }
-
- if (dzwrite)
- {
+//This is not correct... !!! FIX !!!
+//Should be OK now... We'll see...
+//Nope. Having the same starstep write problems in phrase mode as we had with pixels... !!! FIX !!!
+//This is not causing the problem in Hover Strike... :-/
+//The problem was with the SREADX not shifting. Still problems with Z comparisons & other text in pregame screen...
+if (!winhibit)
+{
+ if (phrase_mode)
+ {
+ JaguarWriteLong(address + 0, srcz >> 32, BLITTER);
+ JaguarWriteLong(address + 4, srcz & 0xFFFFFFFF, BLITTER);
+ }
+ else
+ {
+ if (pixsize == 4)
+ JaguarWriteWord(address, srcz & 0x0000FFFF, BLITTER);
+ }
+}//*/
#ifdef VERBOSE_BLITTER_LOGGING
if (logBlit)
{
-printf(" Entering DZWRITE state...\n");
-fflush(stdout);
+// printf(" [%08X%08X]\n", (uint32)(srcz >> 32), (uint32)(srcz & 0xFFFFFFFF));
+// fflush(stdout);
+//printf(" [dstart=%X dend=%X pwidth=%X srcshift=%X]", dstart, dend, pwidth, srcshift);
+ printf(" [dstart=? dend=? pwidth=? srcshift=%X]", srcshift);
+ printf("[daas=%X dabs=%X dam=%X ds=%X daq=%s]\n", daddasel, daddbsel, daddmode, data_sel, (daddq_sel ? "T" : "F"));
+ fflush(stdout);
}
#endif
}
+/*
+This is because the address generator was using only 15 bits of the X when it should have
+used 16!
+
+There's a slight problem here: The X pointer isn't wrapping like it should when it hits
+the edge of the window... Notice how the X isn't reset at the edge of the window:
+
+Blit! (CMD = 00010000)
+Flags: PATDSEL
+ count = 160 x 261
+ a1_base = 000E8008, a2_base = 0001FA68
+ a1_x = 0000, a1_y = 0000, a1_frac_x = 0000, a1_frac_y = 0000, a2_x = 0000, a2_y = 0000
+ a1_step_x = 0000, a1_step_y = 0000, a1_stepf_x = 0000, a1_stepf_y = 0000, a2_step_x = 0000, a2_step_y = 0000
+ a1_inc_x = 0000, a1_inc_y = 0000, a1_incf_x = 0000, a1_incf_y = 0000
+ a1_win_x = 0000, a1_win_y = 0000, a2_mask_x = 0000, a2_mask_y = 0000
+ a2_mask=F a1add=+phr/+0 a2add=+phr/+0
+ a1_pixsize = 5, a2_pixsize = 5
+ srcd=7717771777177717 dstd=0000000000000000 patd=7730773077307730 iinc=00000000
+ srcz1=0000000000000000 srcz2=0000000000000000 dstz=0000000000000000 zinc=00000000, coll=0
+ Phrase mode is ON
+ [in=T a1f=F a1=F zf=F z=F a2=F iif=F iii=F izf=F izi=F]
+ Entering INNER state...
+ Entering DWRITE state... Dest write address/pix address: 000E8008/0 [7730773077307730] (icount=009E, inc=2)
+ srcz=0000000000000000][dcomp=AA zcomp=00 dbinh=00]
+[srcz=0000000000000000 dstz=0000000000000000 zwdata=0000000000000000 mask=7FFF]
+ [dstart=0 dend=40 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=0 daq=F]
+ Entering A1_ADD state [a1_x=0000, a1_y=0000, addasel=0, addbsel=0, modx=1, addareg=F, adda_xconst=1, adda_yconst=0]...
+ Entering DWRITE state... Dest write address/pix address: 000E8018/0 [7730773077307730] (icount=009C, inc=2)
+ srcz=0000000000000000][dcomp=AA zcomp=00 dbinh=00]
+[srcz=0000000000000000 dstz=0000000000000000 zwdata=0000000000000000 mask=7FFF]
+ [dstart=0 dend=40 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=0 daq=F]
+ Entering A1_ADD state [a1_x=0002, a1_y=0000, addasel=0, addbsel=0, modx=1, addareg=F, adda_xconst=1, adda_yconst=0]...
+
+...
+
+ Entering A1_ADD state [a1_x=009C, a1_y=0000, addasel=0, addbsel=0, modx=1, addareg=F, adda_xconst=1, adda_yconst=0]...
+ Entering DWRITE state... Dest write address/pix address: 000E84F8/0 [7730773077307730] (icount=0000, inc=2)
+ srcz=0000000000000000][dcomp=AA zcomp=00 dbinh=00]
+[srcz=0000000000000000 dstz=0000000000000000 zwdata=0000000000000000 mask=7FFF]
+ [dstart=0 dend=40 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=0 daq=F]
+ Entering A1_ADD state [a1_x=009E, a1_y=0000, addasel=0, addbsel=0, modx=1, addareg=F, adda_xconst=1, adda_yconst=0]...
+ Entering IDLE_INNER state...
+
+ Leaving INNER state... (ocount=0104)
+ [in=T a1f=F a1=F zf=F z=F a2=F iif=F iii=F izf=F izi=F]
+
+ Entering INNER state...
+ Entering DWRITE state... Dest write address/pix address: 000E8508/0 [7730773077307730] (icount=009E, inc=2)
+ srcz=0000000000000000][dcomp=AA zcomp=00 dbinh=00]
+[srcz=0000000000000000 dstz=0000000000000000 zwdata=0000000000000000 mask=7FFF]
+ [dstart=0 dend=40 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=0 daq=F]
+ Entering A1_ADD state [a1_x=00A0, a1_y=0000, addasel=0, addbsel=0, modx=1, addareg=F, adda_xconst=1, adda_yconst=0]...
+ Entering DWRITE state... Dest write address/pix address: 000E8518/0 [7730773077307730] (icount=009C, inc=2)
+ srcz=0000000000000000][dcomp=AA zcomp=00 dbinh=00]
+[srcz=0000000000000000 dstz=0000000000000000 zwdata=0000000000000000 mask=7FFF]
+ [dstart=0 dend=40 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=0 daq=F]
+ Entering A1_ADD state [a1_x=00A2, a1_y=0000, addasel=0, addbsel=0, modx=1, addareg=F, adda_xconst=1, adda_yconst=0]...
+
+*/
+
if (a1_add)
{
#ifdef VERBOSE_BLITTER_LOGGING
//Since we don't get here until the inner loop is finished (indone = true) we can get
//away with doing it here...!
ocount--;
-
+
if (ocount == 0)
outer0 = true;
#ifdef VERBOSE_BLITTER_LOGGING
}
#endif
}
-
+
if (a2update)
{
#ifdef VERBOSE_BLITTER_LOGGING
}
}
+// We never get here! !!! FIX !!!
+
+#ifdef VERBOSE_BLITTER_LOGGING
+if (logBlit)
+{
+ printf("Done!\na1_x=%04X a1_y=%04X a1_frac_x=%04X a1_frac_y=%04X a2_x=%04X a2_y%04X\n",
+ GET16(blitter_ram, A1_PIXEL + 2),
+ GET16(blitter_ram, A1_PIXEL + 0),
+ GET16(blitter_ram, A1_FPIXEL + 2),
+ GET16(blitter_ram, A1_FPIXEL + 0),
+ GET16(blitter_ram, A2_PIXEL + 2),
+ GET16(blitter_ram, A2_PIXEL + 0));
+ fflush(stdout);
+}
+#endif
+
// Write values back to registers (in real blitter, these are continuously updated)
- SET16(blitter_ram, A1_PIXEL + 0, a1_y);
SET16(blitter_ram, A1_PIXEL + 2, a1_x);
- SET16(blitter_ram, A1_FPIXEL + 0, a1_frac_y);
+ SET16(blitter_ram, A1_PIXEL + 0, a1_y);
SET16(blitter_ram, A1_FPIXEL + 2, a1_frac_x);
- SET16(blitter_ram, A2_PIXEL + 0, a2_y);
+ SET16(blitter_ram, A1_FPIXEL + 0, a1_frac_y);
SET16(blitter_ram, A2_PIXEL + 2, a2_x);
-}
+ SET16(blitter_ram, A2_PIXEL + 0, a2_y);
+#ifdef VERBOSE_BLITTER_LOGGING
+if (logBlit)
+{
+ printf("Writeback!\na1_x=%04X a1_y=%04X a1_frac_x=%04X a1_frac_y=%04X a2_x=%04X a2_y%04X\n",
+ GET16(blitter_ram, A1_PIXEL + 2),
+ GET16(blitter_ram, A1_PIXEL + 0),
+ GET16(blitter_ram, A1_FPIXEL + 2),
+ GET16(blitter_ram, A1_FPIXEL + 0),
+ GET16(blitter_ram, A2_PIXEL + 2),
+ GET16(blitter_ram, A2_PIXEL + 0));
+ fflush(stdout);
+}
+#endif
+}
/*
-The latest that doesn't work properly:
-
-Blit! (CMD = 09800741)
-Flags: SRCEN CLIP_A1 UPDA1 UPDA1F UPDA2 LFUFUNC=C DCOMPEN
- count = 15 x 18
- a1_base = 00050000, a2_base = 0083F400
- a1_x = 003D, a1_y = 00AD, a1_frac_x = 8000, a1_frac_y = 0000, a2_x = 0027, a2_y = 00A4
- a1_step_x = FFF1, a1_step_y = 0001, a1_stepf_x = 0000, a1_stepf_y = 0000, a2_step_x = FFF1, a2_step_y = 0001
- a1_inc_x = 0001, a1_inc_y = 0000, a1_incf_x = 0000, a1_incf_y = 0000
- a1_win_x = 0180, a1_win_y = 0118, a2_mask_x = 0000, a2_mask_y = 0000
- a2_mask=F a1add=+inc/+0 a2add=+1/+0
- a1_pixsize = 4, a2_pixsize = 4
- srcd=0000000000000000 dstd=0000000000000000 patd=0000000000000000 iinc=00FFF000
- srcz1=0000000000000000 srcz2=0000000000000000 dstz=0000000000000000 zinc=00000000, col=2
- Phrase mode is off
- [in=T a1f=F a1=F zf=F z=F a2=F iif=F iii=F izf=F izi=F]
- Entering INNER state...
- Entering SREAD state... Source read address/pix address: 00858E4E/0 [0000000000000000]
- Entering A2_ADD state [a2_x=0027, a2_y=00A4, addasel=0, addbsel=1, modx=0, addareg=F, adda_xconst=0, adda_yconst=0]...
- Entering DWRITE state...
- Dest write address/pix address: 0007077A/0 [dstart=0 dend=10 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=1 daq=F] [0000000000000000] (icount=000E, inc=1)
- Entering A1_ADD state [a1_x=003D, a1_y=00AD, addasel=3, addbsel=2, modx=0, addareg=T, adda_xconst=7, adda_yconst=0]...
- Entering SREAD state... Source read address/pix address: 00858E50/0 [0000000000000000]
- Entering A2_ADD state [a2_x=0028, a2_y=00A4, addasel=0, addbsel=1, modx=0, addareg=F, adda_xconst=0, adda_yconst=0]...
- Entering DWRITE state...
- Dest write address/pix address: 0007077C/0 [dstart=0 dend=10 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=1 daq=F] [0000000000000000] (icount=000D, inc=1)
- Entering A1_ADD state [a1_x=003E, a1_y=00AD, addasel=3, addbsel=2, modx=0, addareg=T, adda_xconst=7, adda_yconst=0]...
- Entering SREAD state... Source read address/pix address: 00858E52/0 [0000000000000000]
- Entering A2_ADD state [a2_x=0029, a2_y=00A4, addasel=0, addbsel=1, modx=0, addareg=F, adda_xconst=0, adda_yconst=0]...
- Entering DWRITE state...
- Dest write address/pix address: 0007077E/0 [dstart=0 dend=10 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=1 daq=F] [0000000000000000] (icount=000C, inc=1)
- Entering A1_ADD state [a1_x=003F, a1_y=00AD, addasel=3, addbsel=2, modx=0, addareg=T, adda_xconst=7, adda_yconst=0]...
- Entering SREAD state... Source read address/pix address: 00858E54/0 [000000000000014A]
- Entering A2_ADD state [a2_x=002A, a2_y=00A4, addasel=0, addbsel=1, modx=0, addareg=F, adda_xconst=0, adda_yconst=0]...
- Entering DWRITE state...
- Dest write address/pix address: 00070780/0 [dstart=0 dend=10 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=1 daq=F] [000000000000014A] (icount=000B, inc=1)
- Entering A1_ADD state [a1_x=0040, a1_y=00AD, addasel=3, addbsel=2, modx=0, addareg=T, adda_xconst=7, adda_yconst=0]...
- Entering SREAD state... Source read address/pix address: 00858E56/0 [000000000000014A]
- Entering A2_ADD state [a2_x=002B, a2_y=00A4, addasel=0, addbsel=1, modx=0, addareg=F, adda_xconst=0, adda_yconst=0]...
- Entering DWRITE state...
- Dest write address/pix address: 00070782/0 [dstart=0 dend=10 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=1 daq=F] [000000000000014A] (icount=000A, inc=1)
- Entering A1_ADD state [a1_x=0041, a1_y=00AD, addasel=3, addbsel=2, modx=0, addareg=T, adda_xconst=7, adda_yconst=0]...
- Entering SREAD state... Source read address/pix address: 00858E58/0 [000000000000014A]
- Entering A2_ADD state [a2_x=002C, a2_y=00A4, addasel=0, addbsel=1, modx=0, addareg=F, adda_xconst=0, adda_yconst=0]...
- Entering DWRITE state...
- Dest write address/pix address: 00070784/0 [dstart=0 dend=10 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=1 daq=F] [000000000000014A] (icount=0009, inc=1)
- Entering A1_ADD state [a1_x=0042, a1_y=00AD, addasel=3, addbsel=2, modx=0, addareg=T, adda_xconst=7, adda_yconst=0]...
- Entering SREAD state... Source read address/pix address: 00858E5A/0 [000000000000014A]
- Entering A2_ADD state [a2_x=002D, a2_y=00A4, addasel=0, addbsel=1, modx=0, addareg=F, adda_xconst=0, adda_yconst=0]...
- Entering DWRITE state...
- Dest write address/pix address: 00070786/0 [dstart=0 dend=10 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=1 daq=F] [000000000000014A] (icount=0008, inc=1)
- Entering A1_ADD state [a1_x=0043, a1_y=00AD, addasel=3, addbsel=2, modx=0, addareg=T, adda_xconst=7, adda_yconst=0]...
- Entering SREAD state... Source read address/pix address: 00858E5C/0 [000000000000014A]
- Entering A2_ADD state [a2_x=002E, a2_y=00A4, addasel=0, addbsel=1, modx=0, addareg=F, adda_xconst=0, adda_yconst=0]...
- Entering DWRITE state...
- Dest write address/pix address: 00070788/0 [dstart=0 dend=10 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=1 daq=F] [000000000000014A] (icount=0007, inc=1)
- Entering A1_ADD state [a1_x=0044, a1_y=00AD, addasel=3, addbsel=2, modx=0, addareg=T, adda_xconst=7, adda_yconst=0]...
- Entering SREAD state... Source read address/pix address: 00858E5E/0 [000000000000014A]
- Entering A2_ADD state [a2_x=002F, a2_y=00A4, addasel=0, addbsel=1, modx=0, addareg=F, adda_xconst=0, adda_yconst=0]...
- Entering DWRITE state...
- Dest write address/pix address: 0007078A/0 [dstart=0 dend=10 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=1 daq=F] [000000000000014A] (icount=0006, inc=1)
- Entering A1_ADD state [a1_x=0045, a1_y=00AD, addasel=3, addbsel=2, modx=0, addareg=T, adda_xconst=7, adda_yconst=0]...
- Entering SREAD state... Source read address/pix address: 00858E60/0 [000000000000014A]
- Entering A2_ADD state [a2_x=0030, a2_y=00A4, addasel=0, addbsel=1, modx=0, addareg=F, adda_xconst=0, adda_yconst=0]...
- Entering DWRITE state...
- Dest write address/pix address: 0007078C/0 [dstart=0 dend=10 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=1 daq=F] [000000000000014A] (icount=0005, inc=1)
- Entering A1_ADD state [a1_x=0046, a1_y=00AD, addasel=3, addbsel=2, modx=0, addareg=T, adda_xconst=7, adda_yconst=0]...
- Entering SREAD state... Source read address/pix address: 00858E62/0 [000000000000014A]
- Entering A2_ADD state [a2_x=0031, a2_y=00A4, addasel=0, addbsel=1, modx=0, addareg=F, adda_xconst=0, adda_yconst=0]...
- Entering DWRITE state...
- Dest write address/pix address: 0007078E/0 [dstart=0 dend=10 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=1 daq=F] [000000000000014A] (icount=0004, inc=1)
- Entering A1_ADD state [a1_x=0047, a1_y=00AD, addasel=3, addbsel=2, modx=0, addareg=T, adda_xconst=7, adda_yconst=0]...
- Entering SREAD state... Source read address/pix address: 00858E64/0 [000000000000014A]
- Entering A2_ADD state [a2_x=0032, a2_y=00A4, addasel=0, addbsel=1, modx=0, addareg=F, adda_xconst=0, adda_yconst=0]...
- Entering DWRITE state...
- Dest write address/pix address: 00070790/0 [dstart=0 dend=10 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=1 daq=F] [000000000000014A] (icount=0003, inc=1)
- Entering A1_ADD state [a1_x=0048, a1_y=00AD, addasel=3, addbsel=2, modx=0, addareg=T, adda_xconst=7, adda_yconst=0]...
- Entering SREAD state... Source read address/pix address: 00858E66/0 [0000000000000000]
- Entering A2_ADD state [a2_x=0033, a2_y=00A4, addasel=0, addbsel=1, modx=0, addareg=F, adda_xconst=0, adda_yconst=0]...
- Entering DWRITE state...
- Dest write address/pix address: 00070792/0 [dstart=0 dend=10 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=1 daq=F] [0000000000000000] (icount=0002, inc=1)
- Entering A1_ADD state [a1_x=0049, a1_y=00AD, addasel=3, addbsel=2, modx=0, addareg=T, adda_xconst=7, adda_yconst=0]...
- Entering SREAD state... Source read address/pix address: 00858E68/0 [0000000000000000]
- Entering A2_ADD state [a2_x=0034, a2_y=00A4, addasel=0, addbsel=1, modx=0, addareg=F, adda_xconst=0, adda_yconst=0]...
- Entering DWRITE state...
- Dest write address/pix address: 00070794/0 [dstart=0 dend=10 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=1 daq=F] [0000000000000000] (icount=0001, inc=1)
- Entering A1_ADD state [a1_x=004A, a1_y=00AD, addasel=3, addbsel=2, modx=0, addareg=T, adda_xconst=7, adda_yconst=0]...
- Entering SREAD state... Source read address/pix address: 00858E6A/0 [0000000000000000]
- Entering A2_ADD state [a2_x=0035, a2_y=00A4, addasel=0, addbsel=1, modx=0, addareg=F, adda_xconst=0, adda_yconst=0]...
- Entering DWRITE state...
- Dest write address/pix address: 00070796/0 [dstart=0 dend=10 pwidth=8 srcshift=0][daas=0 dabs=0 dam=7 ds=1 daq=F] [0000000000000000] (icount=0000, inc=1)
- Entering A1_ADD state [a1_x=004B, a1_y=00AD, addasel=3, addbsel=2, modx=0, addareg=T, adda_xconst=7, adda_yconst=0]...
- Entering IDLE_INNER state...
- Leaving INNER state... (ocount=0011)
- [in=F a1f=T a1=F zf=F z=F a2=F iif=F iii=F izf=F izi=F]
- Entering A1FUPDATE state...
- [in=F a1f=F a1=T zf=F z=F a2=F iif=F iii=F izf=F izi=F]
- Entering A1UPDATE state... (76/173 -> 61/174)
- [in=F a1f=F a1=F zf=F z=F a2=T iif=F iii=F izf=F izi=F]
- Entering A2UPDATE state... (54/164 -> 39/165)
- [in=T a1f=F a1=F zf=F z=F a2=F iif=F iii=F izf=F izi=F]
- Entering INNER state...
+ int16 a1_x = (int16)GET16(blitter_ram, A1_PIXEL + 2);
+ int16 a1_y = (int16)GET16(blitter_ram, A1_PIXEL + 0);
+ uint16 a1_frac_x = GET16(blitter_ram, A1_FPIXEL + 2);
+ uint16 a1_frac_y = GET16(blitter_ram, A1_FPIXEL + 0);
+ int16 a2_x = (int16)GET16(blitter_ram, A2_PIXEL + 2);
+ int16 a2_y = (int16)GET16(blitter_ram, A2_PIXEL + 0);
+
+Seems that the ending a1_x should be written between blits, but it doesn't seem to be...
+
+Blit! (CMD = 01800000)
+Flags: LFUFUNC=C
+ count = 28672 x 1
+ a1_base = 00050000, a2_base = 00070000
+ a1_x = 0000, a1_y = 0000, a1_frac_x = 49CD, a1_frac_y = 0000, a2_x = 0033, a2_y = 0001
+ a1_step_x = 0000, a1_step_y = 0000, a1_stepf_x = 939A, a1_stepf_y = 0000, a2_step_x = 0000, a2_step_y = 0000
+ a1_inc_x = 0000, a1_inc_y = 0000, a1_incf_x = 0000, a1_incf_y = 0000
+ a1_win_x = 0100, a1_win_y = 0020, a2_mask_x = 0000, a2_mask_y = 0000
+ a2_mask=F a1add=+phr/+0 a2add=+phr/+0
+ a1_pixsize = 4, a2_pixsize = 3
+ srcd=DEDEDEDEDEDEDEDE dstd=0000000000000000 patd=0000000000000000 iinc=00000000
+ srcz1=0000000000000000 srcz2=0000000000000000 dstz=0000000000000000 zinc=00000000, coll=0
+ Phrase mode is ON
+
+Blit! (CMD = 01800000)
+Flags: LFUFUNC=C
+ count = 28672 x 1
+ a1_base = 00050000, a2_base = 00070000
+ a1_x = 0000, a1_y = 0000, a1_frac_x = 49CD, a1_frac_y = 0000, a2_x = 0033, a2_y = 0001
+ a1_step_x = 0000, a1_step_y = 0000, a1_stepf_x = 939A, a1_stepf_y = 0000, a2_step_x = 0000, a2_step_y = 0000
+ a1_inc_x = 0000, a1_inc_y = 0000, a1_incf_x = 0000, a1_incf_y = 0000
+ a1_win_x = 0100, a1_win_y = 0020, a2_mask_x = 0000, a2_mask_y = 0000
+ a2_mask=F a1add=+phr/+0 a2add=+phr/+0
+ a1_pixsize = 4, a2_pixsize = 3
+ srcd=D6D6D6D6D6D6D6D6 dstd=0000000000000000 patd=0000000000000000 iinc=00000000
+ srcz1=0000000000000000 srcz2=0000000000000000 dstz=0000000000000000 zinc=00000000, coll=0
+ Phrase mode is ON
*/
+
// Various pieces of the blitter puzzle are teased out here...
uint16 a1_x, uint16 a1_y, uint32 a1_base, uint8 a1_pitch, uint8 a1_pixsize, uint8 a1_width, uint8 a1_zoffset,
uint16 a2_x, uint16 a2_y, uint32 a2_base, uint8 a2_pitch, uint8 a2_pixsize, uint8 a2_width, uint8 a2_zoffset)
{
- uint16 x = (gena2 ? a2_x : a1_x) & 0x7FFF;
+// uint16 x = (gena2 ? a2_x : a1_x) & 0x7FFF;
+ uint16 x = (gena2 ? a2_x : a1_x) & 0xFFFF; // Actually uses all 16 bits to generate address...!
uint16 y = (gena2 ? a2_y : a1_y) & 0x0FFF;
uint8 width = (gena2 ? a2_width : a1_width);
uint8 pixsize = (gena2 ? a2_pixsize : a1_pixsize);
*/
void ADD16SAT(uint16 &r, uint8 &co, uint16 a, uint16 b, uint8 cin, bool sat, bool eightbit, bool hicinh)
{
+/*if (logBlit)
+{
+ printf("--> [sat=%s 8b=%s hicinh=%s] %04X + %04X (+ %u) = ", (sat ? "T" : "F"), (eightbit ? "T" : "F"), (hicinh ? "T" : "F"), a, b, cin);
+ fflush(stdout);
+}*/
uint8 carry[4];
uint32 qt = (a & 0xFF) + (b & 0xFF) + cin;
carry[0] = (qt & 0x0100 ? 1 : 0);
bool saturate = sat && (btop ^ ctop);
bool hisaturate = saturate && !eightbit;
+/*if (logBlit)
+{
+ printf("bt=%u ct=%u s=%u hs=%u] ", btop, ctop, saturate, hisaturate);
+ fflush(stdout);
+}*/
r = (saturate ? (ctop ? 0x00FF : 0x0000) : q & 0x00FF);
r |= (hisaturate ? (ctop ? 0xFF00 : 0x0000) : q & 0xFF00);
+/*if (logBlit)
+{
+ printf("%04X (co=%u)\n", r, co);
+ fflush(stdout);
+}*/
}
/** ADDAMUX - Address adder input A selection *******************
adda_xconst[0..2] generate a power of 2 in the range 1-64 or all zeroes when
they are all 1.
-addareg selects register value to be added as opposed to constant
+addareg selects register value to be added as opposed to constant
value.
suba_x, suba_y complement the X and Y values
bool adda_yconst, bool addareg, bool suba_x, bool suba_y)
{
-/*INT16/ addac_x, addac_y, addar_x, addar_y, addart_x, addart_y,
+/*INT16/ addac_x, addac_y, addar_x, addar_y, addart_x, addart_y,
INT16/ addas_x, addas_y, suba_x16, suba_y16
:LOCAL;
BEGIN
int16 addar_y = (addasel & 0x04 ? a2_step_y : yterm[addasel & 0x03]);
//////////////////////////////////////////////////////////////////////////////////////
-/* Generate a constant value - this is a power of 2 in the range
+/* Generate a constant value - this is a power of 2 in the range
0-64, or zero. The control bits are adda_xconst[0..2], when they
are all 1 the result is 0.
Constants for Y can only be 0 or 1 */
Unused[0] := DUMMY (unused[0]);
Addac_x := JOIN (addac_x, addac_x[0..6], zero, zero, zero, zero, zero, zero, zero, zero, zero);
-Addac_y := JOIN (addac_y, adda_yconst, zero, zero, zero, zero, zero, zero, zero, zero, zero, zero,
+Addac_y := JOIN (addac_y, adda_yconst, zero, zero, zero, zero, zero, zero, zero, zero, zero, zero,
zero, zero, zero, zero, zero);*/
////////////////////////////////////// C++ CODE //////////////////////////////////////
int16 addac_x = (adda_xconst == 0x07 ? 0 : 1 << adda_xconst);
/* Complement these values (complement flag gives adder carry in)*/
-/*Suba_x16 := JOIN (suba_x16, suba_x, suba_x, suba_x, suba_x, suba_x, suba_x, suba_x, suba_x, suba_x,
+/*Suba_x16 := JOIN (suba_x16, suba_x, suba_x, suba_x, suba_x, suba_x, suba_x, suba_x, suba_x, suba_x,
suba_x, suba_x, suba_x, suba_x, suba_x, suba_x, suba_x);
-Suba_y16 := JOIN (suba_y16, suba_y, suba_y, suba_y, suba_y, suba_y, suba_y, suba_y, suba_y, suba_y,
+Suba_y16 := JOIN (suba_y16, suba_y, suba_y, suba_y, suba_y, suba_y, suba_y, suba_y, suba_y, suba_y,
suba_y, suba_y, suba_y, suba_y, suba_y, suba_y, suba_y);
Adda_x := EO (adda_x, suba_x16, addas_x);
Adda_y := EO (adda_y, suba_y16, addas_y);*/
/** ADDBMUX - Address adder input B selection *******************
-This module selects the register to be updated by the address
-adder. This can be one of three registers, the A1 and A2
-pointers, or the A1 fractional part. It can also be zero, so that the step
+This module selects the register to be updated by the address
+adder. This can be one of three registers, the A1 and A2
+pointers, or the A1 fractional part. It can also be zero, so that the step
registers load directly into the pointers.
*/
{
/*Zero := TIE0 (zero);
-Zero16 := JOIN (zero16, zero, zero, zero, zero, zero, zero, zero,
+Zero16 := JOIN (zero16, zero, zero, zero, zero, zero, zero, zero,
zero, zero, zero, zero, zero, zero, zero, zero, zero);
Addbselb[0-1] := BUF8 (addbselb[0-1], addbsel[0-1]);
Addb_x := MX4 (addb_x, a1_x, a2_x, a1_frac_x, zero16, addbselb[0..1]);
Blitter Address Adder
---------------------
-The blitter address adder is a pair of sixteen bit adders, one
-each for X and Y. The multiplexing of the input terms is
-performed elsewhere, but this adder can also perform modulo
-arithmetic to align X-addresses onto phrase boundaries.
+The blitter address adder is a pair of sixteen bit adders, one
+each for X and Y. The multiplexing of the input terms is
+performed elsewhere, but this adder can also perform modulo
+arithmetic to align X-addresses onto phrase boundaries.
modx[0..2] take values
000 no mask
modx[0..2]
suba_x
suba_y
- :IN);
+ :IN);
BEGIN
dcomp[0..7] // data byte equal flags
srcd[0..7] // bits to use for bit to byte expansion
zcomp[0..3] // output from Z comparators
- :OUT;
+ :OUT;
a1_x[0..1] // low two bits of A1 X pointer
big_pix // pixel organisation is big-endian
blitter_active // blitter is active
void DATA(uint64 &wdata, uint8 &dcomp, uint8 &zcomp, bool &nowrite,
bool big_pix, bool cmpdst, uint8 daddasel, uint8 daddbsel, uint8 daddmode, bool daddq_sel, uint8 data_sel,
- uint8 dbinh, uint8 dend, uint8 dstart, uint64 dstd, uint32 iinc, uint8 lfu_func, uint64 patd, bool patdadd,
+ uint8 dbinh, uint8 dend, uint8 dstart, uint64 dstd, uint32 iinc, uint8 lfu_func, uint64 &patd, bool patdadd,
bool phrase_mode, uint64 srcd, bool srcdread, bool srczread, bool srcz2add, uint8 zmode,
- bool bcompen, bool bkgwren, bool dcompen, uint8 icount, uint8 pixsize)
+ bool bcompen, bool bkgwren, bool dcompen, uint8 icount, uint8 pixsize,
+ uint64 &srcz, uint64 dstz, uint32 zinc)
{
/*
Stuff we absolutely *need* to have passed in/out:
IN:
patdadd, dstd, srcd, patd, daddasel, daddbsel, daddmode, iinc, srcz1, srcz2, big_pix, phrase_mode, cmpdst
OUT:
- changed patd (wdata I guess...)
+ changed patd (wdata I guess...) (Nope. We pass it back directly now...)
*/
// Source data registers
Srcd[8-31] := JOIN (srcd[8-31], srcdlo{8-31});
Srcd[32-63] := JOIN (srcd[32-63], srcdhi{0-31});*/
-// Destination data registers
+// Destination data registers
/*Data_dst := DATA_DST (dstd[0..63], dstz[0..1], clk, dstdld[0..1], dstzld[0..1], load_data[0..1]);
Dstdlo := JOIN (dstdlo, dstd[0..31]);
Dstdhi := JOIN (dstdhi, dstd[32..63]);*/
-// Pattern and Color data registers
+// Pattern and Color data registers
// Looks like this is simply another register file for the pattern data registers. No adding or anything funky
// going on. Note that patd & patdv will output the same info.
// Multiplying data Mixer (NOT IN JAGUAR I)
-/*Datamix := DATAMIX (patdo[0..1], clk, colord[0..15], dpipe[1], dstd[0..63], int0dp[8..10], int1dp[8..10],
+/*Datamix := DATAMIX (patdo[0..1], clk, colord[0..15], dpipe[1], dstd[0..63], int0dp[8..10], int1dp[8..10],
int2dp[8..10], int3dp[8..10], mixsel[0..2], patd[0..63], pdsel[0..1], srcd[0..63], textrgb, txtd[0..63]);*/
// Logic function unit
//////////////////////////////////////////////////////////////////////////////////////
// Increment and Step Registers
-
+
// Does it do anything without the step add lines? Check it!
// No. This is pretty much just a register file without the Jaguar II lines...
/*Inc_step := INC_STEP (iinc, istep[0..31], zinc, zstep[0..31], clk, ext_int, gpu_din, iincld, iincldx, istepadd,
dcomp |= 0x40;
if ((cmpd & 0xFF00000000000000LL) == 0)
dcomp |= 0x80;
+//////////////////////////////////////////////////////////////////////////////////////
+
+// Zed comparator for Z-buffer operations
+
+/*Zedcomp := ZEDCOMP (zcomp[0..3], srczp[0..1], dstz[0..1], zmode[0..2]);*/
+////////////////////////////////////// C++ CODE //////////////////////////////////////
+//srczp is srcz pipelined, also it goes through a source shift as well...
+/*The shift is basically like so (each piece is 16 bits long):
+
+ 0 1 2 3 4 5 6
+ srcz1lolo srcz1lohi srcz1hilo srcz1hihi srcrz2lolo srcz2lohi srcz2hilo
+
+with srcshift bits 4 & 5 selecting the start position
+*/
+//So... basically what we have here is:
+ zcomp = 0;
+
+ if ((((srcz & 0x000000000000FFFFLL) < (dstz & 0x000000000000FFFFLL)) && (zmode & 0x01))
+ || (((srcz & 0x000000000000FFFFLL) == (dstz & 0x000000000000FFFFLL)) && (zmode & 0x02))
+ || (((srcz & 0x000000000000FFFFLL) > (dstz & 0x000000000000FFFFLL)) && (zmode & 0x04)))
+ zcomp |= 0x01;
+
+ if ((((srcz & 0x00000000FFFF0000LL) < (dstz & 0x00000000FFFF0000LL)) && (zmode & 0x01))
+ || (((srcz & 0x00000000FFFF0000LL) == (dstz & 0x00000000FFFF0000LL)) && (zmode & 0x02))
+ || (((srcz & 0x00000000FFFF0000LL) > (dstz & 0x00000000FFFF0000LL)) && (zmode & 0x04)))
+ zcomp |= 0x02;
+
+ if ((((srcz & 0x0000FFFF00000000LL) < (dstz & 0x0000FFFF00000000LL)) && (zmode & 0x01))
+ || (((srcz & 0x0000FFFF00000000LL) == (dstz & 0x0000FFFF00000000LL)) && (zmode & 0x02))
+ || (((srcz & 0x0000FFFF00000000LL) > (dstz & 0x0000FFFF00000000LL)) && (zmode & 0x04)))
+ zcomp |= 0x04;
+
+ if ((((srcz & 0xFFFF000000000000LL) < (dstz & 0xFFFF000000000000LL)) && (zmode & 0x01))
+ || (((srcz & 0xFFFF000000000000LL) == (dstz & 0xFFFF000000000000LL)) && (zmode & 0x02))
+ || (((srcz & 0xFFFF000000000000LL) > (dstz & 0xFFFF000000000000LL)) && (zmode & 0x04)))
+ zcomp |= 0x08;
+
+//TEMP, TO TEST IF ZCOMP IS THE CULPRIT...
+//Nope, this is NOT the problem...
+//zcomp=0;
// We'll do the comparison/bit/byte inhibits here, since that's they way it happens
// in the real thing (dcomp goes out to COMP_CTRL and back into DATA through dbinh)...
#if 1
uint8 dbinht;
// bool nowrite;
COMP_CTRL(dbinht, nowrite,
- bcompen, true/*big_pix*/, bkgwren, dcomp, dcompen, icount, pixsize, phrase_mode, srcd & 0xFF, 0);//zcomp);
+ bcompen, true/*big_pix*/, bkgwren, dcomp, dcompen, icount, pixsize, phrase_mode, srcd & 0xFF, zcomp);
dbinh = dbinht;
// dbinh = 0x00;
#endif
-//////////////////////////////////////////////////////////////////////////////////////
-
-// Zed comparator for Z-buffer operations
-
-/*Zedcomp := ZEDCOMP (zcomp[0..3], srczp[0..1], dstz[0..1], zmode[0..2]);*/
-////////////////////////////////////// C++ CODE //////////////////////////////////////
+#if 1
+#ifdef VERBOSE_BLITTER_LOGGING
+if (logBlit)
+{
+ printf("\n[dcomp=%02X zcomp=%02X dbinh=%02X]\n", dcomp, zcomp, dbinh);
+ fflush(stdout);
+}//*/
+#endif
+#endif
//////////////////////////////////////////////////////////////////////////////////////
// 22 Mar 94
// The data initializer - allows all four initial values to be computed from one (NOT IN JAGUAR I)
-/*Datinit := DATINIT (initcin[0..3], initinc[0..63], initpix[0..15], a1_x[0..1], big_pix, clk, iinc, init_if, init_ii,
+/*Datinit := DATINIT (initcin[0..3], initinc[0..63], initpix[0..15], a1_x[0..1], big_pix, clk, iinc, init_if, init_ii,
init_zf, istep[0..31], zinc, zstep[0..31]);*/
// Adder array for Z and intensity increments
ADDARRAY(addq, daddasel, daddbsel, daddmode, dstd, iinc, initcin, 0, 0, 0, patd, srcd, 0, 0, 0, 0);
//This is normally done asynchronously above (thru local_data) when in patdadd mode...
+//And now it's passed back to the caller to be persistent between calls...!
+//But it's causing some serious fuck-ups in T2K now... !!! FIX !!! [DONE--???]
+//Weird! It doesn't anymore...!
if (patdadd)
patd = ((uint64)addq[3] << 48) | ((uint64)addq[2] << 32) | ((uint64)addq[1] << 16) | (uint64)addq[0];
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
/* The bit terms are mirrored for big-endian pixels outside phrase
-mode. The byte terms are mirrored for big-endian pixels in phrase
+mode. The byte terms are mirrored for big-endian pixels in phrase
mode. */
/*Mirror_bit := AN2M (mir_bit, phrase_mode\, big_pix);
wdata |= (mask & 0x1000 ? ddat : dstd) & 0x0000FF0000000000LL;
wdata |= (mask & 0x2000 ? ddat : dstd) & 0x00FF000000000000LL;
wdata |= (mask & 0x4000 ? ddat : dstd) & 0xFF00000000000000LL;
+/*if (logBlit)
+{
+ printf("\n[ddat=%08X%08X dstd=%08X%08X wdata=%08X%08X mask=%04X]\n",
+ (uint32)(ddat >> 32), (uint32)(ddat & 0xFFFFFFFF),
+ (uint32)(dstd >> 32), (uint32)(dstd & 0xFFFFFFFF),
+ (uint32)(wdata >> 32), (uint32)(wdata & 0xFFFFFFFF), mask);
+ fflush(stdout);
+}//*/
+//This is a crappy way of handling this, but it should work for now...
+ uint64 zwdata;
+ zwdata = ((srcz & mask) | (dstz & ~mask)) & 0x00000000000000FFLL;
+ zwdata |= (mask & 0x0100 ? srcz : dstz) & 0x000000000000FF00LL;
+ zwdata |= (mask & 0x0200 ? srcz : dstz) & 0x0000000000FF0000LL;
+ zwdata |= (mask & 0x0400 ? srcz : dstz) & 0x00000000FF000000LL;
+ zwdata |= (mask & 0x0800 ? srcz : dstz) & 0x000000FF00000000LL;
+ zwdata |= (mask & 0x1000 ? srcz : dstz) & 0x0000FF0000000000LL;
+ zwdata |= (mask & 0x2000 ? srcz : dstz) & 0x00FF000000000000LL;
+ zwdata |= (mask & 0x4000 ? srcz : dstz) & 0xFF00000000000000LL;
+if (logBlit)
+{
+ printf("\n[srcz=%08X%08X dstz=%08X%08X zwdata=%08X%08X mask=%04X]\n",
+ (uint32)(srcz >> 32), (uint32)(srcz & 0xFFFFFFFF),
+ (uint32)(dstz >> 32), (uint32)(dstz & 0xFFFFFFFF),
+ (uint32)(zwdata >> 32), (uint32)(zwdata & 0xFFFFFFFF), mask);
+ fflush(stdout);
+}//*/
+ srcz = zwdata;
//////////////////////////////////////////////////////////////////////////////////////
/*Data_enab[0-1] := BUF8 (data_enab[0-1], data_ena);
/** COMP_CTRL - Comparator output control logic *****************
This block is responsible for taking the comparator outputs and
-using them as appropriate to inhibit writes. Two methods are
+using them as appropriate to inhibit writes. Two methods are
supported for inhibiting write data:
- suppression of the inner loop controlled write operation
Writes can be suppressed by data being equal, by the Z comparator
conditions being met, or by the bit to pixel expansion scheme.
-Pipe-lining issues: the data derived comparator outputs are stable
+Pipe-lining issues: the data derived comparator outputs are stable
until the next data read, well after the affected write from this
operation. However, the inner counter bits can count immediately
-before the ack for the last write. Therefore, it is necessary to
+before the ack for the last write. Therefore, it is necessary to
delay bcompbit select terms by one inner loop pipe-line stage,
when generating the select for the data control - the output is
-delayed one further tick to give it write data timing (2/34).
+delayed one further tick to give it write data timing (2/34).
There is also a problem with computed data - the new values are
calculated before the write associated with the old value has been
only applicable to 8-bit pixel mode (2/34) */
/*Bcompselt[0-2] := EO (bcompselt[0-2], icount[0-2], big_pix);
-Bcompbit := MX8 (bcompbit, srcd[7], srcd[6], srcd[5],
+Bcompbit := MX8 (bcompbit, srcd[7], srcd[6], srcd[5],
srcd[4], srcd[3], srcd[2], srcd[1], srcd[0], bcompselt[0..2]);
Bcompbit\ := INV1 (bcompbit\, bcompbit);*/
////////////////////////////////////// C++ CODE //////////////////////////////////////
/* pipe-line the count */
/*Bcompsel[0-2] := FDSYNC (bcompsel[0-2], bcompselt[0-2], step_inner, clk);
-Bcompbt := MX8 (bcompbitpt, srcd[7], srcd[6], srcd[5],
+Bcompbt := MX8 (bcompbitpt, srcd[7], srcd[6], srcd[5],
srcd[4], srcd[3], srcd[2], srcd[1], srcd[0], bcompsel[0..2]);
Bcompbitp := FD1Q (bcompbitp, bcompbitpt, clk);
Bcompbitp\ := INV1 (bcompbitp\, bcompbitp);*/
/* For pixel mode, generate the write inhibit signal for all modes
on bit inhibit, for 8 and 16 bit modes on comparator inhibit, and
-for 16 bit mode on Z inhibit
+for 16 bit mode on Z inhibit
Nowrite = bcompen . /bcompbit . /phrase_mode
+ dcompen . dcomp[0] . /phrase_mode . pixsize = 011
//////////////////////////////////////////////////////////////////////////////////////
/* For phrase mode, generate the byte inhibit signals for eight bit
-mode 011, or sixteen bit mode 100
+mode 011, or sixteen bit mode 100
dbinh\[0] = pixsize[2] . zcomp[0]
+ pixsize[2] . dcomp[0] . dcomp[1] . dcompen
+ /pixsize[2] . dcomp[0] . dcompen
////////////////////////////////////// C++ CODE //////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
+// !!! TESTING !!! TESTING !!! TESTING !!! TESTING !!! TESTING !!! TESTING !!! TESTING !!!
+// !!! TESTING !!! TESTING !!! TESTING !!! TESTING !!! TESTING !!! TESTING !!! TESTING !!!
+// !!! TESTING !!! TESTING !!! TESTING !!! TESTING !!! TESTING !!! TESTING !!! TESTING !!!
+
#endif
+