LYNX_HEADER CCart::DecodeHeader(const uint8 *data) { LYNX_HEADER header; memcpy(header.magic, data, 4); data += 4; header.page_size_bank0 = MDFN_de16lsb(data); data += 2; header.page_size_bank1 = MDFN_de16lsb(data); data += 2; header.version = MDFN_de16lsb(data); data += 2; memcpy(header.cartname, data, 32); data += 32; memcpy(header.manufname, data, 16); data += 16; header.rotation = *data; data++; memcpy(header.spare, data, 5); data += 5; return(header); }
virtual void Frame(const void *data) { uint16 new_buttons = MDFN_de16lsb((uint8 *)data); bool mode_changed = false; if((old_raw_buttons ^ new_buttons) & (1 << 12) & new_buttons) { mode1 = !mode1; mode_changed = true; } if((old_raw_buttons ^ new_buttons) & (1 << 14) & new_buttons) { mode2 = !mode2; mode_changed = true; } if(mode_changed) MDFN_DispMessage(_("Pad %d - MODE 1: %s, MODE 2: %s"), which + 1, (mode1 ? "B" : "A"), (mode2 ? "B" : "A")); buttons = new_buttons & ~( (1 << 12) | (1 << 14)); buttons |= mode1 << 12; buttons |= mode2 << 14; old_raw_buttons = new_buttons; //printf("%d %08x\n", which, buttons); }
static void DINF(Stream *fp) { union { struct { char name[100]; uint8 raw_date[4]; char method[100]; }; uint8 raw[100 + 4 + 100]; } dinf; uint8 d, m; uint16 y; fp->read(dinf.raw, sizeof(dinf.raw)); d = dinf.raw_date[0]; m = dinf.raw_date[1]; y = MDFN_de16lsb(&dinf.raw_date[2]); dinf.name[99] = dinf.method[99] = 0; MDFN_RemoveControlChars(dinf.name); MDFN_RemoveControlChars(dinf.method); MDFN_printf(_("Dumped by: %s\n"), dinf.name); MDFN_printf(_("Dumped with: %s\n"), dinf.method); { const char* months[12]={_("January"),_("February"),_("March"),_("April"),_("May"),_("June"),_("July"), _("August"),_("September"),_("October"),_("November"),_("December")}; MDFN_printf(_("Dumped on: %s %d, %d\n"),months[(m-1)%12],d,y); } }
int MDFNFILE::read16le(uint16 *val) { if((location + 2) > size) return 0; *val = MDFN_de16lsb(data + location); location += 2; return(1); }
virtual void TransformInput(uint8* data, const bool DisableSR) override { if(DisableSR) { uint16 tmp = MDFN_de16lsb(data); if((tmp & 0xC0) == 0xC0) tmp &= ~0xC0; MDFN_en16lsb(data, tmp); } }
void InputDevice_DualAnalog::UpdateInput(const void *data) { uint8 *d8 = (uint8 *)data; buttons[0] = d8[0]; buttons[1] = d8[1]; for(int stick = 0; stick < 2; stick++) { for(int axis = 0; axis < 2; axis++) { const uint8* aba = &d8[2] + stick * 8 + axis * 4; int32 tmp; tmp = 32768 + MDFN_de16lsb(&aba[0]) - ((int32)MDFN_de16lsb(&aba[2]) * 32768 / 32767); tmp >>= 8; axes[stick][axis] = tmp; } } //printf("%d %d %d %d\n", axes[0][0], axes[0][1], axes[1][0], axes[1][1]); }
void UpdatePP(int w, void *data) { static const unsigned char shifttable[2][12] = { {8,9,0,1,11,7,4,2,10,6,5,3}, {1,0,9,8,2,4,7,11,3,5,6,10} }; const uint16 ind16 = MDFN_de16lsb((uint8*)data); pprdata[w] = 0; for(int x = 0; x < 12; x++) { pprdata[w] |= ((ind16 >> x) & 1) << shifttable[side][x]; } }
static void rom_display_header(void) { MDFN_printf(_("Name: %s\n"), ngpc_rom.name); MDFN_printf(_("System: ")); if(rom_header->mode & 0x10) MDFN_printf(_("Color")); else MDFN_printf(_("Greyscale")); MDFN_printf("\n"); MDFN_printf(_("Catalog: %u (sub %u)\n"), MDFN_de16lsb(rom_header->catalog), rom_header->subCatalog); //Starting PC MDFN_printf(_("Starting PC: 0x%06X\n"), MDFN_de32lsb(rom_header->startPC) & 0xFFFFFF); }
int PCE_HESLoad(const uint8 *buf, uint32 size) { uint32 LoadAddr, LoadSize; uint32 CurPos; uint16 InitAddr; uint8 StartingSong; int TotalSongs; InitAddr = MDFN_de16lsb(&buf[0x6]); CurPos = 0x10; if(!(rom = (uint8 *)MDFN_malloc(0x88 * 8192, _("HES ROM")))) { return(0); } if(!(rom_backup = (uint8 *)MDFN_malloc(0x88 * 8192, _("HES ROM")))) { return(0); } memset(rom, 0, 0x88 * 8192); memset(rom_backup, 0, 0x88 * 8192); while(CurPos < (size - 0x10)) { LoadSize = MDFN_de32lsb(&buf[CurPos + 0x4]); LoadAddr = MDFN_de32lsb(&buf[CurPos + 0x8]); //printf("Size: %08x(%d), Addr: %08x, La: %02x\n", LoadSize, LoadSize, LoadAddr, LoadAddr / 8192); CurPos += 0x10; if(((uint64)LoadSize + CurPos) > size) { uint32 NewLoadSize = size - CurPos; MDFN_printf(_("Warning: HES is trying to load more data than is present in the file(%u attempted, %u left)!\n"), LoadSize, NewLoadSize); LoadSize = NewLoadSize; } // 0x88 * 8192 = 0x110000 if(((uint64)LoadAddr + LoadSize) > 0x110000) { MDFN_printf(_("Warning: HES is trying to load data past boundary.\n")); if(LoadAddr >= 0x110000) break; LoadSize = 0x110000 - LoadAddr; } memcpy(rom + LoadAddr, &buf[CurPos], LoadSize); CurPos += LoadSize; } for(int x = 0; x < 8; x++) mpr_start[x] = buf[0x8 + x]; memcpy(rom_backup, rom, 0x88 * 8192); CurrentSong = StartingSong = buf[5]; TotalSongs = 256; memset(IBP_Bank, 0, 0x2000); uint8 *IBP_WR = IBP_Bank + 0x1C00; for(int i = 0; i < 8; i++) { *IBP_WR++ = 0xA9; // LDA (immediate) *IBP_WR++ = mpr_start[i]; *IBP_WR++ = 0x53; // TAM *IBP_WR++ = 1 << i; } *IBP_WR++ = 0xAD; // LDA(absolute) *IBP_WR++ = 0x00; // *IBP_WR++ = 0x1D; // *IBP_WR++ = 0x20; // JSR *IBP_WR++ = InitAddr; // JSR target LSB *IBP_WR++ = InitAddr >> 8; // JSR target MSB *IBP_WR++ = 0x58; // CLI *IBP_WR++ = 0xFC; // (Mednafen Special) *IBP_WR++ = 0x80; // BRA *IBP_WR++ = 0xFD; // -3 Player_Init(TotalSongs, NULL, NULL, NULL, NULL); //UTF8 **snames); for(int x = 0; x < 0x80; x++) { HuCPUFastMap[x] = rom; PCERead[x] = HESROMRead; PCEWrite[x] = HESROMWrite; } HuCPUFastMap[0xFF] = IBP_Bank - (0xFF * 8192); // FIXME: If a HES rip tries to execute a SCSI command, the CD emulation code will probably crash. Obviously, a HES rip shouldn't do this, // but Mednafen shouldn't crash either. ;) PCE_IsCD = 1; PCE_InitCD(); ROMWriteWarningGiven = FALSE; return(1); }
virtual void Frame(const void *data) override { buttons = MDFN_de16lsb((uint8 *)data); }
void LoadNSFE(NSFINFO *nfe, const uint8 *buf, int32 size, int info_only) { const uint8 *nbuf = 0; size -= 4; buf += 4; while(size) { uint32 chunk_size; uint8 tb[4]; if(size < 4) throw MDFN_Error(0, _("Unexpected EOF while reading NSFE.")); chunk_size = MDFN_de32lsb(buf); size -= 4; buf += 4; if(size < 4) throw MDFN_Error(0, _("Unexpected EOF while reading NSFE.")); memcpy(tb, buf, 4); buf += 4; size -= 4; if((int32)chunk_size < 0 || (int32)chunk_size > size) throw MDFN_Error(0, _("NSFE chunk \"%.4s\" size(%u) is invalid."), (char*)&tb[0], chunk_size); //printf("\nChunk: %.4s %d\n", tb, chunk_size); if(!memcmp(tb, "INFO", 4)) { if(chunk_size < 8) throw MDFN_Error(0, _("NSFE chunk \"%.4s\" size(%u) is invalid."), (char*)&tb[0], chunk_size); nfe->LoadAddr = MDFN_de16lsb(buf); buf+=2; size-=2; nfe->InitAddr = MDFN_de16lsb(buf); buf+=2; size-=2; nfe->PlayAddr = MDFN_de16lsb(buf); buf+=2; size-=2; nfe->VideoSystem = *buf; buf++; size--; nfe->SoundChip = *buf; buf++; size--; chunk_size-=8; if(chunk_size) { nfe->TotalSongs = *buf; buf++; size--; chunk_size--; } else nfe->TotalSongs = 1; if(chunk_size) { nfe->StartingSong = *buf; buf++; size--; chunk_size--; } else nfe->StartingSong = 0; nfe->SongNames = (char **)malloc(sizeof(char *) * nfe->TotalSongs); memset(nfe->SongNames, 0, sizeof(char *) * nfe->TotalSongs); nfe->SongLengths = (int32 *)malloc(sizeof(int32) * nfe->TotalSongs); nfe->SongFades = (int32 *)malloc(sizeof(int32) * nfe->TotalSongs); { int x; for(x=0; x<nfe->TotalSongs; x++) { nfe->SongLengths[x] = -1; nfe->SongFades[x] = -1; } } } else if(!memcmp(tb, "DATA", 4)) { nfe->NSFSize=chunk_size; nbuf = buf; } else if(!memcmp(tb, "BANK", 4)) { memcpy(nfe->BankSwitch, buf, (chunk_size > 8) ? 8 : chunk_size); } else if(!memcmp(tb, "NEND", 4)) { if(chunk_size != 0) throw MDFN_Error(0, _("NSFE chunk \"%.4s\" size(%u) is invalid."), (char*)&tb[0], chunk_size); else if(!nbuf) throw MDFN_Error(0, _("NEND reached without preceding DATA chunk.")); else { nfe->NSFMaxBank = ((nfe->NSFSize+(nfe->LoadAddr&0xfff)+4095)/4096); nfe->NSFMaxBank = round_up_pow2(nfe->NSFMaxBank); if(!info_only) { if(!(nfe->NSFDATA=(uint8 *)malloc(nfe->NSFMaxBank*4096))) throw MDFN_Error(errno, _("Error allocating memory.")); memset(nfe->NSFDATA,0x00,nfe->NSFMaxBank*4096); memcpy(nfe->NSFDATA+(nfe->LoadAddr&0xfff),nbuf,nfe->NSFSize); nfe->NSFRawData = nfe->NSFDATA + (nfe->LoadAddr & 0xFFF); nfe->NSFRawDataSize = nfe->NSFSize; } nfe->NSFMaxBank--; return; } } else if(!memcmp(tb, "tlbl", 4)) { int songcount = 0; if(!nfe->TotalSongs) throw MDFN_Error(0, _("NSFE chunk \"%.4s\" is out of order.")); // Out of order chunk. while(chunk_size > 0) { int slen = strlen((char *)buf); nfe->SongNames[songcount++] = (char*)MDFN_RemoveControlChars(strdup((char *)buf)); buf += slen + 1; chunk_size -= slen + 1; } } else if(!memcmp(tb, "time", 4)) { int count = chunk_size / 4; int ws = 0; chunk_size -= count * 4; while(count--) { nfe->SongLengths[ws] = (int32)MDFN_de32lsb(buf); //printf("%d\n",fe->SongLengths[ws]/1000); buf += 4; ws++; } } else if(!memcmp(tb, "fade", 4)) { int count = chunk_size / 4; int ws = 0; chunk_size -= count * 4; while(count--) { nfe->SongFades[ws] = (int32)MDFN_de32lsb(buf); //printf("%d\n",fe->SongFades[ws]); buf += 4; ws++; } } else if(!memcmp(tb, "auth", 4)) { int which = 0; while(chunk_size > 0) { int slen = strlen((char *)buf); if(!which) nfe->GameName = (char*)MDFN_RemoveControlChars(strdup((char *)buf)); else if(which == 1) nfe->Artist = (char*)MDFN_RemoveControlChars(strdup((char *)buf)); else if(which == 2) nfe->Copyright = (char*)MDFN_RemoveControlChars(strdup((char *)buf)); else if(which == 3) nfe->Ripper = (char*)MDFN_RemoveControlChars(strdup((char *)buf)); which++; buf += slen +1; chunk_size -= slen + 1; } } else if(tb[0] >= 'A' && tb[0] <= 'Z') /* Unrecognized mandatory chunk */ { throw MDFN_Error(0, _("NSFE unrecognized mandatory chunk \"%.4s\"."), (char*)&tb[0]); } buf += chunk_size; size -= chunk_size; } }
void InputDevice_DualShock::UpdateInput(const void *data) { uint8 *d8 = (uint8 *)data; uint8* const rumb_dp = &d8[3 + 16]; buttons[0] = d8[0]; buttons[1] = d8[1]; cur_ana_button_state = d8[2] & 0x01; for(int stick = 0; stick < 2; stick++) { for(int axis = 0; axis < 2; axis++) { const uint8* aba = &d8[3] + stick * 8 + axis * 4; int32 tmp; tmp = 32767 + MDFN_de16lsb(&aba[0]) - MDFN_de16lsb(&aba[2]); tmp = (tmp * 0x100) / 0xFFFF; axes[stick][axis] = tmp; } } //printf("%3d:%3d, %3d:%3d\n", axes[0][0], axes[0][1], axes[1][0], axes[1][1]); //printf("RUMBLE: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", rumble_magic[0], rumble_magic[1], rumble_magic[2], rumble_magic[3], rumble_magic[4], rumble_magic[5]); //printf("%d, 0x%02x 0x%02x\n", da_rumble_compat, rumble_param[0], rumble_param[1]); if(da_rumble_compat == false) { uint8 sneaky_weaky = 0; if(rumble_param[0] == 0x01) sneaky_weaky = 0xFF; MDFN_en16lsb(rumb_dp, (sneaky_weaky << 0) | (rumble_param[1] << 8)); } else { uint8 sneaky_weaky = 0; if(((rumble_param[0] & 0xC0) == 0x40) && ((rumble_param[1] & 0x01) == 0x01)) sneaky_weaky = 0xFF; MDFN_en16lsb(rumb_dp, sneaky_weaky << 0); } //printf("%d %d %d %d\n", axes[0][0], axes[0][1], axes[1][0], axes[1][1]); // // // CheckManualAnaModeChange(); // // Encode analog mode state last. // d8[2] &= ~0x6; d8[2] |= (analog_mode ? 0x02 : 0x00); d8[2] |= (analog_mode_locked ? 0x04 : 0x00); }
static INLINE void RunCDDA(uint32 system_timestamp, int32 run_time) { if(cdda.CDDAStatus == CDDASTATUS_PLAYING) { int32 sample[2]; cdda.CDDADiv -= run_time << 16; while(cdda.CDDADiv <= 0) { const uint32 synthtime = ((system_timestamp + (cdda.CDDADiv >> 16))) / cdda.CDDATimeDiv; cdda.CDDADiv += cdda.CDDADivAcc; //MDFN_DispMessage("%d %d %d\n", read_sec_start, read_sec, read_sec_end); if(cdda.CDDAReadPos == 588) { if(read_sec >= read_sec_end) { switch(cdda.PlayMode) { case PLAYMODE_SILENT: case PLAYMODE_NORMAL: cdda.CDDAStatus = CDDASTATUS_STOPPED; break; case PLAYMODE_INTERRUPT: cdda.CDDAStatus = CDDASTATUS_STOPPED; CDIRQCallback(PCECD_Drive_IRQ_DATA_TRANSFER_DONE); break; case PLAYMODE_LOOP: read_sec = read_sec_start; break; } // If CDDA playback is stopped, break out of our while(CDDADiv ...) loop and don't play any more sound! if(cdda.CDDAStatus == CDDASTATUS_STOPPED) break; } // Don't play past the user area of the disc. if(read_sec >= toc.tracks[100].lba) { cdda.CDDAStatus = CDDASTATUS_STOPPED; break; } if(cd.TrayOpen) { cdda.CDDAStatus = CDDASTATUS_STOPPED; #if 0 cd.data_transfer_done = FALSE; cd.key_pending = SENSEKEY_NOT_READY; cd.asc_pending = ASC_MEDIUM_NOT_PRESENT; cd.ascq_pending = 0x00; cd.fru_pending = 0x00; SendStatusAndMessage(STATUS_CHECK_CONDITION, 0x00); #endif break; } cdda.CDDAReadPos = 0; { uint8 tmpbuf[2352 + 96]; Cur_CDIF->ReadRawSector(tmpbuf, read_sec); //, read_sec_end, read_sec_start); for(int i = 0; i < 588 * 2; i++) cdda.CDDASectorBuffer[i] = MDFN_de16lsb(&tmpbuf[i * 2]); memcpy(cd.SubPWBuf, tmpbuf + 2352, 96); } GenSubQFromSubPW(); read_sec++; } // End if(CDDAReadPos == 588) // If the last valid sub-Q data decoded indicate that the corresponding sector is a data sector, don't output the // current sector as audio. sample[0] = sample[1] = 0; if(!(cd.SubQBuf_Last[0] & 0x40) && cdda.PlayMode != PLAYMODE_SILENT) { sample[0] = (cdda.CDDASectorBuffer[cdda.CDDAReadPos * 2 + 0] * cdda.CDDAVolume) >> 16; sample[1] = (cdda.CDDASectorBuffer[cdda.CDDAReadPos * 2 + 1] * cdda.CDDAVolume) >> 16; } if(!(cdda.CDDAReadPos % 6)) { int subindex = cdda.CDDAReadPos / 6 - 2; if(subindex >= 0) CDStuffSubchannels(cd.SubPWBuf[subindex], subindex); else // The system-specific emulation code should handle what value the sync bytes are. CDStuffSubchannels(0x00, subindex); } if(sbuf[0] && sbuf[1]) { cdda.CDDASynth.offset_inline(synthtime, sample[0] - cdda.last_sample[0], sbuf[0]); cdda.CDDASynth.offset_inline(synthtime, sample[1] - cdda.last_sample[1], sbuf[1]); } cdda.last_sample[0] = sample[0]; cdda.last_sample[1] = sample[1]; cdda.CDDAReadPos++; }
SPCReader::SPCReader(Stream* fp) { #if 0 reg_pc = 0x430; reg_a = 0; reg_x = 0; reg_y = 0; reg_psw = 0; reg_sp = 0xFF; memset(apuram, 0x00, sizeof(apuram)); memset(dspregs, 0x00, sizeof(dspregs)); dspregs[0x6C] = 0xE0; fp->read(&apuram[0x400], 0x1000); return; #endif if(!TestMagic(fp)) throw MDFN_Error(0, _("Not a valid SPC file!")); uint8 header[0x100]; fp->rewind(); fp->read(header, sizeof(header)); reg_pc = MDFN_de16lsb(&header[0x25]); reg_a = header[0x27]; reg_x = header[0x28]; reg_y = header[0x29]; reg_psw = header[0x2A]; reg_sp = header[0x2B]; fp->read(apuram, 65536); fp->read(dspregs, 0x80); fp->seek(0x101C0, SEEK_SET); fp->read(apuram + 0xFFC0, 0x40); if(header[0x23] == 0x1A) { bool binary_tags = true; if(header[0xA0] == '/' && header[0xA3] == '/') binary_tags = false; if(header[0xD2] >= '0' && header[0xD2] <= '9' && header[0xD3] == 0x00) binary_tags = false; fp->seek(0x2E, SEEK_SET); song_name = GrabString(fp, 32); game_name = GrabString(fp, 32); fp->seek(binary_tags ? 0xB0 : 0xB1, SEEK_SET); artist_name = GrabString(fp, 32); } // // // #if 0 fp->seek(0x10200, SEEK_SET); uint8 xid_header[8]; if(fp->read(xid_header, sizeof(xid_header), false) == sizeof(xid_header) && !memcmp(xid_header, "xid6", 4)) { uint8 sub_header[4]; while(fp->read(sub_header, sizeof(sub_header), false) == sizeof(sub_header)) { const uint8 id = sub_header[0]; const uint8 type = sub_header[1]; uint16 len = MDFN_de16lsb(&sub_header[2]); printf("ID: 0x%02x, Type: 0x%02x, Len: 0x%04x\n", id, type, len); if(type == 1 && len > 4) len = (len + 3) &~ 3; switch(id) { default: if(type) fp->seek(len, SEEK_CUR); break; case 0x01: song_name = GrabString(fp, len); break; case 0x02: game_name = GrabString(fp, len); break; case 0x03: artist_name = GrabString(fp, len); break; } } } #endif }