...
Table of Contents |
---|
Much of the impetus behind my studying of “viciv.vhdl” came from an issue I observed while using 640x400 4-bitplanes (16 colour) mode.
The discord thread itself is probably a good read in relation to these studies, so will provide a link to it also:
State Machines
There are two main state machines residing within viciv.vhdl
, they are:
raster_fetch_state
The larger of the two
Encompasses all the various drawing modes, such as:
character modes (multi-colour, monochrome, extended colour)
bitmap modes (monochrome, multi-colour)
sprites (0 to 7)
bitplane mode
note that the 8 bitplanes make use of the same sprite mechanics and are internally considered to be sprites 8 to 15
paint_fsm_state
The smaller of the two
Starts off sitting in ‘Idle’ state, until some activity within the
raster_fetch_state
machine pushes it to a different paint-state.
I’ll provide graphviz/dot diagrams for the two state machines below. My hope is that they will be of good use to newcomers to this file that want an overview of the behaviour (rather than trying to have a read through the over 5000 lines of source code within the “viciv.vhdl” file). Once you get your bearings via a nice overview diagram like this, I hope you’ll be able to navigate to the areas you are interested in easier and hone your focus on the specific areas you want to investigate deeper into.
“raster_fetch_state” state machine
Graphviz | ||
---|---|---|
| ||
digraph raster_fetch_state {
rankdir=TB;
node [shape = rectangle];
graph [splines = ortho];
nodesep = 2;
ranksep = 0.5;
Idle -> FetchScreenRamLine [xlabel="if first_card_of_row !=\n prev_first_card_of_row"];
Idle -> FetchFirstCharacter [xlabel="else"];
FetchScreenRamLine -> FetchScreenRamLine2 [xlabel="if paint_ready='1'"];
FetchScreenRamLine2 -> FetchFirstCharacter [xlabel="if (sixteenbit_charset='1' and end_of_row_16='1')\n or (sixteenbit_charset='0' and end_of_row='1')"];
FetchFirstCharacter -> FetchNextCharacter [xlabel="if bitplane_mode='0' or viciv_bitplane_chargen_on='1'"];
FetchFirstCharacter -> EndOfChargen [xlabel="else"];
FetchNextCharacter -> FetchCharHighByte [xlabel="if sixteenbit_charset='1'"];
FetchNextCharacter -> dot [xlabel="else"];
dot -> FetchTextCell [xlabel="yes"];
dot -> FetchBitmapCell [xlabel="no"];
FetchCharHighByte -> FetchTextCell [xlabel="if text_mode='1'"];
FetchCharHighByte -> FetchBitmapCell [xlabel="else"];
FetchTextCell -> FetchTextCellColourAndSource;
FetchTextCellColourAndSource -> PaintMemWait;
FetchBitmapCell -> FetchBitmapData;
FetchBitmapData -> PaintMemWait;
PaintMemWait -> PaintMemWait2;
PaintMemWait2 -> dot2;
dot2 -> dot3 [xlabel="yes"];
dot2 -> PaintMemWait3 [xlabel="no"];
dot3 -> PaintFullColourFetch [xlabel="yes"];
dot3 -> PaintFullColourHyperRAMFetch [xlabel="no"];
PaintFullColourHyperRAMFetch -> PaintMemWait3 [xlabel="if hyper_data_strobe='1'\n and full_colour_fetch_count>=8"];
PaintFullColourFetch -> PaintMemWait3 [xlabel="if full_colour_fetch_count>=8"];
PaintMemWait3 -> EndOfChargen [xlabel="if (end_of_row = '1')\n or (short_line='1')"];
PaintMemWait3 -> PaintDispatch [xlabel="else"];
PaintDispatch -> FetchNextCharacter [xlabel="if paint_ready='1'"];
EndOfChargen -> SpritePointerFetch [xlabel="if paint_fsm_state = Idle"];
SpritePointerFetch -> Idle [xlabel="if sprite_fetch_sprite_number = 16\n or (sprite_fetch_sprite_number = 8\n and bitplane_mode = '0')"];
SpritePointerFetch -> SpritePointerFetch2 [xlabel="elsif sprite_fetch_sprite_number < 8"]
SpritePointerFetch -> dot4
dot4 -> SpritePointerFetch [xlabel="yes"]
dot4 -> SpritePointerCompute [xlabel="no"]
SpritePointerFetch2 -> SpritePointerCompute1;
SpritePointerCompute1 -> SpritePointerCompute;
SpritePointerCompute -> SpritePointerComputeMSB [xlabel="vicii_sprite_pointer_address(23)='1'"];
SpritePointerCompute -> SpriteDataFetch [xlabel="else"];
SpritePointerComputeMSB -> SpriteDataFetch;
SpriteDataFetch -> SpriteDataFetch2;
SpriteDataFetch2 -> SpritePointerFetch [xlabel="if (sprite_fetch_byte_number = max_sprite_fetch_byte_number)"];
Idle;
FetchScreenRamLine;
FetchScreenRamLine2;
FetchFirstCharacter;
FetchNextCharacter;
EndOfChargen;
FetchCharHighByte;
dot [shape = diamond, label="if text_mode='1'"];
dot2 [shape = diamond, label="if glyph_full_color = '1'"];
dot3 [shape = diamond, label="if glyphs_from_hyperram='0'\n or (not hyper_installed)"];
dot4 [shape = diamond, label="if bitplane_enables(\n sprite_fetch_sprite_number mod 8)='0'"]
FetchTextCell;
FetchTextCellColourAndSource;
FetchBitmapCell;
FetchBitmapData;
PaintFullColourFetch;
PaintFullColourHyperRAMFetch;
PaintMemWait;
PaintMemWait2;
PaintDispatch;
SpritePointerFetch;
SpritePointerFetch2;
SpritePointerCompute1;
SpritePointerCompute;
SpritePointerComputeMSB;
SpriteDataFetch;
SpriteDataFetch2;
} |
“paint_fsm_state” state machine
Graphviz | ||
---|---|---|
| ||
digraph paint_fsm {
rankdir=TB;
node [shape = rectangle];
graph [splines = ortho];
nodesep = 2;
ranksep = 0.5;
// Define custom colors
lightblue = "#ADD8E6";
// Define legend box
subgraph cluster_legend {
label = "Legend";
shape = "none";
color = "gray";
// Define HTML label for legend table
legend_table [label=<
<table border="0" cellborder="1" cellspacing="0">
<tr>
<td bgcolor="lightblue">raster_fetch_state</td>
</tr>
<tr>
<td bgcolor="palegreen">paint_fsm_state</td>
</tr>
</table>
>];
}
Idle [label="Idle", style=filled, fillcolor=palegreen];
PaintFullColour [label="PaintFullColour", style=filled, fillcolor=palegreen];
PaintMultiColour [label="PaintMultiColour", style=filled, fillcolor=palegreen];
PaintMono [label="PaintMono", style=filled, fillcolor=palegreen];
PaintMonoDrive [label="PaintMonoDrive", style=filled, fillcolor=palegreen];
PaintMonoBits [label="PaintMonoBits", style=filled, fillcolor=palegreen];
PaintMultiColourDrive [label="PaintMultiColourDrive", style=filled, fillcolor=palegreen];
PaintMultiColourBits [label="PaintMultiColourBits", style=filled, fillcolor=palegreen];
PaintMultiColourHold [label="PaintMultiColourHold", style=filled, fillcolor=palegreen];
PaintFullColourPixels [label="PaintFullColourPixels", style=filled, fillcolor=palegreen];
Paint4bitColourPixels [label="Paint4bitColourPixels", style=filled, fillcolor=palegreen];
# NOTE: This 'PaintFullColourDone' state wasn't really used by the system, so let's ignore it
# PaintFullColourDone [label="PaintFullColourDone", style=filled, fillcolor=palegreen];
cond1 [shape = diamond, label="[raster_fetch_state:PaintDispatch]\nif paint_ready='1'", style=filled, fillcolor=lightblue];
cond2 [shape = diamond, label="if glyph_goto='1'", style=filled, fillcolor=lightblue];
cond3 [shape = diamond, label="elsif glyph_full_colour='1'", style=filled, fillcolor=lightblue];
cond4 [shape = diamond, label="else", style=filled, fillcolor=lightblue];
cond5 [shape = diamond, label="if multicolour_mode='0'\nand extended_background_mode='0'", style=filled, fillcolor=lightblue];
cond6 [shape = diamond, label="elsif multicolour_mode='1'", style=filled, fillcolor=lightblue]
cond7 [shape = diamond, label="text_mode='1' and glyph_colour(3)='0'", style=filled, fillcolor=lightblue]
cond8 [shape = diamond, label="elsif extended_background_mode='1'", style=filled, fillcolor=lightblue]
cond9 [shape = diamond, label="[raster_fetch_state:EndOfChargen]\nif paint_ready='1'", style=filled, fillcolor=lightblue];
Idle -> cond1;
cond1 -> Idle [xlabel="no"];
cond1 -> cond2 [xlabel="yes"];
cond2 -> Idle [xlabel="yes"];
cond2 -> cond3 [xlabel="no"];
cond3 -> PaintFullColour [xlabel="yes"];
cond3 -> cond4 [xlabel="no"];
cond4 -> cond5;
cond5 -> PaintMono [xlabel="yes"];
cond5 -> cond6 [xlabel="no"];
cond6 -> cond7 [xlabel="yes"];
cond7 -> PaintMono [xlabel="yes"];
cond7 -> PaintMultiColour [xlabel="no"];
cond6 -> cond8 [xlabel="no"]
cond8 -> PaintMono [xlabel="yes"]
cond9 -> Idle [xlabel="yes"]
PaintFullColour -> Paint4bitColourPixels [xlabel="if paint_glyph_4bit='1'"];
PaintFullColour -> PaintFullColourPixels [xlabel="else"];
# Paint4bitColourPixels -> PaintFullColourDone [xlabel = "if not paint_bits_remaining > 0"]
Paint4bitColourPixels -> Idle [xlabel = "if paint_bits_remaining = 0"];
#PaintFullColourPixels -> PaintFullColourDone [xlabel = "if not paint_bits_remaining > 0"]
PaintFullColourPixels -> Idle [xlabel = "if paint_bits_remaining = 0"];
PaintMono -> PaintMonoDrive;
PaintMonoDrive -> PaintMonoBits;
PaintMonoBits -> Idle [xlabel="if paint_bits_remaining = 1\n or paint_bits_remaining = 0"];
PaintMultiColour -> PaintMultiColourDrive;
PaintMultiColourDrive -> PaintMultiColourBits;
PaintMultiColourBits -> PaintMultiColourHold;
PaintMultiColourHold -> Idle [xlabel="if paint_bits_remaining = 0"]
PaintMultiColourHold -> PaintMultiColourBits [xlabel="else"]
}
|