skoolkit 10.1__tar.gz → 10.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (261) hide show
  1. {skoolkit-10.1/skoolkit.egg-info → skoolkit-10.2}/PKG-INFO +2 -2
  2. {skoolkit-10.1 → skoolkit-10.2}/c/csimulator.c +108 -266
  3. {skoolkit-10.1 → skoolkit-10.2}/docs/_sources/asm.rst.txt +1 -1
  4. skoolkit-10.2/docs/_sources/changelog.rst.txt +142 -0
  5. skoolkit-10.1/docs/_sources/changelog.rst.txt → skoolkit-10.2/docs/_sources/changelog9.rst.txt +2 -90
  6. {skoolkit-10.1 → skoolkit-10.2}/docs/_sources/commands.rst.txt +291 -230
  7. {skoolkit-10.1 → skoolkit-10.2}/docs/_sources/components.rst.txt +3 -3
  8. {skoolkit-10.1 → skoolkit-10.2}/docs/_sources/diy.rst.txt +3 -3
  9. {skoolkit-10.1 → skoolkit-10.2}/docs/_sources/extending.rst.txt +15 -2
  10. {skoolkit-10.1 → skoolkit-10.2}/docs/_sources/html-templates.rst.txt +4 -1
  11. {skoolkit-10.1 → skoolkit-10.2}/docs/_sources/man/bin2sna.py.rst.txt +6 -6
  12. {skoolkit-10.1 → skoolkit-10.2}/docs/_sources/man/rzxplay.py.rst.txt +76 -2
  13. {skoolkit-10.1 → skoolkit-10.2}/docs/_sources/man/skool2asm.py.rst.txt +1 -1
  14. {skoolkit-10.1 → skoolkit-10.2}/docs/_sources/man/skool2bin.py.rst.txt +3 -3
  15. {skoolkit-10.1 → skoolkit-10.2}/docs/_sources/man/sna2ctl.py.rst.txt +2 -2
  16. {skoolkit-10.1 → skoolkit-10.2}/docs/_sources/man/sna2skool.py.rst.txt +2 -2
  17. {skoolkit-10.1 → skoolkit-10.2}/docs/_sources/man/snapinfo.py.rst.txt +4 -4
  18. {skoolkit-10.1 → skoolkit-10.2}/docs/_sources/man/snapmod.py.rst.txt +1 -1
  19. {skoolkit-10.1 → skoolkit-10.2}/docs/_sources/man/tap2sna.py.rst.txt +13 -5
  20. {skoolkit-10.1 → skoolkit-10.2}/docs/_sources/man/tapinfo.py.rst.txt +6 -0
  21. {skoolkit-10.1 → skoolkit-10.2}/docs/_sources/man/trace.py.rst.txt +8 -5
  22. {skoolkit-10.1 → skoolkit-10.2}/docs/_sources/ref-files.rst.txt +3 -3
  23. {skoolkit-10.1 → skoolkit-10.2}/docs/_sources/skool-files.rst.txt +2 -2
  24. {skoolkit-10.1 → skoolkit-10.2}/docs/_sources/skool-macros.rst.txt +6 -6
  25. {skoolkit-10.1 → skoolkit-10.2}/docs/_sources/usage.rst.txt +1 -1
  26. {skoolkit-10.1 → skoolkit-10.2}/docs/_static/documentation_options.js +1 -1
  27. {skoolkit-10.1 → skoolkit-10.2}/docs/asm-templates.html +4 -4
  28. {skoolkit-10.1 → skoolkit-10.2}/docs/asm.html +5 -5
  29. {skoolkit-10.1 → skoolkit-10.2}/docs/assemblers.html +4 -4
  30. skoolkit-10.2/docs/changelog.html +267 -0
  31. {skoolkit-10.1 → skoolkit-10.2}/docs/changelog1.html +4 -4
  32. {skoolkit-10.1 → skoolkit-10.2}/docs/changelog2.html +4 -4
  33. {skoolkit-10.1 → skoolkit-10.2}/docs/changelog3.html +4 -4
  34. {skoolkit-10.1 → skoolkit-10.2}/docs/changelog4.html +4 -4
  35. {skoolkit-10.1 → skoolkit-10.2}/docs/changelog5.html +4 -4
  36. {skoolkit-10.1 → skoolkit-10.2}/docs/changelog6.html +4 -4
  37. {skoolkit-10.1 → skoolkit-10.2}/docs/changelog7.html +4 -4
  38. {skoolkit-10.1 → skoolkit-10.2}/docs/changelog8.html +9 -9
  39. skoolkit-10.1/docs/changelog.html → skoolkit-10.2/docs/changelog9.html +37 -131
  40. {skoolkit-10.1 → skoolkit-10.2}/docs/commands.html +362 -300
  41. {skoolkit-10.1 → skoolkit-10.2}/docs/components.html +7 -7
  42. {skoolkit-10.1 → skoolkit-10.2}/docs/control-files.html +4 -4
  43. {skoolkit-10.1 → skoolkit-10.2}/docs/diy.html +4 -4
  44. {skoolkit-10.1 → skoolkit-10.2}/docs/extending.html +28 -6
  45. {skoolkit-10.1 → skoolkit-10.2}/docs/genindex.html +4 -4
  46. {skoolkit-10.1 → skoolkit-10.2}/docs/html-templates.html +8 -5
  47. {skoolkit-10.1 → skoolkit-10.2}/docs/index.html +4 -4
  48. {skoolkit-10.1 → skoolkit-10.2}/docs/man/bin2sna.py.html +10 -10
  49. {skoolkit-10.1 → skoolkit-10.2}/docs/man/bin2tap.py.html +4 -4
  50. {skoolkit-10.1 → skoolkit-10.2}/docs/man/rzxinfo.py.html +4 -4
  51. {skoolkit-10.1 → skoolkit-10.2}/docs/man/rzxplay.py.html +97 -6
  52. {skoolkit-10.1 → skoolkit-10.2}/docs/man/skool2asm.py.html +5 -5
  53. {skoolkit-10.1 → skoolkit-10.2}/docs/man/skool2bin.py.html +7 -7
  54. {skoolkit-10.1 → skoolkit-10.2}/docs/man/skool2ctl.py.html +4 -4
  55. {skoolkit-10.1 → skoolkit-10.2}/docs/man/skool2html.py.html +4 -4
  56. {skoolkit-10.1 → skoolkit-10.2}/docs/man/sna2ctl.py.html +6 -6
  57. {skoolkit-10.1 → skoolkit-10.2}/docs/man/sna2img.py.html +4 -4
  58. {skoolkit-10.1 → skoolkit-10.2}/docs/man/sna2skool.py.html +6 -6
  59. {skoolkit-10.1 → skoolkit-10.2}/docs/man/snapinfo.py.html +8 -8
  60. {skoolkit-10.1 → skoolkit-10.2}/docs/man/snapmod.py.html +5 -5
  61. {skoolkit-10.1 → skoolkit-10.2}/docs/man/tap2sna.py.html +23 -12
  62. {skoolkit-10.1 → skoolkit-10.2}/docs/man/tapinfo.py.html +11 -4
  63. {skoolkit-10.1 → skoolkit-10.2}/docs/man/trace.py.html +12 -9
  64. {skoolkit-10.1 → skoolkit-10.2}/docs/migration.html +4 -4
  65. {skoolkit-10.1 → skoolkit-10.2}/docs/parsing.html +4 -4
  66. {skoolkit-10.1 → skoolkit-10.2}/docs/ref-files.html +6 -6
  67. {skoolkit-10.1 → skoolkit-10.2}/docs/search.html +4 -4
  68. skoolkit-10.2/docs/searchindex.js +1 -0
  69. {skoolkit-10.1 → skoolkit-10.2}/docs/skool-files.html +6 -6
  70. {skoolkit-10.1 → skoolkit-10.2}/docs/skool-macros.html +10 -10
  71. {skoolkit-10.1 → skoolkit-10.2}/docs/usage.html +5 -5
  72. {skoolkit-10.1 → skoolkit-10.2}/docs/whatis.html +4 -4
  73. {skoolkit-10.1 → skoolkit-10.2}/man/man1/bin2sna.py.1 +7 -7
  74. {skoolkit-10.1 → skoolkit-10.2}/man/man1/bin2tap.py.1 +1 -1
  75. {skoolkit-10.1 → skoolkit-10.2}/man/man1/rzxinfo.py.1 +1 -1
  76. {skoolkit-10.1 → skoolkit-10.2}/man/man1/rzxplay.py.1 +113 -3
  77. {skoolkit-10.1 → skoolkit-10.2}/man/man1/skool2asm.py.1 +2 -2
  78. {skoolkit-10.1 → skoolkit-10.2}/man/man1/skool2bin.py.1 +4 -4
  79. {skoolkit-10.1 → skoolkit-10.2}/man/man1/skool2ctl.py.1 +1 -1
  80. {skoolkit-10.1 → skoolkit-10.2}/man/man1/skool2html.py.1 +1 -1
  81. {skoolkit-10.1 → skoolkit-10.2}/man/man1/sna2ctl.py.1 +3 -3
  82. {skoolkit-10.1 → skoolkit-10.2}/man/man1/sna2img.py.1 +1 -1
  83. {skoolkit-10.1 → skoolkit-10.2}/man/man1/sna2skool.py.1 +3 -3
  84. {skoolkit-10.1 → skoolkit-10.2}/man/man1/snapinfo.py.1 +5 -5
  85. {skoolkit-10.1 → skoolkit-10.2}/man/man1/snapmod.py.1 +2 -2
  86. {skoolkit-10.1 → skoolkit-10.2}/man/man1/tap2sna.py.1 +18 -6
  87. {skoolkit-10.1 → skoolkit-10.2}/man/man1/tapinfo.py.1 +9 -1
  88. {skoolkit-10.1 → skoolkit-10.2}/man/man1/trace.py.1 +9 -6
  89. {skoolkit-10.1 → skoolkit-10.2}/setup.cfg +1 -1
  90. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/__init__.py +73 -23
  91. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/audio.py +38 -11
  92. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/ay.py +8 -7
  93. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/basic.py +42 -31
  94. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/bin2sna.py +11 -11
  95. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/bin2tap.py +32 -24
  96. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/config.py +10 -0
  97. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/ctlparser.py +7 -4
  98. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/defaults.py +1 -0
  99. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/disassembler.py +2 -2
  100. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/graphics.py +38 -11
  101. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/image.py +4 -1
  102. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/loadtracer.py +6 -152
  103. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/pagingtracer.py +7 -0
  104. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/pngwriter.py +2 -2
  105. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/refparser.py +17 -15
  106. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/resources/skoolkit.css +11 -3
  107. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/rzxinfo.py +18 -7
  108. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/rzxplay.py +85 -39
  109. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/screen.py +23 -7
  110. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/simulator.py +1 -1
  111. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/simutils.py +14 -12
  112. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/skool2asm.py +13 -7
  113. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/skool2bin.py +50 -45
  114. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/skool2ctl.py +4 -4
  115. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/skool2html.py +25 -17
  116. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/skoolasm.py +53 -16
  117. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/skoolctl.py +8 -7
  118. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/skoolhtml.py +89 -47
  119. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/skoolmacro.py +176 -57
  120. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/skoolparser.py +51 -32
  121. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/skoolutils.py +79 -45
  122. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/sna2ctl.py +16 -14
  123. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/sna2img.py +25 -13
  124. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/sna2skool.py +17 -8
  125. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/snactl.py +6 -3
  126. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/snapinfo.py +35 -25
  127. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/snapmod.py +2 -2
  128. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/snapshot.py +89 -41
  129. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/snaskool.py +2 -2
  130. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/tap2sna.py +47 -37
  131. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/tape.py +293 -53
  132. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/tapinfo.py +54 -9
  133. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/trace.py +30 -19
  134. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/traceutils.py +17 -2
  135. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/z80.py +39 -13
  136. {skoolkit-10.1 → skoolkit-10.2/skoolkit.egg-info}/PKG-INFO +2 -2
  137. {skoolkit-10.1 → skoolkit-10.2}/skoolkit.egg-info/SOURCES.txt +2 -0
  138. {skoolkit-10.1 → skoolkit-10.2}/tests/macrotest.py +286 -51
  139. {skoolkit-10.1 → skoolkit-10.2}/tests/skoolkittest.py +75 -5
  140. {skoolkit-10.1 → skoolkit-10.2}/tests/test_audio.py +45 -1
  141. {skoolkit-10.1 → skoolkit-10.2}/tests/test_basic.py +151 -0
  142. {skoolkit-10.1 → skoolkit-10.2}/tests/test_bin2sna.py +61 -5
  143. {skoolkit-10.1 → skoolkit-10.2}/tests/test_bin2tap.py +209 -19
  144. {skoolkit-10.1 → skoolkit-10.2}/tests/test_disassembler.py +24 -0
  145. {skoolkit-10.1 → skoolkit-10.2}/tests/test_graphics.py +7 -1
  146. {skoolkit-10.1 → skoolkit-10.2}/tests/test_rzxinfo.py +168 -3
  147. {skoolkit-10.1 → skoolkit-10.2}/tests/test_rzxplay.py +885 -341
  148. {skoolkit-10.1 → skoolkit-10.2}/tests/test_screen.py +30 -0
  149. {skoolkit-10.1 → skoolkit-10.2}/tests/test_skool2asm.py +103 -4
  150. {skoolkit-10.1 → skoolkit-10.2}/tests/test_skool2bin.py +159 -12
  151. {skoolkit-10.1 → skoolkit-10.2}/tests/test_skool2ctl.py +22 -1
  152. {skoolkit-10.1 → skoolkit-10.2}/tests/test_skool2html.py +201 -8
  153. {skoolkit-10.1 → skoolkit-10.2}/tests/test_skoolasm.py +284 -25
  154. {skoolkit-10.1 → skoolkit-10.2}/tests/test_skoolctl.py +8 -2
  155. {skoolkit-10.1 → skoolkit-10.2}/tests/test_skoolhtml.py +723 -156
  156. skoolkit-10.2/tests/test_skoolkit.py +119 -0
  157. {skoolkit-10.1 → skoolkit-10.2}/tests/test_skoolparser.py +224 -10
  158. {skoolkit-10.1 → skoolkit-10.2}/tests/test_skoolutils.py +14 -1
  159. {skoolkit-10.1 → skoolkit-10.2}/tests/test_sna2ctl.py +74 -11
  160. {skoolkit-10.1 → skoolkit-10.2}/tests/test_sna2img.py +227 -157
  161. {skoolkit-10.1 → skoolkit-10.2}/tests/test_sna2skool.py +71 -8
  162. {skoolkit-10.1 → skoolkit-10.2}/tests/test_snapinfo.py +141 -5
  163. {skoolkit-10.1 → skoolkit-10.2}/tests/test_snapmod.py +66 -11
  164. {skoolkit-10.1 → skoolkit-10.2}/tests/test_snapshot.py +311 -18
  165. {skoolkit-10.1 → skoolkit-10.2}/tests/test_snaskool.py +102 -2
  166. {skoolkit-10.1 → skoolkit-10.2}/tests/test_tap2sna.py +518 -31
  167. skoolkit-10.2/tests/test_tape.py +547 -0
  168. {skoolkit-10.1 → skoolkit-10.2}/tests/test_tapinfo.py +645 -85
  169. {skoolkit-10.1 → skoolkit-10.2}/tests/test_trace.py +221 -24
  170. {skoolkit-10.1 → skoolkit-10.2}/tests/test_z80.py +21 -1
  171. skoolkit-10.1/docs/searchindex.js +0 -1
  172. skoolkit-10.1/tests/test_skoolkit.py +0 -58
  173. skoolkit-10.1/tests/test_tape.py +0 -72
  174. {skoolkit-10.1 → skoolkit-10.2}/COPYING +0 -0
  175. {skoolkit-10.1 → skoolkit-10.2}/MANIFEST.in +0 -0
  176. {skoolkit-10.1 → skoolkit-10.2}/bin2sna.py +0 -0
  177. {skoolkit-10.1 → skoolkit-10.2}/bin2tap.py +0 -0
  178. {skoolkit-10.1 → skoolkit-10.2}/docs/_sources/asm-templates.rst.txt +0 -0
  179. {skoolkit-10.1 → skoolkit-10.2}/docs/_sources/assemblers.rst.txt +0 -0
  180. {skoolkit-10.1 → skoolkit-10.2}/docs/_sources/changelog1.rst.txt +0 -0
  181. {skoolkit-10.1 → skoolkit-10.2}/docs/_sources/changelog2.rst.txt +0 -0
  182. {skoolkit-10.1 → skoolkit-10.2}/docs/_sources/changelog3.rst.txt +0 -0
  183. {skoolkit-10.1 → skoolkit-10.2}/docs/_sources/changelog4.rst.txt +0 -0
  184. {skoolkit-10.1 → skoolkit-10.2}/docs/_sources/changelog5.rst.txt +0 -0
  185. {skoolkit-10.1 → skoolkit-10.2}/docs/_sources/changelog6.rst.txt +0 -0
  186. {skoolkit-10.1 → skoolkit-10.2}/docs/_sources/changelog7.rst.txt +0 -0
  187. {skoolkit-10.1 → skoolkit-10.2}/docs/_sources/changelog8.rst.txt +0 -0
  188. {skoolkit-10.1 → skoolkit-10.2}/docs/_sources/control-files.rst.txt +0 -0
  189. {skoolkit-10.1 → skoolkit-10.2}/docs/_sources/index.rst.txt +0 -0
  190. {skoolkit-10.1 → skoolkit-10.2}/docs/_sources/man/bin2tap.py.rst.txt +0 -0
  191. {skoolkit-10.1 → skoolkit-10.2}/docs/_sources/man/rzxinfo.py.rst.txt +0 -0
  192. {skoolkit-10.1 → skoolkit-10.2}/docs/_sources/man/skool2ctl.py.rst.txt +0 -0
  193. {skoolkit-10.1 → skoolkit-10.2}/docs/_sources/man/skool2html.py.rst.txt +0 -0
  194. {skoolkit-10.1 → skoolkit-10.2}/docs/_sources/man/sna2img.py.rst.txt +0 -0
  195. {skoolkit-10.1 → skoolkit-10.2}/docs/_sources/migration.rst.txt +0 -0
  196. {skoolkit-10.1 → skoolkit-10.2}/docs/_sources/parsing.rst.txt +0 -0
  197. {skoolkit-10.1 → skoolkit-10.2}/docs/_sources/whatis.rst.txt +0 -0
  198. {skoolkit-10.1 → skoolkit-10.2}/docs/_static/basic.css +0 -0
  199. {skoolkit-10.1 → skoolkit-10.2}/docs/_static/classic.css +0 -0
  200. {skoolkit-10.1 → skoolkit-10.2}/docs/_static/custom.css +0 -0
  201. {skoolkit-10.1 → skoolkit-10.2}/docs/_static/doctools.js +0 -0
  202. {skoolkit-10.1 → skoolkit-10.2}/docs/_static/file.png +0 -0
  203. {skoolkit-10.1 → skoolkit-10.2}/docs/_static/language_data.js +0 -0
  204. {skoolkit-10.1 → skoolkit-10.2}/docs/_static/minus.png +0 -0
  205. {skoolkit-10.1 → skoolkit-10.2}/docs/_static/plus.png +0 -0
  206. {skoolkit-10.1 → skoolkit-10.2}/docs/_static/pygments.css +0 -0
  207. {skoolkit-10.1 → skoolkit-10.2}/docs/_static/searchtools.js +0 -0
  208. {skoolkit-10.1 → skoolkit-10.2}/docs/_static/sidebar.js +0 -0
  209. {skoolkit-10.1 → skoolkit-10.2}/docs/_static/sphinx_highlight.js +0 -0
  210. {skoolkit-10.1 → skoolkit-10.2}/examples/hungry_horace.ctl +0 -0
  211. {skoolkit-10.1 → skoolkit-10.2}/examples/hungry_horace.ref +0 -0
  212. {skoolkit-10.1 → skoolkit-10.2}/examples/hungry_horace.t2s +0 -0
  213. {skoolkit-10.1 → skoolkit-10.2}/long_description.rst +0 -0
  214. {skoolkit-10.1 → skoolkit-10.2}/pyproject.toml +0 -0
  215. {skoolkit-10.1 → skoolkit-10.2}/rzxinfo.py +0 -0
  216. {skoolkit-10.1 → skoolkit-10.2}/rzxplay.py +0 -0
  217. {skoolkit-10.1 → skoolkit-10.2}/setup.py +0 -0
  218. {skoolkit-10.1 → skoolkit-10.2}/skool2asm.py +0 -0
  219. {skoolkit-10.1 → skoolkit-10.2}/skool2bin.py +0 -0
  220. {skoolkit-10.1 → skoolkit-10.2}/skool2ctl.py +0 -0
  221. {skoolkit-10.1 → skoolkit-10.2}/skool2html.py +0 -0
  222. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/cmiosimulator.py +0 -0
  223. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/comment.py +0 -0
  224. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/components.py +0 -0
  225. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/kbtracer.py +0 -0
  226. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/loadsample.py +0 -0
  227. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/opcodes.py +0 -0
  228. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/resources/128-0.rom +0 -0
  229. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/resources/128-1.rom +0 -0
  230. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/resources/48.rom +0 -0
  231. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/resources/plus2-0.rom +0 -0
  232. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/resources/plus2-1.rom +0 -0
  233. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/resources/skoolkit-dark.css +0 -0
  234. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/resources/skoolkit-green.css +0 -0
  235. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/resources/skoolkit-plum.css +0 -0
  236. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/resources/skoolkit-wide.css +0 -0
  237. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/rst.py +0 -0
  238. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/simtables.py +0 -0
  239. {skoolkit-10.1 → skoolkit-10.2}/skoolkit/textutils.py +0 -0
  240. {skoolkit-10.1 → skoolkit-10.2}/skoolkit.egg-info/dependency_links.txt +0 -0
  241. {skoolkit-10.1 → skoolkit-10.2}/skoolkit.egg-info/top_level.txt +0 -0
  242. {skoolkit-10.1 → skoolkit-10.2}/sna2ctl.py +0 -0
  243. {skoolkit-10.1 → skoolkit-10.2}/sna2img.py +0 -0
  244. {skoolkit-10.1 → skoolkit-10.2}/sna2skool.py +0 -0
  245. {skoolkit-10.1 → skoolkit-10.2}/snapinfo.py +0 -0
  246. {skoolkit-10.1 → skoolkit-10.2}/snapmod.py +0 -0
  247. {skoolkit-10.1 → skoolkit-10.2}/tap2sna.py +0 -0
  248. {skoolkit-10.1 → skoolkit-10.2}/tapinfo.py +0 -0
  249. {skoolkit-10.1 → skoolkit-10.2}/tests/test_ay.py +0 -0
  250. {skoolkit-10.1 → skoolkit-10.2}/tests/test_cmiosimulator.py +0 -0
  251. {skoolkit-10.1 → skoolkit-10.2}/tests/test_comment.py +0 -0
  252. {skoolkit-10.1 → skoolkit-10.2}/tests/test_ctlparser.py +0 -0
  253. {skoolkit-10.1 → skoolkit-10.2}/tests/test_image.py +0 -0
  254. {skoolkit-10.1 → skoolkit-10.2}/tests/test_kbtracer.py +0 -0
  255. {skoolkit-10.1 → skoolkit-10.2}/tests/test_pagingtracer.py +0 -0
  256. {skoolkit-10.1 → skoolkit-10.2}/tests/test_refparser.py +0 -0
  257. {skoolkit-10.1 → skoolkit-10.2}/tests/test_simulator.py +0 -0
  258. {skoolkit-10.1 → skoolkit-10.2}/tests/test_skoolmacro.py +0 -0
  259. {skoolkit-10.1 → skoolkit-10.2}/tests/test_textutils.py +0 -0
  260. {skoolkit-10.1 → skoolkit-10.2}/tests/test_traceutils.py +0 -0
  261. {skoolkit-10.1 → skoolkit-10.2}/trace.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: skoolkit
