Been doing some digging into how the uart monitor works currently.
Will paste a few ascii diagrams I was accumulating on how the components work together…
Main Components
+--------------------------------------------------------------------------------------------+ | machine.vhdl | | | | +------------------------------------------------------------------------------------+ | | | monitor_top.v = uart_monitor | | | | | | | | +--------------+ | | | | | monitor_ctrl | | | | | +--------------+ | | | | | | | | +--------------+ | | | | | monitor_bus | | | | | +--------------+ | | | | 1024 x 16 bytes 1024 x 8 bytes 16 x 8 bytes | | | | +--------------+ +---------------+ +---------------+ +--------------+ | | | | | monitor_mem | | asym_ram_sdp | | asym_ram_sdp | | asym_ram_sdp | | | | | | (monitor.a65)| | (historyram0) | | (historyram1) | | (cpustateram)| | | | | +--------------+ +---------------+ +---------------+ +--------------+ | | | | | | | | +--------------+ | | | | | cpu6502 | | | | | +--------------+ | | | | | | | +------------------------------------------------------------------------------------+ | | | +--------------------------------------------------------------------------------------------+
The uart-monitor is presently written in verilog, with the parent file named "monitor_top.v"
It defines a component called "uart_monitor"
"machine.vhdl" makes use of this uart_monitor component, feeds various signals between it and the 4510 cpu.
Inside the uart-monitor is a 6502 cpu component (also written in verilog).
It runs the code that resides within the "monitor_mem" component (which is just the compiled assembly contained within "monitor.a65")
There are various other ram components (e.g., historyram0/1 and cpustateram) that get mapped in a way dictated by the early comment found in “monitor.a65”
; monitor memory map ; ; $0000-$00ff - zero page ; $0100-$01ff - stack ; ; $7000-$7fff - CPU State History (16 entries, 8 bytes each) ; $8000-$8017 - history memory read window (read only) ; ; $9000-$97ff - monitor hardware control registers ; ; $f000-$ffff - 4K Monitor ROM/RAM, also mirrored at $0000-$0fff
The actual mapping logic is orchestrated by the “monitor_bus” component.
historyram0
+-------------------+ clkA | | clkB -------> <------- | | weA | | enaB ------> <------- | | enaA | | ------> | | | diA[127:0] | historyram0 | doB[7:0] -------------> ---------------> | | addrA[9:0] | | addrB[13:0] ------------> <-------------- | | +-------------------+
I haven’t dived too deep into historyram0 and historyram1 as yet, though from my initial gleaming of it, historyram was trying to be more ambitious with the volume of data it captured in each trace entry (current x,y,z,a and a lot more).
Hence the reason why the left-side (write) has a data-bus size of 128-bits (can write 16-bytes per clock cycle).
cpustateram
+-------------------+ (clock) clkA | | clkB (clock) -------> <------- | | (cpu_state_write) weA | | enaB (1) ------> <------- | | (1) enaA | | ------> | { | | (0 [15:0]) | | (monitor_cpu_state[15:0]) | | (monitor_memory_access_address[31:0])| | } --> diA[63:0] | cpustateram | doB[7:0] (cpu_state_rdata[7:0]) -------------> ---------------> | | (cpu_state_write_index) addrA[3:0] | | addrB[6:0] (cpu_address_next[6:0]) ------------> <-------------- | | +-------------------+
This ‘cpustateram' component gets mapped to that $7000-$7fff region (from the 6502 cpu’s addressing perspective).
It's a dual-port ram, where I've put:
stuff on the left relating to signals wanting to write data into the ram.
stuff on the right relating to signals wanting to read data from the ram.
So on the left-side (write), seems like the idea is to write a big chunk of cpu-state related information within a single clock cycle.
monitor_cpu_state (16-bit, one byte is the internal cpu-state details, and the other byte is the currently read byte, I think)
monitor_memory_access_address (32-bit), the current address being accessed.
On the right-side (read), this is to let this 6502 monitor cpu read out this data via an 8-bit bus (a byte at a time).
So, the assembly code within "monitor.a65" will read from $7000-$7fff to try retrieve this cpu-state trace history.
This seems to be the data that is used to generate the output from the uart-monitor's z command. I.e., this stuff:
.z uS Address Rd 15 0000A50E:EA 00 00008100:00 00 00008100:00 00 00008100:00 06 00008100:00 14 0FFF8100:00 15 00008101:00 15 0FFF8101:4C 17 00008102:4C 17 0FFF8102:0D 18 00008103:0D 18 0FFF8103:A5 4F 00008103:A5 4F 0FFF8103:EA 14 0000A50D:EA 14 0FFFA50D:EA
Signals relating to cpustateram
+--------------------------------------------------------------------+ | monitor_top.v / uart_monitor | monitor_cpu_state[15:0] | | ------------------------> | | | monitor_memory_access_address[31:0] | | ------------------------------------> | | +----------------+ | | | monitorctrl | | | (monitor_cpu_state[15:8])| | | | cpu_state[7:0] | | | | -----------------------> | | | | | | | cpu_state_write | | | | <----------------- | | | | | | | cpu_state_write_index | | | | <---------------------- | | | | | | | +----------------+ | | | | +----------------+ | | (cpu_state_rdata) | monitorbus | | | cpu_state | | | | ----------------> | | | | | | | (cpu_address_next[15:0]) | | | | cpu_address[15:0] | | | | ----------------> | | | | | | | (cpu_di) | | | | read_data[7:0] | | | | <--------------- | | | +----------------+ | | | | +----------------+ | | | cpu6502 | | | (cpu_address_next[15:0]) | (monitorcpu) | | | address_next[15:0] | | | | <------------------- | | | | | | | (cpu_di) | | | | data_i[7:0] | | | | --------------> | | | +----------------+ | | | +--------------------------------------------------------------------+
This was me deep-diving even further to learn more about the signals that relate to cpustateram and how that interact with other components.