Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Several bug fixes and improvements #192

Merged
merged 35 commits into from
Oct 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
f595e0f
Don't recompile HDL code when switching between 2 builtin chips
netalondon Oct 8, 2023
b45b4b9
Allow comipling test seperately from hdl to not overrite builtin chips
netalondon Oct 9, 2023
2972e81
Add missing await for chip compilation
netalondon Oct 9, 2023
086ed0a
Reset pin values after switching chip
netalondon Oct 9, 2023
02d0eb2
Omit visualization label for chips without visualizations
netalondon Oct 9, 2023
ea1da07
Fix fomatting
netalondon Oct 9, 2023
133163d
Change builtin chip display to better reflect the book
netalondon Oct 9, 2023
320bd44
Fix inconsistent HDL templates
netalondon Oct 9, 2023
2cf9d11
Don't await useBuiltin inside switch toggle
netalondon Oct 9, 2023
6c08414
Correctly load the first project on startup
netalondon Oct 10, 2023
b3c6ce4
Change "Visualizations" text to "Visualization"
netalondon Oct 10, 2023
51e6c7f
Enable decimal inputs
netalondon Oct 10, 2023
23b4f53
Handle negative decimal inputs
netalondon Oct 10, 2023
1116f30
Disable eval button when decimal input is invalid
netalondon Oct 10, 2023
1f040cd
Fix another inconsistent HDL template
netalondon Oct 10, 2023
0eabaa0
Fix inconsistencies between chip names and file names
netalondon Oct 11, 2023
7ee3a56
Line order change
netalondon Oct 11, 2023
94bb3c1
Set some of the decimal fields to be unsigned according to function
netalondon Oct 15, 2023
702f11d
Fix builtin chip syntax
netalondon Oct 15, 2023
cdd88e1
Change invalid HDL error message
netalondon Oct 15, 2023
60ef893
Remove ALUNoStat
netalondon Oct 15, 2023
7f3aebf
Disable eval button when decimal input overflows
netalondon Oct 16, 2023
46a99ad
Fix virtual scroll
netalondon Oct 16, 2023
f3b3cbc
Add register visualization
netalondon Oct 17, 2023
b2b9557
Add Nand and DFF as builtin only chips
netalondon Oct 17, 2023
fe9d4c7
Add missing semicolons
netalondon Oct 17, 2023
adc9741
Hide internal pins for builtin only chips
netalondon Oct 17, 2023
2409b18
Fix DFF hdl interface
netalondon Oct 17, 2023
b8d3337
Fix DFF description
netalondon Oct 17, 2023
45344d3
Add Screen and Keyboard builtin chips
netalondon Oct 19, 2023
dc00663
Change keyboard output pins to update immediately
netalondon Oct 22, 2023
f7995de
Fix builtin RAM reset
netalondon Oct 22, 2023
76ac209
Fix true and false busses evaluation
netalondon Oct 22, 2023
6703914
Remove redundant console.logs
netalondon Oct 25, 2023
970064d
Merge branch 'main' into bug-fixes
DavidSouther Oct 25, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 40 additions & 15 deletions components/src/chips/keyboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,23 +46,43 @@ function keyPressToHackCharacter(keypress: KeyboardEvent): number {
return 0;
}

