diff --git a/src/blitter.c b/src/blitter.c index 12f8398..1090729 100644 --- a/src/blitter.c +++ b/src/blitter.c @@ -86,41 +86,41 @@ void BlitterMidsummer2(void); // Blitter command bits -#define SRCEN (cmd & 0x00000001) -#define SRCENZ (cmd & 0x00000002) -#define SRCENX (cmd & 0x00000004) -#define DSTEN (cmd & 0x00000008) -#define DSTENZ (cmd & 0x00000010) -#define DSTWRZ (cmd & 0x00000020) -#define CLIPA1 (cmd & 0x00000040) - -#define UPDA1F (cmd & 0x00000100) -#define UPDA1 (cmd & 0x00000200) -#define UPDA2 (cmd & 0x00000400) - -#define DSTA2 (cmd & 0x00000800) - -#define Z_OP_INF (cmd & 0x00040000) -#define Z_OP_EQU (cmd & 0x00080000) -#define Z_OP_SUP (cmd & 0x00100000) - -#define LFU_NAN (cmd & 0x00200000) -#define LFU_NA (cmd & 0x00400000) -#define LFU_AN (cmd & 0x00800000) -#define LFU_A (cmd & 0x01000000) - -#define CMPDST (cmd & 0x02000000) -#define BCOMPEN (cmd & 0x04000000) -#define DCOMPEN (cmd & 0x08000000) - -#define PATDSEL (cmd & 0x00010000) -#define ADDDSEL (cmd & 0x00020000) -#define TOPBEN (cmd & 0x00004000) -#define TOPNEN (cmd & 0x00008000) -#define BKGWREN (cmd & 0x10000000) -#define GOURD (cmd & 0x00001000) -#define GOURZ (cmd & 0x00002000) -#define SRCSHADE (cmd & 0x40000000) +#define SRCEN (cmd.bits.b0) +#define SRCENZ (cmd.bits.b1) +#define SRCENX (cmd.bits.b2) +#define DSTEN (cmd.bits.b3) +#define DSTENZ (cmd.bits.b4) +#define DSTWRZ (cmd.bits.b5) +#define CLIPA1 (cmd.bits.b6) + +#define UPDA1F (cmd.bits.b8) +#define UPDA1 (cmd.bits.b9) +#define UPDA2 (cmd.bits.b10) + +#define DSTA2 (cmd.bits.b11) + +#define Z_OP_INF (cmd.bits.b18) +#define Z_OP_EQU (cmd.bits.b19) +#define Z_OP_SUP (cmd.bits.b20) + +#define LFU_NAN (cmd.bits.b21) +#define LFU_NA (cmd.bits.b22) +#define LFU_AN (cmd.bits.b23) +#define LFU_A (cmd.bits.b24) + +#define CMPDST (cmd.bits.b25) +#define BCOMPEN (cmd.bits.b26) +#define DCOMPEN (cmd.bits.b27) + +#define PATDSEL (cmd.bits.b16) +#define ADDDSEL (cmd.bits.b17) +#define TOPBEN (cmd.bits.b14) +#define TOPNEN (cmd.bits.b15) +#define BKGWREN (cmd.bits.b28) +#define GOURD (cmd.bits.b12) +#define GOURZ (cmd.bits.b13) +#define SRCSHADE (cmd.bits.b30) #define XADDPHR 0 @@ -304,8 +304,11 @@ static int32_t a1_clip_x, a1_clip_y; // to optimize the blitter, then we may revisit it in the future... // Generic blit handler -void blitter_generic(uint32_t cmd) +void blitter_generic(uint32_t cmdi) { + Bits32 cmd; + cmd.WORD = cmdi; + uint32_t srcdata, srczdata, dstdata, dstzdata, writedata, inhibit; uint32_t bppSrc = (DSTA2 ? 1 << ((REG(A1_FLAGS) >> 3) & 0x07) : 1 << ((REG(A2_FLAGS) >> 3) & 0x07)); @@ -337,14 +340,14 @@ void blitter_generic(uint32_t cmd) if (SRCENZ) srczdata = READ_ZDATA(a2, REG(A2_FLAGS)); - else if (cmd & 0x0001C020) // PATDSEL | TOPBEN | TOPNEN | DSTWRZ + else if (cmd.WORD & 0x0001C020) // PATDSEL | TOPBEN | TOPNEN | DSTWRZ srczdata = READ_RDATA(SRCZINT, a2, REG(A2_FLAGS), a2_phrase_mode); } else // Use SRCDATA register... { srcdata = READ_RDATA(SRCDATA, a2, REG(A2_FLAGS), a2_phrase_mode); - if (cmd & 0x0001C020) // PATDSEL | TOPBEN | TOPNEN | DSTWRZ + if (cmd.WORD & 0x0001C020) // PATDSEL | TOPBEN | TOPNEN | DSTWRZ srczdata = READ_RDATA(SRCZINT, a2, REG(A2_FLAGS), a2_phrase_mode); } @@ -515,13 +518,13 @@ void blitter_generic(uint32_t cmd) srcdata = READ_PIXEL(a1, REG(A1_FLAGS)); if (SRCENZ) srczdata = READ_ZDATA(a1, REG(A1_FLAGS)); - else if (cmd & 0x0001C020) // PATDSEL | TOPBEN | TOPNEN | DSTWRZ + else if (cmd.WORD & 0x0001C020) // PATDSEL | TOPBEN | TOPNEN | DSTWRZ srczdata = READ_RDATA(SRCZINT, a1, REG(A1_FLAGS), a1_phrase_mode); } else { srcdata = READ_RDATA(SRCDATA, a1, REG(A1_FLAGS), a1_phrase_mode); - if (cmd & 0x001C020) // PATDSEL | TOPBEN | TOPNEN | DSTWRZ + if (cmd.WORD & 0x001C020) // PATDSEL | TOPBEN | TOPNEN | DSTWRZ srczdata = READ_RDATA(SRCZINT, a1, REG(A1_FLAGS), a1_phrase_mode); } @@ -755,20 +758,23 @@ void blitter_generic(uint32_t cmd) WREG(A2_PIXEL, (a2_y & 0xFFFF0000) | ((a2_x >> 16) & 0xFFFF)); } -void blitter_blit(uint32_t cmd) +void blitter_blit(uint32_t cmdi) { + Bits32 cmd; + cmd.WORD = cmdi; + uint32_t m, e; uint32_t pitchValue[4] = { 0, 1, 3, 2 }; colour_index = 0; - src = cmd & 0x07; - dst = (cmd >> 3) & 0x07; - misc = (cmd >> 6) & 0x03; - a1ctl = (cmd >> 8) & 0x7; - mode = (cmd >> 11) & 0x07; - ity = (cmd >> 14) & 0x0F; - zop = (cmd >> 18) & 0x07; - op = (cmd >> 21) & 0x0F; - ctrl = (cmd >> 25) & 0x3F; + src = cmd.WORD & 0x07; + dst = (cmd.WORD >> 3) & 0x07; + misc = (cmd.WORD >> 6) & 0x03; + a1ctl = (cmd.WORD >> 8) & 0x7; + mode = (cmd.WORD >> 11) & 0x07; + ity = (cmd.WORD >> 14) & 0x0F; + zop = (cmd.WORD >> 18) & 0x07; + op = (cmd.WORD >> 21) & 0x0F; + ctrl = (cmd.WORD >> 25) & 0x3F; // Addresses in A1/2_BASE are *phrase* aligned, i.e., bottom three bits are ignored! // NOTE: This fixes Rayman's bad collision detection AND keeps T2K working! @@ -951,7 +957,7 @@ void blitter_blit(uint32_t cmd) gd_ca = 0xFFFFFF00 | gd_ca; } - blitter_generic(cmd); + blitter_generic(cmd.WORD); } #endif /******************************************************************************* @@ -1112,10 +1118,11 @@ void BlitterWriteWord(uint32_t offset, uint16_t data, uint32_t who/*=UNKNOWN*/) // I.e., the second write of 32-bit value--not convinced this is the best way to do this! // But then again, according to the Jaguar docs, this is correct...! { - if (vjs.useFastBlitter) - blitter_blit(GET32(blitter_ram, 0x38)); - else - BlitterMidsummer2(); + if (vjs.useFastBlitter) { + blitter_blit(GET32(blitter_ram, 0x38)); + } else { + BlitterMidsummer2(); + } } } //F02278,9,A,B @@ -1134,10 +1141,10 @@ void BlitterWriteLong(uint32_t offset, uint32_t data, uint32_t who) void ADDRGEN(uint32_t *, uint32_t *, bool, bool, uint16_t, uint16_t, uint32_t, uint8_t, uint8_t, uint8_t, uint8_t, uint16_t, uint16_t, uint32_t, uint8_t, uint8_t, uint8_t, uint8_t); -void ADDARRAY(uint16_t * addq, uint8_t daddasel, uint8_t daddbsel, uint8_t daddmode, - uint64_t dstd, uint32_t iinc, uint8_t initcin[], uint64_t initinc, uint16_t initpix, - uint32_t istep, uint64_t patd, uint64_t srcd, uint64_t srcz1, uint64_t srcz2, - uint32_t zinc, uint32_t zstep); +void ADDARRAY(const uint16_t * addq, const uint8_t daddasel, const uint8_t daddbsel, const uint8_t daddmode, + const uint64_t dstd, const uint32_t iinc, const uint8_t initcin[], const uint64_t initinc, const uint16_t initpix, + const uint32_t istep, const uint64_t patd, const uint64_t srcd, const uint64_t srcz1, const uint64_t srcz2, + const uint32_t zinc, const uint32_t zstep); void ADD16SAT(uint16_t *r, uint8_t *co, uint16_t a, uint16_t b, uint8_t cin, bool sat, bool eightbit, bool hicinh); void ADDAMUX(int16_t *adda_x, int16_t *adda_y, uint8_t addasel, int16_t a1_step_x, int16_t a1_step_y, int16_t a1_stepf_x, int16_t a1_stepf_y, int16_t a2_step_x, int16_t a2_step_y, @@ -1165,7 +1172,8 @@ void BlitterMidsummer2(void) //Will remove stuff that isn't in Jaguar I once fully described (stuff like texture won't //be described here at all)... - uint32_t cmd = GET32(blitter_ram, COMMAND); + Bits32 cmd; + cmd.WORD = GET32(blitter_ram, COMMAND); // Line states passed in via the command register @@ -1176,7 +1184,7 @@ void BlitterMidsummer2(void) patdsel = (PATDSEL), adddsel = (ADDDSEL), cmpdst = (CMPDST), bcompen = (BCOMPEN), dcompen = (DCOMPEN), bkgwren = (BKGWREN), srcshade = (SRCSHADE); - uint8_t zmode = (cmd & 0x01C0000) >> 18, lfufunc = (cmd & 0x1E00000) >> 21; + uint8_t zmode = (cmd.WORD & 0x01C0000) >> 18, lfufunc = (cmd.WORD & 0x1E00000) >> 21; //Missing: BUSHI //Where to find various lines: // clip_a1 -> inner @@ -2396,10 +2404,10 @@ void ADDRGEN(uint32_t *address, uint32_t *pixa, bool gena2, bool zaddr, //////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////// -void ADDARRAY(uint16_t * addq, uint8_t daddasel, uint8_t daddbsel, uint8_t daddmode, - uint64_t dstd, uint32_t iinc, uint8_t initcin[], uint64_t initinc, uint16_t initpix, - uint32_t istep, uint64_t patd, uint64_t srcd, uint64_t srcz1, uint64_t srcz2, - uint32_t zinc, uint32_t zstep) +void ADDARRAY(const uint16_t * addq, const uint8_t daddasel, const uint8_t daddbsel, const uint8_t daddmode, + const uint64_t dstd, const uint32_t iinc, const uint8_t initcin[], const uint64_t initinc, const uint16_t initpix, + const uint32_t istep, const uint64_t patd, const uint64_t srcd, const uint64_t srcz1, const uint64_t srcz2, + const uint32_t zinc, const uint32_t zstep) { unsigned i; uint16_t adda[4]; @@ -2850,7 +2858,7 @@ Patdhi := JOIN (patdhi, patd[32..63]);*/ uint8_t dech38el[2][8] = { { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }; int en; - uint64_t cmpd; + Bits64 cmpd; uint8_t dbinht; uint16_t addq[4]; uint8_t initcin[4] = { 0, 0, 0, 0 }; @@ -2874,23 +2882,23 @@ Zstep := JOIN (zstep, zstep[0..31]);*/ /*Datacomp := DATACOMP (dcomp[0..7], cmpdst, dstdlo, dstdhi, patdlo, patdhi, srcdlo, srcdhi);*/ ////////////////////////////////////// C++ CODE ////////////////////////////////////// *dcomp = 0; - cmpd = *patd ^ (cmpdst ? dstd : srcd); + cmpd.DATA = *patd ^ (cmpdst ? dstd : srcd); - if ((cmpd & 0x00000000000000FFLL) == 0) + if (cmpd.bytes.b0 == 0) *dcomp |= 0x01u; - if ((cmpd & 0x000000000000FF00LL) == 0) + if (cmpd.bytes.b1 == 0) *dcomp |= 0x02u; - if ((cmpd & 0x0000000000FF0000LL) == 0) + if (cmpd.bytes.b2 == 0) *dcomp |= 0x04u; - if ((cmpd & 0x00000000FF000000LL) == 0) + if (cmpd.bytes.b3 == 0) *dcomp |= 0x08u; - if ((cmpd & 0x000000FF00000000LL) == 0) + if (cmpd.bytes.b4 == 0) *dcomp |= 0x10u; - if ((cmpd & 0x0000FF0000000000LL) == 0) + if (cmpd.bytes.b5 == 0) *dcomp |= 0x20u; - if ((cmpd & 0x00FF000000000000LL) == 0) + if (cmpd.bytes.b6 == 0) *dcomp |= 0x40u; - if ((cmpd & 0xFF00000000000000LL) == 0) + if (cmpd.bytes.b7 == 0) *dcomp |= 0x80u; ////////////////////////////////////////////////////////////////////////////////////// @@ -2908,25 +2916,25 @@ 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))) + // TODO: Byte and bit this - @joematt provenance + if ((((*srcz & 0x000000000000FFFFLL) < (dstz & 0x000000000000FFFFLL)) && (zmode & 0x01u)) + || (((*srcz & 0x000000000000FFFFLL) == (dstz & 0x000000000000FFFFLL)) && (zmode & 0x02u)) + || (((*srcz & 0x000000000000FFFFLL) > (dstz & 0x000000000000FFFFLL)) && (zmode & 0x04u))) *zcomp |= 0x01u; - if ((((*srcz & 0x00000000FFFF0000LL) < (dstz & 0x00000000FFFF0000LL)) && (zmode & 0x01)) - || (((*srcz & 0x00000000FFFF0000LL) == (dstz & 0x00000000FFFF0000LL)) && (zmode & 0x02)) - || (((*srcz & 0x00000000FFFF0000LL) > (dstz & 0x00000000FFFF0000LL)) && (zmode & 0x04))) + if ((((*srcz & 0x00000000FFFF0000LL) < (dstz & 0x00000000FFFF0000LL)) && (zmode & 0x01u)) + || (((*srcz & 0x00000000FFFF0000LL) == (dstz & 0x00000000FFFF0000LL)) && (zmode & 0x02u)) + || (((*srcz & 0x00000000FFFF0000LL) > (dstz & 0x00000000FFFF0000LL)) && (zmode & 0x04u))) *zcomp |= 0x02u; - if ((((*srcz & 0x0000FFFF00000000LL) < (dstz & 0x0000FFFF00000000LL)) && (zmode & 0x01)) - || (((*srcz & 0x0000FFFF00000000LL) == (dstz & 0x0000FFFF00000000LL)) && (zmode & 0x02)) - || (((*srcz & 0x0000FFFF00000000LL) > (dstz & 0x0000FFFF00000000LL)) && (zmode & 0x04))) + if ((((*srcz & 0x0000FFFF00000000LL) < (dstz & 0x0000FFFF00000000LL)) && (zmode & 0x01u)) + || (((*srcz & 0x0000FFFF00000000LL) == (dstz & 0x0000FFFF00000000LL)) && (zmode & 0x02u)) + || (((*srcz & 0x0000FFFF00000000LL) > (dstz & 0x0000FFFF00000000LL)) && (zmode & 0x04u))) *zcomp |= 0x04u; - if ((((*srcz & 0xFFFF000000000000LL) < (dstz & 0xFFFF000000000000LL)) && (zmode & 0x01)) - || (((*srcz & 0xFFFF000000000000LL) == (dstz & 0xFFFF000000000000LL)) && (zmode & 0x02)) - || (((*srcz & 0xFFFF000000000000LL) > (dstz & 0xFFFF000000000000LL)) && (zmode & 0x04))) + if ((((*srcz & 0xFFFF000000000000LL) < (dstz & 0xFFFF000000000000LL)) && (zmode & 0x01u)) + || (((*srcz & 0xFFFF000000000000LL) == (dstz & 0xFFFF000000000000LL)) && (zmode & 0x02u)) + || (((*srcz & 0xFFFF000000000000LL) > (dstz & 0xFFFF000000000000LL)) && (zmode & 0x04u))) *zcomp |= 0x08u; //TEMP, TO TEST IF ZCOMP IS THE CULPRIT... @@ -3039,6 +3047,8 @@ Sfine := DECH38EL (s_fine[0..7], dstart[0..2], sfen\);*/ /*Maskt[0] := BUF1 (maskt[0], s_fine[0]); Maskt[1-7] := OAN1P (maskt[1-7], maskt[0-6], s_fine[1-7], e_fine\[1-7]);*/ ////////////////////////////////////// C++ CODE ////////////////////////////////////// + // TODO: Byte and bit this - @joematt provenance + maskt = s_fine & 0x0001; maskt |= (((maskt & 0x0001) || (s_fine & 0x02u)) && (e_fine & 0x02u) ? 0x0002 : 0x0000); maskt |= (((maskt & 0x0002) || (s_fine & 0x04u)) && (e_fine & 0x04u) ? 0x0004 : 0x0000); @@ -3050,6 +3060,7 @@ Maskt[1-7] := OAN1P (maskt[1-7], maskt[0-6], s_fine[1-7], e_fine\[1-7]);*/ ////////////////////////////////////////////////////////////////////////////////////// /* Produce a look-ahead on the ripple carry */ + // TODO: Byte and bit this - @joematt provenance maskt |= (((s_coarse & e_coarse & 0x01u) || (s_coarse & 0x02u)) && (e_coarse & 0x02u) ? 0x0100 : 0x0000); maskt |= (((maskt & 0x0100) || (s_coarse & 0x04u)) && (e_coarse & 0x04u) ? 0x0200 : 0x0000); maskt |= (((maskt & 0x0200) || (s_coarse & 0x08u)) && (e_coarse & 0x08u) ? 0x0400 : 0x0000); @@ -3086,6 +3097,7 @@ Masku[14] := MX2 (masku[14], maskt[14], maskt[0], mir_byte);*/ mir_bit = true/*big_pix*/ && !phrase_mode; mir_byte = true/*big_pix*/ && phrase_mode; masku = maskt; + // TODO: Byte and bit this - @joematt provenance if (mir_bit) { diff --git a/src/dac.c b/src/dac.c index 4b5bc7b..6d9e630 100644 --- a/src/dac.c +++ b/src/dac.c @@ -164,12 +164,12 @@ void SoundCallback(void * userdata, uint16_t * buffer, int length) { double timeToNextEvent = GetTimeToNextEvent(EVENT_JERRY); - DSPExec(USEC_TO_RISC_CYCLES(timeToNextEvent)); + DSPExec(USEC_TO_RISC_CYCLES(timeToNextEvent)); - HandleNextEvent(EVENT_JERRY); - } - while (!bufferDone); - audio_batch_cb((int16_t*)sampleBuffer, length / 2); + HandleNextEvent(EVENT_JERRY); + } + while (!bufferDone); + audio_batch_cb((int16_t*)sampleBuffer, length / 2); } // LTXD/RTXD/SCLK/SMODE ($F1A148/4C/50/54) diff --git a/src/dsp.c b/src/dsp.c index 26760c5..0673be3 100644 --- a/src/dsp.c +++ b/src/dsp.c @@ -264,16 +264,17 @@ static uint32_t dsp_flags; static uint32_t dsp_matrix_control; static uint32_t dsp_pointer_to_matrix; static uint32_t dsp_data_organization; -uint32_t dsp_control; + +Bits32 dsp_control; static uint32_t dsp_div_control; static uint8_t dsp_flag_z, dsp_flag_n, dsp_flag_c; static uint32_t * dsp_reg = NULL, * dsp_alternate_reg = NULL; uint32_t dsp_reg_bank_0[32], dsp_reg_bank_1[32]; -static uint32_t dsp_opcode_first_parameter; -static uint32_t dsp_opcode_second_parameter; +static uint8_t dsp_opcode_first_parameter; +static uint8_t dsp_opcode_second_parameter; -#define DSP_RUNNING (dsp_control & 0x01) +#define DSP_RUNNING (dsp_control.bits.b0) #define RM dsp_reg[dsp_opcode_first_parameter] #define RN dsp_reg[dsp_opcode_second_parameter] @@ -393,20 +394,24 @@ uint8_t DSPReadByte(uint32_t offset, uint32_t who/*=UNKNOWN*/) uint16_t DSPReadWord(uint32_t offset, uint32_t who/*=UNKNOWN*/) { - offset &= 0xFFFFFFFE; - + Offset offsett; + offsett.LONG = offset; + offset = offsett.Members.offset; if (offset >= DSP_WORK_RAM_BASE && offset <= DSP_WORK_RAM_BASE+0x1FFF) { offset -= DSP_WORK_RAM_BASE; - return GET16(dsp_ram_8, offset); - } + return GET16(dsp_ram_8, offset); + } else if ((offset>=DSP_CONTROL_RAM_BASE)&&(offset> 16; + DSPLong data; + data.LONG = DSPReadLong(offset & 0xFFFFFFFC, who); + + if (offset & 0x03) { + return data.Data.LWORD; + } else { + return data.Data.UWORD; + } } return JaguarReadWord(offset, who); @@ -438,7 +443,7 @@ uint32_t DSPReadLong(uint32_t offset, uint32_t who/*=UNKNOWN*/) case 0x10: return dsp_pc; case 0x14: - return dsp_control; + return dsp_control.WORD; case 0x18: return dsp_modulo; case 0x1C: @@ -547,8 +552,8 @@ void DSPWriteLong(uint32_t offset, uint32_t data, uint32_t who/*=UNKNOWN*/) dsp_flag_c = (dsp_flags >> 1) & 0x01; dsp_flag_n = (dsp_flags >> 2) & 0x01; DSPUpdateRegisterBanks(); - dsp_control &= ~((dsp_flags & CINT04FLAGS) >> 3); - dsp_control &= ~((dsp_flags & CINT5FLAG) >> 1); + dsp_control.WORD &= ~((dsp_flags & CINT04FLAGS) >> 3); + dsp_control.WORD &= ~((dsp_flags & CINT5FLAG) >> 1); break; } case 0x04: @@ -592,7 +597,7 @@ void DSPWriteLong(uint32_t offset, uint32_t data, uint32_t who/*=UNKNOWN*/) } // Protect writes to VERSION and the interrupt latches... mask = VERSION | INT_LAT0 | INT_LAT1 | INT_LAT2 | INT_LAT3 | INT_LAT4 | INT_LAT5; - dsp_control = (dsp_control & mask) | (data & ~mask); + dsp_control.WORD = (dsp_control.WORD & mask) | (data & ~mask); //CC only! //!!!!!!!! @@ -646,7 +651,7 @@ void DSPHandleIRQs(void) return; // Get the active interrupt bits (latches) & interrupt mask (enables) - bits = ((dsp_control >> 10) & 0x20) | ((dsp_control >> 6) & 0x1F); + bits = ((dsp_control.WORD >> 10) & 0x20) | ((dsp_control.WORD >> 6) & 0x1F); mask = ((dsp_flags >> 11) & 0x20) | ((dsp_flags >> 4) & 0x1F); bits &= mask; @@ -733,7 +738,7 @@ void DSPHandleIRQsNP(void) return; // Get the active interrupt bits (latches) & interrupt mask (enables) - bits = ((dsp_control >> 10) & 0x20) | ((dsp_control >> 6) & 0x1F); + bits = ((dsp_control.WORD >> 10) & 0x20) | ((dsp_control.WORD >> 6) & 0x1F); mask = ((dsp_flags >> 11) & 0x20) | ((dsp_flags >> 4) & 0x1F); bits &= mask; @@ -773,11 +778,11 @@ void DSPSetIRQLine(int irqline, int state) { //NOTE: This doesn't take INT_LAT5 into account. !!! FIX !!! uint32_t mask = INT_LAT0 << irqline; - dsp_control &= ~mask; // Clear the latch bit + dsp_control.WORD &= ~mask; // Clear the latch bit if (state) { - dsp_control |= mask; // Set the latch bit + dsp_control.WORD |= mask; // Set the latch bit DSPHandleIRQsNP(); } } @@ -805,7 +810,7 @@ void DSPReset(void) dsp_matrix_control = 0x00000000; dsp_pointer_to_matrix = 0x00000000; dsp_data_organization = 0xFFFFFFFF; - dsp_control = 0x00002000; // Report DSP version 2 + dsp_control.WORD = 0x00002000; // Report DSP version 2 dsp_div_control = 0x00000000; dsp_in_exec = 0; @@ -845,23 +850,23 @@ INLINE void DSPExec(int32_t cycles) while (cycles > 0 && DSP_RUNNING) { - uint16_t opcode; - uint32_t index; - if (IMASKCleared) // If IMASK was cleared, { DSPHandleIRQsNP(); // See if any other interrupts are pending! IMASKCleared = false; } - opcode = DSPReadWord(dsp_pc, DSP); - index = opcode >> 10; - dsp_opcode_first_parameter = (opcode >> 5) & 0x1F; - dsp_opcode_second_parameter = opcode & 0x1F; - dsp_pc += 2; - dsp_opcode[index](); - dsp_opcode_use[index]++; - cycles -= dsp_opcode_cycles[index]; + OpCode opcode; + opcode.WORD = DSPReadWord(dsp_pc, DSP); + uint8_t index = opcode.Codes.index; + uint8_t fp = opcode.Codes.first; + uint8_t sp = opcode.Codes.second; + dsp_opcode_first_parameter = fp; + dsp_opcode_second_parameter = sp; + dsp_pc += 2; + dsp_opcode[index](); + + cycles -= dsp_opcode_cycles[index]; } dsp_in_exec--; @@ -1925,7 +1930,6 @@ INLINE static void DSP_jr(void) }//*/ dsp_pc += 2; // For DSP_DIS_* accuracy DSPOpcode[pipeline[plPtrExec].opcode](); - dsp_opcode_use[pipeline[plPtrExec].opcode]++; pipeline[plPtrWrite] = pipeline[plPtrExec]; // Step 3: Flush pipeline & set new PC @@ -2001,7 +2005,7 @@ INLINE static void DSP_jump(void) } dsp_pc += 2; // For DSP_DIS_* accuracy DSPOpcode[pipeline[plPtrExec].opcode](); - dsp_opcode_use[pipeline[plPtrExec].opcode]++; +// dsp_opcode_use[pipeline[plPtrExec].opcode]++; pipeline[plPtrWrite] = pipeline[plPtrExec]; // Step 3: Flush pipeline & set new PC diff --git a/src/gpu.c b/src/gpu.c index 66959e5..c1095c4 100644 --- a/src/gpu.c +++ b/src/gpu.c @@ -177,7 +177,8 @@ static uint32_t gpu_flags; static uint32_t gpu_matrix_control; static uint32_t gpu_pointer_to_matrix; static uint32_t gpu_data_organization; -static uint32_t gpu_control; +static GPUControl gpu_control; + static uint32_t gpu_div_control; // There is a distinct advantage to having these separated out--there's no need to clear // a bit before writing a result. I.e., if the result of an operation leaves a zero in @@ -192,7 +193,7 @@ static uint32_t gpu_instruction; static uint32_t gpu_opcode_first_parameter; static uint32_t gpu_opcode_second_parameter; -#define GPU_RUNNING (gpu_control & 0x01) +#define GPU_RUNNING (gpu_control.bits.b0) #define RM gpu_reg[gpu_opcode_first_parameter] #define RN gpu_reg[gpu_opcode_second_parameter] @@ -225,6 +226,30 @@ uint32_t gpu_convert_zero[32] = uint8_t * branch_condition_table = 0; #define BRANCH_CONDITION(x) branch_condition_table[(x) + ((jaguar_flags & 7) << 5)] +#ifdef DEBUG +uint32_t gpu_opcode_use[64]; +#endif + +const char * gpu_opcode_str[64]= +{ + "add", "addc", "addq", "addqt", + "sub", "subc", "subq", "subqt", + "neg", "and", "or", "xor", + "not", "btst", "bset", "bclr", + "mult", "imult", "imultn", "resmac", + "imacn", "div", "abs", "sh", + "shlq", "shrq", "sha", "sharq", + "ror", "rorq", "cmp", "cmpq", + "sat8", "sat16", "move", "moveq", + "moveta", "movefa", "movei", "loadb", + "loadw", "load", "loadp", "load_r14_indexed", + "load_r15_indexed", "storeb", "storew", "store", + "storep", "store_r14_indexed","store_r15_indexed","move_pc", + "jump", "jr", "mmult", "mtoi", + "normi", "nop", "load_r14_ri", "load_r15_ri", + "store_r14_ri", "store_r15_ri", "sat24", "pack", +}; + static uint32_t gpu_in_exec = 0; static uint32_t gpu_releaseTimeSlice_flag = 0; @@ -295,14 +320,15 @@ uint8_t GPUReadByte(uint32_t offset, uint32_t who/*=UNKNOWN*/) } // GPU word access (read) -uint16_t GPUReadWord(uint32_t offset, uint32_t who/*=UNKNOWN*/) +INLINE uint16_t GPUReadWord(uint32_t offset, uint32_t who/*=UNKNOWN*/) { if ((offset >= GPU_WORK_RAM_BASE) && (offset < GPU_WORK_RAM_BASE+0x1000)) { - uint16_t data; - offset &= 0xFFF; - data = ((uint16_t)gpu_ram_8[offset] << 8) | (uint16_t)gpu_ram_8[offset+1]; - return data; + offset &= 0xFFF; + OpCode data; + data.Bytes.UBYTE = (uint16_t)gpu_ram_8[offset]; + data.Bytes.LBYTE = (uint16_t)gpu_ram_8[offset+1]; + return data.WORD; } else if ((offset >= GPU_CONTROL_RAM_BASE) && (offset < GPU_CONTROL_RAM_BASE+0x20)) { @@ -324,7 +350,7 @@ uint16_t GPUReadWord(uint32_t offset, uint32_t who/*=UNKNOWN*/) } // GPU dword access (read) -uint32_t GPUReadLong(uint32_t offset, uint32_t who/*=UNKNOWN*/) +INLINE uint32_t GPUReadLong(uint32_t offset, uint32_t who/*=UNKNOWN*/) { if (offset >= 0xF02000 && offset <= 0xF020FF) { @@ -342,34 +368,33 @@ uint32_t GPUReadLong(uint32_t offset, uint32_t who/*=UNKNOWN*/) { offset &= 0x1F; switch (offset) - { - case 0x00: - gpu_flag_c = (gpu_flag_c ? 1 : 0); - gpu_flag_z = (gpu_flag_z ? 1 : 0); - gpu_flag_n = (gpu_flag_n ? 1 : 0); - - gpu_flags = (gpu_flags & 0xFFFFFFF8) | (gpu_flag_n << 2) | (gpu_flag_c << 1) | gpu_flag_z; - - return gpu_flags & 0xFFFFC1FF; - case 0x04: - return gpu_matrix_control; - case 0x08: - return gpu_pointer_to_matrix; - case 0x0C: - return gpu_data_organization; - case 0x10: - return gpu_pc; - case 0x14: - return gpu_control; - case 0x18: - return gpu_hidata; - case 0x1C: - return gpu_remain; - default: // unaligned long read - break; - } - - return 0; + { + case 0x00: + gpu_flag_c = (gpu_flag_c ? 1 : 0); + gpu_flag_z = (gpu_flag_z ? 1 : 0); + gpu_flag_n = (gpu_flag_n ? 1 : 0); + + gpu_flags = (gpu_flags & 0xFFFFFFF8) | (gpu_flag_n << 2) | (gpu_flag_c << 1) | gpu_flag_z; + + return gpu_flags & 0xFFFFC1FF; + case 0x04: + return gpu_matrix_control; + case 0x08: + return gpu_pointer_to_matrix; + case 0x0C: + return gpu_data_organization; + case 0x10: + return gpu_pc; + case 0x14: + return gpu_control.WORD; + case 0x18: + return gpu_hidata; + case 0x1C: + return gpu_remain; + default: // unaligned long read + break; + } + return 0; } return (JaguarReadWord(offset, who) << 16) | JaguarReadWord(offset + 2, who); @@ -473,7 +498,7 @@ void GPUWriteLong(uint32_t offset, uint32_t data, uint32_t who/*=UNKNOWN*/) gpu_flag_c = (gpu_flags & CARRY_FLAG) >> 1; gpu_flag_n = (gpu_flags & NEGA_FLAG) >> 2; GPUUpdateRegisterBanks(); - gpu_control &= ~((gpu_flags & CINT04FLAGS) >> 3); // Interrupt latch clear bits + gpu_control.WORD &= ~((gpu_flags & CINT04FLAGS) >> 3); // Interrupt latch clear bits //Writing here is only an interrupt enable--this approach is just plain wrong! // GPUHandleIRQs(); //This, however, is A-OK! ;-) @@ -523,7 +548,7 @@ void GPUWriteLong(uint32_t offset, uint32_t data, uint32_t who/*=UNKNOWN*/) data &= ~0x04; } - gpu_control = (gpu_control & 0xF7C0) | (data & (~0xF7C0)); + gpu_control.WORD = (gpu_control.WORD & 0xF7C0) | (data & (~0xF7C0)); // if gpu wasn't running but is now running, execute a few cycles #ifdef GPU_SINGLE_STEPPING @@ -579,7 +604,7 @@ void GPUHandleIRQs(void) return; // Get the interrupt latch & enable bits - bits = (gpu_control >> 6) & 0x1F; + bits = gpu_control.gpuIRQ.irqMask; //(gpu_control >> 6) & 0x1F; mask = (gpu_flags >> 4) & 0x1F; // Bail out if latched interrupts aren't enabled @@ -618,11 +643,11 @@ void GPUHandleIRQs(void) void GPUSetIRQLine(int irqline, int state) { uint32_t mask = 0x0040 << irqline; - gpu_control &= ~mask; // Clear the interrupt latch + gpu_control.WORD &= ~mask; // Clear the interrupt latch if (state) { - gpu_control |= mask; // Assert the interrupt latch + gpu_control.WORD |= mask; // Assert the interrupt latch GPUHandleIRQs(); // And handle the interrupt... } } @@ -644,7 +669,7 @@ void GPUReset(void) gpu_pointer_to_matrix = 0x00000000; gpu_data_organization = 0xFFFFFFFF; gpu_pc = 0x00F03000; - gpu_control = 0x00002800; // Correctly sets this as TOM Rev. 2 + gpu_control.WORD = 0x00002800; // Correctly sets this as TOM Rev. 2 gpu_hidata = 0x00000000; gpu_remain = 0x00000000; // These two registers are RO/WO gpu_div_control = 0x00000000; @@ -715,7 +740,6 @@ void GPUExec(int32_t cycles) // BIOS hacking //GPU: [00F03548] jr nz,00F03560 (0xd561) (RM=00F03114, RN=00000004) -> --> JR: Branch taken. //GPU: [00F0354C] jump nz,(r29) (0xd3a1) (RM=00F03314, RN=00000004) -> (RM=00F03314, RN=00000004) - cycles -= gpu_opcode_cycles[index]; } @@ -1572,30 +1596,35 @@ INLINE static void gpu_opcode_abs(void) INLINE static void gpu_opcode_div(void) // RN / RM { + unsigned i; // Real algorithm, courtesy of SCPCD: NYAN! - uint32_t q = RN; - uint32_t r = 0; + Bits32 q; + q.WORD = RN; + + Bits32 r; + r.WORD = 0; // If 16.16 division, stuff top 16 bits of RN into remainder and put the // bottom 16 of RN in top 16 of quotient - if (gpu_div_control & 0x01) - q <<= 16, r = RN >> 16; + if (gpu_div_control & 0x01) { + r.WORD = q.words.UWORD; + q.words.UWORD = q.words.LWORD; + q.words.LWORD = 0; + } for(i=0; i<32; i++) { - uint32_t sign = r & 0x80000000; - r = (r << 1) | ((q >> 31) & 0x01); - r += (sign ? RM : -RM); - q = (q << 1) | (((~r) >> 31) & 0x01); + uint32_t sign = r.bits.b31; + r.WORD = (r.WORD << 1) | q.bits.b31; + r.WORD += (sign ? RM : -RM); + q.WORD = (q.WORD << 1) | !r.bits.b31; // (((~r) >> 31) & 0x01); } - RN = q; - gpu_remain = r; - + RN = q.WORD; + gpu_remain = r.WORD; } - INLINE static void gpu_opcode_imultn(void) { uint32_t res = (int32_t)((int16_t)RN * (int16_t)RM); diff --git a/src/joystick.h b/src/joystick.h index 599afd2..41cee20 100644 --- a/src/joystick.h +++ b/src/joystick.h @@ -13,7 +13,7 @@ extern "C" { #endif -enum +typedef enum BUTTON { BUTTON_FIRST = 0, BUTTON_U = 0, @@ -40,7 +40,7 @@ enum BUTTON_OPTION = 19, BUTTON_PAUSE = 20, BUTTON_LAST = 20 -}; +} BUTTON; void JoystickInit(void); void JoystickReset(void); diff --git a/src/m68000/inlines.h b/src/m68000/inlines.h index 9084ff2..3501d01 100644 --- a/src/m68000/inlines.h +++ b/src/m68000/inlines.h @@ -10,6 +10,10 @@ #ifndef __INLINES_H__ #define __INLINES_H__ +#ifndef INLINE +#define INLINE __inline__ +#endif /* INLINE */ + #include "cpudefs.h" #include "m68kinterface.h" diff --git a/src/m68000/readcpu.c b/src/m68000/readcpu.c index ba96aeb..90befb5 100644 --- a/src/m68000/readcpu.c +++ b/src/m68000/readcpu.c @@ -22,6 +22,7 @@ #include #include +#include "inlines.h" #include "readcpu.h" int nr_cpuop_funcs; diff --git a/src/m68000/readcpu.h b/src/m68000/readcpu.h index 5fe0d49..721706c 100644 --- a/src/m68000/readcpu.h +++ b/src/m68000/readcpu.h @@ -88,6 +88,7 @@ struct instr_def { extern const struct instr_def defs68k[]; extern int n_defs68k; +#pragma pack(push, 1) extern struct instr { long int handler; unsigned char dreg; @@ -110,6 +111,7 @@ extern struct instr { unsigned int isjmp:1; unsigned int unused2:4; } *table68k; +#pragma pack(pop) extern void read_table68k(void); extern void do_merges(void); diff --git a/src/vjag_memory.h b/src/vjag_memory.h index 44749a9..ad23702 100644 --- a/src/vjag_memory.h +++ b/src/vjag_memory.h @@ -8,11 +8,222 @@ #define __MEMORY_H__ #include +#include #ifdef __cplusplus extern "C" { #endif +#pragma pack(push, 1) + typedef union Bits64 { + uint64_t DATA; + struct Bytes8 { +#ifdef LITTLE_ENDIAN + uint8_t b0; + uint8_t b1; + uint8_t b2; + uint8_t b3; + uint8_t b4; + uint8_t b5; + uint8_t b6; + uint8_t b7; +#else + uint8_t b7; + uint8_t b6; + uint8_t b5; + uint8_t b4; + uint8_t b3; + uint8_t b2; + uint8_t b1; + uint8_t b0; +#endif + } bytes; + } Bits64; +#pragma pack(pop) + +#pragma pack(push, 1) +typedef union Bits32 { + uint32_t WORD; + struct Words { +#ifdef LITTLE_ENDIAN + uint16_t LWORD; + uint16_t UWORD; +#else + uint16_t UWORD; + uint16_t LWORD; +#endif + } words; + struct Bytes4 { +#ifdef LITTLE_ENDIAN + uint8_t LL; + uint8_t LU; + uint8_t UL; + uint8_t UU; // Upper upper [UU, UL, LU, LL] +#else + uint8_t UU; // Upper upper [UU, UL, LU, LL] + uint8_t UL; + uint8_t LU; + uint8_t LL; +#endif + } bytes; + struct TopThreeOne { +#ifdef LITTLE_ENDIAN + unsigned int : 1; + uint32_t value : 31; +#else + uint32_t value : 31; + unsigned int : 1; +#endif + } topThreeOne; + struct Bits { +#ifdef LITTLE_ENDIAN + unsigned int b0: 1; + unsigned int b1: 1; + unsigned int b2: 1; + unsigned int b3: 1; + unsigned int b4: 1; + unsigned int b5: 1; + unsigned int b6: 1; + unsigned int b7: 1; + unsigned int b8: 1; + unsigned int b9: 1; + unsigned int b10: 1; + unsigned int b11: 1; + unsigned int b12: 1; + unsigned int b13: 1; + unsigned int b14: 1; + unsigned int b15: 1; + unsigned int b16: 1; + unsigned int b17: 1; + unsigned int b18: 1; + unsigned int b19: 1; + unsigned int b20: 1; + unsigned int b21: 1; + unsigned int b22: 1; + unsigned int b23: 1; + unsigned int b24: 1; + unsigned int b25: 1; + unsigned int b26: 1; + unsigned int b27: 1; + unsigned int b28: 1; + unsigned int b29: 1; + unsigned int b30: 1; + unsigned int b31: 1; +#else + // reverse the order of the bit fields. + unsigned int b31: 1; + unsigned int b30: 1; + unsigned int b29: 1; + unsigned int b28: 1; + unsigned int b27: 1; + unsigned int b26: 1; + unsigned int b25: 1; + unsigned int b24: 1; + unsigned int b23: 1; + unsigned int b22: 1; + unsigned int b21: 1; + unsigned int b20: 1; + unsigned int b19: 1; + unsigned int b18: 1; + unsigned int b17: 1; + unsigned int b16: 1; + unsigned int b15: 1; + unsigned int b14: 1; + unsigned int b13: 1; + unsigned int b12: 1; + unsigned int b11: 1; + unsigned int b10: 1; + unsigned int b9: 1; + unsigned int b8: 1; + unsigned int b7: 1; + unsigned int b6: 1; + unsigned int b5: 1; + unsigned int b4: 1; + unsigned int b3: 1; + unsigned int b2: 1; + unsigned int b1: 1; + unsigned int b0: 1; +#endif + } bits; +} Bits32; +#pragma pack(pop) + +#pragma pack(push, 1) +typedef union GPUControl { + uint32_t WORD; + struct Words words; + struct Bits bits; + struct __attribute__ ((__packed__)) { +#ifdef LITTLE_ENDIAN + unsigned int : 6; + unsigned int irqMask: 5; + unsigned int : 21; +#else + unsigned int : 21; + unsigned int irqMask: 5; + unsigned int : 6; +#endif +} gpuIRQ; +#pragma pack(pop) + +} GPUControl; + +#pragma pack(push, 1) + typedef union OpCode { + uint16_t WORD; + struct Bytes2 { +#ifdef LITTLE_ENDIAN + uint8_t LBYTE; + uint8_t UBYTE; +#else + uint8_t UBYTE; + uint8_t LBYTE; +#endif + } Bytes; + struct Codes { +#ifdef LITTLE_ENDIAN + unsigned int second : 5; + unsigned int first : 5; + unsigned int index : 6; +#else + unsigned int index : 6; + unsigned int first : 5; + unsigned int second : 5; +#endif + } Codes; + } OpCode; +#pragma pack(pop) + + typedef OpCode U16Union; + +typedef union Offset { + uint32_t LONG; +#pragma pack(push, 1) + struct Members { +#ifdef LITTLE_ENDIAN + unsigned int offset : 31; + unsigned int bit : 1; +#else + unsigned int bit : 1; + unsigned int offset : 31; +#endif + } Members; +#pragma pack(pop) +} Offset; + +typedef union DSPLong { + uint32_t LONG; + struct Data { +#ifdef LITTLE_ENDIAN + uint16_t LWORD; + uint16_t UWORD; +#else + uint16_t UWORD; + uint16_t LWORD; +#endif + } Data; +} DSPLong; + extern uint8_t jagMemSpace[]; extern uint8_t * jaguarMainRAM; @@ -76,7 +287,18 @@ extern const char * whoName[10]; r[(a)+2] = ((v) & 0x0000FF00) >> 8, r[(a)+3] = (v) & 0x000000FF #define GET32(r, a) ((r[(a)] << 24) | (r[(a)+1] << 16) | (r[(a)+2] << 8) | r[(a)+3]) #define SET16(r, a, v) r[(a)] = ((v) & 0xFF00) >> 8, r[(a)+1] = (v) & 0xFF -#define GET16(r, a) ((r[(a)] << 8) | r[(a)+1]) + + +//#ifdef USE_STRUCTS +// INLINE static uint16_t GET16(uint8_t* r,uint32_t a) { +// U16Union u16; +// u16.Bytes.UBYTE = r[a]; +// u16.Bytes.LBYTE = r[a+1]; +// return u16.WORD; +// } +//#else + #define GET16(r, a) ((r[(a)] << 8) | r[(a)+1]) +//#endif #ifdef __cplusplus }