1 // license:BSD-3-Clause
2 // copyright-holders:Aaron Giles
3 /***************************************************************************
4
5 cdrom.h
6
7 Generic MAME cd-rom implementation
8
9 ***************************************************************************/
10
11 #ifndef MAME_UTIL_CDROM_H
12 #define MAME_UTIL_CDROM_H
13
14 #pragma once
15
16 #include "osdcore.h"
17 #include "chd.h"
18
19
20
21 /***************************************************************************
22 CONSTANTS
23 ***************************************************************************/
24
25 // tracks are padded to a multiple of this many frames
26 const uint32_t CD_TRACK_PADDING = 4;
27
28 #define CD_MAX_TRACKS (99) /* AFAIK the theoretical limit */
29 #define CD_MAX_SECTOR_DATA (2352)
30 #define CD_MAX_SUBCODE_DATA (96)
31
32 #define CD_FRAME_SIZE (CD_MAX_SECTOR_DATA + CD_MAX_SUBCODE_DATA)
33 #define CD_FRAMES_PER_HUNK (8)
34
35 #define CD_METADATA_WORDS (1+(CD_MAX_TRACKS * 6))
36
37 enum
38 {
39 CD_TRACK_MODE1 = 0, /* mode 1 2048 bytes/sector */
40 CD_TRACK_MODE1_RAW, /* mode 1 2352 bytes/sector */
41 CD_TRACK_MODE2, /* mode 2 2336 bytes/sector */
42 CD_TRACK_MODE2_FORM1, /* mode 2 2048 bytes/sector */
43 CD_TRACK_MODE2_FORM2, /* mode 2 2324 bytes/sector */
44 CD_TRACK_MODE2_FORM_MIX, /* mode 2 2336 bytes/sector */
45 CD_TRACK_MODE2_RAW, /* mode 2 2352 bytes / sector */
46 CD_TRACK_AUDIO, /* redbook audio track 2352 bytes/sector (588 samples) */
47
48 CD_TRACK_RAW_DONTCARE /* special flag for cdrom_read_data: just return me whatever is there */
49 };
50
51 enum
52 {
53 CD_SUB_NORMAL = 0, /* "cooked" 96 bytes per sector */
54 CD_SUB_RAW, /* raw uninterleaved 96 bytes per sector */
55 CD_SUB_NONE /* no subcode data stored */
56 };
57
58 #define CD_FLAG_GDROM 0x00000001 // disc is a GD-ROM, all tracks should be stored with GD-ROM metadata
59 #define CD_FLAG_GDROMLE 0x00000002 // legacy GD-ROM, with little-endian CDDA data
60
61 /***************************************************************************
62 TYPE DEFINITIONS
63 ***************************************************************************/
64
65 struct cdrom_file;
66
67 struct cdrom_track_info
68 {
69 /* fields used by CHDMAN and in MAME */
70 uint32_t trktype; /* track type */
71 uint32_t subtype; /* subcode data type */
72 uint32_t datasize; /* size of data in each sector of this track */
73 uint32_t subsize; /* size of subchannel data in each sector of this track */
74 uint32_t frames; /* number of frames in this track */
75 uint32_t extraframes; /* number of "spillage" frames in this track */
76 uint32_t pregap; /* number of pregap frames */
77 uint32_t postgap; /* number of postgap frames */
78 uint32_t pgtype; /* type of sectors in pregap */
79 uint32_t pgsub; /* type of subchannel data in pregap */
80 uint32_t pgdatasize; /* size of data in each sector of the pregap */
81 uint32_t pgsubsize; /* size of subchannel data in each sector of the pregap */
82
83 /* fields used in CHDMAN only */
84 uint32_t padframes; /* number of frames of padding to add to the end of the track; needed for GDI */
85
86 /* fields used in MAME/MESS only */
87 uint32_t logframeofs; /* logical frame of actual track data - offset by pregap size if pregap not physically present */
88 uint32_t physframeofs; /* physical frame of actual track data in CHD data */
89 uint32_t chdframeofs; /* frame number this track starts at on the CHD */
90 };
91
92
93 struct cdrom_toc
94 {
95 uint32_t numtrks; /* number of tracks */
96 uint32_t flags; /* see FLAG_ above */
97 cdrom_track_info tracks[CD_MAX_TRACKS];
98 };
99
100
101
102 /***************************************************************************
103 FUNCTION PROTOTYPES
104 ***************************************************************************/
105
106 /* base functionality */
107 cdrom_file *cdrom_open(chd_file *chd);
108 void cdrom_close(cdrom_file *file);
109
110 cdrom_file *cdrom_open(const char *inputfile);
111
112 /* core read access */
113 uint32_t cdrom_read_data(cdrom_file *file, uint32_t lbasector, void *buffer, uint32_t datatype, bool phys=false);
114 uint32_t cdrom_read_subcode(cdrom_file *file, uint32_t lbasector, void *buffer, bool phys=false);
115
116 /* handy utilities */
117 uint32_t cdrom_get_track(cdrom_file *file, uint32_t frame);
118 uint32_t cdrom_get_track_start(cdrom_file *file, uint32_t track);
119 uint32_t cdrom_get_track_start_phys(cdrom_file *file, uint32_t track);
120 chd_file *cdrom_get_chd(cdrom_file *file);
121
122 /* TOC utilities */
123 int cdrom_get_last_track(cdrom_file *file);
124 int cdrom_get_adr_control(cdrom_file *file, int track);
125 int cdrom_get_track_type(cdrom_file *file, int track);
126 const cdrom_toc *cdrom_get_toc(cdrom_file *file);
127
128 /* extra utilities */
129 void cdrom_convert_type_string_to_track_info(const char *typestring, cdrom_track_info *info);
130 void cdrom_convert_type_string_to_pregap_info(const char *typestring, cdrom_track_info *info);
131 void cdrom_convert_subtype_string_to_track_info(const char *typestring, cdrom_track_info *info);
132 void cdrom_convert_subtype_string_to_pregap_info(const char *typestring, cdrom_track_info *info);
133 const char *cdrom_get_type_string(uint32_t trktype);
134 const char *cdrom_get_subtype_string(uint32_t subtype);
135 chd_error cdrom_parse_metadata(chd_file *chd, cdrom_toc *toc);
136 chd_error cdrom_write_metadata(chd_file *chd, const cdrom_toc *toc);
137
138 // ECC utilities
139 bool ecc_verify(const uint8_t *sector);
140 void ecc_generate(uint8_t *sector);
141 void ecc_clear(uint8_t *sector);
142
143
144
145 /***************************************************************************
146 INLINE FUNCTIONS
147 ***************************************************************************/
148
msf_to_lba(uint32_t msf)149 static inline uint32_t msf_to_lba(uint32_t msf)
150 {
151 return ( ((msf&0x00ff0000)>>16) * 60 * 75) + (((msf&0x0000ff00)>>8) * 75) + ((msf&0x000000ff)>>0);
152 }
153
lba_to_msf(uint32_t lba)154 static inline uint32_t lba_to_msf(uint32_t lba)
155 {
156 uint8_t m, s, f;
157
158 m = lba / (60 * 75);
159 lba -= m * (60 * 75);
160 s = lba / 75;
161 f = lba % 75;
162
163 return ((m / 10) << 20) | ((m % 10) << 16) |
164 ((s / 10) << 12) | ((s % 10) << 8) |
165 ((f / 10) << 4) | ((f % 10) << 0);
166 }
167
168 // segacd needs it like this.. investigate
169 // Angelo also says PCE tracks often start playing at the
170 // wrong address.. related?
lba_to_msf_alt(int lba)171 static inline uint32_t lba_to_msf_alt(int lba)
172 {
173 uint32_t ret = 0;
174
175 ret |= ((lba / (60 * 75))&0xff)<<16;
176 ret |= (((lba / 75) % 60)&0xff)<<8;
177 ret |= ((lba % 75)&0xff)<<0;
178
179 return ret;
180 }
181
182 #endif // MAME_UTIL_CDROM_H
183