|
|
@@ -441,191 +441,6 @@ static const char *KeyToMnem(keywtab_t *ktab, int type, int value) |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|
|
|
|
static void DecompilePhoneme(FILE *f_out, PHONEME_TAB *ph, int compile_phoneme) |
|
|
|
{ |
|
|
|
USHORT *pc; |
|
|
|
int instn; |
|
|
|
int instn_category; |
|
|
|
int address, address2; |
|
|
|
int data1; |
|
|
|
int type2; |
|
|
|
int ix; |
|
|
|
int any; |
|
|
|
const char *name; |
|
|
|
char buf[120]; |
|
|
|
|
|
|
|
static const char *instn_category_string[16] = { |
|
|
|
"", "", "IF", "IF OR", |
|
|
|
"", "", "", "", |
|
|
|
"", "", "", "FMT", |
|
|
|
"WAV", "NextVowelStart", "PrevVowelEnd", "+wav" |
|
|
|
}; |
|
|
|
|
|
|
|
static const char *nextPh_string[6] = { |
|
|
|
"prevPh", "thisPh", "nextPh", "next2Ph", "nextPhW", "**", |
|
|
|
}; |
|
|
|
|
|
|
|
static const char *instn0_string[] = { |
|
|
|
"invalid", "RETURN", "Continue", "DeleteNextPhoneme", |
|
|
|
}; |
|
|
|
|
|
|
|
static const char *instn10_string[] = { |
|
|
|
"", "VowelIn", "VowelOut", "Tone", "", |
|
|
|
}; |
|
|
|
|
|
|
|
static const char *instn_jumps[] = { |
|
|
|
"JMP", "Invalid", "Invalid", "Invalid", |
|
|
|
"JMP false", "SwitchNextVowelType", "SwitchPrevVowelType", "Invalid" |
|
|
|
}; |
|
|
|
|
|
|
|
static char instn1_paramtype[] = { |
|
|
|
0, 3, 3, 3, 3, 3, 3, 1, |
|
|
|
1, 1, 1, 1, 1, 0, 0, 0, |
|
|
|
3, 3, 3, 3, 3, 3, 3, 3, |
|
|
|
0, 0, 0, 0, 0, 0, 0, 0 |
|
|
|
}; |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
if (compile_phoneme) |
|
|
|
fprintf(f_out, "\nPhoneme %s (%d)\n", WordToString(ph->mnemonic), ph->code); |
|
|
|
else |
|
|
|
fprintf(f_out, "\nProcedure %s\n", proc_names[n_procs]); |
|
|
|
|
|
|
|
pc = prog_buf; |
|
|
|
while (pc < prog_out) { |
|
|
|
instn = *pc++; |
|
|
|
instn_category = (instn >> 12) & 0xf; |
|
|
|
data1 = instn & 0xff; |
|
|
|
type2 = (instn >> 8) & 0xf; |
|
|
|
fprintf(f_out, " %.3x: %.4x %s", (unsigned int)(pc-prog_buf), instn, instn_category_string[instn_category]); |
|
|
|
|
|
|
|
switch (instn_category) |
|
|
|
{ |
|
|
|
case 0: |
|
|
|
case 1: |
|
|
|
type2 = instn >> 8; |
|
|
|
|
|
|
|
if (instn < 0x100) { |
|
|
|
if (data1 > 2) |
|
|
|
data1 = 0; |
|
|
|
fprintf(f_out, "%s", instn0_string[data1]); |
|
|
|
} else if (type2 == i_IPA_NAME) { |
|
|
|
for (ix = 0; ix < data1; ix += 2) { |
|
|
|
instn = *pc++; |
|
|
|
buf[ix] = instn >> 8; |
|
|
|
buf[ix+1] = instn & 0xff; |
|
|
|
} |
|
|
|
buf[ix] = 0; |
|
|
|
fprintf(f_out, "ipa %s", buf); |
|
|
|
} else { |
|
|
|
fprintf(f_out, "%s(", KeyToMnem(keywords, tINSTRN1, type2)); |
|
|
|
switch (instn1_paramtype[type2]) |
|
|
|
{ |
|
|
|
case 0: |
|
|
|
fprintf(f_out, "%.4x", instn); |
|
|
|
break; |
|
|
|
case 1: |
|
|
|
fprintf(f_out, "%d", data1); |
|
|
|
break; |
|
|
|
case 3: |
|
|
|
fprintf(f_out, "%s", WordToString(phoneme_tab2[data1].mnemonic)); |
|
|
|
break; |
|
|
|
} |
|
|
|
fprintf(f_out, ")"); |
|
|
|
} |
|
|
|
break; |
|
|
|
case 2: |
|
|
|
case 3: |
|
|
|
if (type2 < 12) { |
|
|
|
fprintf(f_out, " %s(", nextPh_string[type2 % 6]); |
|
|
|
if (type2 >= 6) { |
|
|
|
switch (data1 >> 5) |
|
|
|
{ |
|
|
|
case 0: |
|
|
|
name = KeyToMnem(keywords, tPHONEME_TYPE, (data1 & 0x1f)); |
|
|
|
if (name != NULL) |
|
|
|
fprintf(f_out, "is%s", name); |
|
|
|
else |
|
|
|
fprintf(f_out, "%d %d", (data1 >> 5), (data1 & 0x1f)); |
|
|
|
break; |
|
|
|
case 1: |
|
|
|
fprintf(f_out, "%d %d", (data1 >> 5), (data1 & 0x1f)); |
|
|
|
break; |
|
|
|
case 2: |
|
|
|
fprintf(f_out, "%d %d", (data1 >> 5), (data1 & 0x1f)); |
|
|
|
break; |
|
|
|
case 4: |
|
|
|
name = KeyToMnem(k_properties, -1, 0x80+(data1 & 0x1f)); |
|
|
|
if (name != NULL) |
|
|
|
fprintf(f_out, "%s", name); |
|
|
|
else |
|
|
|
fprintf(f_out, "%d %d", (data1 >> 5), (data1 & 0x1f)); |
|
|
|
break; |
|
|
|
default: |
|
|
|
fprintf(f_out, "%d %d", (data1 >> 5), (data1 & 0x1f)); |
|
|
|
break; |
|
|
|
} |
|
|
|
} else { |
|
|
|
fprintf(f_out, "%s", WordToString(phoneme_tab2[data1].mnemonic)); |
|
|
|
} |
|
|
|
} else if (type2 == 8) { |
|
|
|
// list of numbers |
|
|
|
fprintf(f_out, " StressLevel("); |
|
|
|
any = 0; |
|
|
|
for (ix = 0; ix < 8; ix++) { |
|
|
|
if (data1 & (1 << ix)) { |
|
|
|
if (any) |
|
|
|
fputc(',', f_out); |
|
|
|
any = 1; |
|
|
|
fprintf(f_out, "%d", ix); |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
name = KeyToMnem(k_conditions, tTEST, instn & 0xfff); |
|
|
|
fprintf(f_out, "%s(", name); |
|
|
|
} |
|
|
|
fprintf(f_out, ")"); |
|
|
|
break; |
|
|
|
case 6: |
|
|
|
fprintf(f_out, "%s", instn_jumps[(instn >> 9) & 7]); |
|
|
|
fprintf(f_out, " %d", instn & 0x1ff); |
|
|
|
break; |
|
|
|
case 9: |
|
|
|
address = ((data1 & 0xf) << 4) + *pc++; |
|
|
|
fprintf(f_out, "CALL %.5x", address); |
|
|
|
break; |
|
|
|
case 10: |
|
|
|
fprintf(f_out, "%s", instn10_string[type2]); |
|
|
|
switch (type2) |
|
|
|
{ |
|
|
|
case 1: |
|
|
|
case 2: |
|
|
|
address = (data1 << 16) + pc[0]; |
|
|
|
address2 = (pc[1] << 16) + pc[2]; |
|
|
|
pc += 3; |
|
|
|
fprintf(f_out, " %.6x %.8x", address, address2); |
|
|
|
break; |
|
|
|
case 3: |
|
|
|
address = ((instn & 0xf) << 16) + *pc++; |
|
|
|
address2 = ((instn & 0xf0) << 12) + *pc++; |
|
|
|
fprintf(f_out, " %.5x %.5x", address, address2); |
|
|
|
break; |
|
|
|
} |
|
|
|
break; |
|
|
|
case 11: |
|
|
|
case 12: |
|
|
|
case 13: |
|
|
|
case 14: |
|
|
|
case 15: |
|
|
|
address = ((instn & 0xf) << 16) + *pc++; |
|
|
|
fprintf(f_out, " %d %.5x", (instn >> 4) & 0xff, address*4); |
|
|
|
break; |
|
|
|
} |
|
|
|
fprintf(f_out, "\n"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static int n_phoneme_tabs; |
|
|
|
static int n_phcodes; |
|
|
|
|
|
|
@@ -2500,8 +2315,6 @@ int CompilePhoneme(int compile_phoneme) |
|
|
|
phoneme_out->mnemonic = 0x01; // will not be recognised |
|
|
|
} |
|
|
|
|
|
|
|
DecompilePhoneme(f_errors, phoneme_out, compile_phoneme); |
|
|
|
|
|
|
|
if (prog_out > prog_buf) { |
|
|
|
// write out the program for this phoneme |
|
|
|
fflush(f_phindex); |