_save_debuggable.tcl 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. namespace eval save_debuggable {
  2. set_help_text save_debuggable \
  3. {Save (part of) a debuggable to file. Examples of debuggables are memory, VRAM, ...
  4. Use 'debug list' to get a complete list of all debuggables.
  5. Usage:
  6. save_debuggable VRAM vram.raw Save the content of the MSX VRAM to a file
  7. called 'vram.raw'
  8. save_debuggable memory mem.sav 0x4000 0x8000
  9. Save the 32 kB content of the memory debuggable
  10. starting from 0x4000 to a file called 'mem.sav'
  11. }
  12. proc save_debuggable {debuggable filename {start 0} {size 0}} {
  13. if {$size == 0} { set size [expr {[debug size $debuggable] - $start}] }
  14. set data [debug read_block $debuggable $start $size]
  15. set file [open $filename "WRONLY CREAT TRUNC"]
  16. fconfigure $file -translation binary -buffersize $size
  17. puts -nonewline $file $data
  18. close $file
  19. }
  20. set_help_text load_debuggable \
  21. {Load a raw data file (somewhere) into a certain debuggable (see also save_debuggable).
  22. Note that saving and reloading the same data again does not always bring the
  23. MSX in the same state (e.g. the subslotregister). Use 'savestate' and 'loadstate'
  24. if you want that.
  25. }
  26. proc load_debuggable {debuggable filename {start 0}} {
  27. set size [file size $filename]
  28. set file [open $filename "RDONLY"]
  29. fconfigure $file -translation binary -buffersize $size
  30. set data [read $file]
  31. close $file
  32. debug write_block $debuggable $start $data
  33. }
  34. set_tabcompletion_proc save_debuggable [namespace code tab_loadsave_debuggable]
  35. set_tabcompletion_proc load_debuggable [namespace code tab_loadsave_debuggable]
  36. proc tab_loadsave_debuggable {args} {
  37. if {[llength $args] == 2} {
  38. return [debug list]
  39. }
  40. if {[llength $args] == 3} {
  41. return [utils::file_completion {*}$args]
  42. }
  43. }
  44. # TODO remove these two procs?
  45. # They were meant as a very quick-and-dirty savestate mechanism, but it
  46. # doesn't work (e.g. because of subslot register)
  47. proc save_all {directory} {
  48. puts stderr "This command ('save_all') has been deprecated (and may be removed in a future release). In contrast to what you might think, it cannot be used to save the machine state. You probably just want to use 'save_state' instead!"
  49. foreach debuggable [debug list] {
  50. save_debuggable $debuggable ${directory}/${debuggable}.sav
  51. }
  52. }
  53. proc load_all {directory} {
  54. puts stderr "This command ('load_all') has been deprecated (and may be removed in a future release). In contrast to what you might think, it cannot be used to load the machine state. You probably just want to use 'load_state' instead!"
  55. foreach debuggable [debug list] {
  56. load_debuggable $debuggable ${directory}/${debuggable}.sav
  57. }
  58. }
  59. # for backwards compatibility
  60. proc vramdump {{filename "vramdump"}} {
  61. #puts stderr "This command ('vramdump') has been deprecated (and may be removed in a future release), please use 'save_debuggable VRAM' instead!"
  62. # I prefer to keep this command as a convenience shortcut
  63. save_debuggable "VRAM" $filename
  64. }
  65. set_help_text vram2bmp \
  66. {Dump a selected region of the video memory into a bitmap file.
  67. vram filename filename [start address] [width] [length]
  68. usage example: vram2bmp RawDataDump.bmp 0 256 1024
  69. }
  70. proc vram2bmp {filename start dx dy} {
  71. set file [open $filename "WRONLY CREAT TRUNC"]
  72. set data_len [expr {$dx * $dy / 2}]
  73. set file_len [expr {$data_len + 0x76}]
  74. set file_len_HI [expr {$file_len / 0x100}]
  75. set dx_HI [expr {$dx / 0x100}]
  76. set dy_HI [expr {$dy / 0x100}]
  77. set data_len_HI [expr {$data_len / 0x100}]
  78. fconfigure $file -translation binary -buffersize $file_len
  79. puts -nonewline $file "\x42\x4d" ;# BMP FILE identificator
  80. puts -nonewline $file [format %c $file_len] ;# <-File length
  81. puts -nonewline $file [format %c $file_len_HI] ;# <-File length
  82. puts -nonewline $file "\x00\x00" ;# last always always zero because maximim file length is 128KB + header length
  83. puts -nonewline $file "\x00\x00\x00\x00" ;# unused
  84. puts -nonewline $file "\x76\x00\x00\x00" ;# offset to bitmap data - always same for 16 colors bmp
  85. puts -nonewline $file "\x28\x00\x00\x00" ;# number of bytes in the header
  86. puts -nonewline $file [format %c $dx] ;# bitmap width
  87. puts -nonewline $file [format %c $dx_HI] ;# bitmap width
  88. puts -nonewline $file "\x00\x00" ;# bitmap width - unused because maximum width is 256
  89. puts -nonewline $file [format %c $dy] ;# bitmap height
  90. puts -nonewline $file [format %c $dy_HI] ;# bitmap height
  91. puts -nonewline $file "\x00\x00" ;# bitmap height, if negative image will look normal in mspaint
  92. puts -nonewline $file "\x01\x00" ;# 1 plane used
  93. puts -nonewline $file "\x04\x00" ;# 4 bits per pixel
  94. puts -nonewline $file "\x00\x00\x00\x00" ;# no compression used
  95. puts -nonewline $file [format %c $data_len] ;# RAW image data length
  96. puts -nonewline $file [format %c $data_len_HI] ;# RAW image data length
  97. puts -nonewline $file "\x00\x00" ;# RAW image data length - always zero, because maximum length is 128KB
  98. puts -nonewline $file "\x00\x00\x00\x00"
  99. puts -nonewline $file "\x00\x00\x00\x00"
  100. puts -nonewline $file "\x00\x00\x00\x00" ;#how many colors used
  101. puts -nonewline $file "\x00\x00\x00\x00" ;#important colors
  102. #set colors (16 colors [0..15])
  103. for {set col 0} {$col < 16} {incr col} {
  104. set color [getcolor $col]
  105. puts -nonewline $file [format %c [expr {[string index $color 2] * 255 / 7}]]
  106. puts -nonewline $file [format %c [expr {[string index $color 1] * 255 / 7}]]
  107. puts -nonewline $file [format %c [expr {[string index $color 0] * 255 / 7}]]
  108. puts -nonewline $file "\x00"
  109. }
  110. set cur_addr $start
  111. for {set i 0} {$i < $dy} {incr i} {
  112. for {set addr $cur_addr} {$addr < ($cur_addr + $dx / 2)} {incr addr} {
  113. puts -nonewline $file [format %c [vpeek $addr]]
  114. }
  115. set cur_addr [expr {$cur_addr + 0x80}]
  116. }
  117. close $file
  118. }
  119. set_help_text save_to_file \
  120. {Helper proc to easily write something to a file.
  121. Typically used in combination with another proc. For example:
  122. save_to_file my_data.hex [showmem 0x8000 20]
  123. }
  124. proc save_to_file {filename data} {
  125. set file [open $filename "WRONLY CREAT TRUNC"]
  126. fconfigure $file -translation binary
  127. puts -nonewline $file $data
  128. close $file
  129. }
  130. namespace export save_debuggable
  131. namespace export load_debuggable
  132. namespace export save_all
  133. namespace export load_all
  134. namespace export vramdump
  135. namespace export vram2bmp
  136. namespace export save_to_file
  137. } ;# namespace save_debuggable
  138. namespace import save_debuggable::*