Split up misc functions into mednafen/cdrom/misc.cpp

This commit is contained in:
twinaphex 2015-07-29 00:38:34 +02:00
parent 3da0bba3d5
commit 4169e214be
7 changed files with 100 additions and 80 deletions

View File

@ -86,6 +86,7 @@ SOURCES_CXX += $(MEDNAFEN_DIR)/cdrom/CDAccess.cpp \
$(MEDNAFEN_DIR)/cdrom/lec.cpp \
$(MEDNAFEN_DIR)/cdrom/SimpleFIFO.cpp \
$(MEDNAFEN_DIR)/cdrom/audioreader.cpp \
$(MEDNAFEN_DIR)/cdrom/misc.cpp \
$(MEDNAFEN_DIR)/cdrom/cdromif.cpp
SOURCES_C += \

View File

@ -38,6 +38,7 @@
#include "mednafen/cdrom/SimpleFIFO.cpp"
#include "mednafen/cdrom/audioreader.cpp"
#include "mednafen/cdrom/cdromif.cpp"
#include "mednafen/cdrom/misc.cpp"
#endif
#include "mednafen/mempatcher.cpp"

View File

@ -2,8 +2,10 @@
#define __MDFN_CDROMFILE_H
#include <stdio.h>
#include <stdint.h>
#include "CDUtility.h"
#include "misc.h"
class CDAccess
{
@ -12,7 +14,7 @@ class CDAccess
CDAccess();
virtual ~CDAccess();
virtual void Read_Raw_Sector(uint8 *buf, int32 lba) = 0;
virtual void Read_Raw_Sector(uint8_t *buf, int32_t lba) = 0;
virtual void Read_TOC(TOC *toc) = 0;

View File

@ -17,7 +17,6 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "../mednafen.h"
#include "CDUtility.h"
#include "edc_crc32.h"
#include "galois.h"
@ -28,7 +27,7 @@
#include <assert.h>
// lookup table for crc calculation
static uint16 subq_crctab[256] =
static uint16_t subq_crctab[256] =
{
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, 0x8108,
0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, 0x1231, 0x0210,
@ -62,7 +61,7 @@ static uint16 subq_crctab[256] =
};
static uint8 scramble_table[2352 - 12];
static uint8_t scramble_table[2352 - 12];
static bool CDUtility_Inited = false;
@ -101,49 +100,49 @@ void CDUtility_Init(void)
}
}
void encode_mode0_sector(uint32 aba, uint8 *sector_data)
void encode_mode0_sector(uint32_t aba, uint8_t *sector_data)
{
CDUtility_Init();
lec_encode_mode0_sector(aba, sector_data);
}
void encode_mode1_sector(uint32 aba, uint8 *sector_data)
void encode_mode1_sector(uint32_t aba, uint8_t *sector_data)
{
CDUtility_Init();
lec_encode_mode1_sector(aba, sector_data);
}
void encode_mode2_sector(uint32 aba, uint8 *sector_data)
void encode_mode2_sector(uint32_t aba, uint8_t *sector_data)
{
CDUtility_Init();
lec_encode_mode2_sector(aba, sector_data);
}
void encode_mode2_form1_sector(uint32 aba, uint8 *sector_data)
void encode_mode2_form1_sector(uint32_t aba, uint8_t *sector_data)
{
CDUtility_Init();
lec_encode_mode2_form1_sector(aba, sector_data);
}
void encode_mode2_form2_sector(uint32 aba, uint8 *sector_data)
void encode_mode2_form2_sector(uint32_t aba, uint8_t *sector_data)
{
CDUtility_Init();
lec_encode_mode2_form2_sector(aba, sector_data);
}
bool edc_check(const uint8 *sector_data, bool xa)
bool edc_check(const uint8_t *sector_data, bool xa)
{
CDUtility_Init();
return(CheckEDC(sector_data, xa));
}
bool edc_lec_check_and_correct(uint8 *sector_data, bool xa)
bool edc_lec_check_and_correct(uint8_t *sector_data, bool xa)
{
CDUtility_Init();
@ -151,10 +150,10 @@ bool edc_lec_check_and_correct(uint8 *sector_data, bool xa)
}
bool subq_check_checksum(const uint8 *SubQBuf)
bool subq_check_checksum(const uint8_t *SubQBuf)
{
uint16 crc = 0;
uint16 stored_crc = 0;
uint16_t crc = 0;
uint16_t stored_crc = 0;
stored_crc = SubQBuf[0xA] << 8;
stored_crc |= SubQBuf[0xB];
@ -167,9 +166,9 @@ bool subq_check_checksum(const uint8 *SubQBuf)
return(crc == stored_crc);
}
void subq_generate_checksum(uint8 *buf)
void subq_generate_checksum(uint8_t *buf)
{
uint16 crc = 0;
uint16_t crc = 0;
for(int i = 0; i < 0xA; i++)
crc = subq_crctab[(crc >> 8) ^ buf[i]] ^ (crc << 8);
@ -179,7 +178,7 @@ void subq_generate_checksum(uint8 *buf)
buf[0xb] = ~(crc);
}
void subq_deinterleave(const uint8 *SubPWBuf, uint8 *qbuf)
void subq_deinterleave(const uint8_t *SubPWBuf, uint8_t *qbuf)
{
memset(qbuf, 0, 0xC);
@ -189,7 +188,7 @@ void subq_deinterleave(const uint8 *SubPWBuf, uint8 *qbuf)
// Deinterleaves 96 bytes of subchannel P-W data from 96 bytes of interleaved subchannel PW data.
void subpw_deinterleave(const uint8 *in_buf, uint8 *out_buf)
void subpw_deinterleave(const uint8_t *in_buf, uint8_t *out_buf)
{
assert(in_buf != out_buf);
@ -204,7 +203,7 @@ void subpw_deinterleave(const uint8 *in_buf, uint8 *out_buf)
}
// Interleaves 96 bytes of subchannel P-W data from 96 bytes of uninterleaved subchannel PW data.
void subpw_interleave(const uint8 *in_buf, uint8 *out_buf)
void subpw_interleave(const uint8_t *in_buf, uint8_t *out_buf)
{
assert(in_buf != out_buf);
@ -212,7 +211,7 @@ void subpw_interleave(const uint8 *in_buf, uint8 *out_buf)
{
for(unsigned bitpoodle = 0; bitpoodle < 8; bitpoodle++)
{
uint8 rawb = 0;
uint8_t rawb = 0;
for(unsigned ch = 0; ch < 8; ch++)
{
@ -229,12 +228,12 @@ void subpw_interleave(const uint8 *in_buf, uint8 *out_buf)
// and the leadout entry together before extracting the D2 bit. Audio track->data leadout is fairly benign though maybe noisy(especially if we ever implement
// data scrambling properly), but data track->audio leadout could break things in an insidious manner for the more accurate drive emulation code).
//
void subpw_synth_leadout_lba(const TOC& toc, const int32 lba, uint8* SubPWBuf)
void subpw_synth_leadout_lba(const TOC& toc, const int32_t lba, uint8_t* SubPWBuf)
{
uint8 buf[0xC];
uint32 lba_relative;
uint32 ma, sa, fa;
uint32 m, s, f;
uint8_t buf[0xC];
uint32_t lba_relative;
uint32_t ma, sa, fa;
uint32_t m, s, f;
lba_relative = lba - toc.tracks[100].lba;
@ -246,8 +245,8 @@ void subpw_synth_leadout_lba(const TOC& toc, const int32 lba, uint8* SubPWBuf)
sa = ((lba + 150) / 75) % 60;
ma = ((lba + 150) / 75 / 60);
uint8 adr = 0x1; // Q channel data encodes position
uint8 control = (toc.tracks[toc.last_track].control & 0x4) | toc.tracks[100].control;
uint8_t adr = 0x1; // Q channel data encodes position
uint8_t control = (toc.tracks[toc.last_track].control & 0x4) | toc.tracks[100].control;
memset(buf, 0, 0xC);
buf[0] = (adr << 0) | (control << 4);
@ -272,7 +271,7 @@ void subpw_synth_leadout_lba(const TOC& toc, const int32 lba, uint8* SubPWBuf)
SubPWBuf[i] = (((buf[i >> 3] >> (7 - (i & 0x7))) & 1) ? 0x40 : 0x00) | 0x80;
}
void synth_leadout_sector_lba(const uint8 mode, const TOC& toc, const int32 lba, uint8* out_buf)
void synth_leadout_sector_lba(const uint8_t mode, const TOC& toc, const int32_t lba, uint8_t* out_buf)
{
memset(out_buf, 0, 2352 + 96);
subpw_synth_leadout_lba(toc, lba, out_buf + 2352);
@ -297,28 +296,8 @@ void synth_leadout_sector_lba(const uint8 mode, const TOC& toc, const int32 lba,
}
}
void scrambleize_data_sector(uint8 *sector_data)
void scrambleize_data_sector(uint8_t *sector_data)
{
for(unsigned i = 12; i < 2352; i++)
sector_data[i] ^= scramble_table[i - 12];
}
void MDFN_strtoupper(char *str)
{
for(size_t x = 0; str[x]; x++)
{
if(str[x] >= 'a' && str[x] <= 'z')
str[x] = str[x] - 'a' + 'A';
}
}
void MDFN_strtoupper(std::string &str)
{
const size_t len = str.length();
for(size_t x = 0; x < len; x++)
{
if(str[x] >= 'a' && str[x] <= 'z')
str[x] = str[x] - 'a' + 'A';
}
}

View File

@ -1,6 +1,11 @@
#ifndef __MDFN_CDROM_CDUTILITY_H
#define __MDFN_CDROM_CDUTILITY_H
#include <stdint.h>
#include <string.h>
#include <retro_inline.h>
// Call once at app startup before creating any threads that could potentially cause re-entrancy to these functions.
// It will also be called automatically if needed for the first time a function in this namespace that requires
// the initialization function to be called is called, for potential
@ -27,9 +32,9 @@ enum
struct TOC_Track
{
uint8 adr;
uint8 control;
uint32 lba;
uint8_t adr;
uint8_t control;
uint32_t lba;
};
// SubQ control field flags.
@ -92,34 +97,34 @@ static INLINE int TOC_FindTrackByLBA(TOC *toc, uint32_t LBA)
//
// Address conversion functions.
//
static INLINE uint32 AMSF_to_ABA(int32 m_a, int32 s_a, int32 f_a)
static INLINE uint32_t AMSF_to_ABA(int32_t m_a, int32_t s_a, int32_t f_a)
{
return(f_a + 75 * s_a + 75 * 60 * m_a);
}
static INLINE void ABA_to_AMSF(uint32 aba, uint8 *m_a, uint8 *s_a, uint8 *f_a)
static INLINE void ABA_to_AMSF(uint32_t aba, uint8_t *m_a, uint8_t *s_a, uint8_t *f_a)
{
*m_a = aba / 75 / 60;
*s_a = (aba - *m_a * 75 * 60) / 75;
*f_a = aba - (*m_a * 75 * 60) - (*s_a * 75);
}
static INLINE int32 ABA_to_LBA(uint32 aba)
static INLINE int32_t ABA_to_LBA(uint32_t aba)
{
return(aba - 150);
}
static INLINE uint32 LBA_to_ABA(int32 lba)
static INLINE uint32_t LBA_to_ABA(int32_t lba)
{
return(lba + 150);
}
static INLINE int32 AMSF_to_LBA(uint8 m_a, uint8 s_a, uint8 f_a)
static INLINE int32_t AMSF_to_LBA(uint8_t m_a, uint8_t s_a, uint8_t f_a)
{
return(ABA_to_LBA(AMSF_to_ABA(m_a, s_a, f_a)));
}
static INLINE void LBA_to_AMSF(int32 lba, uint8 *m_a, uint8 *s_a, uint8 *f_a)
static INLINE void LBA_to_AMSF(int32_t lba, uint8_t *m_a, uint8_t *s_a, uint8_t *f_a)
{
ABA_to_AMSF(LBA_to_ABA(lba), m_a, s_a, f_a);
}
@ -127,7 +132,7 @@ static INLINE void LBA_to_AMSF(int32 lba, uint8 *m_a, uint8 *s_a, uint8 *f_a)
//
// BCD conversion functions
//
static INLINE bool BCD_is_valid(uint8 bcd_number)
static INLINE bool BCD_is_valid(uint8_t bcd_number)
{
if((bcd_number & 0xF0) >= 0xA0)
return(false);
@ -138,18 +143,18 @@ static INLINE bool BCD_is_valid(uint8 bcd_number)
return(true);
}
static INLINE uint8 BCD_to_U8(uint8 bcd_number)
static INLINE uint8_t BCD_to_U8(uint8_t bcd_number)
{
return( ((bcd_number >> 4) * 10) + (bcd_number & 0x0F) );
}
static INLINE uint8 U8_to_BCD(uint8 num)
static INLINE uint8_t U8_to_BCD(uint8_t num)
{
return( ((num / 10) << 4) + (num % 10) );
}
// should always perform the conversion, even if the bcd number is invalid.
static INLINE bool BCD_to_U8_check(uint8 bcd_number, uint8 *out_number)
static INLINE bool BCD_to_U8_check(uint8_t bcd_number, uint8_t *out_number)
{
*out_number = BCD_to_U8(bcd_number);
@ -163,16 +168,16 @@ static INLINE bool BCD_to_U8_check(uint8 bcd_number, uint8 *out_number)
// Sector data encoding functions(to full 2352 bytes raw sector).
//
// sector_data must be able to contain at least 2352 bytes.
void encode_mode0_sector(uint32 aba, uint8 *sector_data);
void encode_mode1_sector(uint32 aba, uint8 *sector_data); // 2048 bytes of user data at offset 16
void encode_mode2_sector(uint32 aba, uint8 *sector_data); // 2336 bytes of user data at offset 16
void encode_mode2_form1_sector(uint32 aba, uint8 *sector_data); // 2048+8 bytes of user data at offset 16
void encode_mode2_form2_sector(uint32 aba, uint8 *sector_data); // 2324+8 bytes of user data at offset 16
void encode_mode0_sector(uint32_t aba, uint8_t *sector_data);
void encode_mode1_sector(uint32_t aba, uint8_t *sector_data); // 2048 bytes of user data at offset 16
void encode_mode2_sector(uint32_t aba, uint8_t *sector_data); // 2336 bytes of user data at offset 16
void encode_mode2_form1_sector(uint32_t aba, uint8_t *sector_data); // 2048+8 bytes of user data at offset 16
void encode_mode2_form2_sector(uint32_t aba, uint8_t *sector_data); // 2324+8 bytes of user data at offset 16
// out_buf must be able to contain 2352+96 bytes.
// "mode" is only used if(toc.tracks[100].control & 0x4)
void synth_leadout_sector_lba(const uint8 mode, const TOC& toc, const int32 lba, uint8* out_buf);
void synth_leadout_sector_lba(const uint8_t mode, const TOC& toc, const int32_t lba, uint8_t* out_buf);
//
// User data error detection and correction
@ -182,44 +187,41 @@ void synth_leadout_sector_lba(const uint8 mode, const TOC& toc, const int32 lba,
// Returns "true" if checksum is ok(matches).
// Returns "false" if checksum mismatch.
// sector_data should contain 2352 bytes of raw sector data.
bool edc_check(const uint8 *sector_data, bool xa);
bool edc_check(const uint8_t *sector_data, bool xa);
// Check EDC and L-EC data of a mode 1 or mode 2 form 1 sector, and correct bit errors if any exist.
// Returns "true" if errors weren't detected, or they were corrected succesfully.
// Returns "false" if errors couldn't be corrected.
// sector_data should contain 2352 bytes of raw sector data.
bool edc_lec_check_and_correct(uint8 *sector_data, bool xa);
bool edc_lec_check_and_correct(uint8_t *sector_data, bool xa);
//
// Subchannel(Q in particular) functions
//
// Returns false on checksum mismatch, true on match.
bool subq_check_checksum(const uint8 *subq_buf);
bool subq_check_checksum(const uint8_t *subq_buf);
// Calculates the checksum of Q subchannel data(not including the checksum bytes of course ;)) from subq_buf, and stores it into the appropriate position
// in subq_buf.
void subq_generate_checksum(uint8 *subq_buf);
void subq_generate_checksum(uint8_t *subq_buf);
// Deinterleaves 12 bytes of subchannel Q data from 96 bytes of interleaved subchannel PW data.
void subq_deinterleave(const uint8 *subpw_buf, uint8 *subq_buf);
void subq_deinterleave(const uint8_t *subpw_buf, uint8_t *subq_buf);
// Deinterleaves 96 bytes of subchannel P-W data from 96 bytes of interleaved subchannel PW data.
void subpw_deinterleave(const uint8 *in_buf, uint8 *out_buf);
void subpw_deinterleave(const uint8_t *in_buf, uint8_t *out_buf);
// Interleaves 96 bytes of subchannel P-W data from 96 bytes of uninterleaved subchannel PW data.
void subpw_interleave(const uint8 *in_buf, uint8 *out_buf);
void subpw_interleave(const uint8_t *in_buf, uint8_t *out_buf);
// Extrapolates Q subchannel current position data from subq_input, with frame/sector delta position_delta, and writes to subq_output.
// Only valid for ADR_CURPOS.
// subq_input must pass subq_check_checksum().
// TODO
//void subq_extrapolate(const uint8 *subq_input, int32 position_delta, uint8 *subq_output);
//void subq_extrapolate(const uint8_t *subq_input, int32_t position_delta, uint8_t *subq_output);
// (De)Scrambles data sector.
void scrambleize_data_sector(uint8 *sector_data);
void MDFN_strtoupper(std::string &str);
void MDFN_strtoupper(char *str);
void scrambleize_data_sector(uint8_t *sector_data);
#endif

28
mednafen/cdrom/misc.cpp Normal file
View File

@ -0,0 +1,28 @@
#include <stdint.h>
#include <string.h>
#include <string>
#include "misc.h"
void MDFN_strtoupper(char *str)
{
size_t x;
for(x = 0; str[x]; x++)
{
if(str[x] >= 'a' && str[x] <= 'z')
str[x] = str[x] - 'a' + 'A';
}
}
void MDFN_strtoupper(std::string &str)
{
size_t x;
const size_t len = str.length();
for(x = 0; x < len; x++)
{
if(str[x] >= 'a' && str[x] <= 'z')
str[x] = str[x] - 'a' + 'A';
}
}

7
mednafen/cdrom/misc.h Normal file
View File

@ -0,0 +1,7 @@
#ifndef __MDFN_CDROM_MISC_H
#define __MDFN_CDROM_MISC_H
void MDFN_strtoupper(std::string &str);
void MDFN_strtoupper(char *str);
#endif