Mercurial > repos > blastem
comparison ym2612.c @ 1904:8312e574100a
Implement selectable YM2612/YM3834 invalid status port behavior
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Wed, 26 Feb 2020 22:40:37 -0800 |
parents | 32a3aa7b4a45 |
children | 508522f08e4d |
comparison
equal
deleted
inserted
replaced
1903:62166274e6c0 | 1904:8312e574100a |
---|---|
130 } | 130 } |
131 if (context->busy_start != CYCLE_NEVER && context->busy_start >= deduction) { | 131 if (context->busy_start != CYCLE_NEVER && context->busy_start >= deduction) { |
132 context->busy_start -= deduction; | 132 context->busy_start -= deduction; |
133 } else { | 133 } else { |
134 context->busy_start = CYCLE_NEVER; | 134 context->busy_start = CYCLE_NEVER; |
135 } | |
136 if (context->last_status_cycle != CYCLE_NEVER && context->last_status_cycle >= deduction) { | |
137 context->last_status_cycle -= deduction; | |
138 } else { | |
139 context->last_status = 0; | |
140 context->last_status_cycle = CYCLE_NEVER; | |
135 } | 141 } |
136 } | 142 } |
137 | 143 |
138 #ifdef __ANDROID__ | 144 #ifdef __ANDROID__ |
139 #define log2(x) (log(x)/log(2)) | 145 #define log2(x) (log(x)/log(2)) |
186 dfopen(debug_file, "ym_debug.txt", "w"); | 192 dfopen(debug_file, "ym_debug.txt", "w"); |
187 memset(context, 0, sizeof(*context)); | 193 memset(context, 0, sizeof(*context)); |
188 context->clock_inc = clock_div * 6; | 194 context->clock_inc = clock_div * 6; |
189 context->busy_cycles = BUSY_CYCLES * context->clock_inc; | 195 context->busy_cycles = BUSY_CYCLES * context->clock_inc; |
190 context->audio = render_audio_source(master_clock, context->clock_inc * NUM_OPERATORS, 2); | 196 context->audio = render_audio_source(master_clock, context->clock_inc * NUM_OPERATORS, 2); |
197 //TODO: pick a randomish high initial value and lower it over time | |
198 context->invalid_status_decay = 225000 * context->clock_inc; | |
199 context->status_address_mask = (options & YM_OPT_3834) ? 0 : 3; | |
191 | 200 |
192 //some games seem to expect that the LR flags start out as 1 | 201 //some games seem to expect that the LR flags start out as 1 |
193 for (int i = 0; i < NUM_CHANNELS; i++) { | 202 for (int i = 0; i < NUM_CHANNELS; i++) { |
194 if (options & YM_OPT_WAVE_LOG) { | 203 if (options & YM_OPT_WAVE_LOG) { |
195 char fname[64]; | 204 char fname[64]; |
1115 } | 1124 } |
1116 } | 1125 } |
1117 } | 1126 } |
1118 } | 1127 } |
1119 | 1128 |
1120 uint8_t ym_read_status(ym2612_context * context, uint32_t cycle) | 1129 uint8_t ym_read_status(ym2612_context * context, uint32_t cycle, uint32_t port) |
1121 { | 1130 { |
1122 uint8_t status = context->status; | 1131 uint8_t status; |
1123 if (cycle >= context->busy_start && cycle < context->busy_start + context->busy_cycles) { | 1132 port &= context->status_address_mask; |
1124 status |= 0x80; | 1133 if (port) { |
1134 if (context->last_status_cycle != CYCLE_NEVER && cycle - context->last_status_cycle > context->invalid_status_decay) { | |
1135 context->last_status = 0; | |
1136 } | |
1137 status = context->last_status; | |
1138 } else { | |
1139 status = context->status; | |
1140 if (cycle >= context->busy_start && cycle < context->busy_start + context->busy_cycles) { | |
1141 status |= 0x80; | |
1142 } | |
1143 context->last_status = status; | |
1144 context->last_status_cycle = cycle; | |
1125 } | 1145 } |
1126 return status; | 1146 return status; |
1147 | |
1127 } | 1148 } |
1128 | 1149 |
1129 void ym_print_channel_info(ym2612_context *context, int channel) | 1150 void ym_print_channel_info(ym2612_context *context, int channel) |
1130 { | 1151 { |
1131 ym_channel *chan = context->channels + channel; | 1152 ym_channel *chan = context->channels + channel; |
1234 save_int8(buf, context->selected_reg); | 1255 save_int8(buf, context->selected_reg); |
1235 save_int8(buf, context->selected_part); | 1256 save_int8(buf, context->selected_part); |
1236 save_int32(buf, context->current_cycle); | 1257 save_int32(buf, context->current_cycle); |
1237 save_int32(buf, context->write_cycle); | 1258 save_int32(buf, context->write_cycle); |
1238 save_int32(buf, context->busy_start); | 1259 save_int32(buf, context->busy_start); |
1260 save_int32(buf, context->last_status_cycle); | |
1261 save_int32(buf, context->invalid_status_decay); | |
1262 save_int8(buf, context->last_status); | |
1239 } | 1263 } |
1240 | 1264 |
1241 void ym_deserialize(deserialize_buffer *buf, void *vcontext) | 1265 void ym_deserialize(deserialize_buffer *buf, void *vcontext) |
1242 { | 1266 { |
1243 ym2612_context *context = vcontext; | 1267 ym2612_context *context = vcontext; |
1309 context->selected_reg = load_int8(buf); | 1333 context->selected_reg = load_int8(buf); |
1310 context->selected_part = load_int8(buf); | 1334 context->selected_part = load_int8(buf); |
1311 context->current_cycle = load_int32(buf); | 1335 context->current_cycle = load_int32(buf); |
1312 context->write_cycle = load_int32(buf); | 1336 context->write_cycle = load_int32(buf); |
1313 context->busy_start = load_int32(buf); | 1337 context->busy_start = load_int32(buf); |
1314 } | 1338 if (buf->size > buf->cur_pos) { |
1339 context->last_status_cycle = load_int32(buf); | |
1340 context->invalid_status_decay = load_int32(buf); | |
1341 context->last_status = load_int8(buf); | |
1342 } else { | |
1343 context->last_status = context->status; | |
1344 context->last_status_cycle = context->write_cycle; | |
1345 } | |
1346 } |