3
- Version: 10.1
3
+ Version: 10.2
4
4
  Summary: A suite of tools for creating disassemblies of ZX Spectrum games
5
5
  Home-page: https://skoolkit.ca
6
6
  Author: Richard Dymond
@@ -10,11 +10,11 @@ Classifier: Development Status :: 5 - Production/Stable
10
10
  Classifier: Operating System :: OS Independent
11
11
  Classifier: Programming Language :: Python :: 3
12
12
  Classifier: Programming Language :: Python :: 3 :: Only
13
- Classifier: Programming Language :: Python :: 3.10
14
13
  Classifier: Programming Language :: Python :: 3.11
15
14
  Classifier: Programming Language :: Python :: 3.12
16
15
  Classifier: Programming Language :: Python :: 3.13
17
16
  Classifier: Programming Language :: Python :: 3.14
17
+ Classifier: Programming Language :: Python :: 3.15
18
18
  Classifier: Topic :: Software Development :: Disassemblers
19
19
  Classifier: Topic :: Utilities
20
20
  Description-Content-Type: text/x-rst
@@ -39,6 +39,20 @@
39
39
  #define CHECK_SIGNALS if ((TIME & 0xFFFFFF) < 10) PyErr_CheckSignals()
40
40
  #define SCR_LEN 6912
