import { h, JSX } from 'preact'; import { useCallback, useEffect, useRef, useState } from 'preact/hooks'; import { Apple2 as Apple2Impl } from '../apple2'; import { Inset } from './Inset'; import styles from './css/Debugger.module.css'; import { ControlButton } from './ControlButton'; export interface DebuggerProps { apple2: Apple2Impl | undefined; e: boolean; } interface DebugData { memory: string; registers: string; running: boolean; stack: string; trace: string; zeroPage: string; } export const Debugger = ({ apple2 }: DebuggerProps) => { const debug = apple2?.getDebugger(); const [data, setData] = useState(); const [memoryPage, setMemoryPage] = useState('08'); const animationRef = useRef(0); const animate = useCallback(() => { if (debug) { setData({ registers: debug.dumpRegisters(), running: debug.isRunning(), stack: debug.getStack(38), trace: debug.getTrace(16), zeroPage: debug.dumpPage(0), memory: debug.dumpPage(parseInt(memoryPage, 16) || 0) }); } animationRef.current = requestAnimationFrame(animate); }, [debug, memoryPage]); useEffect(() => { animationRef.current = requestAnimationFrame(animate); return () => cancelAnimationFrame(animationRef.current); }, [animate]); const doPause = useCallback(() => { apple2?.stop(); }, [apple2]); const doRun = useCallback(() => { apple2?.run(); }, [apple2]); const doStep = useCallback(() => { debug?.step(); }, [debug]); const doMemoryPage = useCallback((event: JSX.TargetedMouseEvent) => { setMemoryPage(event.currentTarget.value); }, []); if (!data) { return null; } const { memory, registers, running, stack, trace, zeroPage } = data; return (
Debugger
Controls
{running ? ( ) : ( )}
Registers
                            {registers}
                        
Trace
                            {trace}
                        
ZP
                            {zeroPage}
                        
Stack
                            {stack}
                        
Memory Page: $
                        {memory}
                    
); };