|
|
1.1 root 1: <?php
2: //
3: // nono
4: // Copyright (C) 2025 nono project
5: // Licensed under nono-license.txt
6: //
7:
8: // gencycles.php
9: // cycles.txt から m680x0cycle.h を生成する。
10:
11: // 種類。
12: $names = array(
13: "030cc",
14: "030ncc",
15: "040",
16: );
17: define("ITEMS", count($names));
18:
19: // cycle_map = array(
20: // "andi_dn" => (2, 2, 1),
21: // :
22: // );
23: // alias_map = array(
24: // "ori_dn" => "andi_dn",
25: // );
26: $cycle_map = array();
27: $alias_map = array();
28:
29: $infile = "cycles.txt";
30: $fp = fopen($infile, "r");
31: $lineno = 0;
32: while (($line = fgets($fp)) !== false) {
33: $lineno++;
34: $line = preg_replace('/;.*$/', "", $line);
35: $line = trim($line);
36: if ($line == "") {
37: continue;
38: }
39:
40: $params = preg_split('/\s+/', $line, -1, PREG_SPLIT_NO_EMPTY);
41: if (count($params) != 4) {
42: print "{$infile}:{$lineno}: Syntax error: columns not 3\n";
43: exit(1);
44: }
45:
46: $new_symbol = $params[0];
47: $cylist = array();
48: $prev = 0;
49: for ($i = 0; $i < ITEMS; $i++) {
50: $val = $params[$i + 1];
51: switch ($val) {
52: case "=": // 左と同じ値 (主に 030 CC/NCC で使う)
53: case "?": // 不明 (とりあえず適当に代入)
54: $val = $prev;
55: break;
56: case ".": // 該当なし
57: break;
58: default:
59: if (is_int($val)) {
60: print "{$infile}:{$lineno}: Syntax error\n";
61: exit(1);
62: }
63: if ($val < -128 || $val > 127) {
64: print "{$infile}:{$lineno}: " +
65: "Out of range: {$val} ({$new_symbol})\n";
66: exit(1);
67: }
68: break;
69: }
70: $cylist[] = $val;
71: $prev = $val;
72: }
73:
74: $symbol = find_symbol($cylist);
75: if ($symbol == "") {
76: // 新規
77: $cycle_map[$new_symbol] = $cylist;
78: } else {
79: // すでに同じサイクルを持つエントリがある
80: $alias_map[$new_symbol] = $symbol;
81: }
82: }
83:
84: // なんとなく昇順にソート。
85: uasort($cycle_map, function($a, $b) {
86: if ($a[0] != $b[0]) {
87: return $a[0] <=> $b[0];
88: }
89: if ($a[1] != $b[1]) {
90: return $a[1] <=> $b[1];
91: }
92: return $a[2] <=> $b[2];
93: });
94:
95: if (0) {
96: var_dump($cycle_map);
97: var_dump($alias_map);
98: }
99:
100: // $cycle_map[idx] => array(type, type2, ...) を
101: // $cycle_table[type][idx] にする。
102: $cycle_table = array();
103: foreach ($cycle_map as $symbol => $cylist) {
104: for ($i = 0; $i < ITEMS; $i++) {
105: $cycle_table[$i][] = $cylist[$i];
106: }
107: }
108: if (0) {
109: var_dump($cycle_table);
110: }
111:
112: // ヘッダ出力
113: $fhdr = fopen("m680x0cycle.h", "w");
114: fprintf($fhdr, "// generated by {$argv[0]}\n");
115: // ここは pragma once が使えない(使わないほうがいい)。
116: fprintf($fhdr, "#ifndef M680X0_CYCLE_HEADER\n");
117: fprintf($fhdr, "#define M680X0_CYCLE_HEADER\n");
118:
119: $i = 0;
120: foreach ($cycle_map as $symbol => $cylist) {
121: fprintf($fhdr,
122: "static constexpr int cycidx_{$symbol} = {$i};\n");
123: $i++;
124: }
125: fprintf($fhdr, "\n");
126: foreach ($alias_map as $from => $to) {
127: fprintf($fhdr,
128: "static constexpr int cycidx_{$from} = cycidx_{$to};\n");
129: }
130:
131: fprintf($fhdr, "#endif\n");
132: fprintf($fhdr, "\n");
133: fprintf($fhdr, "#if defined(M680X0_CYCLE_TABLE)\n");
134:
135: // ソース出力
136: for ($i = 0; $i < ITEMS; $i++) {
137: fprintf($fhdr, "/*static*/ const int8\n");
138: fprintf($fhdr, "MPU680x0Device::cycle_table_{$names[$i]}[] = {\n");
139: $cyarray = $cycle_table[$i];
140: $j = 0;
141: foreach ($cyarray as $cycle) {
142: if (($j % 8) == 0) {
143: fprintf($fhdr, "\t");
144: }
145: fprintf($fhdr, "%3d,", $cycle);
146: if (($j % 8) == 7) {
147: fprintf($fhdr, "\n");
148: }
149: $j++;
150: }
151: if (($j % 8) != 0) {
152: fprintf($fhdr, "\n");
153: }
154: fprintf($fhdr, "};\n");
155: };
156: fprintf($fhdr, "#endif\n");
157: fclose($fhdr);
158: ?>
159: <?php
160: // cycle_map から $keylist を持つエントリを探す。
161: // 見付かればシンボルを返す。見付からなければ "" を返す。
162: function find_symbol($keylist)
163: {
164: global $cycle_map;
165:
166: $n = count($keylist);
167: foreach ($cycle_map as $symbol => $list) {
168: $i = 0;
169: for (; $i < $n; $i++) {
170: if ($keylist[$i] != ".") {
171: if ($keylist[$i] != $list[$i]) {
172: break;
173: }
174: }
175: }
176: if ($i == $n) {
177: return $symbol;
178: }
179: }
180: return "";
181: }
182:
183: function array_cmp($list1, $list2)
184: {
185: if (count($list1) != count($list2)) {
186: return false;
187: }
188: for ($i = 0; $i < count($list1); $i++) {
189: if ($list1[$i] != $list2[$i]) {
190: return false;
191: }
192: }
193: return true;
194: }
195: ?>
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.