| 1 |
|
| 2 |
set_help_text umrcallback \ |
| 3 |
{This is an example of a UMR callback function. You can set the "umr_callback" |
| 4 |
setting in openMSX to "umrcallback" and this function will be called whenever |
| 5 |
openMSX detects a read from uninitialized memory. It might be a good idea to |
| 6 |
go into 'debug break' mode in this callback, so that you can easily examine |
| 7 |
what is going on which has caused the UMR. |
| 8 |
|
| 9 |
@param addr The absolute address in the RAM device. |
| 10 |
@param name The name of the RAM device. |
| 11 |
} |
| 12 |
|
| 13 |
proc umrcallback {addr name} { |
| 14 |
puts stderr [format "UMR detected in RAM device \"$name\", offset: 0x%04X, PC: 0x%04X" $addr [reg PC]] |
| 15 |
} |
| 16 |
|
| 17 |
|
| 18 |
|
| 19 |
|
| 20 |
|
| 21 |
set_help_text vdpcmdinprogresscallback \ |
| 22 |
{This is an example of a vdpcmdinprogress callback function. To use it execute |
| 23 |
set vdpcmdinprogress_callback vdpcmdinprogresscallback |
| 24 |
After changing that setting this proc will be called whenever openMSX detects a |
| 25 |
write to a VDP command engine register while there's still a VDP command in |
| 26 |
progress. Often this is an indication of a bug in the MSX program. This example |
| 27 |
callback proc only prints the register number, the value that was being written |
| 28 |
and the program counter. Feel free to write your own callback procs. For |
| 29 |
example it might be a good idea to enter 'debug break' mode in your callback, |
| 30 |
so that you can easily examine what is going on. |
| 31 |
|
| 32 |
@param reg The VDP command engine register number that was being written |
| 33 |
This is in range 0..14. Note that it's OK to write register 12 |
| 34 |
while a command is in progress. So this callback will not be |
| 35 |
triggered for writes to register 12. |
| 36 |
@param val The value that was being written. |
| 37 |
} |
| 38 |
|
| 39 |
proc vdpcmdinprogresscallback {reg val} { |
| 40 |
puts stderr [format "Write to VDP command engine detected while there's still a command in progress: reg = %d, val = %d, PC = 0x%04X" [expr {$reg + 32}] $val [reg PC]] |
| 41 |
} |
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
set psg_directions_warning_printed false |
| 47 |
proc psgdirectioncallback {} { |
| 48 |
if {[string first "MSX" [machine_info type]] == -1} return |
| 49 |
if {$::psg_directions_warning_printed} return |
| 50 |
set ::psg_directions_warning_printed true |
| 51 |
message {The running MSX software has set unsafe PSG port directions. |
| 52 |
Real (older) MSX machines can get damaged by this.} warning |
| 53 |
} |
| 54 |
interp alias {} default_invalid_psg_directions_callback {} psgdirectioncallback |
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
set ppi_mode_warning_printed false |
| 59 |
proc ppimodecallback {} { |
| 60 |
if {$::ppi_mode_warning_printed} return |
| 61 |
set ::ppi_mode_warning_printed true |
| 62 |
message {Invalid PPI mode selected. This is not yet correctly emulated. On a real MSX this will most likely hang.} warning |
| 63 |
} |
| 64 |
interp alias {} default_invalid_ppi_mode_callback {} ppimodecallback |
| 65 |
|
| 66 |
|
| 67 |
|
| 68 |
proc dihaltcallback {} { |
| 69 |
set machine [machine_info type] |
| 70 |
if {[string match "MSX*" $machine] || $machine eq "SVI"} { # These machines do not use NMI. |
| 71 |
message "DI; HALT detected, which means a hang. You can just as well reset the machine now..." warning |
| 72 |
} |
| 73 |
} |
| 74 |
interp alias {} default_di_halt_callback {} dihaltcallback |
| 75 |
|
| 76 |
|
| 77 |
proc warn_too_fast_vram_access {} { |
| 78 |
message [format "Too fast VRAM access PC=0x%04x Y-pos=%d" [reg PC] [machine_info VDP_msx_y_pos]] warning |
| 79 |
} |
| 80 |
proc debug_too_fast_vram_access {} { |
| 81 |
warn_too_fast_vram_access |
| 82 |
debug break |
| 83 |
} |
| 84 |
|
| 85 |
|
| 86 |
|
| 87 |
proc default_dot_clock_direction_callback {} { |
| 88 |
message "The running MSX software has set bit 0 of VDP register 9 (dot clock direction) to one. In an ordinary MSX, the screen would go black and the CPU would stop running." warning |
| 89 |
} |
| 90 |
|
| 91 |
|
| 92 |
proc sensorkidportstatuscallback {port value} { |
| 93 |
message "Sensor Kid port $port has been [expr {$value ? "enabled" : "disabled"}]" info |
| 94 |
} |
| 95 |
proc sensorkidacquirecallback {port} { |
| 96 |
set time [machine_info time] |
| 97 |
switch $port { |
| 98 |
0 { # Sine |
| 99 |
return [expr {int(sin($time * 0.1) * 127.0) + 128}] |
| 100 |
} |
| 101 |
1 { # Sawtooth |
| 102 |
return [expr {int($time * 10.0) % 256}] |
| 103 |
} |
| 104 |
2 { # Triangle |
| 105 |
set t [expr {int($time * 4.0) % 512}] |
| 106 |
return [expr {($t > 255) ? (511 - $t) : $t}] |
| 107 |
} |
| 108 |
default { |
| 109 |
return 255 |
| 110 |
} |
| 111 |
} |
| 112 |
} |
| 113 |
set sensor_kid_port_status_callback sensorkidportstatuscallback |
| 114 |
set sensor_kid_acquire_callback sensorkidacquirecallback |
| 115 |
|
| 116 |
proc default_V9990_invalid_register_read_callback {reg} { |
| 117 |
message [format "Reading from V9990 write-only register 0x%x" $reg] warning |
| 118 |
} |
| 119 |
proc default_V9990_invalid_register_write_callback {reg value} { |
| 120 |
message [format "Writing 0x%x to V9990 read-only register %i" $value $reg] warning |
| 121 |
} |
| 122 |
|
| 123 |
|