First version of app, by GPT5

This commit is contained in:
2025-10-07 13:32:22 +01:00
parent 68aefead19
commit 50190d002d
8 changed files with 2845 additions and 4 deletions

View File

@@ -18,6 +18,9 @@ export default function Home() {
Get started by editing <code>src/app/page.tsx</code>.
</li>
<li>Save and see your changes instantly.</li>
<li>
Explore the <a href="/registers">Spectrum Next Registers</a>.
</li>
</ol>
<div className={styles.ctas}>

View File

@@ -0,0 +1,45 @@
'use client';
import { useState } from 'react';
import { Register } from './types';
import { Form, Card, Container, Row, Col } from 'react-bootstrap';
interface RegisterBrowserProps {
registers: Register[];
}
export default function RegisterBrowser({ registers }: RegisterBrowserProps) {
const [searchTerm, setSearchTerm] = useState('');
const filteredRegisters = registers.filter(register =>
register.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
register.description.toLowerCase().includes(searchTerm.toLowerCase())
);
return (
<Container fluid>
<Form.Group className="mb-3">
<Form.Control
type="text"
placeholder="Search registers..."
value={searchTerm}
onChange={e => setSearchTerm(e.target.value)}
/>
</Form.Group>
<Row>
{filteredRegisters.map(register => (
<Col key={register.hex_address} xs={12} md={6} lg={4} className="mb-4">
<Card>
<Card.Header>
<strong>{register.name}</strong> ({register.hex_address} / {register.dec_address})
</Card.Header>
<Card.Body>
<pre style={{ whiteSpace: 'pre-wrap' }}>{register.description}</pre>
</Card.Body>
</Card>
</Col>
))}
</Row>
</Container>
);
}

View File

@@ -0,0 +1,87 @@
import { promises as fs } from 'fs';
import path from 'path';
import RegisterBrowser from './RegisterBrowser';
import { Register } from './types';
async function parseNextReg(fileContent: string): Promise<Register[]> {
const registers: Register[] = [];
const paragraphs = fileContent.split(/\n\s*\n/);
for (const paragraph of paragraphs) {
if (!paragraph.trim()) {
continue;
}
const lines = paragraph.trim().split('\n');
processRegisterBlock(lines, registers);
}
return registers;
}
function processRegisterBlock(lines: string[], registers: Register[]) {
const firstLine = lines[0];
const restOfLines = lines.slice(1);
const multiRegisterMatch = firstLine.match(/([0-9a-fA-F,x]+)\s*\(.*?\)\s*=>\s*(.*)/);
if (multiRegisterMatch) {
const hexAddresses = multiRegisterMatch[1].trim();
const decAddresses = multiRegisterMatch[2].trim();
const name = multiRegisterMatch[3] ? multiRegisterMatch[3].trim() : '';
const description = restOfLines.join('\n').trim();
const hexList = hexAddresses.split(',').map(h => h.trim());
const decList = decAddresses.includes('-') ? decAddresses.split('-') : decAddresses.split(',').map(d => d.trim());
if (hexList.length > 1) {
for (let i = 0; i < hexList.length; i++) {
const hexAddr = hexList[i];
const decAddr = decList[i] || decAddresses;
registers.push({
hex_address: hexAddr,
dec_address: isNaN(parseInt(decAddr, 10)) ? decAddr : parseInt(decAddr, 10),
name: `${name} (${hexAddr})`,
description: description,
});
}
} else {
registers.push({
hex_address: hexAddresses,
dec_address: isNaN(parseInt(decAddresses, 10)) ? decAddresses : parseInt(decAddresses, 10),
name: name,
description: description,
});
}
return;
}
const singleRegisterMatch = lines[0].match(/(0x[0-9a-fA-F]{2})\s+(\d+)\s+=>\s+(.*)/);
if(singleRegisterMatch) {
const description = lines.slice(1).join('\n').trim();
const hexAddr = singleRegisterMatch[1].trim();
const decAddr = singleRegisterMatch[2].trim();
const name = singleRegisterMatch[3].trim();
registers.push({
hex_address: hexAddr,
dec_address: parseInt(decAddr, 10),
name: name,
description: description,
});
}
}
export default async function RegistersPage() {
const filePath = path.join(process.cwd(), 'data', 'nextreg_bare.txt');
const fileContent = await fs.readFile(filePath, 'utf8');
const registers = await parseNextReg(fileContent);
return (
<div>
<h1>Spectrum Next Registers</h1>
<RegisterBrowser registers={registers} />
</div>
);
}

View File

@@ -0,0 +1,21 @@
export interface BitwiseOperation {
bits: string;
description: string;
value?: string;
notes?: string[];
}
export interface RegisterAccess {
description?: string;
operations: BitwiseOperation[];
}
export interface Register {
hex_address: string;
dec_address: number | string;
name: string;
description: string;
read?: RegisterAccess;
write?: RegisterAccess;
notes?: string[];
}