|
|
nono 1.3.0
<?php
//
// nono
// Copyright (C) 2025 nono project
// Licensed under nono-license.txt
//
// gencycles.php
// cycles.txt から m680x0cycle.h を生成する。
// 種類。
$names = array(
"030cc",
"030ncc",
"040",
);
define("ITEMS", count($names));
// cycle_map = array(
// "andi_dn" => (2, 2, 1),
// :
// );
// alias_map = array(
// "ori_dn" => "andi_dn",
// );
$cycle_map = array();
$alias_map = array();
$infile = "cycles.txt";
$fp = fopen($infile, "r");
$lineno = 0;
while (($line = fgets($fp)) !== false) {
$lineno++;
$line = preg_replace('/;.*$/', "", $line);
$line = trim($line);
if ($line == "") {
continue;
}
$params = preg_split('/\s+/', $line, -1, PREG_SPLIT_NO_EMPTY);
if (count($params) != 4) {
print "{$infile}:{$lineno}: Syntax error: columns not 3\n";
exit(1);
}
$new_symbol = $params[0];
$cylist = array();
$prev = 0;
for ($i = 0; $i < ITEMS; $i++) {
$val = $params[$i + 1];
switch ($val) {
case "=": // 左と同じ値 (主に 030 CC/NCC で使う)
case "?": // 不明 (とりあえず適当に代入)
$val = $prev;
break;
case ".": // 該当なし
break;
default:
if (is_int($val)) {
print "{$infile}:{$lineno}: Syntax error\n";
exit(1);
}
if ($val < -128 || $val > 127) {
print "{$infile}:{$lineno}: " +
"Out of range: {$val} ({$new_symbol})\n";
exit(1);
}
break;
}
$cylist[] = $val;
$prev = $val;
}
$symbol = find_symbol($cylist);
if ($symbol == "") {
// 新規
$cycle_map[$new_symbol] = $cylist;
} else {
// すでに同じサイクルを持つエントリがある
$alias_map[$new_symbol] = $symbol;
}
}
// なんとなく昇順にソート。
uasort($cycle_map, function($a, $b) {
if ($a[0] != $b[0]) {
return $a[0] <=> $b[0];
}
if ($a[1] != $b[1]) {
return $a[1] <=> $b[1];
}
return $a[2] <=> $b[2];
});
if (0) {
var_dump($cycle_map);
var_dump($alias_map);
}
// $cycle_map[idx] => array(type, type2, ...) を
// $cycle_table[type][idx] にする。
$cycle_table = array();
foreach ($cycle_map as $symbol => $cylist) {
for ($i = 0; $i < ITEMS; $i++) {
$cycle_table[$i][] = $cylist[$i];
}
}
if (0) {
var_dump($cycle_table);
}
// ヘッダ出力
$fhdr = fopen("m680x0cycle.h", "w");
fprintf($fhdr, "// generated by {$argv[0]}\n");
// ここは pragma once が使えない(使わないほうがいい)。
fprintf($fhdr, "#ifndef M680X0_CYCLE_HEADER\n");
fprintf($fhdr, "#define M680X0_CYCLE_HEADER\n");
$i = 0;
foreach ($cycle_map as $symbol => $cylist) {
fprintf($fhdr,
"static constexpr int cycidx_{$symbol} = {$i};\n");
$i++;
}
fprintf($fhdr, "\n");
foreach ($alias_map as $from => $to) {
fprintf($fhdr,
"static constexpr int cycidx_{$from} = cycidx_{$to};\n");
}
fprintf($fhdr, "#endif\n");
fprintf($fhdr, "\n");
fprintf($fhdr, "#if defined(M680X0_CYCLE_TABLE)\n");
// ソース出力
for ($i = 0; $i < ITEMS; $i++) {
fprintf($fhdr, "/*static*/ const int8\n");
fprintf($fhdr, "MPU680x0Device::cycle_table_{$names[$i]}[] = {\n");
$cyarray = $cycle_table[$i];
$j = 0;
foreach ($cyarray as $cycle) {
if (($j % 8) == 0) {
fprintf($fhdr, "\t");
}
fprintf($fhdr, "%3d,", $cycle);
if (($j % 8) == 7) {
fprintf($fhdr, "\n");
}
$j++;
}
if (($j % 8) != 0) {
fprintf($fhdr, "\n");
}
fprintf($fhdr, "};\n");
};
fprintf($fhdr, "#endif\n");
fclose($fhdr);
?>
<?php
// cycle_map から $keylist を持つエントリを探す。
// 見付かればシンボルを返す。見付からなければ "" を返す。
function find_symbol($keylist)
{
global $cycle_map;
$n = count($keylist);
foreach ($cycle_map as $symbol => $list) {
$i = 0;
for (; $i < $n; $i++) {
if ($keylist[$i] != ".") {
if ($keylist[$i] != $list[$i]) {
break;
}
}
}
if ($i == $n) {
return $symbol;
}
}
return "";
}
function array_cmp($list1, $list2)
{
if (count($list1) != count($list2)) {
return false;
}
for ($i = 0; $i < count($list1); $i++) {
if ($list1[$i] != $list2[$i]) {
return false;
}
}
return true;
}
?>
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.