41
41
 
42
+ #define GET_OPCODE_FUNC(opcodes) \
43
+ byte opcode = PEEK(pc); \
44
+ OpcodeFunction* opcode_func = opcodes[opcode]; \
45
+ if (!opcode_func->func) { \
46
+ byte opcode2 = PEEK(ADDR(pc + 1)); \
47
+ switch (opcode) { \
48
+ case 0xCB: opcode_func = &after_CB[opcode2]; break; \
49
+ case 0xED: opcode_func = &after_ED[opcode2]; break; \
50
+ case 0xDD: opcode_func = opcode2 == 0xCB ? &after_DDCB[PEEK(ADDR(pc + 3))] : &after_DD[opcode2]; break; \
51
+ case 0xFD: opcode_func = opcode2 == 0xCB ? &after_FDCB[PEEK(ADDR(pc + 3))] : &after_FD[opcode2]; break; \
52
+ default: break; \
53
+ } \
54
+ }
55
+
42
56
  typedef unsigned char byte;
43
57
 
44
58
  typedef void (*contend_f)(unsigned* t, unsigned* delay, int urc, int n, const unsigned* cpattern);
@@ -1716,7 +1730,7 @@ static void in_a(CSimulatorObject* self, void* lookup, int args[]) {
1716
1730
  value = self->read_port(self, port);
1717
1731
  } else {
1718
1732
  PyObject* m_args = Py_BuildValue("(OI)", self->registers_obj, port);
1719
- PyObject* rv = PyObject_Call(self->in_a_n_tracer, m_args, NULL);
1733
+ PyObject* rv = m_args ? PyObject_Call(self->in_a_n_tracer, m_args, NULL) : NULL;
1720
1734
  Py_XDECREF(m_args);
1721
1735
  if (rv) {
1722
1736
  value = PyLong_AsLong(rv);
@@ -1751,7 +1765,7 @@ static void in_c(CSimulatorObject* self, void* lookup, int args[]) {
1751
1765
  value = self->read_port(self, port);
1752
1766
  } else {
1753
1767
  PyObject* m_args = Py_BuildValue("(OI)", self->registers_obj, port);
1754
- PyObject* rv = PyObject_Call(self->in_r_c_tracer, m_args, NULL);
1768
+ PyObject* rv = m_args ? PyObject_Call(self->in_r_c_tracer, m_args, NULL) : NULL;
1755
1769
  Py_XDECREF(m_args);
1756
1770
  if (rv) {
1757
1771
  value = PyLong_AsLong(rv);
@@ -1820,7 +1834,7 @@ static void ini(CSimulatorObject* self, void* lookup, int args[]) {
1820
1834
  value = self->read_port(self, port);
1821
1835
  } else {
1822
1836
  PyObject* m_args = Py_BuildValue("(OI)", self->registers_obj, port);
1823
- PyObject* rv = PyObject_Call(self->ini_tracer, m_args, NULL);
1837
+ PyObject* rv = m_args ? PyObject_Call(self->ini_tracer, m_args, NULL) : NULL;
1824
1838
  Py_XDECREF(m_args);
1825
1839
  if (rv) {
1826
1840
  value = (byte)PyLong_AsLong(rv);
@@ -2494,7 +2508,7 @@ static void out_a(CSimulatorObject* self, void* lookup, int args[]) {
2494
2508
  OUT(port, value);
2495
2509
  if (self->out_tracer) {
2496
2510
  PyObject* m_args = Py_BuildValue("(OIBI)", self->registers_obj, port, value, 12 + delay);
2497
- PyObject* rv = PyObject_Call(self->out_tracer, m_args, NULL);
2511
+ PyObject* rv = m_args ? PyObject_Call(self->out_tracer, m_args, NULL) : NULL;
2498
2512
  Py_XDECREF(m_args);
2499
2513
  if (rv == NULL) {
2500
2514
  return;
@@ -2527,7 +2541,7 @@ static void out_c(CSimulatorObject* self, void* lookup, int args[]) {
2527
2541
  OUT(port, value);
2528
2542
  if (self->out_tracer) {
2529
2543
  PyObject* m_args = Py_BuildValue("(OIBI)", self->registers_obj, port, value, 13 + delay);
2530
- PyObject* rv = PyObject_Call(self->out_tracer, m_args, NULL);
2544
+ PyObject* rv = m_args ? PyObject_Call(self->out_tracer, m_args, NULL) : NULL;
2531
2545
  Py_XDECREF(m_args);
2532
2546
  if (rv == NULL) {
2533
2547
  return;
@@ -2567,7 +2581,7 @@ static void outi(CSimulatorObject* self, void* lookup, int args[]) {
2567
2581
  OUT(port, value);
2568
2582
  if (self->out_tracer) {
2569
2583
  PyObject* m_args = Py_BuildValue("(OIBI)", self->registers_obj, port, value, 17 + io_delay);
2570
- PyObject* rv = PyObject_Call(self->out_tracer, m_args, NULL);
2584
+ PyObject* rv = m_args ? PyObject_Call(self->out_tracer, m_args, NULL) : NULL;
2571
2585
  Py_XDECREF(m_args);
2572
2586
  if (rv == NULL) {
2573
2587
  return;
@@ -5066,13 +5080,18 @@ static PyObject* convert_memory(PyObject* source) {
5066
5080
  goto done;
5067
5081
  }
5068
5082
  while (mem_ok == 0 && addr < size && (item = PyIter_Next(mem_iter)) != NULL) {
5083
+ long value = 0;
5069
5084
  if (PyLong_Check(item)) {
5070
- mem[addr] = PyLong_AsLong(item) & 0xFF;
5085
+ value = PyLong_AsLong(item);
5086
+ if (PyErr_Occurred()) {
5087
+ mem_ok = -1;
5088
+ }
5071
5089
  } else {
5072
5090
  PyErr_Format(PyExc_TypeError, "Object at memory address %u is not an integer", addr);
5073
5091
  mem_ok = -1;
5074
5092
  }
5075
5093
  Py_DECREF(item);
5094
+ mem[addr] = value & 0xFF;
5076
5095
  addr += 1;
5077
5096
  }
5078
5097
  Py_DECREF(mem_iter);
@@ -5179,6 +5198,10 @@ static PyObject* CSimulator_set_tracer(CSimulatorObject* self, PyObject* args, P
5179
5198
 
5180
5199
  if (PyObject_HasAttrString(tracer, "read_port")) {
5181
5200
  PyObject* read_port = PyObject_GetAttrString(tracer, "read_port");
5201
+ if (read_port == NULL) {
5202
+ ok = 0;
5203
+ goto done;
5204
+ }
5182
5205
  self->in_a_n_tracer = read_port;
5183
5206
  if (in_r_c) {
5184
5207
  self->in_r_c_tracer = read_port;
@@ -5238,35 +5261,7 @@ static PyObject* CSimulator_run(CSimulatorObject* self, PyObject* args, PyObject
5238
5261
 
5239
5262
  while (1) {
5240
5263
  unsigned pc = REG(PC);
5241
- byte opcode = PEEK(pc);
5242
- OpcodeFunction* opcode_func = &opcodes[opcode];
5243
- if (!opcode_func->func) {
5244
- byte opcode2 = PEEK(ADDR(pc + 1));
5245
- switch (opcode) {
5246
- case 0xCB:
5247
- opcode_func = &after_CB[opcode2];
5248
- break;
5249
- case 0xED:
5250
- opcode_func = &after_ED[opcode2];
5251
- break;
5252
- case 0xDD:
5253
- if (opcode2 == 0xCB) {
5254
- opcode_func = &after_DDCB[PEEK(ADDR(pc + 3))];
5255
- } else {
5256
- opcode_func = &after_DD[opcode2];
5257
- }
5258
- break;
5259
- case 0xFD:
5260
- if (opcode2 == 0xCB) {
5261
- opcode_func = &after_FDCB[PEEK(ADDR(pc + 3))];
5262
- } else {
5263
- opcode_func = &after_FD[opcode2];
5264
- }
5265
- break;
5266
- default:
5267
- break;
5268
- }
5269
- }
5264
+ GET_OPCODE_FUNC(&opcodes);
5270
5265
 
5271
5266
  opcode_func->func(self, opcode_func->lookup, opcode_func->args);
5272
5267
  if (PyErr_Occurred()) {
@@ -5300,35 +5295,8 @@ static PyObject* CSimulator_exec_with_cb(CSimulatorObject* self, PyObject* args,
5300
5295
  byte* mem = self->memory;
5301
5296
 
5302
5297
  while (1) {
5303
- byte opcode = PEEK(REG(PC));
5304
- OpcodeFunction* opcode_func = &opcodes[opcode];
5305
- if (!opcode_func->func) {
5306
- byte opcode2 = PEEK(ADDR(REG(PC) + 1));
5307
- switch (opcode) {
5308
- case 0xCB:
5309
- opcode_func = &after_CB[opcode2];
5310
- break;
5311
- case 0xED:
5312
- opcode_func = &after_ED[opcode2];
5313
- break;
5314
- case 0xDD:
5315
- if (opcode2 == 0xCB) {
5316
- opcode_func = &after_DDCB[PEEK(ADDR(REG(PC) + 3))];
5317
- } else {
5318
- opcode_func = &after_DD[opcode2];
5319
- }
5320
- break;
5321
- case 0xFD:
5322
- if (opcode2 == 0xCB) {
5323
- opcode_func = &after_FDCB[PEEK(ADDR(REG(PC) + 3))];
5324
- } else {
5325
- opcode_func = &after_FD[opcode2];
5326
- }
5327
- break;
5328
- default:
5329
- break;
5330
- }
5331
- }
5298
+ unsigned pc = REG(PC);
5299
+ GET_OPCODE_FUNC(&opcodes);
5332
5300
 
5333
5301
  opcode_func->func(self, opcode_func->lookup, opcode_func->args);
5334
5302
  if (PyErr_Occurred()) {
@@ -5337,7 +5305,7 @@ static PyObject* CSimulator_exec_with_cb(CSimulatorObject* self, PyObject* args,
5337
5305
 
5338
5306
  if (opcode == 0xD7) {
5339
5307
  PyObject* arg = PyLong_FromLong(REG(A));
5340
- PyObject* rv = PyObject_CallOneArg(rst16_cb, arg);
5308
+ PyObject* rv = arg ? PyObject_CallOneArg(rst16_cb, arg) : NULL;
5341
5309
  Py_XDECREF(arg);
5342
5310
  if (rv == NULL) {
5343
5311
  return NULL;
@@ -5363,65 +5331,20 @@ static PyObject* CSimulator_exec_frame(CSimulatorObject* self, PyObject* args, P
5363
5331
  return NULL;
5364
5332
  }
5365
5333
 
5334
+ if (exec_map != Py_None && !PySet_Check(exec_map)) {
5335
+ PyErr_SetString(PyExc_TypeError, "'exec_map' is not a set");
5336
+ return NULL;
5337
+ }
5338
+
5366
5339
  unsigned long long* reg = self->registers;
5367
5340
  byte* mem = self->memory;
5368
5341
  unsigned pc;
5369
5342
 
5370
5343
  while (1) {
5371
5344
  pc = REG(PC);
5372
- byte opcode = PEEK(pc);
5373
- byte opcode2 = PEEK(ADDR(pc + 1));
5374
- OpcodeFunction* opcode_func = &opcodes[opcode];
5375
- unsigned r0;
5376
- unsigned r_inc = 1;
5377
- if (!opcode_func->func) {
5378
- switch (opcode) {
5379
- case 0xCB: {
5380
- r_inc = 2;
5381
- opcode_func = &after_CB[opcode2];
5382
- break;
5383
- }
5384
- case 0xED: {
5385
- r_inc = 2;
5386
- opcode_func = &after_ED[opcode2];
5387
- break;
5388
- }
5389
- case 0xDD: {
5390
- r0 = REG(R);
5391
- if (opcode2 == 0xCB) {
5392
- r_inc = 2;
5393
- opcode_func = &after_DDCB[PEEK(ADDR(REG(PC) + 3))];
5394
- } else {
5395
- r_inc = 0;
5396
- opcode_func = &after_DD[opcode2];
5397
- }
5398
- break;
5399
- }
5400
- case 0xFD: {
5401
- r0 = REG(R);
5402
- if (opcode2 == 0xCB) {
5403
- r_inc = 2;
5404
- opcode_func = &after_FDCB[PEEK(ADDR(REG(PC) + 3))];
5405
- } else {
5406
- r_inc = 0;
5407
- opcode_func = &after_FD[opcode2];
5408
- }
5409
- break;
5410
- }
5411
- default:
5412
- break;
5413
- }
5414
- }
5415
-
5416
- if (trace != Py_None) {
5417
- PyObject* m_args = Py_BuildValue("(II)", fetch_count, pc);
5418
- PyObject* rv = PyObject_Call(trace, m_args, NULL);
5419
- Py_XDECREF(m_args);
5420
- if (rv == NULL) {
5421
- return NULL;
5422
- }
5423
- Py_DECREF(rv);
5424
- }
5345
+ unsigned long long t0 = TIME;
5346
+ unsigned r0 = REG(R);
5347
+ GET_OPCODE_FUNC(&opcodes);
5425
5348
 
5426
5349
  opcode_func->func(self, opcode_func->lookup, opcode_func->args);
5427
5350
  if (PyErr_Occurred()) {
@@ -5430,17 +5353,23 @@ static PyObject* CSimulator_exec_frame(CSimulatorObject* self, PyObject* args, P
5430
5353
 
5431
5354
  if (exec_map != Py_None) {
5432
5355
  PyObject* addr = PyLong_FromLong(pc);
5433
- int rv = PySet_Add(exec_map, addr);
5356
+ int rv = addr ? PySet_Add(exec_map, addr) : -1;
5434
5357
  Py_XDECREF(addr);
5435
5358
  if (rv == -1) {
5436
5359
  return NULL;
5437
5360
  }
5438
5361
  }
5439
5362
 
5440
- if (r_inc) {
5441
- fetch_count -= r_inc;
5442
- } else {
5443
- fetch_count -= 2 - ((REG(R) ^ r0) & 1);
5363
+ fetch_count -= opcode == 0xED ? 2 : 2 - ((REG(R) ^ r0) & 1);
5364
+
5365
+ if (trace != Py_None) {
5366
+ PyObject* m_args = Py_BuildValue("(IIK)", fetch_count, pc, t0);
5367
+ PyObject* rv = m_args ? PyObject_Call(trace, m_args, NULL) : NULL;
5368
+ Py_XDECREF(m_args);
5369
+ if (rv == NULL) {
5370
+ return NULL;
5371
+ }
5372
+ Py_DECREF(rv);
5444
5373
  }
5445
5374
 
5446
5375
  if (fetch_count <= 0) {
@@ -5485,6 +5414,11 @@ static PyObject* CSimulator_trace(CSimulatorObject* self, PyObject* args, PyObje
5485
5414
  return NULL;
5486
5415
  }
5487
5416
 
5417
+ if (exec_map != Py_None && !PySet_Check(exec_map)) {
5418
+ PyErr_SetString(PyExc_TypeError, "'exec_map' is not a set");
5419
+ return NULL;
5420
+ }
5421
+
5488
5422
  if (self->tracer == NULL) {
5489
5423
  PyErr_SetString(PyExc_ValueError, "no tracer set");
5490
5424
  return NULL;
@@ -5512,39 +5446,11 @@ static PyObject* CSimulator_trace(CSimulatorObject* self, PyObject* args, PyObje
5512
5446
  unsigned long long t0 = TIME;
5513
5447
  unsigned long long prev_frame = t0 / frame_duration;
5514
5448
  unsigned pc = REG(PC);
5515
- byte opcode = PEEK(pc);
5516
- OpcodeFunction* opcode_func = &opcodes[opcode];
5517
- if (!opcode_func->func) {
5518
- byte opcode2 = PEEK(ADDR(pc + 1));
5519
- switch (opcode) {
5520
- case 0xCB:
5521
- opcode_func = &after_CB[opcode2];
5522
- break;
5523
- case 0xED:
5524
- opcode_func = &after_ED[opcode2];
5525
- break;
5526
- case 0xDD:
5527
- if (opcode2 == 0xCB) {
5528
- opcode_func = &after_DDCB[PEEK(ADDR(pc + 3))];
5529
- } else {
5530
- opcode_func = &after_DD[opcode2];
5531
- }
5532
- break;
5533
- case 0xFD:
5534
- if (opcode2 == 0xCB) {
5535
- opcode_func = &after_FDCB[PEEK(ADDR(pc + 3))];
5536
- } else {
5537
- opcode_func = &after_FD[opcode2];
5538
- }
5539
- break;
5540
- default:
5541
- break;
5542
- }
5543
- }
5449
+ GET_OPCODE_FUNC(&opcodes);
5544
5450
 
5545
5451
  if (disassembling) {
5546
5452
  PyObject* arg = PyLong_FromLong(pc);
5547
- i = PyObject_CallOneArg(disassemble, arg);
5453
+ i = arg ? PyObject_CallOneArg(disassemble, arg) : NULL;
5548
5454
  Py_XDECREF(arg);
5549
5455
  if (i == NULL) {
5550
5456
  return NULL;
@@ -5559,7 +5465,7 @@ static PyObject* CSimulator_trace(CSimulatorObject* self, PyObject* args, PyObje
5559
5465
 
5560
5466
  if (exec_map != Py_None) {
5561
5467
  PyObject* addr = PyLong_FromLong(pc);
5562
- int rv = PySet_Add(exec_map, addr);
5468
+ int rv = addr ? PySet_Add(exec_map, addr) : -1;
5563
5469
  Py_XDECREF(addr);
5564
5470
  if (rv == -1) {
5565
5471
  Py_XDECREF(i);
@@ -5632,6 +5538,11 @@ static PyObject* CSimulator_press_keys(CSimulatorObject* self, PyObject* args, P
5632
5538
  return NULL;
5633
5539
  }
5634
5540
 
5541
+ if (!PyList_Check(keys)) {
5542
+ PyErr_SetString(PyExc_TypeError, "'keys' is not a list");
5543
+ return NULL;
5544
+ }
5545
+
5635
5546
  PyObject* border = PyObject_GetAttrString(self->tracer, "border");
5636
5547
  if (border == NULL) {
5637
5548
  return NULL;
@@ -5655,39 +5566,11 @@ static PyObject* CSimulator_press_keys(CSimulatorObject* self, PyObject* args, P
5655
5566
  PyObject* i = NULL;
5656
5567
  unsigned pc = REG(PC);
5657
5568
  unsigned long long t0 = TIME;
5658
- byte opcode = PEEK(pc);
5659
- OpcodeFunction* opcode_func = &opcodes[opcode];
5660
- if (!opcode_func->func) {
5661
- byte opcode2 = PEEK(ADDR(pc + 1));
5662
- switch (opcode) {
5663
- case 0xCB:
5664
- opcode_func = &after_CB[opcode2];
5665
- break;
5666
- case 0xED:
5667
- opcode_func = &after_ED[opcode2];
5668
- break;
5669
- case 0xDD:
5670
- if (opcode2 == 0xCB) {
5671
- opcode_func = &after_DDCB[PEEK(ADDR(pc + 3))];
5672
- } else {
5673
- opcode_func = &after_DD[opcode2];
5674
- }
5675
- break;
5676
- case 0xFD:
5677
- if (opcode2 == 0xCB) {
5678
- opcode_func = &after_FDCB[PEEK(ADDR(pc + 3))];
5679
- } else {
5680
- opcode_func = &after_FD[opcode2];
5681
- }
5682
- break;
5683
- default:
5684
- break;
5685
- }
5686
- }
5569
+ GET_OPCODE_FUNC(&opcodes);
5687
5570
 
5688
5571
  if (disassembling) {
5689
5572
  PyObject* arg = PyLong_FromLong(pc);
5690
- i = PyObject_CallOneArg(disassemble, arg);
5573
+ i = arg ? PyObject_CallOneArg(disassemble, arg) : NULL;
5691
5574
  Py_XDECREF(arg);
5692
5575
  if (i == NULL) {
5693
5576
  ok = 0;
@@ -5722,7 +5605,7 @@ static PyObject* CSimulator_press_keys(CSimulatorObject* self, PyObject* args, P
5722
5605
  }
5723
5606
  if (!PyObject_IsTrue(k)) {
5724
5607
  PyObject* arg = PyLong_FromLong(0);
5725
- PyObject* p = PyObject_CallOneArg(pop, arg);
5608
+ PyObject* p = arg ? PyObject_CallOneArg(pop, arg) : NULL;
5726
5609
  Py_XDECREF(arg);
5727
5610
  if (p == NULL) {
5728
5611
  ok = 0;
@@ -5773,6 +5656,11 @@ static PyObject* CSimulator_press(CSimulatorObject* self, PyObject* args, PyObje
5773
5656
  return NULL;
5774
5657
  }
5775
5658
 
5659
+ if (!PyList_Check(keys)) {
5660
+ PyErr_SetString(PyExc_TypeError, "'keys' is not a list");
5661
+ return NULL;
5662
+ }
5663
+
5776
5664
  PyObject* border = PyObject_GetAttrString(self->tracer, "border");
5777
5665
  if (border == NULL) {
5778
5666
  return NULL;
@@ -5790,39 +5678,11 @@ static PyObject* CSimulator_press(CSimulatorObject* self, PyObject* args, PyObje
5790
5678
  PyObject* i = NULL;
5791
5679
  unsigned pc = REG(PC);
5792
5680
  unsigned long long t0 = TIME;
5793
- byte opcode = PEEK(pc);
5794
- OpcodeFunction* opcode_func = &opcodes[opcode];
5795
- if (!opcode_func->func) {
5796
- byte opcode2 = PEEK(ADDR(pc + 1));
5797
- switch (opcode) {
5798
- case 0xCB:
5799
- opcode_func = &after_CB[opcode2];
5800
- break;
5801
- case 0xED:
5802
- opcode_func = &after_ED[opcode2];
5803
- break;
5804
- case 0xDD:
5805
- if (opcode2 == 0xCB) {
5806
- opcode_func = &after_DDCB[PEEK(ADDR(pc + 3))];
5807
- } else {
5808
- opcode_func = &after_DD[opcode2];
5809
- }
5810
- break;
5811
- case 0xFD:
5812
- if (opcode2 == 0xCB) {
5813
- opcode_func = &after_FDCB[PEEK(ADDR(pc + 3))];
5814
- } else {
5815
- opcode_func = &after_FD[opcode2];
5816
- }
5817
- break;
5818
- default:
5819
- break;
5820
- }
5821
- }
5681
+ GET_OPCODE_FUNC(&opcodes);
5822
5682
 
5823
5683
  if (disassembling) {
5824
5684
  PyObject* arg = PyLong_FromLong(pc);
5825
- i = PyObject_CallOneArg(disassemble, arg);
5685
+ i = arg ? PyObject_CallOneArg(disassemble, arg) : NULL;
5826
5686
  Py_XDECREF(arg);
5827
5687
  if (i == NULL) {
5828
5688
  ok = 0;
@@ -6004,6 +5864,9 @@ static int get_tsl_accelerators(PyObject* accelerators, tsl_accelerator* accs) {
6004
5864
  if (name == NULL || code_obj == NULL || c0_obj == NULL || c1_obj == NULL || counter_obj == NULL || inc_obj == NULL ||
6005
5865
  loop_time_obj == NULL || loop_r_inc_obj == NULL || ear_obj == NULL || ear_mask_obj == NULL || polarity_obj == NULL) {
6006
5866
  ok = 0;
5867
+ } else if (!PyList_Check(code_obj)) {
5868
+ PyErr_SetString(PyExc_TypeError, "accelerator code is not a list");
5869
+ ok = 0;
6007
5870
  } else {
6008
5871
  accelerator->c0 = PyLong_AsLong(c0_obj);
6009
5872
  accelerator->c1 = PyLong_AsLong(c1_obj);
@@ -6067,9 +5930,9 @@ static unsigned read_port(CSimulatorObject* self, unsigned port) {
6067
5930
  self->tracer_state[8] = ((TIME + self->frame_duration - self->int_active) / self->frame_duration) * self->frame_duration;
6068
5931
  self->tracer_state[9] = 0;
6069
5932
  PyObject* blocks_obj = PyObject_GetAttrString(self->tracer, "blocks");
6070
- PyObject* block_index_obj = PyObject_GetAttrString(self->tracer, "block_index");
6071
- PyObject* block = PyList_GetItem(blocks_obj, PyLong_AsLong(block_index_obj));
6072
- PyObject* data = PyObject_GetAttrString(block, "data");
5933
+ PyObject* block_index_obj = blocks_obj ? PyObject_GetAttrString(self->tracer, "block_index") : NULL;
5934
+ PyObject* block = block_index_obj ? PyList_GetItem(blocks_obj, PyLong_AsLong(block_index_obj)) : NULL;
5935
+ PyObject* data = block ? PyObject_GetAttrString(block, "data") : NULL;
6073
5936
  Py_ssize_t len = PyBytes_Check(data) ? PyBytes_Size(data) : 0;
6074
5937
  Py_XDECREF(data);
6075
5938
  Py_XDECREF(block_index_obj);
@@ -6142,7 +6005,7 @@ static unsigned read_port(CSimulatorObject* self, unsigned port) {
6142
6005
  }
6143
6006
  } else if ((port & 0xC002) == 0xC000) {
6144
6007
  PyObject* outfffd_obj = PyObject_GetAttrString(self->tracer, "outfffd");
6145
- unsigned ay_reg = PyLong_AsLong(outfffd_obj);
6008
+ unsigned ay_reg = outfffd_obj ? PyLong_AsLong(outfffd_obj) : 0xFF;
6146
6009
  Py_XDECREF(outfffd_obj);
6147
6010
  if (ay_reg == 14 && REG(PC) == 0x08B2) {
6148
6011
  /* Avoid an infinite loop at 0x08AF in the 128K ROM:
@@ -6154,9 +6017,9 @@ static unsigned read_port(CSimulatorObject* self, unsigned port) {
6154
6017
  }
6155
6018
  if (ay_reg < 16) {
6156
6019
  PyObject* ay = PyObject_GetAttrString(self->tracer, "ay");
6157
- PyObject* value = PyList_GetItem(ay, ay_reg);
6020
+ PyObject* value = ay ? PyList_GetItem(ay, ay_reg) : NULL;
6158
6021
  Py_XDECREF(ay);
6159
- return PyLong_AsLong(value);
6022
+ return value ? PyLong_AsLong(value) : 0xFF;
6160
6023
  }
6161
6024
  }
6162
6025
 
@@ -6340,39 +6203,11 @@ static PyObject* CSimulator_load(CSimulatorObject* self, PyObject* args, PyObjec
6340
6203
  while (1) {
6341
6204
  PyObject* i = NULL;
6342
6205
  unsigned long long t0 = TIME;
6343
- byte opcode = PEEK(pc);
6344
- OpcodeFunction* opcode_func = self->opcodes[opcode];
6345
- if (!opcode_func->func) {
6346
- byte opcode2 = PEEK(ADDR(pc + 1));
6347
- switch (opcode) {
6348
- case 0xCB:
6349
- opcode_func = &after_CB[opcode2];
6350
- break;
6351
- case 0xED:
6352
- opcode_func = &after_ED[opcode2];
6353
- break;
6354
- case 0xDD:
6355
- if (opcode2 == 0xCB) {
6356
- opcode_func = &after_DDCB[PEEK(ADDR(pc + 3))];
6357
- } else {
6358
- opcode_func = &after_DD[opcode2];
6359
- }
6360
- break;
6361
- case 0xFD:
6362
- if (opcode2 == 0xCB) {
6363
- opcode_func = &after_FDCB[PEEK(ADDR(pc + 3))];
6364
- } else {
6365
- opcode_func = &after_FD[opcode2];
6366
- }
6367
- break;
6368
- default:
6369
- break;
6370
- }
6371
- }
6206
+ GET_OPCODE_FUNC(self->opcodes);
6372
6207
 
6373
6208
  if (disassembling) {
6374
6209
  PyObject* arg = PyLong_FromLong(pc);
6375
- i = PyObject_CallOneArg(disassemble, arg);
6210
+ i = arg ? PyObject_CallOneArg(disassemble, arg) : NULL;
6376
6211
  Py_XDECREF(arg);
6377
6212
  if (i == NULL) {
6378
6213
  break;
@@ -6503,29 +6338,36 @@ cleanup:
6503
6338
  PyObject* item;
6504
6339
  while ((item = PyIter_Next(iter)) != NULL) {
6505
6340
  PyObject* name = PyObject_GetAttrString(item, "name");
6506
- for (int i = 0; i < num_accs; i++) {
6507
- tsl_accelerator* acc = &accs[i];
6508
- if (acc->name == name) {
6509
- if (acc->hits) {
6510
- PyObject* hits = PyLong_FromLong(acc->hits);
6511
- if (PyObject_SetAttrString(item, "hits", hits) == -1) {
6512
- ok = 0;
6341
+ if (name) {
6342
+ for (int i = 0; i < num_accs; i++) {
6343
+ tsl_accelerator* acc = &accs[i];
6344
+ if (acc->name == name) {
6345
+ if (acc->hits) {
6346
+ PyObject* hits = PyLong_FromLong(acc->hits);
6347
+ if (PyObject_SetAttrString(item, "hits", hits) == -1) {
6348
+ ok = 0;
6349
+ }
6350
+ Py_XDECREF(hits);
6513
6351
  }
6514
- Py_XDECREF(hits);
6352
+ break;
6515
6353
  }
6516
- break;
6517
6354
  }
6355
+ } else {
6356
+ ok = 0;
6518
6357
  }
6519
6358
  Py_XDECREF(name);
6520
6359
  Py_DECREF(item);
6360
+ if (!ok) break;
6521
6361
  }
6522
6362
  Py_DECREF(iter);
6523
6363
  }
6524
- PyObject* tsl_misses = PyLong_FromLong(self->tsl_misses);
6525
- PyObject* dec_a_jr_hits = PyLong_FromLong(dec_a_accelerator.args[0]);
6526
- PyObject* dec_a_jp_hits = PyLong_FromLong(dec_a_accelerator.args[1]);
6527
- PyObject* dec_a_misses = PyLong_FromLong(dec_a_accelerator.args[2]);
6528
- if (PyObject_SetAttrString(self->tracer, "tsl_misses", tsl_misses) == -1 ||
6364
+ PyObject* tsl_misses = ok ? PyLong_FromLong(self->tsl_misses) : NULL;
6365
+ PyObject* dec_a_jr_hits = tsl_misses ? PyLong_FromLong(dec_a_accelerator.args[0]) : NULL;
6366
+ PyObject* dec_a_jp_hits = dec_a_jr_hits ? PyLong_FromLong(dec_a_accelerator.args[1]) : NULL;
6367
+ PyObject* dec_a_misses = dec_a_jp_hits ? PyLong_FromLong(dec_a_accelerator.args[2]) : NULL;
6368
+ ok = dec_a_misses != NULL;
6369
+ if (!ok ||
6370
+ PyObject_SetAttrString(self->tracer, "tsl_misses", tsl_misses) == -1 ||
6529
6371
  PyObject_SetAttrString(self->tracer, "dec_a_jr_hits", dec_a_jr_hits) == -1 ||
6530
6372
  PyObject_SetAttrString(self->tracer, "dec_a_jp_hits", dec_a_jp_hits) == -1 ||
6531
6373
  PyObject_SetAttrString(self->tracer, "dec_a_misses", dec_a_misses) == -1) {
@@ -18,7 +18,7 @@ modes are described in the following subsections.
18
18
 
19
19
  @isub mode
20
20
  ^^^^^^^^^^
21
- In ``@isub`` mode, ``@isub`` directives are executed, but ``@ssub``, and
21
+ In ``@isub`` mode, ``@isub`` directives are executed, but ``@ssub`` and
22
22
  ``@rsub`` directives are not. The main purpose of ``@isub`` mode is to make the
23
23
  minimum number of instruction substitutions necessary to produce an ASM file
24
24
  that assembles.