Yes, it would be very helpfull.
Is it also possible to take the vblank in account?
OK, here is the more luxurious script. You can enable checking on too fast VDP writes by typing "toggle_vdp_write_test" in the console. For this to work, put the script in your share/scripts directory of your openMSX installation. Of course you can tweak the script yourself (for ease of doing that I put the I/O port and the amount of cycles to check for at the top). The script will show the list of addresses where too fast VDP I/O is done after each newly found value. Toggle off and on to reset this list. All results are displayed in the console. Enjoy!
Oh, there's also a debug flag. If you set it to 'true', you'll also see *good* writes. But that tends to give a lot of output
namespace eval vdp_write_test { # you can tweak these to test for other stuff variable ioport 0x98 variable cycle_max 26 # if you set this to true, you can also see OK writes, but there are many of those! variable debug false variable last_write_time 0 variable is_enabled false variable watchpoint_id variable address_list proc check_time {} { variable last_write_time variable cycle_max variable debug variable address_list set current_time [machine_info time] set cycles [expr round($::z80_freq*($current_time - $last_write_time))] set screen_enabled [expr [debug read "VDP regs" 1] & 64] set pc [format "%04x" [reg PC]] if {($cycles < $cycle_max) && $screen_enabled} { if {[lsearch -exact $address_list $pc] == -1} { puts [format "VDP I/O write too fast on address: 0x%s, took $cycles cycles (< $cycle_max)" $pc] lappend address_list $pc puts "List of addresses where too fast I/O is done: $address_list" } } else { if {$debug} { if { !$screen_enabled } { set reason "screen is disabled" } else { set reason "took $cycles cycles, > $cycle_max" } puts "VDP I/O write OK on address: 0x$pc, $reason" } } set last_write_time $current_time } proc toggle_vdp_write_test {} { variable is_enabled variable watchpoint_id variable address_list variable ioport if {!$is_enabled} { set watchpoint_id [debug set_watchpoint write_io $ioport {} vdp_write_test::check_time] set is_enabled true set address_list
-
} else {
debug remove_watchpoint $watchpoint_id
set is_enabled false
}
}
namespace export toggle_vdp_write_test
} ;# namespace vdp_write_test
namespace import vdp_write_test::*
I hope you guys can look at these scripts and learn how to write similar things yourself. It's not that hard, really.
If you have questions about it, please ask.
A great intro in Tcl is here: http://www.beedub.com/book/2nd/tclintro.doc.html
Big thanks Manuel!!
sjoerd: taking the vblank into account is a bit tricky, because there isn't a way (yet) to check if vblank is currently active.
Huey: you're welcome! Make sure you guys look at the scripts and use it to learn how to come up with this yourself That makes you less dependent on people like me ;-) (And publish your cool scripts, of course!)
So all the 'bad' writes that are actually good since they are done in vblank will also be printed? Gives a lot of bad writes in my case.
And btw is the 26 cycle count with or without the extra cycle, i.e. is NOP counted as 4 or 5 cyles?
26 cycles are actual CPU cycles, so, the thing you get 3579545 of per second.
I guess I could add a VBLANK check on MSX2, using one of its status regs (thanks mth for the hint). Useful?
If its possible to check timing VBLANK interrupt, you can just check the length of the vblank area. Its almost needed to know, especially when you plan your vram transfers to be quick in vblank.
Btw, the number of cycles between outs needs to be at least 29 in the display area on MSX1, not 26.
Hi All,
I post here to be sure to contact with one message all the emulator teams. Thanks to this script (manuel, thanks again) I removed all the the I/O troubles due to timing of our current project (DD in final release to be charted and produced).
Apparently...
The problem is that on a real msx1 - a Philips 8020 - (and not on msx2 or TR) the game presents a small glitch that corrupts the definition of same tiles during the game.
I tried with different timing between out's thanks to manuel's script so I can safely exclude that I'm facing a normal I/O problem (even with 29 cycles).
The difference between emulators and real HW seems not explicable to me - naturally on all the 3 emulators I use (blue,open and meisei) the game looks perfect as before.
Any hint? Is there some exotic HW aspect that is not emulated apart from the I/O miss when there is low delay among VRAM accesses?
I guess I could add a VBLANK check on MSX2, using one of its status regs (thanks mth for the hint). Useful?Yes. I think that would be very useful.
While developing CoT I was facing some weird graphical glitches on real MSX1 machines. Sprites were severely affected by this and I was absolutely clueless. After trying several timings and DI/EI patterns I found finally a stupid bug where I was doing a MSX2 use over a common MSX1 VDP register that totally fools the MSX1 sprite engine.Once corrected, all my other timings work flawlessly
I've never found (specially on MSX1 machines) any other strange behaviour apart from the DI/EI use when accesing VDP command register and the delay while sending data over the data register. Of course I'm not talking about the mixed modes and so, they could be potentially a great source of troubles on multiple MSX models...