Accurate logging of port input / output in openMSX

Page 2/2
1 |

By tvalenca

Paladin (704)

tvalenca's picture

20-09-2018, 16:40

Guys,
I wrote this script:

namespace eval profile {
	debug set_watchpoint write_io 0x60 {} {profile::p0}
	debug set_watchpoint write_io 0x61 {} {profile::p1}	
	debug set_watchpoint write_io 0x61 {} {profile::p2}	
	debug set_watchpoint write_io 0x62 {} {profile::p3}	
	debug set_watchpoint write_io 0x63 {} {profile::p4}	
	debug set_watchpoint write_io 0x64 {} {profile::p5}	
	debug set_watchpoint write_io 0x65 {} {profile::p6}	
	debug set_watchpoint write_io 0x66 {} {profile::p7}	
	debug set_watchpoint write_io 0x67 {} {profile::p8}	
	debug set_watchpoint write_io 0x68 {} {profile::p9}	
	debug set_watchpoint write_io 0x69 {} {profile::pa}	
	debug set_watchpoint write_io 0x6A {} {profile::pb}	
	debug set_watchpoint write_io 0x6F {} {profile::pf}	

	proc p0 {} { 
		set chan [open v9990.txt a]
		puts $chan “&H60 [format%02X [reg a]]”
		close $chan
	}
	proc p1 {} { 
		set chan [open v9990.txt a]
		puts $chan “&H61 [format%02X [reg a]]”
		close $chan
	}
	proc p2 {} { 
		set chan [open v9990.txt a]
		puts $chan “&H62 [format%02X [reg a]]”
		close $chan
	}
	proc p3 {} { 
		set chan [open v9990.txt a]
		puts $chan “&H63 [format%02X [reg a]]”
		close $chan
	}
	proc p4 {} { 
		set chan [open v9990.txt a]
		puts $chan “&H64 [format%02X [reg a]]”
		close $chan
	}
	proc p5 {} { 
		set chan [open v9990.txt a]
		puts $chan “&H65 [format%02X [reg a]]”
		close $chan
	}
	proc p6 {} { 
		set chan [open v9990.txt a]
		puts $chan “&H66 [format%02X [reg a]]”
		close $chan
	}
	proc p0 {} { 
		set chan [open v9990.txt a]
		puts $chan “&H60 [format%02X [reg a]]”
		close $chan
	}
	proc p7 {} { 
		set chan [open v9990.txt a]
		puts $chan “&H67 [format%02X [reg a]]”
		close $chan
	}
	proc p8 {} { 
		set chan [open v9990.txt a]
		puts $chan “&H68 [format%02X [reg a]]”
		close $chan
	}
	proc p9 {} { 
		set chan [open v9990.txt a]
		puts $chan “&H69 [format%02X [reg a]]”
		close $chan
	}
	proc pa {} { 
		set chan [open v9990.txt a]
		puts $chan “&H6A [format%02X [reg a]]”
		close $chan
	}
	proc pb {} { 
		set chan [open v9990.txt a]
		puts $chan “&H6B [format%02X [reg a]]”
		close $chan
	}
	proc pf {} { 
		set chan [open v9990.txt a]
		puts $chan “&H6f [format%02X [reg a]]”
		close $chan
	}
}

namespace export profile

namespace import profile::*

(not sure if it is correct this way)

And I am not being able to use it. Don't know what I am doing wrong. maybe I don't know what I am doing at all. I am trying to log to a file (v9990.txt) each data OUTed to V9990 ports.

after some point I typed at the console "profile ::p0" and got an error message: "Couldn't open "v9990.txt": Permission denied"

I am using openMSX 0.13 and macOS 10.11 (can't update to a newer macOS version though)

Any thoughts?

By Manuel

Ascended (14667)

Manuel's picture

19-09-2018, 07:34

Specify a path that is guaranteed to be writable, like ~/v9990.txt.

You can reduce the duplication as well, I will look at that later, if you don't beat me to it.

By Manuel

Ascended (14667)

Manuel's picture

19-09-2018, 15:05

OK, I think you meant to do something like this:

namespace eval v9990_profile {

variable file_handle ""
variable watchpoint

proc v9990_profile_start {} {
	variable file_handle
	variable watchpoint

	set file_handle [open "~/V9990.txt" "w"]
	set watchpoint [debug set_watchpoint write_io {0x60 0x6f} {} {v9990_profile::trigger}]
	return "Enabled V9990 profiling"
}

proc trigger {} {
	variable file_handle
	puts $file_handle "&H[format %02X [expr $::wp_last_address & 0xFF]] [format %02X $::wp_last_value]"
}

proc v9990_profile_stop {} {
	variable file_handle
	variable watchpoint
	if {$file_handle ne ""} {
		close $file_handle
		set file_handle ""
		debug remove_watchpoint $watchpoint
		return "Stopped V9990 profiling"
	}
}


namespace export v9990_profile_start
namespace export v9990_profile_stop

} ; #namespace

namespace import v9990_profile::*

This is just a quick script, so please adjust it to your own needs.

Main hints:
- in the console, type: help debug set_watchpoint for some more help
- you can use a watchpoint range
- you can use the special global variables $::wp_last_value and $::wp_last_address in the callback of the watchpoint to see what was going on
- you only need to open the file once and close it once (but BEWARE: the above script bluntly overwrites existing files, it does not append... you might want to change that.)
- the namespace is only to hide internal procs like "trigger" from being exposed to the console command line. So I explicitly export the ones I do want to get exposed.
- I/O port addresses are actually 16-bit, but only the lowest 8-bit really matter, hence the & 0xFF to mask the high bits off.
- internal variables that I need accross procs in this script are declared as 'variable' in the namespace. So they do not become global, but are still usable as 'class variables'. You do have to mention them in each proc where you use them, otherwise Tcl will create a new local variable in that proc
- I protected against stopping-before-you-started with a simple check.
- you could extend it by allowing a file name as argument to the start command. Or of course in any other way you like Smile

By tvalenca

Paladin (704)

tvalenca's picture

19-09-2018, 16:53

Thanks, Manuel! I'll give it a try when I get home from work.

Also, I'm not sure how I execute it. What I think I should do:

1. Save the code above on a file named "v9990_profile.tcl" and place it in "~/.openMSX/share/scripts/" (or "/Applications/openMSX.app/share/scripts/")
2. Launch openMSX, add GFX9000 (or Video9000) extension
3. Type "v9990_profile_start" on console
4. Run whatever I want to have logged
5. Type "v9990_profile_stop" on console when finished.

Is that correct?

By Manuel

Ascended (14667)

Manuel's picture

19-09-2018, 22:33

That will work. You can also load it manually with the 'source' command: source /path/to/my.tcl

By Manuel

Ascended (14667)

Manuel's picture

03-10-2018, 11:27

So, was it helpful?

Page 2/2
1 |
My MSX profile