trunk/src/emu/sound/ymf271.c
| r23978 | r23979 | |
| 17 | 17 | - Src B and Src NOTE bits |
| 18 | 18 | - statusreg Busy and End bits |
| 19 | 19 | - timer register 0x11 |
| 20 | - ch2/ch3 (4 speakers) |
| 21 | - PFM (FM using external PCM waveform) |
| 22 | - detune |
| 23 | - Acc On bit |
| 20 | 24 | - Is memory handling 100% correct? At the moment, seibuspi.c is the only |
| 21 | 25 | hardware currently emulated that uses external handlers. |
| 22 | | - oh, and a lot more... |
| 23 | 26 | */ |
| 24 | 27 | |
| 25 | 28 | #include "emu.h" |
| 26 | 29 | #include "ymf271.h" |
| 27 | 30 | |
| 28 | | #define VERBOSE (1) |
| 31 | #define MAXOUT (+32767) |
| 32 | #define MINOUT (-32768) |
| 29 | 33 | |
| 30 | | #define MAXOUT (+32767) |
| 31 | | #define MINOUT (-32768) |
| 32 | | |
| 33 | 34 | #define SIN_BITS 10 |
| 34 | 35 | #define SIN_LEN (1<<SIN_BITS) |
| 35 | 36 | #define SIN_MASK (SIN_LEN-1) |
| r23978 | r23979 | |
| 41 | 42 | #define ALFO_MAX (+65536) |
| 42 | 43 | #define ALFO_MIN (0) |
| 43 | 44 | |
| 44 | | //#define log2(n) (log((float) n)/log((float) 2)) |
| 45 | | |
| 46 | 45 | // slot mapping assists |
| 47 | | static const int fm_tab[] = { 0, 1, 2, -1, 3, 4, 5, -1, 6, 7, 8, -1, 9, 10, 11, -1 }; |
| 48 | | static const int pcm_tab[] = { 0, 4, 8, -1, 12, 16, 20, -1, 24, 28, 32, -1, 36, 40, 44, -1 }; |
| 46 | static const int fm_tab[16] = { 0, 1, 2, -1, 3, 4, 5, -1, 6, 7, 8, -1, 9, 10, 11, -1 }; |
| 47 | static const int pcm_tab[16] = { 0, 4, 8, -1, 12, 16, 20, -1, 24, 28, 32, -1, 36, 40, 44, -1 }; |
| 49 | 48 | |
| 50 | 49 | static INT16 *wavetable[8]; |
| 51 | 50 | static double plfo_table[4][8][LFO_LENGTH]; |
| r23978 | r23979 | |
| 241 | 240 | |
| 242 | 241 | INLINE int GET_EXTERNAL_KEYCODE(int block, int fns) |
| 243 | 242 | { |
| 244 | | /* TODO: SrcB and SrcNote !? */ |
| 245 | 243 | int n43; |
| 246 | 244 | if (fns < 0x100) |
| 247 | 245 | { |
| r23978 | r23979 | |
| 320 | 318 | int decay_level = 255 - (slot->decay1lvl << 4); |
| 321 | 319 | slot->volume -= slot->env_decay1_step; |
| 322 | 320 | |
| 323 | | if ((slot->volume >> (ENV_VOLUME_SHIFT)) <= decay_level) |
| 321 | if ((slot->volume >> ENV_VOLUME_SHIFT) <= decay_level) |
| 324 | 322 | { |
| 325 | 323 | slot->env_state = ENV_DECAY2; |
| 326 | 324 | } |
| r23978 | r23979 | |
| 331 | 329 | { |
| 332 | 330 | slot->volume -= slot->env_decay2_step; |
| 333 | 331 | |
| 334 | | if (slot->volume < 0) |
| 332 | if (slot->volume <= 0) |
| 335 | 333 | { |
| 334 | slot->active = 0; |
| 336 | 335 | slot->volume = 0; |
| 337 | 336 | } |
| 338 | 337 | break; |
| r23978 | r23979 | |
| 342 | 341 | { |
| 343 | 342 | slot->volume -= slot->env_release_step; |
| 344 | 343 | |
| 345 | | if (slot->volume <= (0 << ENV_VOLUME_SHIFT)) |
| 344 | if (slot->volume <= 0) |
| 346 | 345 | { |
| 347 | 346 | slot->active = 0; |
| 348 | 347 | slot->volume = 0; |
| r23978 | r23979 | |
| 366 | 365 | } |
| 367 | 366 | else |
| 368 | 367 | { |
| 369 | | keycode = GET_EXTERNAL_KEYCODE(slot->block, slot->fns); |
| 368 | keycode = GET_EXTERNAL_KEYCODE(slot->block, slot->fns & 0x7ff); |
| 369 | /* keycode = (keycode + slot->srcb * 4 + slot->srcnote) / 2; */ // not sure |
| 370 | 370 | } |
| 371 | 371 | |
| 372 | 372 | // init attack state |
| r23978 | r23979 | |
| 994 | 994 | update_pcm(j + (3*12), mixp, samples); |
| 995 | 995 | break; |
| 996 | 996 | } |
| 997 | | |
| 998 | | default: break; |
| 999 | 997 | } |
| 1000 | 998 | } |
| 1001 | 999 | |
| r23978 | r23979 | |
| 1014 | 1012 | switch (reg) |
| 1015 | 1013 | { |
| 1016 | 1014 | case 0: |
| 1017 | | { |
| 1018 | 1015 | slot->ext_en = (data & 0x80) ? 1 : 0; |
| 1019 | 1016 | slot->ext_out = (data>>3)&0xf; |
| 1020 | 1017 | |
| r23978 | r23979 | |
| 1040 | 1037 | } |
| 1041 | 1038 | } |
| 1042 | 1039 | break; |
| 1043 | | } |
| 1044 | 1040 | |
| 1045 | 1041 | case 1: |
| 1046 | | { |
| 1047 | 1042 | slot->lfoFreq = data; |
| 1048 | 1043 | break; |
| 1049 | | } |
| 1050 | 1044 | |
| 1051 | 1045 | case 2: |
| 1052 | | { |
| 1053 | 1046 | slot->lfowave = data & 3; |
| 1054 | 1047 | slot->pms = (data >> 3) & 0x7; |
| 1055 | 1048 | slot->ams = (data >> 6) & 0x3; |
| 1056 | 1049 | break; |
| 1057 | | } |
| 1058 | 1050 | |
| 1059 | 1051 | case 3: |
| 1060 | | { |
| 1061 | 1052 | slot->multiple = data & 0xf; |
| 1062 | 1053 | slot->detune = (data >> 4) & 0x7; |
| 1063 | 1054 | break; |
| 1064 | | } |
| 1065 | 1055 | |
| 1066 | 1056 | case 4: |
| 1067 | | { |
| 1068 | 1057 | slot->tl = data & 0x7f; |
| 1069 | 1058 | break; |
| 1070 | | } |
| 1071 | 1059 | |
| 1072 | 1060 | case 5: |
| 1073 | | { |
| 1074 | 1061 | slot->ar = data & 0x1f; |
| 1075 | 1062 | slot->keyscale = (data>>5)&0x7; |
| 1076 | 1063 | break; |
| 1077 | | } |
| 1078 | 1064 | |
| 1079 | 1065 | case 6: |
| 1080 | | { |
| 1081 | 1066 | slot->decay1rate = data & 0x1f; |
| 1082 | 1067 | break; |
| 1083 | | } |
| 1084 | 1068 | |
| 1085 | 1069 | case 7: |
| 1086 | | { |
| 1087 | 1070 | slot->decay2rate = data & 0x1f; |
| 1088 | 1071 | break; |
| 1089 | | } |
| 1090 | 1072 | |
| 1091 | 1073 | case 8: |
| 1092 | | { |
| 1093 | 1074 | slot->relrate = data & 0xf; |
| 1094 | 1075 | slot->decay1lvl = (data >> 4) & 0xf; |
| 1095 | 1076 | break; |
| 1096 | | } |
| 1097 | 1077 | |
| 1098 | 1078 | case 9: |
| 1099 | | { |
| 1100 | 1079 | slot->fns &= ~0xff; |
| 1101 | 1080 | slot->fns |= data; |
| 1102 | 1081 | break; |
| 1103 | | } |
| 1104 | 1082 | |
| 1105 | 1083 | case 10: |
| 1106 | | { |
| 1107 | 1084 | slot->fns &= ~0xff00; |
| 1108 | 1085 | slot->fns |= (data & 0xf)<<8; |
| 1109 | 1086 | slot->block = (data>>4)&0xf; |
| 1110 | 1087 | break; |
| 1111 | | } |
| 1112 | 1088 | |
| 1113 | 1089 | case 11: |
| 1114 | | { |
| 1115 | 1090 | slot->waveform = data & 0x7; |
| 1116 | 1091 | slot->feedback = (data >> 4) & 0x7; |
| 1117 | 1092 | slot->accon = (data & 0x80) ? 1 : 0; |
| 1118 | 1093 | break; |
| 1119 | | } |
| 1120 | 1094 | |
| 1121 | 1095 | case 12: |
| 1122 | | { |
| 1123 | 1096 | slot->algorithm = data & 0xf; |
| 1124 | 1097 | break; |
| 1125 | | } |
| 1126 | 1098 | |
| 1127 | 1099 | case 13: |
| 1128 | | { |
| 1129 | 1100 | slot->ch0_level = data >> 4; |
| 1130 | 1101 | slot->ch1_level = data & 0xf; |
| 1131 | 1102 | break; |
| 1132 | | } |
| 1133 | 1103 | |
| 1134 | 1104 | case 14: |
| 1135 | | { |
| 1136 | 1105 | slot->ch2_level = data >> 4; |
| 1137 | 1106 | slot->ch3_level = data & 0xf; |
| 1138 | 1107 | break; |
| 1139 | | } |
| 1140 | 1108 | |
| 1141 | 1109 | default: |
| 1142 | 1110 | break; |
| 1143 | 1111 | } |
| 1144 | 1112 | } |
| 1145 | 1113 | |
| 1146 | | void ymf271_device::ymf271_write_fm(int grp, int adr, int data) |
| 1114 | void ymf271_device::ymf271_write_fm(int bank, int address, int data) |
| 1147 | 1115 | { |
| 1148 | | int reg; |
| 1149 | | //int slotnum; |
| 1150 | | int slot_group; |
| 1151 | | int sync_mode, sync_reg; |
| 1152 | | //YMF271Slot *slot; |
| 1116 | int groupnum = fm_tab[address & 0xf]; |
| 1117 | if (groupnum == -1) |
| 1118 | { |
| 1119 | logerror("ymf271_write_fm invalid group %02X\n", data); |
| 1120 | return; |
| 1121 | } |
| 1153 | 1122 | |
| 1154 | | //slotnum = 12*grp; |
| 1155 | | //slotnum += fm_tab[adr & 0xf]; |
| 1156 | | //slot = &m_slots[slotnum]; |
| 1157 | | slot_group = fm_tab[adr & 0xf]; |
| 1123 | int reg = (address >> 4) & 0xf; |
| 1158 | 1124 | |
| 1159 | | reg = (adr >> 4) & 0xf; |
| 1160 | | |
| 1161 | 1125 | // check if the register is a synchronized register |
| 1162 | | sync_reg = 0; |
| 1126 | int sync_reg = 0; |
| 1163 | 1127 | switch (reg) |
| 1164 | 1128 | { |
| 1165 | 1129 | case 0: |
| r23978 | r23979 | |
| 1176 | 1140 | } |
| 1177 | 1141 | |
| 1178 | 1142 | // check if the slot is key on slot for synchronizing |
| 1179 | | sync_mode = 0; |
| 1180 | | switch (m_groups[slot_group].sync) |
| 1143 | int sync_mode = 0; |
| 1144 | switch (m_groups[groupnum].sync) |
| 1181 | 1145 | { |
| 1182 | 1146 | case 0: // 4 slot mode |
| 1183 | 1147 | { |
| 1184 | | if (grp == 0) |
| 1148 | if (bank == 0) |
| 1185 | 1149 | sync_mode = 1; |
| 1186 | 1150 | break; |
| 1187 | 1151 | } |
| 1188 | 1152 | case 1: // 2x 2 slot mode |
| 1189 | 1153 | { |
| 1190 | | if (grp == 0 || grp == 1) |
| 1154 | if (bank == 0 || bank == 1) |
| 1191 | 1155 | sync_mode = 1; |
| 1192 | 1156 | break; |
| 1193 | 1157 | } |
| 1194 | 1158 | case 2: // 3 slot + 1 slot mode |
| 1195 | 1159 | { |
| 1196 | | if (grp == 0) |
| 1160 | if (bank == 0) |
| 1197 | 1161 | sync_mode = 1; |
| 1198 | 1162 | break; |
| 1199 | 1163 | } |
| r23978 | r23979 | |
| 1204 | 1168 | |
| 1205 | 1169 | if (sync_mode && sync_reg) // key-on slot & synced register |
| 1206 | 1170 | { |
| 1207 | | switch (m_groups[slot_group].sync) |
| 1171 | switch (m_groups[groupnum].sync) |
| 1208 | 1172 | { |
| 1209 | 1173 | case 0: // 4 slot mode |
| 1210 | 1174 | { |
| 1211 | | write_register((12 * 0) + slot_group, reg, data); |
| 1212 | | write_register((12 * 1) + slot_group, reg, data); |
| 1213 | | write_register((12 * 2) + slot_group, reg, data); |
| 1214 | | write_register((12 * 3) + slot_group, reg, data); |
| 1175 | write_register((12 * 0) + groupnum, reg, data); |
| 1176 | write_register((12 * 1) + groupnum, reg, data); |
| 1177 | write_register((12 * 2) + groupnum, reg, data); |
| 1178 | write_register((12 * 3) + groupnum, reg, data); |
| 1215 | 1179 | break; |
| 1216 | 1180 | } |
| 1217 | 1181 | case 1: // 2x 2 slot mode |
| 1218 | 1182 | { |
| 1219 | | if (grp == 0) // Slot 1 - Slot 3 |
| 1183 | if (bank == 0) // Slot 1 - Slot 3 |
| 1220 | 1184 | { |
| 1221 | | write_register((12 * 0) + slot_group, reg, data); |
| 1222 | | write_register((12 * 2) + slot_group, reg, data); |
| 1185 | write_register((12 * 0) + groupnum, reg, data); |
| 1186 | write_register((12 * 2) + groupnum, reg, data); |
| 1223 | 1187 | } |
| 1224 | 1188 | else // Slot 2 - Slot 4 |
| 1225 | 1189 | { |
| 1226 | | write_register((12 * 1) + slot_group, reg, data); |
| 1227 | | write_register((12 * 3) + slot_group, reg, data); |
| 1190 | write_register((12 * 1) + groupnum, reg, data); |
| 1191 | write_register((12 * 3) + groupnum, reg, data); |
| 1228 | 1192 | } |
| 1229 | 1193 | break; |
| 1230 | 1194 | } |
| 1231 | 1195 | case 2: // 3 slot + 1 slot mode |
| 1232 | 1196 | { |
| 1233 | 1197 | // 1 slot is handled normally |
| 1234 | | write_register((12 * 0) + slot_group, reg, data); |
| 1235 | | write_register((12 * 1) + slot_group, reg, data); |
| 1236 | | write_register((12 * 2) + slot_group, reg, data); |
| 1198 | write_register((12 * 0) + groupnum, reg, data); |
| 1199 | write_register((12 * 1) + groupnum, reg, data); |
| 1200 | write_register((12 * 2) + groupnum, reg, data); |
| 1237 | 1201 | break; |
| 1238 | 1202 | } |
| 1239 | | default: |
| 1240 | | break; |
| 1241 | 1203 | } |
| 1242 | 1204 | } |
| 1243 | 1205 | else // write register normally |
| 1244 | 1206 | { |
| 1245 | | write_register((12 * grp) + slot_group, reg, data); |
| 1207 | write_register((12 * bank) + groupnum, reg, data); |
| 1246 | 1208 | } |
| 1247 | 1209 | } |
| 1248 | 1210 | |
| 1249 | 1211 | void ymf271_device::ymf271_write_pcm(int data) |
| 1250 | 1212 | { |
| 1251 | | int slotnum; |
| 1252 | | YMF271Slot *slot; |
| 1213 | int slotnum = pcm_tab[m_pcmreg & 0xf]; |
| 1214 | if (slotnum == -1) |
| 1215 | { |
| 1216 | logerror("ymf271_write_pcm invalid slot %02X\n", data); |
| 1217 | return; |
| 1218 | } |
| 1219 | YMF271Slot *slot = &m_slots[slotnum]; |
| 1253 | 1220 | |
| 1254 | | slotnum = pcm_tab[m_pcmreg&0xf]; |
| 1255 | | slot = &m_slots[slotnum]; |
| 1256 | | |
| 1257 | | switch ((m_pcmreg>>4)&0xf) |
| 1221 | switch (m_pcmreg >> 4 & 0xf) |
| 1258 | 1222 | { |
| 1259 | 1223 | case 0: |
| 1260 | 1224 | slot->startaddr &= ~0xff; |
| 1261 | 1225 | slot->startaddr |= data; |
| 1262 | 1226 | break; |
| 1227 | |
| 1263 | 1228 | case 1: |
| 1264 | 1229 | slot->startaddr &= ~0xff00; |
| 1265 | 1230 | slot->startaddr |= data<<8; |
| 1266 | 1231 | break; |
| 1232 | |
| 1267 | 1233 | case 2: |
| 1268 | 1234 | slot->startaddr &= ~0xff0000; |
| 1269 | 1235 | slot->startaddr |= (data & 0x7f)<<16; |
| 1270 | 1236 | slot->altloop = (data & 0x80) ? 1 : 0; |
| 1271 | 1237 | break; |
| 1238 | |
| 1272 | 1239 | case 3: |
| 1273 | 1240 | slot->endaddr &= ~0xff; |
| 1274 | 1241 | slot->endaddr |= data; |
| 1275 | 1242 | break; |
| 1243 | |
| 1276 | 1244 | case 4: |
| 1277 | 1245 | slot->endaddr &= ~0xff00; |
| 1278 | 1246 | slot->endaddr |= data<<8; |
| 1279 | 1247 | break; |
| 1248 | |
| 1280 | 1249 | case 5: |
| 1281 | 1250 | slot->endaddr &= ~0xff0000; |
| 1282 | 1251 | slot->endaddr |= (data & 0x7f)<<16; |
| 1283 | 1252 | break; |
| 1253 | |
| 1284 | 1254 | case 6: |
| 1285 | 1255 | slot->loopaddr &= ~0xff; |
| 1286 | 1256 | slot->loopaddr |= data; |
| 1287 | 1257 | break; |
| 1258 | |
| 1288 | 1259 | case 7: |
| 1289 | 1260 | slot->loopaddr &= ~0xff00; |
| 1290 | 1261 | slot->loopaddr |= data<<8; |
| 1291 | 1262 | break; |
| 1263 | |
| 1292 | 1264 | case 8: |
| 1293 | 1265 | slot->loopaddr &= ~0xff0000; |
| 1294 | 1266 | slot->loopaddr |= (data & 0x7f)<<16; |
| 1295 | 1267 | break; |
| 1268 | |
| 1296 | 1269 | case 9: |
| 1297 | 1270 | slot->fs = data & 0x3; |
| 1298 | 1271 | slot->bits = (data & 0x4) ? 12 : 8; |
| 1299 | 1272 | slot->srcnote = (data >> 3) & 0x3; |
| 1300 | 1273 | slot->srcb = (data >> 5) & 0x7; |
| 1301 | 1274 | break; |
| 1275 | |
| 1302 | 1276 | default: |
| 1303 | 1277 | break; |
| 1304 | 1278 | } |
| r23978 | r23979 | |
| 1308 | 1282 | { |
| 1309 | 1283 | switch(id) |
| 1310 | 1284 | { |
| 1311 | | case 0: |
| 1312 | | m_status |= 1; |
| 1285 | case 0: |
| 1286 | m_status |= 1; |
| 1313 | 1287 | |
| 1314 | | // assert IRQ |
| 1315 | | if (m_enable & 4) |
| 1316 | | { |
| 1317 | | m_irqstate |= 1; |
| 1288 | // assert IRQ |
| 1289 | if (m_enable & 4) |
| 1290 | { |
| 1291 | m_irqstate |= 1; |
| 1318 | 1292 | |
| 1319 | | if (!m_irq_handler.isnull()) |
| 1320 | | m_irq_handler(1); |
| 1321 | | } |
| 1293 | if (!m_irq_handler.isnull()) |
| 1294 | m_irq_handler(1); |
| 1295 | } |
| 1322 | 1296 | |
| 1323 | | // reload timer |
| 1324 | | m_timA->adjust(attotime::from_hz(m_clock) * (384 * 4 * (256 - m_timerA)), 0); |
| 1325 | | break; |
| 1297 | // reload timer |
| 1298 | m_timA->adjust(attotime::from_hz(m_clock) * (384 * 4 * (256 - m_timerA)), 0); |
| 1299 | break; |
| 1326 | 1300 | |
| 1327 | | case 1: |
| 1328 | | m_status |= 2; |
| 1301 | case 1: |
| 1302 | m_status |= 2; |
| 1329 | 1303 | |
| 1330 | | // assert IRQ |
| 1331 | | if (m_enable & 8) |
| 1332 | | { |
| 1333 | | m_irqstate |= 2; |
| 1304 | // assert IRQ |
| 1305 | if (m_enable & 8) |
| 1306 | { |
| 1307 | m_irqstate |= 2; |
| 1334 | 1308 | |
| 1335 | | if (!m_irq_handler.isnull()) |
| 1336 | | m_irq_handler(1); |
| 1337 | | } |
| 1309 | if (!m_irq_handler.isnull()) |
| 1310 | m_irq_handler(1); |
| 1311 | } |
| 1338 | 1312 | |
| 1339 | | // reload timer |
| 1340 | | m_timB->adjust(attotime::from_hz(m_clock) * (384 * 16 * (256 - m_timerB)), 0); |
| 1341 | | break; |
| 1313 | // reload timer |
| 1314 | m_timB->adjust(attotime::from_hz(m_clock) * (384 * 16 * (256 - m_timerB)), 0); |
| 1315 | break; |
| 1316 | |
| 1317 | default: |
| 1318 | assert_always(FALSE, "Unknown id in ymf271_device::device_timer"); |
| 1319 | break; |
| 1342 | 1320 | } |
| 1343 | 1321 | } |
| 1344 | 1322 | |
| r23978 | r23979 | |
| 1362 | 1340 | |
| 1363 | 1341 | void ymf271_device::ymf271_write_timer(int data) |
| 1364 | 1342 | { |
| 1365 | | int slotnum; |
| 1366 | | YMF271Group *group; |
| 1367 | | |
| 1368 | | slotnum = fm_tab[m_timerreg & 0xf]; |
| 1369 | | group = &m_groups[slotnum]; |
| 1370 | | |
| 1371 | 1343 | if ((m_timerreg & 0xf0) == 0) |
| 1372 | 1344 | { |
| 1345 | int groupnum = fm_tab[m_timerreg & 0xf]; |
| 1346 | if (groupnum == -1) |
| 1347 | { |
| 1348 | logerror("ymf271_write_timer invalid group %02X\n", data); |
| 1349 | return; |
| 1350 | } |
| 1351 | YMF271Group *group = &m_groups[groupnum]; |
| 1352 | |
| 1373 | 1353 | group->sync = data & 0x3; |
| 1374 | 1354 | group->pfm = data >> 7; |
| 1375 | 1355 | } |
| r23978 | r23979 | |
| 1434 | 1414 | m_ext_address &= ~0xff; |
| 1435 | 1415 | m_ext_address |= data; |
| 1436 | 1416 | break; |
| 1417 | |
| 1437 | 1418 | case 0x15: |
| 1438 | 1419 | m_ext_address &= ~0xff00; |
| 1439 | 1420 | m_ext_address |= data << 8; |
| 1440 | 1421 | break; |
| 1422 | |
| 1441 | 1423 | case 0x16: |
| 1442 | 1424 | m_ext_address &= ~0xff0000; |
| 1443 | 1425 | m_ext_address |= (data & 0x7f) << 16; |
| 1444 | 1426 | m_ext_rw = (data & 0x80) ? 1 : 0; |
| 1445 | 1427 | break; |
| 1428 | |
| 1446 | 1429 | case 0x17: |
| 1447 | 1430 | m_ext_address = (m_ext_address + 1) & 0x7fffff; |
| 1448 | 1431 | if (!m_ext_rw && !m_ext_write_handler.isnull()) |
| 1449 | 1432 | m_ext_write_handler(m_ext_address, data); |
| 1450 | 1433 | break; |
| 1434 | |
| 1435 | case 0x20: |
| 1436 | case 0x21: |
| 1437 | case 0x22: |
| 1438 | // test |
| 1439 | break; |
| 1451 | 1440 | |
| 1452 | 1441 | default: |
| 1453 | 1442 | break; |
| r23978 | r23979 | |
| 1464 | 1453 | case 0: |
| 1465 | 1454 | m_reg0 = data; |
| 1466 | 1455 | break; |
| 1456 | |
| 1467 | 1457 | case 1: |
| 1468 | 1458 | ymf271_write_fm(0, m_reg0, data); |
| 1469 | 1459 | break; |
| 1460 | |
| 1470 | 1461 | case 2: |
| 1471 | 1462 | m_reg1 = data; |
| 1472 | 1463 | break; |
| 1464 | |
| 1473 | 1465 | case 3: |
| 1474 | 1466 | ymf271_write_fm(1, m_reg1, data); |
| 1475 | 1467 | break; |
| 1468 | |
| 1476 | 1469 | case 4: |
| 1477 | 1470 | m_reg2 = data; |
| 1478 | 1471 | break; |
| 1472 | |
| 1479 | 1473 | case 5: |
| 1480 | 1474 | ymf271_write_fm(2, m_reg2, data); |
| 1481 | 1475 | break; |
| 1476 | |
| 1482 | 1477 | case 6: |
| 1483 | 1478 | m_reg3 = data; |
| 1484 | 1479 | break; |
| 1480 | |
| 1485 | 1481 | case 7: |
| 1486 | 1482 | ymf271_write_fm(3, m_reg3, data); |
| 1487 | 1483 | break; |
| 1484 | |
| 1488 | 1485 | case 8: |
| 1489 | 1486 | m_pcmreg = data; |
| 1490 | 1487 | break; |
| 1488 | |
| 1491 | 1489 | case 9: |
| 1492 | 1490 | ymf271_write_pcm(data); |
| 1493 | 1491 | break; |
| 1492 | |
| 1494 | 1493 | case 0xc: |
| 1495 | 1494 | m_timerreg = data; |
| 1496 | 1495 | break; |
| 1496 | |
| 1497 | 1497 | case 0xd: |
| 1498 | 1498 | ymf271_write_timer(data); |
| 1499 | 1499 | break; |
| 1500 | |
| 1500 | 1501 | default: |
| 1501 | 1502 | break; |
| 1502 | 1503 | } |
| r23978 | r23979 | |
| 1664 | 1665 | save_item(NAME(m_slots[i].lfo_amplitude), i); |
| 1665 | 1666 | } |
| 1666 | 1667 | |
| 1667 | | for (i = 0; i < sizeof(m_groups) / sizeof(m_groups[0]); i++) |
| 1668 | for (i = 0; i < ARRAY_LENGTH(m_groups); i++) |
| 1668 | 1669 | { |
| 1669 | 1670 | save_item(NAME(m_groups[i].sync), i); |
| 1670 | 1671 | save_item(NAME(m_groups[i].pfm), i); |