export const Keyboard = ({ keyboard }: { keyboard: KeyboardChip }) => {
export const Keyboard = ({
keyboard,
update,
}: {
keyboard: KeyboardChip;
update?: () => void;
}) => {
const [showPicker, setShowPicker] = useState(false);
const [bits, setBits] = useState(keyboard.out().busVoltage);
let currentKey = 0;

const setKey = useCallback(
(event: KeyboardEvent<HTMLInputElement>) => {
const key = keyPressToHackCharacter(event);
if (key === 0) {
return;
}
event.preventDefault();
keyboard.setKey(key);
setBits(keyboard.out().busVoltage);
setShowPicker(false);
},
[keyboard, setShowPicker, setBits]
);
const onKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {
event.preventDefault();
const key = keyPressToHackCharacter(event);
if (key === currentKey) {
return;
}
setKey(key);
update?.();
};

const onKeyUp = (event: KeyboardEvent<HTMLInputElement>) => {
currentKey = 0;
keyboard.clearKey();
update?.();
setBits(keyboard.out().busVoltage);
};

const setKey = (key: number) => {
if (key === 0) {
return;
}
keyboard.setKey(key);
setBits(keyboard.out().busVoltage);
currentKey = key;
// setShowPicker(false);
};

const changeKey = useCallback(() => {
setShowPicker(true);
Expand All @@ -75,7 +95,12 @@ export const Keyboard = ({ keyboard }: { keyboard: KeyboardChip }) => {
</div>
<div className="flex-1">
{showPicker ? (
<input ref={(e) => e?.focus()} type="text" onKeyDown={setKey} />
<input
ref={(e) => e?.focus()}
type="text"
onKeyDown={onKeyDown}
onKeyUp={onKeyUp}
/>
) : (
<button onClick={changeKey}>
{/* <Icon name="keyboard" /> */}
Expand Down
14 changes: 7 additions & 7 deletions components/src/chips/visualizations.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
import { ALU } from "@nand2tetris/simulator/chip/builtins/index.js";
import {
PC,
VRegister,
Register,
} from "@nand2tetris/simulator/chip/builtins/sequential/bit.js";
import {
RAM,
Expand Down Expand Up @@ -41,7 +41,7 @@ export function getBuiltinVisualization(part: Chip): ReactElement | undefined {
}
}

export function makeVisualization(chip: Chip): ReactElement | undefined {
export function makeVisualization(chip: Chip, updateAction? : () => void): ReactElement | undefined {
if (chip instanceof ALU) {
return (
<ALUComponent
Expand All @@ -59,7 +59,7 @@ export function makeVisualization(chip: Chip): ReactElement | undefined {
/>
);
}
if (chip instanceof VRegister) {
if (chip instanceof Register) {
return (
<RegisterComponent
name={chip.name ?? `Chip ${chip.id}`}
Expand All @@ -71,7 +71,7 @@ export function makeVisualization(chip: Chip): ReactElement | undefined {
return <RegisterComponent name="PC" bits={chip.bits} />;
}
if (chip instanceof Keyboard) {
return <KeyboardComponent keyboard={chip} />;
return <KeyboardComponent keyboard={chip} update={updateAction} />;
}
if (chip instanceof Screen) {
return <ScreenComponent memory={chip.memory} />;
Expand Down Expand Up @@ -108,18 +108,18 @@ export function makeVisualization(chip: Chip): ReactElement | undefined {
}

const vis = [...chip.parts]
.map(makeVisualization)
.map((chip) => makeVisualization(chip, updateAction))
.filter((v) => v !== undefined);
return vis.length > 0 ? <>{vis}</> : undefined;
}

export function makeVisualizationsWithId(chip: {
parts: Chip[];
}): [string, ReactElement][] {
}, updateAction? : () => void): [string, ReactElement][] {
return [...chip.parts]
.map((part, i): [string, ReactElement | undefined] => [
`${part.id}_${i}`,
makeVisualization(part),
makeVisualization(part, updateAction),
])
.filter(([_, v]) => v !== undefined) as [string, ReactElement][];
}
48 changes: 48 additions & 0 deletions components/src/pin_display.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { Ok, isOk } from "@davidsouther/jiffies/lib/esm/result.js";
import {
REGISTRY as BUILTIN_REGISTRY,
getBuiltinChip,
} from "@nand2tetris/simulator/chip/builtins/index.js";

export class ChipDisplayInfo {
signBehaviors: Map<string, boolean> = new Map();

public constructor(chipName: string, unsigned?: string[]) {
if (BUILTIN_REGISTRY.has(chipName)) {
const chip = getBuiltinChip(chipName);
if (isOk(chip)) {
const pins = Array.from(Ok(chip).ins.entries()).concat(
Array.from(Ok(chip).outs.entries())
);
for (const pin of pins) {
this.signBehaviors.set(
pin.name,
!unsigned || !unsigned.includes(pin.name)
);
}
}
}
}

public isSigned(pin: string) {
return this.signBehaviors.get(pin);
}
}

const UNSIGNED_PINS = new Map<string, string[]>([
["Mux4Way16", ["sel"]],
["Mux8Way16", ["sel"]],
["DMux4Way", ["sel"]],
["DMux8Way", ["sel"]],
["RAM8", ["address"]],
["RAM64", ["address"]],
["RAM512", ["address"]],
["RAM4K", ["address"]],
["RAM16K", ["address"]],
["Screen", ["address"]],
["Memory", ["address"]],
["CPU", ["addressM", "pc"]],
]);

export const getDisplayInfo = (chipName: string) =>
new ChipDisplayInfo(chipName, UNSIGNED_PINS.get(chipName));
Loading
Loading