| 1 |
namespace eval vdp { |
| 2 |
|
| 3 |
set_help_text getcolor \ |
| 4 |
{Returns the current V99x8 palette settings for the given color index (0-15). |
| 5 |
The result is format as RGB, with each component in the range 0-7. |
| 6 |
} |
| 7 |
proc getcolor {index} { |
| 8 |
set rb [debug read "VDP palette" [expr {2 * $index}]] |
| 9 |
set g [debug read "VDP palette" [expr {2 * $index + 1}]] |
| 10 |
format "%03x" [expr {(($rb * 16) & 0x700) + (($g * 16) & 0x070) + ($rb & 0x007)}] |
| 11 |
} |
| 12 |
|
| 13 |
set_help_text setcolor \ |
| 14 |
{Changes the V99x8 palette settings. See also getcolor. |
| 15 |
|
| 16 |
usage: |
| 17 |
setcolor <index> <r><g><b> |
| 18 |
<index> 0-15 |
| 19 |
<r><g><b> 0-7 |
| 20 |
} |
| 21 |
proc setcolor {index rgb} { |
| 22 |
if {[catch { |
| 23 |
if {[string length $rgb] != 3} error |
| 24 |
set r [string index $rgb 0] |
| 25 |
set g [string index $rgb 1] |
| 26 |
set b [string index $rgb 2] |
| 27 |
if {($index < 0) || ($index > 15)} error |
| 28 |
if {($r > 7) || ($g > 7) || ($b > 7)} error |
| 29 |
debug write "VDP palette" [expr {$index * 2}] [expr {$r * 16 + $b}] |
| 30 |
debug write "VDP palette" [expr {$index * 2 + 1}] $g |
| 31 |
}]} { |
| 32 |
error "Usage: setcolor <index> <rgb>\n index 0..15\n r,g,b 0..7" |
| 33 |
} |
| 34 |
} |
| 35 |
|
| 36 |
proc format_table {entries columns frmt sep func} { |
| 37 |
set result "" |
| 38 |
set rows [expr {($entries + $columns - 1) / $columns}] |
| 39 |
for {set row 0} {$row < $rows} {incr row} { |
| 40 |
set line "" |
| 41 |
for {set col 0} {$col < $columns} {incr col} { |
| 42 |
set index [expr {$row + ($col * $rows)}] |
| 43 |
if {$index < $entries} { |
| 44 |
append line [format $frmt $index [$func $index]] $sep |
| 45 |
} |
| 46 |
} |
| 47 |
append result "${line}\n" |
| 48 |
} |
| 49 |
return $result |
| 50 |
} |
| 51 |
|
| 52 |
set_help_text vdpreg "Reads or writes a V99x8 register." |
| 53 |
proc vdpreg {reg {value ""}} { |
| 54 |
if {$value eq ""} { |
| 55 |
debug read "VDP regs" $reg |
| 56 |
} else { |
| 57 |
debug write "VDP regs" $reg $value |
| 58 |
} |
| 59 |
} |
| 60 |
|
| 61 |
set_help_text vdpregs "Gives an overview of the V99x8 registers." |
| 62 |
proc vdpregs {} { |
| 63 |
format_table 32 4 "%2d : 0x%02x" " " vdpreg |
| 64 |
} |
| 65 |
|
| 66 |
set_help_text v9990reg "Reads or writes a V9990 register." |
| 67 |
proc v9990reg {reg {value ""}} { |
| 68 |
if {$value eq ""} { |
| 69 |
debug read "Sunrise GFX9000 regs" $reg |
| 70 |
} else { |
| 71 |
debug write "Sunrise GFX9000 regs" $reg $value |
| 72 |
} |
| 73 |
} |
| 74 |
|
| 75 |
set_help_text v9990regs "Gives an overview of the V9990 registers." |
| 76 |
proc v9990regs {} { |
| 77 |
format_table 55 5 "%2d : 0x%02x" " " v9990reg |
| 78 |
} |
| 79 |
|
| 80 |
set_help_text palette "Gives an overview of the V99x8 palette registers." |
| 81 |
proc palette {} { |
| 82 |
format_table 16 4 "%x:%s" " " getcolor |
| 83 |
} |
| 84 |
|
| 85 |
set_help_text vdpvramaddress "Gives the current VDP VRAM pointer" |
| 86 |
proc vdpvramaddress {} { |
| 87 |
return [expr ([expr ([debug read "VDP regs" 14] << 14)] | [expr (([debug read "VRAM pointer" 1] & 63) << 8)] | [debug read "VRAM pointer" 0])] |
| 88 |
} |
| 89 |
|
| 90 |
set_help_text vdpstatus "Shortcut for reading the VDP status registers" |
| 91 |
proc vdpstatus {reg} { |
| 92 |
debug read "VDP status regs" $reg |
| 93 |
} |
| 94 |
|
| 95 |
proc val2bin val { |
| 96 |
set binRep [binary format c $val] |
| 97 |
binary scan $binRep B* binStr |
| 98 |
return $binStr |
| 99 |
} |
| 100 |
|
| 101 |
variable mode_lookup |
| 102 |
|
| 103 |
set mode_lookup(00000000) 1; |
| 104 |
set mode_lookup(00000001) "TEXT40"; |
| 105 |
set mode_lookup(00000010) 3; |
| 106 |
set mode_lookup(00000100) 2; |
| 107 |
set mode_lookup(00001000) 4; |
| 108 |
set mode_lookup(00001001) "TEXT80"; |
| 109 |
set mode_lookup(00001100) 5; |
| 110 |
set mode_lookup(00010000) 6; |
| 111 |
set mode_lookup(00010100) 7; |
| 112 |
set mode_lookup(00011100) 8; |
| 113 |
|
| 114 |
set_help_text get_screen_mode_number "Decodes the current screen mode from the VDP registers (as would be used in the BASIC SCREEN command)" |
| 115 |
proc get_screen_mode_number {} { |
| 116 |
set mode [get_screen_mode] |
| 117 |
if {[string range $mode 0 3] eq "TEXT"} { |
| 118 |
return 0 |
| 119 |
} elseif {$mode eq "invalid"} { |
| 120 |
return -1 |
| 121 |
} |
| 122 |
return $mode |
| 123 |
} |
| 124 |
|
| 125 |
set_help_text get_screen_mode "Decodes the current screen mode from the VDP registers (and returns it as a string)." |
| 126 |
proc get_screen_mode {} { |
| 127 |
variable mode_lookup |
| 128 |
set val [expr {(([vdpreg 0] & 14) << 1) | (([vdpreg 1] & 8) >> 2) | (([vdpreg 1] & 16) >> 4)}] |
| 129 |
if {[catch {set mode $mode_lookup([val2bin $val])}]} { |
| 130 |
return "invalid" |
| 131 |
} |
| 132 |
if {(($mode == 8) || ($mode == 7)) && ([vdpreg 25] & 8)} { |
| 133 |
set mode [expr {([vdpreg 25] & 16) ? 11 : 12}] |
| 134 |
} |
| 135 |
return $mode |
| 136 |
} |
| 137 |
|
| 138 |
set_help_text vpeek \ |
| 139 |
{Similar to the BASIC vpeek command, reads a byte from the video RAM. |
| 140 |
This command has the same view on the VRAM as the programmer sees (as opposed |
| 141 |
to the physical VRAM content): |
| 142 |
- The whole 128kB address space is visible, if the machine has less VRAM |
| 143 |
then some parts will either be mirrored or unmapped. |
| 144 |
- Depending on the current screen mode, the VRAM addressing is interleaved |
| 145 |
or not. This command follows that addressing scheme (IOW, normally you |
| 146 |
don't have to care). |
| 147 |
See also the 'vpoke' command. |
| 148 |
} |
| 149 |
proc vpeek {addr} { |
| 150 |
debug read VRAM $addr |
| 151 |
} |
| 152 |
|
| 153 |
set_help_text vpoke \ |
| 154 |
{Similar to the BASIC vpoke command, writes a byte to the video RAM. |
| 155 |
See the 'vpeek' command for more info about the VRAM address space. |
| 156 |
} |
| 157 |
proc vpoke {addr val} { |
| 158 |
debug write VRAM $addr $val |
| 159 |
} |
| 160 |
|
| 161 |
proc get_frame_duration {} { |
| 162 |
expr {(1368.0 * (([vdpreg 9] & 2) ? 313 : 262)) / (6 * 3579545)} |
| 163 |
} |
| 164 |
|
| 165 |
namespace export getcolor |
| 166 |
namespace export setcolor |
| 167 |
namespace export get_screen_mode |
| 168 |
namespace export get_screen_mode_number |
| 169 |
namespace export vdpreg |
| 170 |
namespace export vdpregs |
| 171 |
namespace export v9990regs |
| 172 |
namespace export vpeek |
| 173 |
namespace export vpoke |
| 174 |
namespace export palette |
| 175 |
namespace export vdpvramaddress |
| 176 |
namespace export vdpstatus |
| 177 |
namespace export get_frame_duration |
| 178 |
|
| 179 |
} ; |
| 180 |
|
| 181 |
namespace import vdp::* |
| 182 |
namespace forget vdp::get_frame_duration; |