openmsx-debugger-0.0.0.svn20141006.orig/0000755000175000017500000000000012414640304016676 5ustar shevekshevekopenmsx-debugger-0.0.0.svn20141006.orig/build/0000755000175000017500000000000012414640014017773 5ustar shevekshevekopenmsx-debugger-0.0.0.svn20141006.orig/build/win_resource.py0000644000175000017500000000146012414415132023053 0ustar shevekshevek# Generates Windows resource header. from outpututils import rewriteIfChanged from version import extractRevisionNumber, packageVersion import sys def iterResourceHeader(): if '-' in packageVersion: versionNumber = packageVersion[ : packageVersion.index('-')] else: versionNumber = packageVersion revision = str(extractRevisionNumber()) versionComponents = versionNumber.split('.') + [ revision ] assert len(versionComponents) == 4, versionComponents yield '#define OPENMSXDEBUGGER_VERSION_INT %s' % ', '.join(versionComponents) yield '#define OPENMSXDEBUGGER_VERSION_STR "%s\\0"' % packageVersion if __name__ == '__main__': if len(sys.argv) == 2: rewriteIfChanged(sys.argv[1], iterResourceHeader()) else: print >> sys.stderr, \ 'Usage: python win-resource.py RESOURCE_HEADER' sys.exit(2) openmsx-debugger-0.0.0.svn20141006.orig/build/version.py0000644000175000017500000000446212414415132022041 0ustar shevekshevek# Contains the openMSX version number and versioning related functions. from executils import captureStdout from makeutils import filterLines from os import makedirs from os.path import isdir import re # Name used for packaging. packageName = 'openmsx-debugger' # Version number. packageVersionNumber = '0.10.0' # Note: suffix should be empty or with dash, like "-rc1" or "-test1" packageVersionSuffix = '' packageVersion = packageVersionNumber + packageVersionSuffix # Is this a release version ("True") or development version ("False"). releaseFlag = False def _extractRevisionFromStdout(log, command, regex): text = captureStdout(log, command) if text is None: # Error logging already done by captureStdout(). return None # pylint 0.18.0 somehow thinks captureStdout() returns a list, not a string. lines = text.split('\n') # pylint: disable-msg=E1103 for revision, in filterLines(lines, regex): print >> log, 'Revision number found by "%s": %s' % (command, revision) return revision else: print >> log, 'Revision number not found in "%s" output:' % command print >> log, text return None def extractGitRevision(log): return _extractRevisionFromStdout( log, 'git describe', r'\S+?-(\S+)$' ) def extractNumberFromGitRevision(revisionStr): if revisionStr is None: return None return re.match(r'(\d+)+', revisionStr).group(0) _cachedRevision = False # because None is a valid result def extractRevision(): global _cachedRevision if _cachedRevision is not False: return _cachedRevision if releaseFlag: # Not necessary, we do not append revision for a release build. return None if not isdir('derived'): makedirs('derived') log = open('derived/version.log', 'w') print >> log, 'Extracting revision info...' try: revision = extractGitRevision(log) print >> log, 'Revision string: %s' % revision print >> log, 'Revision number: %s' % extractNumberFromGitRevision(revision) finally: log.close() _cachedRevision = revision return revision def extractRevisionNumber(): return int(extractNumberFromGitRevision(extractRevision()) or 1) def extractRevisionString(): return extractRevision() or 'unknown' def getVersionedPackageName(): if releaseFlag: return '%s-%s' % (packageName, packageVersion) else: return '%s-%s-%s' % ( packageName, packageVersion, extractRevisionString() ) openmsx-debugger-0.0.0.svn20141006.orig/build/version2code.py0000644000175000017500000000125212414415132022750 0ustar shevekshevek# Generates version include file. from outpututils import rewriteIfChanged from version import extractRevisionString, packageVersion, releaseFlag import sys def iterVersionInclude(): revision = extractRevisionString() yield '// Automatically generated by build process.' yield 'const bool Version::RELEASE = %s;' % str(releaseFlag).lower() yield 'const char* const Version::VERSION = "%s";' % packageVersion yield 'const char* const Version::REVISION = "%s";' % revision if __name__ == '__main__': if len(sys.argv) == 2: rewriteIfChanged(sys.argv[1], iterVersionInclude()) else: print >> sys.stderr, \ 'Usage: python version2code.py VERSION_HEADER' sys.exit(2) openmsx-debugger-0.0.0.svn20141006.orig/build/package-darwin/0000755000175000017500000000000012414415132022651 5ustar shevekshevekopenmsx-debugger-0.0.0.svn20141006.orig/build/package-darwin/Info.plist0000644000175000017500000000156612414415132024631 0ustar shevekshevek CFBundleExecutable openmsx-debugger CFBundleGetInfoHTML openMSX Debugger %VERSION% CFBundleIconFile %ICON% CFBundleIdentifier org.openmsx.openmsx-debugger CFBundleName openMSX Debugger CFBundlePackageType APPL CFBundleShortVersionString %VERSION% CFBundleSignature oMXD CFBundleVersion %VERSION% NSPrefPaneIconFile %ICON% NSPrefPaneIconLabel openMSX Debugger openmsx-debugger-0.0.0.svn20141006.orig/build/package-darwin/debugger-logo.icns0000644000175000017500000012766412414415132026271 0ustar shevekshevekicnsics#H??????????is32}Z:YX ͌m  y<ݢ- vg, bo)}¢ URͭ~. _AG Q#ܨLbE @ @րw>qs)(ʨ޹in|gĝ }\bZ){gF@?UU  );,_APis4 ,-QNE:JZ=Z^pn\6M=XV7-QKh,A@$ ր:T+t},, *ʨ#~*s8mk?Л a=ceXt(}eZRf,p_3{0q"%ĢICN#??????il32\o^WUb? pL>'#,qD" n]g`291/\~ql6y+SUj3oW\eهYbWlր_LU i4#hbH 0|ڞ3؁ ݍҙ٤A?O Д l1o kpG^Y*% ƮI au?V, ޖ &8 M| "Hp|hQ4080_|Ä0τ{1g2)C 1-,vقs% KC Үqz 8alprpqpgF JxG o^WUd? pLA,(1qE' nak`5>"35a~qn;y2#SUo7oX`eڇYfW lր_NU i4#gbH 0wٞ3ف ݍƓ˛>?O Ћٮكl1r glCXY*( ơځ]q ?V, y#)< Nw %Jp{gQ64;2_}Ä3τ{ 2h2)C 1-,wقs ɼKCԹ~ ׯҪׁm y׀ 1[glmjlkcC HqD o^WUb?QowrepLqqNwzwutl_p`[nljjgZߖQaw]C~|l˄qUykSRUfhuAobeՆXӍ?e3`dYŒ5W?]blր^u3U?]_i4#ZBIK$bH?[^0IDզ NKC63?XWݍ#,LD;4+?OUTRƂaE<4,$l1UQN76< =6,&Y*NLko "36-& ?V,MJJ̀e(bO' SUECQv@R]6E7  In^[nsX\Q- 3i`VNF?b:\\U EVNE=EtdSE6#i &ME<5HhXH:,Ą DR;4,=\L>/"  K<+$QB4& τ E,97){ -B- 7)I i8/wقk,KC Dq Usl8mk5Jbx?:0vc;v:YL 5FRHt3l(2Ac.IJiuT`l<+hzg\V4a l/|D|v0 u p)$~Ŭt8&\Gich#H????ih32RѨ |\: 0Mt|RX-02+1ݴV3J csugWdفe_C<فzpQEf ׋SH&Bjgˠ:AZɵy>ׂfij9mN,qpo/k Y b7)v 3dzw8}?|s©]S3OtYXp;p +h꽃 @ 3k"ń; S|XoxTmgFlkM.Xu|>aQޙ}DVU:D pvz8O%at .TTqeVo  i`(|֘^‹e- 'VF ka ։qaj@-JЊ9"JQ(~ވ2\66J WڅХE<ր⽲1b 땂ڻ/#߭ǁl5ߢ%|ز݂NyֆÓIWvd@7m݅ &/2230) -D[mu~Ѩ|\;" 0Mt|RX26716޴V4M bszk[hځi_G<ف |pQHf׋SH,Bjgˡ8EZɵy>׀hij9pN,qro/m Y ~_:)y 3arv8?{s^S3StYWoײ8p /gٸ|@֋ك 2k" Ƅ8 PrRgxTpfDfkM2Sޙv?aQ ӑ$ VU:G pu=,s;P&~`t¼  2TTpeVo j`(|֘  ^‹g. )VGkb ։rb jA.JЊ<#J R(ވ/Y66J WڅХD9~̀ص1b ѳ}'#֦Ɓl5ߞ׃!wدӂ׃Jt̆һHXvd@2hՅ %.11/-( (CXhpzѨWkoV$|\B@DA8/4Mtow||{zrlU|RXV4t}wvtssrna csۻ RP_]ki<فXKzpbihNjQGf3efoSC*HScd Bjg˽?=:]daZɵ93 y>[a_i4/j9[_\N,q/,o/[]Z Y ~<^+WR* )[\X 3F i +,VPJC"8WZW?kr\¿l6QKF@:4S3VXTtYG&T 3 DLFA;60+ p VVSvUt 5FA;61,&!@VTR_ B<61,'"k"QRPTل  '=72,'" xTNRNLwbf ;73-(#  kMUNMJqCHA;83-)$ aQOKHOʂLQ.)$ YU:GJGF~ jya& C  +1DƁyO3N(1mmtDo O/4:}?xDG@Ae @9@x+ 4| :H gAx[3"27S$c9M7"-ғpQ% a4[UC- 36o0f˾yM+^vpO%Afit32C½˗mL6&$0ATnT '067651,)$" !&=_"R2JXT:! %9a< , 5^mcX $]qf8,S2'K}zo%2:@A@;6-(6Zx *UsD Pif`ZUPKFB=A_ 8 2dD =wqlga[VQLHT6Jun R}wrmga\WS_s.kv , ш~wsmibF3d6]z/Sʿ𶏊zm9 M7 Wu3 l ޛ{7= Vr1 z ˤE,Xo)y箩o ^j5Ɇ2 iަ6 Zט  g\ LAR=*nL  eܛ:4j: 3:X\֊rCSq noE,y =_ 'p b@m[e4^,mADn[F hDTċPL"pu 4ĤdD2" [;X_RHP ruk "mCצotz6'[=9fmot{tC#}֤ے&qZ+BUyot\QѤj8kd00mEmot{tC#}iϤJF f1qg\Qפ5M~6tLi&Q;y7R @~)O ʷE Kˑg CJTF)UO(%?Đ)Zޭ%^Ty08gZ*:?3`e ï_9ЂVR-"%`8 e =Te~O^"i+'& GMEnmo뇴))*Cj-suHa0+#+ 2.'z )<&$U }NFlakoi!\'^2eqN =o. e8G\\B љ=ea>חڂ ϏZ^'Vܗu7DAv82Ŗ G,gR $ =ϯub:z: H>|L \qU" ov²m Wͪ[zEd!3~X 9`-QjK ז ˑkeGl}~V( ' u|oL gfsK \xg=AN #rrb07w N&FOrog*} 7 m\Z'ikk(@ S\ {legn-*^6Iwraeq9\^I H&ރkZ_tS ,ܿS kulZWnpRr!羸߇ gmbŻlICbJ -.,ؤJsr[NLLN]rs¨֏l&Qt9 ^ǵ TҨܘ6i}Ñѓl. 7V;)V{R6&%+6Ho ϸ0 z|ma`nF%7WT?Z͡b,0zʛ@wѦ:*E .KvX1fހlLkՂ26UR?Ө ! 2QyoWF;5238BN_tƄ@>bwoeqy=  #5OkʽkE&:L^šo *PsO ">gر'f6Vzgo8 !)5@G?RTӧ0_3{v _ F$͞S L-V[soX kf#f $ 5pf ,Z 0K  )Qu Q}u.L^v Fؖ5:<MͿ4`ާse 2RsϠ)r &Ddٸ^U3 6Vw'h )Hiĝh/p :Z|仜V ,Lmٚ$'?s s >^ə;3įw\ptnmt1Pq宁F%!)148;92 2„Wj %CbѨQG,O{¨r9 TgՍ 06TmN0u,?ё8kV͋$_ŏ@dݒx( וd]  *V'0טAi ~ׅ"2R>Ɏ_م^ ⹁9.rzȟKˑ wpޞDk,z֎Uiߨr ‹N 8 ɤ oo ͮb; +Y67m֝L  $4Nenqpm^E,  =de(AXoĹydL5 -Da(4H]py !(½˖mL6&$0ATnT'057651,(%! "&=_$R2JXU=%"%9aK, 5^meX *asf8,T7'K}yo+7@FFEA;2.;_x *UuD Plje_ZTPKFBFd 9 2dG =zupkf`[VPMY 6JuoR|vqkfa\Wes.kv&, ҋ|uqmgJ8i6]z4Sʿ򹓍}p=R6 Wu7 l ޝ~=  B Vr6 z ΦI 1Xn-y簬r  ]j:ˉ7i=^ؘ  g] QFR=/mMhܛ:4j=  9:Y\֊uCRu ooH2y =_&pf@m[g"4^,mFDn\JkDTċPK'pu9ŤbD6"`:XbRHP ru k "mBצotz:'[=9fmot{tC#}׀ے'q ^,BVyot\Qрi8k g00mEmot{tC#}iЁJEi1qg\Qׁ5M6tLi&Q ;y8Q%@~*P &ʷE K $̑g CJVF")UN+$?!Ɛ)Zޭ%^Ty08"gZ(6?3$`e ð_7XR. &%`8 e8Re~KY$i+++ GM@މnmh|*) .Ci*luHڶa2+#/ 2.$ڀ{ (<&(U }HڀBj_ioh"\'^2ehڃI vbwoeqy? $5OkʽlE&:L^ġo +PsO ">gر)h6Vzgq8 !)5AG?RTӧ0_5{w _F%͞UL.X[upXkf#f #' 7"pf .Z 4K  ,Qu Q} u.L^w Fؖ6=< MͿ 4`ާsg  2RsϠ)r  &Dbٸ_U3 6Uw'h )Hiĝh1p ;Z|㻜W ,Lmٚ$'?s s ?^ʙ;3˼rYnsnmt1Pr宁F%!&.2577/ /׀؄Ti %CbѨQG+Luĺm5 ؙPfՍ 06TmN0u,=|׍Ȋ4gT̋%_ŏ@_ӓr$Ε^]  *Tؒ&-Θ?i {Ѕ֏ؚ!/֚N>Ɏ_҅֐ؔםZ ⹁9.nuGʑ wp՞@iןןס+z͎ـ׎Qdרr ‹N 6׊لւׅ  mo ͮb;   (Uؐօ44h͝I  $4Nenqpm^E,  ;^ז_&?Tj}Žs_I3 +A]{؎&2DYl~s '½˗mL6&$0@Tn =Wnglv||vlgmW=T'067651,)$! !&=`\jz~}|{{vgX$R2JXUV\ZXXVSPMIEA%9bifq~}||{zyywk^, 5^mc^\hvuttsrrqpup:,S~~}||{zwvuiS3'K}zoSfx *U{zzywwvuuttsrsr^9D P 9 2dwvuutsrrqpopofJ =ഹ6JvwsrrqqpponmfUSѾ t-kuqponomlkgS,ÿ 6]zsmmllkjicNSʿ¾zw 7 Wupkjiihgffgffg`P l Ļsmr  VqlhggffedeZ z ɞtnloWnheddbaa`a`abbTyն|nm ^jd` i็k^^_^Li іoommku gd^b׎_\]]^WR= }onmmkmn]\leZZ[\O ionmlkiu:5jd_XYYU* ^onmmkim:Y\֊YWNCR V_nmlkkiu noTUUQ [hllkjiky =__RSSJ'p H\mlkjihq?m[PPQN U_mkjiih~4^\NON5,m [fkkiigjDn\LMNI ']kjihhgqDTċMKKIPL U\kihhgfpuVHIG V^iihgfhޤdDrFFHC" ]eihgfdm;XEEFDRH *]ihgeeasP ruCCD@ k MZhgffdbzʦ "mCצotBABCz U\gfedaf'[=9fmot{tC#}>?@Cے&q Y`gfdb`i,BVyot\Q<==?i8m [bfeba_i00mEmot{tC#}i9:;=JF ]fedba_k2qg \Q789:5M HZebba`^o6tLi6678&Q SZdaa``\s;y84566RU UZba`__Zz@~*2346P V[ba`^^XyʷE 0026K Z[a__^]Xug CJz-/06 F U^`^^]\Xt)UO S,,-9_T#$? W]_^]\[Wsܐ)Zޭ%^Ty <*+,>][YS609 W]^]\\ZVsݏgZ '()+E[YWURP6 ?3 W^^\[[ZUs`e ±_nu&&')LYWUSQNLJ2 R- W]\\[ZYTu%`8 k,e~ F$%&'TWUSQNLJHFD- i+' W\]\ZYXTw GOOnm$"#$,XVSQOMKHFEBA?/ )) W\[[ZYXRzC itH`O !"8UTROMKHFECA?<;8%+# W[[ZYXWRz 2){ $ !FTROMKHFECA><:9652<& S[ZYXWVQtU}: "NB]hR'"RROMKIGFCA?=:86531.)\' SZYXWVUQl^2f=#."' 1RPNKIGECA?=:97631.,+). SXYXWVTRa e8G^B%FPNLJHFDA?=;96631/-,*'&= SXXWVUTR\e# PNLJGFDB@=;97541/-,)'&$"^' UXXVUTSQYuu >LJHFDB@>;976410-,*'&$" 8 UUVVUTSRRzږ,JHFDB@=;976420-,*(&$" S UVVUTSRRQqNHFEC@><976420.,*(&%" z: UVVTSRQQOdF>FECA><:76420.,*)&%#  qU" QVUTSRQPMZU!ECA><:86420.,+(&%#!zE PUTSRQPOLV)3CA?=:86521.,+)'%#!  `- URSSRPPOLSiזA?=;97521.,+)'%#!  }~V NSRQPONLMob5?=;87531.-+)'&#!  |oL OTRPONMLKZ^.K ?=;97631/-,)'&$"  \xg= RSQPONMLJP#>=;97531/,,)'&$"  rrd0 STPPNMLKIOwƏu$ ?>;97642/-+)'&$"  rog* JROONMLKJJb) 9@>;:86410.,*'&$"  ikj) NONMLKJIGN~͎,LI><:76420.,*(&%"  ehn- LRMLLJIIFLl]9":86420.,+(&%"  adr9RRNLKJIHFHX&>ڃ"420.,+(&%"! Z_sS PRMLJIHHFFJm%.,+)&%"! WWmq JMKJHHGFEGZz|߇)'&#!  IDbJ OQKJHGFFEDGm4*J Nӏ$!  ]Qt9PHIHGFFECHXp&iܗ56 l˓M  npPW;)4GF*D6"  `7]ϸ/ `< "wd) (m}}dFXT/*HF7(0V|}t{Yuʞ0wѦ:* o/.&%(g}|zt\ALvX1 6վC *6FkՂ26UR?Ө;-,(7}zwusq]D6QzoWF;5248BN_tƄ@=bwoeqyg,+))}ytsqnljdP=-5OkʽkE&:L^šo2*))) utrpmkjgeb`^SF:/' /PsO ">gرQ)(()emonkigeb`^[YWUSPOMJHFEC66Vzg*'&&*(mmkigeb_^[YWUSPNLJHFEB@?=K8 !)5AG?QSӧ7&&%.bligda_][YVUSPNLJHFDB@><7#42995.20,!0_W%$$/2mhdb_]ZYVTRPNLJGFDB@>;-!Akzuqmie`\XTQMIF@){&#"2_[__][XVTRPNLIGFDA@>;6w~zvrnjfb]ZVRNJFD?;73  _1! 2&\Z\ZXVTRPMKIGFCA?=;9 ?~|wsokgd^[WSOLHEA=962.+$FF 2-ZZXVTQPMKIGFDA?=;96}|ytplie`\XTPLHEA=:63/,(&"͞o 2WYVSROMJIFECA?<;870 ~zuqmjea]YUQMJFC?;740,)&#  !2$ZVQOMJHFECA?<;965*|vsnkgb^ZVRNKGD?<852-+'$ +2CZQLJHFECA?<:8653$wsolhd_[WSPLHEA=962/,(%!P73#XVJHFECA><9864202tqmie`\XTPMIEB>:640,)&" I 4A(ZNFEB@><:76420.6rmjfa]ZURNJFC?;740-*&$  m 3?> ARDB@>;976420-,1okgb^ZVSNKGDA=862.+'$  [ 3=F+B?>;97642/-,*#lhd`[XTPLHEA=963.,)&" Y 3=Nk:=;97641/-,*(% gea\YUQMIFC>;740,)&" f 3;U#;97641/-+)'&$ Jb^ZVRNJFC@<751-+'$  f#39[&6531/-,*'&$"&_[WTOKGEA=962.+'%! & 27] ,21.,+)'&#" RXTPLHEB>:630,)&" ' 8k,,.,+)'&$!  (URNJFC?;740,*&#  1 8V*p(+)'%$! ROKFD@<962-+'$  f7a*Z%&%# 1LHEA=962.+(%" 6e(K"!HFB?;740,)&"   6\&QFC?;851-*'#  u 1K Q>A<962.+'$! } /<"u >:63/,(&" .Li +5!  9740,)&" FؖA .f <   51-+'$  MͿ)?$ 2.+'%!4`ާ{ '.  ,)&" 3QsϠ2)Fs(&# &Deٸ #+~W5$  6Uw0%8h )Hiĝm&Tp  ;Z}仜't  -Lmٚ) >}s s!?^ə?&[}nmt1Pq 宁F  S %CdѨQ FYҍ 06TmN0u =ʋ$_ŏ/ P  *% i 0>ɎX⹁9,&wp} :zv r ‹N 7w ͯd=  +:TjrtsoaH/# t8mk@#VȪV#XX!{{!HHyy kkhab9@. F:&4r?U@@@v.>@ tſ3#vNUkI&v k@Hީ 9@n;;hl,Nn @"+k6<@3QCzHl {(Ǔ3h>5X 9D{@4r x\.#xK<Vy~?-sy~<@=nrx}vZHhlrw>Naglo .P[`fK9+NV[`">23JPUVA(6DJO<?x 3B @5(8:@U2)@[@,@XV &@,# @y@* @GX@L@r@?\H?,?k< 55h&@?9D@E v>e&@7xU@v@T@?;v#U@R&&@5HtoG5$ xx R^9V kJfu @@@@@ j@ĐZ3 Z"ELN D8L;h"{N8=~ڏD闢@.bQ𿙃Q@ @VtL0CTdqz~~zqdTC0 .8DXqGopenmsx-debugger-0.0.0.svn20141006.orig/build/node.mk0000644000175000017500000000026412414415132021254 0ustar shevekshevek# $Id$ include build/node-start.mk DIST:= \ main.mk version.mk \ node-end.mk node-start.mk \ detectsys.py \ install-recursive.sh \ package-darwin include build/node-end.mk openmsx-debugger-0.0.0.svn20141006.orig/build/install-recursive.sh0000755000175000017500000000116712414415132024013 0ustar shevekshevek#!/bin/sh # $Id$ if [ $# -lt 2 ] then echo "Usage: $0 (|)+ " >&2 exit 1 fi if [ $# -eq 2 ] then src="$1" shift if [ -d "$src" ] then src="$src"/* fi else src="" while [ $# -ne 1 ] do src="$src $1" shift done fi dst="$1" for path in $src do name=$(basename "$path") dir=$(dirname "$path") if [ -L "$path" ] then echo "skipping symbolic link: $path" elif [ -d "$path" ] then if [ "$name" != .svn ] then $0 "$path" "$dst" fi else install -m 0755 -d "$dst/$dir" mode=0644 if [ -x "$path" ] then mode=0755 fi install -m $mode "$path" "$dst/$dir" fi done openmsx-debugger-0.0.0.svn20141006.orig/build/main.mk0000644000175000017500000003070512414640014021255 0ustar shevekshevek# $Id$ # # openMSX Build System # ==================== # # This is the home made build system for openMSX, adapted for the openMSX # debugger. # # Used a lot of ideas from Peter Miller's excellent paper # "Recursive Make Considered Harmful". # http://www.tip.net.au/~millerp/rmch/recu-make-cons-harm.html # # TODO: Rename OPENMSX_SUBSET to SUBSET? # Python Interpreter # ================== # We need Python from the 2.x series, version 2.5 or higher. # Usually this executable is available as just "python", but on some systems # you might have to be more specific, for example "python2" or "python2.6". # Or if the Python interpreter is not in the search path, you can specify its # full path. PYTHON?=python # Logical Targets # =============== # Logical targets which require dependency files. #DEPEND_TARGETS:=all app default install run bindist DEPEND_TARGETS:=all app default # Logical targets which do not require dependency files. #NODEPEND_TARGETS:=clean config probe dist NODEPEND_TARGETS:=clean dist # Mark all logical targets as such. .PHONY: $(DEPEND_TARGETS) $(NODEPEND_TARGETS) # Default target; make sure this is always the first target in this Makefile. MAKECMDGOALS?=default default: all # Base Directories # ================ # All created files will be inside this directory. BUILD_BASE:=derived # All global Makefiles are inside this directory. MAKE_PATH:=build # Platforms # ========= ifeq ($(origin OPENMSX_TARGET_OS),environment) # Do not perform autodetection if platform was specified by the user. else # OPENMSX_TARGET_OS not from environment DETECTSYS_PATH:=$(BUILD_BASE)/detectsys DETECTSYS_MAKE:=$(DETECTSYS_PATH)/detectsys.mk DETECTSYS_SCRIPT:=$(MAKE_PATH)/detectsys.py -include $(DETECTSYS_MAKE) $(DETECTSYS_MAKE): $(DETECTSYS_SCRIPT) @echo "Autodetecting native system:" @mkdir -p $(@D) @$(PYTHON) $< > $@ endif # OPENMSX_TARGET_OS PLATFORM:= ifneq ($(origin OPENMSX_TARGET_OS),undefined) PLATFORM:=$(OPENMSX_TARGET_OS) endif # Ignore rest of Makefile if autodetection was not performed yet. # Note that the include above will force a reload of the Makefile. ifneq ($(PLATFORM),) # Load OS specific settings. #$(call DEFCHECK,OPENMSX_TARGET_OS) #include $(MAKE_PATH)/platform-$(OPENMSX_TARGET_OS).mk # Check that all expected variables were defined by OS specific Makefile: # - executable file name extension #$(call DEFCHECK,EXEEXT) # - platform supports symlinks? #$(call BOOLCHECK,USE_SYMLINK) # Paths # ===== #BUILD_PATH:=$(BUILD_BASE)/$(PLATFORM)-$(OPENMSX_FLAVOUR) BUILD_PATH:=$(BUILD_BASE) GEN_SRC_PATH:=$(BUILD_PATH)/src SOURCES_PATH:=src RESOURCES_PATH:=resources ifeq ($(OPENMSX_TARGET_OS),darwin) # Note: Make cannot deal with spaces inside paths: it will even see BINARY_FULL # as two files instead of one. Therefore, we use an underscore during # development and we'll have to rename the app folder for the release # versions. APP_SUPPORT_PATH:=build/package-darwin APP_PATH:=$(BUILD_PATH)/openMSX_Debugger.app APP_PLIST:=$(APP_PATH)/Contents/Info.plist APP_ICON:=$(APP_PATH)/Contents/Resources/debugger-logo.icns APP_RESOURCES:=$(APP_ICON) BINARY_PATH:=$(APP_PATH)/Contents/MacOS PKGINFO_FULL:=$(APP_PATH)/Contents/PkgInfo else BINARY_PATH:=$(BUILD_PATH)/bin endif #BINARY_FILE:=openmsx-debugger$(EXEEXT) BINARY_FILE:=openmsx-debugger BINARY_FULL:=$(BINARY_PATH)/$(BINARY_FILE) VERSION_SCRIPT:=build/version2code.py VERSION_HEADER:=$(BUILD_PATH)/config/Version.ii GENERATED_HEADERS:=$(VERSION_HEADER) # Filesets # ======== # If there will be more resource files, introduce a new category in node.mk. RESOURCES_FULL:=$(RESOURCES_PATH)/resources.qrc # Force evaluation upon assignment. SOURCES_FULL:= HEADERS_FULL:= MOC_HDR_FULL:= UI_FULL:= DIST_FULL:= # Include root node. CURDIR:= include node.mk # Remove "./" in front of file names. # It can cause trouble because Make removes it automatically in rules. SOURCES_FULL:=$(SOURCES_FULL:./%=%) HEADERS_FULL:=$(HEADERS_FULL:./%=%) MOC_HDR_FULL:=$(MOC_HDR_FULL:./%=%) UI_FULL:=$(UI_FULL:./%=%) DIST_FULL:=$(DIST_FULL:./%=%) # Apply subset to sources list. SOURCES_FULL:=$(filter $(SOURCES_PATH)/$(OPENMSX_SUBSET)%,$(SOURCES_FULL)) ifeq ($(SOURCES_FULL),) $(error Sources list empty $(if \ $(OPENMSX_SUBSET),after applying subset "$(OPENMSX_SUBSET)*")) endif # Sanity check: only .cpp files are allowed in sources list, # because we don't have any way to build other sources. NON_CPP_SOURCES:=$(filter-out %.cpp,$(SOURCES_FULL)) ifneq ($(NON_CPP_SOURCES),) $(error The following sources files do not have a .cpp extension: \ $(NON_CPP_SOURCES)) endif MOC_SRC_FULL:=$(patsubst \ $(SOURCES_PATH)/%.h,$(GEN_SRC_PATH)/moc_%.cpp,$(MOC_HDR_FULL) \ ) RES_SRC_FULL:=$(patsubst \ $(RESOURCES_PATH)/%.qrc,$(GEN_SRC_PATH)/qrc_%.cpp,$(RESOURCES_FULL) \ ) UI_HDR_FULL:=$(patsubst \ $(SOURCES_PATH)/%.ui,$(GEN_SRC_PATH)/ui_%.h,$(UI_FULL) \ ) GEN_SRC_FULL:=$(MOC_SRC_FULL) $(RES_SRC_FULL) SOURCES:=$(SOURCES_FULL:$(SOURCES_PATH)/%.cpp=%) GEN_SRC:=$(GEN_SRC_FULL:$(GEN_SRC_PATH)/%.cpp=%) HEADERS:=$(HEADERS_FULL:$(SOURCES_PATH)/%=%) DEPEND_PATH:=$(BUILD_PATH)/dep DEPEND_FULL:=$(addsuffix .d,$(addprefix $(DEPEND_PATH)/,$(SOURCES))) DEPEND_FULL+=$(addsuffix .d,$(addprefix $(DEPEND_PATH)/,$(GEN_SRC))) OBJECTS_PATH:=$(BUILD_PATH)/obj OBJECTS_FULL:=$(addsuffix .o,$(addprefix $(OBJECTS_PATH)/,$(SOURCES))) GEN_OBJ_FULL:=$(addsuffix .o,$(addprefix $(OBJECTS_PATH)/,$(GEN_SRC))) ifeq ($(OPENMSX_TARGET_OS),mingw32) RESOURCE_SRC:=$(RESOURCES_PATH)/openmsx-debugger.rc RESOURCE_OBJ:=$(OBJECTS_PATH)/resources.o RESOURCE_SCRIPT:=build/win_resource.py RESOURCE_HEADER:=$(BUILD_PATH)/config/resource-info.h else RESOURCE_OBJ:= endif # Build Rules # =========== # Include dependency files. ifneq ($(filter $(DEPEND_TARGETS),$(MAKECMDGOALS)),) -include $(DEPEND_FULL) endif # Clean up build tree of current flavour. # We don't have flavours (yet?), so clean up everything except "detectsys". clean: @echo "Cleaning up..." @rm -rf $(OBJECTS_PATH) @rm -rf $(DEPEND_PATH) @rm -rf $(GEN_SRC_PATH) ifeq ($(OPENMSX_TARGET_OS),darwin) @rm -rf $(APP_PATH) else @rm -rf $(BINARY_PATH) endif # Generate version header. .PHONY: forceversionextraction forceversionextraction: $(VERSION_HEADER): forceversionextraction @$(PYTHON) $(VERSION_SCRIPT) $@ # Default target. ifeq ($(OPENMSX_TARGET_OS),darwin) all: app else all: $(BINARY_FULL) endif QT_INSTALL_HEADERS:=$(shell qmake -query QT_INSTALL_HEADERS) QT_INSTALL_LIBS:=$(shell qmake -query QT_INSTALL_LIBS) QT_INSTALL_BINS:=$(shell qmake -query QT_INSTALL_BINS) # On MingW32 you get backslashes from qmake -query, which we don't want: ifeq ($(OPENMSX_TARGET_OS),mingw32) QT_INSTALL_HEADERS:=$(subst \,/,$(QT_INSTALL_HEADERS)) QT_INSTALL_LIBS:=$(subst \,/,$(QT_INSTALL_LIBS)) QT_INSTALL_BINS:=$(subst \,/,$(QT_INSTALL_BINS)) endif QT_COMPONENTS:=Core Widgets Gui Network Xml QT_HEADER_DIRS:=$(addprefix $(QT_INSTALL_HEADERS)/Qt,$(QT_COMPONENTS)) QT_HEADER_DIRS+=$(QT_INSTALL_HEADERS) ifeq ($(OPENMSX_TARGET_OS),darwin) QT_HEADER_DIRS+=$(patsubst %,/Library/Frameworks/Qt%.framework/Headers,$(QT_COMPONENTS)) endif CXX:=g++ WINDRES?=windres CXXFLAGS:= -g -fPIC INCLUDE_INTERNAL:=$(sort $(foreach header,$(HEADERS_FULL),$(patsubst %/,%,$(dir $(header))))) INCLUDE_INTERNAL+=$(BUILD_PATH)/config COMPILE_FLAGS:=$(addprefix -I,$(QT_HEADER_DIRS) $(INCLUDE_INTERNAL) $(GEN_SRC_PATH)) # Enable C++11 COMPILE_FLAGS+=-std=c++11 ifeq ($(OPENMSX_TARGET_OS),darwin) LINK_FLAGS:=-F$(QT_INSTALL_LIBS) $(addprefix -framework Qt,$(QT_COMPONENTS)) SDK_PATH:=/Developer/SDKs/MacOSX10.4u.sdk OSX_VER:=10.4 OSX_MIN_REQ:=1040 COMPILE_ENV:=NEXT_ROOT=$(SDK_PATH) MACOSX_DEPLOYMENT_TARGET=$(OSX_VER) LINK_ENV:=NEXT_ROOT=$(SDK_PATH) MACOSX_DEPLOYMENT_TARGET=$(OSX_VER) COMPILE_FLAGS+=-D__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__=$(OSX_MIN_REQ) COMPILE_FLAGS+=-isysroot $(SDK_PATH) LINK_FLAGS+=-Wl,-syslibroot,$(SDK_PATH) else COMPILE_ENV:= LINK_ENV:= ifeq ($(OPENMSX_TARGET_OS),mingw32) COMPILE_FLAGS+=-static-libgcc -static-libstdc++ LINK_FLAGS:=-Wl,-rpath,$(QT_INSTALL_BINS) -L$(QT_INSTALL_BINS) $(addprefix -lQt5,$(QT_COMPONENTS)) -lws2_32 -lsecur32 -mwindows -static-libgcc -static-libstdc++ else LINK_FLAGS:=-Wl,-rpath,$(QT_INSTALL_LIBS) -L$(QT_INSTALL_LIBS) $(addprefix -lQt5,$(QT_COMPONENTS)) endif endif DEPEND_FLAGS:= # GCC flags: # (these should be omitted if we ever want to support other compilers) # Generic compilation flags. CXXFLAGS+=-pipe # Stricter warning and error reporting. CXXFLAGS+=-Wall # Empty definition of used headers, so header removal doesn't break things. DEPEND_FLAGS+=-MP # Generate Meta Object Compiler sources. $(MOC_SRC_FULL): $(GEN_SRC_PATH)/moc_%.cpp: $(SOURCES_PATH)/%.h @echo "Generating $(@F)..." @mkdir -p $(@D) @$(QT_INSTALL_BINS)/moc -o $@ $< # Generate resource source. $(RES_SRC_FULL): $(GEN_SRC_PATH)/qrc_%.cpp: $(RESOURCES_PATH)/%.qrc @echo "Generating $(@F)..." @mkdir -p $(@D) @$(QT_INSTALL_BINS)/rcc -name $(<:$(RESOURCES_PATH)/%.qrc=%) $< -o $@ # Generate ui files. $(UI_HDR_FULL): $(GEN_SRC_PATH)/ui_%.h: $(SOURCES_PATH)/%.ui @echo "Generating $(@F)..." @mkdir -p $(@D) @$(QT_INSTALL_BINS)/uic -o $@ $< # This is a workaround for the lack of order-only dependencies in GNU Make # versions before than 3.80 (for example Mac OS X 10.3 still ships with 3.79). # It creates a dummy file, which is never modified after its initial creation. # If a rule that produces a file does not modify that file, Make considers the # target to be up-to-date. That way, the targets "ui-dummy-file" depends on # will always be checked before compilation, but they will not cause all object # files to be considered outdated. GEN_DUMMY_FILE:=$(GEN_SRC_PATH)/dummy-file $(GEN_DUMMY_FILE): $(UI_HDR_FULL) $(GENERATED_HEADERS) @test -e $@ || touch $@ # Compile and generate dependency files in one go. SRC_DEPEND_SUBST=$(patsubst $(SOURCES_PATH)/%.cpp,$(DEPEND_PATH)/%.d,$<) GEN_DEPEND_SUBST=$(patsubst $(GEN_SRC_PATH)/%.cpp,$(DEPEND_PATH)/%.d,$<) $(OBJECTS_FULL): $(GEN_DUMMY_FILE) $(OBJECTS_FULL): $(OBJECTS_PATH)/%.o: $(SOURCES_PATH)/%.cpp $(DEPEND_PATH)/%.d @echo "Compiling $(patsubst $(SOURCES_PATH)/%,%,$<)..." @mkdir -p $(@D) @mkdir -p $(patsubst $(OBJECTS_PATH)%,$(DEPEND_PATH)%,$(@D)) @$(COMPILE_ENV) $(CXX) \ $(DEPEND_FLAGS) -MMD -MF $(SRC_DEPEND_SUBST) \ -o $@ $(CXXFLAGS) $(COMPILE_FLAGS) -c $< @touch $@ # Force .o file to be newer than .d file. $(GEN_OBJ_FULL): $(OBJECTS_PATH)/%.o: $(GEN_SRC_PATH)/%.cpp $(DEPEND_PATH)/%.d @echo "Compiling $(patsubst $(GEN_SRC_PATH)/%,%,$<)..." @mkdir -p $(@D) @mkdir -p $(patsubst $(OBJECTS_PATH)%,$(DEPEND_PATH)%,$(@D)) @$(COMPILE_ENV) $(CXX) \ $(DEPEND_FLAGS) -MMD -MF $(GEN_DEPEND_SUBST) \ -o $@ $(CXXFLAGS) $(COMPILE_FLAGS) -c $< @touch $@ # Force .o file to be newer than .d file. # Generate dependencies that do not exist yet. # This is only in case some .d files have been deleted; # in normal operation this rule is never triggered. $(DEPEND_FULL): # Windows resources that are added to the executable. ifeq ($(OPENMSX_TARGET_OS),mingw32) $(RESOURCE_HEADER): forceversionextraction @$(PYTHON) $(RESOURCE_SCRIPT) $@ $(RESOURCE_OBJ): $(RESOURCE_SRC) $(RESOURCE_HEADER) @echo "Compiling resources..." @mkdir -p $(@D) @$(WINDRES) $(addprefix --include-dir=,$(^D)) -o $@ -i $< endif # Link executable. $(BINARY_FULL): $(OBJECTS_FULL) $(GEN_OBJ_FULL) $(RESOURCE_OBJ) ifeq ($(OPENMSX_SUBSET),) @echo "Linking $(@F)..." @mkdir -p $(@D) @$(LINK_ENV) $(CXX) -o $@ $(CXXFLAGS) $^ $(LINK_FLAGS) else @echo "Not linking $(notdir $@) because only a subset was built." endif # Application folder. ifeq ($(OPENMSX_TARGET_OS),darwin) app: $(BINARY_FULL) $(PKGINFO_FULL) $(APP_PLIST) $(APP_RESOURCES) $(PKGINFO_FULL): @echo "Generating $(@F)..." @mkdir -p $(@D) @echo "APPLoMXD" > $@ $(APP_PLIST): $(APP_PATH)/Contents/%: $(APP_SUPPORT_PATH)/% @echo "Generating $(@F)..." @mkdir -p $(@D) @sed -e 's/%ICON%/$(notdir $(APP_ICON))/' \ -e 's/%VERSION%/$(PACKAGE_DETAILED_VERSION)/' < $< > $@ $(APP_RESOURCES): $(APP_PATH)/Contents/Resources/%: $(APP_SUPPORT_PATH)/% @echo "Copying $(@F)..." @mkdir -p $(@D) @cp $< $@ endif # Source Packaging # ================ DIST_BASE:=$(BUILD_BASE)/dist DIST_PATH:=$(DIST_BASE)/$(PACKAGE_FULL) dist: $(DETECTSYS_SCRIPT) @echo "Removing any old distribution files..." @rm -rf $(DIST_PATH) @echo "Gathering files for distribution..." @mkdir -p $(DIST_PATH) @build/install-recursive.sh $(DIST_FULL) $(DIST_PATH) @build/install-recursive.sh $(HEADERS_FULL) $(DIST_PATH) @build/install-recursive.sh $(SOURCES_FULL) $(DIST_PATH) @build/install-recursive.sh $(UI_FULL) $(DIST_PATH) @echo "Creating tarball..." @cd $(DIST_BASE) && \ GZIP=--best tar zcf $(PACKAGE_FULL).tar.gz $(PACKAGE_FULL) endif # PLATFORM openmsx-debugger-0.0.0.svn20141006.orig/build/package-windows/0000755000175000017500000000000012414415132023057 5ustar shevekshevekopenmsx-debugger-0.0.0.svn20141006.orig/build/package-windows/package.cmd0000644000175000017500000000171012414415132025136 0ustar shevekshevek@echo off rem rem **** Run this from the top of the debugger source tree: **** rem rem Usage: package.cmd DEBUGGER_PLATFORM DEBUGGER_CONFIGURATION DEBUGGER_VERSION rem rem **** DEBUGGER_PLATFORM is { Win32, x64 } **** rem **** DEBUGGER_CONFIGURATION is { Release, Debug } **** rem **** DEBUGGER_VERSION is a version string; e.g. 0.7.0 **** if "%3" == "" goto usage if "%4" NEQ "" goto usage setlocal set DEBUGGER_PLATFORM=%1 echo DEBUGGER_PLATFORM is %DEBUGGER_PLATFORM% set DEBUGGER_CONFIGURATION=%2 echo DEBUGGER_CONFIGURATION is %DEBUGGER_CONFIGURATION% set DEBUGGER_VERSION=%3 echo DEBUGGER_VERSION is %DEBUGGER_VERSION% set DEBUGGER_PACKAGE_WINDOWS_PATH=.\build\package-windows set PYTHONPATH=%PYTHONPATH%;.\build python %DEBUGGER_PACKAGE_WINDOWS_PATH%\packagezip.py %DEBUGGER_PLATFORM% %DEBUGGER_CONFIGURATION% %DEBUGGER_VERSION% endlocal goto end :usage echo Usage: package.cmd platform configuration version :end openmsx-debugger-0.0.0.svn20141006.orig/build/package-windows/packagewindows.py0000644000175000017500000000516312414415132026444 0ustar shevekshevekimport os, sys def DeleteDirectoryIfExists(top): if os.path.exists(top): DeleteDirectory(top) def DeleteDirectory(top): for root, dirs, files in os.walk(top, topdown=False): for name in files: os.remove(os.path.join(root, name)) for name in dirs: os.rmdir(os.path.join(root, name)) def GenerateInstallFiles(info): DeleteDirectoryIfExists(info.makeInstallPath) install.installAll(info.makeInstallPath + os.sep, 'bin', 'share', 'doc', info.openmsxExePath, 'mingw32', True, True) def WalkPath(sourcePath): if os.path.isfile(sourcePath): filenames = list() filenames.append(os.path.basename(sourcePath)) yield os.path.dirname(sourcePath), list(), filenames else: for dirpath, dirnames, filenames in os.walk(sourcePath): yield dirpath, dirnames, filenames class PackageInfo: def __init__(self, platform, configuration, version, catapultPath): self.platform = platform.lower() if self.platform == 'win32': self.architecture = 'x86' self.platform = 'Win32' self.win64 = False elif self.platform == 'x64': self.architecture = 'x64' self.platform = 'x64' self.win64 = True else: raise ValueError, 'Wrong platform: ' + platform self.configuration = configuration.lower() if self.configuration == 'release': self.configuration = 'Release' self.catapultConfiguration = 'Unicode Release' elif self.configuration == 'Developer': self.configuration = 'Developer' self.catapultConfiguration = 'Unicode Debug' elif self.configuration == 'Debug': self.configuration = 'Debug' self.catapultConfiguration = 'Unicode Debug' else: raise ValueError, 'Wrong configuration: ' + architecture self.version = version self.catapultPath = catapultPath # Useful variables self.buildFlavor = self.platform + '-VC-' + self.configuration self.buildPath = os.path.join('derived', self.buildFlavor) self.installPath = os.path.join(self.buildPath, 'install') self.sourcePath = 'src' self.codecPath = 'Contrib\\codec\\Win32' self.packageWindowsPath = 'build\\package-windows' self.packagePath = os.path.join(self.buildPath, 'package-windows') self.makeInstallPath = os.path.join(self.packagePath, 'install') self.installerFileName = 'openmsx-debugger-' + version + '-VC-' + self.architecture if __name__ == '__main__': if len(sys.argv) == 5: info = PackageInfo(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4]) else: print >> sys.stderr, \ 'Usage: python packagewindowsinfo.py architecture, configuration, version, catapultPath' sys.exit(2) openmsx-debugger-0.0.0.svn20141006.orig/build/package-windows/packagezip.py0000644000175000017500000000327712414415132025560 0ustar shevekshevekimport os, sys import zipfile import packagewindows def AddFile(zip, path, zipPath): print 'Adding ' + path zip.write(path, zipPath, zipfile.ZIP_DEFLATED) def AddDirectory(zip, root, zipPath): for path, dirs, files in os.walk(root): if '.svn' in dirs: dirs.remove('.svn') # don't visit .svn directories for name in files: thisZipPath = zipPath if os.path.abspath(root) != os.path.abspath(path): thisZipPath = os.path.join(thisZipPath, os.path.relpath(path, root)) AddFile(zip, os.path.join(path, name), os.path.join(thisZipPath, name)) def PackageZip(info): if not os.path.exists(info.packagePath): os.mkdir(info.packagePath) zipFileName = info.installerFileName + '.zip' zipFilePath = os.path.join(info.packagePath, zipFileName) if os.path.exists(zipFilePath): os.unlink(zipFilePath) print 'Generating ' + zipFilePath zip = zipfile.ZipFile(zipFilePath, 'w') AddFile(zip, os.path.join(info.installPath, 'openmsx-debugger.exe'), 'openmsx-debugger.exe') zip.close() zipFileName = info.installerFileName + '-pdb.zip' zipFilePath = os.path.join(info.packagePath, zipFileName) if os.path.exists(zipFilePath): os.unlink(zipFilePath) print 'Generating ' + zipFilePath zip = zipfile.ZipFile(zipFilePath, 'w') AddFile(zip, os.path.join(info.installPath, 'openmsx-debugger.pdb'), 'openmsx-debugger.pdb') zip.close() if __name__ == '__main__': if len(sys.argv) != 4: print >> sys.stderr, 'Usage: python packagezip.py platform configuration version' # E.g. build\package-windows\package.cmd x64 Release 0.7.1 sys.exit(2) else: info = packagewindows.PackageInfo(sys.argv[1], sys.argv[2], sys.argv[3], '') PackageZip(info) openmsx-debugger-0.0.0.svn20141006.orig/build/outpututils.py0000644000175000017500000000204212414415132022765 0ustar shevekshevek# $Id$ # Various utility functions for generating output files and directories. from os import makedirs from os.path import dirname, isdir, isfile def createDirFor(filePath): '''Creates an output directory for containing the given file path. Nothing happens if the directory already exsits. ''' dirPath = dirname(filePath) if dirPath and not isdir(dirPath): makedirs(dirPath) def rewriteIfChanged(path, lines): '''Writes the file with the given path if it does not exist yet or if its contents should change. The contents are given by the "lines" sequence. Returns True if the file was (re)written, False otherwise. ''' newLines = [ line + '\n' for line in lines ] if isfile(path): inp = open(path, 'r') try: oldLines = inp.readlines() finally: inp.close() if newLines == oldLines: print 'Up to date: %s' % path return False else: print 'Updating %s...' % path else: print 'Creating %s...' % path createDirFor(path) out = open(path, 'w') try: out.writelines(newLines) finally: out.close() return True openmsx-debugger-0.0.0.svn20141006.orig/build/msysutils.py0000644000175000017500000000430312414415132022422 0ustar shevekshevekfrom os import environ from os.path import isfile from subprocess import PIPE, Popen import sys def _determineMounts(): # The MSYS shell provides a Unix-like file system by translating paths on # the command line to Windows paths. Usually this is transparent, but not # for us since we call GCC without going through the shell. # Figure out the root directory of MSYS. proc = Popen( [ msysShell(), '-c', '"%s" -c \'import sys ; print sys.argv[1]\' /' % sys.executable.replace('\\', '\\\\') ], stdin = None, stdout = PIPE, stderr = PIPE, ) stdoutdata, stderrdata = proc.communicate() if stderrdata or proc.returncode: if stderrdata: print >> sys.stderr, 'Error determining MSYS root:', stderrdata if proc.returncode: print >> sys.stderr, 'Exit code %d' % proc.returncode raise IOError('Error determining MSYS root') msysRoot = stdoutdata.strip() # Figure out all mount points of MSYS. mounts = { '/': msysRoot + '/' } fstab = msysRoot + '/etc/fstab' if isfile(fstab): try: inp = open(fstab, 'r') try: for line in inp: line = line.strip() if line and not line.startswith('#'): nativePath, mountPoint = ( path.rstrip('/') + '/' for path in line.split() ) mounts[mountPoint] = nativePath finally: inp.close() except IOError, ex: print >> sys.stderr, 'Failed to read MSYS fstab:', ex except ValueError, ex: print >> sys.stderr, 'Failed to parse MSYS fstab:', ex return mounts def msysPathToNative(path): if path.startswith('/'): if len(path) == 2 or (len(path) > 2 and path[2] == '/'): # Support drive letters as top-level dirs. return '%s:/%s' % (path[1], path[3 : ]) longestMatch = '' for mountPoint in msysMounts.iterkeys(): if path.startswith(mountPoint): if len(mountPoint) > len(longestMatch): longestMatch = mountPoint return msysMounts[longestMatch] + path[len(longestMatch) : ] else: return path def msysActive(): return environ.get('OSTYPE') == 'msys' or 'MSYSCON' in environ def msysShell(): return environ.get('MSYSCON') or environ.get('SHELL') or 'sh.exe' if msysActive(): msysMounts = _determineMounts() else: msysMounts = None if __name__ == '__main__': print 'MSYS mounts:', msysMounts openmsx-debugger-0.0.0.svn20141006.orig/build/node-start.mk0000644000175000017500000000063512414415132022411 0ustar shevekshevek# $Id$ # Should be included at the start of each node.mk file. # Get name of current directory. SUBDIR:=$(firstword $(SUBDIRSTACK)) SUBDIRSTACK:=$(wordlist 2,$(words $(SUBDIRSTACK)),$(SUBDIRSTACK)) # Push current directory on directory stack. DIRSTACK:=$(CURDIR) $(DIRSTACK) CURDIR:=$(CURDIR)$(SUBDIR) # Initialise node vars with empty value. SUBDIRS:= DIST:= MOC_SRC_HDR:= SRC_HDR:= SRC_ONLY:= HDR_ONLY:= UI:= openmsx-debugger-0.0.0.svn20141006.orig/build/makeutils.py0000644000175000017500000000347612414415132022356 0ustar shevekshevek# $Id$ import re def filterLines(lines, regex): '''Filters each line of the given line iterator using the given regular expression string. For each match, a tuple containing the text matching each capture group from the regular expression is yielded. ''' matcher = re.compile(regex) for line in lines: if line.endswith('\n'): line = line[ : -1] match = matcher.match(line) if match: yield match.groups() def filterFile(filePath, regex): '''Filters each line of the given text file using the given regular expression string. For each match, a tuple containing the text matching each capture group from the regular expression is yielded. ''' inp = open(filePath, 'r') try: for groups in filterLines(inp, regex): yield groups finally: inp.close() def joinContinuedLines(lines): '''Iterates through the given lines, replacing lines that are continued using a trailing backslash with a single line. ''' buf = '' for line in lines: if line.endswith('\\\n'): buf += line[ : -2] elif line.endswith('\\'): buf += line[ : -1] else: yield buf + line buf = '' if buf: raise ValueError('Continuation on last line') def extractMakeVariables(filePath): '''Extract all variable definitions from the given Makefile. Returns a dictionary that maps each variable name to its value. ''' makeVars = {} inp = open(filePath, 'r') try: for name, value in filterLines( joinContinuedLines(inp), r'[ ]*([A-Za-z0-9_]+)[ ]*:=(.*)' ): makeVars[name] = value.strip() finally: inp.close() return makeVars def parseBool(valueStr): '''Parses a string containing a boolean value. Accepted values are "true" and "false"; anything else raises ValueError. ''' if valueStr == 'true': return True elif valueStr == 'false': return False else: raise ValueError('Invalid boolean "%s"' % valueStr) openmsx-debugger-0.0.0.svn20141006.orig/build/executils.py0000644000175000017500000000375412414415132022364 0ustar shevekshevekfrom msysutils import msysActive, msysShell from os import environ from shlex import split as shsplit from subprocess import PIPE, Popen def captureStdout(log, commandLine): '''Run a command and capture what it writes to stdout. If the command fails or writes something to stderr, that is logged. Returns the captured string, or None if the command failed. ''' # TODO: This is a modified copy-paste from compilers._Command. commandParts = shsplit(commandLine) env = dict(environ) while commandParts: if '=' in commandParts[0]: name, value = commandParts[0].split('=', 1) del commandParts[0] env[name] = value else: break else: raise ValueError( 'No command specified in "%s"' % commandLine ) if msysActive() and commandParts[0] != 'sh': commandParts = [ environ.get('MSYSCON') or environ.get('SHELL') or 'sh.exe', '-c', shjoin(commandParts) ] try: proc = Popen( commandParts, bufsize = -1, env = env, stdin = None, stdout = PIPE, stderr = PIPE, ) except OSError, ex: print >> log, 'Failed to execute "%s": %s' % (commandLine, ex) return None stdoutdata, stderrdata = proc.communicate() if stderrdata: severity = 'warning' if proc.returncode == 0 else 'error' log.write('%s executing "%s"\n' % (severity.capitalize(), commandLine)) # pylint 0.18.0 somehow thinks stderrdata is a list, not a string. # pylint: disable-msg=E1103 stderrdata = stderrdata.replace('\r', '') log.write(stderrdata) if not stderrdata.endswith('\n'): log.write('\n') if proc.returncode == 0: return stdoutdata else: print >> log, 'Execution failed with exit code %d' % proc.returncode return None def shjoin(parts): '''Joins the given sequence into a single string with space as a separator. Characters that have a special meaning for the shell are escaped. This is the counterpart of shlex.split(). ''' def escape(part): return ''.join( '\\' + ch if ch in '\\ \'"$()[]' else ch for ch in part ) return ' '.join(escape(part) for part in parts) openmsx-debugger-0.0.0.svn20141006.orig/build/node-end.mk0000644000175000017500000000152712414415132022023 0ustar shevekshevek# $Id$ # Should be included at the end of each node.mk file. # Process this node. SOURCES_FULL+=$(sort \ $(addprefix $(CURDIR),$(addsuffix .cpp, \ $(MOC_SRC_HDR) $(SRC_HDR) $(SRC_ONLY) \ ))) HEADERS_FULL+=$(sort \ $(addprefix $(CURDIR),$(addsuffix .h, \ $(MOC_SRC_HDR) $(SRC_HDR) $(HDR_ONLY) \ ))) MOC_HDR_FULL+=$(sort \ $(addprefix $(CURDIR),$(addsuffix .h, \ $(MOC_SRC_HDR) \ ))) UI_FULL+=$(sort \ $(addprefix $(CURDIR),$(addsuffix .ui, \ $(UI) \ ))) DIST_FULL+=$(sort \ $(addprefix $(CURDIR),$(DIST) node.mk) \ ) # Process subnodes. ifneq ($(SUBDIRS),) SUBDIRS:=$(addsuffix /,$(SUBDIRS)) SUBDIRSTACK:=$(SUBDIRS) $(SUBDIRSTACK) include $(addprefix $(CURDIR),$(addsuffix node.mk,$(SUBDIRS))) endif # Pop current directory off directory stack. CURDIR:=$(firstword $(DIRSTACK)) DIRSTACK:=$(wordlist 2,$(words $(DIRSTACK)),$(DIRSTACK)) openmsx-debugger-0.0.0.svn20141006.orig/build/msvc/0000755000175000017500000000000012414415132020744 5ustar shevekshevekopenmsx-debugger-0.0.0.svn20141006.orig/build/msvc/genconfig.py0000644000175000017500000000165012414415132023257 0ustar shevekshevek# Generates configuration headers for VC++ builds import sys import os.path import outpututils import win_resource import version2code # # platform: one of { Win32, x64 } # configuration: one of { Debug, Developer, Release } # outputPath: the location in which to generate config files # def genConfig(platform, configuration, outputPath): # # resource-info.hh # resourceInfoHeader = os.path.join(outputPath, 'resource-info.h') generator = win_resource.iterResourceHeader() outpututils.rewriteIfChanged(resourceInfoHeader, generator) # # version.ii # versionHeader = os.path.join(outputPath, 'version.ii') generator = version2code.iterVersionInclude() outpututils.rewriteIfChanged(versionHeader, generator) if len(sys.argv) == 4: genConfig(sys.argv[1], sys.argv[2], sys.argv[3]) else: print >> sys.stderr, 'Usage: python genconfig.py platform configuration outputPath' sys.exit(2) openmsx-debugger-0.0.0.svn20141006.orig/build/msvc/openmsx-debugger.vsprops0000644000175000017500000000360012414415132025654 0ustar shevekshevek openmsx-debugger-0.0.0.svn20141006.orig/build/msvc/openmsx-debugger.vcproj0000644000175000017500000031735612414415132025463 0ustar shevekshevek openmsx-debugger-0.0.0.svn20141006.orig/build/msvc/openmsx-debugger.sln0000644000175000017500000000234312414415132024737 0ustar shevekshevek Microsoft Visual Studio Solution File, Format Version 10.00 # Visual Studio 2008 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "openmsx-debugger", "openmsx-debugger.vcproj", "{A9B5A99F-45C3-4BF9-B596-568F082A59D6}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Debug|x64 = Debug|x64 Release|Win32 = Release|Win32 Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {A9B5A99F-45C3-4BF9-B596-568F082A59D6}.Debug|Win32.ActiveCfg = Debug|Win32 {A9B5A99F-45C3-4BF9-B596-568F082A59D6}.Debug|Win32.Build.0 = Debug|Win32 {A9B5A99F-45C3-4BF9-B596-568F082A59D6}.Debug|x64.ActiveCfg = Debug|x64 {A9B5A99F-45C3-4BF9-B596-568F082A59D6}.Debug|x64.Build.0 = Debug|x64 {A9B5A99F-45C3-4BF9-B596-568F082A59D6}.Release|Win32.ActiveCfg = Release|Win32 {A9B5A99F-45C3-4BF9-B596-568F082A59D6}.Release|Win32.Build.0 = Release|Win32 {A9B5A99F-45C3-4BF9-B596-568F082A59D6}.Release|x64.ActiveCfg = Release|x64 {A9B5A99F-45C3-4BF9-B596-568F082A59D6}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal openmsx-debugger-0.0.0.svn20141006.orig/build/detectsys.py0000644000175000017500000000567012414415132022365 0ustar shevekshevek# $Id$ # Detect the native CPU and OS. # Actually we rely on the Python "platform" module and map its output to names # that the openMSX build understands. from platform import machine, python_version, system import sys def detectCPU(): '''Detects the CPU family (not the CPU model) of the machine were are running on. Raises ValueError if no known CPU is detected. ''' cpu = machine().lower() dashIndex = cpu.find('-') if dashIndex != -1: # Hurd returns "cputype-cpusubtype" instead of just "cputype". cpu = cpu[ : dashIndex] if cpu in ('x86_64', 'amd64'): return 'x86_64' elif cpu in ('x86', 'i386', 'i486', 'i586', 'i686'): return 'x86' elif cpu.startswith('ppc') or cpu.endswith('ppc') or cpu.startswith('power'): return 'ppc64' if cpu.endswith('64') else 'ppc' elif cpu.startswith('arm'): return 'arm' elif cpu == 'aarch64': return 'aarch64' elif cpu == 'aarch64_be': return 'aarch64_be' elif cpu.startswith('mips') or cpu == 'sgi': return 'mipsel' if cpu.endswith('el') else 'mips' elif cpu == 'm68k': return 'm68k' elif cpu == 'ia64': return 'ia64' elif cpu.startswith('alpha'): return 'alpha' elif cpu.startswith('hppa') or cpu.startswith('parisc'): return 'hppa' elif cpu.startswith('s390'): return 's390' elif cpu.startswith('sparc') or cpu.startswith('sun4u'): return 'sparc' elif cpu.startswith('sh'): return 'sheb' if cpu.endswith('eb') else 'sh' elif cpu == 'avr32': return 'avr32' elif cpu == '': # Python couldn't figure it out. os = system().lower() if os == 'windows': # Relatively safe bet. return 'x86' raise ValueError('Unable to detect CPU') else: raise ValueError('Unsupported or unrecognised CPU "%s"' % cpu) def detectOS(): '''Detects the operating system of the machine were are running on. Raises ValueError if no known OS is detected. ''' os = system().lower() if os in ('linux', 'darwin', 'freebsd', 'netbsd', 'openbsd', 'gnu'): return os elif os.startswith('gnu/'): # GNU userland on non-Hurd kernel, for example Debian GNU/kFreeBSD. # For openMSX the kernel is not really relevant, so treat it like # a generic GNU system. return 'gnu' elif os.startswith('mingw') or os == 'windows': return 'mingw32' elif os == 'sunos': return 'solaris' elif os == '': # Python couldn't figure it out. raise ValueError('Unable to detect OS') else: raise ValueError('Unsupported or unrecognised OS "%s"' % os) if __name__ == '__main__': try: print >> sys.stderr, ' Using Python %s native system detection...' % ( python_version() ) hostCPU = detectCPU() hostOS = detectOS() if hostOS == 'mingw32' and hostCPU == 'x86_64': # It is possible to run MinGW on 64-bit Windows, but producing # 64-bit code is not supported yet. hostCPU = 'x86' print >> sys.stderr, ' Detected system: %s-%s' % (hostCPU, hostOS) print 'OPENMSX_TARGET_CPU=%s' % hostCPU print 'OPENMSX_TARGET_OS=%s' % hostOS except ValueError, ex: print >> sys.stderr, ex sys.exit(1) openmsx-debugger-0.0.0.svn20141006.orig/ChangeLog0000644000175000017500000002731512414415132020457 0ustar shevekshevek$Id$ 2012-06-03 Edwin Velds * Reworked breakpoint system to also support watchpoints and conditions. * Several breakpoint related bugfixes. * Made watchpoints visible in DisasmViewer. 2012-05-27 Edwin Velds * Cursor follows pc/breakpoints/pgup/pgdn. * MainMemoryViewer now accepts proper formatted addresses and labels. 2012-05-22 Edwin Velds * Added display of rom blocks 2012-05-20 Edwin Velds * Added recent sessions files to the File menu * Monitor symbol files for changes and immediately ask the user if they need to be reloaded. 2012-05-19 Edwin Velds * Added a goto dialog for disasm view navigation 2012-05-19 Edwin Velds * Added ability to add breakpoints by label 2011-03-06 Edwin Velds * Added support for step_back * Added a workaround for step_over leaving a breakpoint 2009-06-25 David Heremans * The VDP register viewer will now indicate the bits which must be set according to the VDP technical data book. * Ignore those bits when calculating the table addresses. 2009-05-09 David Heremans * Added support for symbol files generated by SJASM 2008-11-01 David Heremans * Launching of command possible. * Indication of used registers for given command. 2008-10-30 David Heremans * Added indication of used bits in ARG register 2008-10-29 David Heremans * First steps towards VDP Command registers dialog. 2008-10-22 David Heremans * More (V9958) registers explained * Started to correctly differentiate between TMS99x8,V9938 and V9958 in decoding table addresses and function of some bits. 2008-10-17 David Heremans * Added the SimpleHexRequest and SimpleHexRequestUser: An attempt to simplify the request of openMSX debugable data 2008-10-13 David Heremans * Check if this it is {physical VRAM} vs the older {VRAM} * More registerViewer code 2008-10-13 Edwin Velds * Small fix in usage of qWarning. * Fixed ChangeLog dates. 2008-10-12 David Heremans * More WIP: some more pixel based fun in the bitmapped vram viewer 2008-10-08 David Heremans * Added WIP: - A bitmapped vram viewer - The VDP status registers explained - The regular VDP registers explained The first two are already functional, but still need some minor refinements, the last one is only a ui and some helper class at the moment. 2008-09-15 David Heremans * Added visual indication to show focus on HexViewer widget. * More special keys handling. * All debuggable views are now editable.A single value OR a chain of characters depending on where you click. 2008-09-14 David Heremans * HexViewer now correctly writes new values to the originatin debugable. 2008-09-13 David Heremans * More mousesupport in HexViewer * Differentiate between data- vs charbased input. And of course visual indication for this feature. 2008-09-12 David Heremans * Added tooltips to HexViewer. * Directly update memoryviewer after linking to a register. 2008-09-11 David Heremans * Made the memoryviewer always start at an offset of "horBytes". * Introduced the backgroundmarker to indicate the selected address. * Fixed an asyncronisation problem which made the scrollbalk cycle between previous values. 2008-09-10 David Heremans * You can now select the cpu register to follow. 2008-09-09 David Heremans * First steps towards MainMemoryViewer with Compass like 'Linked-to-register' functionality. For now at least one can enter the address for the memory viewer as hex value. 2008-05-06 Edwin Velds * Added disassemble restart at PC. 2008-04-19 Edwin Velds * Nearly full rewrite of CPU regs viewer. * Register values editor implemented. * Tooltip for values in binary and decimal. * Added class for writing values back to openmsx. 2008-04-18 Edwin Velds * Added saving op breakpoints. * Added restoring session breakpoints after connect. * Show session file in window title. 2008-04-17 Edwin Velds * Added preliminary support for saving debug sessions. Only symbols currently supported. Note that file format may change without prior notification or support for older files. * Added checks for modified sessions in new/open/quit. 2008-04-15 Edwin Velds * Added type selection to symbol manager. * Changed name/value editing behaviour to allow only a single editor. 2008-04-14 Edwin Velds * Added register selection to symbol manager. 2008-04-12 Edwin Velds * Implemented reload function in symbol manager. * Several fixes fixes to symbol manager. 2008-04-10 Edwin Velds * Update to symbol table gui: - Better handling of edits. - Changing of label slot locations. - GUI (re)stores size of window and columns. 2008-01-27 Arnold Metselaar * Change the first file type option in the load symbolfile dialog to show all supported file types. 2007-12-03 Arnold Metselaar * Added support for link map files like those produced by HiTech's linker to the SymbolManager. 2007-11-17 Edwin Velds * Added menu item for emulator reboot. * Made address labels visible in disassembled code. 2007-05-18 Edwin Velds * Fixed saving and restoring of window size and position. 2007-05-17 Edwin Velds * Improved scrollbar handling in disasm view. * Fixed scrollbar stepping in stack view. 2007-05-15 Edwin Velds * Fixed a bug that caused the disasm view to stop responding. 2007-03-08 Edwin Velds * Fixed communication bug in stack viewer. * Fixed layout bug that caused overlaps. 2007-03-07 Edwin Velds * Fixed dock widget insert bug that lead to crashes on exit. 2007-03-06 Edwin Velds * Changed resize handling of dock layout. 2007-02-23 Edwin Velds * Additional 64-bit fix in SymbolManager. 2007-02-22 Edwin Velds * changed 64-bit compilation error to one that does not warn on 32-bit systems. 2007-02-15 Edwin Velds * Added a generic debuggable viewer. * Reworked some of the dock widget code to support multiple viewers. 2007-02-11 Edwin Velds * Made the HexViewer code usable to view any debuggable. 2007-02-06 Edwin Velds * Removed launch button in connect dialog. * Added signals to react to settings and symbol changes. * Minor change in scrollbar handling of disasm view. 2007-02-05 Edwin Velds * Revised the disasm viewer navigation and display code. * Fixed some label handling issues. * Changed interrupt flag display in register view to DI/EI. 2007-01-14 Edwin Velds * Added a menu for hiding/showing controls. * Added storing and restoring of window layout in the settings. 2007-01-13 Edwin Velds * New docking layout manager. Supports: - Dragging controls off the main window to a separate window. - Docking separate windows back in the main window. Docking occurs to the closest point on the closest edge. For resizable windows, extra resized docking options are available. TODO: - Finish support for multiple docking areas. - Allow resizing of widgets in the docking area. - Refine docking algorithm where needed. * Updated commands to use machine_info where appropriate 2006-10-09 Manuel Bilderbeek * Use new icon by Eric Boon also on Linux and Windows. TODO: in Windows also make it an appIcon via Windows resources. 2006-10-05 Maarten ter Huurne * Use new icon by Eric Boon on OS X. 2006-09-30 Maarten ter Huurne * Committed mouse wheel scrolling support for disasm panel by BouKiCHi. * Corrected location of PkgInfo file (OS X). 2006-09-11 Edwin Velds * Added breakpoint addition dialog * Added preferences dialog * Added preferences for a few fonts * Added proper conversion for numeric inputs 2006-09-09 Edwin Velds * Symbol table rewrite * Added initial Settings class * Fixed widget colours 2006-08-06 Maarten ter Huurne * Implemented "make dist", which creates a source distribution tar.gz archive in the directory "derived/dist". 2006-07-25 Edwin Velds * Added preliminary support for symbol tables. Manual adding of symbols and loading of TNIASM symbol files are implemented. 2006-06-14 Edwin Velds * Updated the connection dialog * Fixed a bug that caused a crash on closing openMSX 2006-05-13 Maarten ter Huurne * Added support for UI files in the new build system. * Got rid of the qmake build, since the generated UI headers in src/ were interfering with the new build system. Make sure you get rid of the files generated by qmake; CVS will tell you which files. 2006-05-12 Wouter Vermaelen * Replaced connection code: - this code _should_ also work on windows - still work in progress 2006-05-10 Maarten ter Huurne * Got new build system working on OS X. 2006-04-14 Maarten ter Huurne * Made a build system similar to openMSX, on request of Edwin. It's still in the early stages, but it can produce a working executable on my system already. To try it, edit build/main.mk and set QT_BASE correctly, then run: make -f build/main.mk This new build system does not interfere with the qmake build, so we can use them side by side until the new system is mature. 2006-01-27 Edwin Velds * Updated to use the new "cpu" status update instead of break/resume. 2005-12-26 Wouter Vermaelen * Use QTcpSocket iso winsock for TCP connections in windows: - should now compile again on windows without manually hacking the generated Makefiles 2005-10-17 Wouter Vermaelen * OpenMSX now uses unix domain sockets, updated connection code 2005-09-28 Edwin Velds * Fixed bug that caused a crash when no subslots/mapper was available 2005-09-24 Edwin Velds * Add breakpoint toggle * Made breakpoints sensitive to slot and mapper segment * Moved slot info outside SlotViewer 2005-09-11 Edwin Velds * Added memory slot/segment viewer widget * Added Breakpoint menu (still inactive) 2005-09-09 Albert Beevendorp * fixed a bug causing the disassembly showing the wrong byte/word 2005-09-08 Edwin Velds * Changed disasm viewer initialisation code * Added ignoring openMSX log messages * Added memory initialisation 2005-09-04 Wouter Vermaelen * fixed compiler warnings * define own 'debug_bin2hex' proc: removes dependency on the bin2hex.tcl script 2005-09-04 Edwin Velds * Fixed typos in connects * Better error handling * Changed errors to avoid winsock conflicts 2005-08-31 Edwin Velds * Initial import openmsx-debugger-0.0.0.svn20141006.orig/AUTHORS0000644000175000017500000000033712414415132017750 0ustar shevekshevek$Id$ Prime Developers: Edwin Velds Additional Development: Wouter Vermaelen Albert Beevendorp Build System: Maarten ter Huurne openmsx-debugger-0.0.0.svn20141006.orig/GPL0000644000175000017500000004311012414415132017241 0ustar shevekshevek GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. openmsx-debugger-0.0.0.svn20141006.orig/node.mk0000644000175000017500000000022612414415132020153 0ustar shevekshevek# $Id$ include build/node-start.mk SUBDIRS:= \ src build resources DIST:= \ ChangeLog AUTHORS GPL README GNUmakefile include build/node-end.mk openmsx-debugger-0.0.0.svn20141006.orig/src/0000755000175000017500000000000012414415132017464 5ustar shevekshevekopenmsx-debugger-0.0.0.svn20141006.orig/src/CPURegsViewer.h0000644000175000017500000000220412414415132022265 0ustar shevekshevek// $Id$ #ifndef CPUREGSVIEWER_H #define CPUREGSVIEWER_H #include class QPaintEvent; class CPURegsViewer : public QFrame { Q_OBJECT; public: CPURegsViewer(QWidget* parent = 0); void setData(unsigned char* datPtr); int readRegister(int id); QSize sizeHint() const; private: void resizeEvent(QResizeEvent* e); void paintEvent(QPaintEvent* e); void mousePressEvent(QMouseEvent* e); //void mouseMoveEvent(QMouseEvent* e); //void mouseReleaseEvent(QMouseEvent* e); void keyPressEvent(QKeyEvent* e); void focusOutEvent(QFocusEvent* e); bool event(QEvent* e); // layout int frameL, frameR, frameT, frameB; int leftRegPos, leftValuePos, rightRegPos, rightValuePos; int rowHeight; int regs[16], regsCopy[16]; bool regsModified[16]; bool regsChanged[16]; int cursorLoc; void drawValue(QPainter& p, int id, int x, int y); void setRegister(int id, int value); void getRegister(int id, unsigned char* data); void applyModifications(); void cancelModifications(); signals: void registerChanged(int id, int value); void pcChanged(quint16); void flagsChanged(quint8); void spChanged(quint16); }; #endif // CPUREGSVIEWER_H openmsx-debugger-0.0.0.svn20141006.orig/src/OpenMSXConnection.cpp0000644000175000017500000001301412414415132023500 0ustar shevekshevek// $Id$ #include "OpenMSXConnection.h" #include #include #include SimpleCommand::SimpleCommand(const QString& command_) : command(command_) { } QString SimpleCommand::getCommand() const { return command; } void SimpleCommand::replyOk (const QString& message) { emit replyStatusOk(true); delete this; } void SimpleCommand::replyNok(const QString& message) { emit replyStatusOk(false); cancel(); } void SimpleCommand::cancel() { delete this; } static QString createDebugCommand(const QString& debuggable, unsigned offset, unsigned size) { return QString("debug_bin2hex [ debug read_block %1 %2 %3 ]") .arg(debuggable).arg(offset).arg(size); } ReadDebugBlockCommand::ReadDebugBlockCommand(const QString& commandString, unsigned size_, unsigned char* target_) : SimpleCommand(commandString) , size(size_), target(target_) { } ReadDebugBlockCommand::ReadDebugBlockCommand(const QString& debuggable, unsigned offset, unsigned size_, unsigned char* target_) : SimpleCommand(createDebugCommand(debuggable, offset, size_)) , size(size_), target(target_) { } static QString createDebugWriteCommand(const QString& debuggable, unsigned offset, unsigned size, unsigned char *data ) { QString cmd = QString("debug write_block %1 %2 [ debug_hex2bin \"") .arg(debuggable).arg(offset); for (unsigned i = offset; i < offset + size; ++i) { cmd += QString("%1").arg(int(data[i]), 2, 16, QChar('0')).toUpper(); } cmd += "\" ]"; return cmd; } WriteDebugBlockCommand::WriteDebugBlockCommand(const QString& debuggable, unsigned offset, unsigned size_, unsigned char* source_) : SimpleCommand(createDebugWriteCommand(debuggable, offset, size_, source_)) { } static unsigned char hex2val(char c) { return (c <= '9') ? (c - '0') : (c - 'A' + 10); } void ReadDebugBlockCommand::copyData(const QString& message) { assert(static_cast(message.size()) == 2 * size); for (unsigned i = 0; i < size; ++i) { target[i] = (hex2val(message[2 * i + 0].toLatin1()) << 4) + (hex2val(message[2 * i + 1].toLatin1()) << 0); } } OpenMSXConnection::OpenMSXConnection(QAbstractSocket* socket_) : socket(socket_) , reader(new QXmlSimpleReader()) , connected(true) { assert(socket->isValid()); reader->setContentHandler(this); reader->setErrorHandler(this); connect(socket, SIGNAL(readyRead()), this, SLOT(processData())); connect(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(socketStateChanged(QAbstractSocket::SocketState))); connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError(QAbstractSocket::SocketError))); socket->write("\n"); } OpenMSXConnection::~OpenMSXConnection() { cleanup(); assert(commands.empty()); assert(!connected); socket->deleteLater(); } void OpenMSXConnection::sendCommand(Command* command) { assert(command); if (connected && socket->isValid()) { commands.enqueue(command); QString cmd = "" + command->getCommand() + ""; socket->write(cmd.toUtf8()); } else { command->cancel(); } } void OpenMSXConnection::cleanup() { if (!connected) return; connected = false; if (socket->isValid()) { socket->disconnect(this, SLOT(processData())); socket->disconnect(this, SLOT(socketStateChanged(QAbstractSocket::SocketState))); socket->disconnect(this, SLOT(socketError(QAbstractSocket::SocketError))); socket->write("\n"); socket->disconnectFromHost(); } cancelPending(); emit disconnected(); } void OpenMSXConnection::cancelPending() { assert(!connected); while (!commands.empty()) { Command* command = commands.dequeue(); command->cancel(); } } void OpenMSXConnection::socketStateChanged(QAbstractSocket::SocketState state) { if (state != QAbstractSocket::ConnectedState) { cleanup(); } } void OpenMSXConnection::socketError(QAbstractSocket::SocketError /*state*/) { cleanup(); } void OpenMSXConnection::processData() { if (input.get()) { // continue input->setData(socket->readAll()); reader->parseContinue(); } else { // first time input.reset(new QXmlInputSource()); input->setData(socket->readAll()); reader->parse(input.get(), true); // incremental parsing } } bool OpenMSXConnection::fatalError(const QXmlParseException& exception) { qWarning("Fatal error on line %i, column %i: %s", exception.lineNumber(), exception.columnNumber(), exception.message().toLatin1().data()); cleanup(); return false; } bool OpenMSXConnection::startElement( const QString& /*namespaceURI*/, const QString& /*localName*/, const QString& /*qName*/, const QXmlAttributes& atts) { xmlAttrs = atts; xmlData.clear(); return true; } bool OpenMSXConnection::endElement( const QString& /*namespaceURI*/, const QString& /*localName*/, const QString& qName) { if (qName == "openmsx-output") { // ignore } else if (qName == "reply") { if (connected) { Command* command = commands.dequeue(); if (xmlAttrs.value("result") == "ok") { command->replyOk (xmlData); } else { command->replyNok(xmlData); } } else { // still receive a reply while we're already closing // the connection, ignore it } } else if (qName == "log") { emit logParsed(xmlAttrs.value("level"), xmlData); } else if (qName == "update") { emit updateParsed(xmlAttrs.value("type"), xmlAttrs.value("name"), xmlData); } else { qWarning("Unknown XML tag: %s", qName.toLatin1().data()); } return true; } bool OpenMSXConnection::characters(const QString& ch) { xmlData += ch; return true; } openmsx-debugger-0.0.0.svn20141006.orig/src/VDPCommandRegisters.ui0000644000175000017500000005057312414415132023655 0ustar shevekshevek VDPCmdRegs 0 0 489 659 Dialog 75 true New command Qt::Vertical 75 true Current registers R32 0x00 0x00 R33 0x00 R34 0x00 0x00 R35 0x00 R36 0x00 0x00 R37 0x00 R38 0x00 0x00 R39 0x00 R40 0x00 0x00 R41 0x00 R42 0x00 0x00 R43 0x00 COLOR R44 0x00 ARG R45 0x00 CMD explained SX SY DX DY NY NX Direction from source: 0: Down 1: Up DIY 50 false Direction from source: 0: RIght 1: Left DIX When 1, ends execution when border color found. When 0, ends execution when a color other than the border color is found. EQ Direction for long side 0: Long side is in x-axis 1: Long side is in y-axis MAJ Select source memory 0: Video RAM 1: Expansion RAM MXS Select destination memory 0: Video RAM 1: Expansion RAM MXD Select memory 0: Video RAM 1: Expansion RAM MXC CMD R46 0: Stop 1: Invalid 2: Invalid 3: Invalid 4: POINT 5: PSET 6: SRCH 7: LINE 8: LMMV 9: LMMM A: LMCM B: LMMC C: HMMV D: HMMM E: YMMM F: HMMC INP AND OR EOR NOT --- --- --- TIMP TAND TOR TEOR TNOT --- --- --- 0x00 00000000 0000 0000 CMD explained Sync regs to new cmd Auto sync true Launch command Qt::Horizontal 138 24 openmsx-debugger-0.0.0.svn20141006.orig/src/DockableWidgetLayout.cpp0000644000175000017500000005514512414415132024250 0ustar shevekshevek// $Id$ #include "DockableWidgetLayout.h" #include "DockableWidget.h" #include #include #include static const int SNAP_DISTANCE = 16; DockableWidgetLayout::DockableWidgetLayout(QWidget* parent, int margin, int spacing) : QLayout(parent) { setMargin(margin); setSpacing(spacing); minWidth = minHeight = 0; maxWidth = maxHeight = 0; } DockableWidgetLayout::DockableWidgetLayout(int spacing) { setSpacing(spacing); minWidth = minHeight = 0; maxWidth = maxHeight = 0; } DockableWidgetLayout::~DockableWidgetLayout() { while (!dockedWidgets.empty()) { DockInfo* info = dockedWidgets.takeFirst(); delete info->item; delete info->widget; delete info; } } void DockableWidgetLayout::addItem(QLayoutItem* item) { addItem(item, -1); } void DockableWidgetLayout::addItem( QLayoutItem* item, int index, DockSide side, int dist, int w, int h) { DockInfo* info = new DockInfo(); info->item = item; info->widget = qobject_cast(item->widget()); info->dockSide = side; info->dockDistance = dist; info->left = 0; info->top = 0; info->width = -1; info->height = -1; info->useHintWidth = true; info->useHintHeight = true; if (info->widget->sizePolicy().horizontalPolicy() != QSizePolicy::Fixed && w > 0) { info->width = w; info->useHintWidth = false; } if (info->widget->sizePolicy().verticalPolicy() != QSizePolicy::Fixed && h > 0 ) { info->height = h; info->useHintHeight = false; } // first widget is the resize widget, set initial size if (dockedWidgets.empty()) { if (info->width == -1) { info->width = item->sizeHint().width(); } if (info->height == -1) { info->height = item->sizeHint().height(); } info->useHintWidth = false; info->useHintHeight = false; } for (int i = 0; i < dockedWidgets.size(); ++i) { Q_ASSERT(dockedWidgets.at(i)->widget != item->widget()); } if (index > -1 && index < dockedWidgets.size()) { dockedWidgets.insert(index, info); } else { dockedWidgets.append(info); } // recalculate size limits calcSizeLimits(); } void DockableWidgetLayout::addWidget(DockableWidget* widget, const QRect& rect) { int index; DockSide side; QRect r(rect); if (insertLocation(r, index, side, widget->sizePolicy())) { DockInfo* d = dockedWidgets.first(); int dist; switch (side) { case TOP: case BOTTOM: dist = r.left() - d->left; break; case LEFT: case RIGHT: dist = r.top() - d->top; break; } widget->show(); addItem(new QWidgetItem(widget), index, side, dist, r.width(), r.height()); update(); } } void DockableWidgetLayout::addWidget( DockableWidget* widget, DockSide side, int dist, int w, int h) { // append item at the back addItem(new QWidgetItem(widget), -1, side, dist, w, h); } void DockableWidgetLayout::changed() { calcSizeLimits(); update(); } Qt::Orientations DockableWidgetLayout::expandingDirections() const { return Qt::Horizontal | Qt::Vertical; } bool DockableWidgetLayout::hasHeightForWidth() const { return false; } int DockableWidgetLayout::count() const { return dockedWidgets.size(); } QLayoutItem* DockableWidgetLayout::takeAt(int index) { if (index < 0 || index >= dockedWidgets.size()) return 0; DockInfo* info = dockedWidgets.takeAt(index); QLayoutItem* item = info->item; delete info; calcSizeLimits(); return item; } QLayoutItem* DockableWidgetLayout::itemAt(int index) const { if (index < 0 || index >= dockedWidgets.size()) return 0; return dockedWidgets.at(index)->item; } QSize DockableWidgetLayout::minimumSize() const { return QSize(minWidth, minHeight); } QSize DockableWidgetLayout::maximumSize() const { return QSize(maxWidth, maxHeight); } QSize DockableWidgetLayout::sizeHint() const { return QSize(layoutWidth, layoutHeight); } void DockableWidgetLayout::setGeometry(const QRect& rect) { QLayout::setGeometry(rect); // Qt sometimes sets the geometry outside the minimumSize/maximumSize range. :/ int W = std::min(maxWidth, std::max(minWidth, rect.width ())); int H = std::min(maxHeight, std::max(minHeight, rect.height())); // set main widget size int dx = W - layoutWidth; int dy = H - layoutHeight; if (dx != 0 || dy != 0) { sizeMove(dx, dy); calcSizeLimits(); } // resize the widgets for (int i = 0; i < dockedWidgets.size(); ++i) { DockInfo* d = dockedWidgets[i]; if (!d->widget->isHidden()) { d->item->setGeometry(d->bounds()); } } } void DockableWidgetLayout::calcSizeLimits() { if (dockedWidgets.empty()) return; // layout with current sizes doLayout(); DockInfo* d = dockedWidgets.first(); // store current size int curWidth = d->width; int curHeight = d->height; QVector distStore; for (int i = 0; i < dockedWidgets.size(); ++i) { distStore.push_back(dockedWidgets.at(i)->dockDistance); } // first check minimum width (blunt method) for (int i = d->widget->minimumWidth(); i <= curWidth; ++i) { // trial layout sizeMove(i - d->width, 0); doLayout(true); // restore d->width = curWidth; for (int j = 1; j < dockedWidgets.size(); ++j) { dockedWidgets.at(j)->dockDistance = distStore.at(j); } // check result if (layoutHeight == checkHeight && layoutWidth - checkWidth == d->width - i) { break; } } minWidth = checkWidth; // first check maximum width (blunt method) for (int i = d->widget->maximumWidth(); i >= curWidth; --i) { // trial layout sizeMove(i - d->width, 0); doLayout(true); // restore d->width = curWidth; for (int j = 1; j < dockedWidgets.size(); ++j) { dockedWidgets.at(j)->dockDistance = distStore.at(j); } // check result if (layoutHeight == checkHeight && layoutWidth - checkWidth == d->width - i) { break; } } maxWidth = checkWidth; // first check minimum height (blunt method) for (int i = d->widget->minimumHeight(); i <= curHeight; ++i) { // trial layout sizeMove(0, i - d->height); doLayout(true); // restore d->height = curHeight; for (int j = 1; j < dockedWidgets.size(); ++j) { dockedWidgets.at(j)->dockDistance = distStore.at(j); } // check result if (layoutWidth == checkWidth && layoutHeight - checkHeight == d->height - i) { break; } } minHeight = checkHeight; // first check maximum width (blunt method) for (int i = d->widget->maximumHeight(); i >= curHeight; --i) { // trial layout sizeMove(0, i - d->height); doLayout(true); // restore d->height = curHeight; for (int j = 1; j < dockedWidgets.size(); ++j) { dockedWidgets.at(j)->dockDistance = distStore.at(j); } // check result if (layoutWidth == checkWidth && layoutHeight - checkHeight == d->height - i) { break; } } maxHeight = checkHeight; // restore layout doLayout(); } void DockableWidgetLayout::sizeMove(int dx, int dy) { DockInfo* d0 = dockedWidgets.first(); for (int i = 1; i < dockedWidgets.size(); ++i) { DockInfo* d = dockedWidgets.at(i); if (d->dockSide == TOP || d->dockSide == BOTTOM) { if (d->dockDistance >= d0->width) { d->dockDistance += dx; } } if (d->dockSide == LEFT || d->dockSide == RIGHT) { if (d->dockDistance >= d0->height) { d->dockDistance += dy; } } } d0->width += dx; d0->height += dy; } void DockableWidgetLayout::doLayout(bool check) { if (dockedWidgets.empty()) return; DockInfo* d = dockedWidgets.first(); d->left = 0; d->top = 0; int W = d->width; int H = d->height; int dx = 0, dy = 0; for (int i = 1; i < dockedWidgets.size(); ++i) { d = dockedWidgets[i]; // only process visible widgets if (d->widget->isHidden()) { d->left = -10000; d->top = -10000; continue; } // determine size if (d->useHintWidth) { d->width = d->item->sizeHint().width(); } if (d->useHintHeight) { d->height = d->item->sizeHint().height(); } // determine location switch (d->dockSide) { case TOP: d->left = d->dockDistance; if (d->dockDistance >= W || d->dockDistance+d->width <= 0) { d->top = H - d->height; } else { d->top = -d->height; } // adjust position until it doesn't overlap other widgets for (int j = 1; j < i; ++j) { DockInfo* d2 = dockedWidgets[j]; QRect r(d->left, d->top - QWIDGETSIZE_MAX, d->width, d->height + QWIDGETSIZE_MAX); if (r.intersects(d2->bounds())) { d->top = d2->top - d->height; } } break; case LEFT: d->top = d->dockDistance; if (d->dockDistance >= H || d->dockDistance+d->height <= 0) { d->left = W - d->width; } else { d->left = -d->width; } // adjust position until it doesn't overlap other widgets for (int j = 1; j < i; ++j) { DockInfo* d2 = dockedWidgets[j]; QRect r(d->left - QWIDGETSIZE_MAX, d->top, d->width + QWIDGETSIZE_MAX, d->height); if (r.intersects(d2->bounds())) { d->left = d2->left - d->width; } } break; case RIGHT: d->top = d->dockDistance; if (d->dockDistance >= H || d->dockDistance+d->height <= 0) { d->left = 0; } else { d->left = W; } // adjust position until it doesn't overlap other widgets for (int j = 1; j < i; ++j) { DockInfo* d2 = dockedWidgets[j]; QRect r(d->left, d->top, d->width + QWIDGETSIZE_MAX, d->height); if (r.intersects(d2->bounds())) { d->left = d2->left + d2->width; } } break; case BOTTOM: d->left = d->dockDistance; if (d->dockDistance >= W || d->dockDistance+d->width <= 0) { d->top = 0; } else { d->top = H; } // adjust position until it doesn't overlap other widgets for (int j = 1; j < i; ++j) { DockInfo* d2 = dockedWidgets[j]; QRect r(d->left, d->top, d->width, d->height + QWIDGETSIZE_MAX); if (r.intersects(d2->bounds())) { d->top = d2->top + d2->height; } } break; } // check negative coordinates if (d->left < dx) dx = d->left; if (d->top < dy) dy = d->top; } // translate widgets and calculate size int& w = check ? checkWidth : layoutWidth; int& h = check ? checkHeight : layoutHeight; w = h = 0; for (int i = 0; i < dockedWidgets.size(); ++i) { DockInfo* d = dockedWidgets[i]; if (!d->widget->isHidden()) { d->left -= dx; d->top -= dy; w = std::max(w, d->right()); h = std::max(h, d->bottom()); } } } bool DockableWidgetLayout::overlaysWithFirstNWidgets(const QRect& r, int n) const { for (int i = 0; i < n; ++i) { if (r.intersects(dockedWidgets[i]->bounds())) { return true; } } return false; } static bool isClose(int a, int b) { return abs(a - b) < SNAP_DISTANCE; } bool DockableWidgetLayout::insertLocation( QRect& rect, int& index, DockSide& side, const QSizePolicy& sizePol) { // best insertion data // Distance is a number that represents the how far // the insertion rectangle is from the final location. unsigned bestDistance = 0xFFFFFFFF; int bestIndex = 0; DockSide bestSide; QRect bestRect; // loop over all widgets and find appropriate matching sides for (int i = 0; i < dockedWidgets.size(); ++i) { DockInfo* d = dockedWidgets[i]; /***************************************************** * Check for placement against the top of the widget * *****************************************************/ if (i == 0 || d->dockSide != BOTTOM) { if (!(rect.left() > d->right() - SNAP_DISTANCE || rect.right() < d->left + SNAP_DISTANCE) && isClose(rect.bottom(), d->top)) { // rectangle is close to the edge unsigned dist = 8 * abs(rect.bottom() - d->top); // now find all points on this side // (use set as a sorted unique list) QSet sidePoints; for (int j = 0; j <= i; ++j) { DockInfo* d2 = dockedWidgets[j]; if (d->top == d2->top) { sidePoints.insert(d2->left); sidePoints.insert(d2->right()); // check if any other widget rest against this side for (int k = i + 1; k < dockedWidgets.size(); ++k) { DockInfo* d3 = dockedWidgets[k]; if (d3->bottom() == d2->top) { sidePoints.insert(d3->left); sidePoints.insert(d3->right()); } } } } // widget placement can occur at all points, find the closest QSet::iterator it = sidePoints.begin(); for (int j = 0; j < sidePoints.size() - 1; ++j) { // check after point unsigned newDist1 = dist + abs(*it - rect.left()); if (newDist1 < bestDistance && isClose(*it, rect.left())) { QRect r(QPoint(*it, d->top - rect.height()), rect.size()); if (!overlaysWithFirstNWidgets(r, i)) { bestDistance = newDist1; bestIndex = i + 1; bestSide = TOP; bestRect = r; } } ++it; // check before point unsigned newDist2 = dist + abs(*it - rect.right()); if (newDist2 < bestDistance && isClose(*it, rect.right())) { QRect r(QPoint(*it - rect.width(), d->top - rect.height()), rect.size()); if (!overlaysWithFirstNWidgets(r, i)) { bestDistance = newDist2; bestIndex = i + 1; bestSide = TOP; bestRect = r; } } } // check for resized placement options if (sizePol.horizontalPolicy() != QSizePolicy::Fixed) { int mid = rect.left() + rect.width() / 2; for (QSet::iterator ita = sidePoints.begin() + 1; ita != sidePoints.end(); ++ita) { for (QSet::iterator itb = sidePoints.begin(); ita != itb; ++itb) { int sp_mid = (*ita + *itb) / 2; int sp_diff = *ita - *itb; if (isClose(sp_mid, mid)) { QRect r(*itb, d->top - rect.height(), sp_diff, rect.height()); if (!overlaysWithFirstNWidgets(r, i)) { bestDistance = dist + abs(sp_mid - mid); bestIndex = i + 1; bestSide = TOP; bestRect = r; } } } } } } } /******************************************************** * Check for placement against the bottom of the widget * ********************************************************/ if (i == 0 || d->dockSide != TOP) { if (!(rect.left() > d->right() - SNAP_DISTANCE || rect.right() < d->left + SNAP_DISTANCE) && isClose(rect.top(), d->bottom())) { // rectangle is close to the edge unsigned dist = 8 * abs(rect.top() - d->bottom()); // now find all points on this side // (use set as a sorted unique list) QSet sidePoints; for (int j = 0; j <= i; ++j) { DockInfo* d2 = dockedWidgets[j]; if (d->bottom() == d2->bottom()) { sidePoints.insert(d2->left); sidePoints.insert(d2->right()); // check if any other widget rest against this side for (int k = i + 1; k < dockedWidgets.size(); ++k) { DockInfo* d3 = dockedWidgets[k]; if (d3->top == d2->bottom()) { sidePoints.insert(d3->left); sidePoints.insert(d3->right()); } } } } // widget placement can occur at all points, find the closest QSet::iterator it = sidePoints.begin(); for (int j = 0; j < sidePoints.size() - 1; ++j) { // check after point unsigned newDist1 = dist + abs(*it - rect.left()); if (newDist1 < bestDistance && isClose(*it, rect.left())) { QRect r(QPoint(*it, d->bottom()), rect.size()); if (!overlaysWithFirstNWidgets(r, i)) { bestDistance = newDist1; bestIndex = i + 1; bestSide = BOTTOM; bestRect = r; } } ++it; // check before point unsigned newDist2 = dist + abs(*it - rect.right()); if (newDist2 < bestDistance && isClose(*it, rect.right())) { QRect r(QPoint(*it - rect.width(), d->bottom()), rect.size()); if (!overlaysWithFirstNWidgets(r, i)) { bestDistance = newDist2; bestIndex = i + 1; bestSide = BOTTOM; bestRect = r; } } } // check for resized placement options if (sizePol.horizontalPolicy() != QSizePolicy::Fixed) { int mid = rect.left() + rect.width() / 2; for (QSet::iterator ita = sidePoints.begin() + 1; ita != sidePoints.end(); ++ita) { for (QSet::iterator itb = sidePoints.begin(); ita != itb; ++itb) { int sp_mid = (*ita + *itb) / 2; int sp_diff = *ita - *itb; if (isClose(sp_mid, mid)) { QRect r(*itb, d->bottom(), sp_diff, rect.height()); if (!overlaysWithFirstNWidgets(r, i)) { bestDistance = dist + abs(sp_mid - mid); bestIndex = i + 1; bestSide = BOTTOM; bestRect = r; } } } } } } } /****************************************************** * Check for placement against the left of the widget * ******************************************************/ if (i == 0 || d->dockSide != RIGHT) { if (!(rect.top() > d->bottom() - SNAP_DISTANCE || rect.bottom() < d->top + SNAP_DISTANCE) && isClose(rect.right(), d->left)) { // rectangle is close to the edge unsigned dist = 8 * abs(rect.right() - d->left); // now find all points on this side // (use set as a sorted unique list) QSet sidePoints; for (int j = 0; j <= i; ++j) { DockInfo* d2 = dockedWidgets[j]; if (d->left == d2->left) { sidePoints.insert(d2->top); sidePoints.insert(d2->bottom()); // check if any other widget rest against this side for (int k = i + 1; k < dockedWidgets.size(); ++k) { DockInfo* d3 = dockedWidgets[k]; if (d3->right() == d2->left) { sidePoints.insert(d3->top); sidePoints.insert(d3->bottom()); } } } } // widget placement can occur at all points, find the closest QSet::iterator it = sidePoints.begin(); for (int j = 0; j < sidePoints.size() - 1; ++j) { // check after point unsigned newDist1 = dist + abs(*it - rect.top()); if (newDist1 < bestDistance && isClose(*it, rect.top())) { QRect r(QPoint(d->left - rect.width(), *it), rect.size()); if (!overlaysWithFirstNWidgets(r, i)) { bestDistance = newDist1; bestIndex = i + 1; bestSide = LEFT; bestRect = r; } } ++it; // check before point unsigned newDist2 = dist + abs(*it - rect.bottom()); if (newDist2 < bestDistance && isClose(*it, rect.bottom())) { QRect r(QPoint(d->left - rect.width(), *it - rect.height()), rect.size()); if (!overlaysWithFirstNWidgets(r, i)) { bestDistance = newDist2; bestIndex = i + 1; bestSide = LEFT; bestRect = r; } } } // check for resized placement options if (sizePol.verticalPolicy() != QSizePolicy::Fixed) { int mid = rect.top() + rect.height() / 2; for (QSet::iterator ita = sidePoints.begin() + 1; ita != sidePoints.end(); ++ita) { for (QSet::iterator itb = sidePoints.begin(); ita != itb; ++itb) { int sp_mid = (*ita + *itb) / 2; int sp_diff = *ita - *itb; if (isClose(sp_mid, mid)) { QRect r(d->left - rect.width(), *itb, rect.width(), sp_diff); if (!overlaysWithFirstNWidgets(r, i)) { bestDistance = dist + abs(sp_mid - mid); bestIndex = i + 1; bestSide = LEFT; bestRect = r; } } } } } } } /******************************************************* * Check for placement against the right of the widget * *******************************************************/ if (i == 0 || d->dockSide != LEFT) { if (!(rect.top() > d->bottom() - SNAP_DISTANCE || rect.bottom() < d->top + SNAP_DISTANCE) && isClose(rect.left(), d->right())) { // rectangle is close to the edge unsigned dist = 8 * abs(rect.left() - d->right()); // now find all points on this side // (use set as a sorted unique list) QSet sidePoints; for (int j = 0; j <= i; ++j) { DockInfo* d2 = dockedWidgets[j]; if (d->right() == d2->right()) { sidePoints.insert(d2->top); sidePoints.insert(d2->bottom()); // check if any other widget rest against this side for (int k = i + 1; k < dockedWidgets.size(); ++k) { DockInfo* d3 = dockedWidgets[k]; if (d3->left == d2->right()) { sidePoints.insert(d3->top); sidePoints.insert(d3->bottom()); } } } } // widget placement can occur at all points, find the closest QSet::iterator it = sidePoints.begin(); for (int j = 0; j < sidePoints.size() - 1; ++j) { // check after point unsigned newDist1 = dist + abs(*it - rect.top()); if (newDist1 < bestDistance && isClose(*it, rect.top())) { QRect r(QPoint(d->left + d->width, *it), rect.size()); if (!overlaysWithFirstNWidgets(r, i)) { bestDistance = newDist1; bestIndex = i + 1; bestSide = RIGHT; bestRect = r; } } ++it; // check before point unsigned newDist2 = dist + abs(*it - rect.bottom()); if (newDist2 < bestDistance && isClose(*it, rect.bottom())) { QRect r(QPoint(d->right(), *it - rect.height()), rect.size()); if (!overlaysWithFirstNWidgets(r, i)) { bestDistance = newDist2; bestIndex = i + 1; bestSide = RIGHT; bestRect = r; } } } // check for resized placement options if (sizePol.verticalPolicy() != QSizePolicy::Fixed) { int mid = rect.top() + rect.height() / 2; for (QSet::iterator ita = sidePoints.begin() + 1; ita != sidePoints.end(); ++ita) { for (QSet::iterator itb = sidePoints.begin(); ita != itb; ++itb) { int sp_mid = (*ita + *itb) / 2; int sp_diff = *ita - *itb; if (isClose(sp_mid, mid)) { QRect r(d->right(), *itb, rect.width(), sp_diff); if (!overlaysWithFirstNWidgets(r, i)) { bestDistance = dist + abs(sp_mid - mid); bestIndex = i + 1; bestSide = RIGHT; bestRect = r; } } } } } } } } if (bestIndex) { rect = bestRect; index = bestIndex; side = bestSide; return true; } else { return false; } } bool DockableWidgetLayout::insertLocation(QRect& rect, const QSizePolicy& sizePol) { int index; DockSide side; return insertLocation(rect, index, side, sizePol); } void DockableWidgetLayout::getConfig(QStringList& list) { for (int i = 0; i < dockedWidgets.size(); ++i) { DockInfo* d = dockedWidgets.at(i); // string format D [Hidden/Visible] [Side] [Distance] [Width] [Height] QString s("%1 D %2 %3 %4 %5 %6"); s = s.arg(d->widget->id()); if (d->widget->isHidden()) { s = s.arg("H"); } else { s = s.arg("V"); } switch (d->dockSide) { case TOP: s = s.arg("T"); break; case LEFT: s = s.arg("L"); break; case RIGHT: s = s.arg("R"); break; case BOTTOM: s = s.arg("B"); break; } s = s.arg(d->dockDistance); if (d->useHintWidth) { s = s.arg(-1); } else { s = s.arg(d->width); } if (d->useHintHeight) { s = s.arg(-1); } else { s = s.arg(d->height); } list.append(s); } } openmsx-debugger-0.0.0.svn20141006.orig/src/Dasm.h0000644000175000017500000000126612414415132020526 0ustar shevekshevek// $Id$ #ifndef DASM_H #define DASM_H #include #include class SymbolTable; struct MemoryLayout; struct DisasmRow { enum RowType { INSTRUCTION, LABEL }; RowType rowType; unsigned short addr; char numBytes; int infoLine; std::string instr; }; static const DisasmRow DISABLED_ROW = {DisasmRow::INSTRUCTION, 0, 1, 0, "- "}; static const int FIRST_INFO_LINE = 1; static const int LAST_INFO_LINE = -65536; typedef std::vector DisasmLines; void dasm(const unsigned char* membuf, unsigned short startAddr, unsigned short endAddr, DisasmLines& disasm, MemoryLayout *memLayout, SymbolTable *symTable, int currentPC); #endif // DASM_H openmsx-debugger-0.0.0.svn20141006.orig/src/CPURegsViewer.cpp0000644000175000017500000002721112414415132022625 0ustar shevekshevek// $Id$ #include "CPURegsViewer.h" #include "CPURegs.h" #include "CommClient.h" #include "OpenMSXConnection.h" #include #include #include #include CPURegsViewer::CPURegsViewer(QWidget* parent) : QFrame(parent) { // avoid UMR memset(®s, 0, sizeof(regs)); memset(®sChanged, 0, sizeof(regsChanged)); memset(®sModified, 0, sizeof(regsModified)); setFrameStyle(WinPanel | Sunken); setFocusPolicy(Qt::StrongFocus); setBackgroundRole(QPalette::Base); setSizePolicy(QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed)); frameR = frameL = frameT = frameB = frameWidth(); cursorLoc = -1; } void CPURegsViewer::resizeEvent(QResizeEvent* e) { QFrame::resizeEvent(e); } void CPURegsViewer::paintEvent(QPaintEvent* e) { // call parent for drawing the actual frame QFrame::paintEvent(e); QPainter p(this); p.setPen(palette().color(QPalette::Text)); rowHeight = fontMetrics().height(); int regWidth = fontMetrics().width("HLW"); int valWidth = fontMetrics().width("FFFFWW"); int d = fontMetrics().descent(); leftRegPos = frameL + 4; leftValuePos = leftRegPos + regWidth; rightRegPos = leftValuePos + valWidth; rightValuePos = rightRegPos + regWidth; // calc and set drawing bounds QRect r(e->rect()); if (r.left() < frameL) r.setLeft(frameL); if (r.top() < frameT) r.setTop (frameT); if (r.right() > (width() - frameR - 1)) r.setRight (width() - frameR - 1); if (r.bottom() > (height() - frameB - 1)) r.setBottom(height() - frameB - 1); p.setClipRect(r); // redraw background p.fillRect(r, palette().color(QPalette::Base)); int y = frameT + rowHeight - 1 - d; for (int r = 0; r < 14; r += 2) { p.drawText(leftRegPos, y, CpuRegs::regNames[r + 0]); drawValue(p, r + 0, leftValuePos, y); p.drawText(rightRegPos, y, CpuRegs::regNames[r + 1]); drawValue(p, r + 1, rightValuePos, y); y += rowHeight; } // draw interrupt mode p.drawText(leftRegPos, y, "IM"); drawValue(p, 14, leftValuePos, y); // draw interrupt state if (regsChanged[CpuRegs::REG_IFF] & 1) { p.setPen(Qt::red); } p.drawText(rightRegPos, y, regs[CpuRegs::REG_IFF] ? "EI" : "DI"); } QSize CPURegsViewer::sizeHint() const { return QSize(frameL + 4 + fontMetrics().width("HLWFFFFWWHLWFFFFW") + 4 + frameR, frameT + 8 * fontMetrics().height() + frameB ); } void CPURegsViewer::drawValue(QPainter& p, int id, int x, int y) { // determine value colour QColor penClr = palette().color(QPalette::Text); if (regsModified[id]) { penClr = Qt::darkGreen; } else if (regsChanged[id]) { penClr = Qt::red; } // print (edit) value if ((cursorLoc >> 2) == id) { // cursor is in this value, print separate digits int digit = 3; if (id < CpuRegs::REG_I) { digit = 0; } else if (id < CpuRegs::REG_IM) { digit = 2; } // write all digit for (/**/; digit < 4; ++digit) { // create string with a single digit QString digitTxt = QString("%1") .arg((regs[id] >> (4 * (3 - digit))) & 15, 0, 16) .toUpper(); // if digit has cursor, draw as cursor if ((cursorLoc & 3) == digit) { // draw curser background QBrush b(palette().color(QPalette::Highlight)); p.fillRect(x, frameT + (cursorLoc >> 3) * rowHeight, fontMetrics().width(digitTxt), rowHeight, b); p.setPen(palette().color(QPalette::HighlightedText)); } else { p.setPen(penClr); } p.drawText(x, y, digitTxt); x += fontMetrics().width(digitTxt); } } else { // regular value print p.setPen(penClr); // create string QString str; if (id < CpuRegs::REG_I) { str.sprintf("%04X", regs[id]); } else if (id < CpuRegs::REG_IM) { str.sprintf("%02X", regs[id]); } else { str.sprintf("%01X", regs[id]); } // draw p.drawText(x, y, str); } // reset pen p.setPen(palette().color(QPalette::Text)); } void CPURegsViewer::setRegister(int id, int value) { regsChanged[id] = regs[id] != value; regs[id] = value; if (regsChanged[id]) { emit registerChanged(id, value); } } void CPURegsViewer::setData(unsigned char* datPtr) { setRegister(CpuRegs::REG_AF , datPtr[ 0] * 256 + datPtr[ 1]); setRegister(CpuRegs::REG_BC , datPtr[ 2] * 256 + datPtr[ 3]); setRegister(CpuRegs::REG_DE , datPtr[ 4] * 256 + datPtr[ 5]); setRegister(CpuRegs::REG_HL , datPtr[ 6] * 256 + datPtr[ 7]); setRegister(CpuRegs::REG_AF2, datPtr[ 8] * 256 + datPtr[ 9]); setRegister(CpuRegs::REG_BC2, datPtr[10] * 256 + datPtr[11]); setRegister(CpuRegs::REG_DE2, datPtr[12] * 256 + datPtr[13]); setRegister(CpuRegs::REG_HL2, datPtr[14] * 256 + datPtr[15]); setRegister(CpuRegs::REG_IX , datPtr[16] * 256 + datPtr[17]); setRegister(CpuRegs::REG_IY , datPtr[18] * 256 + datPtr[19]); setRegister(CpuRegs::REG_PC , datPtr[20] * 256 + datPtr[21]); setRegister(CpuRegs::REG_SP , datPtr[22] * 256 + datPtr[23]); setRegister(CpuRegs::REG_I , datPtr[24]); setRegister(CpuRegs::REG_R , datPtr[25]); setRegister(CpuRegs::REG_IM , datPtr[26]); // IFF separately to only check bit 0 for change regsChanged[CpuRegs::REG_IFF] = (regs[CpuRegs::REG_IFF] & 1) != (datPtr[27] & 1); regs[CpuRegs::REG_IFF] = datPtr[27]; // reset modifications cursorLoc = -1; memset(®sModified, 0, sizeof(regsModified)); memcpy(®sCopy, ®s, sizeof(regs)); update(); emit pcChanged(regs[CpuRegs::REG_PC]); emit spChanged(regs[CpuRegs::REG_SP]); emit flagsChanged(regs[CpuRegs::REG_AF] & 0xFF); } void CPURegsViewer::focusOutEvent(QFocusEvent* e) { if (e->lostFocus()) { cancelModifications(); cursorLoc = -1; update(); } } void CPURegsViewer::mousePressEvent(QMouseEvent* e) { if (e->button() == Qt::LeftButton) { int pos = -1; if (e->x() >= leftValuePos && e->x() < rightRegPos) { pos = 0; } if (e->x() >= rightValuePos) { pos = 4; } if (pos >= 0 && e->y() < frameT + 7 * rowHeight) { int row = (e->y() - frameT) / rowHeight; cursorLoc = pos + 8 * row; if (row == 6) cursorLoc += 2; } update(); } } void CPURegsViewer::keyPressEvent(QKeyEvent* e) { // don't accept when not editting if (cursorLoc < 0) { QFrame::keyPressEvent(e); return; } int move = e->key(); if ((e->key() >= Qt::Key_0 && e->key() <= Qt::Key_9) || (e->key() >= Qt::Key_A && e->key() <= Qt::Key_F) ) { // calculate numercial value int v = e->key() - Qt::Key_0; if (v > 9) v -= Qt::Key_A - Qt::Key_0 - 10; // modify value int id = cursorLoc >> 2; int digit = cursorLoc & 3; regs[id] &= ~(0xF000 >> (4 * digit)); regs[id] |= v << (12 - 4 * digit); regsModified[id] = true; move = Qt::Key_Right; } if (move == Qt::Key_Right) { ++cursorLoc; if (cursorLoc == 4 * CpuRegs::REG_I || cursorLoc == 4 * CpuRegs::REG_R) { cursorLoc += 2; } else if (cursorLoc == 4 * CpuRegs::REG_IM) { cursorLoc = 0; } } else if (move == Qt::Key_Left) { --cursorLoc; if (cursorLoc == -1) { cursorLoc = 4 * CpuRegs::REG_R + 3; } else if (cursorLoc == 4 * CpuRegs::REG_R + 1 || cursorLoc == 4 * CpuRegs::REG_I + 1) { cursorLoc -= 2; } } else if (move == Qt::Key_Up) { cursorLoc -= 8; if (cursorLoc < 0) { cursorLoc += 4 * CpuRegs::REG_IM; // move to lowest row if (cursorLoc == 4 * CpuRegs::REG_I) { cursorLoc = 4 * CpuRegs::REG_I + 2; } else if (cursorLoc < 4 * CpuRegs::REG_R) { cursorLoc = 4 * CpuRegs::REG_I + 3; } else if (cursorLoc == 4 * CpuRegs::REG_R) { cursorLoc = 4 * CpuRegs::REG_R + 2; } else { cursorLoc = 4 * CpuRegs::REG_R + 3; } } else if (cursorLoc >= 4 * CpuRegs::REG_PC) { // move from lowest row cursorLoc -= 2; } } else if (move == Qt::Key_Down) { cursorLoc += 8; if (cursorLoc >= 4 * CpuRegs::REG_IM) { // move from lowest row cursorLoc -= 4 * CpuRegs::REG_IM + 2; } else if (cursorLoc >= 4 * CpuRegs::REG_I) { // move to lowest row if (cursorLoc == 4 * CpuRegs::REG_I) { cursorLoc = 4 * CpuRegs::REG_I + 2; } else if (cursorLoc < 4 * CpuRegs::REG_R) { cursorLoc = 4 * CpuRegs::REG_I + 3; } else if( cursorLoc == 4 * CpuRegs::REG_R) { cursorLoc = 4 * CpuRegs::REG_R + 2; } else { cursorLoc = 4 * CpuRegs::REG_R + 3; } } } else if (move == Qt::Key_Escape) { // cancel changes cancelModifications(); cursorLoc = -1; } else if (move == Qt::Key_Return || move == Qt::Key_Enter) { // apply changes applyModifications(); } else { QFrame::keyPressEvent(e); return; } e->accept(); update(); } //void CPURegsViewer::mouseMoveEvent(QMouseEvent* e) //{ // QToolTip::hideText(); // QFrame::mouseMoveEvent(e); //} int CPURegsViewer::readRegister(int id) { return regs[id]; } void CPURegsViewer::getRegister(int id, unsigned char* data) { data[0] = regs[id] >> 8; data[1] = regs[id] & 255; } void CPURegsViewer::applyModifications() { unsigned char data[26]; getRegister(CpuRegs::REG_AF, &data[ 0]); getRegister(CpuRegs::REG_BC, &data[ 2]); getRegister(CpuRegs::REG_DE, &data[ 4]); getRegister(CpuRegs::REG_HL, &data[ 6]); getRegister(CpuRegs::REG_AF2, &data[ 8]); getRegister(CpuRegs::REG_BC2, &data[10]); getRegister(CpuRegs::REG_DE2, &data[12]); getRegister(CpuRegs::REG_HL2, &data[14]); getRegister(CpuRegs::REG_IX, &data[16]); getRegister(CpuRegs::REG_IY, &data[18]); getRegister(CpuRegs::REG_PC, &data[20]); getRegister(CpuRegs::REG_SP, &data[22]); data[24] = regs[CpuRegs::REG_I]; data[25] = regs[CpuRegs::REG_R]; // send new data to openmsx WriteDebugBlockCommand* req = new WriteDebugBlockCommand( "{CPU regs}", 0, 26, data); CommClient::instance().sendCommand(req); // turn off editing cursorLoc = -1; // update copy for (int i = 0; i < 14; ++i) { if (regsModified[i]) { regsModified[i] = false; regsCopy[i] = regs[i]; regsChanged[i] = true; } } // update screen update(); } void CPURegsViewer::cancelModifications() { bool mod = false; for (int i = 0; i < 14; ++i) mod |= regsModified[i]; if (!mod) return; int ret = QMessageBox::warning( this, tr("CPU registers changes"), tr("You made changes to the CPU registers.\n" "Do you want to apply your changes or ignore them?"), QMessageBox::Apply | QMessageBox::Ignore, QMessageBox::Ignore); if (ret == QMessageBox::Ignore) { memcpy(®s, ®sCopy, sizeof(regs)); memset(®sModified, 0, sizeof(regsModified)); } else { applyModifications(); } } bool CPURegsViewer::event(QEvent* e) { if (e->type() != QEvent::ToolTip) { return QWidget::event(e); } QHelpEvent* helpEvent = static_cast(e); // calc register number int pos = -1; if (helpEvent->x() >= leftValuePos && helpEvent->x() < rightRegPos) { pos = 0; } if (helpEvent->x() >= rightValuePos) { pos = 1; } if (pos >= 0 && helpEvent->y() < frameT + 7 * rowHeight) { pos += 2 * ((helpEvent->y() - frameT) / rowHeight); } if (pos >= 0 && pos != 10 && pos != 11) { // create text with binary and decimal values QString text(CpuRegs::regNames[pos]); text += "\nBinary: "; if (pos < 12) { text += QString("%1 ") .arg((regs[pos] & 0xF000) >> 12, 4, 2, QChar('0')); text += QString("%1 ") .arg((regs[pos] & 0x0F00) >> 8, 4, 2, QChar('0')); } text += " "; text += QString("%1 ").arg((regs[pos] & 0x00F0) >> 4, 4, 2, QChar('0')); text += QString("%1") .arg((regs[pos] & 0x000F) >> 0, 4, 2, QChar('0')); text += "\nDecimal: "; text += QString::number(regs[pos]); // print 8 bit values if (pos < 8) { text += QString("\n%1: %2 %3: %4") .arg(CpuRegs::regNames[pos][0]) .arg(regs[pos] >> 8) .arg(CpuRegs::regNames[pos][1]) .arg(regs[pos] & 255); } else if (pos < 10) { text += QString("\nI%1H: %2 I%3L: %4") .arg(CpuRegs::regNames[pos][1]) .arg(regs[pos] >> 8) .arg(CpuRegs::regNames[pos][1]) .arg(regs[pos] & 255); } QToolTip::showText(helpEvent->globalPos(), text); } else { QToolTip::hideText(); } return QWidget::event(e); } openmsx-debugger-0.0.0.svn20141006.orig/src/main.cpp0000644000175000017500000000106612414415132021117 0ustar shevekshevek// $Id$ #include "DebuggerForm.h" #include "Settings.h" #include #include int main(int argc, char** argv) { QApplication app(argc, argv); // Don't set the icon on OS X, because it will replace the high-res version // with a lower resolution one, even though openMSX-debugger-logo-256.png is 256x256. #ifndef __APPLE__ app.setWindowIcon(QIcon(":icons/openMSX-debugger-logo-256.png")); #endif // restore main settings app.setFont(Settings::get().font(Settings::APP_FONT)); DebuggerForm debugger; debugger.show(); return app.exec(); } openmsx-debugger-0.0.0.svn20141006.orig/src/VDPCommandRegViewer.h0000644000175000017500000000702312414415132023407 0ustar shevekshevek#ifndef VDPCOMMANDREGVIEWER_H #define VDPCOMMANDREGVIEWER_H #include "SimpleHexRequest.h" #include "ui_VDPCommandRegisters.h" #include class view88to16 : public QObject { Q_OBJECT public: view88to16(QWidget* a, QWidget* b, QWidget* c) { rl = rh = rw = -1; disp_rl = disp_rh = 1; disp_rw = 2; w_rl = a; w_rh = b; w_rw = c; } int getRL() const { return rl; } int getRH() const { return rh; } int getRW() const { return rw; } void setDispRL(int mode) { disp_rl = mode; } void setDispRH(int mode) { disp_rh = mode; } void setDispRW(int mode) { disp_rw = mode; } void setWidgetRL(QWidget* wdgt) { w_rl = wdgt; } void setWidgetRH(QWidget* wdgt) { w_rh = wdgt; } void setWidgetRW(QWidget* wdgt) { w_rw = wdgt; } public slots: void finishRH() { setRH(getWidgetText(w_rh)); } void finishRL() { setRL(getWidgetText(w_rl)); } void finishRW() { setRW(getWidgetText(w_rw)); } void setRH(const QString& newval) { bool ok; int val = newval.toInt(&ok, 0) & 0xFF; if (!ok || (val == rh)) return; rh = val; updaterw(); updaterh(); } void setRL(const QString& newval) { bool ok; int val = newval.toInt(&ok, 0) & 0xFF; if (!ok || (val == rl)) return; rl = val; updaterw(); updaterl(); } void setRW(const QString& newval) { //TODO: build a split-in-two method bool ok; int val = newval.toInt(&ok, 0) & 0xFFFF; if (!ok || (val == rw)) return; rw = val; updaterl(); updaterh(); updaterw(); } private: int rh; int rl; int rw; int disp_rw; int disp_rl; int disp_rh; QWidget* w_rh; QWidget* w_rl; QWidget* w_rw; QString convert(int val, int mode) { if (mode & 1) { return QString("0x%1").arg(val, 2, 16, QChar('0')); } else { return QString("%1").arg(val); } } QString getWidgetText(QWidget* wdg) { if (wdg == NULL) return QString(); if (QLabel* ql = dynamic_cast(wdg)) { return ql->text(); } else { QLineEdit* qe = dynamic_cast(wdg); return qe->text(); } } void updateWidget(QWidget* wdg, int val, int mode) { if (QLabel* ql = dynamic_cast(wdg)) { ql->setText(convert(val, mode)); } else { QLineEdit* qe = dynamic_cast(wdg); qe->setText(convert(val, mode)); } } void updaterw() { if (w_rw == NULL) return; rw = rl + 256 * rh; updateWidget(w_rw, rw, disp_rw); } void updaterl() { if (w_rl == NULL) return; rl = rw & 255; updateWidget(w_rl, rl, disp_rl); } void updaterh() { if (w_rh == NULL) return; rh = (rw >> 8) & 255; updateWidget(w_rh, rh, disp_rh); } }; class VDPCommandRegViewer : public QDialog, public SimpleHexRequestUser, private Ui::VDPCmdRegs { Q_OBJECT public: VDPCommandRegViewer(QWidget* parent = 0); ~VDPCommandRegViewer(); private: virtual void DataHexRequestReceived(); void decodeR46(int val); void syncRegToCmd(); unsigned char* regs; unsigned char* statusregs; view88to16* grp_l_sx; view88to16* grp_l_sy; view88to16* grp_l_dx; view88to16* grp_l_dy; view88to16* grp_l_nx; view88to16* grp_l_ny; view88to16* grp_sx; view88to16* grp_sy; view88to16* grp_dx; view88to16* grp_dy; view88to16* grp_nx; view88to16* grp_ny; int R46; public slots: void refresh(); void R45BitChanged(int); void on_lineEdit_r44_editingFinished(); void on_lineEdit_r45_editingFinished(); void on_lineEdit_r46_editingFinished(); void on_comboBox_cmd_currentIndexChanged(int index); void on_comboBox_operator_currentIndexChanged(int index); void on_syncPushButton_clicked(); void on_launchPushButton_clicked(); }; #endif /* VDPCOMMANDREGVIEWER_H */ openmsx-debugger-0.0.0.svn20141006.orig/src/InteractiveButton.h0000644000175000017500000000133412414415132023307 0ustar shevekshevek#ifndef INTERACTIVEBUTTON #define INTERACTIVEBUTTON #include class InteractiveButton : public QPushButton { Q_OBJECT public: InteractiveButton(QWidget* parent = 0); protected: virtual void enterEvent(QEvent* event); virtual void leaveEvent(QEvent* event); signals: void mouseOver(bool state); // this one is specific for the VDPRegViewer and depends on the // name of the button also void newBitValue(int reg, int bit, bool state); public slots: void highlight(bool state); void mustBeSet(bool state); private slots: // this one is specific for the VDPRegViewer void newBitValueSlot(bool); private: void setColor(); bool _mustBeSet; bool _highlight; bool _state; }; #endif // INTERACTIVEBUTTON openmsx-debugger-0.0.0.svn20141006.orig/src/InteractiveLabel.h0000644000175000017500000000057112414415132023055 0ustar shevekshevek#ifndef INTERACTIVELABEL #define INTERACTIVELABEL #include class InteractiveLabel : public QLabel { Q_OBJECT public: InteractiveLabel(QWidget* parent = 0); protected: virtual void enterEvent(QEvent* event); virtual void leaveEvent(QEvent* event); signals: void mouseOver(bool state); public slots: void highlight(bool state); }; #endif // INTERACTIVELABEL openmsx-debugger-0.0.0.svn20141006.orig/src/SymbolManager.ui0000644000175000017500000004740212414415132022572 0ustar shevekshevek SymbolManager 0 0 760 577 Symbol Manager false true 0 Symbol files Loaded symbol files: QAbstractItemView::ExtendedSelection false false true File Last refresh Add Remove Qt::Vertical 20 40 Address labels Address labels: Add Remove Qt::Vertical 20 40 QAbstractItemView::ExtendedSelection false true false true true Symbol Type Value Slots Segments Registers Source 0 0 0 Locations 0 0 Active slots 0-0 0-1 0-2 0-3 1-0 1-1 1-2 1-3 2-0 2-1 2-2 2-3 3-0 3-1 3-2 3-3 0 0 Active segments 0 0 Usage Symbol type Jump label Variable label Value 8 bit registers 16 A I Offset value B C D E IXH IXL H L IYH IYL 16 bit registers BC DE HL IX IY Qt::Horizontal 40 20 Reload all Close btnClose clicked() SymbolManager close() 571 420 233 29 openmsx-debugger-0.0.0.svn20141006.orig/src/DockManager.cpp0000644000175000017500000000402212414415132022341 0ustar shevekshevek// $Id$ #include "DockManager.h" #include "DockableWidget.h" #include "DockableWidgetArea.h" void DockManager::addDockArea(DockableWidgetArea* area) { if (areas.indexOf(area) == -1) { areas.append(area); } } int DockManager::dockAreaIndex(DockableWidgetArea* area) const { return areas.indexOf(area); } void DockManager::dockWidget(DockableWidget* widget, const QPoint& p, const QRect& r) { AreaMap::iterator it = areaMap.begin(); // TODO if (it != areaMap.end()) { areaMap[widget] = it.value(); return it.value()->addWidget(widget, r); } } void DockManager::undockWidget(DockableWidget* widget) { AreaMap::iterator it = areaMap.find(widget); if (it != areaMap.end()) { it.value()->removeWidget(widget); } } void DockManager::insertWidget( DockableWidget* widget, int index, DockableWidgetLayout::DockSide side, int distance, int w, int h) { if (index < 0 || index >= areas.size()) return; //Q_ASSERT(areaMap.find(widget) == areaMap.end()); areas[index]->addWidget(widget, side, distance, w, h); areaMap[widget] = areas[index]; } bool DockManager::insertLocation(QRect& r, const QSizePolicy& sizePol) { AreaMap::iterator it = areaMap.begin(); // TODO if (it == areaMap.end()) return false; return it.value()->insertLocation(r, sizePol); } void DockManager::visibilityChanged(DockableWidget* widget) { AreaMap::iterator it = areaMap.find(widget); if (it != areaMap.end()) { it.value()->layout->changed(); } } void DockManager::getConfig(int index, QStringList& list) const { areas[index]->getConfig(list); } void DockManager::attachWidget(DockableWidget* widget) { dockWidgets.append(widget); } void DockManager::detachWidget(DockableWidget* widget) { dockWidgets.removeAll(widget); } const QList& DockManager::managedWidgets() const { return dockWidgets; } DockableWidget* DockManager::findDockableWidget(const QString& id) const { for (QList::const_iterator it = dockWidgets.begin(); it != dockWidgets.end(); ++it) { if ((*it)->id() == id) return *it; } return 0; } openmsx-debugger-0.0.0.svn20141006.orig/src/BreakpointDialog.h0000644000175000017500000000217512414415132023060 0ustar shevekshevek#ifndef BREAKPOINTDIALOG_OPENMSX_H #define BREAKPOINTDIALOG_OPENMSX_H #include "ui_BreakpointDialog.h" #include "DebuggerData.h" #include struct MemoryLayout; class DebugSession; class Symbol; class BreakpointDialog : public QDialog, private Ui::BreakpointDialog { Q_OBJECT public: BreakpointDialog(const MemoryLayout& ml, DebugSession *session = 0, QWidget* parent = 0); ~BreakpointDialog(); Breakpoints::Type type(); int address(); int addressEndRange(); int slot(); int subslot(); int segment(); QString condition(); void setData(Breakpoints::Type type, int address = -1, int ps = -1, int ss = -1, int segment = -1, int addressEnd = -1, QString condition = QString()); private: const MemoryLayout& memLayout; DebugSession *debugSession; Symbol *currentSymbol; int idxSlot, idxSubSlot; int value, valueEnd; int conditionHeight; QCompleter *jumpCompleter, *allCompleter; private slots: void addressChanged(const QString& text); void typeChanged(int i); void slotChanged(int i); void subslotChanged(int i); void hasCondition(int state); }; #endif // BREAKPOINTDIALOG_OPENMSX_H openmsx-debugger-0.0.0.svn20141006.orig/src/DebugSession.cpp0000644000175000017500000000554612414415132022574 0ustar shevekshevek// $Id$ #include "DebugSession.h" #include #include #include #include DebugSession::DebugSession() : modified(false) { } bool DebugSession::existsAsFile() const { return !fileName.isEmpty(); } const QString& DebugSession::filename() const { return fileName; } bool DebugSession::isModified() const { if(fileName.isEmpty() && symTable.size() == 0) return false; else return modified; } Breakpoints& DebugSession::breakpoints() { return breaks; } SymbolTable& DebugSession::symbolTable() { return symTable; } void DebugSession::clear() { // clear everything symTable.clear(); breaks.clear(); fileName.clear(); modified = false; } void DebugSession::open(const QString& file) { QFile f(file); if (!f.open(QFile::ReadOnly | QFile::Text)) { QMessageBox::warning(0, tr("Open session ..."), tr("Cannot read file %1:\n%2.") .arg(file) .arg(f.errorString())); return; } // clear current project and start reading xml file clear(); QXmlStreamReader ses; ses.setDevice(&f); while (!ses.atEnd()) { ses.readNext(); if (ses.isStartElement() && (ses.name() == "DebugSession")) { // debug session data while (!ses.atEnd()) { ses.readNext(); // end tag if (ses.isEndElement()) break; // begin tag if (ses.isStartElement()) { if (ses.name() == "Symbols") { symTable.loadSymbols(ses); } else if (ses.name() == "Breakpoints") { breaks.loadBreakpoints(ses); } else { skipUnknownElement(ses); } } } } } fileName = file; modified = false; } void DebugSession::skipUnknownElement(QXmlStreamReader& ses) { while (!ses.atEnd()) { ses.readNext(); if (ses.isEndElement()) break; if (ses.isStartElement()) skipUnknownElement(ses); } } bool DebugSession::save() { return saveAs(fileName); } bool DebugSession::saveAs(const QString& newFileName) { // open file for save QFile file(newFileName); if (!file.open(QFile::WriteOnly | QFile::Text)) { QMessageBox::warning(0, tr("Save session ..."), tr("Cannot write file %1:\n%2.") .arg(fileName) .arg(file.errorString())); return false; } // start xml file QXmlStreamWriter ses; ses.setDevice(&file); ses.setAutoFormatting(true); ses.writeDTD(""); ses.writeStartElement("DebugSession"); ses.writeAttribute("version", "0.1"); // write symbols ses.writeStartElement("Symbols"); symTable.saveSymbols(ses); ses.writeEndElement(); // write breakpoints ses.writeStartElement("Breakpoints"); breaks.saveBreakpoints(ses); ses.writeEndElement(); // end ses.writeEndDocument(); modified = false; fileName = newFileName; // only set after successful save return true; } void DebugSession::sessionModified() { modified = true; } openmsx-debugger-0.0.0.svn20141006.orig/src/DebuggerForm.cpp0000644000175000017500000012673712414415132022560 0ustar shevekshevek// $Id$ #include "DebuggerForm.h" #include "BitMapViewer.h" #include "DockableWidgetArea.h" #include "DockableWidget.h" #include "DisasmViewer.h" #include "MainMemoryViewer.h" #include "CPURegsViewer.h" #include "FlagsViewer.h" #include "StackViewer.h" #include "SlotViewer.h" #include "CommClient.h" #include "ConnectDialog.h" #include "SymbolManager.h" #include "PreferencesDialog.h" #include "BreakpointDialog.h" #include "GotoDialog.h" #include "DebuggableViewer.h" #include "VDPRegViewer.h" #include "VDPStatusRegViewer.h" #include "VDPCommandRegViewer.h" #include "Settings.h" #include "Version.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include class QueryPauseHandler : public SimpleCommand { public: QueryPauseHandler(DebuggerForm& form_) : SimpleCommand("set pause") , form(form_) { } virtual void replyOk(const QString& message) { // old openmsx versions returned 'on','false' // new versions return 'true','false' // so check for 'false' bool checked = message.trimmed() != "false"; form.systemPauseAction->setChecked(checked); delete this; } private: DebuggerForm& form; }; class QueryBreakedHandler : public SimpleCommand { public: QueryBreakedHandler(DebuggerForm& form_) : SimpleCommand("debug breaked") , form(form_) { } virtual void replyOk(const QString& message) { form.finalizeConnection(message.trimmed() == "1"); delete this; } private: DebuggerForm& form; }; class ListBreakPointsHandler : public SimpleCommand { public: ListBreakPointsHandler(DebuggerForm& form_, bool merge_ = false) : SimpleCommand("debug_list_all_breaks") , form(form_), merge(merge_) { } virtual void replyOk(const QString& message) { if (merge) { QString bps = form.session.breakpoints().mergeBreakpoints(message); if (!bps.isEmpty()) { form.comm.sendCommand(new SimpleCommand(bps)); form.comm.sendCommand(new ListBreakPointsHandler(form, false)); } else { form.disasmView->update(); form.session.sessionModified(); form.updateWindowTitle(); } } else { form.session.breakpoints().setBreakpoints(message); form.disasmView->update(); form.session.sessionModified(); form.updateWindowTitle(); } delete this; } private: DebuggerForm& form; bool merge; }; class CPURegRequest : public ReadDebugBlockCommand { public: CPURegRequest(DebuggerForm& form_) : ReadDebugBlockCommand("{CPU regs}", 0, 28, buf) , form(form_) { } virtual void replyOk(const QString& message) { copyData(message); form.regsView->setData(buf); delete this; } private: DebuggerForm& form; unsigned char buf[28]; }; class ListDebuggablesHandler : public SimpleCommand { public: ListDebuggablesHandler(DebuggerForm& form_) : SimpleCommand("debug list") , form(form_) { } virtual void replyOk(const QString& message) { form.setDebuggables(message); delete this; } private: DebuggerForm& form; }; class DebuggableSizeHandler : public SimpleCommand { public: DebuggableSizeHandler(const QString& debuggable_, DebuggerForm& form_) : SimpleCommand(QString("debug size %1").arg(debuggable_)) , debuggable(debuggable_) , form(form_) { } virtual void replyOk(const QString& message) { form.setDebuggableSize(debuggable, message.toInt()); delete this; } private: QString debuggable; DebuggerForm& form; }; DebuggerForm::DebuggerForm(QWidget* parent) : QMainWindow(parent) , comm(CommClient::instance()) { VDPRegView = NULL; VDPStatusRegView = NULL; VDPCommandRegView = NULL; createActions(); createMenus(); createToolbars(); createStatusbar(); createForm(); recentFiles = Settings::get().value("MainWindow/RecentFiles").toStringList(); updateRecentFiles(); connect(&session.symbolTable(), SIGNAL(symbolFileChanged()), this, SLOT(symbolFileChanged())); } void DebuggerForm::createActions() { fileNewSessionAction = new QAction(tr("&New Session"), this); fileNewSessionAction->setStatusTip(tr("Clear the current session.")); fileOpenSessionAction = new QAction(tr("&Open Session ..."), this); fileOpenSessionAction->setShortcut(tr("Ctrl+O")); fileOpenSessionAction->setStatusTip(tr("Clear the current session.")); fileSaveSessionAction = new QAction(tr("&Save Session"), this); fileSaveSessionAction->setShortcut(tr("Ctrl+S")); fileSaveSessionAction->setStatusTip(tr("Save the the current debug session")); fileSaveSessionAsAction = new QAction(tr("Save Session &As"), this); fileSaveSessionAsAction->setStatusTip(tr("Save the debug session in a selected file")); fileQuitAction = new QAction(tr("&Quit"), this); fileQuitAction->setShortcut(tr("Ctrl+Q")); fileQuitAction->setStatusTip(tr("Quit the openMSX debugger")); for (int i = 0; i < MaxRecentFiles; ++i) { recentFileActions[i] = new QAction(this); connect(recentFileActions[i], SIGNAL(triggered()), this, SLOT(fileRecentOpen())); } systemConnectAction = new QAction(tr("&Connect"), this); systemConnectAction->setShortcut(tr("Ctrl+C")); systemConnectAction->setStatusTip(tr("Connect to openMSX")); systemConnectAction->setIcon(QIcon(":/icons/connect.png")); systemDisconnectAction = new QAction(tr("&Disconnect"), this); systemDisconnectAction->setShortcut(tr("")); systemDisconnectAction->setStatusTip(tr("Disconnect from openMSX")); systemDisconnectAction->setIcon(QIcon(":/icons/disconnect.png")); systemDisconnectAction->setEnabled(false); systemPauseAction = new QAction(tr("&Pause emulator"), this); systemPauseAction->setShortcut(Qt::Key_Pause); systemPauseAction->setStatusTip(tr("Pause the emulation")); systemPauseAction->setIcon(QIcon(":/icons/pause.png")); systemPauseAction->setCheckable(true); systemPauseAction->setEnabled(false); systemRebootAction = new QAction(tr("&Reboot emulator"), this); systemRebootAction->setStatusTip(tr("Reboot the emulation and start if needed")); systemRebootAction->setEnabled(false); systemSymbolManagerAction = new QAction(tr("&Symbol manager ..."), this); systemSymbolManagerAction->setStatusTip(tr("Start the symbol manager")); systemSymbolManagerAction->setIcon(QIcon(":/icons/symmanager.png")); systemPreferencesAction = new QAction(tr("Pre&ferences ..."), this); systemPreferencesAction->setStatusTip(tr("Set the global debugger preferences")); searchGotoAction = new QAction(tr("&Goto ..."), this); searchGotoAction->setStatusTip(tr("Jump to a specific address or label in the disassembly view")); searchGotoAction->setShortcut(tr("Ctrl+G")); viewRegistersAction = new QAction(tr("CPU &Registers"), this); viewRegistersAction->setStatusTip(tr("Toggle the cpu registers display")); viewRegistersAction->setCheckable(true); viewFlagsAction = new QAction(tr("CPU &Flags"), this); viewFlagsAction->setStatusTip(tr("Toggle the cpu flags display")); viewFlagsAction->setCheckable(true); viewStackAction = new QAction(tr("Stack"), this); viewStackAction->setStatusTip(tr("Toggle the stack display")); viewStackAction->setCheckable(true); viewSlotsAction = new QAction(tr("Slots"), this); viewSlotsAction->setStatusTip(tr("Toggle the slots display")); viewSlotsAction->setCheckable(true); viewMemoryAction = new QAction(tr("Memory"), this); viewMemoryAction->setStatusTip(tr("Toggle the main memory display")); viewMemoryAction->setCheckable(true); viewDebuggableViewerAction = new QAction(tr("Add debuggable viewer"), this); viewDebuggableViewerAction->setStatusTip(tr("Add a hex viewer for debuggables")); viewVDPStatusRegsAction = new QAction(tr("Status Registers"), this); viewVDPStatusRegsAction->setStatusTip(tr("The VDP status registers interpreted")); viewVDPStatusRegsAction->setCheckable(true); viewVDPCommandRegsAction = new QAction(tr("Command Registers"), this); viewVDPCommandRegsAction->setStatusTip(tr("Interact with the VDP command registers")); viewVDPCommandRegsAction->setCheckable(true); viewVDPRegsAction = new QAction(tr("Registers"), this); viewVDPRegsAction->setStatusTip(tr("Interact with the VDP registers")); viewVDPRegsAction->setCheckable(true); viewBitMappedAction = new QAction(tr("Bitmapped VRAM"), this); viewBitMappedAction->setStatusTip(tr("Decode VRAM as screen 5/6/7/8 image")); //viewBitMappedAction->setCheckable(true); executeBreakAction = new QAction(tr("Break"), this); executeBreakAction->setShortcut(tr("CRTL+B")); executeBreakAction->setStatusTip(tr("Halt the execution and enter debug mode")); executeBreakAction->setIcon(QIcon(":/icons/break.png")); executeBreakAction->setEnabled(false); executeRunAction = new QAction(tr("Run"), this); executeRunAction->setShortcut(tr("F9")); executeRunAction->setStatusTip(tr("Leave debug mode and resume execution")); executeRunAction->setIcon(QIcon(":/icons/run.png")); executeRunAction->setEnabled(false); executeStepAction = new QAction(tr("Step into"), this); executeStepAction->setShortcut(tr("F7")); executeStepAction->setStatusTip(tr("Execute a single instruction")); executeStepAction->setIcon(QIcon(":/icons/stepinto.png")); executeStepAction->setEnabled(false); executeStepOverAction = new QAction(tr("Step over"), this); executeStepOverAction->setShortcut(tr("F8")); executeStepOverAction->setStatusTip(tr("Execute the next instruction including any called subroutines")); executeStepOverAction->setIcon(QIcon(":/icons/stepover.png")); executeStepOverAction->setEnabled(false); executeStepOutAction = new QAction(tr("Step out"), this); executeStepOutAction->setShortcut(tr("F11")); executeStepOutAction->setStatusTip(tr("Resume execution until the current routine has finished")); executeStepOutAction->setIcon(QIcon(":/icons/stepout.png")); executeStepOutAction->setEnabled(false); executeStepBackAction = new QAction(tr("Step back"), this); executeStepBackAction->setShortcut(tr("F12")); executeStepBackAction->setStatusTip(tr("Reverse the last instruction")); executeStepBackAction->setIcon(QIcon(":/icons/stepback.png")); executeStepBackAction->setEnabled(false); executeRunToAction = new QAction(tr("Run to"), this); executeRunToAction->setShortcut(tr("F4")); executeRunToAction->setStatusTip(tr("Resume execution until the selected line is reached")); executeRunToAction->setIcon(QIcon(":/icons/runto.png")); executeRunToAction->setEnabled(false); breakpointToggleAction = new QAction(tr("Toggle"), this); breakpointToggleAction->setShortcut(tr("F5")); breakpointToggleAction->setStatusTip(tr("Toggle breakpoint on/off at cursor")); breakpointToggleAction->setIcon(QIcon(":/icons/break.png")); breakpointToggleAction->setEnabled(false); breakpointAddAction = new QAction(tr("Add ..."), this); breakpointAddAction->setShortcut(tr("CTRL+B")); breakpointAddAction->setStatusTip(tr("Add a breakpoint at a location")); breakpointAddAction->setEnabled(false); helpAboutAction = new QAction(tr("&About"), this); executeRunToAction->setStatusTip(tr("Show the appliction information")); connect(fileNewSessionAction, SIGNAL(triggered()), this, SLOT(fileNewSession())); connect(fileOpenSessionAction, SIGNAL(triggered()), this, SLOT(fileOpenSession())); connect(fileSaveSessionAction, SIGNAL(triggered()), this, SLOT(fileSaveSession())); connect(fileSaveSessionAsAction, SIGNAL(triggered()), this, SLOT(fileSaveSessionAs())); connect(fileQuitAction, SIGNAL(triggered()), this, SLOT(close())); connect(systemConnectAction, SIGNAL(triggered()), this, SLOT(systemConnect())); connect(systemDisconnectAction, SIGNAL(triggered()), this, SLOT(systemDisconnect())); connect(systemPauseAction, SIGNAL(triggered()), this, SLOT(systemPause())); connect(systemRebootAction, SIGNAL(triggered()), this, SLOT(systemReboot())); connect(systemSymbolManagerAction, SIGNAL(triggered()), this, SLOT(systemSymbolManager())); connect(systemPreferencesAction, SIGNAL(triggered()), this, SLOT(systemPreferences())); connect(searchGotoAction, SIGNAL(triggered()), this, SLOT(searchGoto())); connect(viewRegistersAction, SIGNAL(triggered()), this, SLOT(toggleRegisterDisplay())); connect(viewFlagsAction, SIGNAL(triggered()), this, SLOT(toggleFlagsDisplay())); connect(viewStackAction, SIGNAL(triggered()), this, SLOT(toggleStackDisplay())); connect(viewSlotsAction, SIGNAL(triggered()), this, SLOT(toggleSlotsDisplay())); connect(viewMemoryAction, SIGNAL(triggered()), this, SLOT(toggleMemoryDisplay())); connect(viewDebuggableViewerAction, SIGNAL(triggered()), this, SLOT(addDebuggableViewer())); connect(viewBitMappedAction, SIGNAL(triggered()), this, SLOT(toggleBitMappedDisplay())); connect(viewVDPRegsAction, SIGNAL(triggered()), this, SLOT(toggleVDPRegsDisplay())); connect(viewVDPCommandRegsAction, SIGNAL(triggered()), this, SLOT(toggleVDPCommandRegsDisplay())); connect(viewVDPStatusRegsAction, SIGNAL(triggered()), this, SLOT(toggleVDPStatusRegsDisplay())); connect(executeBreakAction, SIGNAL(triggered()), this, SLOT(executeBreak())); connect(executeRunAction, SIGNAL(triggered()), this, SLOT(executeRun())); connect(executeStepAction, SIGNAL(triggered()), this, SLOT(executeStep())); connect(executeStepOverAction, SIGNAL(triggered()), this, SLOT(executeStepOver())); connect(executeRunToAction, SIGNAL(triggered()), this, SLOT(executeRunTo())); connect(executeStepOutAction, SIGNAL(triggered()), this, SLOT(executeStepOut())); connect(executeStepBackAction, SIGNAL(triggered()), this, SLOT(executeStepBack())); connect(breakpointToggleAction, SIGNAL(triggered()), this, SLOT(breakpointToggle())); connect(breakpointAddAction, SIGNAL(triggered()), this, SLOT(breakpointAdd())); connect(helpAboutAction, SIGNAL(triggered()), this, SLOT(showAbout())); } void DebuggerForm::createMenus() { // create file menu fileMenu = menuBar()->addMenu(tr("&File")); fileMenu->addAction(fileNewSessionAction); fileMenu->addAction(fileOpenSessionAction); fileMenu->addAction(fileSaveSessionAction); fileMenu->addAction(fileSaveSessionAsAction); recentFileSeparator = fileMenu->addSeparator(); for (int i = 0; i < MaxRecentFiles; ++i) fileMenu->addAction(recentFileActions[i]); fileMenu->addSeparator(); fileMenu->addAction(fileQuitAction); // create system menu systemMenu = menuBar()->addMenu(tr("&System")); systemMenu->addAction(systemConnectAction); systemMenu->addAction(systemDisconnectAction); systemMenu->addSeparator(); systemMenu->addAction(systemPauseAction); systemMenu->addSeparator(); systemMenu->addAction(systemRebootAction); systemMenu->addSeparator(); systemMenu->addAction(systemSymbolManagerAction); systemMenu->addSeparator(); systemMenu->addAction(systemPreferencesAction); // create system menu searchMenu = menuBar()->addMenu(tr("Se&arch")); searchMenu->addAction(searchGotoAction); // create view menu viewMenu = menuBar()->addMenu(tr("&View")); viewMenu->addAction(viewRegistersAction); viewMenu->addAction(viewFlagsAction); viewMenu->addAction(viewStackAction); viewMenu->addAction(viewSlotsAction); viewMenu->addAction(viewMemoryAction); viewVDPDialogsMenu = viewMenu->addMenu("VDP"); viewMenu->addSeparator(); viewMenu->addAction(viewDebuggableViewerAction); connect(viewMenu, SIGNAL(aboutToShow()), this, SLOT(updateViewMenu())); // create VDP dialogs menu viewVDPDialogsMenu->addAction(viewVDPRegsAction); viewVDPDialogsMenu->addAction(viewVDPCommandRegsAction); viewVDPDialogsMenu->addAction(viewVDPStatusRegsAction); viewVDPDialogsMenu->addAction(viewBitMappedAction); connect(viewVDPDialogsMenu, SIGNAL(aboutToShow()), this, SLOT(updateVDPViewMenu())); // create execute menu executeMenu = menuBar()->addMenu(tr("&Execute")); executeMenu->addAction(executeBreakAction); executeMenu->addAction(executeRunAction); executeMenu->addSeparator(); executeMenu->addAction(executeStepAction); executeMenu->addAction(executeStepOverAction); executeMenu->addAction(executeStepOutAction); executeMenu->addAction(executeStepBackAction); executeMenu->addAction(executeRunToAction); // create breakpoint menu breakpointMenu = menuBar()->addMenu(tr("&Breakpoint")); breakpointMenu->addAction(breakpointToggleAction); breakpointMenu->addAction(breakpointAddAction); // create help menu helpMenu = menuBar()->addMenu(tr("&Help")); helpMenu->addAction(helpAboutAction); } void DebuggerForm::createToolbars() { // create debug toolbar systemToolbar = addToolBar(tr("System")); systemToolbar->addAction(systemConnectAction); systemToolbar->addAction(systemDisconnectAction); systemToolbar->addSeparator(); systemToolbar->addAction(systemPauseAction); systemToolbar->addSeparator(); systemToolbar->addAction(systemSymbolManagerAction); // create debug toolbar executeToolbar = addToolBar(tr("Execution")); executeToolbar->addAction(executeBreakAction); executeToolbar->addAction(executeRunAction); executeToolbar->addSeparator(); executeToolbar->addAction(executeStepAction); executeToolbar->addAction(executeStepOverAction); executeToolbar->addAction(executeStepOutAction); executeToolbar->addAction(executeStepBackAction); executeToolbar->addAction(executeRunToAction); } void DebuggerForm::createStatusbar() { // create the statusbar statusBar()->showMessage("No emulation running."); } void DebuggerForm::createForm() { updateWindowTitle(); mainArea = new DockableWidgetArea(); dockMan.addDockArea(mainArea); setCentralWidget(mainArea); // Create main widgets and append them to the list first DockableWidget* dw = new DockableWidget(dockMan); // create the disasm viewer widget disasmView = new DisasmViewer(); dw->setWidget(disasmView); dw->setTitle(tr("Code view")); dw->setId("CODEVIEW"); dw->setFloating(false); dw->setDestroyable(false); dw->setMovable(false); dw->setClosable(false); connect(this, SIGNAL(settingsChanged()), disasmView, SLOT(settingsChanged())); connect(this, SIGNAL(symbolsChanged()), disasmView, SLOT(symbolsChanged())); connect(dw, SIGNAL(visibilityChanged(DockableWidget*)), this, SLOT(dockWidgetVisibilityChanged(DockableWidget*))); // create the memory view widget mainMemoryView = new MainMemoryViewer(); dw = new DockableWidget(dockMan); dw->setWidget(mainMemoryView); dw->setTitle(tr("Main memory")); dw->setId("MEMORY"); dw->setFloating(false); dw->setDestroyable(false); dw->setMovable(true); dw->setClosable(true); connect(dw, SIGNAL(visibilityChanged(DockableWidget*)), this, SLOT(dockWidgetVisibilityChanged(DockableWidget*))); mainMemoryView->setSymbolTable(&session.symbolTable()); // create register viewer regsView = new CPURegsViewer(); dw = new DockableWidget(dockMan); dw->setWidget(regsView); dw->setTitle(tr("CPU registers")); dw->setId("REGISTERS"); dw->setFloating(false); dw->setDestroyable(false); dw->setMovable(true); dw->setClosable(true); connect(dw, SIGNAL(visibilityChanged(DockableWidget*)), this, SLOT(dockWidgetVisibilityChanged(DockableWidget*))); // Hook up the register viewer with the MainMemory viewer connect(regsView, SIGNAL(registerChanged(int,int)), mainMemoryView, SLOT(registerChanged(int,int))); mainMemoryView->setRegsView(regsView); // create flags viewer flagsView = new FlagsViewer(); dw = new DockableWidget(dockMan); dw->setWidget(flagsView); dw->setTitle(tr("Flags")); dw->setId("FLAGS"); dw->setFloating(false); dw->setDestroyable(false); dw->setMovable(true); dw->setClosable(true); connect(dw, SIGNAL(visibilityChanged(DockableWidget*)), this, SLOT(dockWidgetVisibilityChanged(DockableWidget*))); // create stack viewer stackView = new StackViewer(); dw = new DockableWidget(dockMan); dw->setWidget(stackView); dw->setTitle(tr("Stack")); dw->setId("STACK"); dw->setFloating(false); dw->setDestroyable(false); dw->setMovable(true); dw->setClosable(true); connect(dw, SIGNAL(visibilityChanged(DockableWidget*)), this, SLOT(dockWidgetVisibilityChanged(DockableWidget*))); // create slot viewer slotView = new SlotViewer(); dw = new DockableWidget(dockMan); dw->setWidget(slotView); dw->setTitle(tr("Memory layout")); dw->setId("SLOTS"); dw->setFloating(false); dw->setDestroyable(false); dw->setMovable(true); dw->setClosable(true); connect(dw, SIGNAL(visibilityChanged(DockableWidget*)), this, SLOT(dockWidgetVisibilityChanged(DockableWidget*))); // restore layout restoreGeometry(Settings::get().value("Layout/WindowGeometry", saveGeometry()).toByteArray()); QStringList list = Settings::get().value("Layout/WidgetLayout").toStringList(); // defaults needed? if (list.empty() || !list.at(0).startsWith("CODEVIEW ")) { list.clear(); list.append("CODEVIEW D V R 0 -1 -1"); list.append("REGISTERS D V R 0 -1 -1"); list.append("FLAGS D V R 0 -1 -1"); int regW = dockMan.findDockableWidget("REGISTERS")->sizeHint().width(); int regH = dockMan.findDockableWidget("REGISTERS")->sizeHint().height(); int codeW = dockMan.findDockableWidget("CODEVIEW")->sizeHint().width(); int codeH = dockMan.findDockableWidget("CODEVIEW")->sizeHint().height(); int flagW = dockMan.findDockableWidget("FLAGS")->sizeHint().width(); int slotW = dockMan.findDockableWidget("SLOTS")->sizeHint().width(); list.append(QString("SLOTS D V R 0 -1 %1").arg(regH)); list.append(QString("STACK D V R 0 -1 %1").arg(codeH)); list.append(QString("MEMORY D V B %1 %2 %3").arg(codeW) .arg(regW + flagW + slotW) .arg(codeH - regH)); } // add widgets for (int i = 0; i < list.size(); ++i) { QStringList s = list.at(i).split(" ", QString::SkipEmptyParts); // get widget if ((dw = dockMan.findDockableWidget(s.at(0)))) { if (s.at(1) == "D") { // dock widget DockableWidgetLayout::DockSide side; if (s.at(3) == "T") { side = DockableWidgetLayout::TOP; } else if (s.at(3) == "L") { side = DockableWidgetLayout::LEFT; } else if (s.at(3) == "R") { side = DockableWidgetLayout::RIGHT; } else { side = DockableWidgetLayout::BOTTOM; } dockMan.insertWidget(dw, 0, side, s.at(4).toInt(), s.at(5).toInt(), s.at(6).toInt()); if (s.at(2) == "H") dw->hide(); } else if (s.at(1) == "F") { // float widget dw->setFloating(true, s.at(2) == "V"); dw->resize(s.at(5).toInt(), s.at(6).toInt()); dw->move (s.at(3).toInt(), s.at(4).toInt()); } } } // disable all widgets connectionClosed(); connect(regsView, SIGNAL(pcChanged(quint16)), disasmView, SLOT(setProgramCounter(quint16))); connect(regsView, SIGNAL(flagsChanged(quint8)), flagsView, SLOT(setFlags(quint8))); connect(regsView, SIGNAL(spChanged(quint16)), stackView, SLOT(setStackPointer(quint16))); connect(disasmView, SIGNAL(toggleBreakpoint(int)), SLOT(breakpointToggle(int))); connect(&comm, SIGNAL(connectionReady()), SLOT(initConnection())); connect(&comm, SIGNAL(updateParsed(const QString&, const QString&, const QString&)), SLOT(handleUpdate(const QString&, const QString&, const QString&))); connect(&comm, SIGNAL(connectionTerminated()), SLOT(connectionClosed())); // init main memory // added four bytes as runover buffer for dasm // otherwise dasm would need to check the buffer end continously. session.breakpoints().setMemoryLayout(&memLayout); mainMemory = new unsigned char[65536 + 4]; memset(mainMemory, 0, 65536 + 4); disasmView->setMemory(mainMemory); disasmView->setBreakpoints(&session.breakpoints()); disasmView->setMemoryLayout(&memLayout); disasmView->setSymbolTable(&session.symbolTable()); mainMemoryView->setDebuggable("memory", 65536); stackView->setData(mainMemory, 65536); slotView->setMemoryLayout(&memLayout); } DebuggerForm::~DebuggerForm() { delete[] mainMemory; delete mainArea; } void DebuggerForm::closeEvent(QCloseEvent* e) { // handle unsaved session fileNewSession(); // cancel if session is still modified if (session.isModified()) { e->ignore(); return; } // store layout Settings::get().setValue("Layout/WindowGeometry", saveGeometry()); QStringList layoutList; // fill layout list with docked widgets dockMan.getConfig(0, layoutList); // append floating widgets for (QList::const_iterator it = dockMan.managedWidgets().begin(); it != dockMan.managedWidgets().end(); ++it) { if ((*it)->isFloating()) { QString s("%1 F %2 %3 %4 %5 %6"); s = s.arg((*it)->id()); if ((*it)->isHidden()) { s = s.arg("H"); } else { s = s.arg("V"); } s = s.arg((*it)->x()).arg((*it)->y()) .arg((*it)->width()).arg((*it)->height()); layoutList.append(s); } } Settings::get().setValue("Layout/WidgetLayout", layoutList); QMainWindow::closeEvent(e); } void DebuggerForm::updateRecentFiles() { // store settings Settings::get().setValue("MainWindow/RecentFiles", recentFiles); // update actions for(int i = 0; i < MaxRecentFiles; i++) if(i < recentFiles.size()) { recentFileActions[i]->setVisible(true); QString text = QString("&%1 %2").arg(i + 1).arg(QFileInfo(recentFiles[i]).fileName()); recentFileActions[i]->setText(text); recentFileActions[i]->setData(recentFiles[i]); } else recentFileActions[i]->setVisible(false); // show separator only when recent files exist recentFileSeparator->setVisible(recentFiles.size()); } void DebuggerForm::addRecentFile(const QString& file) { recentFiles.removeAll(file); recentFiles.prepend(file); while (recentFiles.size() > MaxRecentFiles) recentFiles.removeLast(); updateRecentFiles(); } void DebuggerForm::removeRecentFile(const QString& file) { recentFiles.removeAll(file); updateRecentFiles(); } void DebuggerForm::updateWindowTitle() { QString title = "openMSX debugger [%1%2]"; if (session.existsAsFile()) { title = title.arg(session.filename()); } else { title = title.arg("unnamed session"); } if (session.isModified()) { title = title.arg('*'); } else { title = title.arg(""); } setWindowTitle(title); } void DebuggerForm::initConnection() { systemConnectAction->setEnabled(false); systemDisconnectAction->setEnabled(true); comm.sendCommand(new QueryPauseHandler(*this)); comm.sendCommand(new QueryBreakedHandler(*this)); comm.sendCommand(new SimpleCommand("openmsx_update enable status")); comm.sendCommand(new ListDebuggablesHandler(*this)); // define 'debug_bin2hex' proc for internal use comm.sendCommand(new SimpleCommand( "proc debug_bin2hex { input } {\n" " set result \"\"\n" " foreach i [split $input {}] {\n" " append result [format %02X [scan $i %c]] \"\"\n" " }\n" " return $result\n" "}\n")); // define 'debug_hex2bin' proc for internal use comm.sendCommand(new SimpleCommand( "proc debug_hex2bin { input } {\n" " set result \"\"\n" " foreach {h l} [split $input {}] {\n" " append result [binary format H2 $h$l] \"\"\n" " }\n" " return $result\n" "}\n")); // define 'debug_memmapper' proc for internal use comm.sendCommand(new SimpleCommand( "proc debug_memmapper { } {\n" " set result \"\"\n" " for { set page 0 } { $page < 4 } { incr page } {\n" " set tmp [get_selected_slot $page]\n" " append result [lindex $tmp 0] [lindex $tmp 1] \"\\n\"\n" " if { [lsearch [debug list] \"MapperIO\"] != -1} {\n" " append result [debug read \"MapperIO\" $page] \"\\n\"\n" " } else {\n" " append result \"0\\n\"\n" " }\n" " }\n" " for { set ps 0 } { $ps < 4 } { incr ps } {\n" " if [machine_info issubslotted $ps] {\n" " append result \"1\\n\"\n" " for { set ss 0 } { $ss < 4 } { incr ss } {\n" " append result [get_mapper_size $ps $ss] \"\\n\"\n" " }\n" " } else {\n" " append result \"0\\n\"\n" " append result [get_mapper_size $ps 0] \"\\n\"\n" " }\n" " }\n" " for { set page 0 } { $page < 4 } { incr page } {\n" " set tmp [get_selected_slot $page]\n" " set ss [lindex $tmp 1]\n" " if { $ss == \"X\" } { set ss 0 }\n" " set device_list [machine_info slot [lindex $tmp 0] $ss $page]\n" " set name \"[lindex $device_list 0] romblocks\"\n" " if { [lsearch [debug list] $name] != -1} {\n" " append result \"[debug read $name [expr {$page * 0x4000}] ]\\n\"\n" " append result \"[debug read $name [expr {$page * 0x4000 + 0x2000}] ]\\n\"\n" " } else {\n" " append result \"X\\nX\\n\"\n" " }\n" " }\n" " return $result\n" "}\n")); // define 'debug_list_all_breaks' proc for internal use comm.sendCommand(new SimpleCommand( "proc debug_list_all_breaks { } {\n" " set result [debug list_bp]\n" " append result [debug list_watchpoints]\n" " append result [debug list_conditions]\n" " return $result\n" "}\n")); } void DebuggerForm::connectionClosed() { systemPauseAction->setEnabled(false); systemRebootAction->setEnabled(false); executeBreakAction->setEnabled(false); executeRunAction->setEnabled(false); executeStepAction->setEnabled(false); executeStepOverAction->setEnabled(false); executeStepOutAction->setEnabled(false); executeStepBackAction->setEnabled(false); executeRunToAction->setEnabled(false); systemDisconnectAction->setEnabled(false); systemConnectAction->setEnabled(true); breakpointToggleAction->setEnabled(false); breakpointAddAction->setEnabled(false); for (QList::const_iterator it = dockMan.managedWidgets().begin(); it != dockMan.managedWidgets().end(); ++it) { (*it)->widget()->setEnabled(false); } } void DebuggerForm::finalizeConnection(bool halted) { systemPauseAction->setEnabled(true); systemRebootAction->setEnabled(true); breakpointToggleAction->setEnabled(true); breakpointAddAction->setEnabled(true); // merge breakpoints on connect mergeBreakpoints = true; if (halted) { setBreakMode(); breakOccured(); } else { setRunMode(); updateData(); } for (QList::const_iterator it = dockMan.managedWidgets().begin(); it != dockMan.managedWidgets().end(); ++it) { (*it)->widget()->setEnabled(true); } } void DebuggerForm::handleUpdate(const QString& type, const QString& name, const QString& message) { if (type == "status") { if (name == "cpu") { if (message == "suspended") { breakOccured(); } else { setRunMode(); } } else if (name == "paused") { pauseStatusChanged(message == "true"); } } } void DebuggerForm::pauseStatusChanged(bool isPaused) { systemPauseAction->setChecked(isPaused); } void DebuggerForm::breakOccured() { setBreakMode(); updateData(); } void DebuggerForm::updateData() { comm.sendCommand(new ListBreakPointsHandler(*this, mergeBreakpoints)); // only merge the first time after connect mergeBreakpoints = false; // refresh memory viewer mainMemoryView->refresh(); // update registers // note that a register update is processed, a signal is sent to other // widgets as well. Any dependent updates shoud be called before this one. CPURegRequest* regs = new CPURegRequest(*this); comm.sendCommand(regs); // refresh slot viewer slotView->refresh(); emit emulationChanged(); } void DebuggerForm::setBreakMode() { executeBreakAction->setEnabled(false); executeRunAction->setEnabled(true); executeStepAction->setEnabled(true); executeStepOverAction->setEnabled(true); executeStepOutAction->setEnabled(true); executeStepBackAction->setEnabled(true); executeRunToAction->setEnabled(true); } void DebuggerForm::setRunMode() { executeBreakAction->setEnabled(true); executeRunAction->setEnabled(false); executeStepAction->setEnabled(false); executeStepOverAction->setEnabled(false); executeStepOutAction->setEnabled(false); executeStepBackAction->setEnabled(false); executeRunToAction->setEnabled(false); } void DebuggerForm::fileNewSession() { if (session.isModified()) { // save current session? int choice = QMessageBox::warning(this, tr("Unsaved session"), tr("The current session has unsaved data.\n" "Do you want to save your changes?"), QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Save); if (choice == QMessageBox::Cancel) { return; } else if (choice == QMessageBox::Save) { fileSaveSession(); // skip new if session is still modified (save was cancelled) if (session.isModified()) return; } } session.clear(); updateWindowTitle(); } void DebuggerForm::fileOpenSession() { QString fileName = QFileDialog::getOpenFileName( this, tr("Open debug session"), QDir::currentPath(), tr("Debug Session Files (*.omds)")); if (!fileName.isEmpty()) openSession(fileName); } void DebuggerForm::openSession(const QString& file) { fileNewSession(); session.open(file); if (systemDisconnectAction->isEnabled()) { // active connection, merge loaded breakpoints comm.sendCommand(new ListBreakPointsHandler(*this, true)); } // update recent if(session.existsAsFile()) addRecentFile(file); else removeRecentFile(file); updateWindowTitle(); } void DebuggerForm::fileSaveSession() { if (session.existsAsFile()) { session.save(); } else { fileSaveSessionAs(); } updateWindowTitle(); } void DebuggerForm::fileSaveSessionAs() { QFileDialog d(this, tr("Save debug session")); d.setNameFilter(tr("Debug Session Files (*.omds)")); d.setDefaultSuffix("omds"); d.setDirectory(QDir::currentPath()); d.setAcceptMode(QFileDialog::AcceptSave); d.setFileMode(QFileDialog::AnyFile); if (d.exec()) { session.saveAs(d.selectedFiles().at(0)); // update recent if(session.existsAsFile()) addRecentFile(session.filename()); } updateWindowTitle(); } void DebuggerForm::fileRecentOpen() { QAction *action = qobject_cast(sender()); if (action) openSession(action->data().toString()); } void DebuggerForm::systemConnect() { if (OpenMSXConnection* connection = ConnectDialog::getConnection(this)) { comm.connectToOpenMSX(connection); } } void DebuggerForm::systemDisconnect() { comm.closeConnection(); } void DebuggerForm::systemPause() { comm.sendCommand(new SimpleCommand(QString("set pause ") + (systemPauseAction->isChecked() ? "true" : "false"))); } void DebuggerForm::systemReboot() { if (systemPauseAction->isChecked()) { systemPauseAction->trigger(); } if (executeRunAction->isEnabled()) { executeRun(); } comm.sendCommand(new SimpleCommand("reset")); } void DebuggerForm::systemSymbolManager() { SymbolManager symManager(session.symbolTable(), this); connect(&symManager, SIGNAL(symbolTableChanged()), &session, SLOT(sessionModified())); symManager.exec(); emit symbolsChanged(); updateWindowTitle(); } void DebuggerForm::systemPreferences() { PreferencesDialog prefs(this); prefs.exec(); emit settingsChanged(); } void DebuggerForm::searchGoto() { GotoDialog gtd(memLayout, &session, this); if (gtd.exec()) { int addr = gtd.address(); if ( addr >= 0) { disasmView->setCursorAddress(addr, 0, DisasmViewer::MiddleAlways); } } } void DebuggerForm::executeBreak() { comm.sendCommand(new SimpleCommand("debug break")); } void DebuggerForm::executeRun() { comm.sendCommand(new SimpleCommand("debug cont")); setRunMode(); } void DebuggerForm::executeStep() { comm.sendCommand(new SimpleCommand("debug step")); setRunMode(); } void DebuggerForm::executeStepOver() { SimpleCommand *sc = new SimpleCommand("step_over"); connect(sc, SIGNAL(replyStatusOk(bool)), this, SLOT(handleCommandReplyStatus(bool))); comm.sendCommand(sc); setRunMode(); } void DebuggerForm::executeRunTo() { comm.sendCommand(new SimpleCommand( "run_to " + QString::number(disasmView->cursorAddress()))); setRunMode(); } void DebuggerForm::executeStepOut() { comm.sendCommand(new SimpleCommand("step_out")); setRunMode(); } void DebuggerForm::executeStepBack() { SimpleCommand *sc = new SimpleCommand("step_back"); connect(sc, SIGNAL(replyStatusOk(bool)), this, SLOT(handleCommandReplyStatus(bool))); comm.sendCommand(sc); setRunMode(); } void DebuggerForm::handleCommandReplyStatus(bool status) { if(status) { finalizeConnection(true); } } void DebuggerForm::breakpointToggle(int addr) { // toggle address unspecified, use cursor address if (addr < 0) addr = disasmView->cursorAddress(); QString cmd, id; if (session.breakpoints().isBreakpoint(addr, &id)) { cmd = Breakpoints::createRemoveCommand(id); } else { // get slot int ps, ss, seg; addressSlot(addr, ps, ss, seg); // create command cmd = Breakpoints::createSetCommand(Breakpoints::BREAKPOINT, addr, ps, ss, seg); } comm.sendCommand(new SimpleCommand(cmd)); comm.sendCommand(new ListBreakPointsHandler(*this)); } void DebuggerForm::breakpointAdd() { BreakpointDialog bpd(memLayout, &session, this); int addr = disasmView->cursorAddress(); int ps, ss, seg; addressSlot(addr, ps, ss, seg); bpd.setData(Breakpoints::BREAKPOINT, addr, ps, ss, seg); if (bpd.exec()) { if (bpd.address() >= 0) { QString cmd = Breakpoints::createSetCommand( bpd.type(), bpd.address(), bpd.slot(), bpd.subslot(), bpd.segment(), bpd.addressEndRange(), bpd.condition() ); comm.sendCommand(new SimpleCommand(cmd)); comm.sendCommand(new ListBreakPointsHandler(*this)); } } } void DebuggerForm::showAbout() { QMessageBox::about( this, "openMSX Debugger", QString(Version::full().c_str())); } void DebuggerForm::toggleRegisterDisplay() { toggleView(qobject_cast(regsView->parentWidget())); } void DebuggerForm::toggleFlagsDisplay() { toggleView(qobject_cast(flagsView->parentWidget())); } void DebuggerForm::toggleStackDisplay() { toggleView(qobject_cast(stackView->parentWidget())); } void DebuggerForm::toggleSlotsDisplay() { toggleView(qobject_cast(slotView->parentWidget())); } void DebuggerForm::toggleBitMappedDisplay() { //toggleView( qobject_cast(slotView->parentWidget())); // not sure if this a good idea for a docable widget // create new debuggable viewer window BitMapViewer* viewer = new BitMapViewer(); DockableWidget* dw = new DockableWidget(dockMan); dw->setWidget(viewer); dw->setTitle(tr("Bitmapped VRAM View")); dw->setId("BITMAPVRAMVIEW"); dw->setFloating(true); dw->setDestroyable(true); dw->setMovable(true); dw->setClosable(true); /* connect( dw, SIGNAL( visibilityChanged(DockableWidget*) ), this, SLOT( dockWidgetVisibilityChanged(DockableWidget*) ) ); connect( this, SIGNAL( debuggablesChanged(const QMap&) ), viewer, SLOT( setDebuggables(const QMap&) ) ); */ // TODO: refresh should be being hanled by VDPDataStore... connect(this, SIGNAL(emulationChanged()), viewer, SLOT(refresh())); /* viewer->setDebuggables( debuggables ); viewer->setEnabled( disasmView->isEnabled() ); */ } void DebuggerForm::toggleVDPCommandRegsDisplay() { if (VDPCommandRegView == NULL) { VDPCommandRegView = new VDPCommandRegViewer(); DockableWidget* dw = new DockableWidget(dockMan); dw->setWidget(VDPCommandRegView); dw->setTitle(tr("VDP registers view")); dw->setId("VDPCommandRegView"); dw->setFloating(true); dw->setDestroyable(false); dw->setMovable(true); dw->setClosable(true); connect(this, SIGNAL(emulationChanged()), VDPCommandRegView, SLOT(refresh())); } else { toggleView(qobject_cast(VDPCommandRegView->parentWidget())); } } void DebuggerForm::toggleVDPRegsDisplay() { if (VDPRegView == NULL) { VDPRegView = new VDPRegViewer(); DockableWidget *dw = new DockableWidget(dockMan); dw->setWidget(VDPRegView); dw->setTitle(tr("VDP registers view")); dw->setId("VDPREGVIEW"); dw->setFloating(true); dw->setDestroyable(false); dw->setMovable(true); dw->setClosable(true); connect(this, SIGNAL(emulationChanged()), VDPRegView, SLOT(refresh())); } else { toggleView(qobject_cast(VDPRegView->parentWidget())); } } void DebuggerForm::toggleVDPStatusRegsDisplay() { if (VDPStatusRegView == NULL) { VDPStatusRegView = new VDPStatusRegViewer(); DockableWidget* dw = new DockableWidget(dockMan); dw->setWidget(VDPStatusRegView); dw->setTitle(tr("VDP status registers view")); dw->setId("VDPSTATUSREGVIEW"); dw->setFloating(true); dw->setDestroyable(false); dw->setMovable(true); dw->setClosable(true); connect(this, SIGNAL(emulationChanged()), VDPStatusRegView, SLOT(refresh())); } else { toggleView(qobject_cast(VDPStatusRegView->parentWidget())); } } void DebuggerForm::toggleMemoryDisplay() { toggleView(qobject_cast(mainMemoryView->parentWidget())); } void DebuggerForm::toggleView(DockableWidget* widget) { if (widget->isHidden()) { widget->show(); } else { widget->hide(); } dockMan.visibilityChanged(widget); } void DebuggerForm::addDebuggableViewer() { // create new debuggable viewer window DebuggableViewer* viewer = new DebuggableViewer(); DockableWidget* dw = new DockableWidget(dockMan); dw->setWidget(viewer); dw->setTitle(tr("Debuggable hex view")); dw->setId("DEBUGVIEW"); dw->setFloating(true); dw->setDestroyable(true); dw->setMovable(true); dw->setClosable(true); connect(dw, SIGNAL(visibilityChanged(DockableWidget*)), this, SLOT(dockWidgetVisibilityChanged(DockableWidget*))); connect(this, SIGNAL(debuggablesChanged(const QMap&)), viewer, SLOT(setDebuggables(const QMap&))); connect(this, SIGNAL(emulationChanged()), viewer, SLOT(refresh())); viewer->setDebuggables(debuggables); viewer->setEnabled(disasmView->isEnabled()); } void DebuggerForm::dockWidgetVisibilityChanged(DockableWidget* w) { dockMan.visibilityChanged(w); updateViewMenu(); } void DebuggerForm::updateViewMenu() { viewRegistersAction->setChecked(regsView->parentWidget()->isVisible()); viewFlagsAction->setChecked(flagsView->isVisible()); viewStackAction->setChecked(stackView->isVisible()); viewSlotsAction->setChecked(slotView->isVisible()); viewMemoryAction->setChecked(mainMemoryView->isVisible()); } void DebuggerForm::updateVDPViewMenu() { if (VDPCommandRegView) { viewVDPCommandRegsAction->setChecked(VDPCommandRegView->isVisible()); } if (VDPRegView) { viewVDPRegsAction->setChecked(VDPRegView->isVisible()); } if (VDPStatusRegView) { viewVDPStatusRegsAction->setChecked(VDPStatusRegView->isVisible()); } } void DebuggerForm::setDebuggables(const QString& list) { debuggables.clear(); // process result string QStringList l = list.split(" ", QString::SkipEmptyParts); for (int i = 0; i < l.size(); ++i) { QString d = l[i]; // combine multiple words if (d[0] == '{') { while (!d.endsWith("}")) { d.push_back(' '); d.append(l[++i]); } } // set initial size to zero debuggables[d] = 0; } // find the size for all debuggables for (QMap::iterator it = debuggables.begin(); it != debuggables.end(); ++it) { comm.sendCommand(new DebuggableSizeHandler(it.key(), *this)); } } void DebuggerForm::setDebuggableSize(const QString& debuggable, int size) { debuggables[debuggable] = size; // emit update if size of last debuggable was set if (debuggable == debuggables.keys().last()) { emit debuggablesChanged(debuggables); } } void DebuggerForm::symbolFileChanged() { static bool shown(false); if(shown) return; shown = true; int choice = QMessageBox::question(this, tr("Symbol file changed"), tr("One or more symbol file have changed.\n" "Reload now?"), QMessageBox::Yes | QMessageBox::No); shown = false; if (choice == QMessageBox::Yes) session.symbolTable().reloadFiles(); } void DebuggerForm::addressSlot(int addr, int& ps, int& ss, int& segment) { int p = (addr & 0xC000) >> 14; ps = memLayout.primarySlot[p]; // figure out secondary slot ss = memLayout.isSubslotted[ps] ? memLayout.secondarySlot[p] : -1; // figure out (rom) mapper segment segment = -1; if (memLayout.mapperSize[ps][ss==-1 ? 0 : ss] > 0) segment = memLayout.mapperSegment[p]; else { int q = 2*p + ((addr & 0x2000) >> 13); if (memLayout.romBlock[q] >= 0) segment = memLayout.romBlock[q]; } } openmsx-debugger-0.0.0.svn20141006.orig/src/DockableWidget.h0000644000175000017500000000260412414415132022507 0ustar shevekshevek// $Id$ #ifndef DOCKABLEWIDGET_H #define DOCKABLEWIDGET_H #include #include class QLabel; class QToolButton; class QHBoxLayout; class QVBoxLayout; class QRubberBand; class DockManager; class DockableWidget : public QWidget { Q_OBJECT; public: DockableWidget(DockManager& manager, QWidget* parent = 0); ~DockableWidget(); QWidget* widget() const; void setWidget(QWidget* widget); const QString& id() const; void setId(const QString& str); QString title() const; void setTitle(const QString& title); bool isFloating() const; void setFloating(bool enable, bool showNow = true); bool isMovable() const; void setMovable(bool enable); bool isClosable() const; void setClosable(bool enable); bool isDestroyable() const; void setDestroyable(bool enable); private: virtual void mousePressEvent(QMouseEvent* event); virtual void mouseMoveEvent(QMouseEvent* event); virtual void mouseReleaseEvent(QMouseEvent* event); virtual void closeEvent(QCloseEvent* event); DockManager& dockManager; QString widgetId; bool floating; bool closable, movable, destroyable; bool dragging; QPoint dragStart, dragOffset; QRubberBand* rubberBand; QWidget* mainWidget; QHBoxLayout* headerLayout; QVBoxLayout* widgetLayout; QWidget* headerWidget; QLabel* titleLabel; QToolButton* closeButton; signals: void visibilityChanged(DockableWidget* w); }; #endif // DOCKABLEWIDGET_H openmsx-debugger-0.0.0.svn20141006.orig/src/SlotViewer.cpp0000644000175000017500000001454612414415132022305 0ustar shevekshevek// $Id$ #include "SlotViewer.h" #include "DebuggerData.h" #include "OpenMSXConnection.h" #include "CommClient.h" #include #include #include class DebugMemMapperHandler : public SimpleCommand { public: DebugMemMapperHandler(SlotViewer& viewer_) : SimpleCommand("debug_memmapper") , viewer(viewer_) { } virtual void replyOk(const QString& message) { viewer.slotsUpdated(message); delete this; } private: SlotViewer& viewer; }; SlotViewer::SlotViewer(QWidget* parent) : QFrame(parent) { setFrameStyle(WinPanel | Sunken); setFocusPolicy(Qt::StrongFocus); setBackgroundRole(QPalette::Base); setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum)); memLayout = NULL; for (int p = 0; p < 4; ++p) { slotsChanged[p] = false; segmentsChanged[p] = false; } frameR = frameL = frameT = frameB = frameWidth(); headerSize1 = 8 + fontMetrics().width("Page"); headerSize2 = 8 + fontMetrics().width("Address"); headerSize3 = 8 + fontMetrics().width("Slot"); headerSize4 = 8 + fontMetrics().width("Segment"); headerHeight = 8 + fontMetrics().height(); } void SlotViewer::resizeEvent(QResizeEvent* e) { QFrame::resizeEvent(e); } void SlotViewer::paintEvent(QPaintEvent* e) { // call parent for drawing the actual frame QFrame::paintEvent(e); QPainter p(this); // calc and set drawing bounds QRect r(e->rect()); if (r.left() < frameL) r.setLeft(frameL); if (r.top() < frameT) r.setTop (frameT); if (r.right() > width() - frameR - 1) r.setRight (width() - frameR - 1); if (r.bottom() > height() - frameB - 1) r.setBottom(height() - frameB - 1); p.setClipRect(r); // redraw background p.fillRect(r, palette().color(QPalette::Base)); QStyleOptionHeader so; so.init(this); so.state |= QStyle::State_Raised; so.orientation = Qt::Horizontal; so.position = QStyleOptionHeader::Beginning; so.sortIndicator = QStyleOptionHeader::None; so.textAlignment = Qt::AlignHCenter; so.rect.setTop(frameT); so.rect.setHeight(headerHeight); so.rect.setLeft(frameL); so.rect.setWidth(headerSize1); so.section = 0; so.text = "Page"; style()->drawControl(QStyle::CE_Header, &so, &p, this); so.rect.setLeft(so.rect.left() + headerSize1); so.rect.setWidth(headerSize2); so.section = 1; so.text = "Address"; style()->drawControl(QStyle::CE_Header, &so, &p, this); so.rect.setLeft(so.rect.left() + headerSize2); so.rect.setWidth(headerSize3); so.section = 2; so.text = "Slot"; style()->drawControl(QStyle::CE_Header, &so, &p, this); so.rect.setLeft(so.rect.left() + headerSize3); so.rect.setWidth(headerSize4); so.section = 3; so.text = "Segment"; style()->drawControl(QStyle::CE_Header, &so, &p, this); int mid1 = frameL + headerSize1 / 2; int mid2 = frameL + headerSize1 + headerSize2 / 2; int mid3 = frameL + headerSize1 + headerSize2 + headerSize3 / 2; int mid4 = frameL + headerSize1 + headerSize2 + headerSize3 + headerSize4 / 2; int dy = (height() - frameT - frameB - headerHeight) / 4; int y = frameT + headerHeight + dy / 2 + fontMetrics().height() / 2 - fontMetrics().descent(); int isOn = isEnabled() && memLayout != NULL; for (int i = 0; i < 4; ++i) { QString str; p.setPen(palette().color(QPalette::Text)); // print page nr str.sprintf("%i", i); p.drawText(mid1 - fontMetrics().width(str) / 2, y, str); // print address str.sprintf("$%04X", i * 0x4000); p.drawText(mid2 - fontMetrics().width(str) / 2, y, str); // print slot if (isOn) { if (memLayout->isSubslotted[memLayout->primarySlot[i]]) { str.sprintf("%i-%i", memLayout->primarySlot[i], memLayout->secondarySlot[i]); } else { str = QString::number(memLayout->primarySlot[i]); } } else { str = "-"; } // set pen colour to red if slot was recently changed if (slotsChanged[i] && isOn) { p.setPen(Qt::red); } else { p.setPen(palette().color(QPalette::Text)); } p.drawText(mid3 - fontMetrics().width(str) / 2, y, str); // print segment if (isOn) { int ms; if (memLayout->isSubslotted[memLayout->primarySlot[i] & 3]) { ms = memLayout->mapperSize[memLayout->primarySlot[i] & 3] [memLayout->secondarySlot[i] & 3]; } else { ms = memLayout->mapperSize[memLayout->primarySlot[i] & 3][0]; } if (ms > 0) { str.sprintf("%i", memLayout->mapperSegment[i]); } else if(memLayout->romBlock[2*i] >= 0) { if (memLayout->romBlock[2*i] == memLayout->romBlock[2*i+1]) { str.sprintf("R%i", memLayout->romBlock[2*i]); } else { str.sprintf("R%i/%i", memLayout->romBlock[2*i], memLayout->romBlock[2*i+1]); } } else { str = "-"; } } else { str = "-"; } // set pen colour to red if slot was recently changed if (segmentsChanged[i] && isOn) { p.setPen(Qt::red); } else { p.setPen(palette().color(QPalette::Text)); } p.drawText(mid4 - fontMetrics().width(str) / 2, y, str); y += dy; } } QSize SlotViewer::sizeHint() const { return QSize(headerSize1 + headerSize2 + headerSize3 + headerSize4 + frameL + frameR, headerHeight + 4*fontMetrics().height()); } void SlotViewer::refresh() { CommClient::instance().sendCommand(new DebugMemMapperHandler(*this)); } void SlotViewer::setMemoryLayout(MemoryLayout* ml) { memLayout = ml; } void SlotViewer::slotsUpdated(const QString& message) { QStringList lines = message.split('\n'); // parse page slots and segments for (int p = 0; p < 4; ++p) { slotsChanged[p] = (memLayout->primarySlot [p] != lines[p * 2][0].toLatin1()-'0') || (memLayout->secondarySlot[p] != lines[p * 2][1].toLatin1()-'0' && memLayout->isSubslotted[p]); memLayout->primarySlot [p] = lines[p * 2][0].toLatin1()-'0'; memLayout->secondarySlot[p] = lines[p * 2][1].toLatin1()-'0'; segmentsChanged[p] = memLayout->mapperSegment[p] != lines[p * 2 + 1].toInt(); memLayout->mapperSegment[p] = lines[p * 2 + 1].toInt(); } // parse slot layout int l = 8; for (int ps = 0; ps < 4; ++ps) { memLayout->isSubslotted[ps] = lines[l++][0] == '1'; if (memLayout->isSubslotted[ps]) { for (int ss = 0; ss < 4; ++ss) { memLayout->mapperSize[ps][ss] = lines[l++].toUShort(); } } else { memLayout->mapperSize[ps][0] = lines[l++].toUShort(); } } // parse rom blocks for (int i = 0; i < 8; ++i, ++l) { if (lines[l][0] == 'X') memLayout->romBlock[i] = -1; else memLayout->romBlock[i] = lines[l].toInt(); } update(); } openmsx-debugger-0.0.0.svn20141006.orig/src/DasmTables.cpp0000644000175000017500000003137512414415132022220 0ustar shevekshevek// $Id$ #include "DasmTables.h" /* * Letter codes in the instructions: * * A - Address * B - Byte value * R - Relative jump offset * W - Word value * X - Indexed address ( 3 byte ) * Y - Indexed address ( 4 byte ) * I - IX or IY register * ! - Invalid opcode * @ - Invalid opcode * # - Invalid opcode */ const char* const mnemonic_xx_cb[256] = { "#","#","#","#","#","#","rlc Y" ,"#", "#","#","#","#","#","#","rrc Y" ,"#", "#","#","#","#","#","#","rl Y" ,"#", "#","#","#","#","#","#","rr Y" ,"#", "#","#","#","#","#","#","sla Y" ,"#", "#","#","#","#","#","#","sra Y" ,"#", "#","#","#","#","#","#","sll Y" ,"#", "#","#","#","#","#","#","srl Y" ,"#", "#","#","#","#","#","#","bit 0,Y","#", "#","#","#","#","#","#","bit 1,Y","#", "#","#","#","#","#","#","bit 2,Y","#", "#","#","#","#","#","#","bit 3,Y","#", "#","#","#","#","#","#","bit 4,Y","#", "#","#","#","#","#","#","bit 5,Y","#", "#","#","#","#","#","#","bit 6,Y","#", "#","#","#","#","#","#","bit 7,Y","#", "#","#","#","#","#","#","res 0,Y","#", "#","#","#","#","#","#","res 1,Y","#", "#","#","#","#","#","#","res 2,Y","#", "#","#","#","#","#","#","res 3,Y","#", "#","#","#","#","#","#","res 4,Y","#", "#","#","#","#","#","#","res 5,Y","#", "#","#","#","#","#","#","res 6,Y","#", "#","#","#","#","#","#","res 7,Y","#", "#","#","#","#","#","#","set 0,Y","#", "#","#","#","#","#","#","set 1,Y","#", "#","#","#","#","#","#","set 2,Y","#", "#","#","#","#","#","#","set 3,Y","#", "#","#","#","#","#","#","set 4,Y","#", "#","#","#","#","#","#","set 5,Y","#", "#","#","#","#","#","#","set 6,Y","#", "#","#","#","#","#","#","set 7,Y","#" }; const char* const mnemonic_cb[256] = { "rlc b" ,"rlc c" ,"rlc d" ,"rlc e" ,"rlc h" ,"rlc l" ,"rlc (hl)" ,"rlc a" , "rrc b" ,"rrc c" ,"rrc d" ,"rrc e" ,"rrc h" ,"rrc l" ,"rrc (hl)" ,"rrc a" , "rl b" ,"rl c" ,"rl d" ,"rl e" ,"rl h" ,"rl l" ,"rl (hl)" ,"rl a" , "rr b" ,"rr c" ,"rr d" ,"rr e" ,"rr h" ,"rr l" ,"rr (hl)" ,"rr a" , "sla b" ,"sla c" ,"sla d" ,"sla e" ,"sla h" ,"sla l" ,"sla (hl)" ,"sla a" , "sra b" ,"sra c" ,"sra d" ,"sra e" ,"sra h" ,"sra l" ,"sra (hl)" ,"sra a" , "sll b" ,"sll c" ,"sll d" ,"sll e" ,"sll h" ,"sll l" ,"sll (hl)" ,"sll a" , "srl b" ,"srl c" ,"srl d" ,"srl e" ,"srl h" ,"srl l" ,"srl (hl)" ,"srl a" , "bit 0,b","bit 0,c","bit 0,d","bit 0,e","bit 0,h","bit 0,l","bit 0,(hl)","bit 0,a", "bit 1,b","bit 1,c","bit 1,d","bit 1,e","bit 1,h","bit 1,l","bit 1,(hl)","bit 1,a", "bit 2,b","bit 2,c","bit 2,d","bit 2,e","bit 2,h","bit 2,l","bit 2,(hl)","bit 2,a", "bit 3,b","bit 3,c","bit 3,d","bit 3,e","bit 3,h","bit 3,l","bit 3,(hl)","bit 3,a", "bit 4,b","bit 4,c","bit 4,d","bit 4,e","bit 4,h","bit 4,l","bit 4,(hl)","bit 4,a", "bit 5,b","bit 5,c","bit 5,d","bit 5,e","bit 5,h","bit 5,l","bit 5,(hl)","bit 5,a", "bit 6,b","bit 6,c","bit 6,d","bit 6,e","bit 6,h","bit 6,l","bit 6,(hl)","bit 6,a", "bit 7,b","bit 7,c","bit 7,d","bit 7,e","bit 7,h","bit 7,l","bit 7,(hl)","bit 7,a", "res 0,b","res 0,c","res 0,d","res 0,e","res 0,h","res 0,l","res 0,(hl)","res 0,a", "res 1,b","res 1,c","res 1,d","res 1,e","res 1,h","res 1,l","res 1,(hl)","res 1,a", "res 2,b","res 2,c","res 2,d","res 2,e","res 2,h","res 2,l","res 2,(hl)","res 2,a", "res 3,b","res 3,c","res 3,d","res 3,e","res 3,h","res 3,l","res 3,(hl)","res 3,a", "res 4,b","res 4,c","res 4,d","res 4,e","res 4,h","res 4,l","res 4,(hl)","res 4,a", "res 5,b","res 5,c","res 5,d","res 5,e","res 5,h","res 5,l","res 5,(hl)","res 5,a", "res 6,b","res 6,c","res 6,d","res 6,e","res 6,h","res 6,l","res 6,(hl)","res 6,a", "res 7,b","res 7,c","res 7,d","res 7,e","res 7,h","res 7,l","res 7,(hl)","res 7,a", "set 0,b","set 0,c","set 0,d","set 0,e","set 0,h","set 0,l","set 0,(hl)","set 0,a", "set 1,b","set 1,c","set 1,d","set 1,e","set 1,h","set 1,l","set 1,(hl)","set 1,a", "set 2,b","set 2,c","set 2,d","set 2,e","set 2,h","set 2,l","set 2,(hl)","set 2,a", "set 3,b","set 3,c","set 3,d","set 3,e","set 3,h","set 3,l","set 3,(hl)","set 3,a", "set 4,b","set 4,c","set 4,d","set 4,e","set 4,h","set 4,l","set 4,(hl)","set 4,a", "set 5,b","set 5,c","set 5,d","set 5,e","set 5,h","set 5,l","set 5,(hl)","set 5,a", "set 6,b","set 6,c","set 6,d","set 6,e","set 6,h","set 6,l","set 6,(hl)","set 6,a", "set 7,b","set 7,c","set 7,d","set 7,e","set 7,h","set 7,l","set 7,(hl)","set 7,a" }; const char* const mnemonic_ed[256] = { "!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" , "!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" , "!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" , "!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" , "!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" , "!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" , "!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" , "!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" , "in b,(c)","out (c),b","sbc hl,bc","ld (A),bc","neg","retn","im 0","ld i,a", "in c,(c)","out (c),c","adc hl,bc","ld bc,(A)","!" ,"reti","!" ,"ld r,a", "in d,(c)","out (c),d","sbc hl,de","ld (A),de","!" ,"!" ,"im 1","ld a,i", "in e,(c)","out (c),e","adc hl,de","ld de,(A)","!" ,"!" ,"im 2","ld a,r", "in h,(c)","out (c),h","sbc hl,hl","ld (A),hl","!" ,"!" ,"!" ,"rrd" , "in l,(c)","out (c),l","adc hl,hl","ld hl,(A)","!" ,"!" ,"!" ,"rld" , "in f,(c)","out (c),0","sbc hl,sp","ld (A),sp","!" ,"!" ,"!" ,"!" , "in a,(c)","out (c),a","adc hl,sp","ld sp,(A)","!" ,"!" ,"!" ,"!" , "!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" , "!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" , "!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" , "!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" ,"!" , "ldi" ,"cpi" ,"ini" ,"outi" ,"!" ,"!" ,"!" ,"!" , "ldd" ,"cpd" ,"ind" ,"outd" ,"!" ,"!" ,"!" ,"!" , "ldir" ,"cpir" ,"inir" ,"otir" ,"!" ,"!" ,"!" ,"!" , "lddr" ,"cpdr" ,"indr" ,"otdr" ,"!" ,"!" ,"!" ,"!" , "!" ,"mulub a,b","!" ,"muluw hl,bc","!","!" ,"!" ,"!" , "!" ,"mulub a,c","!" ,"!" ,"!", "!" ,"!" ,"!" , "!" ,"mulub a,d","!" ,"muluw hl,de","!","!" ,"!" ,"!" , "!" ,"mulub a,e","!" ,"!" ,"!", "!" ,"!" ,"!" , "!" ,"mulub a,h","!" ,"muluw hl,hl","!","!" ,"!" ,"!" , "!" ,"mulub a,l","!" ,"!" ,"!", "!" ,"!" ,"!" , "!" ,"mulub a,(hl)","!" ,"muluw hl,sp","!","!" ,"!" ,"!" , "!" ,"mulub a,a","!" ,"!" ,"!", "!" ,"!" ,"!" }; const char* const mnemonic_xx[256] = { "@" ,"@" ,"@" ,"@" ,"@" ,"@" ,"@" ,"@" , "@" ,"add I,bc","@" ,"@" ,"@" ,"@" ,"@" ,"@" , "@" ,"@" ,"@" ,"@" ,"@" ,"@" ,"@" ,"@" , "@" ,"add I,de","@" ,"@" ,"@" ,"@" ,"@" ,"@" , "@" ,"ld I,W" ,"ld (A),I","inc I" ,"inc Ih" ,"dec Ih" ,"ld Ih,B","@" , "@" ,"add I,I" ,"ld I,(A)","dec I" ,"inc Il" ,"dec Il" ,"ld Il,B","@" , "@" ,"@" ,"@" ,"@" ,"inc X" ,"dec X" ,"ld X,B" ,"@" , "@" ,"add I,sp","@" ,"@" ,"@" ,"@" ,"@" ,"@" , "@" ,"@" ,"@" ,"@" ,"ld b,Ih" ,"ld b,Il" ,"ld b,X" ,"@" , "@" ,"@" ,"@" ,"@" ,"ld c,Ih" ,"ld c,Il" ,"ld c,X" ,"@" , "@" ,"@" ,"@" ,"@" ,"ld d,Ih" ,"ld d,Il" ,"ld d,X" ,"@" , "@" ,"@" ,"@" ,"@" ,"ld e,Ih" ,"ld e,Il" ,"ld e,X" ,"@" , "ld Ih,b","ld Ih,c" ,"ld Ih,d" ,"ld Ih,e" ,"ld Ih,h" ,"ld Ih,l" ,"ld h,X" ,"ld Ih,a", "ld Il,b","ld Il,c" ,"ld Il,d" ,"ld Il,e" ,"ld Il,h" ,"ld Il,l" ,"ld l,X" ,"ld Il,a", "ld X,b" ,"ld X,c" ,"ld X,d" ,"ld X,e" ,"ld X,h" ,"ld X,l" ,"@" ,"ld X,a" , "@" ,"@" ,"@" ,"@" ,"ld a,Ih" ,"ld a,Il" ,"ld a,X" ,"@" , "@" ,"@" ,"@" ,"@" ,"add a,Ih","add a,Il","add a,X","@" , "@" ,"@" ,"@" ,"@" ,"adc a,Ih","adc a,Il","adc a,X","@" , "@" ,"@" ,"@" ,"@" ,"sub Ih" ,"sub Il" ,"sub X" ,"@" , "@" ,"@" ,"@" ,"@" ,"sbc a,Ih","sbc a,Il","sbc a,X","@" , "@" ,"@" ,"@" ,"@" ,"and Ih" ,"and Il" ,"and X" ,"@" , "@" ,"@" ,"@" ,"@" ,"xor Ih" ,"xor Il" ,"xor X" ,"@" , "@" ,"@" ,"@" ,"@" ,"or Ih" ,"or Il" ,"or X" ,"@" , "@" ,"@" ,"@" ,"@" ,"cp Ih" ,"cp Il" ,"cp X" ,"@" , "@" ,"@" ,"@" ,"@" ,"@" ,"@" ,"@" ,"@" , "@" ,"@" ,"@" ,"fd cb" ,"@" ,"@" ,"@" ,"@" , "@" ,"@" ,"@" ,"@" ,"@" ,"@" ,"@" ,"@" , "@" ,"@" ,"@" ,"@" ,"@" ,"@" ,"@" ,"@" , "@" ,"pop I" ,"@" ,"ex (sp),I","@" ,"push I" ,"@" ,"@" , "@" ,"jp (I)" ,"@" ,"@" ,"@" ,"@" ,"@" ,"@" , "@" ,"@" ,"@" ,"@" ,"@" ,"@" ,"@" ,"@" , "@" ,"ld sp,I" ,"@" ,"@" ,"@" ,"@" ,"@" ,"@" }; const char* const mnemonic_main[256] = { "nop" ,"ld bc,W" ,"ld (bc),a","inc bc" ,"inc b" ,"dec b" ,"ld b,B" ,"rlca" , "ex af,af'","add hl,bc","ld a,(bc)","dec bc" ,"inc c" ,"dec c" ,"ld c,B" ,"rrca" , "djnz R" ,"ld de,W" ,"ld (de),a","inc de" ,"inc d" ,"dec d" ,"ld d,B" ,"rla" , "jr R" ,"add hl,de","ld a,(de)","dec de" ,"inc e" ,"dec e" ,"ld e,B" ,"rra" , "jr nz,R" ,"ld hl,W" ,"ld (A),hl","inc hl" ,"inc h" ,"dec h" ,"ld h,B" ,"daa" , "jr z,R" ,"add hl,hl","ld hl,(A)","dec hl" ,"inc l" ,"dec l" ,"ld l,B" ,"cpl" , "jr nc,R" ,"ld sp,W" ,"ld (A),a" ,"inc sp" ,"inc (hl)" ,"dec (hl)" ,"ld (hl),B" ,"scf" , "jr c,R" ,"add hl,sp","ld a,(A)" ,"dec sp" ,"inc a" ,"dec a" ,"ld a,B" ,"ccf" , "ld b,b" ,"ld b,c" ,"ld b,d" ,"ld b,e" ,"ld b,h" ,"ld b,l" ,"ld b,(hl)" ,"ld b,a" , "ld c,b" ,"ld c,c" ,"ld c,d" ,"ld c,e" ,"ld c,h" ,"ld c,l" ,"ld c,(hl)" ,"ld c,a" , "ld d,b" ,"ld d,c" ,"ld d,d" ,"ld d,e" ,"ld d,h" ,"ld d,l" ,"ld d,(hl)" ,"ld d,a" , "ld e,b" ,"ld e,c" ,"ld e,d" ,"ld e,e" ,"ld e,h" ,"ld e,l" ,"ld e,(hl)" ,"ld e,a" , "ld h,b" ,"ld h,c" ,"ld h,d" ,"ld h,e" ,"ld h,h" ,"ld h,l" ,"ld h,(hl)" ,"ld h,a" , "ld l,b" ,"ld l,c" ,"ld l,d" ,"ld l,e" ,"ld l,h" ,"ld l,l" ,"ld l,(hl)" ,"ld l,a" , "ld (hl),b","ld (hl),c","ld (hl),d","ld (hl),e" ,"ld (hl),h","ld (hl),l","halt" ,"ld (hl),a", "ld a,b" ,"ld a,c" ,"ld a,d" ,"ld a,e" ,"ld a,h" ,"ld a,l" ,"ld a,(hl)" ,"ld a,a" , "add a,b" ,"add a,c" ,"add a,d" ,"add a,e" ,"add a,h" ,"add a,l" ,"add a,(hl)","add a,a" , "adc a,b" ,"adc a,c" ,"adc a,d" ,"adc a,e" ,"adc a,h" ,"adc a,l" ,"adc a,(hl)","adc a,a" , "sub b" ,"sub c" ,"sub d" ,"sub e" ,"sub h" ,"sub l" ,"sub (hl)" ,"sub a" , "sbc a,b" ,"sbc a,c" ,"sbc a,d" ,"sbc a,e" ,"sbc a,h" ,"sbc a,l" ,"sbc a,(hl)","sbc a,a" , "and b" ,"and c" ,"and d" ,"and e" ,"and h" ,"and l" ,"and (hl)" ,"and a" , "xor b" ,"xor c" ,"xor d" ,"xor e" ,"xor h" ,"xor l" ,"xor (hl)" ,"xor a" , "or b" ,"or c" ,"or d" ,"or e" ,"or h" ,"or l" ,"or (hl)" ,"or a" , "cp b" ,"cp c" ,"cp d" ,"cp e" ,"cp h" ,"cp l" ,"cp (hl)" ,"cp a" , "ret nz" ,"pop bc" ,"jp nz,A" ,"jp A" ,"call nz,A","push bc" ,"add a,B" ,"rst 00h" , "ret z" ,"ret" ,"jp z,A" ,"cb" ,"call z,A" ,"call A" ,"adc a,B" ,"rst 08h" , "ret nc" ,"pop de" ,"jp nc,A" ,"out (B),a" ,"call nc,A","push de" ,"sub B" ,"rst 10h" , "ret c" ,"exx" ,"jp c,A" ,"in a,(B)" ,"call c,A" ,"dd" ,"sbc a,B" ,"rst 18h" , "ret po" ,"pop hl" ,"jp po,A" ,"ex (sp),hl","call po,A","push hl" ,"and B" ,"rst 20h" , "ret pe" ,"jp (hl)" ,"jp pe,A" ,"ex de,hl" ,"call pe,A","ed" ,"xor B" ,"rst 28h" , "ret p" ,"pop af" ,"jp p,A" ,"di" ,"call p,A" ,"push af" ,"or B" ,"rst 30h" , "ret m" ,"ld sp,hl" ,"jp m,A" ,"ei" ,"call m,A" ,"fd" ,"cp B" ,"rst 38h" }; openmsx-debugger-0.0.0.svn20141006.orig/src/VDPCommandRegViewer.cpp0000644000175000017500000002547412414415132023754 0ustar shevekshevek#include "VDPCommandRegViewer.h" #include "CommClient.h" static const int VIEW_HEX = 1; static const int VIEW_SEPERATE = 2; static QString hex8bit(int val) { return QString("0x%1").arg(val, 2, 16, QChar('0')).toUpper(); } VDPCommandRegViewer::VDPCommandRegViewer(QWidget* parent) : QDialog(parent) { setupUi(this); regs = new unsigned char[64 + 16]; memset(regs, 0, 64 + 16); statusregs = regs + 64; // create the needed groups grp_sx = new view88to16(lineEdit_r32, lineEdit_r33, lineEdit_sx); connect(lineEdit_r32, SIGNAL(editingFinished()), grp_sx, SLOT(finishRL())); connect(lineEdit_r33, SIGNAL(editingFinished()), grp_sx, SLOT(finishRH())); connect(lineEdit_sx, SIGNAL(editingFinished()), grp_sx, SLOT(finishRW())); grp_sy = new view88to16(lineEdit_r34, lineEdit_r35, lineEdit_sy); connect(lineEdit_r34, SIGNAL(editingFinished()), grp_sy, SLOT(finishRL())); connect(lineEdit_r35, SIGNAL(editingFinished()), grp_sy, SLOT(finishRH())); connect(lineEdit_sy, SIGNAL(editingFinished()), grp_sy, SLOT(finishRW())); grp_dx = new view88to16(lineEdit_r36, lineEdit_r37, lineEdit_dx); connect(lineEdit_r36, SIGNAL(editingFinished()), grp_dx, SLOT(finishRL())); connect(lineEdit_r37, SIGNAL(editingFinished()), grp_dx, SLOT(finishRH())); connect(lineEdit_dx, SIGNAL(editingFinished()), grp_dx, SLOT(finishRW())); grp_dy = new view88to16(lineEdit_r38, lineEdit_r39, lineEdit_dy); connect(lineEdit_r38, SIGNAL(editingFinished()), grp_dy, SLOT(finishRL())); connect(lineEdit_r39, SIGNAL(editingFinished()), grp_dy, SLOT(finishRH())); connect(lineEdit_dy, SIGNAL(editingFinished()), grp_dy, SLOT(finishRW())); grp_nx = new view88to16(lineEdit_r40, lineEdit_r41, lineEdit_nx); connect(lineEdit_r40, SIGNAL(editingFinished()), grp_nx, SLOT(finishRL())); connect(lineEdit_r41, SIGNAL(editingFinished()), grp_nx, SLOT(finishRH())); connect(lineEdit_nx, SIGNAL(editingFinished()), grp_nx, SLOT(finishRW())); grp_ny = new view88to16(lineEdit_r42, lineEdit_r43, lineEdit_ny); connect(lineEdit_r42, SIGNAL(editingFinished()), grp_ny, SLOT(finishRL())); connect(lineEdit_r43, SIGNAL(editingFinished()), grp_ny, SLOT(finishRH())); connect(lineEdit_ny, SIGNAL(editingFinished()), grp_ny, SLOT(finishRW())); grp_sx->setRW(QString("0")); grp_sy->setRW(QString("0")); grp_dx->setRW(QString("0")); grp_dy->setRW(QString("0")); grp_nx->setRW(QString("0")); grp_ny->setRW(QString("0")); grp_l_sx = new view88to16(label_r_32, label_r_33, label_r_sx); grp_l_sy = new view88to16(label_r_34, label_r_35, label_r_sy); grp_l_dx = new view88to16(label_r_36, label_r_37, label_r_dx); grp_l_dy = new view88to16(label_r_38, label_r_39, label_r_dy); grp_l_nx = new view88to16(label_r_40, label_r_41, label_r_nx); grp_l_ny = new view88to16(label_r_42, label_r_43, label_r_ny); //Connect the checkboxes QList list = this->findChildren(); QCheckBox* item; foreach(item, list) { connect(item, SIGNAL(stateChanged(int)), this, SLOT(R45BitChanged(int))); } lineEdit_r44->setText("0x00"); lineEdit_r45->setText("0x00"); lineEdit_r46->setText("0x00"); R46 = 0; comboBox_cmd->setCurrentIndex(0); //decodeR46(R46); //on_comboBox_cmd_currentIndexChanged(); //get initiale data refresh(); } VDPCommandRegViewer::~VDPCommandRegViewer() { delete[] regs; } void VDPCommandRegViewer::on_lineEdit_r45_editingFinished() { //for now simply recheck all the checkBoxes and recreate R45 int val = lineEdit_r45->text().toInt(NULL, 0); int r45 = 0; QList list = findChildren(); QCheckBox* item; foreach(item, list) { int order = QString(item->objectName().right(1)).toInt(); if (val & (1 << order)) { r45 = r45 | (1 << order); item->setChecked(true); } else { item->setChecked(false); } } lineEdit_r45->setText(QString("0x%1").arg(r45, 2, 16, QChar('0')).toUpper()); label_arg->setText(QString("%1").arg(r45, 8, 2, QChar('0'))); } void VDPCommandRegViewer::on_comboBox_cmd_currentIndexChanged(int index) { if ((index < 7 || index > 9) && index != 11 && index != 5) { comboBox_operator->setEnabled(false); comboBox_operator->setCurrentIndex(5); } else { if (!comboBox_operator->isEnabled()) { comboBox_operator->setCurrentIndex(R46 & 15); } comboBox_operator->setEnabled(true); } R46 = (15 & R46) + 16 * index; decodeR46(R46); lineEdit_r46->setText(QString("0x%1").arg(R46, 2, 16, QChar('0')).toUpper()); } void VDPCommandRegViewer::on_comboBox_operator_currentIndexChanged(int index) { //if the cmd disables the combox then no influence on R45 if (!comboBox_operator->isEnabled()) return; R46 = index + (R46 & 0xF0); decodeR46(R46); lineEdit_r46->setText(QString("0x%1").arg(R46, 2, 16, QChar('0')).toUpper()); } void VDPCommandRegViewer::decodeR46(int val) { static const QString words[16] = { "-", "VDP", "VRAM", "CPU", "Byte", "Dot", "Stop", "Invalid", "Point", "Pset", "Search", "Line", "Logical move", "High-speed move" }; static const int dest[16] = { 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2 //refers to words }; static const int srce[16] = { 0, 0, 0, 0, 2, 1, 1, 1, 1, 2, 2, 3, 1, 2, 2, 3 //refers to words }; static const int data[16] = { 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4 //refers to words }; static const int cnam[16] = { 6, 7, 7, 7, 8, 9,10,11,12,12,12,12,13,13,13,13 //refers to words }; static const QString oper[16] = { "IMP", "AND", "OR", "EOR", "NOT", "---", "---", "---", "TIMP", "TAND", "TOR", "TEOR", "TNOT", "---", "---", "---", }; static const int argbold[16] = { 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x26, 0x2D, 0x2C, 0x2C, 0x1C, 0x2C, 0x2C, 0x3C, 0x2C, 0x2C, }; static const int regbold[16] = { 0x00, 0x00, 0x00, 0x00, 0x83, 0xCC, 0xC3, 0xFC, 0xFC, 0xBF, 0xB3, 0xFC, 0xFC, 0xBF, 0xAE, 0xFC, }; int operat = (val >> 0) & 15; int cmd = (val >> 4) & 15; QString explication = QString( "Command: %1 " "Destination: %2 " "Source: %3
" "Data: %4 " "Operation: %5"). arg(words[cnam[cmd]]). arg(words[dest[cmd]]). arg(words[srce[cmd]]). arg(words[data[cmd]]). arg(oper[operat]); label_expl1->setText(explication); //a Normal and a Bold font QFont fontN; QFont fontB; fontB.setBold(true); //set the checkbox font in bold if command uses the corresponding bit for (int b = 0; b < 7; ++b) { QCheckBox* item = findChild(QString("checkBoxBit_%1").arg(b)); item->setFont((argbold[cmd] & (1 << b)) ? fontB : fontN); } labelSX ->setFont((regbold[cmd] & 0x01) ? fontB : fontN); labelSY ->setFont((regbold[cmd] & 0x02) ? fontB : fontN); labelDX ->setFont((regbold[cmd] & 0x04) ? fontB : fontN); labelDY ->setFont((regbold[cmd] & 0x08) ? fontB : fontN); labelNX ->setFont((regbold[cmd] & 0x10) ? fontB : fontN); labelNY ->setFont((regbold[cmd] & 0x20) ? fontB : fontN); labelCOLOR->setFont((regbold[cmd] & 0x40) ? fontB : fontN); labelARG ->setFont((regbold[cmd] & 0x80) ? fontB : fontN); //TODO: create basic equivalent //TODO: warn about wrong stuff (majorant < minorant when line drawing for instance) } void VDPCommandRegViewer::on_syncPushButton_clicked() { syncRegToCmd(); } void VDPCommandRegViewer::on_launchPushButton_clicked() { unsigned char newregs[64]; memset(newregs, 0, 64); newregs[32] = lineEdit_r32->text().toInt(NULL, 0); newregs[33] = lineEdit_r33->text().toInt(NULL, 0); newregs[34] = lineEdit_r34->text().toInt(NULL, 0); newregs[35] = lineEdit_r35->text().toInt(NULL, 0); newregs[36] = lineEdit_r36->text().toInt(NULL, 0); newregs[37] = lineEdit_r37->text().toInt(NULL, 0); newregs[38] = lineEdit_r38->text().toInt(NULL, 0); newregs[39] = lineEdit_r39->text().toInt(NULL, 0); newregs[40] = lineEdit_r40->text().toInt(NULL, 0); newregs[41] = lineEdit_r41->text().toInt(NULL, 0); newregs[42] = lineEdit_r42->text().toInt(NULL, 0); newregs[43] = lineEdit_r43->text().toInt(NULL, 0); newregs[44] = lineEdit_r44->text().toInt(NULL, 0); newregs[45] = lineEdit_r45->text().toInt(NULL, 0); newregs[46] = lineEdit_r46->text().toInt(NULL, 0); WriteDebugBlockCommand* req = new WriteDebugBlockCommand( "{VDP regs}", 32, 15, newregs); CommClient::instance().sendCommand(req); } void VDPCommandRegViewer::on_lineEdit_r44_editingFinished() { int val = lineEdit_r44->text().toInt(NULL, 0); label_color->setText(QString("%1 %2"). arg((val >> 4) & 15, 4, 2, QChar('0')). arg((val >> 0) & 15, 4, 2, QChar('0'))); } void VDPCommandRegViewer::R45BitChanged(int state) { //for now simply recheck all the checkBoxes and recreate R45 int r45 = 0; QList list = findChildren(); QCheckBox* item; foreach(item, list) { if (item->isChecked()) { int order = QString(item->objectName().right(1)).toInt(); r45 = r45 | (1 << order); } } lineEdit_r45->setText(QString("0x%1").arg(r45, 2, 16, QChar('0')).toUpper()); label_arg->setText(QString("%1").arg(r45, 8, 2, QChar('0'))); } void VDPCommandRegViewer::on_lineEdit_r46_editingFinished() { int val = lineEdit_r46->text().toInt(NULL, 0) & 0xFF; lineEdit_r46->setText(QString("0x%1").arg(val, 2, 16, QChar('0')).toUpper()); R46 = val; decodeR46(R46); comboBox_operator->setCurrentIndex(R46 & 15); comboBox_cmd->setCurrentIndex((R46 >> 4) & 15); // this might hide the operator again :-) } void VDPCommandRegViewer::refresh() { //new SimpleHexRequest("{VDP regs}",0,64,regs, *this); //new SimpleHexRequest("{VDP status regs}",0,16,regs, *this); // now combined in one request: new SimpleHexRequest( "debug_bin2hex " "[ debug read_block {VDP regs} 0 64 ]" "[ debug read_block {VDP status regs} 0 16 ]", 64 + 16, regs, *this); } void VDPCommandRegViewer::syncRegToCmd() { grp_sx->setRL(hex8bit(regs[32])); grp_sx->setRH(hex8bit(regs[33])); grp_sy->setRL(hex8bit(regs[34])); grp_sy->setRH(hex8bit(regs[35])); grp_dx->setRL(hex8bit(regs[36])); grp_dx->setRH(hex8bit(regs[37])); grp_dy->setRL(hex8bit(regs[38])); grp_dy->setRH(hex8bit(regs[39])); grp_nx->setRL(hex8bit(regs[40])); grp_nx->setRH(hex8bit(regs[41])); grp_ny->setRL(hex8bit(regs[42])); grp_ny->setRH(hex8bit(regs[43])); lineEdit_r44->setText(hex8bit(regs[44])); on_lineEdit_r44_editingFinished(); lineEdit_r45->setText(hex8bit(regs[45])); on_lineEdit_r45_editingFinished(); lineEdit_r46->setText(hex8bit(regs[46])); on_lineEdit_r46_editingFinished(); } void VDPCommandRegViewer::DataHexRequestReceived() { grp_l_sx->setRL(hex8bit(regs[32])); grp_l_sx->setRH(hex8bit(regs[33])); grp_l_sy->setRL(hex8bit(regs[34])); grp_l_sy->setRH(hex8bit(regs[35])); grp_l_dx->setRL(hex8bit(regs[36])); grp_l_dx->setRH(hex8bit(regs[37])); grp_l_dy->setRL(hex8bit(regs[38])); grp_l_dy->setRH(hex8bit(regs[39])); grp_l_nx->setRL(hex8bit(regs[40])); grp_l_nx->setRH(hex8bit(regs[41])); grp_l_ny->setRL(hex8bit(regs[42])); grp_l_ny->setRH(hex8bit(regs[43])); label_r_44->setText(hex8bit(regs[44])); label_r_45->setText(hex8bit(regs[45])); label_r_46->setText(hex8bit(regs[46])); if (autoSyncRadioButton->isChecked()) syncRegToCmd(); } openmsx-debugger-0.0.0.svn20141006.orig/src/DebuggerData.cpp0000644000175000017500000002607612414415132022521 0ustar shevekshevek// $Id$ #include "DebuggerData.h" #include "Convert.h" #include #include // class MemoryLayout MemoryLayout::MemoryLayout() { for (int p = 0; p < 4; ++p) { primarySlot[p] = '0'; secondarySlot[p] = 'X'; mapperSegment[p] = 0; isSubslotted[p] = false; for (int q = 0; q < 4; ++q) { mapperSize[p][q] = 0; } } } // class Breakpoints static const char *BreakpointSetCodes[] = { "set_bp", "set_watchpoint read_mem", "set_watchpoint write_mem", "set_watchpoint read_io", "set_watchpoint write_io", "set_condition" }; static QString getNextArgument(QString& data, int& pos) { QString result; while (data[pos] == ' ' || data[pos] == '\t') ++pos; while (true) { if (data[pos] == ' ' || data[pos] == '\t') break; if (data[pos] == '}' || data[pos] == ']') break; result += data[pos]; ++pos; } return result; } bool Breakpoints::Breakpoint::operator==(const Breakpoint &bp) const { if (bp.type != type) return false; // compare address if (type != CONDITION) { if (bp.address != address) return false; if (type != BREAKPOINT) { int re1 = -1, re2 = -1; if (bp.regionEnd != -1 && bp.regionEnd != bp.address) re1 = bp.regionEnd; if ( regionEnd != -1 && regionEnd != address) re2 = regionEnd; if (re1 != re2) return false; } // compare slot if (bp.ps != ps || bp.ss != ss || bp.segment != segment) return false; } // compare condition return bp.condition == condition; } Breakpoints::Breakpoints() : memLayout(NULL) { } void Breakpoints::clear() { breakpoints.clear(); } void Breakpoints::setMemoryLayout(MemoryLayout* ml) { memLayout = ml; } QString Breakpoints::createSetCommand(Type type, int address, char ps, char ss, int segment, int endRange, QString condition) { QString cmd("debug %1 %2 %3"); QString addr, cond; // address or range if (type > BREAKPOINT && type < CONDITION && endRange > address) addr = QString("{%1 %2}").arg(address).arg(endRange); else addr = QString::number(address); // condition if (type == CONDITION) { cond = QString("{%1}").arg(condition); } else { condition = condition.simplified(); cond = QString("{ [ %1_in_slot %2 %3 %4 ] %5}") .arg(type == WATCHPOINT_MEMREAD || type == WATCHPOINT_MEMWRITE ? "watch" : "pc") .arg(ps==-1 ? 'X' : char('0'+ps)) .arg(ss==-1 ? 'X' : char('0'+ss)) .arg(segment==-1 ? QString('X') : QString::number(segment)) .arg(condition.isEmpty() ? QString() : QString("&& ( %1 ) ").arg(condition)); } return cmd.arg(BreakpointSetCodes[type]) .arg(addr) .arg(escapeXML(cond)); } QString Breakpoints::createRemoveCommand(const QString& id) { // find breakpoint QString cmd("debug remove_"); if (id.startsWith("bp")) cmd += "bp "; else if (id.startsWith("wp")) cmd += "watchpoint "; else cmd += "condition "; cmd += id; return cmd; } void Breakpoints::setBreakpoints(const QString& str) { breakpoints.clear(); QStringList bps = str.split('\n'); for (QStringList::Iterator it = bps.begin(); it != bps.end(); ++it) { if ( it->trimmed().isEmpty() ) continue; Breakpoint newBp; // set id int p = 0; newBp.id = getNextArgument(*it, p); // determine type if( it->startsWith("bp#") ) newBp.type = BREAKPOINT; else if( it->startsWith("wp#") ) { // determine watchpoint type QString wptype = getNextArgument(*it, p); if(wptype == "read_mem") newBp.type = WATCHPOINT_MEMREAD; else if(wptype == "write_mem") newBp.type = WATCHPOINT_MEMWRITE; else if(wptype == "read_io") newBp.type = WATCHPOINT_IOREAD; else if(wptype == "write_io") newBp.type = WATCHPOINT_IOWRITE; else //unknown continue; } else if( it->startsWith("cond#") ) { newBp.type = CONDITION; } else { // unknown continue; } // get address p++; if( newBp.type != CONDITION ) { if ((*it)[p] == '{') { p++; newBp.address = stringToValue(getNextArgument(*it, p)); int q = it->indexOf('}', p); newBp.regionEnd = stringToValue(it->mid(p, q-p)); p = q+1; } else { newBp.address = stringToValue(getNextArgument(*it, p)); newBp.regionEnd = newBp.address; } } else newBp.address = -1; // check and clip command (skip non-default commands) int q = it->lastIndexOf('{'); if (it->mid(q).simplified() != "{debug break}") continue; newBp.condition = it->mid(p, q-p).simplified(); unescapeXML(newBp.condition); parseCondition(newBp); insertBreakpoint(newBp); } } QString Breakpoints::mergeBreakpoints(const QString& str) { // copy breakpoints BreakpointList oldBps(breakpoints); // parse new list setBreakpoints(str); // check old list against new one QStringList mergeSet; while (!oldBps.empty()) { Breakpoint& old = oldBps.first(); BreakpointList::iterator newit = breakpoints.begin(); for (/**/; newit != breakpoints.end(); ++newit) { // check for identical data if (old == *newit) break; } if (newit == breakpoints.end()) { // create command to set this breakpoint again QString cmd = createSetCommand(old.type, old.address, old.ps, old.ss, old.segment, old.regionEnd, old.condition); mergeSet << cmd; } oldBps.removeFirst(); } return mergeSet.join(" ; "); } void Breakpoints::parseCondition(Breakpoint& bp) { bp.ps = -1; bp.ss = -1; bp.segment = -1; // first split off braces if (bp.condition[0] == '{' && bp.condition.endsWith('}')) { if (bp.type != CONDITION) { // check for slot argument QRegExp rx("^\\{\\s*\\[\\s*(pc|watch)_in_slot\\s([X0123])\\s([X0123])\\s(X|\\d{1,3})\\s*\\]\\s*(&&\\s*\\((.+)\\)\\s*)?\\}$"); if (rx.indexIn(bp.condition) == 0) { bool ok; bp.ps = rx.cap(2).toInt(&ok); if (!ok) bp.ps = -1; bp.ss = rx.cap(3).toInt(&ok); if (!ok) bp.ss = -1; bp.segment = rx.cap(4).toInt(&ok); if (!ok) bp.segment = -1; bp.condition = rx.cap(6).trimmed(); } else { bp.condition.chop(1); bp.condition = bp.condition.mid(1).trimmed(); } } else { bp.condition.chop(1); bp.condition = bp.condition.mid(1).trimmed(); } } } bool Breakpoints::inCurrentSlot(const Breakpoint& bp) { if (memLayout == NULL) return true; int page = (bp.address & 0xC000) >> 14; if (bp.ps == -1 || bp.ps == memLayout->primarySlot[page]) { if (memLayout->isSubslotted[bp.ps & 3]) { if (bp.ss == -1 || bp.ss == memLayout->secondarySlot[page]) { if (memLayout->mapperSize[bp.ps & 3][bp.ss & 3] > 0) { if (bp.segment == memLayout->mapperSegment[page]) { return true; } } else { return true; } } } else if (memLayout->mapperSize[bp.ps & 3][0] > 0) { if (bp.segment == memLayout->mapperSegment[page]) { return true; } } else { return true; } } return false; } void Breakpoints::insertBreakpoint(Breakpoint& bp) { for (BreakpointList::iterator it = breakpoints.begin(); it != breakpoints.end(); ++it) { if (it->address > bp.address) { breakpoints.insert(it, bp); return; } } breakpoints.append(bp); } int Breakpoints::breakpointCount() { return breakpoints.size(); } bool Breakpoints::isBreakpoint(quint16 addr, QString *id) { for (BreakpointList::const_iterator it = breakpoints.constBegin(); it != breakpoints.constEnd(); ++it) { if (it->type == BREAKPOINT && it->address == addr) { if (inCurrentSlot(*it)) { if (id) *id = it->id; return true; } } } return false; } bool Breakpoints::isWatchpoint(quint16 addr, QString *id) { for (BreakpointList::const_iterator it = breakpoints.constBegin(); it != breakpoints.constEnd(); ++it) { if (it->type == WATCHPOINT_MEMREAD || it->type == WATCHPOINT_MEMWRITE) if ( (it->address == addr && it->regionEnd < it->address) || (addr >= it->address && addr <= it->regionEnd) ) { if (inCurrentSlot(*it)) { if (id) *id = it->id; return true; } } } return false; } int Breakpoints::findBreakpoint(quint16 addr) { // stub // will implement findfirst/findnext scheme for speed return addr; } int Breakpoints::findNextBreakpoint() { // stub // will implement findfirst/findnext scheme for speed return -1; } void Breakpoints::saveBreakpoints(QXmlStreamWriter& xml) { // write symbols for (BreakpointList::iterator it = breakpoints.begin(); it != breakpoints.end(); ++it) { xml.writeStartElement("Breakpoint"); // type switch (it->type) { case BREAKPOINT: xml.writeAttribute("type", "breakpoint"); break; case WATCHPOINT_IOREAD: xml.writeAttribute("type", "ioread"); break; case WATCHPOINT_IOWRITE: xml.writeAttribute("type", "iowrite"); break; case WATCHPOINT_MEMREAD: xml.writeAttribute("type", "memread"); break; case WATCHPOINT_MEMWRITE: xml.writeAttribute("type", "memwrite"); break; case CONDITION: xml.writeAttribute("type", "condition"); break; } // id xml.writeAttribute("id", it->id); // slot/segment xml.writeAttribute("primarySlot", QString(it->ps < 0 ? '*' : char('0'+it->ps))); xml.writeAttribute("secondarySlot", QString(it->ss < 0 ? '*' : char('0'+it->ss))); xml.writeAttribute("segment", QString::number(it->segment)); // address if (it->type == BREAKPOINT) { xml.writeTextElement("address", QString::number(it->address)); } else if (it->type != CONDITION) { xml.writeTextElement("regionStart", QString::number(it->address)); xml.writeTextElement("regionEnd", QString::number(it->regionEnd)); } // condition xml.writeTextElement("condition", it->condition); // complete xml.writeEndElement(); } } void Breakpoints::loadBreakpoints(QXmlStreamReader& xml) { Breakpoint bp; while (!xml.atEnd()) { xml.readNext(); // exit if closing of main tag if (xml.isEndElement()) { if (xml.name() == "Breakpoints") { break; } else if (xml.name() == "Breakpoint") { insertBreakpoint(bp); } } // begin tag if (xml.isStartElement()) { if (xml.name() == "Breakpoint") { // set type QString type = xml.attributes().value("type").toString().toLower(); if (type == "ioread") { bp.type = WATCHPOINT_IOREAD; } else if (type == "iowrite") { bp.type = WATCHPOINT_IOWRITE; } else if (type == "memread") { bp.type = WATCHPOINT_MEMREAD; } else if (type == "memwrite") { bp.type = WATCHPOINT_MEMWRITE; } else if (type == "condition") { bp.type = CONDITION; } else { bp.type = BREAKPOINT; } // id bp.id = xml.attributes().value("id").toString(); // slot/segment char c = xml.attributes().value("primarySlot").at(0).toLatin1(); bp.ps = c >= '0' && c <= '3' ? c - '0' : -1; c = xml.attributes().value("secondarySlot").at(0).toLatin1(); bp.ss = c >= '0' && c <= '3' ? c - '0' : -1; bp.segment = xml.attributes().value("segment").toString().toInt(); } else if (xml.name() == "address" || xml.name() == "regionStart") { // read symbol name bp.address = xml.readElementText().toInt(); if (bp.type == BREAKPOINT) bp.regionEnd = bp.address; } else if (xml.name() == "regionEnd") { // read symbol name bp.regionEnd = xml.readElementText().toInt(); } else if (xml.name() == "condition") { bp.condition = xml.readElementText().simplified(); } } } } openmsx-debugger-0.0.0.svn20141006.orig/src/MainMemoryViewer.cpp0000644000175000017500000000704512414415132023435 0ustar shevekshevek// $Id: $ #include "MainMemoryViewer.h" #include "HexViewer.h" #include "CPURegs.h" #include "CPURegsViewer.h" #include "SymbolTable.h" #include "Convert.h" #include #include #include #include #include const int MainMemoryViewer::linkRegisters[] = { CpuRegs::REG_BC, CpuRegs::REG_DE, CpuRegs::REG_HL, CpuRegs::REG_IX, CpuRegs::REG_IY, CpuRegs::REG_BC2, CpuRegs::REG_DE2, CpuRegs::REG_HL2, CpuRegs::REG_PC, CpuRegs::REG_SP }; MainMemoryViewer::MainMemoryViewer(QWidget* parent) : QWidget(parent) { // create selection list, address edit line and viewer addressSourceList = new QComboBox(); addressSourceList->setEditable(false); addressSourceList->addItem("Address:"); for (int i = 0; i < 10; ++i) { QString txt = QString("Linked to "); txt.append(CpuRegs::regNames[linkRegisters[i]]); addressSourceList->addItem(txt); } addressValue = new QLineEdit(); addressValue->setText(hexValue(0, 4)); //addressValue->setEditable(false); hexView = new HexViewer(); hexView->setUseMarker(true); hexView->setIsEditable(true); hexView->setIsInteractive(true); hexView->setDisplayMode(HexViewer::FILL_WIDTH_POWEROF2); QHBoxLayout* hbox = new QHBoxLayout(); hbox->setMargin(0); hbox->addWidget(addressSourceList); hbox->addWidget(addressValue); QVBoxLayout* vbox = new QVBoxLayout(); vbox->setMargin(0); vbox->addLayout(hbox); vbox->addWidget(hexView); setLayout(vbox); isLinked = false; linkedId = 0; regsViewer = NULL; symTable = 0; connect(hexView, SIGNAL(locationChanged(int)), this, SLOT(hexViewChanged(int))); connect(addressValue, SIGNAL(returnPressed()), this, SLOT(addressValueChanged())); connect(addressSourceList, SIGNAL(currentIndexChanged(int)), this, SLOT(addressSourceListChanged(int))); } void MainMemoryViewer::settingsChanged() { hexView->settingsChanged(); } void MainMemoryViewer::setLocation(int addr) { addressValue->setText(hexValue(addr, 4).toUpper()); hexView->setLocation(addr); } void MainMemoryViewer::setDebuggable(const QString& name, int size) { hexView->setDebuggable(name, size); } void MainMemoryViewer::setRegsView(CPURegsViewer* viewer) { regsViewer = viewer; } void MainMemoryViewer::setSymbolTable(SymbolTable* symtable) { symTable = symtable; } void MainMemoryViewer::refresh() { hexView->refresh(); } void MainMemoryViewer::hexViewChanged(int addr) { addressValue->setText(hexValue(addr, 4).toUpper()); } void MainMemoryViewer::addressValueChanged() { int addr = stringToValue(addressValue->text()); if (addr == -1 && symTable) { // try finding a label Symbol *s = symTable->getAddressSymbol(addressValue->text()); if (!s) s = symTable->getAddressSymbol(addressValue->text(), Qt::CaseInsensitive); if (s) addr = s->value(); } if(addr >= 0) hexView->setLocation(addr); } void MainMemoryViewer::registerChanged(int id, int value) { if (!isLinked || (id != linkedId)) { return; } addressValue->setText(hexValue(value, 4).toUpper()); hexView->setLocation(value); //hexView->refresh(); } void MainMemoryViewer::addressSourceListChanged(int index) { if (index == 0) { isLinked = false; addressValue->setReadOnly(false); hexView->setIsInteractive(true); } else { isLinked = true; linkedId = linkRegisters[index - 1]; addressValue->setReadOnly(true); hexView->setIsInteractive(false); if (regsViewer) { setLocation(regsViewer->readRegister(linkedId)); } } } openmsx-debugger-0.0.0.svn20141006.orig/src/VDPDataStore.cpp0000644000175000017500000000433612414415132022436 0ustar shevekshevek#include "VDPDataStore.h" #include "CommClient.h" class VDPDataStoreVersionCheck : public SimpleCommand { public: VDPDataStoreVersionCheck(VDPDataStore& dataStore_) : SimpleCommand("debug desc {physical VRAM}") , dataStore(dataStore_) { } virtual void replyOk(const QString& message) { dataStore.old_version = false; dataStore.got_version = true; dataStore.refresh(); delete this; } virtual void replyNok(const QString& message) { dataStore.old_version = true; dataStore.got_version = true; dataStore.refresh(); delete this; } private: VDPDataStore& dataStore; }; static const unsigned TOTAL_SIZE = 0x20000 + 32 + 16 + 64 + 2; VDPDataStore::VDPDataStore() { vram = new unsigned char[TOTAL_SIZE]; memset(vram, 0x00, TOTAL_SIZE); got_version = false; old_version = false; CommClient::instance().sendCommand(new VDPDataStoreVersionCheck(*this)); } VDPDataStore::~VDPDataStore() { delete[] vram; } VDPDataStore& VDPDataStore::instance() { static VDPDataStore oneInstance; return oneInstance; } void VDPDataStore::refresh() { if (!got_version) return; QString req; if (old_version) { req = QString( "debug_bin2hex " "[ debug read_block {VRAM} 0 0x20000 ]" "[ debug read_block {VDP palette} 0 32 ]" "[ debug read_block {VDP status regs} 0 16 ]" "[ debug read_block {VDP regs} 0 64 ]" "[ debug read_block {VRAM pointer} 0 2 ]"); } else { req = QString( "debug_bin2hex " "[ debug read_block {physical VRAM} 0 0x20000 ]" "[ debug read_block {VDP palette} 0 32 ]" "[ debug read_block {VDP status regs} 0 16 ]" "[ debug read_block {VDP regs} 0 64 ]" "[ debug read_block {VRAM pointer} 0 2 ]"); } new SimpleHexRequest(req, TOTAL_SIZE, vram, *this); } void VDPDataStore::DataHexRequestReceived() { emit dataRefreshed(); } const unsigned char* VDPDataStore::getVramPointer() const { return vram; } const unsigned char* VDPDataStore::getPalettePointer() const { return vram + 0x20000; } const unsigned char* VDPDataStore::getStatusRegsPointer() const { return vram + 0x20000 + 32; } const unsigned char* VDPDataStore::getRegsPointer() const { return vram + 0x20000 + 32 + 16; } const unsigned char* VDPDataStore::getVdpVramPointer() const { return vram + 0x20000 + 32 + 16 + 64; } openmsx-debugger-0.0.0.svn20141006.orig/src/InteractiveButton.cpp0000644000175000017500000000331712414415132023645 0ustar shevekshevek#include "InteractiveButton.h" #include #include InteractiveButton::InteractiveButton(QWidget* parent) : QPushButton(parent) { setEnabled(true); setAutoFillBackground(true); _mustBeSet=false; _highlight=false; connect(this, SIGNAL(toggled(bool)), this, SLOT(newBitValueSlot(bool))); } void InteractiveButton::highlight(bool state) { if (_highlight == state) return; _highlight=state; setColor(); } void InteractiveButton::setColor() { // No style sheet since this will not work for Mac OS X atm. QPalette fiddle = QApplication::palette(); int colorset=(_mustBeSet?4:0)+(_highlight?2:0)+((_mustBeSet&!_state)?1:0); switch (colorset) { case 6: fiddle.setColor(QPalette::Active, QPalette::Button, Qt::green); break; case 4: fiddle.setColor(QPalette::Active, QPalette::Button, Qt::darkGreen); break; case 3: case 7: fiddle.setColor(QPalette::Active, QPalette::Button, Qt::red); break; case 2: fiddle.setColor(QPalette::Active, QPalette::Button, Qt::yellow); break; case 5: case 1: fiddle.setColor(QPalette::Active, QPalette::Button, Qt::darkRed); break; }; setPalette(fiddle); update(); } void InteractiveButton::enterEvent(QEvent* event) { emit mouseOver(true); } void InteractiveButton::leaveEvent(QEvent* event) { emit mouseOver(false); } void InteractiveButton::newBitValueSlot(bool state) { _state=state; QString name = objectName(); int bit = name.right(1).toInt(); int reg = name.mid( 1 + name.indexOf('_'), name.lastIndexOf('_') - name.indexOf('_') - 1).toInt(); emit newBitValue(reg, bit, state); setColor(); } void InteractiveButton::mustBeSet(bool state) { if (state == _mustBeSet) return; _mustBeSet=state; setColor(); } openmsx-debugger-0.0.0.svn20141006.orig/src/ConnectDialog.cpp0000644000175000017500000001763212414415132022712 0ustar shevekshevek// $Id$ #include "ConnectDialog.h" #include #include #include #include #include #include #include #ifdef _WIN32 #include "SspiNegotiateClient.h" #include "QAbstractSocketStreamWrapper.h" #include #include #include using namespace openmsx; #else #include #include #include #include #include #endif // Helper functions to setup a connection static QString getUserName() { #ifdef _WIN32 return "default"; #else struct passwd* pw = getpwuid(getuid()); return pw->pw_name ? pw->pw_name : ""; #endif } static bool checkSocketDir(const QDir& dir) { if (!dir.exists()) { return false; } #ifndef _WIN32 // only do permission and owner checks on *nix QFileInfo info(dir.absolutePath()); if (info.ownerId() != getuid()) { return false; } int all = QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner | QFile::ReadGroup | QFile::WriteGroup | QFile::ExeGroup | QFile::ReadOther | QFile::WriteOther | QFile::ExeOther; int needed = QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner; if ((info.permissions() & all) != needed) { return false; } #endif return true; } static bool checkSocket(const QFileInfo& info) { if (!info.fileName().startsWith("socket.")) { // wrong name return false; } #ifndef _WIN32 // only do permission and owner checks on *nix int all = QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner | QFile::ReadGroup | QFile::WriteGroup | QFile::ExeGroup | QFile::ReadOther | QFile::WriteOther | QFile::ExeOther; int needed = QFile::ReadOwner | QFile::WriteOwner; if ((info.permissions() & all) != needed) { return false; } if (info.ownerId() != getuid()) { return false; } #endif return true; } static void deleteSocket(const QFileInfo& info) { QFile::remove(info.absoluteFilePath()); // ignore errors QDir dir; dir.rmdir(info.absolutePath()); // ignore errors } static OpenMSXConnection* createConnection(const QDir& dir, const QString& socketName) { QFileInfo info(dir, socketName); if (!checkSocket(info)) { // invalid socket return NULL; } QAbstractSocket* socket = NULL; #ifdef _WIN32 int port = -1; std::ifstream in(info.absoluteFilePath().toLatin1().data()); in >> port; if (port != -1) { QHostAddress localhost(QHostAddress::LocalHost); socket = new QTcpSocket(); socket->connectToHost(localhost, port); QAbstractSocketStreamWrapper stream(socket); SspiNegotiateClient client(stream); if (!socket->waitForConnected(1000) || !client.Authenticate()) { delete socket; socket = NULL; } } #else int sd = ::socket(AF_UNIX, SOCK_STREAM, 0); if (sd != -1) { sockaddr_un addr; addr.sun_family = AF_UNIX; strcpy(addr.sun_path, info.absoluteFilePath().toLatin1().data()); if (connect(sd, (sockaddr*)&addr, sizeof(addr)) != -1) { socket = new QTcpSocket(); if (!socket->setSocketDescriptor(sd)) { // failed to wrap socket in QTcpSocket delete socket; socket = NULL; close(sd); } } else { // failed to connect to UNIX socket close(sd); } } #endif if (socket) { return new OpenMSXConnection(socket); } else { // cannot connect, must be a stale socket, try to clean it up deleteSocket(socketName); return NULL; } } static void collectServers(QList& servers) { QDir dir((getenv("TMPDIR")) ? getenv("TMPDIR") : QDir::tempPath()); dir.cd("openmsx-" + getUserName()); if (!checkSocketDir(dir)) { // no correct socket directory return; } QDir::Filters filters = #ifdef _WIN32 QDir::Files; // regular files for win32 #else QDir::System; // sockets for *nix #endif foreach (QString name, dir.entryList(filters)) { if (OpenMSXConnection* connection = createConnection(dir, name)) { servers.push_back(connection); } } } // ConnectionInfoRequest class ConnectionInfoRequest::ConnectionInfoRequest( ConnectDialog& dialog_, OpenMSXConnection& connection_) : dialog(dialog_), connection(connection_) { state = GET_MACHINE; connection.sendCommand(this); } QString ConnectionInfoRequest::getCommand() const { switch (state) { case GET_MACHINE: return "machine_info config_name"; case GET_TITLE: return "guess_title"; default: assert(false); return ""; } } void ConnectionInfoRequest::replyOk(const QString& message) { switch (state) { case GET_MACHINE: title = message; state = GET_TITLE; connection.sendCommand(this); break; case GET_TITLE: { if (!message.isEmpty()) { title += " (" + message + ")"; } dialog.connectionOk(connection, title); state = DONE; connect(&connection, SIGNAL(disconnected()), this, SLOT(terminate())); break; } default: assert(false); } } void ConnectionInfoRequest::replyNok(const QString& /*message*/) { cancel(); } void ConnectionInfoRequest::cancel() { dialog.connectionBad(connection); } void ConnectionInfoRequest::terminate() { cancel(); } // class ConnectDialog OpenMSXConnection* ConnectDialog::getConnection(QWidget* parent) { ConnectDialog dialog(parent); // delay for at most 500ms while checking the connections dialog.delay = 1; dialog.startTimer(500); while (!dialog.pendingConnections.empty() && dialog.delay) { qApp->processEvents(QEventLoop::AllEvents, 200); } // if there is only one valid connection, use it immediately, // otherwise execute the dialog. if (dialog.pendingConnections.empty() && dialog.confirmedConnections.size() == 1 ) { dialog.on_connectButton_clicked(); } else { dialog.exec(); } return dialog.result; } ConnectDialog::ConnectDialog(QWidget* parent) : QDialog(parent) , result(NULL) { ui.setupUi(this); on_rescanButton_clicked(); } ConnectDialog::~ConnectDialog() { clear(); } void ConnectDialog::timerEvent(QTimerEvent* event) { killTimer(event->timerId()); delay = 0; } void ConnectDialog::clear() { ui.listConnections->clear(); // First kill the infos. That will remove the disconnect signals. qDeleteAll(connectionInfos); connectionInfos.clear(); qDeleteAll(pendingConnections); pendingConnections.clear(); qDeleteAll(confirmedConnections); confirmedConnections.clear(); } void ConnectDialog::on_connectButton_clicked() { int row = ui.listConnections->currentRow(); if (row != -1) { assert((0 <= row) && (row < confirmedConnections.size())); result = confirmedConnections[row]; confirmedConnections.removeAt(row); } accept(); } void ConnectDialog::on_rescanButton_clicked() { clear(); collectServers(pendingConnections); foreach (OpenMSXConnection* connection, pendingConnections) { connectionInfos.append(new ConnectionInfoRequest(*this, *connection)); } } void ConnectDialog::connectionOk(OpenMSXConnection& connection, const QString& title) { OpenMSXConnections::iterator it = qFind(pendingConnections.begin(), pendingConnections.end(), &connection); if (it == pendingConnections.end()) { // connection is already beiing destoyed return; } pendingConnections.erase(it); confirmedConnections.push_back(&connection); new QListWidgetItem(title, ui.listConnections); if (ui.listConnections->count() == 1) { // automatically select first row ui.listConnections->setCurrentRow(0); } } void ConnectDialog::connectionBad(OpenMSXConnection& connection) { OpenMSXConnections::iterator it = qFind(pendingConnections.begin(), pendingConnections.end(), &connection); if (it == pendingConnections.end()) { // was this connection established but terminated? int id = confirmedConnections.indexOf(&connection); if (id >= 0) { OpenMSXConnection* conn = confirmedConnections.takeAt(id); QListWidgetItem* item = ui.listConnections->takeItem(id); delete item; conn->deleteLater(); } return; } pendingConnections.erase(it); connection.deleteLater(); } openmsx-debugger-0.0.0.svn20141006.orig/src/SymbolManager.h0000644000175000017500000000472112414415132022401 0ustar shevekshevek// $Id$ #ifndef SYMBOLMANAGER_OPENMSX_H #define SYMBOLMANAGER_OPENMSX_H #include "ui_SymbolManager.h" class SymbolTable; class QTreeWidgetItem; class SymbolManager : public QDialog, private Ui::SymbolManager { Q_OBJECT public: SymbolManager(SymbolTable& symtable, QWidget* parent = 0); private: void closeEvent(QCloseEvent* e); void initFileList(); void initSymbolList(); void closeEditor(); // formatting functions void updateItemName(QTreeWidgetItem* item); void updateItemType(QTreeWidgetItem* item); void updateItemValue(QTreeWidgetItem* item); void updateItemSlots(QTreeWidgetItem* item); void updateItemSegments(QTreeWidgetItem* item); void updateItemRegisters(QTreeWidgetItem* item); void beginTreeLabelsUpdate(); void endTreeLabelsUpdate(); SymbolTable& symTable; int treeLabelsUpdateCount; QCheckBox* chkSlots[16]; QCheckBox* chkRegs[18]; QTreeWidgetItem* editItem; int editColumn; private slots: void fileSelectionChange(); void addFile(); void removeFile(); void reloadFiles(); void addLabel(); void removeLabel(); void labelEdit(QTreeWidgetItem* item, int column); void labelChanged(QTreeWidgetItem* item, int column); void labelSelectionChanged(); void changeType(bool checked); void changeSlot(int id, int state); void changeSlot00(int state); void changeSlot01(int state); void changeSlot02(int state); void changeSlot03(int state); void changeSlot10(int state); void changeSlot11(int state); void changeSlot12(int state); void changeSlot13(int state); void changeSlot20(int state); void changeSlot21(int state); void changeSlot22(int state); void changeSlot23(int state); void changeSlot30(int state); void changeSlot31(int state); void changeSlot32(int state); void changeSlot33(int state); void changeRegister(int id, int state); void changeRegisterA(int state); void changeRegisterB(int state); void changeRegisterC(int state); void changeRegisterD(int state); void changeRegisterE(int state); void changeRegisterH(int state); void changeRegisterL(int state); void changeRegisterBC(int state); void changeRegisterDE(int state); void changeRegisterHL(int state); void changeRegisterIX(int state); void changeRegisterIY(int state); void changeRegisterIXL(int state); void changeRegisterIXH(int state); void changeRegisterIYL(int state); void changeRegisterIYH(int state); void changeRegisterOffset(int state); void changeRegisterI(int state); signals: void symbolTableChanged(); }; #endif // SYMBOLMANAGER_OPENMSX_H openmsx-debugger-0.0.0.svn20141006.orig/src/DebugSession.h0000644000175000017500000000126212414415132022230 0ustar shevekshevek// $Id$ #ifndef DEBUGSESSION_H #define DEBUGSESSION_H #include "DebuggerData.h" #include "SymbolTable.h" #include class QXmlStreamReader; class DebugSession : public QObject { Q_OBJECT public: DebugSession(); // session void clear(); void open(const QString& file); bool save(); bool saveAs(const QString& file); bool existsAsFile() const; const QString& filename() const; bool isModified() const; Breakpoints& breakpoints(); SymbolTable& symbolTable(); private: void skipUnknownElement(QXmlStreamReader& ses); Breakpoints breaks; SymbolTable symTable; QString fileName; bool modified; public slots: void sessionModified(); }; #endif // DEBUGSESSION_H openmsx-debugger-0.0.0.svn20141006.orig/src/node.mk0000644000175000017500000000153112414415132020742 0ustar shevekshevek# $Id$ include build/node-start.mk SUBDIRS:= \ openmsx MOC_SRC_HDR:= \ DockableWidget DockableWidgetArea DockableWidgetLayout \ CPURegsViewer CommClient DebuggerForm DisasmViewer FlagsViewer HexViewer \ SlotViewer StackViewer ConnectDialog OpenMSXConnection SymbolManager \ Settings PreferencesDialog BreakpointDialog DebuggableViewer \ DebugSession MainMemoryViewer BitMapViewer VramBitMappedView \ VDPDataStore VDPStatusRegViewer VDPRegViewer InteractiveLabel \ InteractiveButton VDPCommandRegViewer GotoDialog SymbolTable SRC_HDR:= \ DockManager Dasm DasmTables DebuggerData SymbolTable Convert Version \ CPURegs SimpleHexRequest SRC_ONLY:= \ main UI:= \ ConnectDialog SymbolManager PreferencesDialog BreakpointDialog \ BitMapViewer VDPStatusRegisters VDPRegistersExplained VDPCommandRegisters \ GotoDialog include build/node-end.mk openmsx-debugger-0.0.0.svn20141006.orig/src/FlagsViewer.h0000644000175000017500000000113612414415132022054 0ustar shevekshevek// $Id$ #ifndef FLAGSVIEWER_H #define FLAGSVIEWER_H #include class QPainter; class QResizeEvent; class QPaintEvent; class QString; class FlagsViewer : public QFrame { Q_OBJECT; public: FlagsViewer(QWidget* parent = 0); QSize sizeHint() const; public slots: void setFlags(quint8 newFlags); private: void resizeEvent(QResizeEvent* e); void paintEvent(QPaintEvent* e); void drawValue(QPainter& p, int x, int y, const QString& str, const bool changed); int frameL, frameR, frameT, frameB; unsigned char flags; unsigned char flagsChanged; }; #endif // FLAGSVIEWER_H openmsx-debugger-0.0.0.svn20141006.orig/src/DisasmViewer.h0000644000175000017500000000373212414415132022244 0ustar shevekshevek// $Id$ #ifndef DISASMVIEWER_H #define DISASMVIEWER_H #include "Dasm.h" #include #include class CommMemoryRequest; class QScrollBar; class Breakpoints; class SymbolTable; struct MemoryLayout; class DisasmViewer : public QFrame { Q_OBJECT; public: DisasmViewer(QWidget* parent = 0); void setMemory(unsigned char* memPtr); void setBreakpoints(Breakpoints* bps); void setMemoryLayout(MemoryLayout* ml); void setSymbolTable(SymbolTable* st); void memoryUpdated(CommMemoryRequest* req); void updateCancelled(CommMemoryRequest* req); quint16 programCounter() const; quint16 cursorAddress() const; QSize sizeHint() const; enum {Top, Middle, Bottom, Closest, TopAlways, MiddleAlways, BottomAlways}; public slots: void setAddress(quint16 addr, int infoLine = FIRST_INFO_LINE, int method = Top); void setCursorAddress(quint16 addr, int infoLine = FIRST_INFO_LINE, int method = Top); void setProgramCounter(quint16 pc); void scrollBarAction(int action); void scrollBarChanged(int value); void settingsChanged(); void symbolsChanged(); private: void resizeEvent(QResizeEvent* e); void paintEvent(QPaintEvent* e); void keyPressEvent(QKeyEvent* e); void mousePressEvent(QMouseEvent* e); void wheelEvent(QWheelEvent* e); QScrollBar* scrollBar; QPixmap breakMarker; QPixmap watchMarker; QPixmap pcMarker; quint16 programAddr; quint16 cursorAddr; int cursorLine; // layout information int frameL, frameR, frameT, frameB; int labelFontHeight, labelFontAscent; int codeFontHeight, codeFontAscent; int xAddr, xMCode[4], xMnem, xMnemArg; int visibleLines, partialBottomLine; int disasmTopLine; DisasmLines disasmLines; // display data unsigned char* memory; bool waitingForData; CommMemoryRequest* nextRequest; Breakpoints* breakpoints; MemoryLayout* memLayout; SymbolTable* symTable; int findDisasmLine(quint16 lineAddr, int infoLine = 0); int lineAtPos(const QPoint& pos); signals: void toggleBreakpoint(int addr); }; #endif // DISASMVIEWER_H openmsx-debugger-0.0.0.svn20141006.orig/src/SymbolManager.cpp0000644000175000017500000005611312414415132022736 0ustar shevekshevek// $Id$ #include "SymbolManager.h" #include "SymbolTable.h" #include "Settings.h" #include "Convert.h" #include #include #include SymbolManager::SymbolManager(SymbolTable& symtable, QWidget* parent) : QDialog(parent), symTable(symtable) { setupUi(this); // restore layout Settings& s = Settings::get(); restoreGeometry(s.value("SymbolManager/WindowGeometry", saveGeometry()).toByteArray()); treeFiles->header()->restoreState(s.value("SymbolManager/HeaderFiles", treeFiles->header()->saveState()).toByteArray()); treeLabels->header()->restoreState(s.value("SymbolManager/HeaderSymbols", treeLabels->header()->saveState()).toByteArray()); treeLabelsUpdateCount = 0; editColumn = -1; // put slot checkboxes in a convenience array chkSlots[ 0] = chk00; chkSlots[ 1] = chk01; chkSlots[ 2] = chk02; chkSlots[ 3] = chk03; chkSlots[ 4] = chk10; chkSlots[ 5] = chk11; chkSlots[ 6] = chk12; chkSlots[ 7] = chk13; chkSlots[ 8] = chk20; chkSlots[ 9] = chk21; chkSlots[10] = chk22; chkSlots[11] = chk23; chkSlots[12] = chk30; chkSlots[13] = chk31; chkSlots[14] = chk32; chkSlots[15] = chk33; chkRegs[ 0] = chkRegA; chkRegs[ 1] = chkRegB; chkRegs[ 2] = chkRegC; chkRegs[ 3] = chkRegD; chkRegs[ 4] = chkRegE; chkRegs[ 5] = chkRegH; chkRegs[ 6] = chkRegL; chkRegs[ 7] = chkRegBC; chkRegs[ 8] = chkRegDE; chkRegs[ 9] = chkRegHL; chkRegs[10] = chkRegIX; chkRegs[11] = chkRegIY; chkRegs[12] = chkRegIXL;chkRegs[13] = chkRegIXH;chkRegs[14] = chkRegIYL;chkRegs[15] = chkRegIYH; chkRegs[16] = chkRegOffset; chkRegs[17] = chkRegI; connect(treeFiles, SIGNAL(itemSelectionChanged()), this, SLOT(fileSelectionChange())); connect(btnAddFile, SIGNAL(clicked()), this, SLOT(addFile())); connect(btnRemoveFile, SIGNAL(clicked()), this, SLOT(removeFile())); connect(btnReloadFiles, SIGNAL(clicked()), this, SLOT(reloadFiles())); connect(treeLabels, SIGNAL(itemSelectionChanged()), this, SLOT(labelSelectionChanged())); connect(treeLabels, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), this, SLOT(labelEdit(QTreeWidgetItem*, int))); connect(treeLabels, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(labelChanged(QTreeWidgetItem*, int))); connect(btnAddSymbol, SIGNAL(clicked()), this, SLOT(addLabel())); connect(btnRemoveSymbol, SIGNAL(clicked()), this, SLOT(removeLabel())); connect(radJump, SIGNAL(toggled(bool)), this, SLOT(changeType(bool))); connect(radVar, SIGNAL(toggled(bool)), this, SLOT(changeType(bool))); connect(radValue, SIGNAL(toggled(bool)), this, SLOT(changeType(bool))); connect(chk00, SIGNAL(stateChanged(int)), this, SLOT(changeSlot00(int))); connect(chk01, SIGNAL(stateChanged(int)), this, SLOT(changeSlot01(int))); connect(chk02, SIGNAL(stateChanged(int)), this, SLOT(changeSlot02(int))); connect(chk03, SIGNAL(stateChanged(int)), this, SLOT(changeSlot03(int))); connect(chk10, SIGNAL(stateChanged(int)), this, SLOT(changeSlot10(int))); connect(chk11, SIGNAL(stateChanged(int)), this, SLOT(changeSlot11(int))); connect(chk12, SIGNAL(stateChanged(int)), this, SLOT(changeSlot12(int))); connect(chk13, SIGNAL(stateChanged(int)), this, SLOT(changeSlot13(int))); connect(chk20, SIGNAL(stateChanged(int)), this, SLOT(changeSlot20(int))); connect(chk21, SIGNAL(stateChanged(int)), this, SLOT(changeSlot21(int))); connect(chk22, SIGNAL(stateChanged(int)), this, SLOT(changeSlot22(int))); connect(chk23, SIGNAL(stateChanged(int)), this, SLOT(changeSlot23(int))); connect(chk30, SIGNAL(stateChanged(int)), this, SLOT(changeSlot30(int))); connect(chk31, SIGNAL(stateChanged(int)), this, SLOT(changeSlot31(int))); connect(chk32, SIGNAL(stateChanged(int)), this, SLOT(changeSlot32(int))); connect(chk33, SIGNAL(stateChanged(int)), this, SLOT(changeSlot33(int))); connect(chkRegA, SIGNAL(stateChanged(int)), this, SLOT(changeRegisterA(int))); connect(chkRegB, SIGNAL(stateChanged(int)), this, SLOT(changeRegisterB(int))); connect(chkRegC, SIGNAL(stateChanged(int)), this, SLOT(changeRegisterC(int))); connect(chkRegD, SIGNAL(stateChanged(int)), this, SLOT(changeRegisterD(int))); connect(chkRegE, SIGNAL(stateChanged(int)), this, SLOT(changeRegisterE(int))); connect(chkRegH, SIGNAL(stateChanged(int)), this, SLOT(changeRegisterH(int))); connect(chkRegL, SIGNAL(stateChanged(int)), this, SLOT(changeRegisterL(int))); connect(chkRegBC, SIGNAL(stateChanged(int)), this, SLOT(changeRegisterBC(int))); connect(chkRegDE, SIGNAL(stateChanged(int)), this, SLOT(changeRegisterDE(int))); connect(chkRegHL, SIGNAL(stateChanged(int)), this, SLOT(changeRegisterHL(int))); connect(chkRegIX, SIGNAL(stateChanged(int)), this, SLOT(changeRegisterIX(int))); connect(chkRegIY, SIGNAL(stateChanged(int)), this, SLOT(changeRegisterIY(int))); connect(chkRegIXL, SIGNAL(stateChanged(int)), this, SLOT(changeRegisterIXL(int))); connect(chkRegIXH, SIGNAL(stateChanged(int)), this, SLOT(changeRegisterIXH(int))); connect(chkRegIYL, SIGNAL(stateChanged(int)), this, SLOT(changeRegisterIYL(int))); connect(chkRegIYH, SIGNAL(stateChanged(int)), this, SLOT(changeRegisterIYH(int))); connect(chkRegOffset, SIGNAL(stateChanged(int)), this, SLOT(changeRegisterOffset(int))); connect(chkRegI, SIGNAL(stateChanged(int)), this, SLOT(changeRegisterI(int))); groupSlots->setEnabled(false); groupSegments->setEnabled(false); btnRemoveFile->setEnabled(false); btnRemoveSymbol->setEnabled(false); initFileList(); initSymbolList(); } void SymbolManager::closeEvent(QCloseEvent* e) { // store layout Settings& s = Settings::get(); s.setValue("SymbolManager/WindowGeometry", saveGeometry()); s.setValue("SymbolManager/HeaderFiles", treeFiles->header()->saveState()); s.setValue("SymbolManager/HeaderSymbols", treeLabels->header()->saveState()); QDialog::closeEvent(e); } /* * File list support functions */ void SymbolManager::initFileList() { treeFiles->clear(); for (int i = 0; i < symTable.symbolFilesSize(); ++i) { QTreeWidgetItem* item = new QTreeWidgetItem(treeFiles); item->setText(0, symTable.symbolFile(i)); item->setText(1, symTable.symbolFileRefresh(i).toString(Qt::LocaleDate)); } } void SymbolManager::addFile() { // create dialog QFileDialog* d = new QFileDialog(this); QStringList types; types << "All supported files (*.sym *.map)" << "tniASM 0.x symbol files (*.sym)" << "tniASM 1.x symbol files (*.sym)" << "asMSX 0.x symbol files (*.sym)" << "HiTech link map files (*.map)"; d->setNameFilters(types); d->setAcceptMode(QFileDialog::AcceptOpen); d->setFileMode(QFileDialog::ExistingFile); // set default directory d->setDirectory(Settings::get().value("SymbolManager/OpenDir", QDir::currentPath()).toString()); // run if (d->exec()) { QString f = d->selectedNameFilter(); QString n = d->selectedFiles().at(0); // load file from the correct type bool read = false; if (f.startsWith("tniASM 0")) { read = symTable.readFile(n, SymbolTable::TNIASM0_FILE); } else if (f.startsWith("tniASM 1")) { read = symTable.readFile(n, SymbolTable::TNIASM1_FILE); } else if (f.startsWith("asMSX")) { read = symTable.readFile(n, SymbolTable::ASMSX_FILE); } else if (f.startsWith("HiTech")) { read = symTable.readFile(n, SymbolTable::LINKMAP_FILE); } else { read = symTable.readFile(n); } // if read succesful, add it to the list if (read) { initFileList(); initSymbolList(); emit symbolTableChanged(); } } // store last used path Settings::get().setValue("SymbolManager/OpenDir", d->directory().absolutePath()); } void SymbolManager::removeFile() { int r = QMessageBox::question( this, tr("Remove symbol file(s)"), tr("When removing the symbol file(s), do you want keep or " "delete the attached symbols?"), "Keep symbols", "Delete symbols", "Cancel", 1, 2); if (r == 2) return; for (int i = 0; i < treeFiles->selectedItems().size(); ++i) { symTable.unloadFile(treeFiles->selectedItems().at(i)->text(0), r == 0); } initFileList(); initSymbolList(); emit symbolTableChanged(); } void SymbolManager::reloadFiles() { symTable.reloadFiles(); initFileList(); initSymbolList(); emit symbolTableChanged(); } void SymbolManager::fileSelectionChange() { btnRemoveFile->setEnabled(treeFiles->selectedItems().size()); } void SymbolManager::labelEdit(QTreeWidgetItem* item, int column) { // only symbol name and value are editable if (column == 0 || column == 2) { // open editor if manually added symbol Symbol* sym = (Symbol*)(item->data(0, Qt::UserRole).value()); if (sym->source() == 0) { // first close possible existing editor closeEditor(); // open new editor treeLabels->openPersistentEditor(item, column); editItem = item; editColumn = column; } } } /* * Symbol support functions */ void SymbolManager::initSymbolList() { treeLabels->clear(); beginTreeLabelsUpdate(); for (Symbol* sym = symTable.findFirstAddressSymbol(0); sym != 0; sym = symTable.findNextAddressSymbol()) { QTreeWidgetItem* item = new QTreeWidgetItem(treeLabels); // attach a pointer to the symbol object to the tree item item->setData(0L, Qt::UserRole, quintptr(sym)); // update columns updateItemName(item); updateItemType(item); updateItemValue(item); updateItemSlots(item); updateItemSegments(item); updateItemRegisters(item); } endTreeLabelsUpdate(); } void SymbolManager::beginTreeLabelsUpdate() { ++treeLabelsUpdateCount; } void SymbolManager::endTreeLabelsUpdate() { if (treeLabelsUpdateCount > 0) { --treeLabelsUpdateCount; } } void SymbolManager::closeEditor() { if (editColumn >= 0) { treeLabels->closePersistentEditor(editItem, editColumn); editColumn = -1; } } void SymbolManager::addLabel() { // create an empty symbol Symbol* sym = new Symbol(tr("New symbol"), 0); symTable.add(sym); beginTreeLabelsUpdate(); QTreeWidgetItem* item = new QTreeWidgetItem(treeLabels); item->setData(0, Qt::UserRole, quintptr(sym)); updateItemName(item); updateItemType(item); updateItemValue(item); updateItemSlots(item); updateItemSegments(item); updateItemRegisters(item); endTreeLabelsUpdate(); closeEditor(); treeLabels->setFocus(); treeLabels->setCurrentItem(item, 0); treeLabels->scrollToItem(item); treeLabels->openPersistentEditor(item, 0); editItem = item; editColumn = 0; // emit notification that something has changed emit symbolTableChanged(); } void SymbolManager::removeLabel() { QList selection = treeLabels->selectedItems(); // check for selection if (selection.empty()) return; // remove selected items bool deleted = false; for (QList::iterator selit = selection.begin(); selit != selection.end(); ++selit) { // get symbol Symbol* sym = (Symbol*)((*selit)->data(0, Qt::UserRole).value()); // check if symbol is from symbol file if (!sym->source()) { // remove from table symTable.remove(sym); deleted = true; } } if (deleted) { // refresh tree initSymbolList(); emit symbolTableChanged(); } } void SymbolManager::labelChanged(QTreeWidgetItem* item, int column) { if (!treeLabelsUpdateCount) { Symbol* sym = (Symbol*)(item->data(0, Qt::UserRole).value()); // Set symbol text from tree item if any QString symText = item->text(0).trimmed(); if (symText.isEmpty()) symText = "[unnamed]"; sym->setText(symText); // set value TODO: proper decoding of value int value = stringToValue(item->text(2)); if (value >= 0 && value < 65536) sym->setValue(value); treeLabels->closePersistentEditor(item, column); editColumn = -1; // update item name and value beginTreeLabelsUpdate(); updateItemName(item); updateItemValue(item); endTreeLabelsUpdate(); // notify change emit symbolTableChanged(); } } void SymbolManager::labelSelectionChanged() { // remove possible editor closeEditor(); QList selection = treeLabels->selectedItems(); // check if is available at all if (selection.empty()) { // disable everything btnRemoveSymbol->setEnabled(false); groupSlots->setEnabled(false); groupSegments->setEnabled(false); groupType->setEnabled(false); groupRegs8->setEnabled(false); groupRegs16->setEnabled(false); return; } // check selection for "manual insertion", identical slot mask, // identical register mask, identical types and value size bool removeButActive = true; bool anyEight = false; bool sameType = true; Symbol::SymbolType type; int slotMask, slotMaskMultiple = 0; int regMask, regMaskMultiple = 0; for (QList::iterator selit = selection.begin(); selit != selection.end(); ++selit) { // get symbol Symbol* sym = (Symbol*)((*selit)->data(0, Qt::UserRole).value()); // check if symbol is from symbol file if (sym->source()) removeButActive = false; if (selit == selection.begin()) { // first item, reference for slotMask and regMask slotMask = sym->validSlots(); regMask = sym->validRegisters(); type = sym->type(); } else { // other, set all different bits slotMaskMultiple |= slotMask ^ sym->validSlots(); regMaskMultiple |= regMask ^ sym->validRegisters(); // check for different type if (type != sym->type()) sameType = false; } // check for 8 bit values if ((sym->value() & 0xFF00) == 0) { anyEight = true; } } btnRemoveSymbol->setEnabled(removeButActive); groupSlots->setEnabled(true); groupType->setEnabled(true); groupRegs8->setEnabled(anyEight); groupRegs16->setEnabled(true); beginTreeLabelsUpdate(); // set slot selection for (int i = 0; i < 16; ++i) { chkSlots[i]->setTristate(false); if (slotMaskMultiple & 1) { chkSlots[i]->setCheckState(Qt::PartiallyChecked); } else if (slotMask & 1) { chkSlots[i]->setCheckState(Qt::Checked); } else { chkSlots[i]->setCheckState(Qt::Unchecked); } slotMask >>= 1; slotMaskMultiple >>= 1; } // set register selection for (int i = 0; i < 18; ++i) { chkRegs[i]->setTristate(false); if (regMaskMultiple & 1) { chkRegs[i]->setCheckState(Qt::PartiallyChecked); } else if (regMask & 1) { chkRegs[i]->setCheckState(Qt::Checked); } else { chkRegs[i]->setCheckState(Qt::Unchecked); } regMask >>= 1; regMaskMultiple >>= 1; } // temporarily disable exclusive radiobuttons to be able to // deselect them all. radJump->setAutoExclusive (false); radVar->setAutoExclusive (false); radValue->setAutoExclusive(false); // set type radio buttons radJump->setChecked (sameType && type == Symbol::JUMPLABEL); radVar->setChecked (sameType && type == Symbol::VARIABLELABEL); radValue->setChecked(sameType && type == Symbol::VALUE); // enable exclusive radiobuttons (this won't immediately activate // one if none are active). radJump->setAutoExclusive (true); radVar->setAutoExclusive (true); radValue->setAutoExclusive(true); endTreeLabelsUpdate(); } void SymbolManager::changeSlot(int id, int state) { if (treeLabelsUpdateCount) return; // disallow another tristate selection chkSlots[id]->setTristate(false); // get selected items QList selection = treeLabels->selectedItems(); // update items beginTreeLabelsUpdate(); int bit = 1 << id; for (QList::iterator selit = selection.begin(); selit != selection.end(); ++selit) { Symbol* sym = (Symbol*)((*selit)->data(0, Qt::UserRole).value()); // set or clear bit if (state == Qt::Checked) { sym->setValidSlots(sym->validSlots() | bit); } else { sym->setValidSlots(sym->validSlots() & ~bit); } // update item in treewidget updateItemSlots(*selit); } endTreeLabelsUpdate(); // notify change emit symbolTableChanged(); } void SymbolManager::changeRegister(int id, int state) { if (treeLabelsUpdateCount) return; // disallow another tristate selection chkRegs[id]->setTristate(false); // get selected items QList selection = treeLabels->selectedItems(); // update items beginTreeLabelsUpdate(); int bit = 1 << id; for (QList::iterator selit = selection.begin(); selit != selection.end(); ++selit) { Symbol* sym = (Symbol*)((*selit)->data(0, Qt::UserRole).value()); // set or clear bit if (state == Qt::Checked) { sym->setValidRegisters(sym->validRegisters() | bit); } else { sym->setValidRegisters(sym->validRegisters() & ~bit); } // update item in treewidget updateItemRegisters(*selit); } endTreeLabelsUpdate(); // notify change emit symbolTableChanged(); } void SymbolManager::changeType(bool /*checked*/) { if (treeLabelsUpdateCount) return; // determine selected type Symbol::SymbolType newType = Symbol::JUMPLABEL; if (radVar->isChecked()) { newType = Symbol::VARIABLELABEL; } else if (radValue->isChecked()) { newType = Symbol::VALUE; } // get selected items QList selection = treeLabels->selectedItems(); // update items beginTreeLabelsUpdate(); for (QList::iterator selit = selection.begin(); selit != selection.end(); ++selit) { Symbol* sym = (Symbol*)((*selit)->data(0, Qt::UserRole).value()); sym->setType(newType); updateItemType(*selit); } endTreeLabelsUpdate(); // notify change emit symbolTableChanged(); } /* * Symbol tree layout functions */ void SymbolManager::updateItemName(QTreeWidgetItem* item) { Symbol* sym = (Symbol*)(item->data(0, Qt::UserRole).value()); // set text and icon item->setText(0, sym->text()); if (sym->source()) { item->setIcon(0, QIcon(":/icons/symfil.png")); item->setText(6, *sym->source()); } else { item->setIcon(0, QIcon(":/icons/symman.png")); } // set color based on status as well as status in 2nd column switch (sym->status()) { case Symbol::HIDDEN: item->setTextColor(0, QColor(128, 128, 128)); break; case Symbol::LOST: item->setTextColor(0, QColor(128, 0, 0)); break; default: break; } } void SymbolManager::updateItemType(QTreeWidgetItem* item) { Symbol* sym = (Symbol*)(item->data(0, Qt::UserRole).value()); // set symbol type in 2nd column switch (sym->type()) { case Symbol::JUMPLABEL: item->setText(1, tr("Jump label")); break; case Symbol::VARIABLELABEL: item->setText(1, tr("Variable label")); break; case Symbol::VALUE: item->setText(1, tr("Value")); break; } } void SymbolManager::updateItemValue(QTreeWidgetItem* item) { Symbol* sym = (Symbol*)(item->data(0, Qt::UserRole).value()); // symbol value in 3rd column // TODO: Custom prefix/postfix item->setText(2, QString("$%1").arg(sym->value(), 4, 16, QChar('0'))); } void SymbolManager::updateItemSlots(QTreeWidgetItem* item) { Symbol* sym = (Symbol*)(item->data(0, Qt::UserRole).value()); QString slotText; int slotmask = sym->validSlots(); // value represents 16 bits for 4 subslots in 4 slots if (slotmask == 0xFFFF) { slotText = tr("All"); } else if (slotmask == 0) { slotText = tr("None"); } else { // create a list of valid slots // loop over all primary slots for (int ps = 0; ps < 4; ++ps) { QString subText; int subslots = (slotmask >> (4 * ps)) & 15; if (subslots == 15) { // all subslots are ok subText = QString("%1-*").arg(ps); } else if (subslots) { // some subslots are ok if (subslots & 1) subText += "/0"; if (subslots & 2) subText += "/1"; if (subslots & 4) subText += "/2"; if (subslots & 8) subText += "/3"; subText = QString("%1-").arg(ps) + subText.mid(1); } // add to string if any subslots were ok if (!subText.isEmpty()) { if (!slotText.isEmpty()) slotText += ", "; slotText += subText; } } } // valid slots in 4th column item->setText(3, slotText); } void SymbolManager::updateItemSegments(QTreeWidgetItem* item) { item->data(0, Qt::UserRole).value(); } void SymbolManager::updateItemRegisters(QTreeWidgetItem* item) { Symbol* sym = (Symbol*)(item->data(0, Qt::UserRole).value()); QString regText; int regmask = sym->validRegisters(); // value represents 16 bits for 4 subslots in 4 slots if (regmask == 0x3FFFF) { regText = tr("All"); } else if (regmask == 0) { regText = tr("None"); } else { if ((regmask & Symbol::REG_ALL8) == Symbol::REG_ALL8) { // all 8 bit registers selected regText = "All 8 bit, "; regmask ^= Symbol::REG_ALL8; } else if ((regmask & Symbol::REG_ALL16) == Symbol::REG_ALL16) { // all 16 bit registers selected regText = "All 16 bit, "; regmask ^= Symbol::REG_ALL16; } // register list for remaining registers static const char* const registers[] = { "A", "B", "C", "D", "E", "H", "L", "BC", "DE", "HL", "IX", "IY", "IXL", "IXH", "IYL", "IYH", "Offset", "I" }; for (int i = 0; i < 18; ++i) { if (regmask & 1) { regText += QString("%1, ").arg(registers[i]); } regmask >>= 1; } regText.chop(2); } // valid slots in 4th column item->setText(5, regText); } // load of functions that shouldn't really be necessary void SymbolManager::changeSlot00(int state) { changeSlot(0, state); } void SymbolManager::changeSlot01(int state) { changeSlot(1, state); } void SymbolManager::changeSlot02(int state) { changeSlot(2, state); } void SymbolManager::changeSlot03(int state) { changeSlot(3, state); } void SymbolManager::changeSlot10(int state) { changeSlot(4, state); } void SymbolManager::changeSlot11(int state) { changeSlot(5, state); } void SymbolManager::changeSlot12(int state) { changeSlot(6, state); } void SymbolManager::changeSlot13(int state) { changeSlot(7, state); } void SymbolManager::changeSlot20(int state) { changeSlot(8, state); } void SymbolManager::changeSlot21(int state) { changeSlot(9, state); } void SymbolManager::changeSlot22(int state) { changeSlot(10, state); } void SymbolManager::changeSlot23(int state) { changeSlot(11, state); } void SymbolManager::changeSlot30(int state) { changeSlot(12, state); } void SymbolManager::changeSlot31(int state) { changeSlot(13, state); } void SymbolManager::changeSlot32(int state) { changeSlot(14, state); } void SymbolManager::changeSlot33(int state) { changeSlot(15, state); } void SymbolManager::changeRegisterA(int state) { changeRegister(0, state); } void SymbolManager::changeRegisterB(int state) { changeRegister(1, state); } void SymbolManager::changeRegisterC(int state) { changeRegister(2, state); } void SymbolManager::changeRegisterD(int state) { changeRegister(3, state); } void SymbolManager::changeRegisterE(int state) { changeRegister(4, state); } void SymbolManager::changeRegisterH(int state) { changeRegister(5, state); } void SymbolManager::changeRegisterL(int state) { changeRegister(6, state); } void SymbolManager::changeRegisterBC(int state) { changeRegister(7, state); } void SymbolManager::changeRegisterDE(int state) { changeRegister(8, state); } void SymbolManager::changeRegisterHL(int state) { changeRegister(9, state); } void SymbolManager::changeRegisterIX(int state) { changeRegister(10, state); } void SymbolManager::changeRegisterIY(int state) { changeRegister(11, state); } void SymbolManager::changeRegisterIXL(int state) { changeRegister(12, state); } void SymbolManager::changeRegisterIXH(int state) { changeRegister(13, state); } void SymbolManager::changeRegisterIYL(int state) { changeRegister(14, state); } void SymbolManager::changeRegisterIYH(int state) { changeRegister(15, state); } void SymbolManager::changeRegisterOffset(int state) { changeRegister(16, state); } void SymbolManager::changeRegisterI(int state) { changeRegister(17, state); } openmsx-debugger-0.0.0.svn20141006.orig/src/InteractiveLabel.cpp0000644000175000017500000000150112414415132023402 0ustar shevekshevek#include "InteractiveLabel.h" #include #include InteractiveLabel::InteractiveLabel(QWidget *parent) : QLabel(parent) { setEnabled(true); setAutoFillBackground(true); } void InteractiveLabel::highlight(bool state) { // I first tried with style sheets, but then I found in the // documentation that Qt style sheets are currently not supported for // QMacStyle (the default style on Mac OS X). // So I use a QPalette for now. if (state) { QPalette fiddle = QApplication::palette(); fiddle.setColor(QPalette::Active, QPalette::Window, Qt::yellow); setPalette(fiddle); } else { setPalette(QApplication::palette()); } update(); } void InteractiveLabel::enterEvent(QEvent* event) { emit mouseOver(true); } void InteractiveLabel::leaveEvent(QEvent* event) { emit mouseOver(false); } openmsx-debugger-0.0.0.svn20141006.orig/src/DebuggableViewer.h0000644000175000017500000000073312414415132023043 0ustar shevekshevek// $Id$ #ifndef DEBUGGABLEVIEWER_H #define DEBUGGABLEVIEWER_H #include class HexViewer; class QComboBox; class DebuggableViewer : public QWidget { Q_OBJECT public: DebuggableViewer(QWidget* parent = 0); public slots: void settingsChanged(); void setDebuggables(const QMap& list); void refresh(); private: HexViewer* hexView; QComboBox* debuggableList; private slots: void debuggableSelected(int index); }; #endif // DEBUGGABLEVIEWER_H openmsx-debugger-0.0.0.svn20141006.orig/src/SlotViewer.h0000644000175000017500000000115712414415132021744 0ustar shevekshevek// $Id$ #ifndef SLOTVIEWER_H #define SLOTVIEWER_H #include struct MemoryLayout; class QString; class SlotViewer : public QFrame { Q_OBJECT; public: SlotViewer(QWidget* parent = 0); void refresh(); void setMemoryLayout(MemoryLayout* ml); void slotsUpdated(const QString& message); QSize sizeHint() const; private: void resizeEvent(QResizeEvent* e); void paintEvent(QPaintEvent* e); int frameL, frameR, frameT, frameB; int headerSize1, headerSize2, headerSize3, headerSize4; int headerHeight; MemoryLayout* memLayout; bool slotsChanged[4]; bool segmentsChanged[4]; }; #endif // SLOTVIEWER_H openmsx-debugger-0.0.0.svn20141006.orig/src/Version.h0000644000175000017500000000046212414415132021264 0ustar shevekshevek// $Id$ #ifndef VERSION_H #define VERSION_H #include class Version { public: // Defined by build system: static const bool RELEASE; static const char* const VERSION; static const char* const REVISION; // Computed using constants above: static std::string full(); }; #endif // VERSION_H openmsx-debugger-0.0.0.svn20141006.orig/src/openmsx/0000755000175000017500000000000012414415132021155 5ustar shevekshevekopenmsx-debugger-0.0.0.svn20141006.orig/src/openmsx/SspiUtils.h0000644000175000017500000000434512414415132023273 0ustar shevekshevek// $Id$ #ifndef SSPI_UTILS_HH #define SSPI_UTILS_HH #ifdef _WIN32 #include #ifdef __GNUC__ // MinGW32 requires that subauth.h be included before security.h, in order to define several things // This differs from VC++, which only needs security.h #include // MinGW32 does not define NEGOSSP_NAME_W anywhere. It should. #define NEGOSSP_NAME_W L"Negotiate" #endif #ifndef SECURITY_WIN32 #define SECURITY_WIN32 #endif #include #include #include "openmsx.h" // // NOTE: This file MUST be kept in sync between the openmsx and openmsx-debugger projects // namespace openmsx { namespace sspiutils { const unsigned STREAM_ERROR = 0xffffffff; class StreamWrapper { public: virtual uint32 Read(void* buffer, uint32 cb) = 0; virtual uint32 Write(void* buffer, uint32 cb) = 0; }; class SspiPackageBase { protected: CredHandle hCreds; CtxtHandle hContext; StreamWrapper& stream; const unsigned int cbMaxTokenSize; SspiPackageBase(StreamWrapper& stream, const SEC_WCHAR* securityPackage); ~SspiPackageBase(); }; // Generic access control flags, used with AccessCheck const DWORD ACCESS_READ = 0x1; const DWORD ACCESS_WRITE = 0x2; const DWORD ACCESS_EXECUTE = 0x4; const DWORD ACCESS_ALL = ACCESS_READ | ACCESS_WRITE | ACCESS_EXECUTE; const GENERIC_MAPPING mapping = { ACCESS_READ, ACCESS_WRITE, ACCESS_EXECUTE, ACCESS_ALL }; void InitTokenContextBuffer(PSecBufferDesc pSecBufferDesc, PSecBuffer pSecBuffer); void ClearContextBuffers(PSecBufferDesc pSecBufferDesc); void DebugPrintSecurityStatus(const char* context, SECURITY_STATUS ss); void DebugPrintSecurityBool(const char* context, BOOL ret); void DebugPrintSecurityPackageName(PCtxtHandle phContext); void DebugPrintSecurityPrincipalName(PCtxtHandle phContext); void DebugPrintSecurityDescriptor(PSECURITY_DESCRIPTOR psd); PSECURITY_DESCRIPTOR CreateCurrentUserSecurityDescriptor(); unsigned long GetPackageMaxTokenSize(const SEC_WCHAR* package); bool SendChunk(StreamWrapper& stream, void* buffer, uint32 cb); bool RecvChunk(StreamWrapper& stream, std::vector& buffer, uint32 cbMaxSize); } // namespace sspiutils } // namespace openmsx #endif // _WIN32 #endif // SSPI_UTILS_HH openmsx-debugger-0.0.0.svn20141006.orig/src/openmsx/SspiNegotiateClient.cpp0000644000175000017500000000507712414415132025607 0ustar shevekshevek// $Id$ #ifdef _WIN32 #include "SspiNegotiateClient.h" #include "openmsx.h" namespace openmsx { SspiNegotiateClient::SspiNegotiateClient(StreamWrapper& clientStream) : SspiPackageBase(clientStream, NEGOSSP_NAME_W) { } bool SspiNegotiateClient::Authenticate() { TimeStamp tsCredsExpiry; SECURITY_STATUS ss = AcquireCredentialsHandleW( NULL, const_cast(NEGOSSP_NAME_W), SECPKG_CRED_OUTBOUND, NULL, NULL, NULL, NULL, &hCreds, &tsCredsExpiry); DebugPrintSecurityStatus("AcquireCredentialsHandleW", ss); if (ss != SEC_E_OK) { return false; } SecBufferDesc secClientBufferDesc, secServerBufferDesc; SecBuffer secClientBuffer, secServerBuffer; InitTokenContextBuffer(&secClientBufferDesc, &secClientBuffer); InitTokenContextBuffer(&secServerBufferDesc, &secServerBuffer); std::vector buffer; PCtxtHandle phContext = NULL; PSecBufferDesc psecServerBufferDesc = NULL; while (true) { ULONG fContextAttr; TimeStamp tsContextExpiry; ss = InitializeSecurityContextA( &hCreds, phContext, NULL, // To use Kerberos, we'll need an SPN here ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_CONNECTION | ISC_REQ_STREAM, 0, SECURITY_NETWORK_DREP, psecServerBufferDesc, 0, &hContext, &secClientBufferDesc, &fContextAttr, &tsContextExpiry); DebugPrintSecurityStatus("InitializeSecurityContextA", ss); if (ss != SEC_E_OK && ss != SEC_I_CONTINUE_NEEDED) { return false; } // If we have something for the server, send it if (secClientBuffer.cbBuffer) { PRT_DEBUG("Sending " << secClientBuffer.cbBuffer << " bytes to server"); bool ret = SendChunk(stream, secClientBuffer.pvBuffer, secClientBuffer.cbBuffer); ClearContextBuffers(&secClientBufferDesc); if (!ret) { PRT_DEBUG("SendChunk failed"); return false; } } // SEC_E_OK means that we're done if (ss == SEC_E_OK) { DebugPrintSecurityPackageName(&hContext); DebugPrintSecurityPrincipalName(&hContext); return true; } // Receive another buffer from the server PRT_DEBUG("Receiving server chunk"); bool ret = RecvChunk(stream, buffer, cbMaxTokenSize); if (!ret) { PRT_DEBUG("RecvChunk failed"); return false; } PRT_DEBUG("Received " << buffer.size() << " bytes"); // Another time around the loop secServerBuffer.cbBuffer = static_cast(buffer.size()); secServerBuffer.pvBuffer = &buffer[0]; phContext = &hContext; psecServerBufferDesc = &secServerBufferDesc; } } } // namespace openmsx #endif // _WIN32 openmsx-debugger-0.0.0.svn20141006.orig/src/openmsx/SspiNegotiateClient.h0000644000175000017500000000062112414415132025242 0ustar shevekshevek// $Id$ #ifndef SSPI_NEGOTIATE_CLIENT_H #define SSPI_NEGOTIATE_CLIENT_H #ifdef _WIN32 #include "SspiUtils.h" namespace openmsx { using namespace sspiutils; class SspiNegotiateClient : public SspiPackageBase { public: SspiNegotiateClient(StreamWrapper& clientStream); bool Authenticate(); }; } // namespace openmsx #endif // _WIN32 #endif // SSPI_NEGOTIATE_CLIENT_H openmsx-debugger-0.0.0.svn20141006.orig/src/openmsx/node.mk0000644000175000017500000000025712414415132022437 0ustar shevekshevek# $Id$ include build/node-start.mk SRC_HDR:= \ QAbstractSocketStreamWrapper SspiNegotiateClient SspiUtils HDR_ONLY:= \ openmsx \ MSXException include build/node-end.mk openmsx-debugger-0.0.0.svn20141006.orig/src/openmsx/QAbstractSocketStreamWrapper.h0000644000175000017500000000110112414415132027071 0ustar shevekshevek// $Id$ #ifndef QTCP_SOCKET_STREAM_WRAPPER_H #define QTCP_SOCKET_STREAM_WRAPPER_H #ifdef _WIN32 #include #include "SspiUtils.h" namespace openmsx { using namespace sspiutils; class QAbstractSocketStreamWrapper : public StreamWrapper { private: QAbstractSocket* sock; public: QAbstractSocketStreamWrapper(QAbstractSocket* userSock); unsigned int Read(void* buffer, unsigned int cb); unsigned int Write(void* buffer, unsigned int cb); }; } // namespace openmsx #endif // _WIN32 #endif // QTCP_SOCKET_STREAM_WRAPPER_H openmsx-debugger-0.0.0.svn20141006.orig/src/openmsx/openmsx.h0000644000175000017500000000211012414415132023011 0ustar shevekshevek// $Id$ #ifndef OPENMSX_H #define OPENMSX_H // don't just always include this, saves about 1 minute build time!! #ifdef DEBUG #include #endif /// Namespace of the openMSX emulation core. /** openMSX: the MSX emulator that aims for perfection * * Copyrights: see AUTHORS file. * License: GPL. */ namespace openmsx { /** 4 bit integer */ typedef unsigned char nibble; /** 8 bit signed integer */ typedef signed char signed_byte; /** 8 bit unsigned integer */ typedef unsigned char byte; /** 16 bit signed integer */ typedef short signed_word; /** 16 bit unsigned integer */ typedef unsigned short word; /** 32 bit signed integer */ typedef int int32; /** 32 bit unsigned integer */ typedef unsigned uint32; /** 64 bit signed integer */ typedef long long int64; /** 64 bit unsigned integer */ typedef unsigned long long uint64; #ifdef DEBUG #define PRT_DEBUG(mes) \ do { \ std::cout << mes << std::endl; \ } while (0) #else #define PRT_DEBUG(mes) #endif } // namespace openmsx #endif // OPENMSX_H openmsx-debugger-0.0.0.svn20141006.orig/src/openmsx/MSXException.h0000644000175000017500000000122712414415132023656 0ustar shevekshevek// $Id$ #ifndef MSXEXCEPTION_H #define MSXEXCEPTION_H #include namespace openmsx { class MSXException { public: explicit MSXException(const std::string& message_) : message(message_) { } virtual ~MSXException() { } const std::string& getMessage() const { return message; } private: const std::string message; }; class FatalError { public: explicit FatalError(const std::string& message_) : message(message_) { } virtual ~FatalError() { } const std::string& getMessage() const { return message; } private: const std::string message; }; } // namespace openmsx #endif // MSXEXCEPTION_H openmsx-debugger-0.0.0.svn20141006.orig/src/openmsx/QAbstractSocketStreamWrapper.cpp0000644000175000017500000000140512414415132027433 0ustar shevekshevek// $Id$ #ifdef _WIN32 #include "QAbstractSocketStreamWrapper.h" namespace openmsx { QAbstractSocketStreamWrapper::QAbstractSocketStreamWrapper(QAbstractSocket* userSock) : sock(userSock) { } unsigned int QAbstractSocketStreamWrapper::Read(void* buffer, unsigned int cb) { sock->waitForReadyRead(30); qint64 recvd = sock->read(static_cast(buffer), cb); if (recvd == -1) { return STREAM_ERROR; } return static_cast(recvd); } unsigned int QAbstractSocketStreamWrapper::Write(void* buffer, unsigned int cb) { qint64 sent = sock->write(static_cast(buffer), cb); if (sent == -1 || !sock->flush()) { return STREAM_ERROR; } return static_cast(sent); } } // namespace openmsx #endif openmsx-debugger-0.0.0.svn20141006.orig/src/openmsx/SspiUtils.cpp0000644000175000017500000001656512414415132023635 0ustar shevekshevek#ifdef _WIN32 #include "SspiUtils.h" #include "MSXException.h" #include #include // // NOTE: This file MUST be kept in sync between the openmsx and openmsx-debugger projects // namespace openmsx { namespace sspiutils { SspiPackageBase::SspiPackageBase(StreamWrapper& userStream, const SEC_WCHAR* securityPackage) : stream(userStream) , cbMaxTokenSize(GetPackageMaxTokenSize(securityPackage)) { memset(&hCreds, 0, sizeof(hCreds)); memset(&hContext, 0, sizeof(hContext)); if (!cbMaxTokenSize) { throw MSXException("GetPackageMaxTokenSize failed"); } } SspiPackageBase::~SspiPackageBase() { DeleteSecurityContext(&hContext); FreeCredentialsHandle(&hCreds); } void InitTokenContextBuffer(PSecBufferDesc pSecBufferDesc, PSecBuffer pSecBuffer) { pSecBuffer->BufferType = SECBUFFER_TOKEN; pSecBuffer->cbBuffer = 0; pSecBuffer->pvBuffer = nullptr; pSecBufferDesc->ulVersion = SECBUFFER_VERSION; pSecBufferDesc->cBuffers = 1; pSecBufferDesc->pBuffers = pSecBuffer; } void ClearContextBuffers(PSecBufferDesc pSecBufferDesc) { for (ULONG i = 0; i < pSecBufferDesc->cBuffers; i ++) { FreeContextBuffer(pSecBufferDesc->pBuffers[i].pvBuffer); pSecBufferDesc->pBuffers[i].cbBuffer = 0; pSecBufferDesc->pBuffers[i].pvBuffer = nullptr; } } void DebugPrintSecurityStatus(const char* context, SECURITY_STATUS ss) { (void)&context; (void)&ss; #ifdef DEBUG switch (ss) { case SEC_E_OK: PRT_DEBUG(context << ": SEC_E_OK"); break; case SEC_I_CONTINUE_NEEDED: PRT_DEBUG(context << ": SEC_I_CONTINUE_NEEDED"); break; case SEC_E_INVALID_TOKEN: PRT_DEBUG(context << ": SEC_E_INVALID_TOKEN"); break; case SEC_E_BUFFER_TOO_SMALL: PRT_DEBUG(context << ": SEC_E_BUFFER_TOO_SMALL"); break; case SEC_E_INVALID_HANDLE: PRT_DEBUG(context << ": SEC_E_INVALID_HANDLE"); break; case SEC_E_WRONG_PRINCIPAL: PRT_DEBUG(context << ": SEC_E_WRONG_PRINCIPAL"); break; default: PRT_DEBUG(context << ": " << ss); break; } #endif } void DebugPrintSecurityBool(const char* context, BOOL ret) { (void)&context; (void)&ret; #ifdef DEBUG if (ret) { PRT_DEBUG(context << ": true"); } else { PRT_DEBUG(context << ": false - " << GetLastError()); } #endif } void DebugPrintSecurityPackageName(PCtxtHandle phContext) { (void)&phContext; #ifdef DEBUG SecPkgContext_PackageInfoA package; SECURITY_STATUS ss = QueryContextAttributesA(phContext, SECPKG_ATTR_PACKAGE_INFO, &package); if (ss == SEC_E_OK) { PRT_DEBUG("Using " << package.PackageInfo->Name << " package"); } #endif } void DebugPrintSecurityPrincipalName(PCtxtHandle phContext) { (void)&phContext; #ifdef DEBUG SecPkgContext_NamesA name; SECURITY_STATUS ss = QueryContextAttributesA(phContext, SECPKG_ATTR_NAMES, &name); if (ss == SEC_E_OK) { PRT_DEBUG("Client principal " << name.sUserName); } #endif } void DebugPrintSecurityDescriptor(PSECURITY_DESCRIPTOR psd) { (void)&psd; #ifdef DEBUG char* sddl; BOOL ret = ConvertSecurityDescriptorToStringSecurityDescriptorA( psd, SDDL_REVISION, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION | LABEL_SECURITY_INFORMATION, &sddl, nullptr); if (ret) { PRT_DEBUG("SecurityDescriptor: " << sddl); LocalFree(sddl); } #endif } // If successful, caller must free the results with LocalFree() // If unsuccessful, returns null PTOKEN_USER GetProcessToken() { PTOKEN_USER pToken = nullptr; HANDLE hProcessToken; BOOL ret = OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &hProcessToken); DebugPrintSecurityBool("OpenProcessToken", ret); if (ret) { DWORD cbToken; ret = GetTokenInformation(hProcessToken, TokenUser, nullptr, 0, &cbToken); assert(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER && cbToken); pToken = (TOKEN_USER*)LocalAlloc(LMEM_ZEROINIT, cbToken); if (pToken) { ret = GetTokenInformation(hProcessToken, TokenUser, pToken, cbToken, &cbToken); DebugPrintSecurityBool("GetTokenInformation", ret); if (!ret) { LocalFree(pToken); pToken = nullptr; } } CloseHandle(hProcessToken); } return pToken; } // If successful, caller must free the results with LocalFree() // If unsuccessful, returns null PSECURITY_DESCRIPTOR CreateCurrentUserSecurityDescriptor() { PSECURITY_DESCRIPTOR psd = nullptr; PTOKEN_USER pToken = GetProcessToken(); if (pToken) { PSID pUserSid = pToken->User.Sid; const DWORD cbEachAce = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD); const DWORD cbACL = sizeof(ACL) + cbEachAce + GetLengthSid(pUserSid); // Allocate the SD and the ACL in one allocation, so we only have one buffer to manage // The SD structure ends with a pointer, so the start of the ACL will be well aligned BYTE* buffer = (BYTE*)LocalAlloc(LMEM_ZEROINIT, SECURITY_DESCRIPTOR_MIN_LENGTH + cbACL); if (buffer) { psd = (PSECURITY_DESCRIPTOR)buffer; PACL pacl = (PACL)(buffer + SECURITY_DESCRIPTOR_MIN_LENGTH); PACCESS_ALLOWED_ACE pUserAce; if (InitializeSecurityDescriptor(psd, SECURITY_DESCRIPTOR_REVISION) && InitializeAcl(pacl, cbACL, ACL_REVISION) && AddAccessAllowedAce(pacl, ACL_REVISION, ACCESS_ALL, pUserSid) && SetSecurityDescriptorDacl(psd, TRUE, pacl, FALSE) && // Need to set the Group and Owner on the SD in order to use it with AccessCheck() GetAce(pacl, 0, (void**)&pUserAce) && SetSecurityDescriptorGroup(psd, &pUserAce->SidStart, FALSE) && SetSecurityDescriptorOwner(psd, &pUserAce->SidStart, FALSE)) { buffer = nullptr; } else { psd = nullptr; } LocalFree(buffer); } LocalFree(pToken); } if (psd) { assert(IsValidSecurityDescriptor(psd)); DebugPrintSecurityDescriptor(psd); } return psd; } unsigned long GetPackageMaxTokenSize(const SEC_WCHAR* package) { PSecPkgInfoW pkgInfo; SECURITY_STATUS ss = QuerySecurityPackageInfoW(const_cast(package), &pkgInfo); DebugPrintSecurityStatus("QuerySecurityPackageInfoW", ss); if (ss != SEC_E_OK) { return 0; } unsigned long cbMaxToken = pkgInfo->cbMaxToken; FreeContextBuffer(pkgInfo); return cbMaxToken; } bool Send(StreamWrapper& stream, void* buffer, uint32_t cb) { uint32_t sent = 0; while (sent < cb) { uint32_t ret = stream.Write((char*)buffer + sent, cb - sent); if (ret == STREAM_ERROR) { return false; } sent += ret; } return true; } bool SendChunk(StreamWrapper& stream, void* buffer, uint32_t cb) { uint32_t nl = htonl(cb); if (!Send(stream, &nl, sizeof(nl))) { return false; } return Send(stream, buffer, cb); } bool Recv(StreamWrapper& stream, void* buffer, uint32_t cb) { uint32_t recvd = 0; while (recvd < cb) { uint32_t ret = stream.Read((char*)buffer + recvd, cb - recvd); if (ret == STREAM_ERROR) { return false; } recvd += ret; } return true; } bool RecvChunkSize(StreamWrapper& stream, uint32_t* pcb) { uint32_t cb; bool ret = Recv(stream, &cb, sizeof(cb)); if (ret) { *pcb = ntohl(cb); } return ret; } bool RecvChunk(StreamWrapper& stream, std::vector& buffer, uint32_t cbMaxSize) { uint32_t cb; if (!RecvChunkSize(stream, &cb) || cb > cbMaxSize) { return false; } buffer.resize(cb); if (!Recv(stream, &buffer[0], cb)) { return false; } return true; } } // namespace sspiutils } // namespace openmsx #endif openmsx-debugger-0.0.0.svn20141006.orig/src/StackViewer.cpp0000644000175000017500000001072112414415132022420 0ustar shevekshevek// $Id$ #include "StackViewer.h" #include "OpenMSXConnection.h" #include "CommClient.h" #include "Settings.h" #include #include #include #include class StackRequest : public ReadDebugBlockCommand { public: StackRequest(unsigned offset_, unsigned size, unsigned char* target, StackViewer& viewer_) : ReadDebugBlockCommand("memory", offset_, size, target) , offset(offset_) , viewer(viewer_) { } virtual void replyOk(const QString& message) { copyData(message); viewer.memdataTransfered(this); } virtual void cancel() { viewer.transferCancelled(this); } // TODO public members are ugly!! unsigned offset; private: StackViewer& viewer; }; StackViewer::StackViewer(QWidget* parent) : QFrame(parent) { setFrameStyle(WinPanel | Sunken); setFocusPolicy(Qt::StrongFocus); setBackgroundRole(QPalette::Base); setSizePolicy(QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Preferred)); setFont(Settings::get().font(Settings::HEX_FONT)); stackPointer = 0; topAddress = 0; waitingForData = false; vertScrollBar = new QScrollBar(Qt::Vertical, this); vertScrollBar->hide(); frameL = frameT = frameB = frameWidth(); frameR = frameL + vertScrollBar->sizeHint().width(); setMinimumHeight(frameT+frameB+fontMetrics().height()); connect(vertScrollBar, SIGNAL(valueChanged(int)), this, SLOT(setLocation(int))); } QSize StackViewer::sizeHint() const { return QSize(frameL + 4 + fontMetrics().width("FFFFWFFFF ") + 4 + frameR, frameT + 8 * fontMetrics().height() + frameB); } void StackViewer::setScrollBarValues() { vertScrollBar->setMinimum(stackPointer); visibleLines = double(height() - frameT - frameB) / fontMetrics().height(); int lines = (memoryLength - stackPointer) / 2; vertScrollBar->setMaximum(stackPointer + 2 * (lines - int(visibleLines))); vertScrollBar->setSingleStep(2); vertScrollBar->setPageStep(2 * int(visibleLines)); } void StackViewer::resizeEvent(QResizeEvent* e) { QFrame::resizeEvent(e); setScrollBarValues(); vertScrollBar->setGeometry(width() - frameR, frameT, vertScrollBar->sizeHint().width(), height() - frameT - frameB); vertScrollBar->show(); // calc the number of lines that can be displayed // partial lines count as a whole } void StackViewer::paintEvent(QPaintEvent* e) { // call parent for drawing the actual frame QFrame::paintEvent(e); QPainter p(this); int h = fontMetrics().height(); int d = fontMetrics().descent(); // set font p.setPen(Qt::black); // calc and set drawing bounds QRect r(e->rect()); if (r.left() < frameL) r.setLeft(frameL); if (r.top() < frameT) r.setTop (frameT); if (r.right() > width() - frameR - 1) r.setRight (width() - frameR - 1); if (r.bottom() > height() - frameB - 1) r.setBottom(height() - frameB - 1); p.setClipRect(r); // redraw background p.fillRect(r, palette().color(QPalette::Base)); // calc layout (not optimal) int xAddr = frameL + 8; int xStack = xAddr + fontMetrics().width("FFFFF"); int y = frameT + h - 1; int address = topAddress; for (int i = 0; i < int(ceil(visibleLines)); ++i) { // print address QString hexStr; hexStr.sprintf("%04X", address); p.drawText(xAddr, y - d, hexStr); hexStr.sprintf("%02X%02X", memory[address + 1], memory[address]); p.drawText(xStack, y - d, hexStr); y += h; address += 2; if (address >= memoryLength - 1) break; } } void StackViewer::setData(unsigned char* memPtr, int memLength) { memory = memPtr; memoryLength = memLength; setScrollBarValues(); } void StackViewer::setLocation(int addr) { if (waitingForData) { // ignore return; } int start = (addr & ~1) | (stackPointer & 1); int size = 2 * int(ceil(visibleLines)); if (start + size >= memoryLength) { size = memoryLength - start; } StackRequest* req = new StackRequest(start, size, &memory[start], *this); CommClient::instance().sendCommand(req); waitingForData = true; } void StackViewer::setStackPointer(quint16 addr) { stackPointer = addr; setScrollBarValues(); vertScrollBar->setValue(addr); setLocation(addr); } void StackViewer::memdataTransfered(StackRequest* r) { topAddress = r->offset; update(); waitingForData = false; delete r; // check whether a new value is available if ((topAddress & ~1) != (vertScrollBar->value() & ~1)) { setLocation(vertScrollBar->value()); } } void StackViewer::transferCancelled(StackRequest* r) { waitingForData = false; delete r; } openmsx-debugger-0.0.0.svn20141006.orig/src/PreferencesDialog.ui0000644000175000017500000001352512414415132023412 0ustar shevekshevek PreferencesDialog 0 0 654 512 Preferences 9 6 Fonts 9 6 QAbstractItemView::SelectRows 0 6 0 6 false false Use default fixed font false Use custom font 0 6 7 0 0 0 0 80 QFrame::WinPanel QFrame::Sunken openMSX debugger! false Select custom font Select font color Qt::Vertical 20 40 0 6 Qt::Horizontal 131 31 Close okButton clicked() PreferencesDialog accept() 278 253 96 254 openmsx-debugger-0.0.0.svn20141006.orig/src/PreferencesDialog.cpp0000644000175000017500000000644012414415132023555 0ustar shevekshevek#include "PreferencesDialog.h" #include "Settings.h" #include #include #include PreferencesDialog::PreferencesDialog(QWidget* parent) : QDialog(parent) { setupUi(this); connect(listFonts, SIGNAL(currentRowChanged(int)), this, SLOT(fontSelectionChange(int))); connect(rbUseAppFont, SIGNAL(toggled(bool)), this, SLOT(fontTypeChanged(bool))); connect(rbUseFixedFont, SIGNAL(toggled(bool)), this, SLOT(fontTypeChanged(bool))); connect(rbUseCustomFont, SIGNAL(toggled(bool)), this, SLOT(fontTypeChanged(bool))); connect(btnSelectFont, SIGNAL(clicked()), this, SLOT(fontSelectCustom())); connect(btnFontColor, SIGNAL(clicked()), this, SLOT(fontSelectColor())); initFontList(); listFonts->setCurrentRow(0); } /* * Font settings */ void PreferencesDialog::initFontList() { Settings& s = Settings::get(); listFonts->clear(); for (int f = Settings::APP_FONT; f < Settings::FONT_END; ++f) { new QListWidgetItem(s.fontName((Settings::DebuggerFont)f), listFonts); } } void PreferencesDialog::fontSelectionChange(int row) { updating = true; if (row == 0) { rbUseAppFont->setText(tr("Use system font")); } else { rbUseAppFont->setText(tr("Use application font")); } rbUseAppFont->setEnabled(row >= 0); rbUseFixedFont->setEnabled(row > 1); rbUseCustomFont->setEnabled(row >= 0); switch (Settings::get().fontType( (Settings::DebuggerFont)row)) { case Settings::APPLICATION_DEFAULT: rbUseAppFont->setChecked(true); break; case Settings::FIXED_DEFAULT: rbUseFixedFont->setChecked(true); break; case Settings::CUSTOM: rbUseCustomFont->setChecked(true); break; } lblPreview->setFont(Settings::get().font ((Settings::DebuggerFont)row)); setFontPreviewColor(Settings::get().fontColor((Settings::DebuggerFont)row)); btnSelectFont->setEnabled(rbUseCustomFont->isChecked()); btnFontColor->setEnabled(row > 1); updating = false; } void PreferencesDialog::fontTypeChanged(bool state) { if (!state || updating) return; Settings::DebuggerFont f = (Settings::DebuggerFont)(listFonts->currentRow()); Settings& s = Settings::get(); if (rbUseAppFont->isChecked()) { s.setFontType(f, Settings::APPLICATION_DEFAULT); } else if (rbUseFixedFont->isChecked()) { s.setFontType(f, Settings::FIXED_DEFAULT); } else { s.setFontType(f, Settings::CUSTOM); } lblPreview->setFont(s.font(f)); btnSelectFont->setEnabled(rbUseCustomFont->isChecked()); } void PreferencesDialog::fontSelectCustom() { bool ok; Settings::DebuggerFont f = (Settings::DebuggerFont)(listFonts->currentRow()); QFont newFont = QFontDialog::getFont(&ok, Settings::get().font(f)); if (ok) { lblPreview->setFont(newFont); Settings::get().setFont(f, newFont); } } void PreferencesDialog::fontSelectColor() { Settings::DebuggerFont f = (Settings::DebuggerFont)(listFonts->currentRow()); QColor newColor = QColorDialog::getColor(Settings::get().fontColor(f), this); if (newColor.isValid()) { Settings::get().setFontColor(f, newColor); setFontPreviewColor(newColor); } } void PreferencesDialog::setFontPreviewColor(const QColor& c) { if (listFonts->currentRow() > 1) { QPalette pal = lblPreview->palette(); pal.setColor(QPalette::WindowText, c); lblPreview->setPalette(pal); } else { lblPreview->setPalette(QPalette()); } } openmsx-debugger-0.0.0.svn20141006.orig/src/Dasm.cpp0000644000175000017500000001113412414415132021054 0ustar shevekshevek// $Id$ #include "Dasm.h" #include "DasmTables.h" #include "SymbolTable.h" #include #include static char sign(unsigned char a) { return (a & 128) ? '-' : '+'; } static int abs(unsigned char a) { return (a & 128) ? (256 - a) : a; } static std::string toHex(unsigned value, unsigned width) { std::ostringstream s; s << std::hex << std::setw(width) << std::setfill('0') << value; return s.str(); } static std::string translateAddress( int address, MemoryLayout* memLayout, SymbolTable* symTable) { if (Symbol* label = symTable->getAddressSymbol(address, memLayout)) { return label->text().toStdString(); } else { return '#' + toHex(address, 4); } } static int get16(const unsigned char* memBuf, int address) { return memBuf[address] + 256 * memBuf[address + 1]; } void dasm(const unsigned char* membuf, unsigned short startAddr, unsigned short endAddr, DisasmLines& disasm, MemoryLayout* memLayout, SymbolTable* symTable, int currentPC) { int pc = startAddr; int labelCount = 0; Symbol* symbol = symTable->findFirstAddressSymbol(pc, memLayout); disasm.clear(); while (pc <= int(endAddr)) { // check for a label while (symbol && symbol->value() == pc) { ++labelCount; DisasmRow destsym; destsym.rowType = DisasmRow::LABEL; destsym.numBytes = 0; destsym.infoLine = labelCount; destsym.addr = pc; destsym.instr = symbol->text().toStdString(); disasm.push_back(destsym); symbol = symTable->findNextAddressSymbol(memLayout); } labelCount = 0; DisasmRow dest; dest.rowType = DisasmRow::INSTRUCTION; dest.addr = pc; dest.numBytes = 0; dest.infoLine = 0; dest.instr.clear(); const char* s; const char* r = 0; switch (membuf[pc]) { case 0xCB: s = mnemonic_cb[membuf[pc + 1]]; dest.numBytes = 2; break; case 0xED: s = mnemonic_ed[membuf[pc + 1]]; dest.numBytes = 2; break; case 0xDD: case 0xFD: r = (membuf[pc] == 0xDD) ? "ix" : "iy"; if (membuf[pc + 1] != 0xcb) { s = mnemonic_xx[membuf[pc + 1]]; dest.numBytes = 2; } else { s = mnemonic_xx_cb[membuf[pc + 3]]; dest.numBytes = 4; } break; default: s = mnemonic_main[membuf[pc]]; dest.numBytes = 1; } for (int j = 0; s[j]; ++j) { switch (s[j]) { case 'A': { int address = get16(membuf, pc + dest.numBytes); dest.instr += translateAddress(address, memLayout, symTable); dest.numBytes += 2; break; } case 'B': dest.instr += '#' + toHex(membuf[pc + dest.numBytes], 2); dest.numBytes += 1; break; case 'R': { int address = (pc + 2 + (signed char)membuf[pc + dest.numBytes]) & 0xFFFF; dest.instr += translateAddress(address, memLayout, symTable); dest.numBytes += 1; break; } case 'W': dest.instr += '#' + toHex(get16(membuf, pc + dest.numBytes), 4); dest.numBytes += 2; break; case 'X': { unsigned char offset = membuf[pc + dest.numBytes]; dest.instr += '(' + std::string(r) + sign(offset) + '#' + toHex(abs(offset), 2) + ')'; dest.numBytes += 1; break; } case 'Y': { unsigned char offset = membuf[pc + 2]; dest.instr += '(' + std::string(r) + sign(offset) + '#' + toHex(abs(offset), 2) + ')'; break; } case 'I': dest.instr += r; break; case '!': dest.instr = "db #ED,#" + toHex(membuf[pc + 1], 2); dest.numBytes = 2; case '@': dest.instr = "db #" + toHex(membuf[pc], 2); dest.numBytes = 1; case '#': dest.instr = "db #" + toHex(membuf[pc + 0], 2) + "#CB,#" + toHex(membuf[pc + 2], 2); dest.numBytes = 2; case ' ': { dest.instr.resize(7, ' '); break; } default: dest.instr += s[j]; break; } } // handle overflow at end or label int dataBytes = 0; if (symbol && pc + dest.numBytes > symbol->value()) { dataBytes = symbol->value() - pc; } else if (pc + dest.numBytes > endAddr) { dataBytes = endAddr - pc; } else if (pc + dest.numBytes > currentPC) { dataBytes = currentPC - pc; } switch (dataBytes) { case 1: dest.instr = "db #" + toHex(membuf[pc + 0], 2); dest.numBytes = 1; break; case 2: dest.instr = "db #" + toHex(membuf[pc + 0], 2) + ",#" + toHex(membuf[pc + 1], 2); dest.numBytes = 2; break; case 3: dest.instr = "db #" + toHex(membuf[pc + 0], 2) + ",#" + toHex(membuf[pc + 1], 2) + ",#" + toHex(membuf[pc + 2], 2); dest.numBytes = 3; break; default: break; } if (dest.instr.size() < 8) dest.instr.resize(8, ' '); disasm.push_back(dest); pc += dest.numBytes; } } openmsx-debugger-0.0.0.svn20141006.orig/src/SimpleHexRequest.h0000644000175000017500000000252412414415132023107 0ustar shevekshevek#ifndef SIMPLEHEXREQUEST_H #define SIMPLEHEXREQUEST_H #include "OpenMSXConnection.h" /** * A set of helper classes if code needs to read openmsx debugables into an array of unsigned chars * if class A needs to read a given debugable then this schem will suffice * - Class A inherits from SimpleHexRequestUser * - Class A can reimplement the DataHexRequestReceived if it wants to react when new data has arrived * - Class A can reimplement the DataHexRequestCanceled if it wants to react to failures of the request * - to read the debuggable into the memmory just create a new SimpleHexRequest, fi. * new SimpleHexRequest("{VDP status regs}",0,16,statusregs, *this); * */ class SimpleHexRequestUser { protected: virtual ~SimpleHexRequestUser(); virtual void DataHexRequestReceived(); virtual void DataHexRequestCanceled(); friend class SimpleHexRequest; }; class SimpleHexRequest : public ReadDebugBlockCommand { public: SimpleHexRequest(const QString& debuggable, unsigned size, unsigned char* target, SimpleHexRequestUser& user); SimpleHexRequest(const QString& debuggable, unsigned offset, unsigned size, unsigned char* target, SimpleHexRequestUser& user); virtual void replyOk(const QString& message); virtual void cancel(); unsigned offset; private: SimpleHexRequestUser& user; }; #endif // SIMPLEHEXREQUEST_H openmsx-debugger-0.0.0.svn20141006.orig/src/DockManager.h0000644000175000017500000000222212414415132022006 0ustar shevekshevek// $Id$ #ifndef DOCKMANAGER_H #define DOCKMANAGER_H #include "DockableWidgetLayout.h" #include #include class QRect; class QPoint; class DockableWidget; class DockableWidgetArea; class DockManager { public: void addDockArea(DockableWidgetArea* area); int dockAreaIndex(DockableWidgetArea* area) const; void insertWidget(DockableWidget* widget, int index, DockableWidgetLayout::DockSide side, int distance, int w = -1, int h = -1); void dockWidget(DockableWidget* widget, const QPoint& p, const QRect& r); void undockWidget(DockableWidget* widget); bool insertLocation(QRect& r, const QSizePolicy& sizePol); void visibilityChanged(DockableWidget* widget); void getConfig(int index, QStringList& list) const; void attachWidget(DockableWidget* widget); void detachWidget(DockableWidget* widget); const QList& managedWidgets() const; DockableWidget* findDockableWidget(const QString& id) const; private: typedef QMap AreaMap; AreaMap areaMap; QList areas; QList dockWidgets; }; #endif // DOCKMANAGER_H openmsx-debugger-0.0.0.svn20141006.orig/src/DisasmViewer.cpp0000644000175000017500000004274212414415132022603 0ustar shevekshevek// $Id$ #include "DisasmViewer.h" #include "OpenMSXConnection.h" #include "CommClient.h" #include "DebuggerData.h" #include "Settings.h" #include #include #include #include #include #include #include #include #include #include class CommMemoryRequest : public ReadDebugBlockCommand { public: CommMemoryRequest(unsigned offset_, unsigned size_, unsigned char* target, DisasmViewer& viewer_) : ReadDebugBlockCommand("memory", offset_, size_, target) , offset(offset_), size(size_) , viewer(viewer_) { } virtual void replyOk(const QString& message) { copyData(message); viewer.memoryUpdated(this); } virtual void cancel() { viewer.updateCancelled(this); } // TODO Refactor: public members are ugly unsigned offset; unsigned size; int address; int line; int method; private: DisasmViewer& viewer; }; DisasmViewer::DisasmViewer(QWidget* parent) : QFrame(parent) { setFrameStyle(WinPanel | Sunken); setFocusPolicy(Qt::StrongFocus); setBackgroundRole(QPalette::Base); setSizePolicy(QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Preferred)); breakMarker = QPixmap(":/icons/breakpoint.png"); watchMarker = QPixmap(":/icons/watchpoint.png"); pcMarker = QPixmap(":/icons/pcarrow.png"); memory = NULL; cursorAddr = 0; cursorLine = 0; visibleLines = 0; programAddr = 0xFFFF; waitingForData = false; nextRequest = NULL; scrollBar = new QScrollBar(Qt::Vertical, this); scrollBar->setMinimum(0); scrollBar->setMaximum(0xFFFF); scrollBar->setSingleStep(0); scrollBar->setPageStep(0); settingsChanged(); // manual scrollbar handling routines (real size of the data is not known) connect(scrollBar, SIGNAL(actionTriggered(int)), this, SLOT(scrollBarAction(int))); connect(scrollBar, SIGNAL(valueChanged(int)), this, SLOT(scrollBarChanged(int))); } QSize DisasmViewer::sizeHint() const { return QSize(xMnemArg + xMCode[0], 20 * codeFontHeight); } void DisasmViewer::resizeEvent(QResizeEvent* e) { QFrame::resizeEvent(e); scrollBar->setGeometry(width() - frameR, frameT, scrollBar->sizeHint().width(), height() - frameT - frameB); // reset the address in order to trigger a check on the disasmLines if (!waitingForData) { setAddress(scrollBar->value()); } } void DisasmViewer::settingsChanged() { frameL = frameT = frameB = frameWidth(); frameR = frameL + scrollBar->sizeHint().width(); setMinimumHeight(frameT + 5 * fontMetrics().height() + frameB); // set font sizes Settings& s = Settings::get(); QFontMetrics lfm(s.font(Settings::LABEL_FONT)); QFontMetrics cfm(s.font(Settings::CODE_FONT)); labelFontHeight = lfm.height(); labelFontAscent = lfm.ascent(); codeFontHeight = cfm.height(); codeFontAscent = cfm.ascent(); // calculate layout locations int charWidth = cfm.width("0"); xAddr = frameL + 40; xMCode[0] = xAddr + 6 * charWidth; xMCode[1] = xMCode[0] + 3 * charWidth; xMCode[2] = xMCode[1] + 3 * charWidth; xMCode[3] = xMCode[2] + 3 * charWidth; xMnem = xMCode[3] + 4 * charWidth; xMnemArg = xMnem + 7 * charWidth; setMinimumSize(xMCode[0], 2*codeFontHeight); setMaximumSize(QApplication::desktop()->width(), QApplication::desktop()->height()); update(); } void DisasmViewer::symbolsChanged() { int disasmStart = disasmLines.front().addr; int disasmEnd = disasmLines.back().addr + disasmLines.back().numBytes; CommMemoryRequest* req = new CommMemoryRequest( disasmStart, disasmEnd - disasmStart, &memory[disasmStart], *this); req->address = disasmLines[disasmTopLine].addr; req->line = disasmLines[disasmTopLine].infoLine; req->method = TopAlways; if (waitingForData) { delete nextRequest; nextRequest = req; } else { waitingForData = true; CommClient::instance().sendCommand(req); } } void DisasmViewer::paintEvent(QPaintEvent* e) { // call parent for drawing the actual frame QFrame::paintEvent(e); QPainter p(this); // calc and set drawing bounds QRect r(e->rect()); if (r.left() < frameL) r.setLeft(frameL); if (r.top() < frameT) r.setTop(frameT); if (r.right() > width() - frameR - 1) r.setRight (width() - frameR - 1); if (r.bottom() > height() - frameB - 1) r.setBottom(height() - frameB - 1); p.setClipRect(r); // draw background p.fillRect(frameL + 32, frameT, width() - 32 - frameL - frameR, height() - frameT - frameB, palette().color(QPalette::Base)); // calculate lines while drawing visibleLines = 0; int y = frameT; QString hexStr; const DisasmRow* row; bool displayDisasm = memory != NULL && isEnabled(); Settings& s = Settings::get(); p.setFont(s.font(Settings::CODE_FONT)); while (y < height() - frameB) { // fetch the data for this line row = displayDisasm ? &disasmLines[disasmTopLine+visibleLines] : &DISABLED_ROW; int h, a; switch (row->rowType) { case DisasmRow::LABEL: h = labelFontHeight; a = labelFontAscent; break; case DisasmRow::INSTRUCTION: h = codeFontHeight; a = codeFontAscent; break; } // draw cursor line bool isCursorLine = cursorAddr >= row->addr && cursorAddr < row->addr+row->numBytes && row->infoLine == cursorLine; if (isCursorLine) { cursorAddr = row->addr; p.fillRect(frameL + 32, y, width() - 32 - frameL - frameR, h, palette().color(QPalette::Highlight)); if (hasFocus()) { QStyleOptionFocusRect so; so.backgroundColor = palette().color(QPalette::Highlight); so.rect = QRect(frameL + 32, y, width() - 32 - frameL - frameR, h); style()->drawPrimitive(QStyle::PE_FrameFocusRect, &so, &p, this); } p.setPen(palette().color(QPalette::HighlightedText)); } // if there is a label here, draw the label, otherwise code if (row->rowType == DisasmRow::LABEL) { // draw label hexStr = QString("%1:").arg(row->instr.c_str()); p.setFont(s.font(Settings::LABEL_FONT)); if (!isCursorLine) { p.setPen(s.fontColor(Settings::LABEL_FONT)); } p.drawText(xAddr, y + a, hexStr); p.setFont(s.font(Settings::CODE_FONT)); } else { // draw code line // default to text pen if (!isCursorLine) { p.setPen(s.fontColor(Settings::CODE_FONT)); } // draw breakpoint marker if (row->infoLine == 0) { if (breakpoints->isBreakpoint(row->addr)) { p.drawPixmap(frameL + 2, y + h / 2 -5, breakMarker); if (!isCursorLine) { p.fillRect(frameL + 32, y, width() - 32 - frameL - frameR, h, Qt::red); p.setPen(Qt::white); } } else if (breakpoints->isWatchpoint(row->addr)) { p.drawPixmap(frameL + 2, y + h / 2 -5, watchMarker); } } // draw PC marker if (row->addr == programAddr && row->infoLine == 0) { p.drawPixmap(frameL + 18, y + h / 2 - 5, pcMarker); } // print the address hexStr.sprintf("%04X", row->addr); p.drawText(xAddr, y + a, hexStr); // print 1 to 4 bytes for (int j = 0; j < row->numBytes; ++j) { hexStr.sprintf("%02X", displayDisasm ? memory[row->addr + j] : 0); p.drawText(xMCode[j], y + a, hexStr); } // print the instruction and arguments p.drawText(xMnem, y + a, row->instr.substr(0, 7).c_str()); p.drawText(xMnemArg, y + a, row->instr.substr(7 ).c_str()); } // next line y += h; ++visibleLines; // check for end of data if (disasmTopLine+visibleLines == int(disasmLines.size())) break; } partialBottomLine = y > height() - frameB; visibleLines -= partialBottomLine; } void DisasmViewer::setCursorAddress(quint16 addr, int infoLine, int method) { cursorAddr = addr; cursorLine = 0; setAddress(addr, infoLine, method); } void DisasmViewer::setAddress(quint16 addr, int infoLine, int method) { int line = findDisasmLine(addr, infoLine); if (line >= 0) { int dt, db; switch (method) { case Top: case Middle: case Bottom: case Closest: dt = db = 10; break; case TopAlways: dt = 10; db = visibleLines + 10; break; case MiddleAlways: dt = db = 10 + visibleLines / 2; break; case BottomAlways: dt = 10 + visibleLines; db = 10; break; default: assert(false); dt = db = 0; // avoid warning } if ((line > dt || disasmLines[0].addr == 0) && (line < int(disasmLines.size()) - db || disasmLines.back().addr+disasmLines.back().numBytes > 0xFFFF)) { // line is within existing disasm'd data. Find where to put it. if (method == Top || method == TopAlways || (method == Closest && line < disasmTopLine)) { // Move line to top disasmTopLine = line; } else if (method == Bottom || method == BottomAlways || (method == Closest && line >= disasmTopLine + visibleLines)) { // Move line to bottom disasmTopLine = line - visibleLines + 1; } else if (method == MiddleAlways || (method == Middle && (line < disasmTopLine || line >= disasmTopLine + visibleLines))) { // Move line to middle disasmTopLine = line - visibleLines / 2; } disasmTopLine = std::min( disasmTopLine, int(disasmLines.size()) - visibleLines); disasmTopLine = std::max(disasmTopLine, 0); update(); return; } } if (method == Closest) { if (addr < disasmLines[disasmTopLine].addr) { method = Top; } else { method = Bottom; } } // The requested address it outside the pre-disassembled bounds. // This means that a new block of memory must be transfered from // openMSX and disassembled. // determine disasm bounds int disasmStart; int disasmEnd; int extra = 4 * (visibleLines > 9 ? visibleLines+partialBottomLine : 10); switch (method) { case Middle: case MiddleAlways: disasmStart = addr - 3 * extra / 2; disasmEnd = addr + 3 * extra / 2; break; case Bottom: case BottomAlways: disasmStart = addr - 2 * extra; disasmEnd = addr + extra; break; default: disasmStart = addr - extra; disasmEnd = addr + 2 * extra; } disasmStart = std::max(disasmStart, 0); disasmEnd = std::min(disasmEnd, 0xFFFF); CommMemoryRequest* req = new CommMemoryRequest( disasmStart, disasmEnd - disasmStart + 1, &memory[disasmStart], *this); req->address = addr; req->line = infoLine; req->method = method; if (waitingForData) { delete nextRequest; nextRequest = req; } else { waitingForData = true; CommClient::instance().sendCommand(req); } } void DisasmViewer::memoryUpdated(CommMemoryRequest* req) { // disassemble the newly received memory dasm(memory, req->offset, req->offset + req->size - 1, disasmLines, memLayout, symTable, programAddr); // locate the requested line disasmTopLine = findDisasmLine(req->address, req->line); switch (req->method) { case Middle: case MiddleAlways: disasmTopLine -= visibleLines / 2; break; case Bottom: case BottomAlways: disasmTopLine -= visibleLines - 1; break; } disasmTopLine = std::max(disasmTopLine, 0); disasmTopLine = std::min(disasmTopLine, int(disasmLines.size()) - visibleLines); updateCancelled(req); // sync the scrollbar with the actual address reached if (!waitingForData) { // set the slider with without the signal disconnect(scrollBar, SIGNAL(valueChanged(int)), this, SLOT(scrollBarChanged(int))); scrollBar->setSliderPosition(disasmLines[disasmTopLine].addr); connect (scrollBar, SIGNAL(valueChanged(int)), this, SLOT(scrollBarChanged(int))); // set the line setAddress(disasmLines[disasmTopLine].addr, disasmLines[disasmTopLine].infoLine); update(); } } void DisasmViewer::updateCancelled(CommMemoryRequest* req) { delete req; if (nextRequest) { CommClient::instance().sendCommand(nextRequest); nextRequest = NULL; } else { waitingForData = false; } } quint16 DisasmViewer::cursorAddress() const { return cursorAddr; } quint16 DisasmViewer::programCounter() const { return programAddr; } void DisasmViewer::setProgramCounter(quint16 pc) { cursorAddr = pc; programAddr = pc; setAddress(pc, 0, MiddleAlways); } int DisasmViewer::findDisasmLine(quint16 lineAddr, int infoLine) { int line = disasmLines.size() - 1; while( line >= 0 ) { if( lineAddr >= disasmLines[line].addr ) { if( infoLine == 0 ) return line; if (infoLine == LAST_INFO_LINE) return line-1; while (disasmLines[line].infoLine != infoLine && disasmLines[line].addr == lineAddr) { line--; if (line < 0) return -1; } return line; } line--; } return -1; } void DisasmViewer::scrollBarAction(int action) { switch (action) { case QScrollBar::SliderSingleStepAdd: setAddress(disasmLines[disasmTopLine + 1].addr, disasmLines[disasmTopLine + 1].infoLine, TopAlways); break; case QScrollBar::SliderSingleStepSub: if (disasmTopLine > 0) { setAddress(disasmLines[disasmTopLine - 1].addr, disasmLines[disasmTopLine - 1].infoLine, TopAlways); } break; case QScrollBar::SliderPageStepAdd: { int line = disasmTopLine + visibleLines + partialBottomLine - 1; if (line < int(disasmLines.size())) { setAddress(disasmLines[line].addr, disasmLines[line].infoLine, TopAlways); } break; } case QScrollBar::SliderPageStepSub: if (disasmTopLine > 0) { setAddress(disasmLines[disasmTopLine - 1].addr, disasmLines[disasmTopLine - 1].infoLine, BottomAlways); } break; default: break; } } // moving the slider is handled separately because // the SliderMoved action won't catch the extreme values void DisasmViewer::scrollBarChanged(int value) { setAddress(value, FIRST_INFO_LINE, TopAlways); } void DisasmViewer::setMemory(unsigned char* memPtr) { memory = memPtr; // init disasmLines DisasmRow newRow; newRow.rowType = DisasmRow::INSTRUCTION; newRow.numBytes = 1; newRow.infoLine = 0; newRow.instr = "nop"; newRow.instr.resize(8, ' '); for (int i = 0; i < 150; ++i) { newRow.addr = i; disasmLines.push_back(newRow); } disasmTopLine = 50; } void DisasmViewer::setBreakpoints(Breakpoints* bps) { breakpoints = bps; } void DisasmViewer::setMemoryLayout(MemoryLayout* ml) { memLayout = ml; } void DisasmViewer::setSymbolTable(SymbolTable* st) { symTable = st; } void DisasmViewer::keyPressEvent(QKeyEvent* e) { switch (e->key()) { case Qt::Key_Up: { int line = findDisasmLine(cursorAddr, cursorLine); if (line > 0) { cursorAddr = disasmLines[line - 1].addr; cursorLine = disasmLines[line - 1].infoLine; } setAddress(cursorAddr, cursorLine, Closest); e->accept(); break; } case Qt::Key_Down: { int line = findDisasmLine(cursorAddr, cursorLine); if (line >= 0 && line < int(disasmLines.size()) - 1) { cursorAddr = disasmLines[line + 1].addr; cursorLine = disasmLines[line + 1].infoLine; } setAddress(cursorAddr, cursorLine, Closest); e->accept(); break; } case Qt::Key_PageUp: { int line = findDisasmLine(cursorAddr, cursorLine); if( line >= disasmTopLine && line < disasmTopLine+visibleLines ) { line -= visibleLines; if(line >= 0) { cursorAddr = disasmLines[line].addr; cursorLine = disasmLines[line].infoLine; setAddress(disasmLines[disasmTopLine - 1].addr, disasmLines[disasmTopLine - 1].infoLine, BottomAlways); } else { setCursorAddress(disasmLines[0].addr, disasmLines[0].infoLine, Closest); } } else setAddress(cursorAddr, cursorLine, Closest); e->accept(); break; } case Qt::Key_PageDown: { int line = findDisasmLine(cursorAddr, cursorLine); if( line >= disasmTopLine && line < disasmTopLine+visibleLines ) { line += visibleLines; if( line < int(disasmLines.size()) ) { cursorAddr = disasmLines[line].addr; cursorLine = disasmLines[line].infoLine; line = disasmTopLine + visibleLines + partialBottomLine - 1; line = std::min(line, int(disasmLines.size())); setAddress(disasmLines[line].addr, disasmLines[line].infoLine, TopAlways); } else { setCursorAddress(disasmLines.back().addr, disasmLines.back().infoLine, Closest); } } else setAddress(cursorAddr, cursorLine, Closest); e->accept(); break; } default: QFrame::keyReleaseEvent(e); } } void DisasmViewer::wheelEvent(QWheelEvent* e) { int line = std::max(0, disasmTopLine - e->delta() / 40); if (e->orientation() == Qt::Vertical) { setAddress(disasmLines[line].addr, disasmLines[line].infoLine, TopAlways); e->accept(); } } void DisasmViewer::mousePressEvent(QMouseEvent* e) { if (!(e->button() == Qt::LeftButton)) { QFrame::mousePressEvent(e); return; } if (e->x() >= frameL && e->x() < width() - frameR && e->y() >= frameT && e->y() < height() - frameB) { int line = lineAtPos(e->pos()); if (e->x() > frameL + 32) { // check if the line exists // (bottom of memory could have an empty line) if (line + disasmTopLine < int(disasmLines.size())) { cursorAddr = disasmLines[disasmTopLine + line].addr; cursorLine = disasmLines[disasmTopLine + line].infoLine; } else { return; } // scroll if partial line if (line == visibleLines) { setAddress(disasmLines[disasmTopLine + 1].addr, TopAlways); } else { update(); } } else if (e->x() < frameL + 16) { // clicked on the breakpoint area if (line + disasmTopLine < int(disasmLines.size())) { emit toggleBreakpoint(disasmLines[line + disasmTopLine].addr); } } } } int DisasmViewer::lineAtPos(const QPoint& pos) { int line = -1; int y = frameT; do { ++line; switch (disasmLines[disasmTopLine+line].rowType) { case DisasmRow::LABEL: y += labelFontHeight; break; case DisasmRow::INSTRUCTION: y += codeFontHeight; break; } } while (y < pos.y()); return line; } openmsx-debugger-0.0.0.svn20141006.orig/src/ConnectDialog.h0000644000175000017500000000276612414415132022361 0ustar shevekshevek// $Id$ #ifndef CONNECTDIALOG_HH #define CONNECTDIALOG_HH #include "OpenMSXConnection.h" #include "ui_ConnectDialog.h" #include #include class QString; class ConnectionInfoRequest; class ConnectDialog : public QDialog { Q_OBJECT public: static OpenMSXConnection* getConnection(QWidget* parent = 0); private slots: void on_connectButton_clicked(); void on_rescanButton_clicked(); private: ConnectDialog(QWidget* parent); ~ConnectDialog(); void clear(); void connectionOk(OpenMSXConnection& connection, const QString& title); void connectionBad(OpenMSXConnection& connection); void timerEvent(QTimerEvent *event); int delay; Ui::ConnectDialog ui; typedef QList OpenMSXConnections; OpenMSXConnections pendingConnections; OpenMSXConnections confirmedConnections; OpenMSXConnection* result; QList connectionInfos; friend class ConnectionInfoRequest; }; // Command handler to get initial info from new openmsx connections class ConnectionInfoRequest : public QObject, Command { Q_OBJECT public: ConnectionInfoRequest(ConnectDialog& dialog, OpenMSXConnection& connection); virtual QString getCommand() const; virtual void replyOk (const QString& message); virtual void replyNok(const QString& message); virtual void cancel(); private: enum State { GET_MACHINE, GET_TITLE, DONE }; ConnectDialog& dialog; OpenMSXConnection& connection; State state; QString title; private slots: void terminate(); }; #endif openmsx-debugger-0.0.0.svn20141006.orig/src/CommClient.h0000644000175000017500000000122112414415132021663 0ustar shevekshevek// $Id$ #ifndef COMMCLIENT_H #define COMMCLIENT_H #include class OpenMSXConnection; class Command; class QString; class CommClient : public QObject { Q_OBJECT public: static CommClient& instance(); void sendCommand(Command* command); public slots: void connectToOpenMSX(OpenMSXConnection* conn); void closeConnection(); signals: void connectionReady(); void connectionTerminated(); void logParsed(const QString& level, const QString& message); void updateParsed(const QString& type, const QString& name, const QString& message); private: CommClient(); ~CommClient(); OpenMSXConnection* connection; }; #endif // COMMCLIENT_H openmsx-debugger-0.0.0.svn20141006.orig/src/DebuggerForm.h0000644000175000017500000001115712414415132022212 0ustar shevekshevek// $Id$ #ifndef DEBUGGERFORM_H #define DEBUGGERFORM_H #include "DockManager.h" #include "DebugSession.h" #include #include class DockableWidgetArea; class DisasmViewer; class MainMemoryViewer; class CPURegsViewer; class FlagsViewer; class StackViewer; class SlotViewer; class CommClient; class QAction; class QMenu; class QToolBar; class VDPStatusRegViewer; class VDPRegViewer; class VDPCommandRegViewer; class DebuggerForm : public QMainWindow { Q_OBJECT; public: DebuggerForm(QWidget* parent = 0); ~DebuggerForm(); public slots: void showAbout(); private: void closeEvent(QCloseEvent* e); void createActions(); void createMenus(); void createToolbars(); void createStatusbar(); void createForm(); void openSession(const QString& file); void updateRecentFiles(); void addRecentFile(const QString& file); void removeRecentFile(const QString& file); void finalizeConnection(bool halted); void pauseStatusChanged(bool isPaused); void breakOccured(); void setBreakMode(); void setRunMode(); void updateData(); void refreshBreakpoints(); void addressSlot(int addr, int& ps, int& ss, int& segment); QMenu* fileMenu; QMenu* systemMenu; QMenu* searchMenu; QMenu* viewMenu; QMenu* viewVDPDialogsMenu; QMenu* executeMenu; QMenu* breakpointMenu; QMenu* helpMenu; QToolBar* systemToolbar; QToolBar* executeToolbar; QAction* fileNewSessionAction; QAction* fileOpenSessionAction; QAction* fileSaveSessionAction; QAction* fileSaveSessionAsAction; QAction* fileQuitAction; enum { MaxRecentFiles = 5 }; QAction *recentFileActions[MaxRecentFiles]; QAction *recentFileSeparator; QAction* systemConnectAction; QAction* systemDisconnectAction; QAction* systemPauseAction; QAction* systemRebootAction; QAction* systemSymbolManagerAction; QAction* systemPreferencesAction; QAction* searchGotoAction; QAction* viewRegistersAction; QAction* viewFlagsAction; QAction* viewStackAction; QAction* viewSlotsAction; QAction* viewMemoryAction; QAction* viewDebuggableViewerAction; QAction* viewBitMappedAction; QAction* viewVDPStatusRegsAction; QAction* viewVDPRegsAction; QAction* viewVDPCommandRegsAction; QAction* executeBreakAction; QAction* executeRunAction; QAction* executeStepAction; QAction* executeStepOverAction; QAction* executeRunToAction; QAction* executeStepOutAction; QAction* executeStepBackAction; QAction* breakpointToggleAction; QAction* breakpointAddAction; QAction* helpAboutAction; DockManager dockMan; DockableWidgetArea* mainArea; QStringList recentFiles; DisasmViewer* disasmView; MainMemoryViewer* mainMemoryView; CPURegsViewer* regsView; FlagsViewer* flagsView; StackViewer* stackView; SlotViewer* slotView; VDPStatusRegViewer* VDPStatusRegView; VDPRegViewer* VDPRegView; VDPCommandRegViewer* VDPCommandRegView; CommClient& comm; DebugSession session; MemoryLayout memLayout; unsigned char* mainMemory; bool mergeBreakpoints; QMap debuggables; private slots: void fileNewSession(); void fileOpenSession(); void fileSaveSession(); void fileSaveSessionAs(); void fileRecentOpen(); void systemConnect(); void systemDisconnect(); void systemPause(); void systemReboot(); void systemSymbolManager(); void systemPreferences(); void searchGoto(); void toggleRegisterDisplay(); void toggleFlagsDisplay(); void toggleStackDisplay(); void toggleSlotsDisplay(); void toggleMemoryDisplay(); void toggleBitMappedDisplay(); void toggleVDPRegsDisplay(); void toggleVDPStatusRegsDisplay(); void toggleVDPCommandRegsDisplay(); void addDebuggableViewer(); void executeBreak(); void executeRun(); void executeStep(); void executeStepOver(); void executeRunTo(); void executeStepOut(); void executeStepBack(); void breakpointToggle(int addr = -1); void breakpointAdd(); void handleCommandReplyStatus(bool status); void toggleView(DockableWidget* widget); void initConnection(); void handleUpdate(const QString& type, const QString& name, const QString& message); void setDebuggables(const QString& list); void setDebuggableSize(const QString& debuggable, int size); void connectionClosed(); void dockWidgetVisibilityChanged(DockableWidget* w); void updateViewMenu(); void updateVDPViewMenu(); void updateWindowTitle(); void symbolFileChanged(); friend class QueryPauseHandler; friend class QueryBreakedHandler; friend class ListBreakPointsHandler; friend class CPURegRequest; friend class ListDebuggablesHandler; friend class DebuggableSizeHandler; signals: void settingsChanged(); void symbolsChanged(); void debuggablesChanged(const QMap& list); void emulationChanged(); }; #endif // DEBUGGERFORM_H openmsx-debugger-0.0.0.svn20141006.orig/src/Version.cpp0000644000175000017500000000032012414415132021610 0ustar shevekshevek// $Id$ #include "Version.h" #include "Version.ii" std::string Version::full() { return std::string("openMSX Debugger ") + VERSION + (RELEASE ? "" : (std::string("-") + REVISION)); } openmsx-debugger-0.0.0.svn20141006.orig/src/CPURegs.h0000644000175000017500000000104412414415132021104 0ustar shevekshevek// $Id: $ #ifndef CPUREGS_H #define CPUREGS_H struct CpuRegs { static const int REG_AF; static const int REG_AF2; static const int REG_BC; static const int REG_BC2; static const int REG_DE; static const int REG_DE2; static const int REG_HL; static const int REG_HL2; static const int REG_IX; static const int REG_IY; static const int REG_PC; static const int REG_SP; static const int REG_I; static const int REG_R; static const int REG_IM; static const int REG_IFF; static const char* const regNames[14]; }; #endif //CPUREGS_H openmsx-debugger-0.0.0.svn20141006.orig/src/CommClient.cpp0000644000175000017500000000213112414415132022217 0ustar shevekshevek// $Id$ #include "CommClient.h" #include "OpenMSXConnection.h" CommClient::CommClient() : connection(NULL) { } CommClient::~CommClient() { closeConnection(); } CommClient& CommClient::instance() { static CommClient oneInstance; return oneInstance; } void CommClient::connectToOpenMSX(OpenMSXConnection* conn) { closeConnection(); connection = conn; connect(connection, SIGNAL(disconnected()), SLOT(closeConnection())); connect(connection, SIGNAL(logParsed(const QString&, const QString&)), SIGNAL(logParsed(const QString&, const QString&))); connect(connection, SIGNAL(updateParsed(const QString&, const QString&, const QString&)), SIGNAL(updateParsed(const QString&, const QString&, const QString&))); emit connectionReady(); } void CommClient::closeConnection() { if (connection) { connection->disconnect(this, SLOT(closeConnection())); delete connection; connection = NULL; emit connectionTerminated(); } } void CommClient::sendCommand(Command* command) { if (connection) { connection->sendCommand(command); } else { command->cancel(); } } openmsx-debugger-0.0.0.svn20141006.orig/src/VDPStatusRegViewer.cpp0000644000175000017500000001503512414415132023651 0ustar shevekshevek#include "VDPStatusRegViewer.h" #include "VramBitMappedView.h" #include "VDPDataStore.h" #include "InteractiveLabel.h" #include #include highlightDispatcher::highlightDispatcher() { counter = 0; } void highlightDispatcher::receiveState(bool state) { if (state) { if (counter == 0) { emit dispatchState(true); } ++counter; } else { --counter; if (counter == 0) { emit dispatchState(false); } } } VDPStatusRegViewer::VDPStatusRegViewer(QWidget* parent) : QDialog(parent) { setupUi(this); //statusregs = VDPDataStore::instance().getStatusRegsPointer(); statusregs = new unsigned char[16]; // now hook up some signals and slots connectHighLights(); // get initiale data refresh(); } VDPStatusRegViewer::~VDPStatusRegViewer() { delete[] statusregs; } void VDPStatusRegViewer::decodeVDPStatusRegs() { // first update all hex values label_val_0->setText(QString("%1").arg(statusregs[0],2,16,QChar('0')).toUpper()); label_val_1->setText(QString("%1").arg(statusregs[1],2,16,QChar('0')).toUpper()); label_val_2->setText(QString("%1").arg(statusregs[2],2,16,QChar('0')).toUpper()); label_val_3->setText(QString("%1").arg(statusregs[3],2,16,QChar('0')).toUpper()); label_val_4->setText(QString("%1").arg(statusregs[4],2,16,QChar('0')).toUpper()); label_val_5->setText(QString("%1").arg(statusregs[5],2,16,QChar('0')).toUpper()); label_val_6->setText(QString("%1").arg(statusregs[6],2,16,QChar('0')).toUpper()); label_val_7->setText(QString("%1").arg(statusregs[7],2,16,QChar('0')).toUpper()); label_val_8->setText(QString("%1").arg(statusregs[8],2,16,QChar('0')).toUpper()); label_val_9->setText(QString("%1").arg(statusregs[9],2,16,QChar('0')).toUpper()); // update all the individual bits for (int r = 0; r <= 9; ++r) { for (int b = 7; b >= 0; --b) { QString name = QString("label_%1_%2").arg(r).arg(b); InteractiveLabel* l = findChild(name); l->setText((statusregs[r] & (1 << b)) ? "1" : "0"); } } // Start the interpretation label_I_0_7->setText((statusregs[0] & 128) ? "Interrupt" : "No int"); label_I_0_6->setText((statusregs[0] & 64) ? "5th sprite" : "No 5th"); label_I_0_5->setText((statusregs[0] & 32) ? "Collision" : "No collision"); label_I_0_0->setText(QString("sprnr:%1").arg(statusregs[0] & 31)); label_I_1_7->setText((statusregs[1] & 128) ? "Light" : "No light"); label_I_1_6->setText((statusregs[1] & 64) ? "switch on" : "Switch off"); label_I_1_0->setText((statusregs[1] & 1) ? "hor scanline int" : "no hor int"); QString id; switch (statusregs[1] & 62) { case 0: id = QString("v9938"); break; case 2: id = QString("v9948"); break; case 4: id = QString("v9958"); break; default: id = QString("unknown VDP"); } label_I_1_1->setText(id); label_I_2_7->setText((statusregs[2] & 128) ? "Transfer ready" : "Transfering"); label_I_2_6->setText((statusregs[2] & 64) ? "Vertical scanning" : "Not vert scan"); label_I_2_5->setText((statusregs[2] & 32) ? "Horizontal scanning" : "Not hor scan"); label_I_2_4->setText((statusregs[2] & 16) ? "Boundary color detected" : "BC not deteced"); label_I_2_1->setText((statusregs[2] & 2) ? "First field" : "Second field"); label_I_2_0->setText((statusregs[2] & 1) ? "Command execution" : "No command exec"); label_I_3->setText(QString("Column: %1").arg(statusregs[3] | ((statusregs[4] & 1) << 8))); label_I_5->setText(QString("Row: %1").arg(statusregs[5] | ((statusregs[6] & 3) << 8))); label_I_7->setText(QString("Color: %1").arg(statusregs[7])); label_I_8->setText(QString("Border X: %1").arg(statusregs[8] | ((statusregs[9] & 1) << 8))); } void VDPStatusRegViewer::doConnect(InteractiveLabel* lab, highlightDispatcher* dis) { connect(lab, SIGNAL(mouseOver(bool)), dis, SLOT(receiveState(bool))); connect(dis, SIGNAL(dispatchState(bool)), lab, SLOT(highlight(bool))); } void VDPStatusRegViewer::makeGroup(QList list, InteractiveLabel* explained) { // First "steal" the Tooltip of the explained widget. InteractiveLabel* item; foreach (item, list) { item->setToolTip(explained->toolTip()); } // now create a dispatcher and connect all to them list << explained; highlightDispatcher* dispat = new highlightDispatcher(); foreach (item, list) { doConnect(item, dispat); } } void VDPStatusRegViewer::connectHighLights() { QList list; list.clear(); list << label_0_7; makeGroup(list, label_I_0_7); list.clear(); list << label_0_6; makeGroup(list, label_I_0_6); list.clear(); list << label_0_5; makeGroup(list, label_I_0_5); list.clear(); list << label_0_4 << label_0_3 << label_0_2 << label_0_1 << label_0_0; makeGroup(list, label_I_0_0); list.clear(); list << label_1_7; makeGroup(list, label_I_1_7); list.clear(); list << label_1_6; makeGroup(list, label_I_1_6); list.clear(); list << label_1_4 << label_1_3 << label_1_2 << label_1_1; makeGroup(list, label_I_1_1); list.clear(); list << label_1_0; makeGroup(list, label_I_1_0); list.clear(); list << label_2_7; makeGroup(list, label_I_2_7); list.clear(); list << label_2_6; makeGroup(list, label_I_2_6); list.clear(); list << label_2_5; makeGroup(list, label_I_2_5); list.clear(); list << label_2_4; makeGroup(list, label_I_2_4); list.clear(); list << label_2_1; makeGroup(list, label_I_2_1); list.clear(); list << label_2_0; makeGroup(list, label_I_2_0); list.clear(); list << label_2_0; makeGroup(list, label_I_2_0); list.clear(); list << label_3_7 << label_3_6 << label_3_5 << label_3_4; list << label_3_3 << label_3_2 << label_3_1 << label_3_0; list << label_4_7 << label_4_6 << label_4_5 << label_4_4; list << label_4_3 << label_4_2 << label_4_1 << label_4_0; makeGroup(list, label_I_3); list.clear(); list << label_5_7 << label_5_6 << label_5_5 << label_5_4; list << label_5_3 << label_5_2 << label_5_1 << label_5_0; list << label_6_7 << label_6_6 << label_6_5 << label_6_4; list << label_6_3 << label_6_2 << label_6_1 << label_6_0; makeGroup(list, label_I_5); list.clear(); list << label_7_7 << label_7_6 << label_7_5 << label_7_4; list << label_7_3 << label_7_2 << label_7_1 << label_7_0; makeGroup(list, label_I_7); list.clear(); list << label_8_7 << label_8_6 << label_8_5 << label_8_4; list << label_8_3 << label_8_2 << label_8_1 << label_8_0; list << label_9_7 << label_9_6 << label_9_5 << label_9_4; list << label_9_3 << label_9_2 << label_9_1 << label_9_0; makeGroup(list, label_I_8); } void VDPStatusRegViewer::refresh() { new SimpleHexRequest("{VDP status regs}", 0, 16, statusregs, *this); } void VDPStatusRegViewer::DataHexRequestReceived() { decodeVDPStatusRegs(); } openmsx-debugger-0.0.0.svn20141006.orig/src/DockableWidget.cpp0000644000175000017500000001346712414415132023053 0ustar shevekshevek// $Id$ #include "DockableWidget.h" #include "DockManager.h" #include #include #include #include #include #include #include #include #include #include DockableWidget::DockableWidget( DockManager& manager, QWidget* parent) : QWidget(parent), dockManager(manager) { mainWidget = 0; floating = false; movable = true; closable = true; destroyable = true; dragging = false; setAttribute(Qt::WA_DeleteOnClose, true); titleLabel = new QLabel(); closeButton = new QToolButton(); closeButton->setIcon(style()->standardIcon(QStyle::SP_TitleBarCloseButton)); closeButton->setToolButtonStyle(Qt::ToolButtonIconOnly); int sz = style()->pixelMetric(QStyle::PM_SmallIconSize); closeButton->setIconSize(style()->standardIcon( QStyle::SP_TitleBarCloseButton).actualSize(QSize(sz, sz))); closeButton->setAutoRaise(true); connect(closeButton, SIGNAL(clicked()), this, SLOT(close())); headerLayout = new QHBoxLayout(); headerLayout->setMargin(0); headerLayout->addWidget(titleLabel, 1); headerLayout->addWidget(closeButton, 0); headerWidget = new QWidget(); headerWidget->setLayout(headerLayout); widgetLayout = new QVBoxLayout(); widgetLayout->setMargin(3); widgetLayout->setSpacing(1); widgetLayout->addWidget(headerWidget); setLayout(widgetLayout); dockManager.attachWidget(this); rubberBand = new QRubberBand(QRubberBand::Rectangle); } DockableWidget::~DockableWidget() { delete mainWidget; delete rubberBand; dockManager.detachWidget(this); } QWidget* DockableWidget::widget() const { return mainWidget; } void DockableWidget::setWidget(QWidget* widget) { if (mainWidget) { widgetLayout->removeWidget(mainWidget); } mainWidget = widget; if (widget) { widgetLayout->addWidget(widget, 1); int minW = sizeHint().width() - widget->sizeHint().width() + widget->minimumWidth(); int minH = sizeHint().height() - widget->sizeHint().height() + widget->minimumHeight(); int maxW = sizeHint().width() - widget->sizeHint().width() + widget->maximumWidth(); int maxH = sizeHint().height() - widget->sizeHint().height() + widget->maximumHeight(); maxW = std::min(maxW, QWIDGETSIZE_MAX); maxH = std::min(maxH, QWIDGETSIZE_MAX); setMinimumSize(minW, minH); setMaximumSize(maxW, maxH); setSizePolicy(widget->sizePolicy()); } } const QString& DockableWidget::id() const { return widgetId; } void DockableWidget::setId(const QString& str) { widgetId = str; } QString DockableWidget::title() const { return windowTitle(); } void DockableWidget::setTitle(const QString& title) { setWindowTitle(title); titleLabel->setText(title + ':'); } bool DockableWidget::isFloating() const { return floating; } void DockableWidget::setFloating(bool enable, bool showNow) { if (floating == enable) return; floating = enable; setWindowFlags(floating ? Qt::Tool : Qt::Widget); if (floating && showNow) { show(); } } bool DockableWidget::isMovable() const { return movable; } void DockableWidget::setMovable(bool enable) { movable = enable; } bool DockableWidget::isClosable() const { return closable; } void DockableWidget::setClosable(bool enable) { if (closable == enable) return; closable = enable; if (enable) { closeButton->show(); } else { closeButton->hide(); } dragging = false; rubberBand->hide(); } bool DockableWidget::isDestroyable() const { return destroyable; } void DockableWidget::setDestroyable(bool enable) { destroyable = enable; setAttribute(Qt::WA_DeleteOnClose, enable); } void DockableWidget::closeEvent(QCloseEvent* event) { if (closable || destroyable) { if (destroyable && floating) { dockManager.undockWidget(this); event->accept(); } else { hide(); event->ignore(); emit visibilityChanged(this); } } else { event->ignore(); } } void DockableWidget::mousePressEvent(QMouseEvent* event) { if (movable && event->button() == Qt::LeftButton) { dragging = true; dragStart = event->globalPos(); dragOffset = event->pos(); } } void DockableWidget::mouseMoveEvent(QMouseEvent* event) { if (!dragging) return; if (event->buttons() & Qt::LeftButton) { // dragging of widget in progress, update rubberband if (!rubberBand->isVisible()) { if (abs(event->globalX() - dragStart.x()) > 20 || abs(event->globalY() - dragStart.y()) > 20 ) { rubberBand->resize(width(), height()); rubberBand->move(event->globalX()-dragOffset.x(), event->globalY()-dragOffset.y()); rubberBand->show(); } } else { QRect r(event->globalX()-dragOffset.x(), event->globalY()-dragOffset.y(), width(), height()); if (floating && dockManager.insertLocation(r, sizePolicy())) { rubberBand->move(r.x(), r.y()); rubberBand->resize(r.width(), r.height()); } else { rubberBand->move(event->globalX()-dragOffset.x(), event->globalY()-dragOffset.y()); rubberBand->resize(width(), height()); } } } else { dragging = false; rubberBand->hide(); } } void DockableWidget::mouseReleaseEvent(QMouseEvent* event) { if (!dragging) return; dragging = false; rubberBand->hide(); // only do anything if this was a meaningful drag if (!movable || (abs(event->globalX() - dragStart.x()) <= 20 && abs(event->globalY() - dragStart.y()) <= 20)) { return; } if (floating) { QRect mouseRect(event->globalX() - dragOffset.x(), event->globalY() - dragOffset.y(), width(), height()); QRect r(mouseRect); if (dockManager.insertLocation(r, sizePolicy())) { setFloating(false); dockManager.dockWidget(this, QPoint(), mouseRect); } else { move(event->globalPos() - dragOffset); } } else { dockManager.undockWidget(this); setFloating(true); move(event->globalPos() - dragOffset); } } openmsx-debugger-0.0.0.svn20141006.orig/src/DebuggerData.h0000644000175000017500000000344712414415132022163 0ustar shevekshevek// $Id$ #ifndef DEBUGGERDATA_H #define DEBUGGERDATA_H #include #include #include #include struct MemoryLayout { MemoryLayout(); int primarySlot[4]; int secondarySlot[4]; int mapperSegment[4]; int romBlock[8]; bool isSubslotted[4]; int mapperSize[4][4]; }; class Breakpoints { public: Breakpoints(); enum Type { BREAKPOINT = 0, WATCHPOINT_MEMREAD, WATCHPOINT_MEMWRITE, WATCHPOINT_IOREAD, WATCHPOINT_IOWRITE, CONDITION }; void clear(); void setMemoryLayout(MemoryLayout* ml); void setBreakpoints(const QString& str); QString mergeBreakpoints(const QString& str); int breakpointCount(); bool isBreakpoint(quint16 addr, QString *id = 0); bool isWatchpoint(quint16 addr, QString *id = 0); /* xml session file functions */ void saveBreakpoints(QXmlStreamWriter& xml); void loadBreakpoints(QXmlStreamReader& xml); int findBreakpoint(quint16 addr); int findNextBreakpoint(); static QString createSetCommand(Type type, int address, char ps = -1, char ss = -1, int segment = -1, int endRange = -1, QString condition = QString()); static QString createRemoveCommand(const QString& id); private: struct Breakpoint { Type type; QString id; quint16 address; // end for watchpoint region quint16 regionEnd; // gui specific condition variables char ps; char ss; qint16 segment; // general condition QString condition; // compare content bool operator==(const Breakpoint &bp) const; }; typedef QLinkedList BreakpointList; BreakpointList breakpoints; MemoryLayout* memLayout; void parseCondition(Breakpoint& bp); void insertBreakpoint(Breakpoint& bp); bool inCurrentSlot(const Breakpoint& bp); }; #endif // DEBUGGERDATA_H openmsx-debugger-0.0.0.svn20141006.orig/src/Settings.h0000644000175000017500000000160012414415132021432 0ustar shevekshevek// $Id$ #ifndef SETTINGS_H #define SETTINGS_H #include #include #include class Settings : public QSettings { Q_OBJECT public: enum DebuggerFont { APP_FONT, FIXED_FONT, CODE_FONT, LABEL_FONT, HEX_FONT, FONT_END }; enum DebuggerFontType { APPLICATION_DEFAULT, FIXED_DEFAULT, CUSTOM }; static Settings& get(); QString fontName(DebuggerFont f) const; const QFont& font(DebuggerFont f) const; void setFont(DebuggerFont f, const QFont& ft); DebuggerFontType fontType(DebuggerFont f) const; void setFontType(DebuggerFont f, DebuggerFontType t); const QColor& fontColor(DebuggerFont f) const; void setFontColor(DebuggerFont f, const QColor& c); private: Settings(); ~Settings(); QFont fonts[FONT_END]; DebuggerFontType fontTypes[FONT_END]; QColor fontColors[FONT_END]; void getFontsFromSettings(); void updateFonts(); }; #endif // SETTINGS_H openmsx-debugger-0.0.0.svn20141006.orig/src/BitMapViewer.h0000644000175000017500000000174312414415132022200 0ustar shevekshevek#ifndef BITMAPVIEWER_OPENMSX_H #define BITMAPVIEWER_OPENMSX_H #include "ui_BitMapViewer.h" #include class VramBitMappedView; class BitMapViewer : public QDialog, private Ui::BitMapViewer { Q_OBJECT public: BitMapViewer(QWidget* parent = 0); private: void decodeVDPregs(); VramBitMappedView* imageWidget; int screenMod; bool useVDP; private slots: void refresh(); void on_screenMode_currentIndexChanged(const QString& text); void on_showPage_currentIndexChanged(int index); void on_linesVisible_currentIndexChanged(int index); void on_bgColor_valueChanged(int value); void on_useVDPRegisters_stateChanged(int state); void on_saveImageButton_clicked(bool checked); void on_editPaletteButton_clicked(bool checked); void on_useVDPPalette_stateChanged(int state); void on_zoomLevel_valueChanged(double d); void imagePositionUpdate(int x, int y, int color, unsigned addr, int byteValue); void VDPDataStoreDataRefreshed(); }; #endif /* BITMAPVIEWER_OPENMSX_H */ openmsx-debugger-0.0.0.svn20141006.orig/src/BreakpointDialog.ui0000644000175000017500000002115712414415132023247 0ustar shevekshevek BreakpointDialog 0 0 401 376 0 0 Add breakpoint 6 9 6 0 Type: Breakpoint Memory read watchpoint Memory write watchpoint IO read watchpoint IO write watchpoint Condition Qt::Horizontal 40 20 0 0 Add breakpoint at address: 0 6 any Subslot: cmbxSubslot Segment: cmbxSegment any 0 1 2 3 Slot: cmbxSlot any 0 1 2 3 Qt::Horizontal 40 20 With PC in Condition true 0 48 6 0 Qt::Horizontal 131 31 OK true Cancel edtAddress edtAddressRange cmbxSlot cmbxSubslot cmbxSegment cbCondition txtCondition okButton cancelButton cmbxType okButton clicked() BreakpointDialog accept() 278 253 96 254 cancelButton clicked() BreakpointDialog reject() 369 253 179 282 openmsx-debugger-0.0.0.svn20141006.orig/src/StackViewer.h0000644000175000017500000000146612414415132022073 0ustar shevekshevek// $Id$ #ifndef STACKVIEWER_H #define STACKVIEWER_H #include class StackRequest; class QScrollBar; class QPaintEvent; class StackViewer : public QFrame { Q_OBJECT; public: StackViewer(QWidget* parent = 0); void setData(unsigned char* memPtr, int memLength); QSize sizeHint() const; public slots: void setLocation(int addr); void setStackPointer(quint16 addr); private: void resizeEvent(QResizeEvent* e); void paintEvent(QPaintEvent* e); void setScrollBarValues(); void memdataTransfered(StackRequest* r); void transferCancelled(StackRequest* r); QScrollBar* vertScrollBar; int frameL, frameR, frameT, frameB; double visibleLines; bool waitingForData; int stackPointer; int topAddress; unsigned char* memory; int memoryLength; friend class StackRequest; }; #endif // STACKVIEWER_H openmsx-debugger-0.0.0.svn20141006.orig/src/GotoDialog.h0000644000175000017500000000077512414415132021676 0ustar shevekshevek#ifndef GOTODIALOG_H #define GOTODIALOG_H #include "ui_GotoDialog.h" #include struct MemoryLayout; class DebugSession; class Symbol; class GotoDialog : public QDialog, private Ui::GotoDialog { Q_OBJECT public: GotoDialog(const MemoryLayout& ml, DebugSession *session = 0, QWidget* parent = 0); int address(); private: const MemoryLayout& memLayout; DebugSession *debugSession; Symbol *currentSymbol; private slots: void addressChanged(const QString& text); }; #endif // GOTODIALOG_H openmsx-debugger-0.0.0.svn20141006.orig/src/FlagsViewer.cpp0000644000175000017500000000445412414415132022415 0ustar shevekshevek// $Id$ #include "FlagsViewer.h" #include #include FlagsViewer::FlagsViewer(QWidget* parent) : QFrame(parent) { flags = flagsChanged = 0; // avoid UMR setFrameStyle(WinPanel | Sunken); setFocusPolicy(Qt::StrongFocus); setBackgroundRole(QPalette::Base); setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); frameR = frameL = frameT = frameB = frameWidth(); } void FlagsViewer::resizeEvent(QResizeEvent* e) { QFrame::resizeEvent(e); } void FlagsViewer::paintEvent(QPaintEvent* e) { const char* const flagNames[8] = { "C" , "N", "P" , "", "H", "", "Z" , "S" }; const char* const flagOn[8] = { "(C)" , "" , "(PE)", "", "", "", "(Z)" , "(M)" }; const char* const flagOff[8] = { "(NC)", "" , "(PO)", "", "", "", "(NZ)", "(P)" }; // call parent for drawing the actual frame QFrame::paintEvent(e); QPainter p(this); p.setPen(palette().color(QPalette::Text)); // calc and set drawing bounds QRect r(e->rect()); if (r.left() < frameL) r.setLeft(frameL); if (r.top() < frameT) r.setTop (frameT); if (r.right() > width() - frameR - 1) r.setRight (width() - frameR - 1); if (r.bottom() > height() - frameB - 1) r.setBottom(height() - frameB - 1); p.setClipRect(r); // redraw background p.fillRect(r, palette().color(QPalette::Base)); int h = fontMetrics().height(); int flagWidth = fontMetrics().width("ZW"); int valWidth = fontMetrics().width("0 "); int d = fontMetrics().descent(); int y = frameT + h - 1 - d; for (int flag = 7; flag >= 0; --flag) { int x = frameL + 4; p.drawText(x, y, flagNames[flag]); x += flagWidth; int bit = 1 << flag; drawValue(p, x, y, (flags & bit) ? "1" : "0", flagsChanged & bit); x += valWidth; p.drawText(x, y, (flags & bit) ? flagOn[flag] : flagOff[flag]); y += h; } } QSize FlagsViewer::sizeHint() const { return QSize(frameL + 4 + fontMetrics().width("ZW0 (PE) ") + 4 + frameR, frameT + 8 * fontMetrics().height() + frameB); } void FlagsViewer::drawValue(QPainter& p, int x, int y, const QString& str, bool changed) { if (changed) { p.setPen(Qt::red); } p.drawText(x, y, str); if (changed) { p.setPen(palette().color(QPalette::Text)); } } void FlagsViewer::setFlags(quint8 newFlags) { flagsChanged = flags ^ newFlags; flags = newFlags; update(); } openmsx-debugger-0.0.0.svn20141006.orig/src/GotoDialog.cpp0000644000175000017500000000251012414415132022216 0ustar shevekshevek#include "GotoDialog.h" #include "DebugSession.h" #include "Convert.h" #include GotoDialog::GotoDialog(const MemoryLayout& ml, DebugSession *session, QWidget* parent) : QDialog(parent), memLayout(ml), currentSymbol(0) { setupUi(this); debugSession = session; if( session ) { // create address completer QCompleter *completer = new QCompleter(session->symbolTable().labelList(true, &ml), this); completer->setCaseSensitivity(Qt::CaseInsensitive); edtAddress->setCompleter(completer); connect(completer, SIGNAL(activated(const QString&)), this, SLOT(addressChanged(const QString&))); } connect(edtAddress, SIGNAL(textEdited(const QString&)), this, SLOT(addressChanged(const QString&))); } int GotoDialog::address() { if(currentSymbol) return currentSymbol->value(); else return stringToValue(edtAddress->text()); } void GotoDialog::addressChanged(const QString& text) { int addr = stringToValue(text); if (addr == -1 && debugSession) { // try finding a label currentSymbol = debugSession->symbolTable().getAddressSymbol(text); if (!currentSymbol) currentSymbol = debugSession->symbolTable().getAddressSymbol(text, Qt::CaseInsensitive); if (currentSymbol) addr = currentSymbol->value(); } QPalette pal; pal.setColor(QPalette::Text, addr==-1 ? Qt::red : Qt::black); edtAddress->setPalette(pal); } openmsx-debugger-0.0.0.svn20141006.orig/src/VDPRegViewer.cpp0000644000175000017500000010016112414415132022440 0ustar shevekshevek#include "VDPRegViewer.h" #include "VDPDataStore.h" #include "InteractiveButton.h" #include "CommClient.h" static const int VDP_TMS99X8 = 1; static const int VDP_V9938 = 0; static const int VDP_V9958 = 4; // class buttonHighlightDispatcher buttonHighlightDispatcher::buttonHighlightDispatcher() : counter(0) { } void buttonHighlightDispatcher::receiveState(bool state) { if (state) { if (counter == 0) { emit dispatchState(true); } ++counter; } else { --counter; if (counter == 0) { emit dispatchState(false); } } } // class VDPRegViewer VDPRegViewer::VDPRegViewer(QWidget *parent) : QDialog(parent) { setupUi(this); regs = new unsigned char[64 + 16 + 2]; vdpid = 99; // make sure that we parse the first time the status registers are read vdpid = VDP_V9958; //quick hack for now //now hook up some signals and slots connectHighLights(); //get initiale data refresh(); decodeStatusVDPRegs(); // part of the quick hack :-) } VDPRegViewer::~VDPRegViewer() { delete[] regs; } void VDPRegViewer::setRegisterVisible(int r, bool visible) { QString name1 = QString("label_R%1").arg(r); QLabel* l1 = findChild(name1); l1->setVisible(visible); QString name2 = QString("label_val_%1").arg(r); QLabel* l2 = findChild(name2); l2->setVisible(visible); for (int b = 7; b >= 0; --b) { QString name3 = QString("pushButton_%1_%2").arg(r).arg(b); InteractiveButton *i = findChild(name3); i->setVisible(visible); } // now hide/show the explications of the give register switch (r) { case 8: label_dec_tp->setVisible(visible); label_dec_spd->setVisible(visible); break; case 9: label_dec_nt->setVisible(visible); label_dec_nt2->setVisible(visible); label_dec_il->setVisible(visible); label_dec_eo->setVisible(visible); label_dec_ln->setVisible(visible); label_dec_ln2->setVisible(visible); break; case 12: label_t2->setVisible(visible); label_bc->setVisible(visible); label_dec_t2->setVisible(visible); label_dec_bc->setVisible(visible); break; case 13: label_on->setVisible(visible); label_off->setVisible(visible); label_dec_on->setVisible(visible); label_dec_off->setVisible(visible); break; } } void VDPRegViewer::decodeStatusVDPRegs() { //const unsigned char* statusregs = regs + 64; //int id = statusregs[1] & 62; // + (machine_has_TMS99x8 ? 1 : 0) // test MSX1 id = 1; //if (vdpid != id) { // vdpid = id; if (vdpid == VDP_TMS99X8) { // TMS9918 = MSX1 VDP groupBox_V9958->setVisible(false); groupBox_TableBase->setVisible(true); groupBox_Color->setVisible(true); groupBox_Display->setVisible(false); groupBox_Access->setVisible(false); groupBox_dec_V9958->setVisible(false); groupBox_dec_TableBase->setVisible(true); groupBox_dec_Color->setVisible(true); groupBox_dec_Display->setVisible(false); groupBox_dec_Access->setVisible(false); label_dec_416K->setVisible(true); label_dec_ie1->setVisible(false); label_dec_ie2->setVisible(false); label_dec_dg->setVisible(false); setRegisterVisible( 8, false); setRegisterVisible( 9, false); setRegisterVisible(10, false); setRegisterVisible(11, false); setRegisterVisible(12, false); setRegisterVisible(13, false); setRegisterVisible(20, false); setRegisterVisible(21, false); setRegisterVisible(22, false); pushButton_0_2->setText("0"); pushButton_0_2->setToolTip(""); pushButton_0_3->setText("0"); pushButton_0_3->setToolTip(""); pushButton_0_4->setText("0"); pushButton_0_4->setToolTip(""); pushButton_0_5->setText("0"); pushButton_0_5->setToolTip(""); pushButton_0_6->setText("0"); pushButton_0_6->setToolTip(""); pushButton_1_7->setText("4/16"); pushButton_1_7->setToolTip( "4/16K selection\n" "0 selects 4027 RAM operation\n" "1 selects 4108/4116 RAM operation"); // mask all A16 bits of regs < 7 pushButton_2_6->setText("0"); pushButton_4_5->setText("0"); pushButton_6_5->setText("0"); // mask all A15 pushButton_2_5->setText("0"); pushButton_4_4->setText("0"); pushButton_6_4->setText("0"); // mask all A14 bits of regs < 7 pushButton_2_4->setText("0"); pushButton_4_3->setText("0"); pushButton_6_3->setText("0"); disconnect(modeBitsDispat, 0, pushButton_0_2, 0); disconnect(modeBitsDispat, 0, pushButton_0_3, 0); disconnect(pushButton_0_2, 0, 0, 0); disconnect(pushButton_0_3, 0, 0, 0); disconnect(pushButton_0_4, 0, 0, 0); disconnect(pushButton_0_5, 0, 0, 0); disconnect(pushButton_0_6, 0, 0, 0); monoGroup(pushButton_1_7, label_dec_416K); } else { // V9938 = MSX2 VDP // or // V9958 = MSX2+ VDP groupBox_TableBase->setVisible(true); groupBox_Color->setVisible(true); groupBox_Display->setVisible(true); groupBox_Access->setVisible(true); groupBox_dec_TableBase->setVisible(true); groupBox_dec_Color->setVisible(true); groupBox_dec_Display->setVisible(true); groupBox_dec_Access->setVisible(true); label_dec_416K->setVisible(false); label_dec_ie1->setVisible(true); label_dec_dg->setVisible(true); setRegisterVisible( 8, true); setRegisterVisible( 9, true); setRegisterVisible(10, true); setRegisterVisible(11, true); setRegisterVisible(12, true); setRegisterVisible(13, true); setRegisterVisible(20, true); setRegisterVisible(21, true); setRegisterVisible(22, true); pushButton_0_2->setText("M4"); pushButton_0_3->setText("M5"); pushButton_0_4->setText("IE1"); pushButton_0_6->setText("DG"); pushButton_1_7->setText("0"); pushButton_0_2->setToolTip("Used to change the display mode."); pushButton_0_3->setToolTip("Used to change the display mode."); pushButton_0_4->setToolTip("Enables interrupt from Horizontal scanning line by Interrupt Enable 1."); pushButton_0_6->setToolTip("Sets the color bus to input mode, and inputs data into the VRAM."); pushButton_1_7->setToolTip(""); // all A16 bits of regs < 7 pushButton_4_5->setText("A16"); pushButton_6_5->setText("A16"); // all A15 pushButton_4_4->setText("A15"); pushButton_6_4->setText("A15"); // all A14 pushButton_4_3->setText("A14"); pushButton_6_3->setText("A14"); ////pushButton_0_5->setText("IE2"); ////disconnect(pushButton_0_7, 0, 0, 0); ////disconnect(label_dec_416K, 0, 0, 0); ////reGroup(pushButton_0_2, modeBitsDispat); ////reGroup(pushButton_0_3, modeBitsDispat); ////monoGroup(pushButton_0_4, label_dec_ie1); ////monoGroup(pushButton_0_5, label_dec_ie2); ////monoGroup(pushButton_0_6, label_dec_dg); //break; // V9958 = MSX2+ VDP ////groupBox_TableBase->setVisible(true); ////groupBox_Color->setVisible(true); ////groupBox_Display->setVisible(true); ////groupBox_Access->setVisible(true); ////groupBox_dec_TableBase->setVisible(true); ////groupBox_dec_Color->setVisible(true); ////groupBox_dec_Display->setVisible(true); ////groupBox_dec_Access->setVisible(true); ////label_dec_416K->setVisible(false); ////label_dec_ie1->setVisible(true); ////label_dec_dg->setVisible(true); ////setRegisterVisible( 8, true); ////setRegisterVisible( 9, true); ////setRegisterVisible(10, true); ////setRegisterVisible(11, true); ////setRegisterVisible(12, true); ////setRegisterVisible(13, true); ////setRegisterVisible(20, true); ////setRegisterVisible(21, true); ////setRegisterVisible(22, true); ////pushButton_0_2->setText("M4"); ////pushButton_0_3->setText("M5"); ////pushButton_0_4->setText("IE1"); ////pushButton_0_6->setText("DG"); ////pushButton_1_7->setText("0"); ////pushButton_0_2->setToolTip("Used to change the display mode."); ////pushButton_0_3->setToolTip("Used to change the display mode."); ////pushButton_0_4->setToolTip("Enables interrupt from Horizontal scanning line by Interrupt Enable 1."); ////pushButton_0_6->setToolTip("Sets the color bus to input mode, and inputs data into the VRAM."); ////pushButton_1_7->setToolTip(""); pushButton_1_7->setToolTip(""); disconnect(pushButton_0_7, 0, 0, 0); disconnect(label_dec_416K, 0, 0, 0); reGroup(pushButton_0_2, modeBitsDispat); reGroup(pushButton_0_3, modeBitsDispat); monoGroup(pushButton_0_4, label_dec_ie1); monoGroup(pushButton_0_5, label_dec_ie2); monoGroup(pushButton_0_6, label_dec_dg); if (vdpid == VDP_V9938){ groupBox_V9958->setVisible(false); groupBox_dec_V9958->setVisible(false); label_dec_ie2->setVisible(true); pushButton_0_5->setText("IE2"); pushButton_0_5->setToolTip("Enables interrupt from Lightpen by Interrupt Enable 2."); pushButton_8_6->setText("LP"); pushButton_8_6->setToolTip(""); pushButton_8_7->setText("MS"); pushButton_8_7->setToolTip(""); } else { groupBox_V9958->setVisible(true); groupBox_dec_V9958->setVisible(true); label_dec_ie2->setVisible(false); pushButton_0_5->setText("0"); pushButton_0_5->setToolTip(""); pushButton_8_7->setText("0"); pushButton_8_7->setToolTip(""); pushButton_8_6->setText("0"); pushButton_8_6->setToolTip(""); /* Since mouse/lightpen are disabled this will affect * status reg1 bit 7 (LPS) and * status reg1 bit 6 (FL) */ } //break; } //} } static QString dec2(int val) { return QString("%1").arg(val, 2, 10, QChar('0')); } static QString dec3(int val) { return QString("%1").arg(val, 3, 10, QChar('0')); } static QString hex2(int val) { return QString("%1").arg(val, 2, 16, QChar('0')).toUpper(); } static QString hex5(int val) { return QString("%1").arg(val, 5, 16, QChar('0')).toUpper(); } void VDPRegViewer::decodeVDPRegs() { // first update all hex values label_val_0->setText(hex2(regs[0])); label_val_1->setText(hex2(regs[1])); label_val_2->setText(hex2(regs[2])); label_val_3->setText(hex2(regs[3])); label_val_4->setText(hex2(regs[4])); label_val_5->setText(hex2(regs[5])); label_val_6->setText(hex2(regs[6])); label_val_7->setText(hex2(regs[7])); // Only on V9938 and V9958 this makes sence if (vdpid != VDP_TMS99X8) { label_val_8 ->setText(hex2(regs[ 8])); label_val_9 ->setText(hex2(regs[ 9])); label_val_10->setText(hex2(regs[10])); label_val_11->setText(hex2(regs[11])); label_val_12->setText(hex2(regs[12])); label_val_13->setText(hex2(regs[13])); label_val_14->setText(hex2(regs[14])); label_val_15->setText(hex2(regs[15])); label_val_16->setText(hex2(regs[16])); label_val_17->setText(hex2(regs[17])); label_val_18->setText(hex2(regs[18])); label_val_19->setText(hex2(regs[19])); label_val_20->setText(hex2(regs[20])); label_val_21->setText(hex2(regs[21])); label_val_22->setText(hex2(regs[22])); label_val_23->setText(hex2(regs[23])); } // Only on V9958 this makes sence if (vdpid == VDP_V9958) { label_val_25->setText(hex2(regs[25])); label_val_26->setText(hex2(regs[26])); label_val_27->setText(hex2(regs[27])); } // determine screenmode int m = ((regs[0] & 0x0E) << 1) | ((regs[1] & 0x18) >> 3); const char* const screen[32] = { "SCREEN 1", "SCREEN 3", "SCREEN 0", "let's find out 3", "SCREEN 2", "let's find out 5", "let's find out 6", "let's find out 7", "SCREEN 4", "let's find out 9", "SCREEN 0 width 80", "let's find out 11", "SCREEN 5", "let's find out 13", "let's find out 14", "let's find out 15", "SCREEN 6", "let's find out 17", "let's find out 18", "let's find out 19", "SCREEN 7", "let's find out 21", "let's find out 22", "let's find out 23", "let's find out 24", "let's find out 25", "let's find out 26", "let's find out 27", "SCREEN 8", "let's find out 29", "let's find out 30", "let's find out 31" }; int basicscreen; switch (m){ case 2: basicscreen=0;break; case 0: basicscreen=1;break; case 4: basicscreen=2;break; case 1: basicscreen=3;break; case 8: basicscreen=4;break; case 12: basicscreen=5;break; case 16: basicscreen=6;break; case 20: basicscreen=7;break; case 28: basicscreen=8;break; case 10: basicscreen=9;break; //screen 0 width 80 default: basicscreen=10; //not a valid basic screen mode }; // 2 vdps, 11 basic screenmodes, 12 registers static const int mustbeone[][11][12] = { { // TMS99x8 MSX1 VDP chip {0, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0,0,0,0}, // screen 0; {0, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0,0,0,0}, // screen 1; {0, 0, 0x00, 0x7f, 0x03, 0x00, 0x00, 0x00, 0,0,0,0}, // screen 2; {0, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0,0,0,0}, // screen 3; {0, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0,0,0,0}, // screen 4; {0, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0,0,0,0}, // screen 5; {0, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0,0,0,0}, // screen 6; {0, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0,0,0,0}, // screen 7; {0, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0,0,0,0}, // screen 8; {0, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0,0,0,0}, // screen 0 width 80; {0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0} // undefined basic screen; }, { // V9938 and V9958 MSX2/2+ VDP chip // Note that there is a hardcoded check for reg5 bit 2 (A9) in spritemode 2 // which deliberatly isn't set here in the table! {0, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0,0,0,0}, // screen 0; {0, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0,0,0,0}, // screen 1; {0, 0, 0x00, 0x7f, 0x03, 0x00, 0x00, 0x00, 0,0,0,0}, // screen 2; {0, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0,0,0,0}, // screen 3; {0, 0, 0x00, 0x7f, 0x03, 0x03, 0x00, 0x00, 0,0,0,0}, // screen 4; {0, 0, 0x1f, 0x00, 0x00, 0x03, 0x00, 0x00, 0,0,0,0}, // screen 5; {0, 0, 0x1f, 0x00, 0x00, 0x03, 0x00, 0x00, 0,0,0,0}, // screen 6; {0, 0, 0x1f, 0x00, 0x00, 0x03, 0x00, 0x00, 0,0,0,0}, // screen 7; {0, 0, 0x1f, 0x00, 0x00, 0x03, 0x00, 0x00, 0,0,0,0}, // screen 8; {0, 0, 0x03, 0x07, 0x00, 0x00, 0x00, 0x00, 0,0,0,0}, // screen 0 width 80; {0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0} // undefined basic screen; } }; static const int bitsused[][11][12] = { {// MSX1 = static const int VDP_TMS99X8 = 1 {0,1, 0x0f, 0xff, 0x07, 0x7f, 0x07, 7,8,9, 0x00, 0x00}, // screen 0; {0,1, 0x0f, 0xff, 0x07, 0x7f, 0x07, 7,8,9, 0x00, 0x00}, // screen 1; {0,1, 0x0f, 0xff, 0x07, 0x7f, 0x07, 7,8,9, 0x00, 0x00}, // screen 2; {0,1, 0x0f, 0xff, 0x07, 0x7f, 0x07, 7,8,9, 0x00, 0x00}, // screen 3; {0,1, 0x00, 0x00, 0x00, 0x00, 0x00, 7,8,9, 0x00, 0x00}, // screen 4; {0,1, 0x00, 0x00, 0x00, 0x00, 0x00, 7,8,9, 0x00, 0x00}, // screen 5; {0,1, 0x00, 0x00, 0x00, 0x00, 0x00, 7,8,9, 0x00, 0x00}, // screen 6; {0,1, 0x00, 0x00, 0x00, 0x00, 0x00, 7,8,9, 0x00, 0x00}, // screen 7; {0,1, 0x00, 0x00, 0x00, 0x00, 0x00, 7,8,9, 0x00, 0x00}, // screen 8; {0,1, 0x00, 0x00, 0x00, 0x00, 0x00, 7,8,9, 0x00, 0x00}, // screen 0 width 80; {255,255,255,255,255,255,255,255,255,255,255,255} // undefined basic screen; }, { // MSX2 = static const int VDP_V9938 = 0; {0,1, 0x7f, 0xff, 0x3f, 0xff, 0x3f, 7,8,9, 0x07, 0x03}, // screen 0; {0,1, 0x7f, 0xff, 0x3f, 0xff, 0x3f, 7,8,9, 0x07, 0x03}, // screen 1; {0,1, 0x7f, 0xff, 0x3f, 0xff, 0x3f, 7,8,9, 0x07, 0x03}, // screen 2; {0,1, 0x7f, 0xff, 0x3f, 0xff, 0x3f, 7,8,9, 0x07, 0x03}, // screen 3; {0,1, 0x7f, 0xff, 0x3f, 0xfc, 0x3f, 7,8,9, 0x07, 0x03}, // screen 4; {0,1, 0x7f, 0xff, 0x3f, 0xfc, 0x3f, 7,8,9, 0x07, 0x03}, // screen 5; {0,1, 0x7f, 0xff, 0x3f, 0xfc, 0x3f, 7,8,9, 0x07, 0x03}, // screen 6; {0,1, 0x7f, 0xff, 0x3f, 0xfc, 0x3f, 7,8,9, 0x07, 0x03}, // screen 7; {0,1, 0x7f, 0xff, 0x3f, 0xfc, 0x3f, 7,8,9, 0x07, 0x03}, // screen 8; {0,1, 0x7f, 0xff, 0x3f, 0xff, 0x3f, 7,8,9, 0x07, 0x03}, // screen 0 width 80; {255,255,255,255,255,255,255,255,255,255,255,255} // undefined basic screen; } }; // update all the individual bits int upper_r = (vdpid == VDP_TMS99X8) ? 7 : (vdpid == VDP_V9938) ? 23 : 27; for (int r = 0; r <= upper_r; ++r) { if (r == 24) continue; for (int b = 7; b >= 0; --b) { QString name = QString("pushButton_%1_%2").arg(r).arg(b); InteractiveButton* i = findChild(name); i->setChecked((regs[r] & (1 << b)) ? true : false); if (r<12){ i->mustBeSet((mustbeone[ (vdpid == VDP_TMS99X8)?0:1 ][basicscreen][r] & (1 << b)) ? true : false); // if A8 of R5 is a 'mustbeone' then we indicate this for A9 also // This bit is cleared in the table since it isn't used in the Sprite // Attribute Table address calculation otherwise, but will only impact the // Sprite Color Table if (r==5 && b==2 && vdpid!=VDP_TMS99X8 && mustbeone[1][basicscreen][5] ){ i->mustBeSet(true); } } } } // Start the interpretation label_dec_ie2->setText((regs[0] & 32) ? "Interrupt from lightpen enabled" : "Interrupt from lightpen disabled"); label_dec_ie1->setText((regs[0] & 16) ? "Reg 19 scanline interrupt enabled" : "Reg 19 scanline interrupt disabled"); if (vdpid != VDP_TMS99X8) { if (m == 20 || m == 28) { pushButton_2_6->setText("0"); pushButton_2_5->setText("A16"); pushButton_2_4->setText("A15"); pushButton_2_3->setText("A14"); pushButton_2_2->setText("A13"); pushButton_2_1->setText("A12"); pushButton_2_0->setText("A11"); } else { pushButton_2_6->setText("A16"); pushButton_2_5->setText("A15"); pushButton_2_4->setText("A14"); pushButton_2_3->setText("A13"); pushButton_2_2->setText("A12"); pushButton_2_1->setText("A11"); pushButton_2_0->setText("A10"); } } if (m == 28 && vdpid == VDP_V9958) { bool yjk = (regs[25] & 8); bool yae = (regs[25] & 16); int scr = yjk ? (yae ? 10 : 12) : 8; label_dec_m->setText(QString("M=%1%2%3 : SCREEN %4") .arg(m) .arg(yjk ? "+YJK" : "") .arg(yae ? "+YAE" : "") .arg(scr)); } else { label_dec_m->setText(QString("M=%1 : %2") .arg(m) .arg(screen[m])); } label_dec_bl->setText((regs[1] & 64) ? "Display enabled" : "Display disabled"); label_dec_ie0->setText((regs[1] & 32) ? "V-Blank interrupt enabled" : "V-Blank interrupt disabled"); label_dec_si->setText((regs[1] & 2) ? "16x16 sprites" : "8x8 sprites"); label_dec_mag->setText((regs[1] & 1) ? "magnified sprites" : "regular sized"); // Now calculate the addresses of all tables // TODO : clean up code and get rid of all the mustbeset bits for regs>5 since there are never must bits. // some variables used for readability of the code below int row = vdpid==VDP_TMS99X8?0:1; QString regtexttext; int must,must2; // the pattern name table address must=mustbeone[row][basicscreen][2] ; long nameTable = ((255^must) & bitsused[row][basicscreen][2] & regs[2]) << 10; if ((m == 20 || m == 28) && vdpid != VDP_TMS99X8) nameTable = ((nameTable & 0xffff) << 1) | ((nameTable & 0x10000) >> 16); regtexttext = hex5(nameTable); if ((must & regs[2]) != must ) { label_dec_r2->setText("" + regtexttext +""); label_dec_r2->setToolTip("Some of the obligatory 1 bits are reset!"); } else { label_dec_r2->setText(regtexttext); label_dec_r2->setToolTip(NULL); } // the color table address must=mustbeone[row][basicscreen][3] ; must2=mustbeone[row][basicscreen][10] ; regtexttext=hex5( ( ((255^must) & bitsused[row][basicscreen][ 3] & regs[ 3]) << 6 ) | ( ((255^must2) & bitsused[row][basicscreen][10] & regs[10]) << 14 ) ); if (((must & regs[3]) != must ) || ((must2 & regs[10]) != must2 ) ){ label_dec_r3->setText("" + regtexttext +""); label_dec_r3->setToolTip("Some of the obligatory 1 bits are reset!"); } else { label_dec_r3->setText(regtexttext); label_dec_r3->setToolTip(NULL); } // the pattern generator address must=mustbeone[row][basicscreen][4] ; regtexttext=hex5( ( ( 255^must) & bitsused[row][basicscreen][4] & regs[4]) << 11 ); if ((must & regs[4]) != must ){ label_dec_r4->setText("" + regtexttext +""); label_dec_r4->setToolTip("Some of the obligatory 1 bits are reset!"); } else { label_dec_r4->setText(regtexttext); label_dec_r4->setToolTip(NULL); } // the sprite attribute tabel address must=mustbeone[row][basicscreen][5] ; must2=mustbeone[row][basicscreen][11] ; regtexttext=hex5( ( (((255^must) & bitsused[row][basicscreen][ 5] & regs[ 5]) << 7) | (((255^must2) & bitsused[row][basicscreen][11] & regs[11]) << 15)) ); if (((must & regs[5]) != must ) || ((must2 & regs[11]) != must2 ) ){ label_dec_r5->setText("" + regtexttext +""); label_dec_r5->setToolTip("Some of the obligatory 1 bits are reset!"); } else { label_dec_r5->setText(regtexttext); label_dec_r5->setToolTip(NULL); }; // special case for sprite mode 2 if (must && !( 4 & regs[ 5])) { // only in mode2 there are some 'must'-bits :-) label_dec_r5->setText("" + regtexttext +""); label_dec_r5->setToolTip("Bit A9 should be set, to obtain the Sprite Color Table address this bit is masked
With the current bit reset the Color Tabel will use the same address as the Sprite Atribute Tabel!"); }; // the sprite pattern generator address label_dec_r6->setText(hex5( ((255^mustbeone[row][basicscreen][6]) & bitsused[row][basicscreen][6] & regs[6]) << 11)); // end of address calculations label_dec_tc->setText(dec2((regs[7] >> 4) & 15)); label_dec_bd->setText(dec2((regs[7] >> 0) & 15)); if (vdpid != VDP_TMS99X8) { label_dec_tp->setText((regs[8] & 32) ? "Color 0 uses the color registers" : "Color 0 is transparent (=shows border)"); label_dec_spd->setText((regs[8] & 2) ? "Sprites disabled" : "Sprites enabled"); label_dec_ln->setText((regs[9] & 128) ? "212" : "192"); label_dec_il->setText((regs[9] & 8) ? "interlaced" : "non-interlaced"); label_dec_eo->setText((regs[9] & 4) ? "alternate pages" : "same page"); label_dec_nt->setText((regs[9] & 2) ? "PAL" : "NTSC"); label_dec_t2 ->setText(dec2((regs[12] >> 4) & 15)); label_dec_bc ->setText(dec2((regs[12] >> 0) & 15)); label_dec_on ->setText(dec2((regs[13] >> 4) & 15)); label_dec_off->setText(dec2((regs[13] >> 0) & 15)); int x = ((regs[18] >> 0) & 15); int y = ((regs[18] >> 4) & 15); x = x > 7 ? 16 - x : -x; y = y > 7 ? 16 - y : -y; label_dec_r18->setText(QString("(%1,%2)").arg(x).arg(y)); label_dec_r19->setText(dec3(regs[19])); label_dec_r23->setText(dec3(regs[23])); label_dec_r14->setText(hex5(((regs[14] & 7) << 14) | ((regs[81] & 63) << 8) | regs[80])); label_dec_r15->setText(dec2(regs[15] & 15)); label_dec_r16->setText(dec2(regs[16] & 15)); label_dec_r17->setText(dec3(regs[17] & 63).append((regs[17] & 128) ? ", auto incr" : "")); } //V9958 registers if (vdpid == VDP_V9958) { label_dec_r26->setText(QString("horizontal scroll %1") .arg((regs[26] & 63) * 8 - (7 & regs[27]))); label_dec_sp2->setText((regs[25] & 1) ? "Scroll uses 2 pages" : "Scroll same page"); label_dec_msk->setText((regs[25] & 2) ? "Hide 8 leftmost pixels" : "No masking"); label_dec_wte->setText((regs[25] & 4) ? "Disabled CPU Waitstate" : "Enable CPU Waitstate"); if (regs[25] & 8) { label_dec_yjk->setText("YJK System"); label_dec_yae->setText((regs[25] & 16) ? "Attribute enabled (Y=4bits)" : "regular YJK (Y=5bits)"); } else { label_dec_yjk->setText("Normal RGB"); label_dec_yae->setText("Ignored (YJK disabled)"); } label_dec_vds->setText((regs[25] & 32) ? "Pin8 is /VDS" : "Pin8 is CPUCLK"); label_dec_cmd->setText((regs[25] & 64) ? "CMD engine in char modes" : "V9938 VDP CMD engine"); } } void VDPRegViewer::doConnect(InteractiveButton* but, buttonHighlightDispatcher* dis) { connect(but, SIGNAL(mouseOver(bool)), dis, SLOT(receiveState(bool))); connect(dis, SIGNAL(dispatchState(bool)), but, SLOT(highlight(bool))); } void VDPRegViewer::monoGroup(InteractiveButton* but, InteractiveLabel* lab) { connect(lab, SIGNAL(mouseOver(bool)), but, SLOT(highlight(bool))); connect(but, SIGNAL(mouseOver(bool)), lab, SLOT(highlight(bool))); connect(lab, SIGNAL(mouseOver(bool)), lab, SLOT(highlight(bool))); connect(but, SIGNAL(mouseOver(bool)), but, SLOT(highlight(bool))); } void VDPRegViewer::reGroup(InteractiveButton* item, buttonHighlightDispatcher* dispat) { //button must rehighlight itself connect(item, SIGNAL(mouseOver(bool)), item, SLOT(highlight(bool))); // and then talk to dispatcher doConnect(item, dispat); } buttonHighlightDispatcher* VDPRegViewer::makeGroup( QList list, InteractiveLabel* explained) { // First "steal" the Tooltip of the explained widget. InteractiveButton* item; //foreach(item, list) { // item->setToolTip(explained->toolTip()); //} // Create a dispatcher and connect all to them buttonHighlightDispatcher* dispat = new buttonHighlightDispatcher(); connect(explained, SIGNAL(mouseOver(bool)), dispat, SLOT(receiveState(bool))); connect(dispat, SIGNAL(dispatchState(bool)), explained, SLOT(highlight(bool))); foreach(item, list){ doConnect(item, dispat); } return dispat; } void VDPRegViewer::connectHighLights() { // Before connecting the highlights we connect the special // 'Toggled Bit' event // Warning: This function is not available with MSVC 6!! Not that it // matters to me on my Linux environment :-) QList list = findChildren(); InteractiveButton* item; foreach(item, list) { connect(item, SIGNAL(newBitValue(int,int,bool)), this, SLOT(registerBitChanged(int,int,bool))); } // register 0 (+M1,M2) monoGroup(pushButton_0_5, label_dec_ie2); monoGroup(pushButton_0_4, label_dec_ie1); list.clear(); list << pushButton_0_3 << pushButton_0_2 << pushButton_0_1; list << pushButton_1_4 << pushButton_1_3; modeBitsDispat = makeGroup(list, label_dec_m); // register 1 monoGroup(pushButton_1_6, label_dec_bl); monoGroup(pushButton_1_5, label_dec_ie0); monoGroup(pushButton_1_1, label_dec_si); monoGroup(pushButton_1_0, label_dec_mag); // register 8 //monoGroup(pushButton_8_7, label_dec_ms); //monoGroup(pushButton_8_6, label_dec_lp); monoGroup(pushButton_8_5, label_dec_tp); //monoGroup(pushButton_8_4, label_dec_cb); //monoGroup(pushButton_8_3, label_dec_vr); monoGroup(pushButton_8_1, label_dec_spd); //monoGroup(pushButton_8_0, label_dec_bw); // register 9 monoGroup(pushButton_9_7, label_dec_ln); list.clear(); list << pushButton_9_5 << pushButton_9_4; makeGroup(list, label_dec_m); //TODO fix label monoGroup(pushButton_9_3, label_dec_il); monoGroup(pushButton_9_2, label_dec_eo); monoGroup(pushButton_9_1, label_dec_nt); //monoGroup(pushButton_9_0, label_dec_dc); // register 2 list.clear(); list << pushButton_2_7 << pushButton_2_6 << pushButton_2_5; list << pushButton_2_4 << pushButton_2_3 << pushButton_2_2; list << pushButton_2_1 << pushButton_2_0; makeGroup(list, label_dec_r2); // register 3 + 10 list.clear(); list << pushButton_3_7 << pushButton_3_6 << pushButton_3_5; list << pushButton_3_4 << pushButton_3_3 << pushButton_3_2; list << pushButton_3_1 << pushButton_3_0; list << pushButton_10_7 << pushButton_10_6 << pushButton_10_5; list << pushButton_10_4 << pushButton_10_3 << pushButton_10_2; list << pushButton_10_1 << pushButton_10_0; makeGroup(list, label_dec_r3); // register 4 list.clear(); list << pushButton_4_7 << pushButton_4_6 << pushButton_4_5; list << pushButton_4_4 << pushButton_4_3 << pushButton_4_2; list << pushButton_4_1 << pushButton_4_0; makeGroup(list, label_dec_r4); // register 5 + 11 list.clear(); list << pushButton_5_7 << pushButton_5_6 << pushButton_5_5; list << pushButton_5_4 << pushButton_5_3 << pushButton_5_2; list << pushButton_5_1 << pushButton_5_0; list << pushButton_11_7 << pushButton_11_6 << pushButton_11_5; list << pushButton_11_4 << pushButton_11_3 << pushButton_11_2; list << pushButton_11_1 << pushButton_11_0; makeGroup(list, label_dec_r5); // register 6 list.clear(); list << pushButton_6_7 << pushButton_6_6 << pushButton_6_5; list << pushButton_6_4 << pushButton_6_3 << pushButton_6_2; list << pushButton_6_1 << pushButton_6_0; makeGroup(list, label_dec_r6); // register 7 list.clear(); list << pushButton_7_7 << pushButton_7_6; list << pushButton_7_5 << pushButton_7_4; makeGroup(list, label_dec_tc); list.clear(); list << pushButton_7_3 << pushButton_7_2; list << pushButton_7_1 << pushButton_7_0; makeGroup(list, label_dec_bd); // register 12 list.clear(); list << pushButton_12_7 << pushButton_12_6; list << pushButton_12_5 << pushButton_12_4; makeGroup(list, label_dec_t2); list.clear(); list << pushButton_12_3 << pushButton_12_2; list << pushButton_12_1 << pushButton_12_0; makeGroup(list, label_dec_bc); // register 13 list.clear(); list << pushButton_13_7 << pushButton_13_6; list << pushButton_13_5 << pushButton_13_4; makeGroup(list, label_dec_on); list.clear(); list << pushButton_13_3 << pushButton_13_2; list << pushButton_13_1 << pushButton_13_0; makeGroup(list, label_dec_off); // register 14 list.clear(); list << pushButton_14_7 << pushButton_14_6 << pushButton_14_5; list << pushButton_14_4 << pushButton_14_3 << pushButton_14_2; list << pushButton_14_1 << pushButton_14_0; makeGroup(list, label_dec_r14); // register 15 list.clear(); list << pushButton_15_7 << pushButton_15_6 << pushButton_15_5; list << pushButton_15_4 << pushButton_15_3 << pushButton_15_2; list << pushButton_15_1 << pushButton_15_0; makeGroup(list, label_dec_r15); // register 16 list.clear(); list << pushButton_16_7 << pushButton_16_6 << pushButton_16_5; list << pushButton_16_4 << pushButton_16_3 << pushButton_16_2; list << pushButton_16_1 << pushButton_16_0; makeGroup(list, label_dec_r16); // register 17 list.clear(); list << pushButton_17_7 << pushButton_17_6 << pushButton_17_5; list << pushButton_17_4 << pushButton_17_3 << pushButton_17_2; list << pushButton_17_1 << pushButton_17_0; makeGroup(list, label_dec_r17); // register 18 list.clear(); list << pushButton_18_7 << pushButton_18_6 << pushButton_18_5; list << pushButton_18_4 << pushButton_18_3 << pushButton_18_2; list << pushButton_18_1 << pushButton_18_0; makeGroup(list, label_dec_r18); // register 19 list.clear(); list << pushButton_19_7 << pushButton_19_6 << pushButton_19_5; list << pushButton_19_4 << pushButton_19_3 << pushButton_19_2; list << pushButton_19_1 << pushButton_19_0; makeGroup(list, label_dec_r19); // register 23 list.clear(); list << pushButton_23_7 << pushButton_23_6 << pushButton_23_5; list << pushButton_23_4 << pushButton_23_3 << pushButton_23_2; list << pushButton_23_1 << pushButton_23_0; makeGroup(list, label_dec_r23); // register 25 monoGroup(pushButton_25_0, label_dec_sp2); monoGroup(pushButton_25_1, label_dec_msk); monoGroup(pushButton_25_2, label_dec_wte); monoGroup(pushButton_25_3, label_dec_yjk); monoGroup(pushButton_25_4, label_dec_yae); monoGroup(pushButton_25_5, label_dec_vds); monoGroup(pushButton_25_6, label_dec_cmd); // register 26 list.clear(); list << pushButton_26_7 << pushButton_26_6 << pushButton_26_5; list << pushButton_26_4 << pushButton_26_3 << pushButton_26_2; list << pushButton_26_1 << pushButton_26_0; list << pushButton_27_7 << pushButton_27_6 << pushButton_27_5; list << pushButton_27_4 << pushButton_27_3 << pushButton_27_2; list << pushButton_27_1 << pushButton_27_0; makeGroup(list, label_dec_r26); } void VDPRegViewer::refresh() { //new SimpleHexRequest("{VDP regs}",0,64,regs, *this); //new SimpleHexRequest("{VDP status regs}",0,16,regs, *this); // now combined in one request: new SimpleHexRequest( "debug_bin2hex " "[ debug read_block {VDP regs} 0 64 ]" "[ debug read_block {VDP status regs} 0 16 ]" "[ debug read_block {VRAM pointer} 0 2 ]", 64 + 16 + 2, regs, *this); } void VDPRegViewer::DataHexRequestReceived() { decodeStatusVDPRegs(); decodeVDPRegs(); } void VDPRegViewer::registerBitChanged(int reg, int bit, bool state) { // maybe this call is the result of our own SetChecked (VDPDataStorte // update event) if ((state ? 1 : 0) == (regs[reg] & (1 << bit))) { return; } // state does not correspond to the current register setting so we send // an update command if (state) { regs[reg] |= (1 << bit); } else { regs[reg] &= ~(1 << bit); } CommClient::instance().sendCommand( new SimpleCommand( QString("debug write {VDP regs} %1 %2").arg(reg).arg(regs[reg]))); // Update display without waiting for the VDPDataStore update decodeVDPRegs(); // and then we could request an update nevertheless since some other // objects might want to see this change through the VDPDataStore also // :-) // VDPDataStore::instance().refresh(); } void VDPRegViewer::on_VDPcomboBox_currentIndexChanged(int index) { switch (index) { case 0: vdpid = VDP_V9958; break; case 1: vdpid = VDP_V9938; break; case 2: vdpid = VDP_TMS99X8; break; } decodeStatusVDPRegs(); decodeVDPRegs(); } openmsx-debugger-0.0.0.svn20141006.orig/src/GotoDialog.ui0000644000175000017500000000623112414415132022055 0ustar shevekshevek GotoDialog 0 0 304 118 0 0 Go to address 6 9 6 0 0 0 Address or label: Qt::Vertical 20 5 6 0 Qt::Horizontal 131 31 OK Cancel okButton clicked() GotoDialog accept() 278 253 96 254 cancelButton clicked() GotoDialog reject() 369 253 179 282 openmsx-debugger-0.0.0.svn20141006.orig/src/VramBitMappedView.h0000644000175000017500000000262212414415132023165 0ustar shevekshevek#ifndef VRAMBITMAPPEDVIEW #define VRAMBITMAPPEDVIEW #include #include #include #include #include #include class VramBitMappedView : public QWidget { Q_OBJECT public: VramBitMappedView(QWidget* parent = 0); void setZoom(float zoom); void setScreenMode(int mode); void setLines(int nrLines); void setVramSource(const unsigned char* adr); void setVramAddress(int adr); void setPaletteSource(const unsigned char* adr); void setBorderColor(int value); void mousePressEvent(QMouseEvent* e); void mouseMoveEvent (QMouseEvent* e); public slots: void refresh(); signals: void imageChanged(); void imagePosition(int xcoormsx, int ycoormsx, int color, unsigned addr, int byte); void imageClicked (int xcoormsx, int ycoormsx, int color, unsigned addr, int byte); private: void paintEvent(QPaintEvent*); void decode(); void decodePallet(); void decodeSCR5(); void decodeSCR6(); void decodeSCR7(); void decodeSCR8(); void decodeSCR10(); void decodeSCR12(); void setPixel2x2(int x, int y, QRgb c); void setPixel1x2(int x, int y, QRgb c); QRgb getColor(int c); QRgb msxpallet[16]; QImage image; QPixmap piximage; const unsigned char* pallet; const unsigned char* vramBase; float zoomFactor; unsigned int vramAddress; int lines; int screenMode; int borderColor; }; #endif // VRAMBITMAPPEDVIEW openmsx-debugger-0.0.0.svn20141006.orig/src/BitMapViewer.cpp0000644000175000017500000001734412414415132022537 0ustar shevekshevek#include "BitMapViewer.h" #include "VramBitMappedView.h" #include "VDPDataStore.h" #include static const unsigned char defaultPalette[32] = { // RB G 0x00, 0, 0x00, 0, 0x11, 6, 0x33, 7, 0x17, 1, 0x27, 3, 0x51, 1, 0x27, 6, 0x71, 1, 0x73, 3, 0x61, 6, 0x64, 6, 0x11, 4, 0x65, 2, 0x55, 5, 0x77, 7, }; BitMapViewer::BitMapViewer(QWidget* parent) : QDialog(parent) , screenMod(0) // avoid UMR { setupUi(this); // hand code entering the actual display widget in the scrollarea With // the designer-qt4 there is an extra scrollAreaWidget between the // imageWidget and the QScrollArea so the scrollbars are not correctly // handled when the image is resized. (since the intermediate widget // stays the same size). I did not try to have this intermediate widget // resize and all, since it was superflous anyway. imageWidget = new VramBitMappedView(); QSizePolicy sizePolicy1(QSizePolicy::Fixed, QSizePolicy::Fixed); sizePolicy1.setHorizontalStretch(0); sizePolicy1.setVerticalStretch(0); sizePolicy1.setHeightForWidth(imageWidget->sizePolicy().hasHeightForWidth()); imageWidget->setSizePolicy(sizePolicy1); imageWidget->setMinimumSize(QSize(256, 212)); scrollArea->setWidget(imageWidget); useVDP = true; const unsigned char* vram = VDPDataStore::instance().getVramPointer(); const unsigned char* palette = VDPDataStore::instance().getPalettePointer(); imageWidget->setVramSource(vram); imageWidget->setVramAddress(0); imageWidget->setPaletteSource(palette); //now hook up some signals and slots connect(&VDPDataStore::instance(), SIGNAL(dataRefreshed()), this, SLOT(VDPDataStoreDataRefreshed())); connect(&VDPDataStore::instance(), SIGNAL(dataRefreshed()), imageWidget, SLOT(refresh())); connect(refreshButton, SIGNAL(clicked(bool)), &VDPDataStore::instance(), SLOT(refresh())); connect(imageWidget, SIGNAL(imagePosition(int,int,int,unsigned int,int)), this, SLOT(imagePositionUpdate(int,int,int,unsigned int,int))); connect(imageWidget, SIGNAL(imageClicked (int,int,int,unsigned int,int)), this, SLOT(imagePositionUpdate(int,int,int,unsigned int,int))); // and now go fetch the initial data VDPDataStore::instance().refresh(); } void BitMapViewer::decodeVDPregs() { const unsigned char* regs = VDPDataStore::instance().getRegsPointer(); // Get the number of lines int v1 = (regs[9] & 128) ? 212 : 192; printf("\nlines acording to the bits %i,: %i\n", (regs[9] & 128), v1); linesLabel->setText(QString("%1").arg(v1, 0, 10)); if (useVDP) linesVisible->setCurrentIndex((regs[9] & 128) ? 1 : 0); // Get the border color int v2 = regs[7] & 15; printf("\nborder acording to the regs %i,: %i\n", regs[7], v2); if (regs[8] & 32) v2 = 0; printf("\ncolor 0 is pallet regs %i,: %i\n", (regs[8] & 32), v2); borderLabel->setText(QString("%1").arg(v2, 0, 10)); if (useVDP) bgColor->setValue(v2); // Get current screenmode static const int bits_modetxt[128] = { 1, 3, 0, 255, 2, 255, 255, 255, 4, 255, 80, 255, 5, 255, 255, 255, 6, 255, 255, 255, 7, 255, 255, 255, 255, 255, 255, 255, 8, 255, 255, 255, 255, 255, 255, 255,255, 255, 255, 255, 255, 255, 255, 255,255, 255, 255, 255, 255, 255, 255, 255,255, 255, 255, 255, 255, 255, 255, 255, 12, 255, 255, 255, 255, 255, 255, 255,255, 255, 255, 255, 255, 255, 255, 255,255, 255, 255, 255, 255, 255, 255, 255,255, 255, 255, 255, 255, 255, 255, 255,255, 255, 255, 255, 255, 255, 255, 255,255, 255, 255, 255, 255, 255, 255, 255,255, 255, 255, 255, 255, 255, 255, 255,255, 255, 255, 255, 255, 255, 255, 255, 11, 255, 255, 255, }; static const int bits_mode[128] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, }; int v3 = ((regs[0] & 0x0E) << 1) | ((regs[1] & 0x18) >> 3) | ((regs[25] & 0x18) << 2); printf("screenMod according to the bits: %i\n", v3); modeLabel->setText(QString("%1").arg(bits_modetxt[v3], 0, 10)); if (useVDP) screenMode->setCurrentIndex(bits_mode[v3]); // Get the current visible page unsigned p = (regs[2] >> 5) & 3; unsigned q = 1 << 15; if (bits_modetxt[v3] > 6) { p &= 1; q <<= 1; } printf("visible page according to the bits: %i\n",p); addressLabel->setText(QString("0x%1").arg(p * q, 5, 16, QChar('0'))); if (useVDP) showPage->setCurrentIndex(p); } void BitMapViewer::refresh() { // All of the code is in the VDPDataStore; VDPDataStore::instance().refresh(); } void BitMapViewer::on_screenMode_currentIndexChanged(const QString& text) { screenMod = text.toInt(); printf("\nnew screenMod: %i\n", screenMod); //change then number of visibe pages when this changes imageWidget->setVramAddress(0); // make sure that we are decoding new mode from page 0, imagine viewing // page 3 of screen5 and then switching to screen 8 without changing the // starting vram address.... imageWidget->setScreenMode(screenMod); showPage->clear(); showPage->insertItem(0, "0"); showPage->insertItem(1, "1"); if (screenMod < 7) { showPage->insertItem(2, "2"); showPage->insertItem(3, "3"); } } void BitMapViewer::on_showPage_currentIndexChanged(int index) { //if this is the consequence of a .clear() in the // on_screenMode_currentIndexChanged we do nothing! if (index == -1) return; static const int m1[4] = { 0x00000, 0x08000, 0x10000, 0x18000 }; printf("\nvoid BitMapViewer::on_showPage_currentIndexChanged( int %i);\n", index); if (screenMod >= 7) index *= 2; int vramAddress = m1[index]; printf("vramAddress %i\n", vramAddress); imageWidget->setVramAddress(vramAddress); } void BitMapViewer::on_linesVisible_currentIndexChanged(int index) { static const int m[3] = { 192, 212, 256 }; int lines = m[index]; imageWidget->setLines(lines); } void BitMapViewer::on_bgColor_valueChanged(int value) { imageWidget->setBorderColor(value); } void BitMapViewer::on_useVDPRegisters_stateChanged(int state) { useVDP = state; screenMode->setEnabled(!state); linesVisible->setEnabled(!state); showPage->setEnabled(!state); bgColor->setEnabled(!state); decodeVDPregs(); imageWidget->refresh(); } void BitMapViewer::on_zoomLevel_valueChanged(double d) { imageWidget->setZoom(float(d)); } void BitMapViewer::on_saveImageButton_clicked(bool checked) { QMessageBox::information( this, "Not yet implemented", "Sorry, the save image dialog is not yet implemented"); } void BitMapViewer::on_editPaletteButton_clicked(bool checked) { useVDPPalette->setChecked(false); QMessageBox::information( this, "Not yet implemented", "Sorry, the palette editor is not yet implemented, " "only disabling 'Use VDP palette registers' for now"); } void BitMapViewer::on_useVDPPalette_stateChanged(int state) { if (state) { const unsigned char* palette = VDPDataStore::instance().getPalettePointer(); imageWidget->setPaletteSource(palette); } else { imageWidget->setPaletteSource(defaultPalette); } imageWidget->refresh(); } /* void BitMapViewer::on_refreshButton_clicked(bool checked) { refresh(); decodeVDPregs(); imageWidget->refresh(); } */ void BitMapViewer::VDPDataStoreDataRefreshed() { decodeVDPregs(); } void BitMapViewer::imagePositionUpdate( int x, int y, int color, unsigned addr, int byteValue) { labelX->setText(QString("%1").arg(x, 3, 10, QChar('0'))); labelY->setText(QString("%1").arg(y, 3, 10, QChar('0'))); labelColor->setText(QString("%1").arg(color, 3, 10, QChar('0'))); labelByte->setText(QString("0x%1").arg(byteValue, 2, 16, QChar('0'))); labelVramAddr->setText(QString("0x%1").arg(addr, 5, 16, QChar('0'))); } openmsx-debugger-0.0.0.svn20141006.orig/src/Settings.cpp0000644000175000017500000000633412414415132021776 0ustar shevekshevek// $Id$ #include "Settings.h" #include static const char *DebuggerFontNames[Settings::FONT_END] = { "Application Font", "Default Fixed Font", "Code Font", "Label Font", "Hex viewer font" }; static QString fontLocation(Settings::DebuggerFont f) { return QString("Fonts/").append(DebuggerFontNames[f]); } static QString fontColorLocation(Settings::DebuggerFont f) { return QString("Fonts/%1 Color").arg(DebuggerFontNames[f]); } Settings::Settings() : QSettings("openMSX", "debugger") { getFontsFromSettings(); } Settings::~Settings() { } Settings& Settings::get() { static Settings instance; return instance; } void Settings::getFontsFromSettings() { // first get application default QVariant v = value(fontLocation(APP_FONT)); if (v.type() == QVariant::Font) { fonts[APP_FONT] = v.value(); fontTypes[APP_FONT] = CUSTOM; } else { fontTypes[APP_FONT] = APPLICATION_DEFAULT; fonts[APP_FONT] = qApp->font(); } // then get default fixed spacing font v = value(fontLocation(FIXED_FONT)); if (v.type() == QVariant::Font) { fonts[FIXED_FONT] = v.value(); fontTypes[FIXED_FONT] = CUSTOM; } else { fontTypes[FIXED_FONT] = APPLICATION_DEFAULT; fonts[FIXED_FONT] = fonts[APP_FONT]; } // then the rest for (int f = CODE_FONT; f < FONT_END; ++f) { v = value(fontLocation((DebuggerFont)f)); if (v.type() == QVariant::Font) { fonts[f] = v.value(); fontTypes[f] = CUSTOM; } else if (v.toString() == "FixedDefault") { fonts[f] = fonts[FIXED_FONT]; fontTypes[f] = FIXED_DEFAULT; } else { fonts[f] = fonts[APP_FONT]; fontTypes[f] = CUSTOM; } } // read colors for (int f =CODE_FONT; f < FONT_END; ++f) { fontColors[f] = value(fontColorLocation((DebuggerFont)f), QColor(Qt::black)) .value(); } } QString Settings::fontName(DebuggerFont f) const { return QString(DebuggerFontNames[f]); } const QFont& Settings::font(DebuggerFont f) const { return fonts[f]; } void Settings::setFont(DebuggerFont f, const QFont& ft) { fontTypes[f] = CUSTOM; fonts[f] = ft; setValue(fontLocation(f), fonts[f]); if (f <= FIXED_FONT) updateFonts(); } Settings::DebuggerFontType Settings::fontType(DebuggerFont f) const { return fontTypes[f]; } void Settings::setFontType(DebuggerFont f, DebuggerFontType t) { if (fontTypes[f] == t) return; fontTypes[f] = t; switch (t) { case APPLICATION_DEFAULT: setValue(fontLocation(f), "AppDefault"); if (f == APP_FONT) { fonts[f] = qApp->font(); } else { fonts[f] = fonts[APP_FONT]; } break; case FIXED_DEFAULT: if (f > FIXED_FONT) { setValue(fontLocation(f), "FixedDefault"); fonts[f] = fonts[FIXED_FONT]; } break; case CUSTOM: setValue(fontLocation(f), fonts[f]); break; } if (f > FIXED_FONT) updateFonts(); } const QColor& Settings::fontColor(DebuggerFont f) const { return fontColors[f]; } void Settings::setFontColor(DebuggerFont f, const QColor& c) { if (f > FIXED_FONT) { fontColors[f] = c; setValue(fontColorLocation(f), c); } } void Settings::updateFonts() { for (int f = CODE_FONT; f < FONT_END; ++f) { switch (fontTypes[f]) { case APPLICATION_DEFAULT: fonts[f] = fonts[APP_FONT]; break; case FIXED_DEFAULT: fonts[f] = fonts[FIXED_FONT]; break; default: break; } } } openmsx-debugger-0.0.0.svn20141006.orig/src/VramBitMappedView.cpp0000644000175000017500000001746312414415132023531 0ustar shevekshevek#include "VramBitMappedView.h" #include #include #include /** Clips x to the range [LO,HI]. * Slightly faster than std::min(HI, std::max(LO, x)) * especially when no clipping is required. */ template static inline int clip(int x) { return unsigned(x - LO) <= unsigned(HI - LO) ? x : (x < HI ? LO : HI); } VramBitMappedView::VramBitMappedView(QWidget* parent) : QWidget(parent) , image(512, 512, QImage::Format_RGB32) { lines = 212; screenMode = 5; borderColor = 0; pallet = NULL; vramBase = NULL; vramAddress = 0; for (int i = 0; i < 15; ++i) { msxpallet[i] = qRgb(80, 80, 80); } setZoom(1.0f); // mouse update events when mouse is moved over the image, Quibus likes this // better then my preferd click-on-the-image setMouseTracking(true); } void VramBitMappedView::setZoom(float zoom) { zoomFactor = std::max(1.0f, zoom); setFixedSize(int(512 * zoomFactor), int(lines * 2 * zoomFactor)); update(); } void VramBitMappedView::decode() { if (!vramBase) return; printf("\n" "screenMode: %i\n" "vram to start decoding: %i\n", screenMode, vramAddress); switch (screenMode) { case 12: decodeSCR12(); break; case 11: case 10: decodeSCR10(); break; case 8: decodeSCR8(); break; case 7: decodeSCR7(); break; case 6: decodeSCR6(); break; case 5: decodeSCR5(); break; } piximage = piximage.fromImage(image); update(); } void VramBitMappedView::decodePallet() { if (!pallet) return; for (int i = 0; i < 16; ++i) { int r = (pallet[2 * i + 0] & 0xf0) >> 4; int b = (pallet[2 * i + 0] & 0x0f); int g = (pallet[2 * i + 1] & 0x0f); r = (r >> 1) | (r << 2) | (r << 5); b = (b >> 1) | (b << 2) | (b << 5); g = (g >> 1) | (g << 2) | (g << 5); msxpallet[i] = qRgb(r, g, b); } } static unsigned interleave(unsigned x) { return (x >> 1) | ((x & 1) << 16); } void VramBitMappedView::setPixel2x2(int x, int y, QRgb c) { image.setPixel(2 * x + 0, 2 * y + 0, c); image.setPixel(2 * x + 1, 2 * y + 0, c); image.setPixel(2 * x + 0, 2 * y + 1, c); image.setPixel(2 * x + 1, 2 * y + 1, c); } void VramBitMappedView::setPixel1x2(int x, int y, QRgb c) { image.setPixel(x, 2 * y + 0, c); image.setPixel(x, 2 * y + 1, c); } void VramBitMappedView::decodeSCR12() { int offset = vramAddress; for (int y = 0; y < lines; ++y) { for (int x = 0; x < 256; x += 4) { unsigned p[4]; p[0] = vramBase[interleave(offset++)]; p[1] = vramBase[interleave(offset++)]; p[2] = vramBase[interleave(offset++)]; p[3] = vramBase[interleave(offset++)]; int j = (p[2] & 7) + ((p[3] & 3) << 3) - ((p[3] & 4) << 3); int k = (p[0] & 7) + ((p[1] & 3) << 3) - ((p[1] & 4) << 3); for (unsigned n = 0; n < 4; ++n) { int z = p[n] >> 3; int r = clip<0, 31>(z + j); int g = clip<0, 31>(z + k); int b = clip<0, 31>((5 * z - 2 * j - k) / 4); r = (r << 3) | (r >> 2); b = (b << 3) | (b >> 2); g = (g << 3) | (g >> 2); setPixel2x2(x + n, y, qRgb(r, g, b)); } } } } void VramBitMappedView::decodeSCR10() { int offset = vramAddress; for (int y = 0; y < lines; ++y) { for (int x = 0; x < 256; x += 4) { unsigned p[4]; p[0] = vramBase[interleave(offset++)]; p[1] = vramBase[interleave(offset++)]; p[2] = vramBase[interleave(offset++)]; p[3] = vramBase[interleave(offset++)]; int j = (p[2] & 7) + ((p[3] & 3) << 3) - ((p[3] & 4) << 3); int k = (p[0] & 7) + ((p[1] & 3) << 3) - ((p[1] & 4) << 3); for (unsigned n = 0; n < 4; ++n) { QRgb c; if (p[n] & 0x08) { // YAE c = msxpallet[p[n] >> 4]; } else { // YJK int z = p[n] >> 3; int r = clip<0, 31>(z + j); int g = clip<0, 31>(z + k); int b = clip<0, 31>((5 * z - 2 * j - k) / 4); r = (r << 3) | (r >> 2); b = (b << 3) | (b >> 2); g = (g << 3) | (g >> 2); c = qRgb(r, g, b); } setPixel2x2(x + n, y, c); } } } } void VramBitMappedView::decodeSCR8() { int offset = vramAddress; for (int y = 0; y < lines; ++y) { for (int x = 0; x < 256; ++x) { unsigned char val = vramBase[interleave(offset++)]; int b = val & 0x03; int r = val & 0x1C; int g = val & 0xE0; b = b | (b << 2) | (b << 4) | (b << 6); r = (r >> 2) | r | (r << 3); g = g | (g >> 3) | (g >> 6); setPixel2x2(x, y, qRgb(r, g, b)); } } } QRgb VramBitMappedView::getColor(int c) { // TODO do we need to look at the TP bit??? return msxpallet[c ? c : borderColor]; } void VramBitMappedView::decodeSCR7() { int offset = vramAddress; for (int y = 0; y < lines; ++y) { for (int x = 0; x < 512; x += 2) { int val = vramBase[interleave(offset++)]; setPixel1x2(x + 0, y, getColor((val >> 4) & 15)); setPixel1x2(x + 1, y, getColor((val >> 0) & 15)); } } } void VramBitMappedView::decodeSCR6() { int offset = vramAddress; for (int y = 0; y < lines; ++y) { for (int x = 0; x < 512; x += 4) { int val = vramBase[offset++]; setPixel1x2(x + 0, y, getColor((val >> 6) & 3)); setPixel1x2(x + 1, y, getColor((val >> 4) & 3)); setPixel1x2(x + 2, y, getColor((val >> 2) & 3)); setPixel1x2(x + 3, y, getColor((val >> 0) & 3)); } } } void VramBitMappedView::decodeSCR5() { int offset = vramAddress; for (int y = 0; y < lines; ++y) { for (int x = 0; x < 256; x += 2) { int val = vramBase[offset++]; setPixel2x2(x + 0, y, getColor((val >> 4) & 15)); setPixel2x2(x + 1, y, getColor((val >> 0) & 15)); } } } void VramBitMappedView::paintEvent(QPaintEvent* event) { QRect srcRect(0, 0, 512, 2 * lines); QRect dstRect(0, 0, int(512 * zoomFactor), int(2 * lines * zoomFactor)); QPainter qp(this); //qp.drawImage(rect(),image,srcRect); qp.drawPixmap(dstRect, piximage, srcRect); } void VramBitMappedView::refresh() { decodePallet(); decode(); update(); } void VramBitMappedView::mouseMoveEvent(QMouseEvent* e) { static const unsigned bytes_per_line[] = { 0, //screen 0 1, //screen 1 2, // 2 3, // 3 4, 128, // 5 128, 256, // 7 256, 256, // 9 256, 256, 256 }; static const unsigned pixels_per_byte[] = { 0,1,2,3,4, 2, // 5 4, 2, // 7 1, 1, //9 1, 1, 1 }; int x = int(e->x() / zoomFactor); int y = int(e->y() / zoomFactor) / 2; // I see negative y-coords sometimes, so for safety clip the coords x = std::max(0, std::min(511, x)); y = std::max(0, std::min(255, y)); if ((screenMode != 6) && (screenMode != 7)) { x /= 2; } unsigned offset = bytes_per_line[screenMode] * y + x / pixels_per_byte[screenMode]; unsigned addr = offset + vramAddress; int val = (screenMode >= 7) ? vramBase[interleave(addr)] : vramBase[addr]; int color; switch (screenMode) { case 5: case 7: color = ((x & 1) ? val : (val >> 4)) & 15; break; case 6: color = (val >> (2 * (3 - (x & 3)))) & 3; break; case 8: case 10: case 11: case 12: color = val; break; default: color = 0; // avoid warning } emit imagePosition(x, y, color, addr, val); } void VramBitMappedView::mousePressEvent(QMouseEvent* e) { // since mouseMove only emits the correct signal we reuse/abuse that method mouseMoveEvent(e); decodePallet(); decode(); update(); } void VramBitMappedView::setBorderColor(int value) { borderColor = clip<0, 15>(value); decodePallet(); decode(); update(); } void VramBitMappedView::setScreenMode(int mode) { screenMode = mode; decode(); update(); } void VramBitMappedView::setLines(int nrLines) { lines = nrLines; decode(); setFixedSize(int(512 * zoomFactor), int(lines * 2 * zoomFactor)); update(); //setZoom(zoomFactor); } void VramBitMappedView::setVramAddress(int adr) { vramAddress = adr; decodePallet(); decode(); update(); } void VramBitMappedView::setVramSource(const unsigned char* adr) { vramBase = adr; decodePallet(); decode(); update(); } void VramBitMappedView::setPaletteSource(const unsigned char* adr) { pallet = adr; decodePallet(); decode(); update(); } openmsx-debugger-0.0.0.svn20141006.orig/src/BitMapViewer.ui0000644000175000017500000003751112414415132022370 0ustar shevekshevek BitMapViewer 0 0 604 619 Dialog 0 QFrame::StyledPanel QFrame::Raised 0 2 Screen mode: false 5 6 7 8 10 11 12 false 0 1 2 3 Lines visible false 192 212 256 Show page Replace color 0 by false Displayed as: Qt::Vertical QSizePolicy::Fixed 0 13 Qt::Horizontal 22 17 0 Border color VDP mode: Vram address start: 5 Lines visible 0x00000 212 Use current VDP settings true Qt::Horizontal 22 17 1 Save image... Edit palette.. Use VDP palette registers true Qt::Vertical QSizePolicy::Minimum 0 0 Zoom 2 1.000000000000000 16.000000000000000 0.250000000000000 Take VRAM snapshot 0 0 0 0 QFrame::Panel Qt::ScrollBarAsNeeded Qt::ScrollBarAsNeeded false Qt::AlignCenter 38 0 508 420 X: 0 0 18 0 000 Y: 0 0 18 0 000 Color: 0 0 18 0 000 Qt::Horizontal 40 20 Vram address: 0 0 42 0 0x00000 byte value: 0 0 24 0 0x00 openmsx-debugger-0.0.0.svn20141006.orig/src/DebuggableViewer.cpp0000644000175000017500000000303412414415132023373 0ustar shevekshevek// $Id$ #include "DebuggableViewer.h" #include "HexViewer.h" #include #include DebuggableViewer::DebuggableViewer(QWidget* parent) : QWidget(parent) { // create selection list and viewer debuggableList = new QComboBox(); debuggableList->setEditable(false); hexView = new HexViewer(); hexView->setIsInteractive(true); hexView->setIsEditable(true); QVBoxLayout* vbox = new QVBoxLayout(); vbox->setMargin(0); vbox->addWidget(debuggableList); vbox->addWidget(hexView); setLayout(vbox); connect(debuggableList, SIGNAL(currentIndexChanged(int)), this, SLOT(debuggableSelected(int))); } void DebuggableViewer::settingsChanged() { hexView->settingsChanged(); } void DebuggableViewer::refresh() { hexView->refresh(); } void DebuggableViewer::debuggableSelected(int index) { QString name = debuggableList->itemText(index); int size = debuggableList->itemData(index).toInt(); // add braces when the name contains a space if (name.contains(QChar(' '))) { name.append(QChar('}')); name.prepend(QChar('{')); } hexView->setDebuggable(name, size); } void DebuggableViewer::setDebuggables(const QMap& list) { debuggableList->clear(); for (QMap::const_iterator it = list.begin(); it != list.end(); ++it) { // set name and strip braces if necessary QString name = it.key(); if (name.contains(QChar(' '))) { name = name.mid(1, name.size() - 2); } debuggableList->addItem(name, it.value()); } // activate the first item if (!list.empty()) debuggableSelected(0); } openmsx-debugger-0.0.0.svn20141006.orig/src/DockableWidgetArea.cpp0000644000175000017500000000221512414415132023631 0ustar shevekshevek// $Id$ #include "DockableWidgetArea.h" #include "DockableWidgetLayout.h" #include "DockableWidget.h" DockableWidgetArea::DockableWidgetArea(QWidget* parent) : QWidget(parent) { layout = new DockableWidgetLayout(); setLayout(layout); } void DockableWidgetArea::removeWidget(DockableWidget* widget) { layout->removeWidget(widget); widget->setParent(0); } void DockableWidgetArea::addWidget(DockableWidget* widget, const QRect& rect) { widget->setParent(this); QRect r(rect); r.moveTopLeft(mapFromGlobal(r.topLeft())); layout->addWidget(widget, r); } void DockableWidgetArea::addWidget( DockableWidget* widget, DockableWidgetLayout::DockSide side, int distance, int w, int h) { widget->setParent(this); layout->addWidget(widget, side, distance, w, h); } void DockableWidgetArea::paintEvent(QPaintEvent* e) { QWidget::paintEvent(e); } bool DockableWidgetArea::insertLocation(QRect& r, const QSizePolicy& sizePol) { r.moveTopLeft(mapFromGlobal(r.topLeft())); bool ok = layout->insertLocation(r, sizePol); r.moveTopLeft(mapToGlobal(r.topLeft())); return ok; } void DockableWidgetArea::getConfig(QStringList& list) { layout->getConfig(list); } openmsx-debugger-0.0.0.svn20141006.orig/src/MainMemoryViewer.h0000644000175000017500000000165112414415132023077 0ustar shevekshevek// $Id: $ #ifndef MAINMEMORYVIEWER_H #define MAINMEMORYVIEWER_H #include class HexViewer; class CPURegsViewer; class SymbolTable; class QComboBox; class QLineEdit; class MainMemoryViewer : public QWidget { Q_OBJECT public: MainMemoryViewer(QWidget* parent = 0); void setDebuggable(const QString& name, int size); void setRegsView(CPURegsViewer* viewer); void setSymbolTable(SymbolTable* symtable); public slots: void setLocation(int addr); void settingsChanged(); void refresh(); void registerChanged(int id, int value); void hexViewChanged(int addr); void addressValueChanged(); void addressSourceListChanged(int index); private: HexViewer* hexView; QComboBox* addressSourceList; QLineEdit* addressValue; static const int linkRegisters[]; CPURegsViewer* regsViewer; SymbolTable* symTable; int linkedId; bool isLinked; }; #endif // MAINMEMORYVIEWER_H openmsx-debugger-0.0.0.svn20141006.orig/src/OpenMSXConnection.h0000644000175000017500000000513212414415132023147 0ustar shevekshevek#ifndef OPENMSXCONNECTION_HH #define OPENMSXCONNECTION_HH #include #include #include #include #include class QXmlInputSource; class QXmlSimpleReader; class Command { public: virtual ~Command() {} virtual QString getCommand() const = 0; virtual void replyOk (const QString& message) = 0; virtual void replyNok(const QString& message) = 0; virtual void cancel() = 0; }; class SimpleCommand : public QObject, public Command { Q_OBJECT public: SimpleCommand(const QString& command); virtual QString getCommand() const; virtual void replyOk (const QString& message); virtual void replyNok(const QString& message); virtual void cancel(); signals: void replyStatusOk(bool status); private: QString command; }; class ReadDebugBlockCommand : public SimpleCommand { public: ReadDebugBlockCommand(const QString& commandString, unsigned size, unsigned char* target); ReadDebugBlockCommand(const QString& debuggable, unsigned offset, unsigned size, unsigned char* target); protected: void copyData(const QString& message); private: unsigned size; unsigned char* target; }; class WriteDebugBlockCommand : public SimpleCommand { public: WriteDebugBlockCommand(const QString& debuggable, unsigned offset, unsigned size, unsigned char* source); }; class OpenMSXConnection : public QObject, private QXmlDefaultHandler { Q_OBJECT public: /** require: socket must be in connected state */ OpenMSXConnection(QAbstractSocket* socket); ~OpenMSXConnection(); void sendCommand(Command* command); signals: void disconnected(); void logParsed(const QString& level, const QString& message); void updateParsed(const QString& type, const QString& name, const QString& message); private slots: void processData(); void socketStateChanged(QAbstractSocket::SocketState state); void socketError(QAbstractSocket::SocketError state); private: void cleanup(); void cancelPending(); // QXmlDefaultHandler bool fatalError(const QXmlParseException& exception); bool startElement(const QString& namespaceURI, const QString& localName, const QString& qName, const QXmlAttributes& atts); bool endElement(const QString& namespaceURI, const QString& localName, const QString& qName); bool characters(const QString& ch); //std::auto_ptr socket; QAbstractSocket* socket; std::auto_ptr input; std::auto_ptr reader; QString xmlData; QXmlAttributes xmlAttrs; QQueue commands; bool connected; }; #endif openmsx-debugger-0.0.0.svn20141006.orig/src/PreferencesDialog.h0000644000175000017500000000102512414415132023214 0ustar shevekshevek#ifndef PREFERENCESDIALOG_OPENMSX_H #define PREFERENCESDIALOG_OPENMSX_H #include "ui_PreferencesDialog.h" #include class PreferencesDialog : public QDialog, private Ui::PreferencesDialog { Q_OBJECT public: PreferencesDialog(QWidget* parent = 0); private: void initFontList(); void setFontPreviewColor(const QColor& c); bool updating; private slots: void fontSelectionChange(int row); void fontTypeChanged(bool state); void fontSelectCustom(); void fontSelectColor(); }; #endif // PREFERENCESDIALOG_OPENMSX_H openmsx-debugger-0.0.0.svn20141006.orig/src/ConnectDialog.ui0000644000175000017500000000447412414415132022545 0ustar shevekshevek ConnectDialog 0 0 382 246 Dialog 9 6 Active sessions: 0 6 Connect Cancel Rescan Qt::Vertical 20 40 QAbstractItemView::SelectRows cancelButton clicked() ConnectDialog reject() 330 66 197 125 openmsx-debugger-0.0.0.svn20141006.orig/src/VDPRegistersExplained.ui0000644000175000017500000137363512414415132024220 0ustar shevekshevek VDPRegisters 0 0 820 777 Dialog QFrame::NoFrame QFrame::Raised 0 0 0 Qt::Horizontal 10 10 9 Mode registers 1 3 0 45 21 30 0 R#0 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 21 21 30 0 Qt::StrongFocus Register 0 FF Qt::AlignCenter 0 0 27 21 27 21 8 0 true false 0 0 27 21 27 21 8 tooltip set in VDPRegViewer code (VDP dependent) DG true false 0 0 27 21 27 21 8 tooltip set in VDPRegViewer code (VDP dependent) IE2 true false 0 0 27 21 27 21 8 tooltip set in VDPRegViewer code (VDP dependent) IE1 true false 0 0 27 21 27 21 8 tooltip set in VDPRegViewer code (VDP dependent) M5 true false 0 0 27 21 27 21 8 tooltip set in VDPRegViewer code (VDP dependent) M4 true false 0 0 27 21 27 21 8 Used to change the display mode. M3 true false 0 0 27 21 27 21 8 register 0 bit 0 0 true false 45 21 30 0 R#1 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 21 21 30 0 Qt::StrongFocus Register 1 FF Qt::AlignCenter 0 0 27 21 27 21 8 tooltip set in VDPRegViewer code (VDP dependent) 0 true false false 0 0 27 21 27 21 8 When 1, screen display enabled. When 0, screen disabled. BL true false 0 0 27 21 27 21 8 Enables interrupt from Horizontal scanning line by Interrupt Enable 0. IE0 true false 0 0 27 21 27 21 8 Used to change the display mode. M1 true false 0 0 27 21 27 21 8 Used to change the display mode. M2 true false 0 0 27 21 27 21 8 0 true false 0 0 27 21 27 21 8 When 1, sprite size is 16 x 16. When 0, 8 x 8. SI true false 0 0 27 21 27 21 8 Sprite expansion; when 1: expanded. When 0, normal. MAG true false 45 21 30 0 R#8 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 21 21 30 0 Qt::StrongFocus Register 8 FF Qt::AlignCenter 0 0 27 21 27 21 8 When 1, sets the color bus to input mode and enables mouse. MS true false 0 0 27 21 27 21 8 When 1, enables light pen. When 0, disables light pen. LP true false 0 0 27 21 27 21 8 Sets the color of code 0 to the color of the palette. TP true false 0 0 27 21 27 21 8 When 1, sets the color bus to input mode. When 0, sets the color bus to output mode. CB true false 0 0 27 21 27 21 8 Selects the type of Video RAM. 1 = 64K x 1 bit or 64K x 4 bits. 0 = 16K x 1 bit or 16K x 4 bits. VR true false 0 0 27 21 27 21 8 0 true false 0 0 27 21 27 21 8 When 1, disables display of sprites. When 0, displays sprites. SPD true false 0 0 27 21 27 21 8 When 1, sets black and white in 32 tones. When 0, sets color (available only with a composite encoder). BW true false 45 21 30 0 R#9 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 21 21 30 0 Qt::StrongFocus Register 9 FF Qt::AlignCenter 0 0 27 21 27 21 8 When 1, sets the horizontal dot count to 212. When 0, sets the horizontal dot count to 192. LN true false false 0 0 27 21 27 21 8 0 true false 0 0 27 21 27 21 8 Selects simultaneous mode. S1 true false 0 0 27 21 27 21 8 Selects simultaneous mode. S0 true false 0 0 27 21 27 21 8 When 1, interlace (Complete NTSC timing) When 0, non-interlace (Incomplete NTSC timing) IL true false 0 0 27 21 27 21 8 When 1, displays two graphic screens interchangably by Even field/Odd field. When 0, displays the same graphic screen by Even field/Odd field. E0 true false 0 0 27 21 27 21 8 When 1, PAL (313 lines) When 0, NTSC (262 lines) (For RGB output only) NT true false 0 0 27 21 27 21 8 When 1, sets *DLCLK to input mode. When 0, sets *DLCLK to output mode. DC true false Qt::Vertical 20 4 V9958 Registers 1 3 0 45 21 30 0 R#25 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 21 21 30 0 Qt::StrongFocus Register 25 FF Qt::AlignCenter 0 0 27 21 27 21 8 Display adjust register 0 true false 0 0 27 21 27 21 8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:8pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Video Command Mode</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">0=Normal</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">1=Screen 2-4 as screen 8</p></body></html> CMD true false 0 0 27 21 27 21 8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:8pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">YJK Attribute Enable</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">0=No Attribute</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">1=With Attribute</p></body></html> VDS true false 0 0 27 21 27 21 8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:8pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">YJK Attribute Enable</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">0=No Attribute</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">1=With Attribute</p></body></html> YAE true false 0 0 27 21 27 21 8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:8pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">YJK Mode Enable</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">0=Normal RGB</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">1=YJK System</p></body></html> YJK true false 0 0 27 21 27 21 8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:8pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">VRAM Access Waitstates</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">0=Normal</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">1=Enable CPU Waitstate</p></body></html> WTE true false 0 0 27 21 27 21 8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:8pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">H-Scroll Mask 8 Pixels</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">0=Normal</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">1=Hide Leftmost Pixels</p></body></html> MSK true false 0 0 27 21 27 21 8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:8pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">H-Scroll Screen Width</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">0=One page</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">1=Two pages</p></body></html> SP2 true false 45 21 30 0 R#26 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 21 21 30 0 Qt::StrongFocus Register 26 FF Qt::AlignCenter 0 0 27 21 27 21 8 Display offset register 0 true false 0 0 27 21 27 21 8 Display offset register 0 true false 0 0 27 21 27 21 8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:8pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The screen is shifted <span style=" font-weight:600;">TO THE LEFT</span> as specified in <span style=" font-weight:600;">8-dot units</span> (16-dot units in Screen 6-7).</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">When SP2=0: Scrolling is done within one page and the non-displayed left side of the page is </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">displayed on the right hand side of the screen (HO8 is ignored in this mode).</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">When SP2=1: Scrolling is done within 2 pages, and when scrolled, the second page appears to</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">the right habd side of the first page, and when scrolled more, the first page reappears to the right</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">of the second page.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600; font-style:italic;">Note</span><span style=" font-style:italic;">: When SP2=1, the A15 bit of the Pattern Name table base address register should be set</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-style:italic;">to "1" (VDP Reg 2, Bit 5), otherwise only the leftmost page would be displayed.</p></body></html> H08 true false 0 0 27 21 27 21 8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:8pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The screen is shifted <span style=" font-weight:600;">TO THE LEFT</span> as specified in <span style=" font-weight:600;">8-dot units</span> (16-dot units in Screen 6-7).</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">When SP2=0: Scrolling is done within one page and the non-displayed left side of the page is </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">displayed on the right hand side of the screen (HO8 is ignored in this mode).</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">When SP2=1: Scrolling is done within 2 pages, and when scrolled, the second page appears to</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">the right habd side of the first page, and when scrolled more, the first page reappears to the right</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">of the second page.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600; font-style:italic;">Note</span><span style=" font-style:italic;">: When SP2=1, the A15 bit of the Pattern Name table base address register should be set</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-style:italic;">to "1" (VDP Reg 2, Bit 5), otherwise only the leftmost page would be displayed.</p></body></html> H07 true false 0 0 27 21 27 21 8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:8pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The screen is shifted <span style=" font-weight:600;">TO THE LEFT</span> as specified in <span style=" font-weight:600;">8-dot units</span> (16-dot units in Screen 6-7).</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">When SP2=0: Scrolling is done within one page and the non-displayed left side of the page is </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">displayed on the right hand side of the screen (HO8 is ignored in this mode).</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">When SP2=1: Scrolling is done within 2 pages, and when scrolled, the second page appears to</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">the right habd side of the first page, and when scrolled more, the first page reappears to the right</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">of the second page.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600; font-style:italic;">Note</span><span style=" font-style:italic;">: When SP2=1, the A15 bit of the Pattern Name table base address register should be set</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-style:italic;">to "1" (VDP Reg 2, Bit 5), otherwise only the leftmost page would be displayed.</p></body></html> H06 true false 0 0 27 21 27 21 8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:8pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The screen is shifted <span style=" font-weight:600;">TO THE LEFT</span> as specified in <span style=" font-weight:600;">8-dot units</span> (16-dot units in Screen 6-7).</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">When SP2=0: Scrolling is done within one page and the non-displayed left side of the page is </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">displayed on the right hand side of the screen (HO8 is ignored in this mode).</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">When SP2=1: Scrolling is done within 2 pages, and when scrolled, the second page appears to</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">the right habd side of the first page, and when scrolled more, the first page reappears to the right</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">of the second page.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600; font-style:italic;">Note</span><span style=" font-style:italic;">: When SP2=1, the A15 bit of the Pattern Name table base address register should be set</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-style:italic;">to "1" (VDP Reg 2, Bit 5), otherwise only the leftmost page would be displayed.</p></body></html> H05 true false 0 0 27 21 27 21 8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:8pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The screen is shifted <span style=" font-weight:600;">TO THE LEFT</span> as specified in <span style=" font-weight:600;">8-dot units</span> (16-dot units in Screen 6-7).</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">When SP2=0: Scrolling is done within one page and the non-displayed left side of the page is </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">displayed on the right hand side of the screen (HO8 is ignored in this mode).</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">When SP2=1: Scrolling is done within 2 pages, and when scrolled, the second page appears to</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">the right habd side of the first page, and when scrolled more, the first page reappears to the right</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">of the second page.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600; font-style:italic;">Note</span><span style=" font-style:italic;">: When SP2=1, the A15 bit of the Pattern Name table base address register should be set</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-style:italic;">to "1" (VDP Reg 2, Bit 5), otherwise only the leftmost page would be displayed.</p></body></html> H04 true false 0 0 27 21 27 21 8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:8pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The screen is shifted <span style=" font-weight:600;">TO THE LEFT</span> as specified in <span style=" font-weight:600;">8-dot units</span> (16-dot units in Screen 6-7).</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">When SP2=0: Scrolling is done within one page and the non-displayed left side of the page is </p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">displayed on the right hand side of the screen (HO8 is ignored in this mode).</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">When SP2=1: Scrolling is done within 2 pages, and when scrolled, the second page appears to</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">the right habd side of the first page, and when scrolled more, the first page reappears to the right</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">of the second page.</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600; font-style:italic;">Note</span><span style=" font-style:italic;">: When SP2=1, the A15 bit of the Pattern Name table base address register should be set</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-style:italic;">to "1" (VDP Reg 2, Bit 5), otherwise only the leftmost page would be displayed.</p></body></html> H03 true false 45 21 30 0 R#27 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 21 21 30 0 Qt::StrongFocus Register 27 FF Qt::AlignCenter 0 0 27 21 27 21 8 Interrupt line register 0 true false 0 0 27 21 27 21 8 Interrupt line register 0 true false 0 0 27 21 27 21 8 Interrupt line register 0 true false 0 0 27 21 27 21 8 Interrupt line register 0 true false 0 0 27 21 27 21 8 Interrupt line register 0 true false 0 0 27 21 27 21 8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:8pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The screen is shifted <span style=" font-weight:600;">TO THE RIGHT</span> (unlike as for Register 26 which shifts to the left) as specified in</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">1-dot units</span> (2-dot units in Screen 6-7). When this register is set to a non-zero value, the colors of the</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">leftmost pixel(s) will be undefined, to avoid this dirt effect, the MSK bit must be set, the leftmost 8</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">pixels (16 pixels in Screen 6-7) will be then covered by the border color.</p></body></html> H02 true false 0 0 27 21 27 21 8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:8pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The screen is shifted <span style=" font-weight:600;">TO THE RIGHT</span> (unlike as for Register 26 which shifts to the left) as specified in</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">1-dot units</span> (2-dot units in Screen 6-7). When this register is set to a non-zero value, the colors of the</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">leftmost pixel(s) will be undefined, to avoid this dirt effect, the MSK bit must be set, the leftmost 8</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">pixels (16 pixels in Screen 6-7) will be then covered by the border color.</p></body></html> H01 true false 0 0 27 21 27 21 8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:8pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The screen is shifted <span style=" font-weight:600;">TO THE RIGHT</span> (unlike as for Register 26 which shifts to the left) as specified in</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">1-dot units</span> (2-dot units in Screen 6-7). When this register is set to a non-zero value, the colors of the</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">leftmost pixel(s) will be undefined, to avoid this dirt effect, the MSK bit must be set, the leftmost 8</p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">pixels (16 pixels in Screen 6-7) will be then covered by the border color.</p></body></html> H00 true false Qt::Vertical 20 4 Table Base Address Registers 1 3 0 45 21 30 0 R#2 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 21 21 30 0 Qt::StrongFocus Register 2 FF Qt::AlignCenter 0 0 27 21 27 21 8 Pattern name table base address register 0 true false false 0 0 27 21 27 21 8 Pattern name table base address register A16 true false 0 0 27 21 27 21 8 Pattern name table base address register A15 true false 0 0 27 21 27 21 8 Pattern name table base address register A14 true false 0 0 27 21 27 21 8 Pattern name table base address register A13 true false 0 0 27 21 27 21 8 Pattern name table base address register A12 true false 0 0 27 21 27 21 8 Pattern name table base address register A11 true false 0 0 27 21 27 21 8 Pattern name table base address register A10 true false 45 21 30 0 R#3 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 21 21 30 0 Qt::StrongFocus Register 3 FF Qt::AlignCenter 0 0 27 21 27 21 8 Color table base address register low A13 true false 0 0 27 21 27 21 8 Color table base address register low A12 true false 0 0 27 21 27 21 8 Color table base address register low A11 true false 0 0 27 21 27 21 8 Color table base address register low A10 true false 0 0 27 21 27 21 8 Color table base address register low A9 true false 0 0 27 21 27 21 8 Color table base address register low A8 true false 0 0 27 21 27 21 8 Color table base address register low A7 true false 0 0 27 21 27 21 8 Color table base address register low A6 true false 45 21 30 0 R#10 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 21 21 30 0 Qt::StrongFocus Register 10 FF Qt::AlignCenter 0 0 27 21 27 21 8 Color table base address register high 0 true false 0 0 27 21 27 21 8 Color table base address register high 0 true false 0 0 27 21 27 21 8 Color table base address register high 0 true false 0 0 27 21 27 21 8 Color table base address register high 0 true false 0 0 27 21 27 21 8 Color table base address register high 0 true false 0 0 27 21 27 21 8 Color table base address register high A16 true false 0 0 27 21 27 21 8 Color table base address register high A15 true false 0 0 27 21 27 21 8 Color table base address register high A14 true false 45 21 30 0 R#4 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 21 21 30 0 Qt::StrongFocus Register 4 FF Qt::AlignCenter 0 0 27 21 27 21 8 Pattern generator table base address register 0 true false 0 0 27 21 27 21 8 Pattern generator table base address register 0 true false 0 0 27 21 27 21 8 Pattern generator table base address register A16 true false 0 0 27 21 27 21 8 Pattern generator table base address register A15 true false 0 0 27 21 27 21 8 Pattern generator table base address register A14 true false 0 0 27 21 27 21 8 Pattern generator table base address register A13 true false 0 0 27 21 27 21 8 Pattern generator table base address register A12 true false 0 0 27 21 27 21 8 Pattern generator table base address register A11 true false 45 21 30 0 R#5 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 21 21 30 0 Qt::StrongFocus Register 5 FF Qt::AlignCenter 0 0 27 21 27 21 8 Sprite attribute table base address register low A14 true false 0 0 27 21 27 21 8 Sprite attribute table base address register low A13 true false 0 0 27 21 27 21 8 Sprite attribute table base address register low A12 true false 0 0 27 21 27 21 8 Sprite attribute table base address register low A11 true false 0 0 27 21 27 21 8 Sprite attribute table base address register low A10 true false 0 0 27 21 27 21 8 Sprite attribute table base address register low A9 true false 0 0 27 21 27 21 8 Sprite attribute table base address register low A8 true false 0 0 27 21 27 21 8 Sprite attribute table base address register low A7 true false 45 21 30 0 R#11 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 21 21 30 0 Qt::StrongFocus Register 11 FF Qt::AlignCenter 0 0 27 21 27 21 8 Sprite attribute table base address register high 0 true false 0 0 27 21 27 21 8 Sprite attribute table base address register high 0 true false 0 0 27 21 27 21 8 Sprite attribute table base address register high 0 true false 0 0 27 21 27 21 8 Sprite attribute table base address register high 0 true false 0 0 27 21 27 21 8 Sprite attribute table base address register high 0 true false 0 0 27 21 27 21 8 Sprite attribute table base address register high 0 true false 0 0 27 21 27 21 8 Sprite attribute table base address register high A16 true false 0 0 27 21 27 21 8 Sprite attribute table base address register high A15 true false 45 21 30 0 R#6 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 21 21 30 0 Qt::StrongFocus Register 6 FF Qt::AlignCenter 0 0 27 21 27 21 8 Sprite pattern generator table base address register 0 true false 0 0 27 21 27 21 8 Sprite pattern generator table base address register 0 true false 0 0 27 21 27 21 8 Sprite pattern generator table base address register A16 true false 0 0 27 21 27 21 8 Sprite pattern generator table base address register A15 true false 0 0 27 21 27 21 8 Sprite pattern generator table base address register A14 true false 0 0 27 21 27 21 8 Sprite pattern generator table base address register A13 true false 0 0 27 21 27 21 8 Sprite pattern generator table base address register A12 true false 0 0 27 21 27 21 8 Sprite pattern generator table base address register A11 true false Qt::Horizontal 10 10 9 Color Registers QLayout::SetMinimumSize 0 0 1 3 60 21 30 0 R#7 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 40 21 30 0 Qt::StrongFocus Register 7 FF Qt::AlignCenter 0 0 27 21 27 21 8 Text color/Back drop color register TC3 true false 0 0 27 21 27 21 8 Text color/Back drop color register TC2 true false 0 0 27 21 27 21 8 Text color/Back drop color register TC1 true false 0 0 27 21 27 21 8 Text color/Back drop color register TC0 true false 0 0 27 21 27 21 8 Text color/Back drop color register BD3 true false 0 0 27 21 27 21 8 Text color/Back drop color register BD2 true false 0 0 27 21 27 21 8 Text color/Back drop color register BD1 true false 0 0 27 21 27 21 8 Text color/Back drop color register BD0 true false 60 21 30 0 R#12 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 40 21 30 0 Qt::StrongFocus Register 12 FF Qt::AlignCenter 0 0 27 21 27 21 8 Text color/Back color register\nUsed for blinking in TEXT 2 mode. T23 true false 0 0 27 21 27 21 8 Text color/Back color register\nUsed for blinking in TEXT 2 mode. T22 true false 0 0 27 21 27 21 8 Text color/Back color register\nUsed for blinking in TEXT 2 mode. T21 true false 0 0 27 21 27 21 8 Text color/Back color register\nUsed for blinking in TEXT 2 mode. T20 true false 0 0 27 21 27 21 8 Text color/Back color register\nUsed for blinking in TEXT 2 mode. BC3 true false 0 0 27 21 27 21 8 Text color/Back color register\nUsed for blinking in TEXT 2 mode. BC2 true false 0 0 27 21 27 21 8 Text color/Back color register\nUsed for blinking in TEXT 2 mode. BC1 true false 0 0 27 21 27 21 8 Text color/Back color register\nUsed for blinking in TEXT 2 mode. BC0 true false 60 21 30 0 R#13 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 40 21 30 0 Qt::StrongFocus Register 13 FF Qt::AlignCenter 0 0 27 21 27 21 8 Blinking period register ON3 true false 0 0 27 21 27 21 8 Blinking period register ON2 true false 0 0 27 21 27 21 8 Blinking period register ON1 true false 0 0 27 21 27 21 8 Blinking period register ON0 true false 0 0 27 21 27 21 8 Blinking period register OF3 true false 0 0 27 21 27 21 8 Blinking period register OF2 true false 0 0 27 21 27 21 8 Blinking period register OF1 true false 0 0 27 21 27 21 8 Blinking period register OF0 true false 60 21 30 0 R#20 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 40 21 30 0 Qt::StrongFocus Register 20 FF Qt::AlignCenter 0 0 27 21 27 21 8 Color burst register 1 0 true false 0 0 27 21 27 21 8 Color burst register 1 0 true false 0 0 27 21 27 21 8 Color burst register 1 0 true false 0 0 27 21 27 21 8 Color burst register 1 0 true false 0 0 27 21 27 21 8 Color burst register 1 0 true false 0 0 27 21 27 21 8 Color burst register 1 0 true false 0 0 27 21 27 21 8 Color burst register 1 0 true false 0 0 27 21 27 21 8 Color burst register 1 0 true false 60 21 30 0 R#21 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 40 21 30 0 Qt::StrongFocus Register 21 FF Qt::AlignCenter 0 0 27 21 27 21 8 Color burst register 2 0 true false 0 0 27 21 27 21 8 Color burst register 2 0 true false 0 0 27 21 27 21 8 Color burst register 2 1 true false 0 0 27 21 27 21 8 Color burst register 2 1 true false 0 0 27 21 27 21 8 Color burst register 2 1 true false 0 0 27 21 27 21 8 Color burst register 2 0 true false 0 0 27 21 27 21 8 Color burst register 2 1 true false 0 0 27 21 27 21 8 Color burst register 2 1 true false 60 21 30 0 R#22 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 40 21 30 0 Qt::StrongFocus Register 22 FF Qt::AlignCenter 0 0 27 21 27 21 8 Color burst register 3 0 true false 0 0 27 21 27 21 8 Color burst register 3 0 true false 0 0 27 21 27 21 8 Color burst register 3 0 true false 0 0 27 21 27 21 8 Color burst register 3 0 true false 0 0 27 21 27 21 8 Color burst register 3 0 true false 0 0 27 21 27 21 8 Color burst register 3 1 true false 0 0 27 21 27 21 8 Color burst register 3 0 true false 0 0 27 21 27 21 8 Color burst register 3 1 true false Qt::Vertical 20 4 Display Registers 0 0 1 3 45 21 30 0 R#18 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 21 21 30 0 Qt::StrongFocus Register 18 FF Qt::AlignCenter 0 0 27 21 27 21 8 Display adjust register V3 true false 0 0 27 21 27 21 8 Display adjust register V2 true false 0 0 27 21 27 21 8 Display adjust register V1 true false 0 0 27 21 27 21 8 Display adjust register V0 true false 0 0 27 21 27 21 8 Display adjust register H3 true false 0 0 27 21 27 21 8 Display adjust register H2 true false 0 0 27 21 27 21 8 Display adjust register H1 true false 0 0 27 21 27 21 8 Display adjust register H0 true false 45 21 30 0 R#23 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 21 21 30 0 Qt::StrongFocus Register 23 FF Qt::AlignCenter 0 0 27 21 27 21 8 Display offset register DO7 true false 0 0 27 21 27 21 8 Display offset register DO6 true false 0 0 27 21 27 21 8 Display offset register DO5 true false 0 0 27 21 27 21 8 Display offset register DO4 true false 0 0 27 21 27 21 8 Display offset register DO3 true false 0 0 27 21 27 21 8 Display offset register DO2 true false 0 0 27 21 27 21 8 Display offset register DO1 true false 0 0 27 21 27 21 8 Display offset register DO0 true false 45 21 30 0 R#19 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 21 21 30 0 Qt::StrongFocus Register 19 FF Qt::AlignCenter 0 0 27 21 27 21 8 Interrupt line register IL7 true false 0 0 27 21 27 21 8 Interrupt line register IL6 true false 0 0 27 21 27 21 8 Interrupt line register IL5 true false 0 0 27 21 27 21 8 Interrupt line register IL4 true false 0 0 27 21 27 21 8 Interrupt line register IL3 true false 0 0 27 21 27 21 8 Interrupt line register IL2 true false 0 0 27 21 27 21 8 Interrupt line register IL1 true false 0 0 27 21 27 21 8 Interrupt line register IL0 true false Qt::Vertical 20 4 Access Registers 0 0 1 3 45 21 30 0 R#14 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 21 21 30 0 Qt::StrongFocus Register 14 FF Qt::AlignCenter 0 0 27 21 27 21 8 VRAM Access base address register 0 true false 0 0 27 21 27 21 8 VRAM Access base address register 0 true false 0 0 27 21 27 21 8 VRAM Access base address register 0 true false 0 0 27 21 27 21 8 VRAM Access base address register 0 true false 0 0 27 21 27 21 8 VRAM Access base address register 0 true false 0 0 27 21 27 21 8 VRAM Access base address register A16 true false 0 0 27 21 27 21 8 VRAM Access base address register A15 true false 0 0 27 21 27 21 8 VRAM Access base address register A14 true false 45 21 30 0 R#15 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 21 21 30 0 Qt::StrongFocus Register 15 FF Qt::AlignCenter 0 0 27 21 27 21 8 Status register pointer 0 true false 0 0 27 21 27 21 8 Status register pointer 0 true false 0 0 27 21 27 21 8 Status register pointer 0 true false 0 0 27 21 27 21 8 Status register pointer 0 true false 0 0 27 21 27 21 8 Status register pointer S3 true false 0 0 27 21 27 21 8 Status register pointer S2 true false 0 0 27 21 27 21 8 Status register pointer S1 true false 0 0 27 21 27 21 8 Status register pointer S0 true false 45 21 30 0 R#16 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 21 21 30 0 Qt::StrongFocus Register 16 FF Qt::AlignCenter 0 0 27 21 27 21 8 Color palette address register 0 true false 0 0 27 21 27 21 8 Color palette address register 0 true false 0 0 27 21 27 21 8 Color palette address register 0 true false 0 0 27 21 27 21 8 Color palette address register 0 true false 0 0 27 21 27 21 8 Color palette address register C3 true false 0 0 27 21 27 21 8 Color palette address register C2 true false 0 0 27 21 27 21 8 Color palette address register C1 true false 0 0 27 21 27 21 8 Color palette address register C0 true false 45 21 30 0 R#17 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 21 21 30 0 Qt::StrongFocus Register 17 FF Qt::AlignCenter 0 0 27 21 27 21 8 Control register pointer AII true false 0 0 27 21 27 21 8 Control register pointer 0 true false 0 0 27 21 27 21 8 Control register pointer RS5 true false 0 0 27 21 27 21 8 Control register pointer RS4 true false 0 0 27 21 27 21 8 Control register pointer RS3 true false 0 0 27 21 27 21 8 Control register pointer RS2 true false 0 0 27 21 27 21 8 Control register pointer RS1 true false 0 0 27 21 27 21 8 Control register pointer RS0 true false Qt::Horizontal 10 10 2 Qt::Horizontal 9 Qt::Horizontal 40 20 Decoding the mode registers 0 0 5 0 0 Screen mode Screen 0 PAL 0 0 , 212 lines, Display enabeled interlaced alternate pages Interrupt from Horizontal scanning line enabled. Interrupt from Horizontal scanning line enabled. Interrupt from Horizontal scanning line enabled. 16x16 sprites ,magnified sprites ,enabled Color 0 is transparent DG explained Uses 4/16K memory Decoding the V9958 registers 0 0 5 0 0 explaining SP2 explaining msk explaining wte explaining yjk explaining yae explaining vds explaining cmd explaining h0x Decoding the Table Base Registers QFormLayout::ExpandingFieldsGrow 3 2 0 5 0 0 Pattern name table 40 0 Screen mode 0x0000 Color table Screen mode 0x0000 Pattern generator table Screen mode 0x0000 Sprite attribute table Screen mode 0x0000 Sprite pattern generator table Screen mode 0x0000 Decoding the Display registers QFormLayout::ExpandingFieldsGrow 3 2 0 9 0 0 Display adjust Screen mode (0,0) Display offset Screen mode 255 Interrupt line Screen mode 255 Color Registers 3 2 0 5 5 0 Text color 15 0 Screen mode 15 Backdrop color Screen mode 15 Blinking text color Screen mode 15 Blinking backdrop Screen mode 15 Blinking time on Screen mode 15 Blinking time off Screen mode 15 Access registers 3 2 0 5 5 0 Access address 22 0 Screen mode 255 status register Screen mode 255 color Screen mode 255 VDP register Screen mode 255 Qt::Horizontal 40 20 Qt::Vertical 20 3 Qt::Horizontal 40 20 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt; font-weight:600; font-style:italic;">Quick hack</span><span style=" font-size:10pt; font-style:italic;"> use this to switch between VDP chip, since no autodetection yet in the code</span></p></body></html> Qt::RichText V9958 V9938 TMS99x8 InteractiveButton QPushButton
InteractiveButton.h
InteractiveLabel QLabel
InteractiveLabel.h
openmsx-debugger-0.0.0.svn20141006.orig/src/VDPDataStore.h0000644000175000017500000000226612414415132022103 0ustar shevekshevek#ifndef VDPDATASTORE_H #define VDPDATASTORE_H #include "SimpleHexRequest.h" #include class VDPDataStore : public QObject, public SimpleHexRequestUser { Q_OBJECT public: static VDPDataStore& instance(); const unsigned char* getVramPointer() const; const unsigned char* getPalettePointer() const; const unsigned char* getRegsPointer() const; const unsigned char* getStatusRegsPointer() const; const unsigned char* getVdpVramPointer() const; private: VDPDataStore(); ~VDPDataStore(); virtual void DataHexRequestReceived(); unsigned char* vram; bool old_version; // VRAM debuggable has old or new name? bool got_version; // is the above boolean already filled in? friend class VDPDataStoreVersionCheck; public slots: void refresh(); signals: void dataRefreshed(); // The refresh got the new data /** This might become handy later on, for now we only need the dataRefreshed * void dataChanged(); //any of the contained data has changed void vramChanged(); //only the vram changed void paletteChanged(); //only the palette changed void regsChanged(); //only the regs changed void statusRegsChanged(); //only the regs changed */ }; #endif /* VDPDATASTORE_H */ openmsx-debugger-0.0.0.svn20141006.orig/src/Convert.h0000644000175000017500000000034312414415132021255 0ustar shevekshevek#ifndef CONVERT_H #define CONVERT_H class QString; int stringToValue(const QString& str); QString hexValue(int value, int width = 0); QString& escapeXML(QString& str); QString& unescapeXML(QString& str); #endif // CONVERT_H openmsx-debugger-0.0.0.svn20141006.orig/src/SymbolTable.cpp0000644000175000017500000004503512414415132022414 0ustar shevekshevek// $Id$ #include "SymbolTable.h" #include "DebuggerData.h" #include #include #include #include #include #include #include // class SymbolTable SymbolTable::SymbolTable() { connect(&fileWatcher, SIGNAL(fileChanged(const QString&)), this, SLOT(fileChanged(const QString&))); } SymbolTable::~SymbolTable() { clear(); } void SymbolTable::add(Symbol* symbol) { symbols.append(symbol); symbol->table = this; mapSymbol(symbol); } void SymbolTable::removeAt(int index) { Symbol* symbol = symbols.takeAt(index); unmapSymbol(symbol); delete symbol; } void SymbolTable::remove(Symbol* symbol) { symbols.removeAll(symbol); unmapSymbol(symbol); delete symbol; } void SymbolTable::clear() { addressSymbols.clear(); valueSymbols.clear(); qDeleteAll(symbols); symbols.clear(); } int SymbolTable::size() const { return symbols.size(); } void SymbolTable::mapSymbol(Symbol* symbol) { if (symbol->type() != Symbol::VALUE) { addressSymbols.insert(symbol->value(), symbol); } if (symbol->type() != Symbol::JUMPLABEL) { valueSymbols.insert(symbol->value(), symbol); } } void SymbolTable::unmapSymbol(Symbol* symbol) { QMutableMapIterator i(addressSymbols); while (i.hasNext()) { i.next(); if (i.value() == symbol) i.remove(); } QMutableHashIterator j(valueSymbols); while (j.hasNext()) { j.next(); if (j.value() == symbol) j.remove(); } } void SymbolTable::symbolTypeChanged(Symbol* symbol) { unmapSymbol(symbol); mapSymbol(symbol); } void SymbolTable::symbolValueChanged(Symbol* symbol) { unmapSymbol(symbol); mapSymbol(symbol); } Symbol* SymbolTable::findFirstAddressSymbol(int addr, MemoryLayout* ml) { for (currentAddress = addressSymbols.begin(); currentAddress != addressSymbols.end(); ++currentAddress) { if ((*currentAddress)->value() >= addr) { if ((*currentAddress)->isSlotValid(ml)) { return *currentAddress; } } } return 0; } Symbol* SymbolTable::getCurrentAddressSymbol() { return currentAddress != addressSymbols.end() ? *currentAddress : 0; } Symbol* SymbolTable::findNextAddressSymbol(MemoryLayout* ml) { for (++currentAddress; currentAddress != addressSymbols.end(); ++currentAddress) { if ((*currentAddress)->isSlotValid(ml)) { return *currentAddress; } } return 0; } Symbol* SymbolTable::getValueSymbol(int val, Symbol::Register reg, MemoryLayout* ml) { for (QMultiHash::iterator it = valueSymbols.find(val); it != valueSymbols.end() && it.key() == val; ++it) { if ((it.value()->validRegisters() & reg) && it.value()->isSlotValid(ml)) { return it.value(); } } return 0; } Symbol* SymbolTable::getAddressSymbol(int addr, MemoryLayout* ml) { for (QMultiMap::iterator it = addressSymbols.find(addr); it != addressSymbols.end() && it.key() == addr; ++it) { if (it.value()->isSlotValid(ml)) { return it.value(); } } return 0; } Symbol* SymbolTable::getAddressSymbol(const QString& label, bool case_sensitive) { for (QMultiMap::iterator it = addressSymbols.begin(); it != addressSymbols.end(); ++it) { if (it.value()->text().compare(label, Qt::CaseSensitive)==0) return it.value(); if (!case_sensitive && it.value()->text().compare(label, Qt::CaseInsensitive)==0) return it.value(); } return 0; } QStringList SymbolTable::labelList(bool include_vars, const MemoryLayout* ml) const { QStringList labels; for (QMultiMap::const_iterator it = addressSymbols.begin(); it != addressSymbols.end(); ++it) { if (it.value()->type() == Symbol::JUMPLABEL || (include_vars && it.value()->type() == Symbol::VARIABLELABEL ) ) if( ml == 0 || it.value()->isSlotValid(ml) ) labels << it.value()->text(); } return labels; } int SymbolTable::symbolFilesSize() const { return symbolFiles.size(); } const QString& SymbolTable::symbolFile(int index) const { return symbolFiles.at(index).fileName; } const QDateTime& SymbolTable::symbolFileRefresh(int index) const { return symbolFiles.at(index).refreshTime; } bool SymbolTable::readFile(const QString& filename, FileType type) { if (type == DETECT_FILE) { if (filename.endsWith(".map")) { // HiTech link map file type = LINKMAP_FILE; } else if (filename.endsWith(".sym")) { // auto detect which sym file QFile file(filename); if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { QTextStream in(&file); QString line = in.readLine(); if (line[0] == ';') { type = ASMSX_FILE; } else if (line.contains("; last def. pass")) { type = TNIASM0_FILE; } else if (line.contains(": %equ ")) { type = TNIASM1_FILE; } else if (line.contains(": equ ")) { type = SJASM_FILE; } } } } switch (type) { case TNIASM0_FILE: return readTNIASM0File(filename); case TNIASM1_FILE: return readTNIASM1File(filename); case SJASM_FILE: return readSJASMFile(filename); case ASMSX_FILE: return readASMSXFile(filename); case LINKMAP_FILE: return readLinkMapFile(filename); default: return false; } } void SymbolTable::appendFile(const QString& file, FileType type) { SymbolFileRecord rec; rec.fileName = file; rec.fileType = type; rec.refreshTime = QDateTime::currentDateTime(); symbolFiles.append(rec); fileWatcher.addPath(file); } // Universal value parsing routine. Accepts: // - 0123h, 1234h, 1234H (hex) // - 0x1234 (hex) // - 1234 (dec) // - 0123 (oct) // The string may (optionally) end with a '; comment' part (with or without // whitespace around the ';' character). static bool parseValue(const QString& str, int& result) { QStringList l = str.split(";"); // ignore stuff after ';' QString s = l.at(0).trimmed(); bool success; if (s.endsWith('h', Qt::CaseInsensitive)) { s.chop(1); result = s.toInt(&success, 16); } else { result = s.toInt(&success, 0); // any base (e.g. 0x..) } return success; } bool SymbolTable::readSymbolFile( const QString& filename, FileType type, const QString& equ) { QFile file(filename); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { return false; } appendFile(filename, type); QTextStream in(&file); while (!in.atEnd()) { QString line = in.readLine(); QStringList l = line.split(equ); if (l.size() != 2) continue; int value; if (!parseValue(l.at(1), value)) continue; Symbol* sym = new Symbol(l.at(0), value); sym->setSource(&symbolFiles.back().fileName); add(sym); } return true; } bool SymbolTable::readTNIASM0File(const QString& filename) { return readSymbolFile(filename, TNIASM0_FILE, ": equ "); } bool SymbolTable::readTNIASM1File(const QString& filename) { return readSymbolFile(filename, TNIASM1_FILE, ": %equ "); } bool SymbolTable::readSJASMFile(const QString& filename) { return readSymbolFile(filename, SJASM_FILE, ": equ "); } bool SymbolTable::readASMSXFile(const QString& filename) { QFile file( filename ); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { return false; } appendFile(filename, ASMSX_FILE); QTextStream in(&file); int filePart = 0; while (!in.atEnd()) { QString line = in.readLine(); if (line[0] == ';') { if (line.startsWith("; global and local")) { filePart = 1; } else if (line.startsWith("; other")) { filePart = 2; } } else { if ((line[0] == '$') || (line[4] == 'h') || (line[5] == 'h') || (line[8] == 'h')) { if (filePart == 1) { QStringList l = line.split(" "); Symbol* sym; if (line[0] == '$') { sym = new Symbol(l.at(1).trimmed(), l.at(0).right(4).toInt(0, 16)); } else if ((line[4] == 'h') || (line[5] == 'h')) { sym = new Symbol(l.at(1).trimmed(), l.at(0).mid(l.at(0).indexOf('h') - 4, 4).toInt(0, 16)); } else { QString m = l.at(0); QStringList n = m.split(":"); // n.at(0) = MegaROM page sym = new Symbol(l.at(1).trimmed(), n.at(1).left(4).toInt(0, 16)); } sym->setSource(&symbolFiles.back().fileName); add(sym); } else if (filePart == 2) { // } } } } return true; } bool SymbolTable::readLinkMapFile(const QString& filename) { const QString magic("Machine type"); const QString tableStart("*\tSymbol Table"); QRegExp rx(" [0-9A-Fa-f]{4} (?![ 0-9])"); QRegExp rp("^([^ ]+) +[^ ]* +([0-9A-Fa-f]{4}) $"); QFile file(filename); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { return false; } appendFile(filename, LINKMAP_FILE); QTextStream in(&file); if (in.atEnd()) return false; if (!in.readLine().startsWith(magic)) return false; while (true) { if (in.atEnd()) return false; if (in.readLine().startsWith(tableStart)) break; } while (!in.atEnd()) { QString line = in.readLine(); Q_ASSERT(!line.endsWith("\r")); if (line.isEmpty()) continue; line += " "; int len = line.length(); int l; int pos = 0; bool ok = false; // HiTech uses multiple columns of non-fixed width and // a column for psect may be blank so the address may in // the first or second match. for (int tries = 0; (tries < 2) && !ok; ++tries) { pos = rx.indexIn(line, pos); l = pos + rx.matchedLength(); if ((l > 0) && (len % l) == 0) { ok = true; for (int posn = pos + l; (posn < len) && ok; posn += l) { ok = (posn == rx.indexIn(line, posn)); } } pos = l - 1; } if (!ok) continue; for (pos = 0; pos < len; pos += l) { QString part = line.mid(pos, l); if (rp.indexIn(part) == 0) { QStringList l = rp.capturedTexts(); Symbol* sym = new Symbol(l.at(1), l.last().toInt(0, 16)); sym->setSource(&symbolFiles.back().fileName); add(sym); } } } return true; } void SymbolTable::fileChanged(const QString & /*path*/) { emit symbolFileChanged(); } void SymbolTable::reloadFiles() { for (int i = 0; i < symbolFiles.size(); ++i) { // check if file is newer QFileInfo fi = QFileInfo(symbolFiles[i].fileName); if (fi.lastModified() <= symbolFiles[i].refreshTime) continue; // file info QString name = symbolFiles[i].fileName; FileType type = symbolFiles[i].fileType; // symbol file is newer QMap symCopy; // copy all symbols originating from this file QMutableListIterator si(symbols); while (si.hasNext()) { si.next(); if (si.value()->source() == &symbolFiles[i].fileName) { symCopy.insert(si.value()->text(), Symbol(*si.value())); } } // remove existing file unloadFile(name); // read the new file readFile(name, type); // find old symbols in newly loaded file QMutableListIterator ni(symbols); QString* newFile = &symbolFiles.back().fileName; while (ni.hasNext()) { ni.next(); if (ni.value()->source() != newFile) continue; // find symbol in old list QMap::iterator sit = symCopy.find(ni.value()->text()); if (sit == symCopy.end()) continue; // symbol existed before, copy settings ni.value()->setValidSlots(sit->validSlots()); ni.value()->setValidRegisters(sit->validRegisters()); ni.value()->setType(sit->type()); if (sit->status() == Symbol::LOST) { ni.value()->setStatus(Symbol::ACTIVE); } else { ni.value()->setStatus(sit->status()); } symCopy.erase(sit); } // all symbols left in map are lost for (QMap::iterator sit = symCopy.begin(); sit != symCopy.end(); ++sit) { Symbol* sym = new Symbol(sit.value()); sym->setStatus(Symbol::LOST); sym->setSource(newFile); add(sym); } } } void SymbolTable::unloadFile(const QString& file, bool keepSymbols) { int index = -1; for (int i = 0; i < symbolFiles.size(); ++i) { if (symbolFiles[i].fileName == file) { index = i; break; } } if (index >= 0) { QString* name = &symbolFiles[index].fileName; if (!keepSymbols) { // remove symbols from address map QMutableMapIterator mi(addressSymbols); while (mi.hasNext()) { mi.next(); if (mi.value()->source() == name) mi.remove(); } // remove symbols from value hash QMutableHashIterator hi(valueSymbols); while (hi.hasNext()) { hi.next(); if (hi.value()->source() == name) hi.remove(); } } // remove symbols from value hash QMutableListIterator i(symbols); while (i.hasNext()) { i.next(); Symbol* sym = i.value(); if (sym->source() == name) { if (keepSymbols) { sym->setSource(0); } else { i.remove(); delete sym; } } } // remove record fileWatcher.removePath(symbolFiles[index].fileName); symbolFiles.removeAt(index); } } /* * Session loading/saving */ void SymbolTable::saveSymbols(QXmlStreamWriter& xml) { // write files QMap fileIds; for (int i = 0; i < symbolFiles.size(); ++i) { // add id mapping fileIds[&symbolFiles[i].fileName] = i; // write element xml.writeStartElement("SymbolFile"); switch (symbolFiles[i].fileType) { case TNIASM0_FILE: xml.writeAttribute("type","tniasm0"); break; case TNIASM1_FILE: xml.writeAttribute("type","tniasm1"); break; case ASMSX_FILE: xml.writeAttribute("type","asmsx"); break; case LINKMAP_FILE: xml.writeAttribute("type","linkmap"); break; default: break; } xml.writeAttribute("refreshTime", QString::number(symbolFiles[i].refreshTime.toTime_t())); xml.writeCharacters(symbolFiles[i].fileName); xml.writeEndElement(); } // write symbols for (QList::iterator sit = symbols.begin(); sit != symbols.end(); ++sit) { Symbol* sym = *sit; xml.writeStartElement("Symbol"); // status if (sym->status() == Symbol::HIDDEN) { xml.writeAttribute("status", "hidden"); } else if (sym->status() == Symbol::LOST) { xml.writeAttribute("status", "lost"); } // type if (sym->type() == Symbol::JUMPLABEL) { xml.writeTextElement("type", "jump"); } else if (sym->type() == Symbol::VARIABLELABEL) { xml.writeTextElement("type", "variable"); } else { xml.writeTextElement("type", "value"); } // text, value, slots and registers xml.writeTextElement("name", sym->text()); xml.writeTextElement("value", QString::number(sym->value())); xml.writeTextElement("validSlots", QString::number(sym->validSlots())); xml.writeTextElement("validRegisters", QString::number(sym->validRegisters())); // write source filename if (sym->source()) { xml.writeTextElement("source", QString::number(fileIds[sym->source()])); } // complete xml.writeEndElement(); } } void SymbolTable::loadSymbols(QXmlStreamReader& xml) { Symbol* sym; while (!xml.atEnd()) { xml.readNext(); // exit if closing of main tag if (xml.isEndElement() && xml.name() == "Symbols") break; // begin tag if (xml.isStartElement()) { if (xml.name() == "SymbolFile") { // read attributes and text QString ftype = xml.attributes().value("type").toString().toLower(); QString rtime = xml.attributes().value("refreshTime").toString(); QString fname = xml.readElementText(); // check type FileType type = TNIASM0_FILE; if (ftype == "tniasm1") { type = TNIASM1_FILE; } else if (ftype == "asmsx") { type = ASMSX_FILE; } else if (ftype == "linkmap") { type = LINKMAP_FILE; } // append file appendFile(fname, type); // change time symbolFiles.back().refreshTime.setTime_t(rtime.toUInt()); } else if (xml.name() == "Symbol") { // add empty symbol sym = new Symbol("", 0); add(sym); // get status attribute QString stat = xml.attributes().value("status").toString().toLower(); if (stat == "hidden") { sym->setStatus(Symbol::HIDDEN); } else if( stat == "lost" ) { sym->setStatus(Symbol::LOST); } } else if (xml.name() == "type") { // read symbol type element QString type = xml.readElementText().trimmed().toLower(); if (type == "jump") { sym->setType(Symbol::JUMPLABEL); } else if( type == "variable" ) { sym->setType(Symbol::VARIABLELABEL); } else if( type == "value" ) { sym->setType(Symbol::VALUE); } } else if (xml.name() == "name") { // read symbol name sym->setText(xml.readElementText()); } else if (xml.name() == "value") { // read symbol value sym->setValue(xml.readElementText().toInt()); } else if (xml.name() == "validSlots") { // read numeric valid slot mask sym->setValidSlots(xml.readElementText().toInt()); } else if (xml.name() == "validRegisters") { // read numeric valid registers mask sym->setValidRegisters(xml.readElementText().toInt()); } else if (xml.name() == "source") { // read source file id int id = xml.readElementText().toInt(); if (id >= 0 && id < symbolFiles.size()) { sym->setSource(&symbolFiles[id].fileName); } } } } } // class Symbol Symbol::Symbol(const QString& str, int addr, int val) : symText(str), symValue(addr), symSlots(val) { symStatus = ACTIVE; symType = JUMPLABEL; symSource = 0; if (addr & 0xFF00) { symRegisters = REG_ALL16; } else { symRegisters = REG_ALL; } table = 0; } Symbol::Symbol(const Symbol& symbol) { table = 0; symStatus = symbol.symStatus; symText = symbol.symText; symValue = symbol.symValue; symSlots = symbol.symSlots; symSegments = symbol.symSegments; symRegisters = symbol.symRegisters; symSource = symbol.symSource; symType = symbol.symType; } const QString& Symbol::text() const { return symText; } void Symbol::setText(const QString& str) { symText = str; } int Symbol::value() const { return symValue; } void Symbol::setValue(int addr) { if (addr == symValue) return; symValue = addr; if (table) table->symbolValueChanged(this); } int Symbol::validSlots() const { return symSlots; } void Symbol::setValidSlots(int val) { symSlots = val & 0xFFFF; } int Symbol::validRegisters() const { return symRegisters; } void Symbol::setValidRegisters(int regs) { symRegisters = regs; if (symValue & 0xFF00) { symRegisters &= REG_ALL16; } } const QString* Symbol::source() const { return symSource; } void Symbol::setSource(const QString* name) { symSource = name; } Symbol::SymbolStatus Symbol::status() const { return symStatus; } void Symbol::setStatus(SymbolStatus s) { symStatus = s; } Symbol::SymbolType Symbol::type() const { return symType; } void Symbol::setType(SymbolType t) { if (symType == t) return; symType = t; if (table) table->symbolTypeChanged(this); } bool Symbol::isSlotValid(const MemoryLayout* ml) const { if (!ml) return true; int page = symValue >> 14; int ps = ml->primarySlot[page] & 3; int ss = 0; if (ml->isSubslotted[page]) ss = ml->secondarySlot[page] & 3; if (symSlots & (1 << (4 * ps + ss))) { if (symSegments.empty()) return true; for (int i = 0; i < symSegments.size(); ++i) { if (ml->mapperSegment[page] == symSegments[i]) { return true; } } } return false; } openmsx-debugger-0.0.0.svn20141006.orig/src/Convert.cpp0000644000175000017500000000275212414415132021616 0ustar shevekshevek#include "Convert.h" #include "Settings.h" #include int stringToValue(const QString& str) { QString s = str.trimmed(); int base = 10; // find base (prefix or postfix) if (s.startsWith("&") && s.size() >= 2) { switch (s[1].toUpper().toLatin1()) { case 'H': base = 16; break; case 'B': base = 2; break; case 'O': base = 8; break; } s = s.remove(0, 2); } else if (s.startsWith("#") || s.startsWith("$")) { base = 16; s = s.remove(0, 1); } else if (s.startsWith("0x")) { base = 16; s = s.remove(0, 2); } else if (s.startsWith("%")) { base = 2; s = s.remove(0, 1); } else if (!s.isEmpty()) { switch (s.right(1)[0].toUpper().toLatin1()) { case 'H': case '#': base = 16; break; case 'B': base = 2; break; case 'O': base = 8; break; } if (base != 10) s.chop(1); } // convert value bool ok; int value = s.toInt(&ok, base); if (!ok) return -1; return value; } QString hexValue(int value, int width) { Settings& s = Settings::get(); return QString("%1%2%3").arg(s.value("Preferences/HexPrefix", "$").toString()) .arg(value, width, 16, QChar('0')) .arg(s.value("Preferences/HexPostfix", "").toString()); } QString& escapeXML(QString& str) { return str.replace('&', "&").replace('<', "<").replace('>', ">"); } QString& unescapeXML(QString& str) { return str.replace("&", "&").replace("<", "<").replace(">", ">"); } openmsx-debugger-0.0.0.svn20141006.orig/src/CPURegs.cpp0000644000175000017500000000126012414415132021437 0ustar shevekshevek// $Id: $ #include "CPURegs.h" const int CpuRegs::REG_AF = 0; const int CpuRegs::REG_AF2 = 1; const int CpuRegs::REG_BC = 2; const int CpuRegs::REG_BC2 = 3; const int CpuRegs::REG_DE = 4; const int CpuRegs::REG_DE2 = 5; const int CpuRegs::REG_HL = 6; const int CpuRegs::REG_HL2 = 7; const int CpuRegs::REG_IX = 8; const int CpuRegs::REG_IY = 9; const int CpuRegs::REG_PC = 10; const int CpuRegs::REG_SP = 11; const int CpuRegs::REG_I = 12; const int CpuRegs::REG_R = 13; const int CpuRegs::REG_IM = 14; const int CpuRegs::REG_IFF = 15; const char* const CpuRegs::regNames[14] = { "AF", "AF'", "BC", "BC'", "DE", "DE'", "HL", "HL'", "IX", "IY", "PC", "SP", "I", "R" }; openmsx-debugger-0.0.0.svn20141006.orig/src/VDPStatusRegisters.ui0000644000175000017500000026510312414415132023557 0ustar shevekshevek VDPStatusRegisters 0 0 516 324 Dialog 0 0 140 0 Status registers 10 20 121 271 0 0 Qt::Horizontal QSizePolicy::Expanding 5 5 Qt::Horizontal QSizePolicy::Expanding 5 5 0 0 S#0 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 Qt::StrongFocus Register Xrr FF 0 0 8 0 Qt::StrongFocus test 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 S#1 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 Qt::StrongFocus Register Xrr FF 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 S#2 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 Qt::StrongFocus Register Xrr FF 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 S#3 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 Qt::StrongFocus Register Xrr FF 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 S#4 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 Qt::StrongFocus Register Xrr FF 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 S#5 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 Qt::StrongFocus Register Xrr FF 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 S#6 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 Qt::StrongFocus Register Xrr FF 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 S#7 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 Qt::StrongFocus Register Xrr FF 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 S#8 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 Qt::StrongFocus Register Xrr FF 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 S#9 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 0 0 Qt::StrongFocus Register Xrr FF 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 0 0 8 0 Qt::StrongFocus 0 Qt::AlignCenter 345 300 Interpretation F: Vertical scanning interrupt flag When S#0 is read, this flag is reset. --- 5S: Flag for the fifth sprite Five sprites are aligned on the first horizontal line (In the G3 to G7 modes, 9 sprites are allowed) --- C: Collision flag Two sprites have collided. --- Fifth sprite number: The number of the fifth (or ninth) sprite. --- Qt::Horizontal 40 20 FL: Lightpen flag (Lightpen flag set) If the lightpen is to detect light, this bit as well as the IE2 bit must both set in order for an interrupt to be enabled. When S#1 is read, FL is reset. Mouse switch 2 (Mouse flag set) The second switch on the mouse was pressed. In this case, when S#1 is read, FL is not reset. --- LPS: Lightpen switch (Lightpen flag set) The lightpen switch was pressed. In this case, when S#1 is read, LPS is not reset. Mouse switch 1 (Mouse flag set) The first switch on the mouse was pressed. In this case, when S#1 is read, LPS is not reset. --- Identification number: The identification number (ID #) of the MSX-VIDEO. ( 0 if V9938, 1 if V9948, 2 if V9958) --- FH: Horizontal scanning interrupt flag Horizontal scanning interrupt (which is specified in R#19) flag. If IE1 is set, an interrupt is enabled. When S#1 is read, FH is reset. --- Qt::Horizontal 40 20 5 TR: Transfer ready flag When the CPU sends commands to the VRAM and other devices, the CPU checks this flag while transferring data. When this flag is set to 1, transfer may be done. --- VR: Vertical scanning line timing flag During vertical scanning, this flag is set to 1. --- HR: Horizontal scanning line timing flag During horizontal scanning, this flag is set to 1. --- BD: Boundary color detect flag When the search command is executed, this flag detects whether the boundary color was detected or not. --- EO: Display field flag When 0, indicates the first field. When 1, indicates the second field. --- CE: Command execution flag Indicates that a command is being executed. --- Qt::Horizontal 40 20 Column register Is set to indicate the collision location of sprites, the location of lightpen detection, and the relative movement of the mouse. --- Row register Is set to indicate the collision location of sprites, the location of lightpen detection, and the relative movement of the mouse. --- Color register The color register is used when the POINT and VRAM to CPU commands are executed. The VRAM data is set in this register. --- Border X register When the search command is executed and the border color has been detected, the X coordinate is set in the above registers. --- Qt::Vertical 20 40 InteractiveLabel QLabel
InteractiveLabel.h
openmsx-debugger-0.0.0.svn20141006.orig/src/VDPRegViewer.h0000644000175000017500000000257112414415132022113 0ustar shevekshevek#ifndef VDPREGVIEWER_H #define VDPREGVIEWER_H #include "SimpleHexRequest.h" #include "ui_VDPRegistersExplained.h" #include class InteractiveButton; /** See remarks for the highlightDispatcher in VDPStatusRegViewer.h :-) */ class buttonHighlightDispatcher : public QObject { Q_OBJECT public: buttonHighlightDispatcher(); public slots: void receiveState(bool state); signals: void dispatchState(bool state); private: int counter; }; class VDPRegViewer : public QDialog, public SimpleHexRequestUser, private Ui::VDPRegisters { Q_OBJECT public: VDPRegViewer(QWidget* parent = 0); ~VDPRegViewer(); private: void decodeVDPRegs(); void decodeStatusVDPRegs(); void setRegisterVisible(int r, bool visible); void connectHighLights(); void doConnect(InteractiveButton* lab, buttonHighlightDispatcher* dis); buttonHighlightDispatcher* makeGroup( QList, InteractiveLabel*); void reGroup(InteractiveButton*, buttonHighlightDispatcher*); void monoGroup(InteractiveButton*, InteractiveLabel*); virtual void DataHexRequestReceived(); unsigned char* regs; buttonHighlightDispatcher* modeBitsDispat; int vdpid; public slots: void refresh(); void registerBitChanged(int reg, int bit, bool state); //quick hack while no autodetection... void on_VDPcomboBox_currentIndexChanged(int index); }; #endif /* VDPSTATUSREGVIEWER_H */ openmsx-debugger-0.0.0.svn20141006.orig/src/DockableWidgetLayout.h0000644000175000017500000000372412414415132023711 0ustar shevekshevek// $Id$ #ifndef DOCKABLEWIDGETLAYOUT_H #define DOCKABLEWIDGETLAYOUT_H #include #include class QLayoutItem; class DockableWidget; class QStringList; class DockableWidgetLayout : public QLayout { Q_OBJECT; public: enum DockSide { TOP, LEFT, RIGHT, BOTTOM }; DockableWidgetLayout(QWidget* parent = 0, int margin = 0, int spacing = -1); DockableWidgetLayout(int spacing); ~DockableWidgetLayout(); void addItem(QLayoutItem* item); void addItem(QLayoutItem* item, int index, DockSide side = RIGHT, int dist = 0, int w = -1, int h = -1); void addWidget(DockableWidget* widget, const QRect& rect); void addWidget(DockableWidget* widget, DockSide side, int distance, int width = -1, int height = -1); bool insertLocation(QRect& rect, const QSizePolicy& sizePol); QLayoutItem* itemAt(int index) const; QLayoutItem* takeAt(int index); int count() const; Qt::Orientations expandingDirections() const; bool hasHeightForWidth() const; QSize minimumSize() const; QSize maximumSize() const; void setGeometry(const QRect &rect); QSize sizeHint() const; void changed(); void getConfig(QStringList& list); private: class DockInfo { public: QRect bounds() const { return QRect(left, top, width, height); } int right() const { return left + width; } int bottom() const { return top + height; } DockableWidget* widget; QLayoutItem* item; DockSide dockSide; int dockDistance; int left; int top; int width; int height; bool useHintHeight; bool useHintWidth; }; QList dockedWidgets; int layoutWidth, layoutHeight; int minWidth, minHeight; int maxWidth, maxHeight; int checkWidth, checkHeight; void calcSizeLimits(); void sizeMove(int dx, int dy); void doLayout(bool check = false); bool insertLocation(QRect& rect, int& index, DockSide& side, const QSizePolicy& sizePol); bool overlaysWithFirstNWidgets(const QRect& r, int n) const; }; #endif // DOCKABLEWIDGETLAYOUT_H openmsx-debugger-0.0.0.svn20141006.orig/src/DockableWidgetArea.h0000644000175000017500000000136112414415132023277 0ustar shevekshevek// $Id$ #ifndef DOCKABLETWIDGETAREA_H #define DOCKABLETWIDGETAREA_H #include "DockableWidgetLayout.h" #include class DockableWidget; class QPaintEvent; class DockableWidgetArea : public QWidget { Q_OBJECT; public: DockableWidgetArea(QWidget* parent = 0); private: void paintEvent(QPaintEvent* e); void removeWidget(DockableWidget* widget); void addWidget(DockableWidget* widget, const QRect& rect); void addWidget(DockableWidget* widget, DockableWidgetLayout::DockSide side, int distance, int width = -1, int height = -1); bool insertLocation(QRect& r, const QSizePolicy& sizePol); void getConfig(QStringList& list); DockableWidgetLayout* layout; friend class DockManager; }; #endif // DOCKABLETWIDGETAREA_H openmsx-debugger-0.0.0.svn20141006.orig/src/HexViewer.cpp0000644000175000017500000005003312414415132022077 0ustar shevekshevek// $Id$ #include "HexViewer.h" #include "OpenMSXConnection.h" #include "CommClient.h" #include "Settings.h" #include #include #include #include #include #include #include static const int EXTRA_SPACING = 4; class HexRequest : public ReadDebugBlockCommand { public: HexRequest(const QString& debuggable, unsigned offset_, unsigned size, unsigned char* target, HexViewer& viewer_) : ReadDebugBlockCommand(debuggable, offset_, size, target) , offset(offset_) , viewer(viewer_) { } virtual void replyOk(const QString& message) { copyData(message); viewer.hexdataTransfered(this); } virtual void cancel() { viewer.transferCancelled(this); } unsigned offset; private: HexViewer& viewer; }; HexViewer::HexViewer(QWidget* parent) : QFrame(parent) { setFrameStyle(WinPanel | Sunken); setFocusPolicy(Qt::StrongFocus); setBackgroundRole(QPalette::Base); setSizePolicy(QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Expanding)); horBytes = 16; hexTopAddress = 0; hexMarkAddress = 0; hexData = NULL; previousHexData = NULL; debuggableSize = 0; waitingForData = false; displayMode = FILL_WIDTH; highlitChanges = true; addressLength = 4; isEditable = false; isInteractive = false; beingEdited = false; editedChars = false; useMarker = false; hasFocus = false; vertScrollBar = new QScrollBar(Qt::Vertical, this); vertScrollBar->setMinimum(0); vertScrollBar->setSingleStep(1); frameL = frameT = frameB = frameWidth(); frameR = frameL + vertScrollBar->sizeHint().width(); settingsChanged(); createActions(); connect(vertScrollBar, SIGNAL(valueChanged(int)), this, SLOT(scrollBarChanged(int))); } HexViewer::~HexViewer() { delete[] hexData; delete[] previousHexData; } void HexViewer::createActions() { fillWidthAction = new QAction(tr("&Fill with"), this); fillWidthAction->setShortcut(tr("Ctrl+F")); fillWidthAction->setStatusTip(tr("Fill the width with as many bytes as possible.")); fillWidth2Action = new QAction(tr("Power of &2"), this); fillWidth2Action->setShortcut(tr("Ctrl+2")); fillWidth2Action->setStatusTip(tr("Fill the with with the maximum power of 2 possible.")); setWith8Action = new QAction(tr("&8 bytes."), this); setWith8Action->setShortcut(tr("Ctrl+8")); setWith8Action->setStatusTip(tr("Set width to 8 bytes.")); setWith16Action = new QAction(tr("&16 bytes."), this); setWith16Action->setShortcut(tr("Ctrl+6")); setWith16Action->setStatusTip(tr("Set width to 16 bytes.")); setWith32Action = new QAction(tr("&32 bytes."), this); setWith32Action->setShortcut(tr("Ctrl+3")); setWith32Action->setStatusTip(tr("Set width to 32 bytes.")); connect(fillWidthAction, SIGNAL(triggered()), this, SLOT(changeWidth())); connect(fillWidth2Action, SIGNAL(triggered()), this, SLOT(changeWidth())); connect(setWith8Action, SIGNAL(triggered()), this, SLOT(changeWidth())); connect(setWith16Action, SIGNAL(triggered()), this, SLOT(changeWidth())); connect(setWith32Action, SIGNAL(triggered()), this, SLOT(changeWidth())); addAction(fillWidthAction); addAction(fillWidth2Action); addAction(setWith8Action); addAction(setWith16Action); addAction(setWith32Action); setContextMenuPolicy(Qt::ActionsContextMenu); } void HexViewer::changeWidth() { if (sender() == fillWidthAction) setDisplayMode(FILL_WIDTH); else if (sender() == fillWidth2Action) setDisplayMode(FILL_WIDTH_POWEROF2); else if (sender() == setWith8Action) setDisplayWidth(8); else if (sender() == setWith16Action) setDisplayWidth(16); else if (sender() == setWith32Action) setDisplayWidth(32); } void HexViewer::setIsEditable(bool enabled) { isEditable = enabled; setUseMarker(true); } void HexViewer::setUseMarker(bool enabled) { useMarker = enabled; // below we should check if current marker is visible etc // but since in the debugger we will set this at instanciation // and then never change it again this is a quicky in case we do later on if (useMarker){ hexMarkAddress = hexTopAddress; } update(); } void HexViewer::setIsInteractive(bool enabled) { isInteractive = enabled; vertScrollBar->setEnabled(enabled); } void HexViewer::setDisplayMode(Mode mode) { displayMode = mode; setSizes(); } void HexViewer::setDisplayWidth(short width) { displayMode = FIXED; horBytes = width; setSizes(); } void HexViewer::settingsChanged() { QFontMetrics fm(Settings::get().font(Settings::HEX_FONT)); lineHeight = fm.height(); charWidth = fm.width("W"); hexCharWidth = fm.width("0ABCDEF") / 7; xAddr = frameL + 8; xData = xAddr + addressLength * hexCharWidth + charWidth; dataWidth = 3 * hexCharWidth; setSizes(); } void HexViewer::setSizes() { visibleLines = (height() - frameT - frameB) / lineHeight; partialBottomLine = (height() - frameT - frameB) != lineHeight * visibleLines; frameR = frameL; int w; // fit display to width if (displayMode != FIXED) { // scrollbar width int sbw = vertScrollBar->sizeHint().width(); horBytes = 1; int hb2 = 1; w = width() - frameL - frameR - xData - dataWidth - 2 * charWidth - 8; // calculate how many additional bytes can by displayed while (w-sbw >= dataWidth + charWidth) { ++horBytes; if( horBytes == 2*hb2 ) hb2 = horBytes; w -= dataWidth + charWidth; if ((horBytes & 3) == 0) w -= EXTRA_SPACING; if ((horBytes & 7) == 0) w -= EXTRA_SPACING; // remove scrollbar if (horBytes * visibleLines >= debuggableSize) sbw = 0; } // limit to power of two if needed if (displayMode == FILL_WIDTH_POWEROF2) horBytes = hb2; } // check if a scrollbar is needed if (horBytes * visibleLines < debuggableSize) { int maxLine = int(ceil(double(debuggableSize) / horBytes)) - visibleLines; maxLine = std::max(maxLine, 0); vertScrollBar->setMaximum(maxLine); vertScrollBar->setPageStep(visibleLines); frameR += vertScrollBar->sizeHint().width(); vertScrollBar->setGeometry(width() - frameR, frameT, vertScrollBar->sizeHint().width(), height() - frameT - frameB); vertScrollBar->show(); } else { vertScrollBar->hide(); hexTopAddress = 0; hexMarkAddress = 0; } // now see were the chars are drawn rightValuePos = xData + horBytes * dataWidth; xChar = rightValuePos + charWidth + EXTRA_SPACING * (int(horBytes / 4) + int(horBytes / 8)); rightCharPos = xChar + horBytes * charWidth; if (isEnabled()) { ///vertScrollBar->setValue(hexTopAddress / horBytes); setTopLocation(horBytes * int(hexTopAddress / horBytes)); } else { update(); } } QSize HexViewer::sizeHint() const { return QSize(frameL + 16 + (6 + 3 * horBytes / 2) * fontMetrics().width("A") + frameR, frameT + 10 * fontMetrics().height() + frameB ); } void HexViewer::resizeEvent(QResizeEvent* e) { QFrame::resizeEvent(e); setSizes(); } void HexViewer::wheelEvent(QWheelEvent* e) { int v = vertScrollBar->value() - e->delta() / 40; vertScrollBar->setValue(v); e->accept(); } void HexViewer::paintEvent(QPaintEvent* e) { // call parent for drawing the actual frame QFrame::paintEvent(e); // exit if no debuggable is set if (debuggableName.isEmpty()) return; QPainter p(this); // set font info p.setFont(Settings::get().font(Settings::HEX_FONT)); QColor fc(Settings::get().fontColor(Settings::HEX_FONT)); int a = p.fontMetrics().ascent(); p.setPen(fc); // calc and set drawing bounds QRect r(e->rect()); if (r.left() < frameL) r.setLeft(frameL); if (r.top() < frameT) r.setTop (frameT); if (r.right() > width() - frameR - 1) r.setRight (width() - frameR - 1); if (r.bottom() > height() - frameB - 1) r.setBottom(height() - frameB - 1); p.setClipRect(r); // redraw background p.fillRect(r, palette().color(QPalette::Base)); int y = frameT; int address = hexTopAddress; for (int i = 0; i < visibleLines+partialBottomLine; ++i) { // print address QString hexStr = QString("%1").arg(address, addressLength, 16, QChar('0')); p.setPen(palette().color(QPalette::Text)); p.drawText(xAddr, y + a, hexStr.toUpper()); // print bytes int x = xData; for (int j = 0; j < horBytes; ++j) { // print data if (address + j < debuggableSize) { hexStr.sprintf("%02X", hexData[address + j]); // draw marker if needed if (useMarker || beingEdited) { QRect b(x, y, dataWidth, lineHeight); if ((address + j) == hexMarkAddress) { p.fillRect(b, hasFocus ? Qt::cyan : Qt::lightGray); } // are we being edited ?? if (hasFocus && isEditable && !editedChars && ((address + j) == hexMarkAddress)) { if (beingEdited) { p.fillRect(b, Qt::darkGreen); if (cursorPosition) { hexStr.sprintf("%2X", editValue); } } else { p.drawRect(b); } } } // determine value colour if (highlitChanges) { QColor penClr = palette().color(QPalette::Text); if (hexData[address + j] != previousHexData[address + j]) { if ((address + j) != hexMarkAddress || !beingEdited) { penClr = Qt::red; } } if (((address + j) == hexMarkAddress ) && beingEdited && (cursorPosition == 0)) { penClr = Qt::white; } p.setPen(penClr); } p.drawText(x, y + a, hexStr); } x += dataWidth; // at extra spacing if ((j & 3) == 3) x += EXTRA_SPACING; if ((j & 7) == 7) x += EXTRA_SPACING; } // print characters x += charWidth; for (int j = 0; j < horBytes; ++j) { if (address + j >= debuggableSize) break; unsigned char chr = hexData[address + j]; if (chr < 32 || chr > 127) chr = '.'; // draw marker if needed if (useMarker || beingEdited) { QRect b(x, y, charWidth, lineHeight); if ((address + j) == hexMarkAddress) { p.fillRect(b, hasFocus ? Qt::cyan : Qt::lightGray); } // are we being edited ?? if (hasFocus && isEditable && editedChars && ((address + j) == hexMarkAddress)) { if (beingEdited) { p.fillRect(b, Qt::darkGreen); } else { p.drawRect(b); } } } // determine value colour if (highlitChanges) { QColor penClr = palette().color(QPalette::Text); if (hexData[address + j] != previousHexData[address + j]) { penClr = Qt::red; } if (((address + j) == hexMarkAddress ) && beingEdited && (cursorPosition == 0)) { penClr = Qt::white; } p.setPen(penClr); } p.drawText(x, y + a, QString(chr)); x += charWidth; } y += lineHeight; address += horBytes; if (address >= debuggableSize) break; } // copy the new values to the old-values buffer memcpy(previousHexData, hexData, debuggableSize); } void HexViewer::setDebuggable(const QString& name, int size) { delete[] hexData; hexData = NULL; delete[] previousHexData; previousHexData = NULL; if (size) { debuggableName = name; debuggableSize = size; addressLength = 2 * int(ceil(log(double(size)) / log(2.0) / 8)); hexTopAddress = 0; hexMarkAddress = 0; hexData = new unsigned char[size]; memset(hexData, 0, size); previousHexData = new unsigned char[size]; memset(previousHexData, 0, size); settingsChanged(); } else { debuggableName.clear(); debuggableSize = 0; } } void HexViewer::scrollBarChanged(int addr) { int start = addr * horBytes; if (start == hexTopAddress) { // nothing changed or a callback since we changed the value to // the current hexTopAddress return; } if (!useMarker) { setTopLocation(addr * horBytes); emit locationChanged(addr * horBytes); } else { //maybe marker is still "fully" visible? int size = horBytes * visibleLines; hexTopAddress = start; if ((start > hexMarkAddress) || ((start + size -1) < hexMarkAddress)) { hexMarkAddress = (hexMarkAddress % horBytes) + ((start < hexMarkAddress) ? size - horBytes : 0); hexMarkAddress += start; emit locationChanged(hexMarkAddress); } refresh(); } } void HexViewer::setLocation(int addr) { if (!useMarker) { setTopLocation(addr); } else { // check if newmarker is in fully visible lines, // if so we do not change hexTopAddress if (addr != hexMarkAddress) { emit locationChanged(addr); } hexMarkAddress = addr; int size = horBytes * visibleLines; if ((addr < hexTopAddress) || (addr >= (hexTopAddress+size))) { setTopLocation(addr); } refresh(); } } void HexViewer::setTopLocation(int addr) { if (debuggableName.isEmpty()) { return; } int start = horBytes * int(addr / horBytes); if (!waitingForData || (start != hexTopAddress)) { hexTopAddress = start; refresh(); } } void HexViewer::hexdataTransfered(HexRequest* r) { transferCancelled(r); update(); } void HexViewer::transferCancelled(HexRequest* r) { delete r; waitingForData = false; // check whether a new value is available if (int(hexTopAddress / horBytes) != vertScrollBar->value()) { vertScrollBar->setValue(hexTopAddress / horBytes); } } void HexViewer::refresh() { // calculate data request int size = horBytes * (visibleLines + partialBottomLine); size = std::min(size, debuggableSize - hexTopAddress); // send data request HexRequest* req = new HexRequest( debuggableName, hexTopAddress, size, hexData + hexTopAddress, *this); CommClient::instance().sendCommand(req); waitingForData = true; } void HexViewer::keyPressEvent(QKeyEvent* e) { // don't hanlde if not interactive if ((!beingEdited && !useMarker) || !isInteractive) { QFrame::keyPressEvent(e); return; } bool setValue = false; int newAddress = hexMarkAddress; // entering a new digit ? // for now hex only, do we need decimal entry also ?? if (!editedChars && ((e->key() >= Qt::Key_0 && e->key() <= Qt::Key_9) || (e->key() >= Qt::Key_A && e->key() <= Qt::Key_F))) { // calculate numercial value int v = e->key() - Qt::Key_0; if (v > 9) v -= Qt::Key_A - Qt::Key_0 - 10; if (beingEdited) { editValue = (editValue << 4) + v; ++cursorPosition; if (cursorPosition == 2){ setValue = true; ++newAddress; } } else { editValue = v; beingEdited = true; cursorPosition = 1; } } else if (useMarker && e->key() == Qt::Key_Right) { setValue = beingEdited & !editedChars; ++newAddress; cursorPosition = 0; } else if (useMarker && e->key() == Qt::Key_Left) { setValue = beingEdited & !editedChars; --newAddress; cursorPosition = 0; } else if (useMarker && e->key() == Qt::Key_Up) { setValue = beingEdited & !editedChars; newAddress -= horBytes; cursorPosition = 0; } else if (useMarker && e->key() == Qt::Key_Down) { setValue = beingEdited & !editedChars; newAddress += horBytes; cursorPosition = 0; } else if (useMarker && e->key() == Qt::Key_Home) { setValue = beingEdited & !editedChars; newAddress = 0; cursorPosition = 0; } else if (useMarker && e->key() == Qt::Key_PageUp) { setValue = beingEdited & !editedChars; hexTopAddress -= horBytes * visibleLines; newAddress -= horBytes * visibleLines; cursorPosition = 0; } else if (useMarker && e->key() == Qt::Key_PageDown) { setValue = beingEdited & !editedChars; hexTopAddress += horBytes * visibleLines; newAddress += horBytes * visibleLines; cursorPosition = 0; } else if (useMarker && e->key() == Qt::Key_End) { setValue = beingEdited & !editedChars; newAddress = debuggableSize - 1; cursorPosition = 0; } else if (useMarker && e->key() == Qt::Key_Backspace) { editedChars = !editedChars; } else if (!editedChars && (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter)) { setValue = true; } else if (e->key() == Qt::Key_Shift || e->key() == Qt::Key_Control || e->key() == Qt::Key_Meta || e->key() == Qt::Key_Alt || e->key() == Qt::Key_AltGr || e->key() == Qt::Key_CapsLock || e->key() == Qt::Key_NumLock || e->key() == Qt::Key_ScrollLock) { // do nothing for these keys if editing chars // if not editing chars they do nothing by deafult :-) } else if (e->key() == Qt::Key_Escape) { beingEdited = false; e->accept(); update(); return; } else if (editedChars) { editValue = (e->text().toLatin1())[0]; setValue = true; ++newAddress; } else { QFrame::keyPressEvent(e); return; } //apply changes if (setValue) { //TODO actually write the values to openMSX memory //for now we change the value in our local buffer previousHexData[hexMarkAddress] = char(editValue); WriteDebugBlockCommand* req = new WriteDebugBlockCommand( debuggableName, hexMarkAddress, 1, previousHexData); CommClient::instance().sendCommand(req); editValue = 0; cursorPosition = 0; beingEdited = editedChars; // keep editing if we were inputing chars refresh(); } // indicate key Event handled e->accept(); // Move Marker if needed if ((editedChars || useMarker) && (hexMarkAddress != newAddress)) { if (newAddress < 0) newAddress += debuggableSize; if (newAddress >= debuggableSize) newAddress -= debuggableSize; // influencing hexTopAddress during Key_PageUp/Down might need following 2 lines. if (hexTopAddress < 0) hexTopAddress += debuggableSize; if (hexTopAddress >= debuggableSize) hexTopAddress -= debuggableSize; // Make scrolling downwards using cursors more "intuitive" int addr = hexTopAddress + horBytes * visibleLines; if ((newAddress >= addr) && (newAddress <= (addr + horBytes))) { hexTopAddress += horBytes; } if (useMarker) { setLocation(newAddress); } else { //we can only get here when not using Markers but if we //are typing in chars in charEdit mode, so scrolling //one line is covered in code above hexMarkAddress = newAddress; refresh(); } } else { update(); } } int HexViewer::coorToOffset(int x, int y) { int offset = -1; if (x >= xData && x < rightValuePos) { offset = 0; x -= xData; while (x > 4*dataWidth) { offset += 4; x -= 4*dataWidth + EXTRA_SPACING; if (offset % 8 == 0) x -= EXTRA_SPACING; } offset += x / dataWidth; } else if (x >= xChar && x < rightCharPos) { offset = (x - xChar) / charWidth; } int yMaxOffset = frameT + (visibleLines+partialBottomLine) * lineHeight; if (offset >= 0 && y < yMaxOffset) { offset += horBytes * ((y - frameT) / lineHeight); } return offset; } bool HexViewer::event(QEvent* e) { if (e->type() != QEvent::ToolTip) { return QWidget::event(e); } // calculate address for tooltip QHelpEvent* helpEvent = static_cast(e); int offset = coorToOffset(helpEvent->x(), helpEvent->y()); if (offset >= 0 && (hexTopAddress + offset) < debuggableSize) { // create text with binary and decimal values int address = hexTopAddress + offset; unsigned char chr = hexData[address]; QString text = QString("Address: %1").arg(address, addressLength, 16, QChar('0')); // print 8 bit values text += "\nBinary: "; text += QString("%1 ").arg(chr >> 4, 4, 2, QChar('0')); text += QString("%1") .arg(chr & 0x000F, 4, 2, QChar('0')); text += "\nDecimal: "; text += QString::number(chr); // print 16 bit values if possible if ((address + 1) < debuggableSize) { unsigned int wd = chr; wd += 256 * hexData[address + 1]; text += QString("\n\nWord: %1").arg(wd, 4, 16, QChar('0')); text += "\nBinary: "; text += QString("%1 ").arg((wd & 0xF000) >> 12, 4, 2, QChar('0')); text += QString("%1 ").arg((wd & 0x0F00) >> 8, 4, 2, QChar('0')); text += QString("%1 ").arg((wd & 0x00F0) >> 4, 4, 2, QChar('0')); text += QString("%1 ").arg((wd & 0x000F) >> 0, 4, 2, QChar('0')); text += "\nDecimal: "; text += QString::number(wd); } QToolTip::showText(helpEvent->globalPos(), text); } else { QToolTip::hideText(); } return QWidget::event(e); } void HexViewer::mousePressEvent(QMouseEvent* e) { if (e->button() == Qt::LeftButton && isInteractive) { int offset=coorToOffset(e->x(), e->y()); if (offset >= 0) { int addr = hexTopAddress + offset; if (useMarker && (hexMarkAddress != addr)) { setLocation(addr); } else { if (!useMarker) hexMarkAddress = addr; editValue = 0; cursorPosition = 0; beingEdited = isEditable; } editedChars = (e->x() >= xChar); } update(); } } void HexViewer::focusInEvent(QFocusEvent* e) { hasFocus = true; update(); } void HexViewer::focusOutEvent(QFocusEvent* e) { if (e->lostFocus()) { editValue = 0; cursorPosition = 0; beingEdited = false; hasFocus = false; } update(); } openmsx-debugger-0.0.0.svn20141006.orig/src/HexViewer.h0000644000175000017500000000377612414415132021560 0ustar shevekshevek// $Id$ #ifndef HEXVIEWER_H #define HEXVIEWER_H #include class HexRequest; class QScrollBar; class QPaintEvent; class HexViewer : public QFrame { Q_OBJECT public: HexViewer(QWidget* parent = 0); ~HexViewer(); enum Mode { FIXED, FILL_WIDTH, FILL_WIDTH_POWEROF2 }; void setDebuggable(const QString& name, int size); void setIsInteractive(bool enabled); void setUseMarker(bool enabled); void setIsEditable(bool enabled); void setDisplayMode(Mode mode); void setDisplayWidth(short width); QSize sizeHint() const; public slots: void setLocation(int addr); void setTopLocation(int addr); void scrollBarChanged(int addr); void settingsChanged(); void refresh(); private: void wheelEvent(QWheelEvent* e); void resizeEvent(QResizeEvent* e); void paintEvent(QPaintEvent* e); void mousePressEvent(QMouseEvent* e); bool event(QEvent* e); void keyPressEvent(QKeyEvent* e); void focusInEvent(QFocusEvent* e); void focusOutEvent(QFocusEvent* e); void createActions(); void setSizes(); void hexdataTransfered(HexRequest* r); void transferCancelled(HexRequest* r); int coorToOffset(int x, int y); QScrollBar* vertScrollBar; QAction *fillWidthAction; QAction *fillWidth2Action; QAction *setWith8Action; QAction *setWith16Action; QAction *setWith32Action; // layout int frameL, frameR, frameT, frameB; int leftCharPos, leftValuePos, rightValuePos, rightCharPos; Mode displayMode; short horBytes; int visibleLines, partialBottomLine; int lineHeight, xAddr, xData, xChar, dataWidth, charWidth, hexCharWidth; int addressLength; // data QString debuggableName; int debuggableSize; int hexTopAddress; int hexMarkAddress; unsigned char* hexData; unsigned char* previousHexData; bool waitingForData; bool highlitChanges; bool useMarker; bool isInteractive; bool isEditable; bool beingEdited; bool editedChars; bool hasFocus; int cursorPosition,editValue; friend class HexRequest; private slots: void changeWidth(); signals: void locationChanged(int addr); }; #endif // HEXVIEWER_H openmsx-debugger-0.0.0.svn20141006.orig/src/DasmTables.h0000644000175000017500000000045012414415132021653 0ustar shevekshevek// $Id$ #ifndef DASMTABLES_H #define DASMTABLES_H extern const char* const mnemonic_xx_cb[256]; extern const char* const mnemonic_cb[256]; extern const char* const mnemonic_ed[256]; extern const char* const mnemonic_xx[256]; extern const char* const mnemonic_main[256]; #endif // DASMTABLES_H openmsx-debugger-0.0.0.svn20141006.orig/src/BreakpointDialog.cpp0000644000175000017500000002147212414415132023414 0ustar shevekshevek#include "BreakpointDialog.h" #include "DebugSession.h" #include "Convert.h" #include #include BreakpointDialog::BreakpointDialog(const MemoryLayout& ml, DebugSession *session, QWidget* parent) : QDialog(parent), memLayout(ml), currentSymbol(0) { setupUi(this); value = valueEnd = -1; debugSession = session; if( session ) { // create address completer jumpCompleter = new QCompleter(session->symbolTable().labelList(), this); allCompleter = new QCompleter(session->symbolTable().labelList(true), this); jumpCompleter->setCaseSensitivity(Qt::CaseInsensitive); allCompleter->setCaseSensitivity(Qt::CaseInsensitive); connect(jumpCompleter, SIGNAL(activated(const QString&)), this, SLOT(addressChanged(const QString&))); connect(allCompleter, SIGNAL(activated(const QString&)), this, SLOT(addressChanged(const QString&))); } connect(edtAddress, SIGNAL(textEdited(const QString&)), this, SLOT(addressChanged(const QString&))); connect(edtAddressRange, SIGNAL(textEdited(const QString&)), this, SLOT(addressChanged(const QString&))); connect(cmbxType, SIGNAL(activated(int)), this, SLOT(typeChanged(int))); connect(cmbxSlot, SIGNAL(activated(int)), this, SLOT(slotChanged(int))); connect(cmbxSubslot, SIGNAL(activated(int)), this, SLOT(subslotChanged(int))); connect(cbCondition, SIGNAL(stateChanged(int)), this, SLOT(hasCondition(int))); typeChanged(0); slotChanged(0); idxSlot = idxSubSlot = 0; hasCondition(0); } BreakpointDialog::~BreakpointDialog() { delete jumpCompleter; delete allCompleter; } Breakpoints::Type BreakpointDialog::type() { return Breakpoints::Type(cmbxType->currentIndex()); } int BreakpointDialog::address() { return value; } int BreakpointDialog::addressEndRange() { if (valueEnd < value) return value; else return valueEnd; } int BreakpointDialog::slot() { return cmbxSlot->currentIndex() - 1; } int BreakpointDialog::subslot() { return cmbxSubslot->currentIndex() - 1; } int BreakpointDialog::segment() { return cmbxSegment->currentIndex() - 1; } QString BreakpointDialog::condition() { if( cbCondition->checkState() == Qt::Checked ) return txtCondition->toPlainText(); else return QString(); } void BreakpointDialog::setData(Breakpoints::Type type, int address, int ps, int ss, int segment, int addressEnd, QString condition) { // set type cmbxType->setCurrentIndex(int(type)); typeChanged(cmbxType->currentIndex()); // set address if (address >= 0) { edtAddress->setText( hexValue(address) ); addressChanged(edtAddress->text()); } // primary slot if (cmbxSlot->isEnabled() && ps >= 0) { cmbxSlot->setCurrentIndex(ps+1); slotChanged(cmbxSlot->currentIndex()); } // secondary slot if (cmbxSubslot->isEnabled() && ss >= 0) { cmbxSubslot->setCurrentIndex(ss+1); subslotChanged(cmbxSubslot->currentIndex()); } // segment if (cmbxSegment->isEnabled() && segment >= 0) { cmbxSegment->setCurrentIndex(segment+1); } // end address if (edtAddressRange->isEnabled() && addressEnd >= 0) { edtAddressRange->setText( hexValue(addressEnd) ); addressChanged(edtAddressRange->text()); } // condition condition = condition.trimmed(); if (cbCondition->isChecked() == condition.isEmpty()) cbCondition->setChecked(!condition.isEmpty()); txtCondition->setText(condition); } void BreakpointDialog::addressChanged(const QString& text) { // determine source QLineEdit *ed; if (text == edtAddress->text()) ed = edtAddress; else ed = edtAddressRange; bool first = ed == edtAddress; // convert value int v = stringToValue(text); if (v == -1 && debugSession) { Symbol *s = debugSession->symbolTable().getAddressSymbol(text); if (s) v = s->value(); if (first) currentSymbol = s; } // assign address if (first) value = v; else { if (v > value) valueEnd = v; else { valueEnd = -1; v = -1; } } // adjust controls for (in)correct values QStandardItemModel* model = qobject_cast(cmbxSlot->model()); QPalette pal; if (v == -1) { // set line edit text to red for invalid values TODO: make configurable pal.setColor(QPalette::Normal, QPalette::Text, Qt::red); ed->setPalette(pal); if (first) { cmbxSlot->setCurrentIndex(0); cmbxSlot->setEnabled(false); } } else { //pal.setColor(QPalette::Normal, QPalette::Text, Qt::black); ed->setPalette(pal); if (!first) return; cmbxSlot->setEnabled(true); if(currentSymbol) { // enable allowed slots int s = currentSymbol->validSlots(); int num = 0, last = 0; for(int i = 4; i >= 0; i--) { QModelIndex index = model->index(i, 0, cmbxSlot->rootModelIndex()); if(i) { bool ena = (s & (15<<(4*(i-1)))) != 0; model->itemFromIndex(index)->setEnabled(ena); if(ena) { num++; last = i; } } else { model->itemFromIndex(index)->setEnabled( num == 4 ); if(num == 4) last = 0; } } cmbxSlot->setCurrentIndex(last); } else { // enable everything for(int i = 0; i < 5; i++) { QModelIndex index = model->index(i, 0, cmbxSlot->rootModelIndex()); model->itemFromIndex(index)->setEnabled(true); } cmbxSlot->setCurrentIndex(idxSlot); } } slotChanged(cmbxSlot->currentIndex()); } void BreakpointDialog::typeChanged(int s) { switch(s) { case 1: case 2: lblAddress->setText(tr("Add watchpoint at memory address or range:")); edtAddressRange->setVisible(true); edtAddress->setCompleter(allCompleter); edtAddressRange->setCompleter(allCompleter); break; case 3: case 4: lblAddress->setText(tr("Add watchpoint on IO port or range:")); edtAddressRange->setVisible(true); edtAddress->setCompleter(0); edtAddressRange->setCompleter(0); break; default: lblAddress->setText(tr("Add breakpoint at address:")); edtAddressRange->setVisible(false); edtAddress->setCompleter(jumpCompleter); } switch(s) { case 1: case 2: lblInSlot->setText(tr("With address in")); break; default: lblInSlot->setText(tr("With PC in")); } if(s == 5) { lblAddress->setEnabled(false); edtAddress->setEnabled(false); lblSlot->setEnabled(false); lblSubslot->setEnabled(false); lblSegment->setEnabled(false); cmbxSlot->setEnabled(false); cmbxSubslot->setEnabled(false); cmbxSegment->setEnabled(false); cbCondition->setCheckState(Qt::Checked); cbCondition->setEnabled(false); } else { lblAddress->setEnabled(true); edtAddress->setEnabled(true); lblSlot->setEnabled(true); lblSubslot->setEnabled(true); lblSegment->setEnabled(true); addressChanged(edtAddress->text()); cbCondition->setEnabled(true); cbCondition->setCheckState( txtCondition->toPlainText().isEmpty() ? Qt::Unchecked : Qt::Checked ); } } void BreakpointDialog::slotChanged(int s) { if(!currentSymbol) idxSlot = s; if (s && memLayout.isSubslotted[s - 1]) { if(currentSymbol) { // enable subslots int v = (currentSymbol->validSlots() >> (4*(s-1))) & 15; int num = 0, last = 0; QStandardItemModel* model = qobject_cast(cmbxSubslot->model()); for(int i = 4; i >= 0; i--) { QModelIndex index = model->index(i, 0, cmbxSubslot->rootModelIndex()); if(i) { bool ena = (v & (1<<(i-1))) != 0; model->itemFromIndex(index)->setEnabled(ena); if(ena) { num++; last = i; } } else { model->itemFromIndex(index)->setEnabled( num == 4 ); if(num == 4) last = 0; } } cmbxSubslot->setCurrentIndex(last); } else { cmbxSubslot->setCurrentIndex(idxSubSlot); } cmbxSubslot->setEnabled(true); } else { cmbxSubslot->setEnabled(false); cmbxSubslot->setCurrentIndex(0); } subslotChanged(cmbxSubslot->currentIndex()); } void BreakpointDialog::subslotChanged(int i) { if(!currentSymbol) idxSubSlot = i; int oldseg = cmbxSegment->currentIndex()-1; cmbxSegment->clear(); cmbxSegment->addItem("any"); int ps = cmbxSlot->currentIndex() - 1; int ss = i - 1; if (ps >=0 && !memLayout.isSubslotted[ps]) ss = 0; int mapsize; if (ps < 0 || ss < 0 || memLayout.mapperSize[ps][ss] == 0) { // no memory mapper, maybe rom mapper? if (value >= 0 && memLayout.romBlock[((value & 0xE000)>>13)] >= 0) { mapsize = 256; // TODO: determine real size } else { cmbxSegment->setEnabled(false); cmbxSegment->setCurrentIndex(0); return; } } else mapsize = memLayout.mapperSize[ps][ss]; for (int s = 0; s < mapsize; ++s) { cmbxSegment->addItem(QString("%1").arg(s)); } cmbxSegment->setEnabled(true); if (oldseg >= 0 && oldseg < mapsize) cmbxSegment->setCurrentIndex(oldseg+1); } void BreakpointDialog::hasCondition(int state) { if( state == Qt::Checked ) { txtCondition->setVisible(true); layout()->setSizeConstraint(QLayout::SetDefaultConstraint); resize( width(), conditionHeight ); } else { conditionHeight = height(); txtCondition->setVisible(false); resize( width(), sizeHint().height() ); layout()->setSizeConstraint(QLayout::SetMaximumSize); } } openmsx-debugger-0.0.0.svn20141006.orig/src/SimpleHexRequest.cpp0000644000175000017500000000202412414415132023435 0ustar shevekshevek#include "SimpleHexRequest.h" #include "CommClient.h" // class SimpleHexRequest SimpleHexRequest::SimpleHexRequest( const QString& debuggable, unsigned size, unsigned char* target, SimpleHexRequestUser& user_) : ReadDebugBlockCommand(debuggable, size, target) , offset(0) , user(user_) { CommClient::instance().sendCommand(this); } SimpleHexRequest::SimpleHexRequest( const QString& debuggable, unsigned offset_, unsigned size, unsigned char* target, SimpleHexRequestUser& user_) : ReadDebugBlockCommand(debuggable, offset_, size, target) , offset(offset_) , user(user_) { CommClient::instance().sendCommand(this); } void SimpleHexRequest::replyOk(const QString& message) { copyData(message); user.DataHexRequestReceived(); delete this; } void SimpleHexRequest::cancel() { user.DataHexRequestCanceled(); delete this; } // class SimpleHexRequestUser SimpleHexRequestUser::~SimpleHexRequestUser() { } void SimpleHexRequestUser::DataHexRequestReceived() { } void SimpleHexRequestUser::DataHexRequestCanceled() { } openmsx-debugger-0.0.0.svn20141006.orig/src/VDPStatusRegViewer.h0000644000175000017500000000323612414415132023316 0ustar shevekshevek#ifndef VDPSTATUSREGVIEWER_H #define VDPSTATUSREGVIEWER_H #include "SimpleHexRequest.h" #include "ui_VDPStatusRegisters.h" #include #include /** The highlightDispatcher serves 2 purposes for the InteractiveLabel widgets * a) keep a correct state: Assume widget A and B are related (both are * highlighted at the same time) and they are touching each other. I don't * think that there is a garuanteed order in the enterEvent,leaveEvent, so if * we use the MouseOver signal to connect to the highlight slots of A and B * then this sequence might arise if our mouse moves from A to B and produce * a wrong result: * B.mouseOver(true); A.mouseOver(false) -> highlights are false for both A and B. * * b) serve as a central hub (star toplogy) to dispatch events from one widget * to all others. This way all InteractiveLabel widgets only need to connect * to this highlightDispatcher */ class highlightDispatcher : public QObject { Q_OBJECT public: highlightDispatcher(); public slots: void receiveState(bool state); signals: void dispatchState(bool state); private: int counter; }; class VDPStatusRegViewer : public QDialog, public SimpleHexRequestUser, private Ui::VDPStatusRegisters { Q_OBJECT public: VDPStatusRegViewer(QWidget* parent = 0); ~VDPStatusRegViewer(); public slots: void refresh(); private: void decodeVDPStatusRegs(); void connectHighLights(); void doConnect(InteractiveLabel* lab, highlightDispatcher* dis); void makeGroup(QList list, InteractiveLabel* explained); virtual void DataHexRequestReceived(); unsigned char* statusregs; }; #endif // VDPSTATUSREGVIEWER_H openmsx-debugger-0.0.0.svn20141006.orig/src/SymbolTable.h0000644000175000017500000001031512414415132022052 0ustar shevekshevek// $Id$ #ifndef SYMBOLTABLE_H #define SYMBOLTABLE_H #include #include #include #include #include #include #include #include struct MemoryLayout; class SymbolTable; class Symbol { public: Symbol(const QString& str, int addr, int val = 0xFFFF); Symbol(const Symbol& symbol); // ACTIVE status is for regular symbols. HIDDEN is for symbols // that are in the list but not shown anywhere. LOST is a special // status for symbols that were once loaded from a symbol file, but // weren't found later. These aren't deleted immediately because // the possible custom settings would be lost even if the reload // was of a bad file (after a failed assembler run for instance). enum SymbolStatus { ACTIVE, HIDDEN, LOST }; enum SymbolType { JUMPLABEL, VARIABLELABEL, VALUE }; enum Register { REG_A = 1, REG_B = 2, REG_C = 4, REG_D = 8, REG_E = 16, REG_H = 32, REG_L = 64, REG_BC = 128, REG_DE = 256, REG_HL = 512, REG_IX = 1024, REG_IY = 2048, REG_IXL = 4096, REG_IXH = 8192, REG_IYL = 16384, REG_IYH = 32768, REG_OFFSET = 65536, REG_I = 131072, REG_ALL8 = 1+2+4+8+16+32+64+4096+8192+16384+32768+65536+131072, REG_ALL16 = 128+256+512+1024+2048, REG_ALL = 0x3FFFF }; const QString& text() const; void setText(const QString& str); int value() const; void setValue(int addr); int validSlots() const; void setValidSlots(int val); int validRegisters() const; void setValidRegisters(int regs); const QString* source() const; void setSource(const QString* name); SymbolStatus status() const; void setStatus(SymbolStatus s); SymbolType type() const; void setType(SymbolType t); bool isSlotValid(const MemoryLayout* ml = 0) const; private: SymbolTable* table; QString symText; int symValue; int symSlots; QList symSegments; int symRegisters; const QString* symSource; SymbolStatus symStatus; SymbolType symType; friend class SymbolTable; }; class SymbolTable : public QObject { Q_OBJECT public: enum FileType { DETECT_FILE, TNIASM0_FILE, TNIASM1_FILE, SJASM_FILE, ASMSX_FILE, LINKMAP_FILE }; SymbolTable(); ~SymbolTable(); void add(Symbol* symbol); void removeAt(int index); void remove(Symbol *symbol); void clear(); int size() const; /* xml session file functions */ void saveSymbols(QXmlStreamWriter& xml); void loadSymbols(QXmlStreamReader& xml); /* Symbol access functions */ Symbol* findFirstAddressSymbol(int addr, MemoryLayout* ml = 0); Symbol* getCurrentAddressSymbol(); Symbol* findNextAddressSymbol(MemoryLayout* ml = 0); Symbol* getValueSymbol(int val, Symbol::Register reg, MemoryLayout* ml = 0); Symbol* getAddressSymbol(int val, MemoryLayout* ml = 0); Symbol* getAddressSymbol(const QString& label, bool case_sensitive = false); QStringList labelList(bool include_vars = false, const MemoryLayout* ml = 0) const; void symbolTypeChanged(Symbol* symbol); void symbolValueChanged(Symbol* symbol); int symbolFilesSize() const; const QString& symbolFile(int index) const; const QDateTime& symbolFileRefresh(int index) const; bool readFile(const QString& filename, FileType type = DETECT_FILE); void reloadFiles(); void unloadFile(const QString& file, bool keepSymbols = false); private: void appendFile(const QString& file, FileType type); bool readSymbolFile( const QString& filename, FileType type, const QString& equ); bool readTNIASM0File(const QString& filename); bool readTNIASM1File(const QString& filename); bool readASMSXFile(const QString& filename); bool readSJASMFile(const QString& filename); bool readLinkMapFile(const QString& filename); void mapSymbol(Symbol* symbol); void unmapSymbol(Symbol* symbol); QList symbols; QMultiMap addressSymbols; QMultiHash valueSymbols; QMultiMap::iterator currentAddress; struct SymbolFileRecord { QString fileName; QDateTime refreshTime; FileType fileType; }; QList symbolFiles; QFileSystemWatcher fileWatcher; private slots: void fileChanged(const QString & path); signals: void symbolFileChanged(); }; #endif // SYMBOLTABLE_H openmsx-debugger-0.0.0.svn20141006.orig/resources/0000755000175000017500000000000012414415132020707 5ustar shevekshevekopenmsx-debugger-0.0.0.svn20141006.orig/resources/icons/0000755000175000017500000000000012414415132022022 5ustar shevekshevekopenmsx-debugger-0.0.0.svn20141006.orig/resources/icons/breakpoint.png0000644000175000017500000000052412414415132024667 0ustar shevekshevekPNG  IHDR Vu\ pHYs  tIME*5tEXtCommentCreated with The GIMPd%nbKGDIDAT(c?)\SVS󿁠 Mj6P  p^@@ܹC 1\}Y >AT $gРvdbuH I1l :dObdOWG p<#@%@Ψqb J6IENDB`openmsx-debugger-0.0.0.svn20141006.orig/resources/icons/symmanager.png0000644000175000017500000000052012414415132024670 0ustar shevekshevekPNG  IHDRa pHYs 7˭tIME #CtEXtCommentCreated with The GIMPd%nbKGDIDAT8S 0 L?_faLƿ [T2q䋮 >D_QR)%b}Hܦ XI>%j眛Gyn ,^-OF=_q`r/Նjs#&"qDSd^ >óF5Ax\G׉y6o? ,۲{<IENDB`openmsx-debugger-0.0.0.svn20141006.orig/resources/icons/pcarrow.png0000644000175000017500000000040712414415132024206 0ustar shevekshevekPNG  IHDR Vu\ pHYs  tIME$tEXtCommentCreated with The GIMPd%nbKGDkIDAT(cx:><apoo0FׄUH MncjB1 4}c7 i@Āl> D Ć; a V-J×4G5fVIENDB`openmsx-debugger-0.0.0.svn20141006.orig/resources/icons/stepover.png0000644000175000017500000000043112414415132024375 0ustar shevekshevekPNG  IHDRR pHYs 7˭tIME00VtEXtCommentCreated with The GIMPd%nPLTE*Uaaa3̙tRNS@fbKGDaQIDAT0091 #8z<B :>y??B^!Dm&mtL! ,t?$IENDB`openmsx-debugger-0.0.0.svn20141006.orig/resources/icons/openMSX-debugger-logo-48.png0000644000175000017500000000762412414415132027043 0ustar shevekshevekPNG  IHDR00W pHYs  tIME 3`tEXtCommentCreated with The GIMPd%nbKGDIDATh޽Y Xi~߳$dK= 3""1u,ePdIMY¤EJ-4!-2ʞ R׮?u_g{{~r?OW{.77ÇU "##7Gmڴ)P!p~?;9ło9e@?NԏSxtrs|ISwwa!SױEĶOӻ۶tdp:PgZSxC$Ws]uԕwjN0`+l/WP4sL 4jB#N^ @B{N?!OMMV4$'/s3%ɩUk׹{YoPTTTR0fdt4gK K5WCᵒU.+ҥKٗXXXtp7!aW0DYDݿ*/VX!C[/FܗCfU^>&ҥK={fAO?{tA 5Zg3$_7oP6\fDF_0nu0ܦ_L*M"KIkEO o ;SP(<0 k$! 3%ߵ'n4)N6?~([>i۶mKinoc[“;ST¯otnή1y| >[lAekQ( 9Oj- ++>Ů yp/B߳yNwS|j%BbgffV;7E"֊ͭ Y@I7[@8a%\:ȋt|)vК|1M;vTƌ'nsWF6v ?\t8O&l6[?|Uk'NRGhqp1l\}ܽ{W5iҤiNU=p3'PH=Z x5ȑ#y&]&#Z S٩Bt_S%#fcb@̙#VΝñcǐσHi- 88xb"nI.UU$`>}㿈<âEhʄ 'A,YaÖ\ ܥXWGp$ KWK.##SN=Z5˗/Ǿ}*@@` 8% A cL)%&y$`|^^fϞ-022.n߾]{aa!"4$ 竨M!$^}7G W&j^,,<u VBК*|X,ؾ}[JJ*<=bm`CZ][#5%|v+# "?a"s}g^'I}vvvh.]lɫ`]*`"6m gl[dg#8F'ɘNT܁g0gaKIU熸'4^ 'g̘bM=PGl@]R'++WB)-- \q3%\ɉfWnZK mHM'8=HjQw׹FUx{~ϊ?XQ0+3{x%)plFIKp-E$QSrmX>z.Za O"&fQnV" X͌7p>l !5DnD@uQh؀Cb@6mlBR'5#/q["߂ЌBIr+^ׯkI{gmڴZJ@ONL/L Z7ơ2޾\o8-{2,6҄ #?H%"t+EzEH@=6 CNNN[iB1_l `"Y-?|G[]'pxnJX!߬):HN#iqf%wT}1y7`L+-d\\\2z+Ѵ4NJx5t™7*<͞(OOޘh+N$&6xlkI/ص7u*W|;"-+"mT-*{<[*Nj1/>'s/ю!2%x~1үA*&G7"D@NFj̾XN|Y0J]2y1b 9MV)v6}λ]&J(F{>4S!d6ڵ4x,F`ܻw i)[q._tƭ됕ulLHbtLT^CfCs85kK?..ڲǎAO,X ///e˖aqR u)WJ ЯZNN\s^}'4j6ڎAh~Ƃ ЫW/5ǃgJHyhmB}AlZqxԅ ՇQdnjSZ?mrL;BQw*ԩ#5N#Gf."|U&6O-|?!L!?Jtggܓ)橯!s'/鄾Tr.\HH+XBKNjw ywLk 3F,l@=oiV+oШ&ːgCv<aXΫX[oV҄Veziy+JƦܪhu/+`_wlr:iN ʻDK- 3^A4ThFc݊C12U.%hfƍhܲ?/Sn䞠ބ03oDB౐g:!Ш//}p1=՛ גj"&H-#NRӈhP(ڎ偡́j;i5)1?_=ccA4Ӑomх-Jc{k@kէ=?Vc2( G~yikGZZD{.ڶm??/i;ߌ+jVc/,w|q`~vle ƺ`Sg'N;wx6Ϳ2eOu%nsfʯڭ7dr u?~=Bn"&f'x1KRbʞ|\hj.<v>QHhpggD˖zv&d  Ҋ]8 aFFKV:볤 8mV-~9thڄ3l@K[~ ?,zD1?T9$Q] fCOO … *ݻ*,kܱmP <C]v??5"\-n,4kg+[x1\?}Z=Uue|B59uT~sK#&U ?RgN>1\0슑>oP ]]+]BI~;enfXN<3N*+O"\ V͈?Dj۷1a\g#((۷9&& +I\ɞȍ҇'oRg|1e/D}X":72䧷iͯhU1⋄4k+UkELۋ"4)lό8)TR0FjQy2}sRkWe>NJ͑ Y(,i!%ˋu++DIENDB`openmsx-debugger-0.0.0.svn20141006.orig/resources/icons/stepinto.png0000644000175000017500000000043712414415132024401 0ustar shevekshevekPNG  IHDRR pHYs 7˭tIME-3Ǜk`tEXtCommentCreated with The GIMPd%nPLTE*Uaaa̙tRNSv8bKGDaVIDAT 0 0BF3A~ A.Y %ٻ =RhZIo$">H4ńHS$){1 1j;IENDB`openmsx-debugger-0.0.0.svn20141006.orig/resources/icons/openMSX-debugger-logo-32.png0000644000175000017500000000433012414415132027023 0ustar shevekshevekPNG  IHDR szz pHYs  tIME 18 tEXtCommentCreated with The GIMPd%nbKGD0n޼91<<|NK]jic6D&&&:gee)*/So_Ի73 &,,쌻{|c6Gopp*Tâş>``Ꝥmɘ OHH ;q}記լ}l<{f@CCJq [@oOԨ*MIII~KGqɃ1v|4R o/cc1Lac tX+ӫ|P[[_8lާru0R^~-IPYsg{;m "2duuˤ3fBޱ]ϟ?mѳfw˟ﶲqnᥥ)ws{HAL„]&Qe 33-3%&ġCbQ}hI 8[)=FdƍƑO|;41`㷴55$?S2Ou;O:e@Ez.]ŋ0CW@&)L{TRR`Pj5~V[ං@i_dgk:\?40UU 00 Οƀոv%]?,]L~[d]'_2%kЭ:սhe@YZZ~[[[^8?ƌ;bї!5Š+\(Ȉ-&f2looy9|w8u2YwRIe|dgz"66 9k~ 9YPTՑqC;R֓]*mcpf[0a%`-4TZxxx ::yyy(v az[K[JtWX h &TR C4FDDD9PY00CTj?ݖwf[F;ɻ}cF 枧gzvnE`-HO?;;_9 -|R;…NЯSQ#|@oS^ܺK{ܼعs>L6C ;xp7 {oܪ?Moo){e*T荺VBӨ'Jo4\]]Ǐ奮BA": :?T5+u}0y .'-r^ t_SYЗvmzu} >Ӿ ޤ)MwOJWݻ‘߭Z BQ ̟^IYy+|i2e"ff͂3|Ј1cr q!Hr2 w7%ەr$sIT|uN&_| bIENDB`openmsx-debugger-0.0.0.svn20141006.orig/resources/icons/node.mk0000644000175000017500000000012112414415132023272 0ustar shevekshevek# $Id$ include build/node-start.mk DIST:= \ *.png include build/node-end.mk openmsx-debugger-0.0.0.svn20141006.orig/resources/icons/openMSX-debugger-logo-256.png0000644000175000017500000012614212414415132027121 0ustar shevekshevekPNG  IHDR\rfbKGD pHYs   IDATxw|\ϽS5MK ۀ  $bH%d4x7 l H !@6 1eƒ\%˲ܙѝь,p!|>󙢫;s;;9G~G~G~?PC-$""FJѺL#E"-KDZ":*Hh֢;EODv6Ays̙r~8:LIZsgiaakA4h]@4ٯ F4]ZzY#"K'tRs~G(Z%P." x}nٵk'{e袻~, 5J)\nG P@0"PTXHqq1QQQA8F'$ Zj_E婅1Q<ipOo5P>31;, 2! 7; "rF-Svտ~z6l[6ى2 R{C)PJaHP e(}pZjkk~ kЈz/~ O} $LaO+x)DA sndoM*蟡5"2֦⚎/aʕKl߾2\R~χr2  6 hmaYЖBkDBa&neee4651i,MMM T7w"}w>3] e^p+/9^P #HKA B/yeh4-[xϏO꥗W.**H8L( [mZtʨЖϵ8NDV8mـc]n<>o EcCǏg D #v` ;~rWQ5)zx \IƟQ7OA6;M-GlDcj\џrD:ȲeWa↢***(--0͔+Oh B(G Q]O3xy Z W7FXp!^x!)S:{}sشuK}(&a:8 Z VX''A=k#44RSpȋWJSooƚT&!0edp455QYYhaQ]]<=J%C$XhX2HH>n)ϛ?"܈h[[ >P456qɥ0sT>?z(ß f`=';F' T-I74 ux 0&BScuaBA/nivntXhPYYɬ(--1x<^bq{/DӍ3W)%)2DR/4*'My@Dn/wqW]u}}}(?8Uiw ,Y'8yZXL3ېǏ'|Zvя((/R[:DMU E>nag2tb"9}tN8LӤ"D4ϭJxTfc>k]3 3oGw%!)"?ӕvۭ(2e W^y%ƍWމW9|8& >i 's!=g\yShؿ/o?88 }1^]c?ᐇ'ϯ㴅̞YESc>ߐ?4 GV5jmqYg1c h͓Fyoǯŗ%+SO4`r.c``m۾tU=VIJ$m]RچN@MSC!3fTz̫Hؗ[(FD Ll7o.\_@(=O/ε/7#{@tNgE.Hc]Mwp\}߇wc¤ syO_svҾzcQ\2wt[(omsoe]^Uq>IIJ8jfͨ`{\zLᱫ CVZ@{zY֚ǟ 3+ق5d jHWH} ,$7+HU2g/o1b~c7ph64d& 2_e|.Aet [N)eмaO=JWT<931aq>$ c?aDc\tFq\E,y9+a:qR:CГ ߱p\` QaB?L̑8@D"K//[2 n6=g3qO M袜?(iQ#XlGd=tB =ٳ*8"0/{<9*8un4bˬe,]q C)N;dpPbUrsY8f)+&f8GzP~~!-yQxD2D~E˹;P;}Kk***b@8G|( ڿ7w_OQ{@B"˲_癿n>SQ\d/=eA=:+S_m]@&GR̴?a<o!c1^[geIg;sΧcfk 7Dly\DkOR_|Eٌb 4|}0޺fu,V-F~{3qK'& s1nl1sfUqi06;@ "FR݇"Cmϵ|I<ok-|VLC0K?6%gL`rCb1Xz??~ O[_7}u  "\+3Kk\.W6I5:H;HX@`w˭r׽ӛ^Ѽ.E0শ6Ĥ%46RZRJ gv@g'E(ӟ(--}̜ؽm\=+.[ϝBQ8:nIIISOn)ʹƦĭD7[/B(/x.AڼIqXWM[zn+yW_ބmkFÞ[x6mn|tuϺt#lY|= ܔ0~7$w)R8p41]i藺5 EO {8\s#)) ;뢱|r9\Fk<KEn@}ǝwrma(3*?}!5k~eGҏ˃>{PFքhP[00D*8i$ ǃ>埻vs)g Œգ)(UU9,@կl'L ۢ#e i8 >oqW5~O?5@@eL*+f%hx鳱׎wW eXʐ>Ǖ0n\ uu"a+p41 [7ēOPVV墮>uirbfϪ=jg5/"&M*42+Bx>1;oG p5ǢqU_A[\ρjrXp9]9@A~%0ʇAw<&ᰇ&XDyYϕamHn9n0xgxk[WT Zm=gO6Joz>7 ""W<裘uVܢ<[-dYrv4{,[R^K!/u&L(e2*+M;o>`&?0`¢"D >c~N]|\ C^sqX,zo|[Pƿ؄ee.㉛0~RepO"iY#|GC}!ǖPDQ?{*viء4hO?LMm i̊+9'pFd6*Z޴Ģ1oIO}-!MP)\9(wjۯGee2{ϕP1c3VXAkk+55hC$7>=9s/NR̛QNk]̳F/KvlVs-N?%uǀRa ~G/C6=ٻ$v1?ؽ{- &Ϗr0wsRJ1{f=~`!OxQ&x/{1C_f(*[¤ TTqGN泳m'iB.xOyYGy]asfϠ,5,q)<8#oGi_ uԧ>E0d̙\@ QY=RZ`z1 O>{>i,D">܎|#;0 #Q bi*D󱟴Ayy9)- ΋ }}}Z7K ҏ4'dzbۛeJib^0R2}j%uu [ 0T:b `rj#gdZ0 ~(Euu5Z|]9&TF/+yE^DQJV.!eXR9O IDAT?AN_2dh2I00⣨Џ{QV\iL&[ xwJJ|tITW @€{sZ/n%g^;x?>8|G)< )nHJ G2]2j(pST'0|v@<0LV\Iqq1%tuuO+U^iT)\:!Ok{=( y&>%KdsfCοݣkij,rN1 ?$zM*CLPJmM`J[oe &X_x!}wÜ,BaPI@y~zo<8CӺvl2XhQ.?3?T(|}R>]4P5mhE!㗡AUe K`Z4YK70X~=[l9xij(:'Dk<-&MLm]Vp:yY|o[ 3OW(䥬,@8Mc4 {a{.ZZZhjs~%aXFPX_KEG27$Dk.̪rҷά?TߕRsEfҴo5m0RP&KhnސlAW_e&D +VxWiN9yYNs%8pT=v˖-j]~9gN.`/dmCJד*Mr2nP~HG8%G?ܤ1k ٹs| +_Q\Ex1 Ŭ3z<|6O`jL!0|'vsзC@}dxk !PZZ@qQە3͏Ck׭Oh4ڵԈfժUq*Îՠg@'?4 iӦj9(f䂟\a/sWe\Y.νD1EF(+ G$@`fl8qX&Nrs (0FfJGG;/PL4Jgz4Rjuu qY%s_!Q[:Lqq~+sLWƍuVo~LE)EMu1~۞^.@ G%yQJ1vX^g9t/qyq8J_q."?w^\ 6IC}"«z@)CA;hX‹/ c2=Jw=~un%Ưj].۾9,ӱ@hӦ0a͚5yf_ &FW>?.afYJ_8rPQT ^{%n n\.#m2wqeFgoټ OEkkk^^__vAWWhC$&&MԩS4i-q1sF=߹.P{ coC`Ϟ=SEKy[[;vR]]+o`>~@ CS  PK$#rXΧHm۱@ @8\y啔M?ZTǥ-qAZ[[ٳg>(۶moKX`@`s=LR21j#$"kRS5W_}uf7aVyyRߡ]j8#LEEYi05"!_^?c劕z)X=lJmm-~&MĤIhllR۷vvEkk+:v`޽7k_SL3fdaۅr~ml@Rj#rм;=~kN kUzͿsgG`Mq5ay?r uǎTWWvZ>pW(++czV'`ݺuo}q3nܸaVaaܛz#i"x1,kYsJ]A6SLCJ{Px.BA/?~+0M3QlɢNC|r^xÊ͛Ǽyַŋ/ȭ֭[ꪫ袋ep0XMX=c_4[o2EŹ@Y϶'xaNj(ǟiSP.x\|.nH{P]]hMWW===G,?>gÆ |{cŊtvvr5d0gfH Q9`Gێ::Ҿo]x}%9@u%wyA)u 82`&CIfHN #A"3$>uE @wO7W_}5'O>)S_nv^|EV^ܹsZ)^0z@~dzu6(,,D[η3@?sa@&( ެ4?'0A ϧ<{9X@`o{;e>H]]]H]v ]sbYS; &Ev؁Rp(+_ȡwM{IBP]^i2kGa9 :林 5mmmq+w]㪫[oMx4 rĮA">+?-"b g( {g Cu (]s_Z!0 Eߝgşquô 8pbDݻv{ϟ?[oロP(Ċ+я~ 쩢Eݢ#Hw^_yÏmRjaNr1 4=PN$RG#+AD ]]]Jvs1/C ./?U D22o |TUF(*v Q=%-tv Zx1>/(lͰ*Mɏ4Z@OOJ)LDǭ\c1YA)%G(U"0Gzx(). [0R`tP(hdyC,Pc\@PDB"~0 2vJ@.?%o/Cotɍo 2 ^wJֿۻ ph9fx~:RZ_@M^<hZE1B ٻ$A#kv'G_p%@ Cwci$; ȬfF"-C9q!#`IgBx]dʏZ ;x ۷og˖-޽pSYYICCuuuarJi F9tvv'7'B%࿀6yHt҉9֨uBz̸]/zO NP QXy{b#rdb}PDZZZXz5Vblݺ~~?cƌaڴi̛7sDIIɻq *Qk\b۳XJK`~$g*]Ѣ-v Rhm=HH[i˧^5JeZk,K'iǎY5kְvZZZZعs' l۶իW3ydMƌ39,0]۰M=ض}}C'giq-j8k-Hyy6p GSDvLZĎ{8Оsfbx\sNXf ˖-cʕ#Ļ=lڴM62aN>d,ˢ=n$i 3hnjqE1Z[wkw#̢(,6\ 6x5? DExFĢq'ޗ :bO¿%㊫>x|PJ<>+BQQ q6l@sssd͛m%tv)&plD@3uL nYa9#qZdXfZ9V <邱و_ X:+#WVޣeIDt>X ˊcYH T{} oK.P9~A Ewٲe+rYgtRطo=aaYV1b&iD1BOw}Glۖ,R-#a{I("p$ƒg$-<*""0c" ="?342˲dwttfV\IAA^x!gy&'OfرL<38ۍO[5788իz*Gwhc{ON 9Xzm6h;B K)ٶmu5PU˗/gɒ%E1^\9dJ960~rj$ϑAr: ُMN,1/6 ~\ nx} ,|~Ŋ`0 a5X,`EkD)55}C nѷS,F< x 0 ̛7m۶Qa޼y444dYW^if͚H8%[45@yTV -Yb0 vd@JQ^QZ3qpa\ְ~zM< mϓX ŸLO9ڊ+'`do?6SHe` [N ]^|ţl `({3 +>(`(N3 u\cܹ^g}occ#sMK9 477GbݺWg-s4Xpvj00RK)a8+++LN |DZͼF+X,O'Pf:^[9[Ӕ-P(>6`/SXcT[B]m- a@}t@%+Y30&0MMML< &0M &0ydRUaFnnv{)otp0mP(AGj(k3لi]XYYkk^Ck͌)18c⠶=mc˖YT;yqsIy)a73J}*3,x;mm'}\"'c h _H:ueF5WpO{<>.+E{=eIr9vS۶mcٲerˍDLK/K>bPQ $0x '@uu {/"¼r@ML~ n nQf%J~?MM5469gI)?nV,7ݺ Ƙܧ|xio6Cv x4 (}e!J >TH7 DS"˜zzY*b"=%ϙAtv}v S IDATG'55KX={6i2e6nHkk+mmmڵ+N  RUUEMM 3gLDQ#LJ/ʜâE Ni "*],:c7#W@D8e^|DWp o 4:fo"h %c@wc&Aݘx(/|뻈FOEPsC>'u6%c=)X*&0 A"3Smݷ@c5)wܱvk*cA9, y181%gLĹ 45x DWh4JKK 7p7|3ep_HϨclgoM]^z)c-_6ra躍.fN&PʏH?H3=m >k- _}#mhN%-zJcc#vU.lUUMIE@uؽ ŎBLJޗx3Ez_5=|AÓVG. #vAO2;݂l뛦JL:NDOxRLl }k?ok; Q8abL}+j4;7?(v!0f(Y ,4^2L"LVa@Bx%B8@ h@VТ("455ʕԒՌ q@2yf *?Jgg/ ZA3=p(bʔޙU=n6mlBY " QuD(#6"h+"ʦ8 ,S,BM4{rss8'7{Mz,w99yٳرG};E{\qLq@X\×}GMM-O=JI>#5ChbU*Xq?¦{3gTG 4Vz+ !H  ACB^ye~ӟG2 9^f _XF<~Nmm-*;v젶r3#Op14*5"ZEgxӴ[P=3MS8ܭ~njiq&Mw1HGslB2NA6~#" L‚BA?3f4N ʽ+k_ {zhg` A*)Sң!Xz5wu'O<4AY |B|Ә4$Ptp`.M).&RORIY%xxE#|NNHH,{翕VXNGI%ˮf9? h5~pRczt%%^hlRLg7^JἳKgOP? %C ܁.CߚS[[C?D_?'.48:o̜v}2OB#vAfA=WĞSn `xD GXYoL6 !4+s.-gD ?No_` yGxٵjp;oƄJs 9з.lsݒTKutL)nW_r\1AhNx'89JT)pO-l s0 G|×,UJQUY(//cʔ)NJx!\eAv7@YN K=@‹˗N>>x'jTV/H&!:o!VlyͪkkjyxcrJ^|O\ees/+s >;+]H'60p#J}Yr"t"\p#*~~Z=TM_s]!3E&4Mf`$dA{b $$=F~)S޵WKoLL0ABۇ|s,]שfٲevɡcWv*ګ57xI 42tS 9!wy9 ;6@pueqJ)dҤID"¡U9d0m;9!Ǔ %JRݬX+V}N*%'8X235NLgݮ4 ܼy3|C{Moj0Ǝ&8tq"Ȭ> Sc*+P#(K2C <`xDp7#J)NuÑJ+R(pDQJI~ 1B֊X Jamgj6g>M_.R,`Bաyo6HN97ɝeףltF=̟A2|H[21Q;lluޙN@IDMۇH~"޾Sr .0xO}>?8oXiS3=v#s*_@+t_3hNf(!{)?XR~iӦQUU5@=ǽU#5b2 dTʰѕ(Xb<Vp)&OMө0W_{zsWB^^b=>gS$RJ.Dj+++ioog֬YˣPj0 %'՟iD`$ɤtrB`ogӦME&1uH#L/**_`byɚoCr4o0C$)ɣ ޭ}Y-+I9 sߣ'rgpJ d%@ Y|O&]TJn*qChB:.ݣw0;hk+J$ϧ>qo'חPYg)88 ]7?W<k[,O(/"Jq7˟ +(C-غ]i^8\4r?HpHqSOw$YZVBИݰEpFrr[_z*3Btl }_;ӟ;}>޽c=V(U9!xZ[o fhA4gO[/hn馸8PoZq,P)ʷOU i<.\#~b>JKK/~={Z)+|:BA@ ׿M6w޿od}ttdvp]5{V%P.TSӀ 0W%%)*B: ]!Ga6 ,@ RqZZٲ.cR.Ywt}nٴ)ɂXJNN%x ~}RҲG>R)*k Q?0|e7mr?6?fXuv\:0 8BU*HCHr'aAK zUUhFuM5s%);h8 &imaVv7F2b,nnΦfz{l ~ru4~;Uؖ+(,0R\wuenyykb١}ky679/';}Oxx(C}y9_@8xr%ճ~ 4!Xp!'N Z'PnWu tY݀@E.zFf;:2;G|K_|[)uRqҘqDh)"<2c3T`-x;qn 8[QU:_A{BƯp+VpWO?i vIy \KK_7>S|\Pw!Q+(p{(eK'(\$hþ}^+%]JI"BӨRŠ7^ uײ"ΓlG*%\d0*t-$phILJy8AѢtF0Qu}庫R/|:Eh… )?x'lrIp 7J &7`,qxvx^{ 6PU j&K٫93>E @|`56$QDp IhOwH"R /Yg㶓=#SGxl9drrQ]n\=||N K\H }duN0!ZJTe__!r ֭Sh`kJG|PS\\us$)btuEiog@"}8S}mLP=jJ rl-^6i:_WӟDĐ\oJ%(ޟM%JGNn} JJy!: ٻWvwC*y?^C3CcnBN /21c*0#ڻ87l@92w s@y; G4Z}m3R^seƌ&Pb7ڔX3鉱kwa6[3ZxUv3wLl .8YQV܎!%)k7Bunv~`vҭfkB!0$|J7/d:3$XA>"}q:)~R"锎*sF)1`[F~u}/_4%_SJO(&LF^ށ:BmJI2[Z&Shmf66o{81 ;;X0$6UGJH&=ڠQ+P-a@KrWG)uJq:@ s== Zg(ޏlSu:k rU:3@C~ˊ$^܋JvƆ G֔ihe Ńk">ގnjp^Dd7n\*^<Bh|C3}4-lPܕ]DY<IҴhvtttipi,#c$#{b(+;]ha~JT|J).p<lG/(HAcԈ{"wim!噷`0b6lc]캫)WhֆS ׉20.mq87f9X֙x7t;攚DZ|f͚E^8N ~ᡠ - 0#mWw͝tuCd&ںNI1̞ ',Vك?'~L)E`+00ħ((,(J)>T:T)fn =^.wdVxwGeEQv=z.@];!۹:&7ő)e3NauoTJ@IE20$\|p!qʼz#šJ3H8<[n_e+%%PYA(3' 0$`Hq￟K/*'m~ 1ݺW=R^װ3_3R\\lϮe#g~wj|3\Xžz 㦟+KEM><ʐL$ 駝~N@-A.}1LOOOd"A~+-[K/w6*+Lt@ #o FJ"SttT)):GAS1j?? wIX_TQ:Y8Kp GI`+"|P#|dMf})%%%}ݤ$IR)SM#9(vՔЕ!j 8)pB1 5p9b[oQ)uiO8'D" xT{f6^% qzz˖-{Xݻ;I$ TJMss3~' *u~ݛ^kH$u]_dUOXL$it2;U|+ _ od9@x1"p?O<=.7]7M||ēSh;n=~Eϖ!,AE9KKDmvJJػ)?}Yg j#=P=1 e=m===$FVl c4#{~,4 L&G>~C\߬1G(&.a Ƿ|vk0 ?Wo IDAT~cK.dT-xx^5Bmn7F}ߋ@$kq a#~.UJj{w3A Yd /&/ tsnk>Wz):Ub?ާvDvȨb PG˞.h0dqhnnfժU6 }^|.@Ft4Zꨯ'+eP(>rE>~CɝM B030oPh( :Ɓ6-;C&X>sN((%zDcg/|H$X8*i2Y {IoyA<\sdp#1*;)#.3`;:/Xp1yr˅`{16lؠІCo2WiJaQk45uV [*)[Xf ]-BA>V\XpWJ(hWAiY 3(*c/-[[/7b;*^'5$7 t ߶i?^py+)TO`Hd Ҙ3#:s/0}\Xߎ 2~s3PNct)b{çԭi׾')c[hiia޽S[S9|2O=O?˿L8%V󫌺JiF"! )!Rɽ4\ޙ۠[߯TR B:p8eeTUMI&s~tJ(q*F |3ӓE44=F4M㷿]7MZ[;^{-/,}J_|<'N襶?MXyOhU)Nc2JJ),"JKK(.)(GA"r b twoSCeAhE0TP=uOgL8~B794MFLG?~;yWD"L8rbZG1 >Ċ!2N}, 36@k \P63լƙ&f΃YSU+WzES\R=[ۨ3K8w{~2K0 (&*(ՋR}eE-1o>|>A*壽M[#<ʎal޼_ݽO՛Ybf{8Xr V)0R=Z6hgKۭ(3I-IT|>g8uu!ЬI]w~z6l͛I&hfRi[ekPV67ё)%@Qr)Q`0Aj=؎ |B> ta䖦iBaL̔S4 M^ze_BQQsaڴi! 100@,KOk=*,oG~?ray9cBꥱ{,}Xs J%mwo.کzB+U{( Y0cg40utV04:}mFΝڵft >5iuk5@uu55Q]= !4 k<_۩eԩTO<dz@qq1{__"'p¸IRlڴaǿO5ܱbNw5Q^@]32X$ ErA^U{,K88DTa멯F}T**MCYb!V?xd*I*i G#  Oaa!HHq1e%UQQQɄ*3#фe;wo/I^^55TVUQQQAQQ!pp<|~?F*vo{Pσ=OmTê3Xy/DZ`mSQ˾Oc8#ȣG[v)衬Hj*VZRHQɓZfЇi鲂!Cfب::&o ?φhhOK3eJKJ)6T *E*"JlN]](ڵh4ib38ftmk?iB𲷘l LтZd3h67jgO+^fW@O_>Z(n )Z”SR"%%D"EG0" |>4% JljbMgg'mmm4۷юHQJG(SXXhbH%STTτ r)L`|nA0$  ^cѢEV:өbz^zecH#>]b#1C]mvY~.h{ D72J!~װR(i2+Lz6}ƙ̝;wqyyyq~[? 3@P(D04*++a8a.ldɴ4w0Oՙg5fAC] ltA:H~ A _ħ t-& ()MW)Ԑҏ!UEu|'q1cڴiY0Wx zzzHY# 1udjk먬8RRx?fLXtNz:9H^I?4$S#(TQ9_*g*9SO=5-W^^Yg{wIB TTTPZZJ^^%c>`(N<'HCp8 7o{/wǭt&T\\ȼL:s0i ׏nvHci6 !LѾw/]]]tuuūI&R^^ 7ԩSY`\rɸ3%'bLD2X>3XX̀ |iaCij'E؜rf neRoRVy彬_ɘD1^:h0a+;#MT`Pߩ㢋.b޼yP(4nyLf-[vsm?৴F:KC+ed@F6Dd6}@x8`;ݱ(P1@1 ˸{@}&h6gdw񐬯LBjjj;w.\s gqFZTc@X{o_gv6Aڇu6|.psfo6(HYdY 9#H/nmH3Rk o>Giv}0r`vFL w $,Ye]gJ_6~rgh^^yuYmGLZܾk89}B%o{ .KvIEM_oG!h{%X |@Rje3k3l!s%NXcAzi}ZM(//T׻ zW~MwV5βHįzakϠ:+}2< #r +z\N 6xVWo٘$ CP]Jm4* J C`=&H2Yzlr8꫑4(mNG䌼c3 A/q)S\P|{d&/Tw1d="׃6 0׳r'J!dQRRDeE o8S3RT y1~mEA >9%A(nK1{C#?ye s2W.Q.xu *r8 x@ 0Hoo7> d}#bb2oN*[e#|xhv.A~!; ׮j˅;`Jj6m,B缂k Wҫ5%OK!%3oRkKܹ.h-G}!ws,=H0+&sN0Wv=2ilÅSF3Ja`*e_žһw)>/g'm? #pNι`$u ^P'}7Bgk~1-)drSF UHOH];v7ջ?SVVL(tն8$: ] ) ,@o {@%Ao\pȄ(M3 IDAT{F I2[ƒuFz]+a.G3pp|i۶mp8Į,Vln?_>z3~~30$HlQ( 7?niGYY 1:3A`!JJ4nfoZՒbrnv\FvUZ'Z2nvfʣp$x(ns\iO`а> bWA~~bB0ph@'~LsfFA~Ғ|>!_5oJc l+ 9yJ6[w;/( 0j<ƙiM\;#3NᡟFo@OyE `pxATu@@^~0nR~[?Ʀn.\xqlyRSR[G;NŒ(o؆wsқ-[q@V8spF8RD sYW!'rmvg>4L#@F0q6d: {PX3Ņ%;ǐGˡ#8#9e,Yu]' ,/8tJ0 ϴmN`Nrj8]E]ԂeM^C8$ĥ92(t6C\$ <4u]7sT*EKK*0="!l%M>aB~)|>oInA4= ;pm0-s<^JʋF/ E#91R%s⤓NnG JRjp8̯a' 7](4=jJ dvIܘxSD i?M)qmȢ-S ֹ;W p`Kj8x' !:&L9Yf siexS#DGSw +,kR1/VZ13n#ÐR)P!43<Xq,d:iȮ% 0ؗ&wQTY< Z=.9(0)r{^LG7t$I0T8p/-[ƒ%K]xrہtml~2J;j~%p¥u'<‹$ `ɒ%̝;wܲ1&H&+@88=ƁTu]H;\ZCok![>%B;ًIs C4߯ 5`aKǭ{>[5W qpSblnTЃ ~U5bFΉ,O`08r㹥m` ry+ȩtzAu[݉S.]>?3v@-cAE Rm2SVVC=d ({̉A*9vV[- CN"Y\~v'Ô2\z,Y]@KK+aWrLpցGFcD(eFۃTp[n rdrivw@eiv! [vVr݊£(rIIVOd)SP__Oqq1 1R__? 'I@@6+ x颴s5xχ?afϞWO@&ApٸD̽6Іo^^ I dz2^|K׋.nr3g ꢻ.֯_ϬY-{?@oo;w"0ۀiOSFc[vh!H64%vq)m744}.Sw?{j6wE$OKZt[{9ty ^yN8Їr2 1fQG(}k!Nz<+I 0!}LJx^oޤ oYmlٲCpQ1-FHSmVp7VQ1cV046-^{e =`6 wIƤii''တ F2(**wߝ,F6%9.jĢnw38O-9sl2nV~ϻo/=Gd Wd$ORDr, $NRIlp;jk2Ic1|sՑH$Fd7/`:4͝=2EO6-gOf3cqkq~<'aZ (++# Mtvvys5[ۛ5ά\N7NX-AZq ̘QF~oB0w\t]g7}#O jhP5 MRFnaN'HtIeeEH^= ,K lA Tee%===r )@ͼ>t( i49|# ,^}5֬ GŴRI U|PT=J WJmHqz־Vmf 3goa[X-` ;걧 #Dr M[}sL>=s4ͬi auW{}á@|EU`Yl/hk/8B&k.,T@9Q(,PVTUͦj<*+0l6x<9GY[[3<Ë/)=n>m4Ofs:~ @@ @0>Ay^ à?D(ԏ\s5if~Cuu hk!(.]p睔DSZ̜)^tEaN&1I"a%}-9)iJOJ[$sfrpXo={!wysM2dΝ_Fك  ,H磪*h~;.hŶ,D"A8hoo'388H?mFҴ'ۀ@Rج D *%Q)!Rr̲i ;LplZZf,FmPXɫT>J$$$G,KY>Ɲw~eŒ3&=ɓ'Q=>Ovgۍ`0HK@5 PH$璘s/qcxP(ĉ'طo裏>:;;h%á!Z8ey<84wu0~<,o==\3H?▛qȓ-Zۢf uo$ ={g}8^@E^/7|s[zzz8|07nwޡSiFeҠʠXxvLʧ 9M.?FIjֺfܐ_?z^/0sԌJ]*Yg/j'_/[[[W\IRRR ϖ^^{5~Pڸ/cze䂱g+o6ye#-z{zL&PÁkݟQ"T%6|?ly6,Yr^۶mC!,˗+VƬYoR^1>ri+0ULSw<ز Xaz?Z<<o _Q:ٔ`lULNg뮻Ἰ˖-'$P^^}c=FMM >,O=/2vcE,wH%KeyB pb4 .78 -W, D,"y,I087o?/}{|Mmm-_s/^͛s Q6m|_\Tg &E'Dwh!(2:c 0aK/F6~jY֒+ _8_T{UqǮuK.6R\\L}s?#̙3 @^^_~yϹ&w=?Fqć,,^u-Dҡ$8ug4UpBE|Nu ՅVPcr%88o.t%$J!H\.T %?Sno{ٳ'rJ}ќ+o^z5_+ X(( "Nu^EEBgW0$&c^ 1Zp) IDAT!XAGBz mD?UyuWWǁ?c^ kg$-)Ypg#+K'5L~OeIbYQL}`F=CJ&A}9x\ʭM~+#YC9C2srEњ[\NFY|#hᒅ*orMDQL2[F "#{ <2hBL0ev =<~BG"^@)PUVʡ[oVBztKifɏ~eKd޼9˧yC Dl=Hw!e9Op0ujd;v\E:0pŗ_X*B)LwpŷW=G8K/=#~<0٫JVןREQz%Gp؉?gōUSv{b?яطoXٗ<$pe188Hgg'uuuڹƣ8fWv9O> ].; @vjj}4/|_[G;;L6zjvҥK{),,kً,$PN<ѣ(gPXRJK(χϗߟATGf.> g|:Hh4Joo/tt# H$ɔ#L I9bؤEy2,Ej_WV*\=}Pb Ay ?_IQwa6 o&[g/\ ?,S˕lD%ZkL ܄!2_Tn;!z((STTߟ ())?^SPQO+}2$ MwwOJc CooN"HyI#2K˃>t;q,#T#565M~c?ߏ((ܕUB=S0k`FBqj60R9a\.Ay? D؜$ FkRW(EK/UX8_L:#%9 8pPwη]<ꐒҍcZEA4n<. Uud%{2Eg`&3`p0m㘦9~o0r9{zgh(yys6*`ˉ_R,Ӆ2k` * NM~ fwHl( I72?Fw}`\YTYise˜c%tvI:NGxŢhV׌2Whȡv"kCV[/3*Xx >BUpkNJM/eJAEyzT۝jKi8[]/h𧦻M@D@}ϓPT$(*,~ //w[Ct:Ȏ em LIH&ށzvIu]2800 D0B Wc7$=K, Fz>[F*pe*Dzc}gvG'<9 6Wj+*KR\Uj>P~B1'A? <7vZɉ8phyF^N&y& g [X,nNr @L4^yz,x`X@ '@䢩 '؊ T AC#B"&媊C||HGAێ&)^7~$Od.?(f MmaЉM薣Yy9,6܂gPb%l !{ ?Ix/ &lp\H_|_P^zmoN% M#twi$T{k*1gin(485T{mI)0 d[emf`?f3#z NHO= P /SS$TH{@ kL[P4gj~{Juף&FYۮ]uOWZ1%>B CCc6 .-Dhl=8:]<0O7}%E@|z_X?wVdA<0A*V7G6<"Q/ǪO;W&rsDHe4-G/^@.lQT!m$X\+4iUknRI @nKtRH/6(^kx r9 F#*Cx@ 8p,D3XY"⑙8 9P)Ʉap:y[Dm]?wdRng9IENDB`openmsx-debugger-0.0.0.svn20141006.orig/resources/icons/openMSX-debugger-logo-128.png0000644000175000017500000003655412414415132027126 0ustar shevekshevekPNG  IHDR>a pHYs  tIME 11tEXtCommentCreated with The GIMPd%nbKGD}ݗoq3]˷/^xgϜwԩ'N(Sofxu/_UunnnPb(^88::BBXb k׆֭[; `ǎpȑ2}y`,&`1Mﱟ'ߕ+&_Ϟ=ް~=#Tɒ5kV(VTTV 6l 4C:uFPrp. e˔JBRL2(,y0t07oܹ3z׮]Q0}MK:R0#XLAgx!T ;smd?޿{? &&&СCЧOȑ#,X\]]K.A/UzRM҃>)C"}!c/S;56G1s*Y)ZW(~]|yhܸ1  K,-[:uQN ?O8<&sL"hc芍U >ܴi`,L; hB# 1( .΃!wUIf19slٲ2A{_yl7Mky Xt3M_-BL0&Fyx+={Y'ڵ+L>O6i$x?ēAF2dr|||XS_@k;kw'݈l !X d`_-U\H#>+K,{{{XBB̾|~rƎ;#a;лVktn'#w I [|y#$d" '%h8e3EP6^ӧ/0sL( SgHefD?a4?=ɗpAL2A!(h9kuQ1TwOHx|~~~ ^r!x˅ OS;cx A*7<.k-jeUVo!XaHk ЭP[yBcaq)3gLYɍ , 3uŐ7o>u[)wCDq ks.77qqO̱+Y:?p#|wݻ/)r4illl^4iG]d 8 vd lu >|]_e8YFo>H>"=<1#+UƍsI??tto<&ǒGgoSUb'#*mZ_ǃm[ _BV-Y. <4֡M^Fذ~)R>|#9s#w2*:.۸l@dJ,Cjaœѿ/kN4[ gφ…ۇYtip\݂xDAu)ovvPlYXl%\~}_]ŕ5/h֎p r899A&MY $>Cίhٳg+ߩS'Xh9s1 Je]PG$$CBx 6F/r -O`~UǏ/7K=s2 1 1 b׌ߣ$KbG |o6]0{ IL2m͛7YY|֬YR8ap1 h_$)[ k;jV?zE?}tD@q!:l\D$ߌ^̾dHpk >}2{8u@!#G2`ԩʕc ?@"n>B[ Z"ZD<-IrJI?+b$b bAʅY_\89&#~xuLNg#7o*U0ilB`m`4(S4]z=zT:H\˩rx55L);GAaMb7gϞ}YZl)j\(Hٔ,qCЄ2pt_' H^F$ $}' Xhw*\QQo gfxUD!дG-A@f1SnSQr(Ki6:|Sfxpt Kf_p"y @KUqt$\dVMXaz2k1Jʈ*Ъ`a]w݃p>nW_:sĉu֕ 5TB| o4pٞ/|''6,#F@^S'a}p`,\8u7h0;\=?X{W@TP[yhg.b>yD'dB3JK5]j 7ES%h|-ެV 7PO|2D>m,*u'^$8vF!sA)'7O &8^р)3s(Iw&_@.|j8{tL1+UV>2*WժUZkIvߏșwD m5_G;d<T6 ={n@}SdCRAǎNjQwB=!{V 8]+N)UɚC-ߦ)a lظ:",|X=l7G~;tZ\E BYKvEHjR_~TB#_@&["H\}^KSȖ->G8""XBPcp >PC] < jYЊ j>|g6j"҈2 hq~Oc5oO>$jWDa+ lܴYJ* Nd~_~2w(jMe*POQ'A?~,}֭..Uk+"U`"^”SY*HEsuq?Rg``ar@] QK|2rq5%zOZF~[سgf͚A qg `9:4w\yڨtMwS4ۀVĴ,-e=: pz"՘?]m̊{m` ?>P,ze!b\JoD>u k; 49'|*'A2teT,sI02O)<\XЧ7"_&O   O@S'{O>ŀn$fPx_^3'/?C̉jhX^=( A̛Py ޽Y plm3s!(ϠN|ǂ>|v4F8j^TƅYEQ?M}vt...TT41oi{C0}(SN>|%O{zzN+g?3>ZXt3l!D^CԽk'uv٤jxyXώScA+PrDߞ75)h|M-^V΋K삹 %4Nlݺ5Æ Dai"Hēh%y1'݀fmfphD&O `Upaț\$w(2qS Wuɯ*䮄;5gRИ+WV|2ۈNV| %ēQ>"Rƍ֓)%7PKʁ5E !Oy.i?;3VݻϾrׯYKVu8C~f_ a A ҈4BJY?O PΪE|GKQ9n":")͗/3"(quNoݺn+QFP@ GM4ߗ j}@enS;߄wb`ŊV  p^K|=l۶ N<&n\KRB)"k&̾Dk9ɯPNbA&i"U4tҩoZУyr]ЇALxض_cȡCARyc.U|ĕ=ޓ8H1!ރq?oƨV͌>N>|#+E\%0(TϠ)?bʕhdMh* ;QSԫ-By {Щc(VX}[By&u|wP.>'[UҥKރuaFHBw]UgIH&>_dj&W13Y5_*^U'_ -$(Ν{Vj֬ 2,#{d@ȗ@2c_e_9sGFoJ'ܽ[r.A KS%m,ȧQ& m39=Bƈ|gW @\4Z̙keZ4E3w׸O'~5@k¶AƌVP7Ϊ!*4қUog"gȠZ"U' K*MuQ| x4 F+䚟3|eQ;f͚6D88dMֺ_nl+[A0/{qOaH/}Q›)#? +T(SEK Q‘}6|*;ɧB8חU>[1E~!#S\#?3 4iOb 3,NzڮBhmc흼P@l/u0fӷU>ZB*)ח*2&?M$ȀQ'}ީ'Mv0aB$ieiL X"i zа$ر,ĦS&M 8G /&O#T>E>ٳg!5ܹ>,NxOJ}70_c=ƶ(7-|Ts̾s|=,DY&>TwЎXt@70E7~}a(VϤA \pJʽbڗ~|;`x}|@a(ւ^ XiƵ_*fhl1GVH=[1!*c %M H:O@@7M3z4T\M v֦|X7,m{@3`b6n YX9>h?FH"~NJA2A-(STL]n?BB"f|i7U>S%^SAYoJ;#-ZGgo(__6LC`Zt}kA`w%uvnT9g'Oh*`2F!{D>#ƍx`|PD Xȴp^K0zE'?~ ^4oTW­8xj ,#9dߧNT, ~ ҝ$[ä1x5|e|& =*|2|ĹO_C8tPoꕟ0!KGO*=s!h@:h 5Kزeds`2E{<?q|!C+#ZB5L&cxr0\8Y\c;/7*&)+t/ fQ0nx(T3+%+0hEF~G.@k }̓v^5xMae'77p4vY Fq D .NvxJ8WgsE'0BLUMOf_皯28sخ}ooo8AhsHk H8 = AM6w?5$<:Ԫ50aWϭKUYKݾ}}>JؼN YEá8( Ǩx_pFض^؀yØ&JxУ4gOPrFR6]ƨ,dThf'@#Qڂ޺(^C }pعs7ر:t-@I5G PʟUDL?:v͚ oL 88b?SGaҰ~Xv"|klp],eIT8 Y/ϑOpKϝE1t]qаQ/?`e6뤥*Ei ^ƛ~.nPȱ,g>53Tt2CVo  1Gm߾j~_3B׆oKfvZl' ]-^<LӦ4_{>D<0:̞QV̈́SNzK\{ ;/ 8J[I>_"?j:,VE|PÀl4M٢ŜjMFu5`iUC Ŋ僖M ap4xtg:}1b^Oɒi=Pj)SBXFhzhղ6L< 6l¯1ͧCr W#]]@PhkȢ~Kgj)Ŵi) yIk ]v'M`ܹlr:uhѢP1 v;[P^"b( "x-OaŢ0֯tց]d)#x fyh,B^i( ׶}QД/IkӴNaS \ &!B*.(Y'pɓƍ`]l=$:0Aĺu6@=@L;'%Vp2T_pҢEstҤI}iKPyQK9Gt d$}䳳 c*KȒ8mk2{ɴHa޽lŋ1W^cf44iJǘcX 2@v62lMm$$>gNMhyHhcȏf֬V\eU4~z @y0G A8`hF85t6}!c5gȝ+P ,  B/_~ȓ'/̑eUbۃтldCZ͛.hт-VQG&4Rч~[p!Z'PJoN~e ~LOOt~JA:.7$$?xuL0%QFF.;cl_ϧ%c}4ٳg H#|z\ 1SVHL)##t2'?'_g<E_. pgux5mJʔ)F{iպ5HA`>1ˎBqoYȞ!VK_.~i1}ƈf>k42/7?CxT3q9UU`92HKKu 0Y *8`VPV,Ba%ZæFN B|d?׻mfI!e, 8Bx-f|;_j/' |N 47\IK Z-j``K >H=&_وF仉Rb|o,F̖#؏G [Ȝ93 i>4k}}:z5P50k"*{")3 H01Cj${i\y9>s-zr҉yWncޜ]E5ѴRMP\s=z&RbSH@5@Fk}EpuvMB7M4@J7 #VK;q.zn[f^0@/_6  Fj+VWɣ1H|5E$_D, h;߷hNpnRooY_^=ޒUC֐Q//o(Q,vR.! @[]79!r?3M7OU0Ze?~((Lܺ$ֈlM%ށ[?"W 6!,‰c`bi!?R-AeBЛw1?^> 7OjeX r?sӯ3Z߯W*L|#Ǘ`AnB{E~)^ YbȗH7@5f~_M|d)TDj!x]@23ZLa-yWtY{_5]:6)A8Bm@B[2CظYaMk~MRQ,q;mVyyEVNaswT> @C_ڶj`e j:H(4i<3}d})od"~_]:~M\u.YeFN5@087Pi 㔑?[.m7GMcs|~0QKQU,RAɊKkM|S>leBfYUnny khq_c&PDɒݎѶw@j 5OBRl8r&R0c;:L{N>SD jmkZv^9북u'$+{O - /fSY#:tʉ7~1hO_% ;wVnڔA5|?34noyLO^Nhs}yWﵓ~vŊ~fi؁djpr8YAtU ;:N&wSpsM+ 'OWhFfNN>C]B$4>A'O+zk'U&RUk)Y, ݾ}6`֗IXc͛Ȗ-[D2%D1CiOg"zOK MBYḨ7 J֑vhA7n˯J4NxV^q׋O[m%+&I?I- ;_Abe3 𸁐挎b-Ayr"@}Ro~lj ~S>ig ;ޜI%,*e)z>7}AF6vg1wVHW8w>-VTc!}D $NK2Ro^VJIGā2Njo-E..vfh\m]'#鬸pee( Vr=IzYM$B rhgx^^~B(3qYևV֔\GkωJbY)|yw4Ug/lhBvhߞ> tU4MLzj'OB}ּVͿtIn|$>W)a: ?/RZǺ{J*S=WЬ{|r&4-Q )4GiȞ(U~˩8T]?{pȅTKəh)oKq6ի"Oē пil੠5\z1jļOS0klt ɏK׸H*KPzF>յ..FMX B{i9]w܅*U\y1q@ 7ҼႴ3((!ICd3)_ᄦM:*v~ |Ga4o61OeFy~+KU T3дE ukeP,qRz= džIlE,(8q#*Uk? Al9GҵJ"qՒ(IJ ]t",XB\q BAej Ghkqt{ǫ]F=8j4 %k+kp*M6ekӦMg3h iGL^?![|1&ЗF_ ۼ^-}L =\a6ZIAqaB`ϧEUH/.4Fj!ld4"&4jÇ_hz_4{n6TCP|i(S-b%P(A=& o7Q>nXy\C 3y ׼nbWI=:S 3hz"C/m۶oo6rǎlBM%E* +p%ieܱc{(Q"/Ԩf =aj6j\8z}U0nb1DFcWcQbwlNThHVZ/dB~{5)śHX6Ձ{/5r E_L!+`0paG6dŊcC)'q=|-xը^ Z6Y zu}4P,UR[7v*xp.]7iŘQ._f2XiAF8wŋ4%̙3麌K}Z[w= SӺ)QU+ oI~1hbq|0dH4mܤ1cF6Ox̙5K#k? ]Xbk,BoAkmoACy0p+̟? C2et?†apj'Ħa;j!${GKa>=Ld T)i!(=./4t8RpdM1-UX e&8| . _AjXۍ4;y hstXKu {?"MRb'{@ ̻pBw{ߤp±R1NIif1-&Q)z޼y˗wMtxp+{\".cjR(FJ%T S?\o,ϳJ~pam~p<sc<#H}@o%AjhSS -|rGLD!̘^+ zÊnjT77nfaV b*JN2. *-Z 2Q̙f;tip|}L!YAٽU1kVReBkkKYB`$av5V<~^~ê{rjZ<DFg=wAqӦ3JNp:(mc-D.\YMqg4B%K!76%)+Fn'T]Pꤿ1 ?_Э쳨@252e  gjP^Zw1b40 @u5jA W`k zKP ($ёl^/oؠ-,1yr .xЪaOKi/ QުpԬ=TBA<Ξ]+*uKx!pfOZ؂BB 7-t#p7\4=>09ZjFt*(VTϢ_6_PXg[^:K~?qK-d:ӷ28HOR- ~I|aam3b,uVMEdQìjXZ Ş[{[@K)ޱ,,ŏd5.[ !%!GrDV#[j`Se+*;J}jNTsAhtZa%y'jDTxVOK凡՟ԱsfibW/ͺ7a;t=>uD =\A~A7|>vj}~c QQ 11 1c^/;uC%\J.FJRŕ[v@,~FQpVtBh\_E +.pRD(,x\U2gժ(6-+/X0~rsR;13IENDB`openmsx-debugger-0.0.0.svn20141006.orig/resources/icons/pause.png0000644000175000017500000000044012414415132023643 0ustar shevekshevekPNG  IHDRa pHYs 7˭tIME9I$atEXtCommentCreated with The GIMPd%nbKGDIDAT8cx)%8`ps* 9p #A?)HLL)l@Cq4 !b@$#d- %bre!qa!0>,ja|;ۖIENDB`openmsx-debugger-0.0.0.svn20141006.orig/resources/icons/symman.png0000644000175000017500000000031612414415132024034 0ustar shevekshevekPNG  IHDR 2Ͻ pHYs  tIMEGW#itEXtCommentCreated with The GIMPd%nbKGD>>[2IDATc?LJCԀxT.S!66N@UH0x p|L).IENDB`openmsx-debugger-0.0.0.svn20141006.orig/resources/icons/openMSX-debugger-logo.xcf0000644000175000017500000047576512414415132026625 0ustar shevekshevekgimp xcf fileBBYS gimp-commentCreated with The GIMPgimp-image-grid(style intersections) (fgcolor (color-rgba 0.000000 0.000000 0.000000 1.000000)) (bgcolor (color-rgba 1.000000 1.000000 1.000000 1.000000)) (xspacing 10.000000) (yspacing 10.000000) (spacing-unit inches) (xoffset 0.000000) (yoffset 0.000000) (offset-unit inches) "Jz1t8y New Layer     Q$4DTdt J (8<D;:qj7 5aa;;'99A9k:{: &26e14c4B3G1'w0 = -N ,:r ,5  +o ,8*#(?&%%%%%&Tw&)Mr ' $CGKMPSW[^`_]R<%$-  $?%HfʷuM%?p Q[)( 7k=$~K*$9')7(= De "3CP]gqx|seTD4##$=C 8Wrĺ{X1(%&Isũ~@(. ӻN$. $׺}E-23\! &ѬrB..f! '˒L(!$5 *ڦX'D +ݳa% #ܶd  #ܵb $ܳ] 'ۭJ/Ӝ80" 1X2٠92q3ܯH4} "ݯM { ߢ8"i "ِ70G(@[t)Ѐ !5J^q!ݲ* )9GVcq~˃ "-7AJT]flsx~ջ=$(6KRUX\biowϑT*@@r-foot     "p"|"2BRbr"5"`eee}=X6I !*4;?.Q-ɼ,_% K ++' *6)( (C'v' '%# #1"'!$ }!h b  :;!!!R6i#$Fd+%8IZiw}=X6I  )29=.Q ,õ,_$ H ,+& *4)% (A'q' '%# #/"%!# y e ^  89 !!O4e##C`|+$6GVes3 D30 / -    ,   *  )  (    '  &  %  #  "  "  !               !  !     #  ,}==  &51˯.-s +H *)U'&%!$5#"!  ٽ¹U .-   !#!AGM"B~' #Bi/ "2CVh|>@@:(;pW<(.5⿙qF#0 ˗b(- ͎L*P 'ۈ2%P#Z!O+q" J "e#r#$o'%[&56&a'x*++,,*'Y#"濖i7͵dF$wiZI8%$@=8';lT9',5ڹmD"0 Ē^'- ƉI *ܗN 'Ӄ0%N#W!L*m! H "b#n"$l&%X&34&^'s*++,,*'؜V""޹e5Ư|`C#»seVG6$$@;6 1 0 - * ' % # !    " # $ % & & ' * + + , , * ' "   %@iC" 9t64h!/S,f)G&$" s0 !#)$:%;&)& '(m) ){**q++:++n*A'G$M~BǕiB# |hVC2" f ;;;:s@@ mag-grip     #-#IJJ#######$%%21:?|?GJ ;  , . 3 s 8 5 4  3  3  3  2  ;,.3s8 5 43332 4 3 ; < ; < ; < < ; < < ; < ; < ; < ; ; < < ; < < < < ; ( 4 3 ;<;<;<<;<<;<;<;<;;<<;<<<<;(&(                                                                                             !!   $AH9Nv}{yxutrpnljhfdb`TB.J~|zxvtrpnljhgeba_][YWL0Z|zyvusqomkhgecb`]\YWVTRPN;}|{ywusqonkjgfcb`^\ZXWTRPNLJH?Q~{zwvtronljhfdca^]ZXWUSQNMKIGE}~|zyvtrqolkigdca_][YWVSQONKJGFD7~}zxwusqomkiheca`^\ZXVTRPNLJHFDC }{yxvsronligedb`^\ZXVTRPOMJIGECA }|zxutrpnmjifdca_][YWUSQOMKIGEDB?}zxwtrqnmkigeca_][YXUTRPNLJHFDB@?'}{ywusqomkigeca_^\ZXVTSPNLJIFDC@><7~|zwutronljhfdba_][XWTRQNMKIGECA?=;\~|zxvtrpoljhgec`^][YWUSQPNKJHEDB@=<:f|zywurqomkigedb_][YWVTRPNLJHFDBA?=;8f}|ywvsqonkjgeda`^\ZXVUSQOLJIGECA?=;97}~|zwvtrpnljhfdba^]ZXWURQOMKIGECA?>;986~|{xwtspnlkigeca_][YWUSQOMLIHFDB@>=:874 }{ywtsqomkigecb`^[ZXVTRPNLJHFDB@?<;9753 }{ywvtqpnljgfdb`^\[XVTRQOMJIGECA?=;97542 ~{zxvtrpnljifdba_][YWUSQOMKJGFCA@><:76420v~|{ywuspnlkigeca`][YWUTRPNKJHFDB@><:86521/^~}{ywutqomkjhedb_^\ZXVTRPNLKHGEB@?<;97531/-<~|ywusrpmljhfeb`^][YVURQOLKIGECA?=;:86420.,"~|zxwtrpoljifec`^][YWVSQONKIGEDB@>;:86420.,*u{yvusqomkigecb`]\ZXVTQPNLJHFDBA><:97421/,+)Tywvsqpmljhfdb`^]ZXVURQOLJIGEBA?=;986320.+*'1xvtrpnljhgeba^\ZXWUSQOMKIHEDA?=<:76420.,*)&vtrqnmjigeca_][YWVSRONLJHEDB@><:86531/-+)&%Ksromkihfcb`]\YXVTRPNLJIGDCA?=;87531/-+)'&##qpnljhfdb`^\ZXVUSQOMKIGECA@=<:7532/.,)(&$"Inljhgdc`_][YWUSQOMKIGEDB@=;:86421.-*(&$#!"mkigeca_][ZWVTRPMLIHFDB@><;97531/-+)'%#! Mihfdb`^\ZXVURPNMKIFEC@?=;975310.+*'%#! hfeb`_\ZYWTSQOMKIGECA?=<:86320.,*(&$" geca_][YWUTQONLJHFDB?><:86420.,*(&%#!/@@?@@%*@@Gu̟qr /ZdH D&()#*f**4+u+%+ ,-,P,,,,. ---,D,,,+D+**/*+))*("(,  2  4  5  6 7 9 ; ; : 9 6 9 = \ 6 1  .   *   %                                                  !  "  "  "  "  "  "  "  "  "  "  "                                                   !  "  "  " ,245679;;:9 69=\61.* %               ' DA. !B@><:("@><;974$  "?=;:7532/ ">;976420.,* "=:96431/-*(' ";87532/-,)(&$ ":75320.,*(&$"! "86420.,+(&%"! "7531.-+)'%#!"532/.+*(%$! "42/.,*(&%# "21/,+('%#! 0/-+)(&#" /.,*(&$"  .,+)&$"! -+)'%#! +)'&$"  *(&$"! ('$#! '%$! &$"  $#  "! !         !  "  "  "@<H:,8%53 2 U0 / /K./5-,,m,+++((*@*-* **, ***B+,,I,`,x- . ; ; : 9 9 9 8 7 5 . 0 2 5  < : 9 8 4 1 1 5 6 $  #  "  !  !   !                                                                             !   "    "   $   % &  (  + 0;;:999875.0 2 5<:98 4115 6 $#"!!!             ! " " $ %&(+ 0         "#%'0125 Ada`]\ZWVSRPNLJIFDB@><;86531/-+)'%#! W`^\ZYVTRQOMKHGDCA?=;:85420.+)(&$" O^\[YWUSQOMKIGFDA@><:86420.,+(&$# T][ZWUSRPNLJHFDB@>=:87520/-+('%#!$\[YXVTRPNMKIFDCA?=;97531/-+)'&#" 8[YWTSPOMKIGECA?>;98632/-,*(&$" YWUSQONLJGEDB@><:86521.,+)'%#! >UTRPMLJHGDB@>=:97521/-+)'%#"TRQNMKIFECA?=;97541/.+)'%$"  IQOMKIGEDA?><986420.,*(&$" "ONKJHECA@><:97421/,*)&%#!ELJIGDB@><:87531/.+)(%#!+KHFECA?=;985310-,)(&$"  AGFCB?><:86420.-*(&%"!(FDB@><:97520.,+)&%#!EC@><;875310.+*'%#" 0A?>;986420-,*(&$"  @><:87531/-*(&%#!,<;96521/-+)'&#!497531/.,*(%$" 86420.,*(&$# !421.-+)&%#! $1/-+*'&#! &-,*(&$"!) *('$#!U* "%#!/  06 ()O'&&C%%D$ $m#! q/Gq5!D ZD#7Z$U/%%G')j*U+" -5q//q2<9 !  !                                      2    !  !    򑐐              s m x  +/ / 10 .0 52 2`3`45۹yYY6/; < ~ : < = >:<=>@@mag     aKKKhty.P"2Nm}63ӣwM0ߠf0.ԋF%7F+E "=Thjhf)d )Jiwurpnki'C Kq~|ywt)3 8h,1 I$A Q3K!bPv{yvBݶ~|yM&} _e-벐6] ݺ  Ý4 tT 罠bn İWѮTЮoWϱ}0aõAs\ݿ#O iŊ5F^e2  yMA   # a; 3 IA_-nF2o&X 6n2 rU%tB h1 Bb S 2i K 4XE kd  )r>=Ej(\7x4=dWA0u K Z6 2utM DLb K63ԢvM0ߠf0.ӋE%8F+E "=Thkif)d *Jivurpnli'C Kr~|zwu%2 7h $1 H "A Q";Q!bPy}zBݸ}N& _e-촓5] ޼  Š4  tT 翢an ƲWұTҰsWѳ6aŷF  süa   ) ¼U iǎ$   5Ec   e8      y    MB       ~  * a;   :   OA^  3s   !K1o   ,]  =s2r    [  ,yC g  7   Gb R 8m   P 4   ]Dk   !h      /v>    CFj    .a   =|4   BeW   F0u  P   $_6   8ysN   ILc  "P63ӢvM0ߠf0.ԋF&8F+D "=Thkhf)d )Kiwurpnli'C Kq~{zwust~%3 8h\hx~$1 Igk|"A Qqrt!cPBN& _f-6^¿   4 tT an XT͸Wпaʢsد”ݩ iŐ5F射~ eՔ~} y|~}| zz|~~}| MBh|~~}} hmz~~}{} moy~~}{} b;rsz~~}| w|~~}}|~A^*gy|~~}}{|biy~~}}||z{2ojmx~~}}|z}npw~~}}||{2rqry~}}||{| uz~~}||{zz~B g`yz|~~}||{y{ *g{}~}}||{{zy{b Rgly~~}||{zy~ kmv}~||{{zyy 5mov}~||{{zyyDk pqv|}||{{zzyyz  rsw|}||{{zyyxz~> uy{|{{zzyyxwyFk cxyz{|{zyyxuy +펶C a=^&|0r./̞\o!qJ|<Ou ~ &: 'Tl )k} +hD PC{ f+c) ua}d |#y| ~;wy{~V % ֵiWG:0)&$%)/8CO]n)!!#$&&')*,-.01234B^z$-5;?CDEDDB@=;963110/02789:;PqS]][XVTQOMKHFCB?=;8641/,+()+06>?@Abdb_][XVTQPMKHFDA@=;86410-+(&$" '0;DFGdf0.+)&$",;JJMu&+E^u'%" -CNOh" 6\ !:RSd $1;CIMPPNKGB<4-'%*5Ij3SVg `nlifca_\YWUROLJGDCM]v1U[ntqnlifda_\YWUROMJLRg 5]_yvtqoljgdb_]ZWURQVez ?aeywuroljheb`][XW_m !Qev}zxusomkheba^_i  4gj}zxurpnkhfcbo Rk}냀}{xuspnkiiq ;mv~{yvtqnlWTv &gr~|ywW/9l WtvD+e! Hvm5 -[! =====% յiWG:0)&$%*08CO^n(!"#$%'()*,,./1134B^z$-5;?BDEEDB@=;96411/003789:;PrS]][XUTROMJHFDB?<:8632/,*(),06>?@Bbdb`][YWTRPMJHFDB@=;9742/-+(&$! '0;DFFdg      0-,)&%" ,;IJNu     2Kcy'$" .CNOh      %=a!!:RTd +7AIPSVUUSQMIB:3.,1;Oo4SWg esqnkhfda^\[XUROLIJScz1U[nxurqnkheda^\[XTRQRWl 5]_zzxutqokhfdb_\YVW]j ?ae}{yvtqnlifdb`]]ds !Pdw~|ywtqpmjfdben  4gj烁~|yvtspmjght Rk}놄|ywusommu ;nv}zxvqq]Zz &hr}{\6@q WtzJ 2j! Hvq; 3a! =====% նiVG:1)&$%)08BO^n( "#$%'')*+,./0234B^z$-5;@BDEEDB@=<96311//03789;;PrS]\[XVTQOLKHFCB?=:8531/,+()+06>?ABbdb`][YVTROMKHGDA?=;8742/-+('$! '0;EFGdf䃂0-+)'%"+;JKNu兊'%# .CNPh ߂ "9QSe ˇ4RWg 㴺1U[oὼ 5]^z黺 >`e徽 !Qew  4gj鿾 Rj} ;mw &gr Vt! HvŶ  =====Ce˶eC%Ĕa+ k'!Պ<$܇.'a) $.   1a $ .5y) +7e- :$0F'@=;c><'=<;:9+~80}|{7 8zzx6 C~yx6 Tzvu5 hutr4 rqp3 /}po3 Mtnl2 olki1"}ji1Jmhf0wfec//tcb/bca`.x`_.V_^\-x][-T[ZY, uYW, ^XV,#!$jUS+$!pTS+ &$":VQP* (&$!yPO* )&$\ON* +)'-[MK) ,)(|KJ) .,*]JH) 2/-4QGF( 2/-qFE(520rEC( 752OCC( 9753QA@' :86m@>'=:8}?>'@=;c><'=<;:v9a8F7$665e4+3 3 y2 .1 1 a0/ / ..$--,,,a++.***<)))'(k(((+'a'''(t M L/} L=z %T|Gw  /bfQt 9{UWr EF!\o R:"_m ]0"`j a+$ag!a'&ad!_%&^b  \'(\`"Z+)Y\"X0*TZ"W9+QW"WB-MU#WN.HR#W\/DO#Yk0@M#[|2=J$]Ȏ3:H$aǢ47D$fƷ57B$jB8?A$o\9+%(bHI**QcK5() RKB&)!RNO+%(;rP<#(!oQP#(chS7 'ZUN'MdW4' AXR'4pf[7&)`\Z'#Wl_?&Q `a%%O vbN%I fe6$5 ff#e uiP#L kk;# 4h mm(" K zod"5yuqU "3qrsH !4juv> +]}wy5  L|z{0 0^|}~- Bs\:,.fHI*%UbK5)&VKB%&VON,%@qP<# 'sQQ# !ggT7  ^UORdW5EYR 9sf[7.d\Z([l^?%U `b%$S vbN!M fe6: fg $i thOQ kk< 9l ln( &O zod:|uqU 8tstH 9muv= 1a}xx5 $P|z{0 5a||~- @{}|. 8g(t twyyxwvvuutrt wxyyxwvvuutru/} fyyxwvutru=z Yjwyywwvuttsw|Gw fjuxxvvutsxfQt iltxxvvutspuUWr lswwuututtrmqF \o mnswwuutslq:!_l nosvwuuttssrkq1#aj k osvwvuttssrqjq+$ag]opsuvuutsrrqpip'&ae[Zosuvuttsrrqpip&'_b vosuussrqpio&(\_psutssrqpio*)Y]qpsttrrqpohn0*UZqsttrrqpohn8+QWqprssrrqqppoonhnB-LTqprssrqqponhnN.HRqprrqpqponngm\/DPqrsrqqpponngmk0@Mrqrrqpoonmfl|1,lmlkjihhdgHJ*lkllklkkiihhgdfycK5(lmlkkjjihhgdfyLB&mlmlljjiihhghgceyNO+&mllkkjjiihhggdeqrO<#lkkjkjjiihhggfeehwQP#mlkjjihggfeegthT6 mlljjiihhggfgfedgsUOmlkjihhgfedeodW4mljjhhghgfeedcjXQmljihhggfeedagf[7nmkiihhggffeeddc`c{]Ynlkiihggffeddcc_bwl^?mkjhhggffeeddccb_at `b%mkihhggffeeddccb_as vbNljighggfeddcb_`q fd6mjhggfeddcb_`k ffhgfedcba``dr tiPhggffeedccbbaa``ak kk<hggffedccbbaa`__f ln(ihhfeedccbbaa``_^br zodkiheeddccbbaa``_]^juqU lkhfeddcbbaa``__]^i}stH mkieedcbbaa``__^\^j}uv> mlhddcbbaa``__^]^fw}wy5 mkgccba`_^]]bn|z{1 nkfccba``_^]]^ez}|}. yjeccbbaa``__^^]]\Z\j}}. hedcbaa`_^]\YZg|Psvy|~ cpsvy{}RC knpsux{} ehknoruxz}S 8&ehjmortwz| ,k1begjloqtw]B:_bdgilort-U*A\^adgilnid8EY[^acfhk?oDIWY[^`cfh vPJSVY[^`cUz[KPSVX[]`2}cJMPRUWZ\ iHKLPRUWM~lCGJLORT1~l?EGILNQ~i;ADFIKLc4>@DFH6[.;>ACE#P&8;>@BD 58:=@8257:0*e/247#C ,/24*+/1 ")+.&)'#%a "+    k' <.~~a~~}zv$o d U B ,k a8   . y+~e|uf$PF +ha )v e oԴ-ɕ^2 2^+㳃U3 %@a'`& &`%i-7S^Z0&k%`-"qw"&`#&7qw4&!US_a!ԕ3^k@!^Z_%^!20ww4 2!"ww"! 4_k_4 !2  2^%%^ԕ@@aax-& &ՔY/-`& &`)Yk& &k~;7t`& &`q .䶊a@%  %@an 2!ɕ^2 2^h~ Դip/md# oE.zE-҇1Q. Z,Q_,\#X*} H*K4*Uc(x?(B, (U\ & h #hv #͆1Z #4W !}x !_6"˅35!<s X d;ߨ<R gm ,, yf fB e oԴ-ɕ^2 2^+㳃U3 %@a'`& &`%i-7S^Z0&k%`-"qw"&`#&7qw4&!US_a!ԕ3^k@!^Z_%^!20ww4 2!"ww"! 4_k_4 !2  2^%%^ԕ@@aax-& &ՔY/+`& &`)Tk& &k~;3l`& &`q +䶊a@%  %@an!.!ɕ^2 2^hw Դij/m_# oA.z@-ч1L.U,QZ,\#S*} C*K1*U\(x;(C(~ (UV & b #ho #͆1U #3R !}q !`2"˅32!;m S d7ާ<M ef +) y` f= e oԴ-ɕ^2 2^+㳃U3 %@a'`& &`%i-7S^Z0&k%`-"qw"&`#&7qw4&!US_a!ԕ3^k@!^Z_%^!20ww4 2!"ww"! 4_k_4 !2  2^%%^ԕ@@—aav2& &֗a2 `& &`)k& &k};`& &`q䶊a@%  %@an'!ɕ^2 2^h Դh#0l# o&.x-х3-,Q,R**P*Q({(J(U  #  #h #~3 #% !y!_"s/ !"  ~kԖCL~ l {wB@=L<;'EB@>G:8&FC@\97&HFCp76&KHF65&MKH|54&PNKq42&SPNh30&USPa1/&XVT\/.&ZXVZ.-&][YY-+&`][Y,+&b`^[+*&ec`a)(&gfcf('&jhfn&&&nkiw%$&pnk%#& spn#"&usq! &Ыz|xvs!&͏M" "(+{xvj&乌qW+ B_w}zyN&fM~{0&ƍfF%/R`r'~#>'_>1Gi(%i`'Ew1'((a(%( )濫v) 痢0) ù* l* ﳱ * ﶴ֛ +ﹶB +Ի ,[ , ,d - -]. .F//0i11&2b334/5T6t789:B@=M<;'EC@>F:9&EC@\97&HFCp76&JIF64&MKI|53&PMKq43&SPNh21&USQb10&XVS\//&ZXVY.-&][XX-,&_][Y,+&b`^[+)&eb`a*(&gecf(&&jhfn'&&mjiw%$&pmk$#& spn#"&usp" &Ъ{|xut &͎L!  &)zxvj&乌qX, =Xoww}{yN&eH߀}|0&ǍfG%+MZk셂'~#;|'_=.Bbwኈ("cጋ`'@pᏍ0'((a(&( ᡟ)ᤡv) ᧥/)଩ù* ௬l* ᴱ * ᶴ֜ +⸶B +ྻӻ ,[ , ,d - -] . .E//0j11&2b334/5T6t689:B?=L<;'EB@>G:8&ECA[97&HFDp76&KHF64&MKI|53&ONLq42&SPNi31&URPa10&XUT\//&ZXVZ/-&]ZXX-,&_][Y,+&c`^\+)&eca`)(&hedf('&khfn'%&nkhw%$&pnl$#& rpn#!&usq" &ͦ|wvs!&͊D{yvj&䷊vc=}{xN&`}|0&ɒrU$'}!'i1*`*1'((a(&( )v)  0)  ù*  l*  *֛ +B + Ի , [ ,  ,d - -] . .F//0j11&2c334/5T6t789:'&C&e&&&&&&&&&&&&&&&&&&&e&C&&'''a'+'((k('()) <)**.*+ a+,,,-$-. . / / a0 1.1 y2 3+3e456$6F7a8v9~|{}3 1S{zx~; %BywvG 2vut}W  tsq{l qpow3 onmqR lkjiv'  iggwQ 5fedi5 5dcb`wi"5`_^b]4^]\[k\4[YXWqe'2XWVUSrz?'USRQPnb.  )QPONLbb4 !$&3+NMKIHLswO+&(*.HGEDRx¢d0ECCB@@Hj3A@>=;:9Hf6;:987653:6443 ?}|{~3 5W{yy~; *Gxwv~F 6vus}W $tsr{k qpow4 onlqR lkkiv' hgwP fedi5 dca`wj"!`^b]"^][[l\$ZYXWqe'%XWVUSry@'TSRQPnc/)QONMLaa4"$'1+MLKJHLsvO+%(*.IHGEDRw¢c0EDBAA?Hj3@?>=<;:Hg6<:997653:6433 ?}|{~3 fedaa``_^]][YZgyzy; iheba``_^]]\[YZcqxv~G kjfba``__^^]]\\[ZZ_hyvus~W lkgbaa`__^]]\\[Z[[`mtsr{l mkfaa`_^^]\\[ZZXYcrpnw4 pkea``_^^]]\\[ZZWXbommrR ib``__^]\\[ZYWWblkkiv' gdcb__]\\[ZZYXW]ihfwQ gec__^]\\[[ZZYZYXWWfdj5 ihd_^^]]\[[ZZYYXUdbaawj"ljd^^]]\\[[ZZYYXXWU!`_^b]jc^^]]\[[ZYXWW#^]\Zk\^^\\[[ZZYXWWVW$[ZYWqf'\[[ZZYZ\\R%XWUTTsz@[ZZYYXXWYVE'TRQPnc/YZWMB5))QPONLba4!$-+MLKJIMrwO+&(+.IGFEDRwc0EDBB@?Hj3@>=;;9Hg6;:987553:6432 ?  ~ |qv\a0rF&$ e +s"y #. %a & ( *$ +/a 1. 4<7'k;+a ?~Vl l~=$ ZB(: B V-]w%xs*Fli?T'2KY\-3ީ?g $gz&oﲵa&JxM{ﮰ%)3J& &i !8Y~vrprv}M@lcE+  !0Cbx#uD (Cfzuplihiihfeeffhm|n8ʎX #'/PuϽe8KiH] 4UvѿyeXU[o~=,@I [ڵs3rsvyz$/N^e`WE ,cfhkmow_Ilwmd[Q H./1357:Uj÷eI) *4=FPYclu̻{ 10/.-++)(&&%##! &/9BKUk²% .-+*(''&%#"! "+5Jlʹb( *?Tfv' .=N_oȷ2'&6GXhxϾe(0@Qarŵ')9IZk{ͽQ(!2BRctó' +;K[l}ʺ('$4DTevg( -=N^oȸ'&6GWgxϿR(/@P`qƶ'(8IYjzͽ#'!1ARbsĴV( *:K[k|˻'$4DTdu±*( ,=M]n~ɹm'%6FWgw(.?P_pǶW((8IXiyξ' 1AQarĴ*( ):J[k{˼o'"3CTdtò ' ,N^oȷ ('7GXiyξ\' 0AQarŴ ( )9JZj{̼-("2CSdtóu) +;L\l|ʺ)#4DUev) ->N^oȸ*'7GWgxϿ*/?P`q+(8IYjz+ 1ARcs+ *;K\l|,$4DUeu, ,=N^o-%5FWgxUe o~<"z ]B'7 FQ2`x!ps/Joi:T,7OZV-!8ީ@a )kz'hᲴb+N{M s᮰%.8N& $নh%;Z~vrqsw}I Ai^B) .Bax nD '@a{|upkgddedcb`_adfin}o3X  #,Lqų`6KjB] 3Srųr_TS[o}=,@I Xϭo3rtvxz$/N^e`VD ,dehjmow_Ilwmd[Q G..1357:<>@CEHJLNQSUXZ\_af}s$.Oi{qh_oZ ɱxi^TMIDCEHMT^ivΘ] 1H]kt}u ˽ְH +Uj~ķfI) *4=FPYclu˻{ 10/.-+*)(&&$#"! &/9BLUkò% /--+*)('%$$"! "+5Jlʺb( )?Tfv' .>N_oǷ2''7GWhxϿe( 0@QaqƵ'(8JZj{ͼQ(!1BScsó' +;L\m}ʺ('$4EUfvg( ->M^o~ȸ'&6GWgxϿS(/@P`qƶ'(8HYjzͽ#'!1ARbsĴV( *:K[k|˻'#3DTdu±*( -O_oǷ('7HXhxξ\' 0AQarŵ ( )9JZk{̼-(!2CScsót) +N^oȸ*&7GWgxϿ*/?P`q+(9IZjz+!2BScs+ *;L\l|,$4DTeu, -=M^n-&6GWgxX ~6 B u sssTpxf.eixީOY^mz4bW_oM%Vbpw&hY`fa^q|zyxxwwx{󟡣VQE7.% -UC D2  !%&"#&% $B[pywX .+JeqtoiqwtgL- Ks] %8SpsQ%-Om~>,@I @xʾl5 *'qtvy{$/N^e`WE -oj5cfhjmox_Ilwmd[Q H..1367:<>ACFHJLOQSUXZ\^ae}s$-Ni{qh_oZ ɱxj^TMHECEIMU^ivΘ] 1H]jt}u ˽հH +=JT]fpyŴL 2>Uk~ķfI) *4=FPYbku̻| 10..-+*)(&&%$"! &/9BLUkò% /.-,*)('%%#" "+5Jkʹb( )?Tfv' ->N_oȷ2'&7GXhxξe( 0@PaqŴ'(9IZk{̼Q(!2CScsó' +;L\l}ʻ''$4EUevg( ->N^oȸ'&6GWgxϿS(/@O`qƶ'(8HYjyͽ#'!1ARcrĴV( *:K[k|˻'$4DTeu±*( -N_oǷ('7GXhyξ\' 0AQarŵ ( )9JZk{̼-("2CSdtót) +;L\m}ʺ)$4EUev) -=N_oȷ*&6GXhxϿ*/?P`q+(8IYjz+!1ARbs+ *:K\l|,#4DUdu, -=N^n~-&6FWgxtv-a:F/$9,e6+( y3.# h "  Ҷ  1~ 25 2 2 D Ĕ Ce˶eC*$%%<%<%  %D%/&*%D% %<%/& %DD% &/%/&%D<% & %<D% &/%/& %D<% &&/((D( ))/**D*++D;< ~= =]=<!<a< ;Ĵ/;˻z:±!:ɸb:п 9;< ~= =]=<!<a< ;ij/;˺z:±!:ɹb: 9;< ~= =]=<!<a< ;ij/;˺z:!:ȸa:п 9:;< > =D==/<<</;; :D::/9./?P`q-'8HYjz. 0ARbs. ):J[k{/"3CTdu/ ,O_o1'7GXhy1 0AQar2):JZj{2"2BSct2 +;L\m}3$4EUfv3 -=N_o4&6GWhx40@Par4 (9IYjz5!2BRcs5 *;K\l|6#4DTeu6 -=M^n6&6FWg7/?P`7(8HY8 1AR9 *:J9#3C9 ,<:$5:.;'; ; << ==..?P`q- '8HXiz. 0AQbs. ):J[k{/"3CTdt/ ,O_o1'7GXhy1 0@Qar2):JZj{2"2CTct2 +;L\m}3$4EVfv3 ->N_o4&7GWhx40@Par4 (9IZjz5!2ARcs5 *:K\k|6#4DUdu6 ,=M]n7%6FWg7/?P`7(9IY8!1BR9 *:J9#3C9 ,<:%5:.;'; ; << ==..>O`q- '7HYiy. 0AQbs. *:J[l|/#3CTdu/ ,O_o1&7HXhy10AQaq2 ):JZj{2"3CSct2 +N_o4&6GWhx40@Qaq4 (9IYj{5!2BRbs5 *;K\l|6#4DTeu6 ,=M]n6&6FWg7/?P`7'8IY8 1BR9 *:K9#3D9 ,=:%5:.;';; << ==+ ,,/--D- . ./ / /D / 0 0/ 1 1D 1 2 2D 2 33/44D4 55/66D6 47/88[8%99D9 ::/::!;y";AƷ*9ξe9Ġ 8˻28€7ɹ"7f7ǣ 6ξ26ł6̼#5i5ʦ4$4k4Ϫ 343͇3󔤵%2󍝮m2򅖦Ҭ 101wo1pֱ 0iz70brՎ0[k|'/Tdtq/M]m~ٳ .EVgw8.?O`p׏.7HXiy -0AQbr̬)-):JZk{ݩ> -"3CSctn 2+O`p׏.7HYiy -0AQbr̬)-)9JZk{ީ> -"3CSdtn 2+O`p؏.7HYhy -0AQar̬)-)9JZk|ު> -"2CTdtn 2+&>>0>&>>>>)4>>=&,>=>@>@ = = < ; : 8 8 7  6   7  6 4 4  3  3   3   1  1    1  1    0     /     .     .    .       -   .     ,     -     ,       +@=<;;:998776554231101~~~}/~}0~}|{.~}{/~}|{z/~}}|{zyzzyy-}||{zyx.|{zzyxwxww,{zyzyyxxwv-{zzyxwxwwvvu-zyyxwwvut,                                                                                              ~~}}||芌~~}||{{񂁁~~}||{zz􉈈~~}}|{{zz~}|{{zyy~}}|{{zzyx䌋~~}||{zzyyx눇~}}||{zyyxxw􊉉~~}}||{{zyxwwv~~}}||{zzyxxwvvu~~}||{{zyyxwvvuu勌~}}|{{zzyxxwvvuut~~}||{zyyxwwvvutt酊~}}||{zzyyxxwvvuutss~~}||{{zyyxxwvvuttsrr~~}|{{zzyyxwwvuttsrq~~}}||{zzyyxxwvvuuttssrqq~}|{{zzyywvvuttsrrqqp~~}}|{zzyxxwvuuttssrqqpo~~}||{{zyyxwwvuuttsrrqppon~~}}|{{zxwvuuttssrqqpoon󂁁~~}}||zzyxwwvuuttsrqppoonn~}}|{zzyxxwwvvuutssrqqpoonnm~~}||{{zyyxwwvuutssrrqppoonnmml~~}}||{zzyxxwvvuutssrrqppoonnmmlk~~}|{{zyyxxwwvuuttsrrqqppoonnmllk~~}|{{zzyyxxwwvuuttsrqqpponmmllkkj~~}|{{zyyxwwvvuttssrqppoonmmllkjji~}|{zzyxxwwvuutssrqqpoonmllkkjii~~}}|{{zzyxwwvuttsrrqqpoonnmllkkjjiihs~}}||{zzyyxwwvuutssrrqppoonmmllkkjjihhgy}~~}||{{zyyxxwvvuutssrrqqpponnmllkkjihhgg|}}||{{zzyxxwwvvuuttsrrqpponnmmlkkjjihhgfff{}|{{zyxwwvvuutssrqqpoonnmmllkjjiihggfe|{zyxwwvuutssrrqppoonmmlkjjihhgffeUyz{zzyxxwvvuutsrrqpoonnmllkkjiihggffedz{zzyyxwvvuuttssrqqponnmmllkjjihhggfeedc|xzzyxxwvvuuttssrrqpponnmmlkkjihhgffeddcryxyxwwvvuttsrqqpoomlkjihgffeeccb_yxxwwvuuttssrrqqppnnmlkjjiihhgffedccba?uxwvvuttssrrqqpoonmmlkjjihhggfeddccbba`fuwvvuutssrrqpoonmmlkkjiihhggffeedccbaa`suuvuutsrrqpponnmllkjjiihhggfeedccba`a`_ruutsrrqponnmmllkkjiihhggfeedccbba``_^ytsttssrqpponmmlkjjihhgffeedccbbaa``_^^tstsrrqqponnmlkkjjihggffeedccbaa`_^^nrsrqqppnmllkjjiihggfeedccbbaa``__^]]nqrqqpoonmmlkkjjiihhggfeedccbba``_^^]\\mqqponmllkjjiihggffeeddcbbaa`__^]\\[hqppoonmmlkkjjihhgffeedccbba``_^^]\[[onmlkjiihggffedcbbaa`__^]]\\[[Znmlkjiihggfeedcbaa``_^^]]\\[[ZYlmmlkjihhgffeddccba`__^]\\[ZYYmlkjjiihggfeeddccbba``_^^]]\[[ZYXkmllkjiihgffedccba``_^^]]\[[ZYYXWillkjjihhgfeedcbbaa``_^^]]\[[ZZYYXXWVkjihggfeeddccbaa`_^^]\\[ZZYXWWVgiihgfeeddcbba``__^]]\[[ZYYXXWVVUhgfeddccbaa``__^^]]\[ZZYXWWVVUTghggfeddccbaa``__^]]\\[[ZZYXXWVVUUTgfeddccbba`_`^^]\[[ZYYXWWVVUUTSfedccbbaa`__^^]]\\[ZZYXXWVVUUTTSRedcbaa`__^]\[[ZYYXWWVVUTSSRdcbaa`__^]\\[ZZYXXWWVUUTSSRQ                                                                            {zzyyxxwwvuutsrrqpponnmmlkkjiihhggffeddca_~~}}||{zyzyxwwvvuuttssrqqponmmlkjiihggfeeddcbb^f}}|}||{{zyzyyxyyxwwvuutssrrponmllkjjihhggffedccbaa`^||{|{{zzyyxwyyxxwvvuttsrrqppoonmmlkjiihgffeeddcbba`_]P{{zyxwyxwwvuuttsrrqqppoonmmlkjjihhgffeedcca`_ZUzzyyxwxwvvuxxvvuutssrqpponnmllkkjjiihggffeddccbbaa``_^\\zyyxxwvwwvvutwwvuuttssrqpponmmllkjjihhgffeedccbba``_^]\[*xwwvuvvttvutsrqpponnmllkjjiigfedccbbaa``__^]]\[Qwwvuuvuuttsuuttsrrqppomlkjjihhgffeedccbbaa``_^]\\[ZWUvvutsruutssrrqpponnmllkkjjiihggffeedcbba`_^]]\[[ZYV3uttsrtsrrqqppoonnmllkjjihhggfeddccbaa``_^^]\\[[ZZXVWttsrsrrqsqponmmlkkihgfeddccba``_^^]\\[ZZYXVssrqrqppsrrqqpoonmllkjjihhgfeeddcbba``_^^]]\\[[YYXWUHsrqqpqpporqppoonnmllkjiihggffeeddcbbaa`__^]]\\[ZYYXWWVRHqpqpponqpoonmmlkjjihhgfeeddcbbaa``_^^]]\[[ZYYXXWVVUSHUpponmqppoonmmlkkjjihhggfeddccbbaa``_^^]\\[[ZZYYXWWVUSQ?poonnmponnmllkkjiihhggffeddcbba``__^^]\\[[ZZYXXWVVUTSRM?nnmmlmllpoonmmlkjiihgffeeddccbaa``_^^]\[[ZZYXXWWVUUTTSRQNmmlkonnmmllkjjiihgffeddcbbaa`__^]]\\[ZZYXXWWVVUTSSRQPGllkjnmmlkkjjihhgffeeddcbaa`_^]]\[[ZZYYXXWVVUUSRQOM:kkjimllkjjiihggfeeddcbaa``__^^]]\[[ZZYXXWVUUTSRRQQPNJkjiihimllkjjiihhgffeedccbba``__^]\\[[ZYYXWWVUTTSRRQQPOMHEiihmlkjiihgffeeddccbaa``__^]]\\[ZYYXXWVVUUTSSRRQQPPONMMEihhglkjjiihhggfeedccbaa``__^]]\[[YZYXXWVVUTTSSRRQQPOONNMLGghhggffkjjiihhgffeddccbbaa`__^]]\[[ZYYXWWVVUTTSRRQPPONNMMLKJIffejihhggffeddccbbaa``_^^]]\[[ZZYXXWVVUTTSSRQQPPOONMMLLKIIffeediihhgffeddccbaa`_^^]\\[ZZYYXWWVUUTSSRRQQPPOONNMLKKIededdihggffeddccbba``__^]]\[[ZYYXWWVVUTTSSRQQPOONNMLKJJHGHddcchgffedcbbaa``_^^]]\\[[ZYYXWWVUUTSSRRQPPONMMLLKJJIIHFcbbgfeeddccba``_^]][ZYXXWWVUUTTSSRRQPOONMLLKKJIIHGEEaagffeddccbbaa`__^^]]\\[[ZYYXWWVUUTSSRRQQPOONMMLLKJJIHHGGFEba``feedccba`_^]]\[ZZYYXWWVVUUTSSRQQPOONNMMLLKKJIIHGGFFEDa`_`eeddccbba``_^]]\[[ZYYXWWVVUTTSSRRQQPOONMMLKKJJIHHGGFEECC__^eddccbaa`__^]]\\[ZZYXXWVVUUTSSRQPONNLKJIIHGFFDC^dcbbaa`__^^]\\[[ZYYXWWVVUTSSRRQQPONNMLLKJJIIHGGFEEDCCBA^]]dccbaa`__^]]\[[ZYYXWWVUUTSSRQPPOONMMLKKJIHGFFEDDCCBAA]\cbba``_^^]\\[[ZYYXWWVVTSRQPOONMMLKJJIHGFEEDCCBB@\[baa`__^]]\[[ZZYXXWVVUUTTSSRRQPPONNMMLKJJIHHGFFEDCCBAA??[Zba``__^]]\[[ZYYXXWWVVUTTSSRQQPPOONNMLLKJJIIHGGFFEDCCBBAA@?>>Ya`__^^]\\[ZZYYXXWVVUUTTSRRQPPONNMMLLKKJIIHHGFFEEDCCBBAA@@?==Y`__^^]\\[[ZZYYXXWVVUUTSSRQQPOONNMLLKJJIIHGGFEEDCCBBA@@??>==<<_^]]\[[ZZYXWWVVUUTSSRQQPOONNMLKJJIHHGFFEDDCBBAA@??>==<<;^]\\[ZYYXWWVVUUTSSRRQQPOONMMLKJJIHHGFFEDDCCBBA@@??>>==<<;:^]\\[ZYXXWVVUUTSRRQPPOONNLLKJIHGGFEEDDCCBBAA@??>==<<;:9]\\[[ZZYXXWVVUTTSRQQPPOONMMLLKKJJIHHGGFFEDDCBBA@??>>==<;;:99\[[ZYYXWVUUTTSSRQQPPOONMMLKKJIHGGFFEDDCCBAA@??>>=<<;;::98[[ZYXXWVVUTTSRQPPONMMLLKJJIHGGFEDDCBBA@@?>=<;;::987[ZZYYXWWVVUUTSSRQQPPONNMMLKKJIIHHGFFECBA@??>>=<<;;:99877ZZYXXWVVUUTSSRQQPPOONNMLLKJJIIHGGFEEDCBBA@?>>=<;;:998876YYXWWVUUTTSRRQPPOONNMMLKKJJIHHGGFFEDDCCBBAA@??>>=<<;::998776YXXWVVUTTSRRQQPPONNMLLKJJIIHGGFFEDDCBBA@@??>==<;;::9987665XWWVVUTTSRRQPPOONMMKJIHHGFFEEDCCBBA@@??>==<<;;:998776554XWVVUTTSSQPOONNMLLKJIHHGGFFEDDCBBA@@??>==<<;::9887665544WVVUTTSSRRQPPOONMMLKKJJHGFFEDCCBA@@??>>==<<;;:99877655443VUUTSSRQQPPOONNMLLKKJIIHGGFEEDDCBBA@@??>>==<;;:98876654433UTSRRQPPONMMLLKJJIHGFFEDDCCBAA@@??>==<<;;:987766544322TTSSRQPPNMLLKKJIIHHGFFEDCCBBAA@??>==<<;::998776654433221TSSRQQPOONMMLKKJJIHHGFFEEDCCBBA@@?>>==<;;:998876654433211SSRRQPPONNMLLKKJIIHGGFFEDDCCBBAA@@??>==<<;::988765544322100RRQQPOONMMLKJIHHGGFEEDCCBAA@?>>==<;;::988766544332110//RQPPONNMMLKKJIIHHGFFEDDCBAA@??>>=<;::98765543322100/.QQPOONMMLLKJJIIHGGFFEEDDCCBA@@?>>==<;::9887766544332110//..QPOONNMMLKKJIHGGFFEEDCCBAA@@??>>=<<;::99887665544322100//.--    ,    +   +      +  )  *) )( ) )('('' '&'% && & %%%$ $%%%$$$ $ $ $$$ " """""##""###""## " "#""##"xwvuvuuts,wxwwvvuutsr+wvutsrq*vutsrqrqq+vuutsrqrqpqppo)tsrqpon)srqpoopoonm)srqponml)rqrqqppoopoonnmml)qponmnmllk)qppoonmlmlkkjkj(poonnmlkjkjjii(nonmnmmlkjih'mlklkkjjihgh'mlkjkjjihgf'lkjijihhgfe'kjkjjiihgfed&kjjihgfed'jihgfgffedc'ihgfedcbcab%hgfedcdccbcaa&gfedcba`&gffededccba`_%ededdccba`_^%edcba`_^]^%dcba``a``_^]\%cbcbbaa`a`_`_^_^]^^]\\%ba`_`_^_^^]\]\\[[%a`_^]^]]\\[Z%a`_^]\[Z[ZZYY$`__^]^^]\\[\[[ZYZYY%`^_^^]]\[ZYZYYXXW$^]\[\[[Z[ZZYYXWXWWV#]\]\[[ZYXYXXWWV$]\\[Z[ZYZYYXWVU$[ZYXWVUT$[ZYZZYXXWWXWWVVUVVUTTS#ZYXWVVUTSSTSSR#YXYXWXWWVUTSRSRQQ#YXWXWWVVUTSRSRRQP"WXWWVVUTSTSRRQOP"WVVUVUTTUTSSRQPO#VUVUUTTSRQRQQPON#:UTTSSRQPONM#8TTSTSSRRQPPOPOONMNMMLM"7SSRQPOPOONMLLK"6RQRQQPPOPOONNMLK#65QQPOONMNMMLKJKJJ"65PPONONMNMMLLKJI#632OONMLKJKJJIH"541NNMLKJIHG#43.NMMLKKJKJJIIHG#430*LLKJIHGFE"31-LKKJJIHIIGHGFGFFE#20(JJIHGFED#210-JIJIHHGFEDC#1/.(HHIHHGGFEDC#10/-'HHGHGGFEDCB#0.-)*GFFEDCBA@"/.,'FFEEDCBA@#.-,(FEDEDDCCBCBBA@?#.--,*DDCBABA@@?@@?>?>".-,,*CCBA@?>=>>"-,++)$CBBA@A@??>=#            !  !   !   ! !  ! !  !    !     !      !     "       !        "     !    "      "   "      "     $    #  $    %     &   % ''())**+,,-././0022444668889:;<dcbba``__^]]\[[ZZYXXWVVUTTSSRQPcbaa``_^^\[ZZYYXWWVUUTTSSRRQQPba``_^]]\[[ZZYXWWVVUTTSSRQQPPOa^]]\[[ZZYYXWWVUUTSSRRQPPOOa`]\ZYXXWVVUTTSRRQQPPONN_\򄅆YXWWVUUTTSRRQQPOONNM^WWVUUTSSRRQPOONNML]VVUTTSSRQQPOONMML!UUTSSRQPPONNMLLK VTTSRRQQPPOONMMLLK zTTSRRQPPONMMLKKJ {SRQQPPOONMMLLKKJI sQPPONNMMLKKJJIH sPPOONMMLLKKJIIH r񐑐NMMKJIIHHG y呐LLKJJIIHHGG y쎍JJIHHGFF W펍&Ee~GFEE ꍌ}|1^ED!⍏~}|{zxxvvtte!₏~}|{zywwuttrqp!h~}{{yxwvvtsrqpo!=~}{zyxwvutsrqpon!~}}{zyxwvutrqppnnl"}~|{zyxwvutsqppnmlk"c炁~}}{zyxwvutsrponmlkj"z~}|{zyxwvusrrponmlkji#]~}|{zyxwutsrrponmlkjig#%|~}|{zxwvutsrqponmljjigg$]|{zyxvvttrqponllkiihgf$%|yxwwuusrqpnnmljjhhfed%n~xwvuusrqpnmmkjihgfedc%%}zqpsutsrpponlkkihgfedbb&_wnnotsrqpommkjihgfedcb`&%xnnoqqoonlkjihgfedba`_'?tnnomlkiihffedcaa_^(0nnmlkiihfeedca`_^])ennmlkjihfedcba`_^\\)'nnlkjhhgfdcba`^]][[)cnnmjhgfedcba`_]]\ZY* lnnkggedcba`^]][[ZX+Cnnmheccaa`^]][ZYXW+ ^nnldcaa_^]\[ZYXWV, knnkb`_^]\[ZXWWVT-Innmd_^]\[ZXXWVTT-gnnj^\\[ZXXWVUTR. nna\[ZYWVUTSRQ/Vnnk`ZXXVUUSRQP/ cnncXWVUTSRQPO0 _i_WVUTSRQONM1>WUUTRQQONML2LUTSQQPNMLK3$TSQPONMLKJ3:RPONMLKJI4 FONMKJJIH5!NMLJJHGF56KJJIGFE6KIHGFED7HGFDCC8%FECCB80DCB@9.AA?:-?>;+< &= ;;;a:8o5T3h&18/ځ,- *+ )(Z! $qB [/   A !!.""##+$$-%%)&m&'X'())m)*&+i+,,--.R/ / 0, 1 1 2 3R 4j55 67+8#9j:                                                                        POONMMLLKKJJIIHGGFFEDDCBBA@@?>==<<;:9887766554332100//.--,OONMMLKKJJIHHGFFEEDCCBBAA@??>>=<<;;:9987765543321100//.--,,ONMMLLKKJIIHGGFFEDDCBAA@@?>>==<;::99887765443321100/..,+NMMLLKJJIHHGFFEDCCBA@@?>==<<;;::9988766544322100//.--,+MLKKJJIHHGGFFEDCCBBAA@@??>>=<<;;::9987766544332210//..--,++**LLKKJJIHHGFFEEDCCBAA@@>=<;;:9887766544332110//.--,++**)LKKJIIHHGFEEDCBBAA@??>==<<;;::99887765544322100/..--,,++**)(KJJIHHGFEEDCBBAA@??>==<<;;:99877665544332110//-,+**))'JJIIHHGFFEDDCCBAA@@??>==<;:9988776554322100/..--,,++*))(('JIHHGGFFEEDDCBBA@@?>==<;::9877654332110//.--,,+*))(''IHGGFFEEDCCBBA@@??>>=<<;;:9987765544322100/..--,++**))(('&&HHGFEEDCCBBA@@?>>==<;;:9988766554433110/.-,,+**))(''&&%HHGGFEDDCCBBAA@??>==<<;::99877665544210/..--,,+**)(('&&%%$GGFEEDDCBBA@?>>==<;;::988654321100/..--,,+**))('&&%%$$FFEDDCCBAA@@?>>=<<;::998776554322100//..--,++**))(('&&%$$##FEEDDCBBAA@??>>==<<;::998877655443321100//..-,,+**))(''&&%$$#"EEDCCBBAA@@?>><;:998776643221100//.--,,+**)(('&&%$##""DDCBBAA@??>>==<;;::9887665543322100/.--,++*))((''&&%$$##"!DCCBBA@@?>>==<;;:9987766544322110//.--,++**))(''&%%$$##""! ?>fec<;;:9988766543321100//..-,,++*))(''&&%$$##""! om.@Qhzfdcba`_]]\ZY7665443322110//..-,,++**))(''&&%%$##""!  nmlkihgfed#Rz_]\[ZZXW5544322100/..--,++**)((&%$$##"!! mkjjhggedbba_^] 9WnWVUT3322110//..-,,++*))(''&%%$##"!! lkihgfedcba`_^\[ZY@oUSS322100/..--,++**))((''&%$$#"!! jihfeedcba_^]\[ZYXWUYRRP2110//.--,+**))(''&&%$$#"!! iggfddcba_^]][ZYXWUUSS)nON00//.--,,+*))('&&%%$##""!! hgfedcaa__]\[ZYWVVTSSRQP=..-,,++*))(('&&%$#""! ffdcba`_^][[ZYXVUTSRQPONM&n--,++**)((''&%%$##"!! edcba`_^][ZZXWVVUSRQPOMMLKa,,++*))(''&%$$#"!! dcba`_]]\ZYYXVUTSRQPNNMKJJHG`++**)((''%$##"! cba__^\[ZYXWVUTSRQPONLKKIHGFn*))(''&&%$##"!! b`__^\[[YXWVUSSRQONMMKJIHGFDD t*(('&%%$#""! a`^]\[ZYXWVTTRRQOOMMKJIHGFDDCB6(('&&%$##"!! `^]\[ZYXWUUSSRPPOMLKJIHGFECCB@?o(''&%%$$#""!  ^]][ZYWWUTSSQQONMLKJIGFEDCBA@?>H&&%%$$#""!! ]\[YYWWUUTRQPONMLKJIHFEDCBA@?>=<%%$$##""  \[ZYXVUTSRQPONMLJIHGFEECBA@?>=;;f$$##"! ZZXXWVTSRQPNMMKKJIGFEECBA@?><;:9'$##""!! YXXVUTSRQOONLKKJHGFEDCB@@?==;;987#"!!  XWVUTSRQONNLKJIHGFEDBBA??=<;:9976n"!  WVUTSRPPONMLJIHGFDCBB@@?><;;986544!! VTSSRQONMLKJIHGFECBAA@?==;:9865543! UTSQQOOMLKJIHGFECBAA?>=<;:88754321TRRPONMLKJIHGEDDBA@?>=<::887653210RQPONMLKJIGGFDCBA@?>=<;:987543210/QPONLKKIHHGEECBA@>>=<::976543210/.PONMKKJIHFEDCBA@?==<:997754321//.-ONLLKIIGFEDCAA@?=<;:9876543210/.-o NMKKIHGGEDCB@@>>=<::87653310/..,+* LKJIHGFEDBB@?>=<;:986654310/.--+*)   KJIHGFEDBA@??=<;:987654210/.-,+*)( JIHFFECBA@?>><;:987643210/.-,+*)( IGFFDCBA@?>=<;9987653220/.-,+))'&  HGFDCCA@?><<;9986643210/--,+*('&%   GEDCBA@>>=;::876543110/-,,+)('&%$ FDDBA??><;:9976543210/.-+**('&%$  DCBA@?><;;:976543210..-,*)('&%$#*  CBA?>>=<;:876542210.--+*)(&&%$""G B@?>><;:986553221/.-,+*)('&%$#! d A??=<;:987653211/.-,+*)(&%$$"!!m  ?>=<::986654210/.-,+*)''%%##! c    ?<<::986553220/.-,+*)'&&$##!     =;::987544210/-,,*)((&&$#"!     <::876544210/.-,+)(('%$#!   ˀq_,2=+*)*(b&%e#F"r! J m  !!!"""""""""~"^"I!!K   n)###### # ## "#" ##$##$ $$#$ %% % $ $ %&&%%&&' &&'( '( ( ) )) )2 +13 3244433535 5 450,+**)'BBA@A@?@??>=<=<<",+**)'AA@@?@??>?>=>==<;#+*))(&@@?>>=<;:#*)(('%"??>>=<;<;;:9#)(''%>==>==<<;:98"('&% >==<<;<;;::9:99887"('&&$#<<;:9:99887#'&%$!;;:98776#&%$"!;;:9876565"&%%$##"::898876545"%$##"998776543"$#" 88765432"$##""!877656554544332##"!! 6654321#"! 5543210#"!!454433210$! 4433210/$ 432322110/./..# 22110/.-$2110100//.-,#00/.-.--,+#//..-,++$/..-,+,,++**$..-.--,+**)$--,-,++*)($,,+*)('$,++*)('%++)*))('&%*))('&'%&%))('&%&('(''&%%$&''&%&%%$#&&&%&%%$#"%&&%$%$$#"!"%%$$#"##""!' $$##"! '##"! & #"!! ! & "!!  ' !  (  ' ' ) )  ( ) * *   *  + + + +,,-,--// / /  0'>=*=:; ;<=        !$'  &)#R9$$> ,:?;987654320//.,++)('&%$#"!   )87654320/.-,++)('&%$#!!    '654221/.-,+*)('&%##!  43110.-,+*((&%%##"     #21/.--+*)('&$$#!   "0.-,+*)(&&$##!     -,+*)('&%#"!     **)(&%$#"!    )''%$#"!     &%$#"   $#!     "                         # '+77:  U+ m + 5  m5$5!5%"9I,+.A 3a;}X646655775;6>=9 ~  4 4  4    5   5  4 5 65567899:: A;;<<=== @@head     TzzͳͿ{:{J}%5[cs͓̓ͣ8Jbd\=,Fvʒm6,) -k|4'%[ }#("+= @V8g,z^:FV G! o!&"C""">#y#$#E#N#M$ c$$$%__ aa=7 4 1  0    .  -  +  *     ( &     &    %  #         #       !    !                                             PghaC%    Lz˕r<2#    4p뾀;.   ` Á)/   3C F[  ?k  3  &  ~  c  @    K  !  [      L!  t!  -"   H"   "  ""   D#   }# $   %#  J#  S#   R$ g$ $  $% __  aa=[ch7^hu5`m2Rh|/\m.Zn-j*dz*m'by&i%n$s$v"x"x!wspm~~h~~}~}}~}|t~}|{zm󁀀~~}}||{{zd𾮯~{zzyu⅄Ʋxyxwwl۹wwv| ޹yup̖|fڢ{qgrcp|mv~h~~p~~x~~} j~}}|!p~}}|!v}}|{"h~~}||{|"n~}||{z"q}}|{zz"v||{zyz#h||{yyxy#m|{zzxwz$p{zyxww#rzzywvv#uzywvuu#gzyxwvuv$kywwvuty$mxvvuusr$owvuttsr$pvvussqq%pvttsrqp__ qussrqpoaa=l752 0= ." -+*(W'&%$#"! y! !'""#%$%%1&&'')((B))+^**,&+++-),,,,. -k------FZ`~vF/ 6mvF)4|k- &#} [# =݅+ V@#g8s#s,uu^^zGG^;&;:/!pw"F%%V - .G .o /& /C / / 0> 0y 1 0 0E 0N 1M 1a Ш}U33U} b8LL?*.G\f^@b Y$1EtֽtEL_/Y <"2Ȃ2EQ< cШ}U33U}c2K   /    +    (  %   #    !                                                                                                                                                 "K_ezK        h D Lr -{ V 8/i P4ccl{3.J1 ݓ1 1 1'_ 28ߩ5 x6a)-x qtsrqpooa##aqsrqqoonrsrpponm__rqqponml##qrqpnmmkponmlk__"ponmlkjwonlkkiaa*onmlkkiiaamnmlkiih__lmlljihgmkjihhflkkjihgfxmkjihggetSmkihhffekmjihgfeddlihgfedcbV khhgeedca ihgfedcbas& hgfdcba`g  jfedcba`_#lfecba`__~ 5lddcba`_^oMMjdcba`_^]] Jfbaa`^^\[z ;jca`_^]\[i C 6ulba__]][[Zv  Sja`_]]\[ZXq  |f`_]\[ZZXZn { {j_^]\[ZYXWq ' pk_]\[[ZXWWR8& . lc]\[ZYXW/,fujxh. hj\\[ZV.y˪m + Pj][ZXƪ_ 2   "Ue[X$cŏolN IkU'N 3.p}'8>SWNy  5 0ː  0~?--       ") # 5  ! *  ,   ////////////-----k- -.,,,),-++&+,*^*+)B)(()('()7(()))))))7))('h&%$#"Tj!w$%  X˻b8LL?*.G\f^@bX` Y$1EtֽtEL_/Yf <,"2Ȃ2EQ< N #,9P0Kcc2K Z EX` 3'f y l0 $ { R  n S  m$"  [    a VC + 6- i =1 1 ` D=  nG[ $ L{ %B* Kވ9-Q#sڱm,Q j' \ g_sx 뽿Ѭr.oi "R oAF"`Uwu!k%!c/ 0L{@i*H漣V o4 ĒN b ԧq8 9 ӣn91" S  K iBk ^< +l v .@c -XmM( #CvrdNc>MȠJ4 }(򻼸MeL4  X˻b8LL?*.G\f^@bX` Y$1EtֽtEL_/Yf <,"2Ȃ2EQ<M !*5M.Kcc2K׹T EX`ݲ0'fވy e0 # } zT h V g#&[  cVE.2-k~<4/_ B@gF\' N{ '>* Mވ9-Q!nٯi +Le$ W ߏaYlq ݲĢl+ic"Ni>A"ZPpn!d#!], -Hs< cz'DᜉR h2 ḉI ڞ\ zȝj5 6 ǚg6. N G c>یd Z8 *f o .?]  & `<0G0x޴&1aI3  X˻b8LL?*.G\f^@bX`MMNNOOPS Y$1EtֽtEL_/YfKLLMMNNQ <,"2Ȃ2EQ<KKLLMMOEJcc2KJJKLM  EX`IHIJJKKL!fGGHIIJyFGHGHIIJ %EFFGGHH EEFGGI CCDDEEFH  ~BCBCDEEJ$$~@ABBCCDL66 Y?@ABBCNHL" [P??@@AABQ$ae, ==>??@@AU2ol, <<==>>?@YL|x Vm;<<==>>?Zt{[9:;<<==>Y -899:;;<<=T8d87899:;;Czѣ#[67889::LD56767899U&\745566778Yc233556678U =22334456A>y0112344OK//0022344X k1../001123U{ J,--.//012B$ h.+,,--//01Sވ9-Q?**++,,-../W   cɔ.)**+,--.> # nҨK )*++--S  s1Q]Pyp ()*++T  &+7hL')+Cѿ &)U̮ 4Sp &Þ" !q~ ! :n`  MV00E:2(                     !     !  ;;;;;;;;;;;;::::::k: :9999)9888&877^766B555 4544575555555557443)u2 1 0 , +uT )j%w!$R#: &P4 T')+e, `J,~.$f//vc g1ܝ1Mu4B6>7  : H &M2 0576 ]%0z`!/"b"& 4r`%4Ԙ$ 4@ع6<7 : E &   +   3   5  3  8  5  6  6  8  6  : : &'() *,F -´ /U 02؝4~6H9 :< & 3z u)(?\ v𽾽}.f b^y!sM4v#Y-.\t.%;%'y *nĩh: .,% ," w3q4'22 V2 1 b/Dt!-r#/Dp-%9$'u *jνd8 .*# *!   !   2  2  5  4  5  "  1  $  % ' ,1 "?!H `y[ 2TQ=tZ!"$Ք&ĨB(ߗ: +MȍO&  @@l-arm     mΉP'Z@q:7530-,** ,)&% $$"                  DE9@ABb7=>_`a5:\]^_`27XZ[\]^_04UVXYY[\]^-/1RTUUVWYZ[\],.OPQSSUUVWYZ[]*+,KMNOPRRTUUVXYZ[))HJKLMNOPRSSTVWXYZ+EGHHJKLNNOPRRSUUWXY)BDEEGHIJKLNNOQQSTUVWX%#$?@ABCDEGHIJKMMOPPRRTUVW$!=>?AABDEFGHIKLLMNOPQSTUW#;<=>@@BCCEFGHJJLLMOOQRSTU#9:;==>?@BCDEFGHIJKLMOPQRST!5789:;<=??AACDEFGIIJKMMOPQSS 3446789:;<=>?ABCDFFHIJJLLMOPQR122356789:<<>?@ABCDEGHHIJLMNPPQ.002245678:;<==?@ABDDEGGHJKLMNPP,-.0123456789:<=>>@ABCDEGHHJKLMNO+,-//123456789:<<>?@ABCEEFGIJKLMN)+,--//12355678:;<=>?@ACCDFFHIJKMM&'))*,,./012345679:;<=>?@BBDEFGHIJLL$%&'(**+-..012346779:;<=>?@ABDEFGHIJK#$%''))+,-./012355789:;<=>?ABCDEFGHIK !"$%&''))+,-./013356789:;<>>?ABCDEFGHI !"$$%''))+,-./012456789:;<=?@ABCDEFGH ""#$%''(*+,-./013456789;;<=>?@BCDEFG !"#$&'()*+,-.012235678::<=>?@ABCDFG!!"$%%'()*+,-./123456789:;=>>@ABCEE ""#%%'()++--/0113466889:<<>?@ABCE!!#$%&'(**,,-/012345679:;;=>?@ACD !!"$%&'()++--/013345779:;<=>?@BB!!#$%&'()++-./012345679:;<=>?AA!"#$&&')**+,./012455779:;<=??A !"#$&&')*+,-./012356789:;<>>@ !##$&''))+,-./012345789:;<>?  !"#%%&')*+,-./023456789:;<>  !"$%&'')*+--./022356889:<=  !"#$%'()*+,-//123456799:;  ""#%%'()*,,-//02345678:: !!#$%%'(**+--/0123556899  "#$$&'()*,-./012345679  "#$%&'()*,--/01244578  "#$%&'()++-./0133467  !"#$%'()*++--/012356 !"#$%''))*,-./01235  !"#$%&()*+,-./0234  !"#$%'()*+,.//0127??   ,     %                                                                                                                                                                                              !" $ &+xyz{}~~$tvvxyy{|}~pqrsu xxy{|}~mnqrstvwxyz{|}~IJklmnopqrsuuvxyz{}}~Fefghijlmnopqrsuvvxyz{|~~ cdefhiijlmnopqsstvwwy{||}~;x bcdefhijklmnopqstuvwxyz{}}yz{ abddeghijklmnopqrtuvwxy{{}~~{|}`abcefghijkmmnoqqstuvwxzz{|~ _`accefghijklmnoqrstuvxyz{||~ ^_`accefghikklmnpqrstuwwxzz|}~ ]^_aacdefghijkmmopqrstuvwyy{{}~ ]_``bcdefghiklmmopqrsuuvxyy{|}~ [\^^`aacdefgijkllnopqsstuwwyz{|}~ []^_`abcdeggiijlmmoprrsuuvwyz{|~ Y[[\]_``bceffhhjklmnoprrstuvxyz||}~ XYZ[\]_`abceeghhjklmnopqstuuvxyz{}}~ WYZ[\]^_`abceffhijklmnpprrsuvwxy{{|~~ WYZ\]^_`abceffhhjklmnoqrstuuwxyz||~ UWXYZ[[]^_`abcefghijllmnoqrstuvwxzz{}~ TUWWXZ[\]^_`abdeeghijklmnpqqrtuvxyzz{}~ TUUVWYZ[]]^_abbddfghijklmopqrstuvwxz{{}~ STTVWXYZ[\^_`abbcefghijlmnnpqrstuwwxz{|}~ QRSTVWXY[\\]^`abcdefgiijlmnopqsttuwxyy{|}~ PRRTUVWXYZ[]]_`abceefghikllnopqsttuwwxz{|~ OPRSTUVWXYZ[]^__abceeghhjkkmnopqrsuvvwyz{}} NOQQSTUVWYY[\]^_`abcdefgiiklmnopqrtuvvxy{{|~ MOPQQSTUVWXZZ\]^^`abcdefhijklmnoprrtuuvxyz{}}~ MNOOPQSTUVWXY[\]]_`bbcdffhijklnnopqsttvwxz{{}~ KLMOPQRSTUVXXY[\]^_`bccdfggijklnopqqssuvwxy{|}~ KLMOPQRSTUVXYZ[\]^_aabcdfghijlmmnoprstuvwyyz|}~ IJKMNOPQRTUVWWXZ[\]^_abccefgiijllnopprstuwwyy{|}IJJLMNOPQSTUVVXYZ[\]^_`bbdeeghikklnopqrstuwxyz{{HIJJKMNOPQRSTVWXYZ\\]^_`bbdefghikklmnpqrstuwxxyFHIJKLMNOQRRTUVWXYZ[\^__`bcdefhijkllmopqrtuuwxEGHHJKLNNOPQSTTUWXYZ\\^^_abcdefhiiklmnoqrrsuvwEGIJKLMOOQQSTUVWYYZ[]^_`abcdefgijkklnoprsstDFGGIJKLMNPQQRTUVXYY[[\]_`abcdefghjklmnoqqrCDDFGHIKLLMOPQRSTUWWXY[[]^_`abcdffghjjlmoppBCDDFGHJKKLNNPQRSTUVXXY[\\^_`abcefghijklmn@BCCEFGIJJKLNOOQRSTUVWXZZ[\^_`acddefhijll@BCDEFGHJJLMMOOQRSUVWXXZ[\]^_`bbdefghij?@ABCDEGGIJJKMNOPQRSTVVXYZ[\]^_`abddfgh>?@ABCDEFHHJJLMNOPQSTTVWXYZ[\]^_`abdef=>?ABCDEGGHIKLMNOPRSTUUWXYZ[\]^`aacd<=>?@ABCDEGGIJJLMNOPQRSUVWXYZ[]]_`ab:<<=?@ABDEEGHIJKLMOOQRSSUVWXY[[\^__9;<=>?@ACDDFGHIJKLMNOQRRTUWWYY[[\8:;<=>@@BCCDFGHIKLMMNPPRSTUWWYZ[79:;<=??@ABCDFGHJJLMMOPQRSTUVWXZ789:;<=>?ABCCEFGIIJKLNNPQRSTUV 6789;;<=>@ABCDEFGHJKLMNOPQRS"56789:<<=?@@BCDEFGHIKLMMOP$356789;;<=?@ABCDEFGHJKLM&{:: f!   "                                                                                                                                                                                                                                                                                                                ,n!*My~nWM<  ߍ~}|{yxx B܌~}|{zyxwvtsrOی~}}{zyxvuusrqpڋ ~~|{zyxvvusrqpox;~}||{ywwvtssqpon{zyx}}{zyxwvutsqponm}|{zyxޏ~~}{{yxwvutrqponml~}||{yxw~|{zzxwvutsqqonmmk ΀~}{{zyx~||{zyxvutsrqonmlkj ́~~|{zyxw~}|zzxwwutsrqpnmlkki ʃ~}}|zzyw~}{{yywvutsrqpommkjihɃ~||{yxxv~}|{yyxvuusrqpommlkihgȄ~}}{zyxw~}|{zywwutssqponllkjigfȃ~}{zyxww~|{zywvuusrrpommljiiggeŅ~}|{zxxv~}||zyxvutsrrponmlkjhhffeĆ~}||zyxwv~}}{zyxvuutsqponmlkjhhgeecÆ~~}{{yxwvu~~|{{yxwvusrrppnmlkjihffecbą~}|{zyxwut~||zyxwuutsrqonmlkjhhffecba~}}{{yxwuut~}{zzxwvutsrqonmlljihgfecba`}||{yxwwuts~}{zzyxvutrqqpnmlkjihgeedba`_~}|{zxxwvttr~}{{zxwvutsrqpomlkjihgfddbba_^~||zyxwvusrqp~}|{zxwwutsrqpnnmljihgfecbba`_^~}||zyywvvtsrqp~}|{yyxwuttsqponmljiigfedcba`^]\}|{zyxwuusrqpo~|{zxwwuttsqponllkihgfeecba`_]][}||{yxwvutsrqpnm}}{zywvvusrqponmkkjhhgeecba__^][Z~||{yxwvutsrqoonm~|{{yxvvutrqponmlkiigfedcba`_^]\[Y}|{zxwwvttsqponml~}}{zyxvuutrrponmlkjihfedcba`^^]\ZZX~|{zyywvutsrqoonllj~}{{zxwvttsqponnlkjihffdcbb`_]]\[YXW}}|zzxxvvtsrqponlljj~}|{yxwvussqqponlkjiggfdccb`_^]\[YXXV~}|{zxwwvttrrponmlkjhh~}|zyywvutsrponmmljihgfdcbaa_^]\[ZYXVU}|{zyxwvttsrppnnmkkihgf}|{yywwutsrpponlljiigfeccba_^]\[ZXWWVU~}|{zyxvutssqponmljihggf{{zyxwutsrqponlkkihgeedbb`_^]\[ZYXVVUT}|{zyxwuutrrppnmlkjihgfdcyxxwutsrqpnmlkkihgfedbb`_^]\\ZYXWVTSR~||zzxwvutsrqpnmlkjihgfedcbxwuutrqpomllkjihfedcb`__^\[ZYXWVUTRR}|zyyxwvtsrqponmljihggfdcbawvusrrqonmlkiihfedcba_^^\\ZYXWUTTSQP|{zyxwvussqppnmlkjihffecbaa`tssrponlkkjigfedcba`_^][ZYYWVUTSQQOzyywvutsqqpomlkkjhhfedcaa`^]rqqonmlkjhgfedcba`_]\[[YYXVUTRQQPNywwvussqponmljihgffecba`_^]\ppomljjhgffdcba`_^][[YXWWUTSRQPOMxwvutsrpoonlkjihgfedcb`__]][Znmlkjihgfecba`_^\\[YXXVUTSRQPNNLvutsrqponlkjiigfedcb``^^]\[YXlljihfeddca`_^\[ZZXWVUTSRQOONLKtsrrponmlkiigfedcba`_^]\[ZXWVjihgfedbb`_^]\[ZXXWVUSRQOOMMLJsrqonmmkjhhgfedcba`^]\[ZYXWVUhgfddba`_^]\[ZYXVVTSRQPONMKJJqponlljihggedcba`_^]\[YYXVUTSfedba`_^]\[ZYXWVTTSQPONMLJJHnllkjiggeddba`_^]\ZZYWVVUTSQdcaa`^]\[ZYXWUUTSRPONMLKIHGlkjihgfedcb`_^]\[ZYXWVTTRQPPba`_]][ZYXWVUSRQPONMLJJIGG jihgfedcaa__^\[[YXWVVTSRQOON__^\[[YXWVUSSRQOOMLKJIHGE gfeecbaa_^]\[YXWVUUTRRPONMLK\[[YYWWUTRRQONMLKJIHGFD edbba`_^\[ZYXWVTTSRQONMLKJI[ZYWWUTSRPPNMMLKIHGFDCba__^][ZYYWWUTSRQPNMMLKIHZXWVUTSRQPOMMLJJHGFDCB`^]\[ZYXVVTTSQPONMLKIIHGFVUTSRQPNNLKJIIGFECCB[ZYXWVUTSQPPOMMLKIHGFEDCSRQPONMLKJHGFEDCBAd@6UⶏgG@@- 'u8 "# .p"/>$@"&-;&,5' %' (())*******)))(((''&%%$##"!  !"#$%&())+- ~=;974)'%#"   &%#!                               =oa.:nml];8mljiih2 5lkjihfedE3kjihgeddbaC8)jihgfecba`_^A5'ihgfecca`_^]\[>2%hgfecca`_^]\[ZYW</#gfedcaa_^]][ZYWVUU3.,!fedcb``_]][ZYXVUUTRRF!+ edcaa`^^\[ZYXWVTSSRPON6%dcba`_^][[YXWUUSRRPONNLK4$cb``_]\[[YXWVUTSQQONNLKJIH2"ba`_]\[ZYXWVUTRRPPOMMKJIHGED/ a`_^]\[ZYWWUTSQPONMLLKIHGFEDBA-`_^]\ZYYWWUTSRQOOMLLJJHGFECCB@@+ _^][[ZYXWUTSRQPOMLKJIHGFEDCB@?>==^]\[ZXWWUTSSQPOMMKJIIGFEDCAA??=<;:( ][ZYWVUUTRQPOMLLJJIHFFDCBA?>=<;:980 \[ZYXWVTTSQPPNMLJIHHGEDCBA@?><<:98765\[YXWVTSRQPPNMLKJHGGEDDBA@?==<;:876542#ZYXWVUTRRPONMLKJHHGEDCBA@>>=<:987654321!YXWVUTSRPONMLKJIGFEECBA@?><<:987654321//YWVUTSQQONMMKJIHFFDCCA@?>=<;:87655321//--WVUTSQQPOMLLJIHGFEDBB@?>=<;:976543210/.,,*$VUTSQPOONMKJIHGFEDBA@?>=<;:977643210..-+**(UTSRQPOMLKKIHGFEDCBA?>=<;:987553210/.-,+))''TSRQPOMLKKIHGFEDCBA?>><;:987653310/.-,+))''&%TRQPONMKJIHGFEDCBA@?=<;:987654210/.-,+))''%$$" SQPONMLJJIGFEDCB@?>=<;;987654310/.-,+*(''%$#""QPONMKJJIHGFDCBA@?>=<::876532210.-,+*)('&$#"!  QONMLKJIHFEECBA@>>=;:987654321/.-,+*)('%%$"!! ONNLKJHHGEECBA@?><<:9886643110/--++)('%%#""  OMLKJIGGEEDCA@?>=;;:976543210/-,,**('&%$#!! MLKJIGGFDDBB@?>=<;:977543310/--++)('&%$"!!  LKIHGFDDCAA?>=<;:976543210/.-++)('&%$#!! KJHGFDDCBA??=<;:977554210/.,+**)'&&$#"! JIGFECCB@@>><;:987653210/.-,+*)'&&$#"!  JHGFEDCB@@?><;:987543210/.-,+))''&$##!  IGGEDCBA@?><;:987654320/.-,+*)'&%%#"!  HFEDCBA@?>=<:988653220/.--+*)''&%$"!  GEDCBA?>==;:997654321//-,+*)('%$#"! EDCBA@?>=<::87654320//-,,*)('%%#""  EDBA@?=<<:9986553210/--+**('%%$#!! DCA@?>=<;9976543210/.-,*)('&$$#"  CB@@>=<;:887544210/--,*)('&%$#"  A@??=<;:977643310/.-++)('&%$#"  A?>=<;:987653210/--++*)('%$#"!  @>=<;;987653210/.-,*))''%$#"! C<!9/7#4 2 )0 9-+j )g '{%y #s !sP  I" #G%&'(')'*<,-U-'. / 0U 0 1 2 3 3 4445B55J66_7777788m88       (   !"$%&&()*+,-.012  ""$%&&()*+,..01  !"$%%'()*+-..0  "#$%&'()*+,-. !""$$&'()*,-.  !""$%&'))*,,  "#$%''))*+  !"#$%&()*+  !"#%%''()  !#$%&'()  !"#$&'(  !"&  )$-.13578< ~3456789:<==>@ABCDEFGHI(12456789;;=>?@ABCDEF889;<=$122457789;<=>?@ACD,011345678:;<==?@./012346789::;<0./012345788:2-./01244674,-./02336+,-./18*+,;) ~  $79;=WVTSRQPOMMLKJHHFEECBA@POMMLKIHGFEDCB@@TRQPONMLKJHHFEECCA@?>=MLKJHGFEDCBA@?NMLLJIHGFDDCA@?>==;:IHGFEDCBA@>=$GEDCBA@?>=<;988FEDCBA@?>=6DCA@?>=<8@?==<;:<;::<:8 / 1 3 /79;=         %( [?=<<:987654320/.-,+*)(&%$#"!  =<;;987653210//.,+*)('%$#"!  =<:9876543210.-,+*)(&&%$"!  ;9876542110..,+*)(&&%$""  ;9877542210..-+*)('%%$"!   :876543110.-,+*)('&%$#"   987643210/.-,*)('&$$""!  87543210/.,,*))'&%$""!   7644210/.-+*))''%$#"  320/.-,+*)(&%$#"!  1/.-,+)(''%%#"!  ,+*)('&%$#!  )('&$#"!  "!  '  Y885~5^4I43322x/+'# ( Z@@body     ut t, -=M |0AE4OP-P=[a_gm ? < = < < :  :  9 9   :  8  8  7   7 7  6  ?<<<~<}~}:}|:|{9|{:|{zz:z{zzy8zy9yx8xw8xw7xwwvvu6wvvuvu ?<=<<;;:::998877 .":[v+ /Hl)&Ed'"Go$9h " &N  +Z +_ &\R? +hI(i!?"W$'o% 6' C( L) X* a+ d, d.c/`0V0M2 C242(5n5V69 3   1    -   +    )  '   %   "  !                                                                                                                                     )@`z      #6Nq   -Ki    )Lt    #?m   -S      2_   2d   ,a     &X     E   1m   N    /n!    E"    \$   .s%      ='   I( Q)    ]*     "e+     "h,    "i.  g/  e0   [0  S2 I2 ;2  .5  "r5[6930-+)&%""񏎍  ~ ~} ~}}|} ~~~}|}|| ~}~~~񀅏 ~~~~~}~~~}~}~~}~~}|}!~~}~}|}|"~}~}||}$~}~}}|{~%~~~~}}|{|{'~~}|}||{zz(~}|}||{|{{zz)}|{z*}||{{zy{+|{z{zzyy,|{zzyx.zyzyyxyx/yzyxyxx0yxwv0xwvv~2wvwv{2wvvx2vuvvw5uv5t|694 1 .+)'%#"  !"$%&()*+,-./0 1 2 2 3 4 5667899:;;<=== +qT5 '̳dA, # ĭ\? !ؽf> ݸ^2ѨvD༈O# ŐS$ !ǏP"ĆE$u4 &ۣY!(ł< *Z +{2 -ܙG .^/s)1ц32ޕ< 3F4O5R7R8R7L8D 9<::==> / )  &     #    !                                                                                                                                                                                                                 ûuY;&  ͵hF2   ůaE& ٿjD" ޺c8 ҪyI%ྋT)ƓW*!ȒU$ "ʼnJ $x9 &ۥ]' (ƅA )^% *~7-ܛL.b$ .v. 1҈71ޗA2K3S4V6V7V7P8H9@::==>/*&$!~~~}~}|~}|{~~}~}}||{z~}|{zyy~}|{|{{zyzyyx~~}|}||{zyxw ~~}~~}}|{zyxwv ~}~}}||{z{zzyxwvuvuu ~}|{zyxwvut ~}|{zyxwvuuts ~}}|{|{{zzyxyxxwwvutsr~}~|}|{||{{z{zyyxwvututtsrrqrq~}|{zyxwvutsrsrrqqp~}|{{zyxwxwxwwvvutsrqpqppoo~}|}||{zyxwxwwvutsrpqppopoonnm}|{|{{zyxwvutsrqponm}||{zyzyyxwwvuvuuttssrqrqppopoonnml|{z{zyzzyyxxwxwwvuutsrssrrqqponomnmmlk{zyxwxxwvvuvuutstsrsrrqponmlkj󂁀~||ywvuuttstssrqrqqppoonmnmmllklkkjjihzutssrrqponmlkjkjiih˽vtrrqponmlkjihiihgg ѻwsqpopoonmlkjkkjijihhghgfgupnonnmmlkjihgf־zpnmmlkjihhgfeͰ~plkkjkkjjiihgfedغojjihghgfgfeefeddcݾ~ojiihhghggffededdcc!޽zlhghggffededdcb!ܷtigffedcba#Ӭmffeedcba&ǚxgddcbcbba`'۳mdccbbabaa`a``_)ɚuebba`_^*ۭgaa`_^],鿌k``__^].͙qa_^_]]\.ئxa]^]]\1}b]]\[\\[[1껂c\[[Z[Z2d[[ZZY3ǍeYYX4ʎdXX7ɍcXWW7ɍbWV7ɉ_V8‚]9|::==>/*'$!!#%&(*+,./02 3 4 5 6789:;<<=>? =3<%;n:Y:? 9===<;:998876654442322 1 00//.7 .*-p-\-B-g=f=fe<ed;dc;dccb:bcbba9baba``8a`9`_``_^7_^_^^7_^_^^]]7^]]\]\\5]\[6\[Z5\[ZY4[Z[ZZYX3ZYXW3ZYXXWXWWV2YXWV2XWXWWVWVVUU2XWWVUT1WVUTS1VUTSR/VUTTSTSSRQQ/TUTSTTSSRQRQQ/ZSTSSRRQPQPO.uWRRQPOPPO.kTRRQQPPON.ܜbPQPPONM.ҍZPOONML-zUONONMNMMLMLKK,===<;;:9987766 5 5 4 3 3 2 2 1 1000//..--?<< E;&:`:79v9C88 K7 7 L6!7 I66@5v515b4!4G4w3+3 V3|2-2 W2y1'1L1 l0040 T0l/~/. /I / _ / k .z .( .> . P . ] . c .j -w -$ -1 -= -G - P - W - \ - _ - - ` .Z .[ 7 6  6  4 5  4 3J3 ,3d2 =2 z2H2 &1P1 &1Q0'1N1"1 E0y0 60f0 '/L/z/ 0/Z/. 2.[.|. ,. P.p-- 9-X-o-- 2 -M -b ,n ,} ,- , B ,T ,` ,f ,m ,z ,( , 5 , @ , K ,T ,Z ,_ ,b , +c +] +^ 7vut5vuututst5utustss5tuttstssrr4tsrqs4srq|3srrqqpqu3rqpq3qpox2qpor2pon|2onoonmmq2nm~1nmlq1mlmlm~1lkq0mklkk}1kjin1kjjix1jihm0iht0ihhgi0hggo0gffhy/gfei/fep/ede}/eddi/dcn.cbcd}.cbbg.bal.ax.a``d.`__g-_m-^a~-^]]b-]d-\j-\[]x -[Z_ -Za ,ZYYa ,Xg ,XYr ,WZ ,WV[ ,VU[ ,VU\ ,UT^ ,TSc ,SUk ,STs ,RVz ,QU ,PV ,OU ,NT ,NT ,M\ +LMS +LKL +KJ 7665 5 5 4 4 4 3 3 3 3 2 2 2 1 1 1 1 0000/////......--------,,,,,,,,,,,,,,,,,,+++ >6+7j8 K9,:n:;<<= ~ D6 17n8P92:r:;<<= ~tx6su7r8v9::;<<= ~,8t7V7:6ۀ 5Y554v3K 3'2^211k170 o0 7/ p/ 5. i. -- ] - !, K, v, 6+ ^ +*A*b * )@)\ ){(7(O (e($'<'M'_'&2&A&K&\&w%(%6%>%C%K %Y%l$$%$+$1$5$8$:$h $;$*%+%0 -w#+Y+= +ۂ$+\+8 )x *N*+)`)5(m(: ( q' : ' r& 8 ' k' 0& _% %& N & x& 9$ `%!%C %d$"$B #^#|#:#Q $f#&"?#O "`# #4#C#M "]"x!*!8!@!E!L !Z"m""&"-"2"6"9"<"i "<!+!,!mQNNMMLLKJK,aNLLKJ,щVLLKJI,tOKKJIJIIHIH*`LJJIHG+ԉTJIIHGF+nLHHGFEF)YHGGFFE*}MFFEED*bHFFEDECC)׉PEDDCB)hEDCCBA(ݒQCBBA@(jEBAA@?' OAA@@?( iC@@?>( N@@??>>==' fB>>=<=<& J>==<<' _?=<<;' ؃E<<;:& T<;::9% sA::99& J998& b;887% ہA88776%N87665%i;66554$?6554%M6443432#f834322$|<332121#G221$^6100$p800/$ ,* , ,h - C -& -r . D .# .\///a0.0Z1'1 F2l3.3 E4\5 q5,536 :7 >8 ?9 ;: 3;<>+KJ +JI +I +IHH +HG +GF +FE ,Ep ,D_ ,CV ,CP -BGp -A@Z -A@N .?Eo .?V .>=I/=?\/=;I0;<[0:E}19:T198?m287H378W36*+++++++,,,,---...//001 1 2 3 3 4 5 5 6789:;<=>=;9*y8 f7O6 94#g3D1#d0 :. M, $Y+ )_' *]% $Q#>{"*] :l ?h6Y!&Ca $$9Qo) "2D\r, )8KYco3 "+26=;9,z8"g7P6 ;4%h3E1$e0;.O, %Z+ *`'  +^%  %R# ?|"+^ ;m ?i7Z'Ca $9Qo "2D\r  )8KYco"  "+26& ,5:=;9M8-D7)*:k6)(1X4(''+D}3'&&'4_1&%%*By0$%.U.$##'7d,"!"!'@n+! ! &Cr'  &Cp% $Odz#*3AS`iu" !*3:=&     +      0  9~ ==;:976 4 2 1/-+(&#! #',1 9 ;3=l1\>0~5 =l.֙P=d,ީd' 2p1.v7-ݭr7,՟f0*ÊS"  &Ңl: #ϫyI !ƤvJ'гe@" ʯmJ. DZz[@* ǻxdL7' Ļse\Q?-" %9:;;:73-%  ;3=l1\>0~5 =l.֙P=d,ީd' 2p1.v7-ݭr7,՟f0*ÊS"  &Ңl: #ϫyI !ƤvJ'гe@" ʯmJ. DZz[@* ǻxdL7'Ļse\Q?-" $9:;;:73-% $.'7 ;3=l1]>07=l.֚Q=d,ުe) 2q2.w8-ݭs8,՟g1*ÊT"  &Ңm; #ϫzJ! !ƥwK'гfA" ʯnK0 Dz|\B+ ȼzfN:)Žvh_UB1% ?@AA@?;81*  ""&* <:864 1 /-*'$ "(*%)%)%(%%%%q%S %:%,%!%_&;&(&a'9'|'G(߃"(J )| )?* f* *+ F , c- {!- 0. ? /J 0S1X1X2S3J5ݕ@ 6ς2 7h#8O94 ;+ * * ) &  !q!S !:!,!!"`";"($b$9$|%G$߃"'J &| '?( f( *( F ( c+ {!* 0, ? ,J ,S-X0X.S3J2ݕ@ 3ς2 3h#5O94 ;>!=!= ;!7!2!}+!a!I!;"1"j "H"5#j$D#݃)%Q $.  &S  &ۂ+ &H  ' m ' 3 ' M ( i  * ( ) 6 * E,N,W-[.[.V/M1ݗC1τ6 3j&3Q567 79;=!!!!!!""""###$$$%%&&''(()**+,--./0 1 2 3 4 5789;<@@ l-arm II     ttyyuEuUueuuuuuuvvvwyuyyy 2yy22**. *{{'  %#!tt&& m m""$$&X&X(((**^*^* ,,K,O,/. . .7 6.T U.g y.y . . . .% .& ." . . . . y.y U.U 6.6 . .  . /,e,K5,, *^*^/*'*(((V&X&$$""l m#&rt!#%  '{{* .**22yj(@@ New Layer#1     zuz{{zzz{ {{-{={M{]{m{}{{{{{................@@openmsx-debugger-0.0.0.svn20141006.orig/resources/icons/symfil.png0000644000175000017500000000031712414415132024034 0ustar shevekshevekPNG  IHDR 2Ͻ pHYs  tIME.^tEXtCommentCreated with The GIMPd%nbKGD3IDATc?LJ2001 $ I6BL*$&Ar٠U+IENDB`openmsx-debugger-0.0.0.svn20141006.orig/resources/icons/break.png0000644000175000017500000000053412414415132023616 0ustar shevekshevekPNG  IHDRa pHYs  tIME#ש$tEXtCommentCreated with The GIMPd%nbKGDIDAT8c`4$a4o ( vSu 6P  p^Z6{r?4TmAy@T $g}~~A64w@jhg!iF >/ 9C1r V6Dc;hrrve~>q <`^JjiCIENDB`openmsx-debugger-0.0.0.svn20141006.orig/resources/icons/openMSX-debugger-logo-16.png0000644000175000017500000000164312414415132027031 0ustar shevekshevekPNG  IHDRabKGD pHYs  tIME 22KU\tEXtCommentCreated with The GIMPd%nIDAT8Ou{HQtfiVF7(nԊ(RM(CVV6(R2DYE)i2Z0cTX&YrmOgKVKz|CS%8:r)FGI3,IϦIԼzW<԰$<Şs'^i5m?1՟n@?m sޑN`Sڊ9s`Z ӃV] 6_g Ţ^ɠp͈[?]GhA!4p9WZ2AH^YjJzE!-D-n3βUSf DWZ|hwFFC(>e[L|'@'X\|ai*7їU*ǂ+ (uM56fVy bA03IENDB`openmsx-debugger-0.0.0.svn20141006.orig/resources/icons/disconnect.png0000644000175000017500000000125312414415132024662 0ustar shevekshevekPNG  IHDRa pHYs  tIME1aSbKGD8IDATnUϙ  P 4Qp { 4)(5T H(Ia(yq4C`C7к.<<{;otܗ'$D#7m?Rΐ2=5?Uzܗb=`72]ZǶֲ) s)I_IkHk{$`jCse+e+V(X Rc%vbX;K\^PA7[`n0_t4yw$'& +3 IENDB`openmsx-debugger-0.0.0.svn20141006.orig/resources/icons/runto.png0000644000175000017500000000037612414415132023705 0ustar shevekshevekPNG  IHDRR pHYs 7˭tIME6 $tEXtCommentCreated with The GIMPd%nPLTE*Uaaa3ٟB,tRNS@fbKGDaf}9IDAT[c`W#rqqqPd0 3*0 `a(00P j2SO.IENDB`openmsx-debugger-0.0.0.svn20141006.orig/resources/icons/run.png0000644000175000017500000000044112414415132023333 0ustar shevekshevekPNG  IHDRR pHYs 7˭tIME!)tEXtCommentCreated with The GIMPd%nPLTEZ`aaayfDtRNS@fbKGD ٥SIDAT 19D@xkm*%@73@5׸dI4J*Jde4W-d?rs3IENDB`openmsx-debugger-0.0.0.svn20141006.orig/resources/icons/stepout.png0000644000175000017500000000043112414415132024231 0ustar shevekshevekPNG  IHDRR pHYs 7˭tIME2"`qE tEXtCommentCreated with The GIMPd%nPLTE*Uaaa3̙tRNS@fbKGDaQIDAT0 W"d{ȱ(C ,$3cH;KDѯEK `B Q4Dp L1Aݳ:BIENDB`openmsx-debugger-0.0.0.svn20141006.orig/resources/icons/watchpoint.png0000644000175000017500000000074212414415132024713 0ustar shevekshevekPNG  IHDR Vu\sRGBbKGD pHYs  tIME*0f@ےtEXtCommentCreated with The GIMPd%n9IDAT(ϕ;Kqib:4tPDul/AZi,0$;xH@^jIOXI yx1hG?X(Pi>-u)DF0|(%O_|(܁BIENDB`openmsx-debugger-0.0.0.svn20141006.orig/resources/icons/openmsx-debugger.ico0000644000175000017500000036211612414415132026002 0ustar shevekshevek((Lh(F@@(2=@@(o@@h 00f0000h   nhVh(&('(,-+-,./113:<22$$  .09;FHZ^os79RThl}sw]`EG)*           !?AVYqu HK{ ]`  -$$<44MFFhbb}xxurr\XXA>>300   .0PSty vz  JּwvvPNN*)) PR  IM./11DF hkg|}555VVVwvvٶeee맧Y[[ -- <>`c KN') () GImp7ó"""CCCddd껻YZZ055#11 (),.7:@CFIJMMPLODF23 ! ""QQQRR򆆆######100RRQrrrRNN 58kj###?>>```:447hCA&# ,-,NNMnnn!  8KƷ{{{-*&":::\\\|||{{  :<srkiiGEE40,($!(((HIHiijB88  <Y*'򆅅  973/,'$  666WWWxvw  >@zx 0>:62.*&"EDDeffD::?R4,, D@<851-)%"FFFttt䵵@yPMOOO0GC?<840,($  aaa)CG   LJFB>:72/*'#YYZTHGDO˺ "%#!.QMIEA>962.*&"%%%@@@```|rrF_($eee &*(&#!QTOLHD@<841,)%! Hp=:eee -.,*(&$!.ZVRNKGC?;83/,($  ľ&IxFB___ .21.,*(&$" *\YURNJFB>:62.*&# *Ju@=nnn57530.,*(&#C`\XTPLHD@<952-)&" +Kj2-9<:8541/,*( fc_ZWSOLHD?<840,($  yyy-M~JG>@><:8641/-+9ifb^ZVRNJFB>;730+'#  C.,Nq84>DC@><:8632/-flhd`\XUQMIEB=:62.*&" )))8 Po3.7IGECA?=;8642&6sokhc_[XTPLHD@<851-)%! 6Ri($333NLJHFCA?<:864^vrnjfb^ZVSOJGC?<840,($   yyy3 Sbҿ~~~ MPNLJHFCA?=;95z x upmiea]ZVQNJFB>:62.*'# yyy, !TZ <URQNLJHFDA?>;3' { wtolhd`\XTPLIE@=:62.*&" mll(#VQ  TfWUSQNLJHFDB?= C ~ z v rnjgb_[WTPKHD@<840,)$! ooo'$W9nbZXUSQOMJIFDB@I } y uqnifb^ZVRNJFB?;74/,($ lj(&7lj^\ZXVTQOLKIFDB!D | xtplhda]XUQMIFB>:62.*&#]@?('Vne`^\ZXVTROMKIGE-4 { wsokgd`\XTPLHDA=951-*%!d``J(&)) 4njeca^\ZXVTRONLIG;% ~zvrnjfb_[WROKGD?<840,($!ɿ<+* kmjgfca^]ZXVTRONKJB } xuqmiea^ZVRNJFB>:73/+'---1,,Annljheda_][YWTRPNLI  | xtplhd`\XTPMIEA=962(ig0.-7pnpnljhfda_][YVTRPNL0R ~ z wrokgc`\XTPLHD@<4YYYY540/# sossqoljhfdb`][YWTSQNH  } yvqnjfb^ZWRNJE0sssʾC10D {w vsqnmjhfdb`^[YWUSQN?1T~ | x tplhea]YS:$ 632 v | zwusqomjigdb`^\ZWUSQOJ." 3FDLLG@DB=1 BBBssskGE544 9 ~ | z xvsromkigdb`^\ZXUSRP_*'۾KKK000///111:::GGGTTS[[[RRReffghhJ665x ~ | zx vtromkigdca^\ZXVI{y"##HHHjjj̬zzz;876 ~ } z xvtrgYMA!8#!0$$*%$%$$"!! "A<;dddccc 222QQQzzz߾e:8:99:  } w dP)&?43GGGccc~~~ȶ~~XXX666MMM```rrrϰD ;::L qW2.HCDeeekkkZZZNNNGGGDDDFEEKKKUTUbbbsssЖSRS++,PQQvvvxxxzRP><<<| p%!TB@`__lllCCC)))&'HvyV&;I|Z``~~~ܔDDDHHHiiifffRRRȸN?>== w(#YKJlkkhhhA,*;\Z J 9 !**#NRBknj̏m.pv:=%@BӭBRSٴMMM;;;ZXA@65   dKJkkjNNN<I [ZZYYWH2&%fjafDH4735 9< DH,Y\t JqABB///tO{qupt}2Ǿw[Y: "   q96eeeLLL%f^]\[ZYXV\ l2-srվѼbh7|⧨GGHHy| 0aB@+('%"   ihiYYXvvv^^^he_^\[ZYXW[ C?̰FA@:>;߲^^^#&z] ob``bqZ~ b41/-*)&$"   mnnmmm-,- da_^\\[ZX[ n(#if􌅅.1嘘 zLv Ϥ:8631/-*(&$"   ssssssgfgnha`^]\\ZY^C>5g~r '@><:7521.,*(&$!   xwwwwxLLL khb`_^]\Z\ l"rp()lr7(((]\57 Q~FDB@><97521.,*(&$!  |||{{z??? gfa``^]]Z`?;qrrDI,,,] LMKHFDB@=<97520.,*(%#!  ~~~}}~:99 yfcba`_^][b VS()(gp .0 `]QOMJHFDB@=;97520.,*(%#!   zzz;;; mhccba`_^^v0*!/0EJp #% jn78*LSQNMKHFCB@=;87420.,)'%#   wwvBBB mjddba`_]cNJй!# b6WZ ^c)RQNLJHFDA?<:86420.,)'$#  zzzPPP  kiedcba`^d XT !]b23!!QPNLJGECA>=:86420-+)'$" ```hhfdcba`_n|zryy ~@___ (* $RPNLJHECA?=:8642/-+)&%" jjj$$$hgfedcb`a>9Ѹ 58v.0GRPNKJGEC@?<:8631/-+)&$" ttt???liggfddc`g he|}}Z_ަ.0w~qxU[w&TRPNLJGDC@><:8531/,*(&$"  XXXmjhgfedc`jzw&"".1:EDEelILVTRPMKIGDC@><:8531/,*(&$" iii222nlihgfedan i̿!zekhoXVTQOMKIFDB@><97531.,*(&$! MNMmljhgfeecw'"Z[\'*QRQ[`ipZXVTQOMJIFDB@>;:7530.,*(&#!gff010mljihgffe:4ѷ$//LPb׼ *, ovJM\ZXVSQOLJHFDB@=;97520.,*(& KLK###lkjjihgff HDV[>>>rz+ ^\YWUSPNLJHFDB?=;96420.,*%rrr888&%%mlljihgem nj􈈈EJ QW OTQ `^\ZWUSQNLJHFCB?=;86420.( PPP---lllkjihfp{xxvuMQ3ަ hndb`^[YWUSPNLJGFCA?=:8642, @@@.-,llmlkjhfuxxxKKK[[[rppipUUU  * $&)Zdb`^\YWTRPNLIHECA?=;86. ppp888nnmlkjie-'rrr((( DDDyxx{Př]b@OP28z*+Cfdb_][XVTRPMLJHEC@><:&OOO666oonmlkje94iii ...\bM’*,UZb}Usuq|~{f{|821%*,-2ffca_][YVTRPMKIGEC@:<<<888poonmlkfA< DDD:@@48000(9:4 ,./1Zhfca_\ZXVTQOMLIGD. Õ:;:>>>ppoonmlf@;VVV||} %';?\\\ tuucDB.012Kihfca_\ZXVTRONK5|||<<ljgeca_\ZXUTRAfff?@?rqpponmh72555ttt KKK滺~xx&',/KP>fhxxx_cmrZ424568hkigeb`^\ZW?RRREEErrrpooni4.,,,"""ttt xxx;šsssJL؁lj678:`mkigeb`^DBBBLKKqqrqppnj2,zzz,,,(((nnn9; IMɻ89:<XomkifdH445RRRqqsrqpok1,:::nnn人555 rrrhhh#,+O;<>QqomgH++,YYYqrtrrqpl2,:::,,,""" iiicbc(((g<9=>?Lsh5 '&&___t qussrql4.zzz,,,VVV^^^+++jh?ABH'''ddc][oqvutrrl60XXX000BBDH,,,fefkoqvutssn50SSS;;:DEFH667eeempwuuttp,&ؼNNNKKJFGHIGGGaaahqxvvutr$HIH```|||HIJK^^^YXYYuyxwvus~|yDCCzzz񬬬pppeeeJKLM||}KKKuvyxvus|zwBBBBBBXXXVVV333|||LMNP梢787rtzywvt| rn==>>vy~~| |z}YTWWWppo^Z`ab`(((pu~}||{2+ΦFFFrrrpbcb]878gs ~}|{yvRSSooozxdded*v{~}|~ D>ٺPPPssssfggbVVVffgpu~~| \Xhiigu ~|LEMMMmmlpppm kkke! Ա|  ~|{xMMMGFF}}}wPMȤs lmmk\fffPPPͥ~ A;ض $$$qa`p "̧xnnopg...|||ٷPI~rn zzzwqprrrv e`şYTs pqqrmܹܿ…  /(ɘ rqr}}}w.(ttttt |MGřҰŚJD~rrsssreٴ֮ҥ]X C=ְ kll{?:xww vvvuutttutuuuuuvvkӮԩѤΟƐPJ  UP jjjHC{ zzy yx x xww www wwwwwwxqgggѣϞ̙ɔǏPLfaJIJ kkkJE~ } | |{ {{ zz zzzy y zy y zz zv d...>>>ʞ͘ʓƎĈ|zv^YKE|wHHI**)qqqFA   ~ ~ ~} | | | | | | || || | | x hgff۽ɒǎĉ„~zyuuppkkgxsϢ ?@@~~~60    ~ ~ ~ ~ ~ ~ ~ ~ ~zlPPPŽňƒ~zyutoojjed`a\mhȕIHH !^^^ { lWWWdddͥ|}yxtsnnihdd__ZZUUPZTwsְLLKDDDwww[W {g888___m{( <5JDSMYSZTXSTNNHD?@9NHsnҨ;;;iii,$ u]>>>GGGrrrz{zupos}   ;4uq{{OMM&&&>>>ghgJD ~ lfff$$$DDD^^^llliihlROr83p4/n0+l-(j*&g($d&!a$_"[V--.))($$$""")))555LLLvuu_\{ vX쭭hhh../***888BBBHGHJJJIIIGGGCCC>>>:9:454112././//121777PPPtssRs | pPԧ```HHH677+++&&&%%%*+*444BBBSTThhh^o | | n^????<|????LJ|~>p08??Àx?<(@pu9/&TWň ?@??:y~=4}~UWV 6/218;)) ~BOQB))o0*! !0',$#jjYRCó+$x?<e r"kstnX``7mj+36H{rqn514O9@Ax{zZ'#,Q./VW0, >'$EHG`cQӲ^_^aPOqk1#::đ ZX){zytCqq JGE d rus=8797pB>[RxusNPNegedCB(* rҧW\6^ ;ABRmok _{PN$00d%  2+Kx] KHOm<43n NH̝2hkjeGIv ?`f]JG\W*++r^^qGI7*(NFEhm;[Id<9=LPPJ~cm0|x03dqt@SR+>A$%$"IEwB W 1^ZSknl vz<fnl..............................................................................................................aav3........................aaaaaaaaaaaaaaaaaaa........._____a__a_aa..........................;ԅee˗...................aav;ee˗LeQa_a____________a..............;eL9999................99999e;QnH!U:NNN~U&Z_____a......ԗ999999................L9999999N 5ggggg"" ~qZ_a_v9999˗.................99999999Ng}WU;9999999v.................999999999dgg䨨OV9999999999...................999999⨨OOOO\999999˪...................e999994OO5NNŔ999999ˋ.....................99999999cOOggKP99999999ː......................999999QcO" ͨ,99999Ã........................99999e}@ &Zcc99999..........................99999˗"۠ZKOOg9999999............................9999IWa_:I99999999L..............................v9ʨOOP OON?;9˗.................................9999;g䨨OOOx ~K Q;LLLe.....................................˗e̴KO} ʨON_!UNc"gg K ղ...........................................iT4"ONaa_6 uKI IOʀ..................................................#5c&nn_a緽UN ʞͬ__................................................ OOO ntnaa_PI"먨&_..............................................'䨨OOO"@tnn_UNW " 먨"N_.............................................#OgWqattn__P"5}⨨OO _............................................AͨONZ___bt_6 :K "ʑg...........................................OOOgKHn_bBttnP5ʨ ..........................................XOO}!nn_8Bt_q~ " "......................................... ntn_8btnU"}Og1.........................................gOZttttn_88tt 55램5nn........................................RX䨨Ntta>>88bttn__U䨨OO:nnn.......................................A|OOOOtaF>88bBtn__agnn.......................................8) gUBtt_FFF>>8ttn____NOXkn.......................................醨OUBBFF>>88btn_6cO1n.......................................8醨On8F>>8bbttn___Z"k.......................................AgO bBaFF>88Btn_a@OO5t.......................................>醨OnbBBnFF>88tn___K"tt.......................................><5O}&8nF>>8tnna_O tt.......................................>888bbbFF>>>Bttnnaa O1n...................................F|gt>>88ǍꩳF>>888tn_~.................................>YXNa>F8>8>88nꩭsFF>8ttn_@g'n...............................FaF>>>8>88곩FF>88BnnOD..............................F>&F>>>888888t8곩F>>8bBBtt_~gOOn.............................FtFFF>>>>88t>곩FF>>88Bttn:B.............................yFFF>8>888ꩳFF>>88bt"On............................FFF>>>888FFF8BBttU GB...........................FFF>>>>8p곩F>>>8}OXB..........................FFF>>8Вpr곩FF>8BnO"DB.........................ayFF>>>8tpF>>>8BniʨbB........................sFF>>8Fpp곩F>8t_ ⨨5CB跷.......................yysFF>>>ppyFF>8bn6uʨX%Ƿ.......................8ꩭFFFF>>bꩭ*FZ"䚌bbǷ.....................ayFFF>>>bkt8t_uO5.....................ꩭsFAEۻxP U ʨOOX....................곳곩***gOI,5@O....................ysYM!!!i!&i @g яt...................`GqNK WN ZPU~ ⨨g't...................>ppGɁ N PPPq NN IK :~N...................p+U KPo^\99UN KPq ʨ䨨g'Ra..................p+~KWMbo]V^-dIcNOO䨨gjt__a_a.................._~qF8¸335OX[]OWW䨨gXjtttn____...................)PkF:TT I5Og7]5ciPא999]䨨OgggᚂBtttnnnn___a................... ~KUi..FSOOOOO ڶUe99 gbBBttn____a..................NN....j5OOO"7997VҎe䨨O폏BBttnnn___a_a.................~N....F)2OOOOgv7=iҵ OObBBttnn___a...............@~NP.....Y䨨OOOO̶99= صҵLO#8Btttn_____..............@N .......z2OOOն7➻صҵve9⨨g>888bBBBtnnn__a..............NNx........{EOOOOOOOvڶ9975ҵҾސ-"Y>>>>88bBtttn__.............N@x........w5OOOO4ն999"iҵҾ3F>>888bBtttn__............N~.........s'OOOڶ977OI/Ja9øk>>>888btn_............@ ..........*s{|OOOOOOOOOO}Q799"gKaL˶h>>>888bttttnn_...........KNUZ..........`䨨OO",79\5U__91F>>>88Bttnn_......................z'OOOOOOL997- ha_99ڐ8>>>8888bBttn..........W~............*0䨨OOOOOO"@ڶ˶9973L;_ڶ7k>F>8>>88bBttt...........N i...........݆OOO!7799=I59ڶaL79FFF>88888bbBta..........c............+݆OOOOOOOOOO"97˶7- v779997_aLFF>>>8Гbtt...........Ni............*+2OOOOO ڶ979 9ڶ97Q_aFF>>>8>8n.......................swSOOOOOOe99- ڶ999_ڿFF>>>88888bbBBB_...........P.............*z|OOOOOOOOOOge999977ö9__;9FFF>>>8888BBB_...........~x..............*0ਨOOOڶ9VK7999ڶ97v_ն>FF>>>8>88..........................*݆OOOOOOOggOg~977=ch799ڶe7=99isFFF>>8888bbB.............K..............y*ٙOOOOOOgONq 5ڶ97 979LêڶFF>>>>8>............. x...............EOOOO5q5~ڶ79[97^^^ZBFFF>>>8>8_.............. P...............*wOOOOOOOOg5cOv9[Oc FF>888Ƿ...............x...............ywOOOOOcaq"c?ڶe7樨F*FFFF>>>888.................Kx...............y*wgOOO Wg 7ڶNK @>F>>.................~................y*w5OOOOOOOO}۷_aUOO5UvԶ]NN;'܌bFFFFn...................................yy*䨨Oa~_qO :o:9O5CFna..................... P................y|OOOOOOOͻi g@__@OOOOO"I WuKLg#.......................qq................ꩳy|OOOOOO5@5gK_}OOOd"'Ƿ.........................I ................ꩳ|OOO auOOO 䨨O>y8...........................I ................ꩩ|OOOOOOOOxa_Z5OOOOOUg>..............................!U................ꩳꩡ|OOOOON_Z c5gOOOgUKg#n_................................ʻU................곩ਨOOOOOO"I}}gOOO KOO28................................... ................ꩳ|䨨OOOOOOOOOOOOOOOO xOOX888................................... ................곳+EOOOOOOOOOOOP5 g888...................................qU................(f"OOOOOOOOOOOPU "58>8...................................UU.................lOOOOOOOOOOOOgWNOO55>88>...................................NPN..............곳lOOOOOOOOOOOOqN NN O "8>>....................................N............m5OOOOOOOOO "O~|>>F....................................Ii...........EOOOOOOOOOOOOOOO~qqNNNNKN }O>>FF....................................5@..........(SOOOOOOOOK@ W}"O'>FFF....................................U...........OOOOOOOOOOOOOOƨO2FF.....................................c.........mਨOOOOOOOOOqOOF......................................5K.........|OOOOOOOOOOOOK@ g......................................"U....... SOOOOOOOOOOONNO`....................................... i ........l5OOOOOOOOOO I2......................................."@........$OOOOOOOOOOOO @~O{.........................................}......(OOOOOOOOP~ O`s.........................................gxN......mOOOOOOOOOOOO N~g..........................................i......SOOOOOOOOOgZ u |`...........................................g ....OOOOOOO6i NO䨨............................................ ....rEOOOOOOOOOOZu䨨OO............................................g!...lਨOOOOqZq E䨨2..............................................O...Or SOOOOOOOOOOOOOOg6 䨨Oyyy..............................................."N...OSm䨨OOOO ZZN:|OgE$yy.................................................iN"...ESr(OOOOOOOOOOgZ6~~곳5|yy...................................................I...OSrSOOOOOOgZZN)곩...................................................N...OfrrEOOOOOO_6곳곳곩y.....................................................i....Eff|OOOOOgqN........................................................  ...ffflmm|O䨨OOO䨨q~N.........................................................."Z ....Efmmmmm|OOOONZ6Nwr............................................................Oqc.....fmm$mf|OOOqiUrr.............................................................. ہ.....lmmSgOOq6@{rr................................................................. U.... OONZxK(ppr....................................................................gq~N@:.pr mqiۻKDppppp........................................................................gqU~)<绬P~W ..ppppppppp..........................................................................."ほۻxqPqqPqq~K .......pppppppppp................................................................................."INUq绬 W }.............pp........................................................................................➞ III...................................................................................................................................................................................................................????<|????LJ|~>p08??Àx?<( [a 4 w WZYSN Rfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffiffffffffffffa ffffffffffffffffffffffffU]]fffffffffff ؈ȍU ffffffff݌ fffffffffffffffffkfffffffffaffffffffff̍Qffffffffff`Uffffffffffff݁ffffffffffffaоffffffffffffffPffffffffffffffa ]Q]PffffffffffffffffX́U݈Qffffffffffffffffff-̍U]ȍQQfffffffffffffffffffffiҌU،Yffffffffffffffffffffffffc\ٙÜ̉ffffffffffffffffffffffff7͙9݈Ȍȑffffffffffffffffffffffc33U]ȌYffffffffffffffffffffffjQ39U݌̅ffffffffffffffffffffff3339U،͑fffffffffffffffffffffّ39ÜYffffffffffffffffffffc8̉3339݈Ȍٙffffffffffffffffffffj|̅:333]Ȍ̉ffffffffffffffffffffjș9::339̅ffffffffffffffffffffѓ33399U͙fffffffffffffffffff::333͙fffffffffffffffffffY339:J3339șfffffffffffffffffff7œ33:339fffffffffffffffffffY33339:333șfffffffffffffffffff͓3331JJ:339fffffffffffffffffff̉::3333D3:39̙fffffffffffffffffff::333JJJ3339fffffffffffffffffff:3394JJ333999fffffffffffffffff::3DDDJJ339șffffffffffffffff339DDJJJ:33399fffffffffffffffѪ3DDD333fffffffffffffff:DDD3339ffffffffffffff4JJ::DDDD::33999ffffffffffffff9JJ:DDDDJ3333ffffffffffffffDJ:DDDDJD::33\9fffffffffffffa4JJ3DDDDJJ33̃3ffffffffffffaDJJJJDDDDDJJJ3333ffffffffffffJJDDDDD:393ffffffffffff4DDDJDDDDDDJ939fffffffffffaDDDJDDDDJJJJ939fffffffffffdDDDJDJDDDDDJ939ffffffffffDDDDDJ93::9X39ffffffffffDDDDJDJŕUU]̃31fffffffffaDDDDDDJJDJJJ́U]̈\:1fffffffffcDDDDDD3UXQ]ȍ33fffffffffDDDDJ5U؈U]:3fffffffffDDDU؍UUUU]3:fffffffffDD]U".U؍UUX̃fffffffffD]3R"⾰؅؈Y\z9fffffffffE]: QP]́-Q99fffffffff]Ք؈؈́(+(ՓfffffffffUdJJ̅(3393ffffffffefjJw,ӣ333ffffffff]QffJJJ}:333339fffffffUffJJJx(,ڪ::33339ffffffm]VfffJJJGPڪ:33333ffffffmUffffJJ́,ڪ:3333ffffffVfffdDẃ:::33333fffffmUffffjD},:::33339ffffffVffffdJJDx33339fffffmffffdGxQQ3333339fffffmQfffffdǴ333339fffffVfffffjDG̍㪪333339ffffffffffJD[પ::33333ffffmUffffffDGѾપ33993fffffmQffffffJDD}셾J3:3333fffffffffffDJMJ:33333fffffffffffJDDx[㤪33339fffffmUfffffffDDx͐(JJ:339fffffmUfffffffDDQ:3333ffffffmQfffffffDJG|U]텾:JJJ:39fffffffffffffJDDXQ"":J:::3fffffffVfffffffDDG| ]33JJffffffffffffffDJDGX ^\̃33JJ9ffffffffVfffffffJDDDQ[\33JJ9ffffffffhUffffffffDJJGQ-P33JJDfffffffffhUffffffffDDDD|]Q̈Q334JJJJ9ffffffffffhUffffffffJJDGȈ ::JD9fffffffffffmUffffffffDDDD8̅ ̃3:DJJffffffffffffhUffffffffDDDG̅X̅ãDffffffffffffflffffffffDDDDU̅3:D9ffffffffffffffhffffffffDDDG}3:fffffffffffffffhUffffffffDDDD̍̅::fffffffffffffffffhffffffffDDDGȪfffffffffffffffffhUffffffffDDDD̅::fffffffffffffffffhUffffffffDDDDU̪ffffffffffffffffflUffffffffdDDG|ÜffffffffffffffffflUVffffffdDDD|Q]UȪffffffffffffffffffflfffdDDDxU]݌̅\ȪffffffffffffffffffffffdDDD|UU]]QȪffffffffffffffffffffffdDDDMUXȪffffffffffffffffffVfffffDDDHͤffffffffffffffffffm]ffffDDDGUǪfffffffffffffffffflflfffDDDGǤfffffffffffffffffflUlffDDDGQʪffffffffffffffffffflffdDDD|XJFffffffffffffffffffffffdDDDx\zJffffffffffffffffffffhffdDDDx́Ṳffffffffffffffffffffh]flfdDDDGQǤfffffffffffffffffffffffDDDḠfffffffffffffffffffffXffDDDD|́zFfffffffffffffffffffffhflDDDD|Q]DDffffffffffffffffffffflf̄DDDG׌Dfffffffffffffffffffffff\flDDDǴTHDJDffffffffffffffffffffffflḟDDD|DDxtJDFfffffffffffffffffffffffffl|tDDẃDDD}tDDDfffffffffffffffffffffffffhfȈtDGtDDDDDDDDDDffffffffffffffffffffffffflfl͇tD|́DDDDDDDDDDFffffffffffffffffffffffffffflx||wGőtDDDDDDDDDDffffffffffffffffffffffffffffXfwLJwwQDDDDDDDDDDFfffffffffffffffffffffffffffflQff̈xwwѕtDDDDDDDDDDfffffffffffffffffffffffffffffffflxxwww̅XDDDDDDDDDDFfffffffffffffffffffffffffffffflffhwwwwww̅]DDDDDDDDDDDfffffffffffffffffffffffffffffffflffDwwwwwwUDDDDDDDDDDDFfffffffffffffffffffffffffffffffffl]dDDDDDDwQUtDDDDDDDDDDFffffffffffffffffffffffffffffffffffflUUWQUfDDDDDDDDDDDffffffffffffffffffffffffffffffffffffflQUUU]fffdDDDDDDDFffffffffffffffffffffffffffffffffffffffff̍QQU݈ffffffDDDDDffffffffffffffffffffffffffffffffffffffffffffȌfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff????<|????LJ|~>p08??Àx?<(@0 -/@CVY`cjnpt~`cW[nr|[_ ! '>66GBAEAA622 %'MPos _b ㌕կ|||A@@ ;>~ )* I  -任~ 23*+ ;ŋnnn  Z]  '''sss ei I>>>}}}t#vy >B11()01LtSSSUUU+++[[ZӢp{{$%,.KNHK*+F@11 665www:% -%RRRlee >]/+0&& :2+# nno @H;;1@80(!f\\I  MF>6.&yyyXtrr"*&!8SKD<4,$`$ tqq*3.*&JXQIA92*" ! a$1<84/*f^VOG?80(  *e&!򳳳6E@<84-Gld\TLE=5.&yyy*_* NJFA<8$rqjbZRJB;3+$ >==( U G.,TSNJFB=/~ wog_XPH@91)!=77&/_^XTOJFB2 | tme^UNF>7/' qkk' Bh`\XTOLG0 zrjc\SLD<4-$xw*mjfa]XTPL. xphaYQJB:2"LHHcCA-bqnjfb]YTPDc ~ vnf_WOG/5"!?&9~ xsojfb^ZUQBFU_a^VQA7XMM4#l | xtokgb^ZVb#͸,-,TTT||||[Y7 } r ]Z30fTRtkk{yy|||xvu~~)))(((^^^ڣH:5 skMK}|}zzzdiixjNw{{{cccrrr><As_\yyyeKIL ZM0*)9~RN,+|h{|jqrchhhʘÁȼB-  ihiZGExxxXWWW ^\ZWi$¼}}}\dkltrv[U2/*'" sssvwwcbc&%&oc_\[Z ]Yqx&Քp T# 83/*&" |||{{{TTT id`^[jк#RVⴴ jkGJ b^#D@<72.*&! ~~~KKK hca_]JFhrrqL.0Uw["QLHD@;72.*%! NNN jdb`` V\]` &=?PLHC>:62.)$ \\\hecalOVVW`aEH0)(PLHC?:61-)$ {{{,,,mhfdbB> ,.:syhn!TPLGB>:51,($ FGFmkhfcXTvxyz XTOKFB>950,(${{z,,,lkigf3LM载{ "\XSNJFB=940,' LLL&%%lljhj ͯ02_rt}z4,+`\WSNJFA=84/999mmlip444FFF>@?э \`=@<d`[VRNJEA<4|||777pomkx  >Y[㠠ʱT=<,0dc_ZVRMIE-bbb???ppoly!FFF򌑒MP灏>}ź12Xhc_ZVR;OOOrqpnxvvv444疗_~q||Vtv(S*'6Okgb^CEEEqrqoxjjj͡^hhtr:IojHBBBs srqzjjjabb?E?GGGk\ottr|cccCFQQQktvtzyyynnnHJ`_`Ywxvx ׸ZZZvvvķLNqrqszwx ǛNNNbbbPTrrrq{yvieZZZUWYYXty{y92yyybabȮY[hhhjz|{221lh^^zzzv~|| UUUr"b`dddr~~|82444ee~~~|~̡MMM___wjf~94>>>uNLʣ60nl\jjjΠ-& ***yecs t TNַڼ~rrkdccӨhcְ&&&{nmyxwwvvvvvvqeeeΞɔÈZUJDfff/..qo~ } |{ {{ {z { w dgggѨĈ~ztpjfzv000MMMig     zl[[[gggǝOI\W`[]XTOUPȕPOO322{uuJE  { gbbbLLL^]]qB?|&{xurpjB?\RQ222@@@||| xӓoooVVVDDD888444999FGG_`_R{ xP|?`????`0`8?|(@$QWpu|~C@?=@Ƴvaagop\.-6βJ[egBB/1!ʟ'%wxx{yCUtwSVT||$$o]lgFHFzuX``o>AH_b`l{}XB@9 4"!XPOGHkll  jT"}MMOMv 9. H.&%>A? -2nBAXT eOMNǓ231tkjba687sMP~~fcIW""dfeP# c0ҫY\ZsB;3273vӹSPwttk"034K BHBV W _sr+.z+}^Y]r!x}<fv_~m LEFIwHHHHHzzB7:iiii\nGeHoxHHjB7niiiiiiiiviiiiiiiii\O6JPf(-zօiiiii掎ziiiiiiiiiiA>>>>ّiiiiiiiiiiiBiiiiiiiiiEۏ>Jݒviiiiiviiiiiiiiii,6Jniiiiiiiiii뎎}iiiiiiii7P>>ˌlׯ>\iiiiiiiivi\}mۏ>>H!!ˏABnii\nBzЫP>J( (lx dAfPsKe掎[>>>A]!,Ï(Hw>R]UHӇLsqˏJH >>>>(HUw]x,sAoN>>1rUHwUs,A[PL]]]3tOP>>(U,P4Uw33t4UH>>fU5>>>44U3{w]UH>5JL{ t44]3{tUHxq95> t4+tUH,9ba93{ww+3{t4Uf9H3433w4]UΏ>aHI3{I3{{ >H{+33Ų+33wI46>4H]+u鿿IW+{wt>>M4++{W+IPPqw+uu3uKP>tڝ++ku5l!dLdۏ> ]]Wbp!!llKA(Ï>>>q8𨝝t!Kd g(L!>>>>>>>PN{𝝝X׬3@__sZ,PhJ>>>Pa]HH 5af,>!G$67ʍn >>>>P>p4]]HH0cP>>>6眜TL#FF`2iꏏ>|tt4]UUHH u>>,Q#FF#\>>|{t]UHH!'u,>>>}Qa#`G5wt4]UH+uu~>>h뜜>>>J *Hi3{{wt4]UUl+J>>>s7"HBz33{wt4]L'cJ>>>Bi!:B՝e֍3{w 44H+&>>>>>>,S}iR:ez3{ t4 >>>A}兜3{{wIIO+++k>>>PO':i/L}7: =vu⼼{t!++?>>>>>>P!aS(݂334H+J>P,xHH'>B@:1aIU++?>>ˢd>O7> U'++V>>>>>J6͝HO>>>>>;+(+,>0x!P>P0>P{{{R'V>>>ˏ>>>>{V>>>>>>>>>>PP!>>>J>0+>>>>>R1RL(1f3+>>>>>ۇ0L(ds,⎎L^>>>>>>>>>>aȒsRA>䎎sȎ,>>>>>0ˏ> 鎎0X>>>>˰>%鎎K㣣>>>>>>>>>P01>J鎎τ>>>Pq>>>򎎎>>>>>f>>P?򎎎a>>>>>>>>>>P>>++1JY.P>>PKl [V0R>ƺ..Ə>>>>>(xDV+͎>쏏>PP,lDV!C)))>>>6㣣R0>(W㪪㪣K00?kk.WWWsO ''͎W|?`????`0`8?|(@ 1|_cWX\[w qWV3333333333033333333DDEU33334E\UT~p33DUC333<ʋ~E\3335x33333\Ż%33333<[C333333\R狻33333335Xw$\3333333334U"z~zC33333333333133333333333程~33333333333꫋33333333333a狋3333333336f3333333336qf3333333336ff껻3333333336iff3333333336aff{3333333336ffa{33333336ffafa33333331ifffiffa{3333331ffffa333333 fiff333333fffff333336fff333339f碪3333ow3333w*"%*za3333"$x{"+3333vffhŷUTUU333:s6ikˮ»33339fi(E˻337s39i̭U!ffa33333L̲vfa333s33u~Lff33733̴U^ffaa33333k\*^Uff33s333|\Ŗfff333s333\|Tffaa33:333|ŬFifff333:3333\̤Šfffa33373333绤\Ȼiifa333373333~r[iif333333333껻+i333333333333333333333wc3333333373333c3333333373;33wc333333337333wc33333333:s39zc333333338s39{c333333333s;393333333333;9f3333333333733w33333333338s33333333333;wi3333333333373333333333333x;33333333333337;333333333333333;3333333333333338w3?3333333333333333:wz3333333333333333338wz33333333333333333333333333333333333333333333333|?`????`0`8?|(0`%&8:BDEGEGDGBD;=*+   =?Y\nq~ >\]rlkywwUSS)((JM~  Z ae ίʶ3 46 (GGGD ;=$% CCCCvvv&  IL()FH(pryȚϽOIIJII^^^kkkدIWX"$LO13> sfe$999*"" >wQN:325.# ^^^B°N@?+?5+! ^^^+Q,$MG=2( )''~}}`TS_$, 0*$&YOD:/%vub$ 7 <60(H`VLA7-"c AHB=7-ph]SI>4* ~~vuW N.,RNIC=Az oe[PF;1'njjp[Y*b[UOIDG wlbXMC9.$W:8Mga[UPJG  tj_UK@6,#= 7omga\VPA { qg\RG/O@?1 jy smhb\WPF k/+P O L JR/,}rrzx15  z r c XX'$U*'M$!}|ttt999ݨU(%+K {sD@rhhfhh~wxxxjjjñ>!Q {NKnfe_1.UR=65]aFr]tumŎڠpgȏɿT0-* qppiiiQQQ_^[Y[W}uP=6V-*/)# zzzhhh,,,e_\cӽ`䟡4WѠe0,@:4.)# ccc lda^D@%glV- \TRQNKE?:4.(" jjj&&&ifb`vyyzWZyNJE?93-'"556ifdh !KN0dgfl!#z8'&PJD>82-'! VVVlhfs %閜/DEUOIC=82,&555ljgA>qplEEEYuw|< >jd^V4EEErqn~mmm OsvrMJ<kf=PPP[rspbbb>>>AATTTdrus{y|||ƳFIONOuwuXTnnn­LN___pxw=7UUU}}}zzzȰRX{{{hzygggXZx|{ ѫeee\X]\uuuu~|[VOOOlb̥}~QQQ|xhdWQ~lg\TT̨p kV́yuܽKIIw+%t OIɟЫZUt rkxxxسɓOJ>8KJJ93{ z y xx x xrxwxƌ~zok{wOOO`YX4.   ~ ~ xhhhhoooGAHBJDC>~рȀ??  (0` XtvbW }~E0 M@?-|%gladbv**?gihSVT[ v!B;{x}zvsvttPK[Y-DD>\^NQO~OHOmjnquq,EltgcnjlX]::~zb]KQ*o i *#"o[[DTP16sE>_ DGE4/ W:9s<54Osw]khU'%{wy>2JWZTQQS0.W/+6;,=()ABdho/dgH798xzzgeE}B~PEJEg~~X Qw  XTV pgg^TSѬ:2lomm>C;"Iv}ts'"$x*')P'*ìb#@A@0OKMpln{m.+C (N(#XVVz^Ǐ<f 27 ]`^LIGc*>5Uɝv ׽CCB7Ӛ1XX1+[ 895:⿌lckM:=?)$ckތـz⌌ccc"c{o"-Kd3ΙcccAc(cɅΙcccs(""cOxcccc/Q5♙⿿tccccccOxs(Q?♙⦦ ccc"!♙⿿ccccc"vccc.,♙⧦ؘccccc"xckL=♙⦦癙c3㘘"\♙c6cccccc\!"KK♙c'cccc,cݝ&wc實sz'6' ccxx`A&&/_G |Ԅfeeee ~??>>~рȀ??  (0` [^Y 5MY^]r[Y x 3333"""#33;33333"338ffffffh*_8fffff338fffffffQXfffffff#333ffffffeQUfffffh33336fffffQXfffffc33333ffhQfffh3333333(UQU333333333}33333333:wݹU3333333<w}U3333333A]}Dw3333333Aw}tDw}3333333AWGwDDG}3333333EtwwDGw333333GDDtDG}33333tDDDGw33333NDDGw}33337DDDDzQ}333>NDDDDzQ{333~GɟU{333NTۻ333JD_Uwۻ333Neawwݻ3393DXfl&twwݻ333Nff DGw}ݳ3933NLfohDDGwݳ333&fe"&Dww}333>AffVfDGww3?334AffftDDGw3933>fofhbDDt}33933>_ihUNDG33933>ٻYT~NG33333>Q~333333>Yt33333333>QC3333339333\\C333333913\C333333?13Y333333?33C3333333>T33333331>Q33333333?1333333333̮333333333_3N333333333333Z33333333333?4ɚ3333333333333?y3333333333333333?3333333333333333~??>>~рȀ??  ( @ OSsx}y}Z] %0,+`c^a iʆ !" W񽽽ڄ  >ͦ___VVV* ()HI~K??A>> ~ ;=>~|JDD-$:::_XX F UDC%?/+''\!=*LJ:+ c% O'%<4.eUF6'$ [ fEBNF=Pp`QA2";aXOG\{l\M=.[jbXPX wgXH3 |ssG| tjbZR vHFM!pFBpNKiDB`t84o^\lpz{eee?ihii<9kQN[VebaSfqHXJ$!" |||mmmCBBd^^ x9v&,ưc308.& pppBBBe`~95(킓] qu2EH?6.%FFFmgbJz~HOV["$lrPH>6-$ fffljfдu XOF>4,EEEllk 㞞 3> "QT`WNF<* xxxfffpor'''BBB+]Wᴭ0b_VI&kkkrqs |||FFF333nz{U*&]_7 nnnq sv rssb`E{z{jvw mmm̝yvLxxllk۞tpUmmmy{}JE\HC~3-gggh`Ɠ)" ԯNIjЦQL2,eECuGAup.'sk˘uq~ztttoGD  } } | u ȅcccVS@:93E@d[Z:4 z ݆uuummmkkkyzyz  xx?xxX( @*&(j=5V)'cEDA=?un}~] ~5 A%(&&#RRx{y# ? E;LDC ~w3d[Z20o:6eacO,JB@6TVUX]fӯRrta22t \<k8:9~z x~N16  p ѵ%rusb^gyu EJ{}mpdge r  6_ urAM!xIBK% H(w(CThE@T hki@BAô%<+rNI>3%rz{w _r_Xr857wc G= :2oFDM@<~+Tz͘"IQIP~z|0VP)$132NJaXWjRNAj 86"%becVW  /+-^lknl-( ]`^ym ,S|srwZ>M)eܗ*^RssssskBfG7ssss'RssssssWBBQVssssAsgw?=㛛ըq55z8j:r/CdUaK#I5јz8jBBB]IO7758Œ/u?E6l\C|/BB%˛ ~雛_/ B 6BhiŒ/⛛BBB4Jfm5BBBQm켛BB?9풛.BB{4ٛBPxDB?BB?$璒2?¡3B?ᤒŒ }Bhۯ; Y-1cےhcxx?xxX( @hl* x   ynOL`dc[ ffjswvffff""$ڙff$B"+ffj".""ffffkB"G"""Mvfffff"3~D""""fffffBLs7""""Ffffff$3?3}""""#fffff#3537B"""#fffff7"""Gwfffc_U_3B"""Cwvffo_UU_>""""wvffU_<"""""wvffݾB""""$wvff۫""C7wvfnfB" "O33wvfe""Iw??37vffeX""+q3vnfeT""$33fffe""-ڙ6ffeR""w䩺D?_fffeR""r$"?SffffeR""MB""fffffeT"""""Dffff&eT"""""Dffffn"eX""""-B"ffffmb&U""""."$Vfffff"UB"""",Vfffffm"%R""-Ufffffff(""UUVfffffffmUUfffffffffmffVfffffffxx?xxX(  7?z} ;Ӷ. >󹸷>'&>::1;<ThSQ'<! `{VS=TS4LaPljJ? gVUn t/*c`vvpZX.nnne:6[ M^'OnɸP&# ZZZf|2. F!(W[=.,?.iiikif/+:A@N=yyyp:::zYS T1t}zvD@TO㱱GBi Ϣv4,} ksrROqo}pp z ?( ! sr RO ? 7 [ ɸif4,e:6 {VS.GBNP;S'OTzMc`gVUpZX .qovYn W[:::t/*'TO>::vvit_ >'&JP&#!(S ^Ϣ}z.?z}}pp:A@14} n<=?hSQ=.,F|2.avD@j+klp/PPt8 #:]qT`lDPPw=(i.\BZ>WePPPP[5RM"oooPPPPPP1K~ooooYPPPPP+)zoooPPPPP'U 333?openmsx-debugger-0.0.0.svn20141006.orig/resources/icons/openMSX-debugger-logo-64.png0000644000175000017500000001332312414415132027032 0ustar shevekshevekPNG  IHDR@@iq pHYs  tIME 1tEXtCommentCreated with The GIMPd%nbKGD7IDATx[ XNi~% $Me!͌ef$1W(m&I/dl3$Xdi(%{L3tM(u=9羟۞HTC~7ovZXvvNDVVV`ff[zZZ3gΨEӧOe/Ο2e ѳgOt}t{ppӟXIn "ÜE"9"8tE/R,R;$|i֭cƌFu[KO> +60 FP|_tCJlll^!<q _ ^Z9!#;:B#77AI8zůJkѣF1~Bt bx( e M)'w^VZ~fD܅¤WaӈN.Foĩ kƍCv1/ 3iD48}i}cWȓg r^ka= "|xޭ C84l2;/66lKKK|;9 z!D60U@PPm?~ a@!pe\O\7 Q1e; q#ڴiOt eEܾSW 0_02# Q /..~L!'d^wW*fqE|ex5=pmH͑w;TM&L*RI?G#"" ܿ/=cB1ѹ̛N5U"z&st*WC#3<|h)sSc3yN\B0HɈsPæCZS(䒨XPT?g{ѳj]-[d2ӯKM8-"w*h5/@8$pDF' X SR*L?&?£y/**={wH&$r)}S<ą* O( yG ,X5D~0jr l%B_JZT!|lV"ܻO 1 - 0ອ s^Ñg"(5a[rvBFF9^|T y>bðsBf~~;w.3 тPuÏ'k<-E 09s&{',zjܹsx"8׊<=@9J&D|u`w``Çرcػw//_T'O"&w @@<NDp(srHxOGѠQ(ү#$UEI-ZXVxTN)yr8 o(u}}G{yXaβ)p )#(+rni̚&ATg$0TE. N)80Ck\8-"d"-Cܬ!“g˅-IKZ:M 9R}܊֔xf_G䕫,..FHp~XP<ås1#2O& W0n 31Na&@|y[Z[L>҂ CիL&+,ۺqyc`#*O #$~az)&{KԼlX/)wY@nE |TCނЄWdhB?7774jdl] ׊^adUT9b i954\T.d2H%"~KZ[kç,;wS"O/i#' HSI[NYY;kGA= ## n?ȕIQ"~\DT!W(H)nd[n]-yrf!okD֎O|dIȷ! M_u4V)1jJ ё`[3W|S c3KJRsWd#7*;NxLsJ؁|Oǟs }ݻo؍U `nSA*f~@~x„%#ӌ g5Bj `| /$W>5Uݿkzr z<z\S UԚ?N~q[ihozذ>Rc?05x>p|Mi *K^[,e8 ͋B$dp-E[{r9@9آ~/2#Vtb$u?UpㅮpGr.BZMԩk8~"!`޻H굩3S̞#Q…oZ/N kW pJ.: `]m^p[reGZZu~e|unu(^Bsrv#!qQp5?DmXDδyхƼy @eBE&6"& !t%ת jff&t<} Yqd[,{pӚY7͝[ nt6Bք[I!+uZI޽]WE֪?^aQΏ OF!"R΂'4/4!g3/fͪl,(TL\CZ@Uδxo Tבiqk~"TyZklI[DߢvW1sv '' "7qlk,̶~# Wp$6mJ5n&B^3JSS&OƎ;PPPZ\4]C!DE͕Z_lgXWtFHdhذ! - .peYM/I̩~#F{^KC;-ߠu yǎ:u*Y=HwBdoJ`-?3Ru1qV0CET}RO(_N,54މ<ѠIʢwyy_rg*ڎG\\\#+2 vҼsn]UT}.StlhX^YEy}kcOgV~D1'vRYj =]>U5fL*GHefv:.VYzׅs,H2wճ],~.RRr?lO,9.\HkuGzR|f(B\Ti-:铉\ɢ'D˹m=J(Bn 7sK/s.pLUEA.QS 5nLVzz03omѽ=w055G:zJKX:@R*E[O_6`4u^azūcPHP .6 MIle6~ o~5v%**JUT*2%vйaaMG,Y*d"NjtdYj,efFlQ\ɒx-OHv͆ccIENDB`openmsx-debugger-0.0.0.svn20141006.orig/resources/openmsx-debugger.rc0000644000175000017500000000707312414415132024517 0ustar shevekshevek// Originally a Microsoft Developer Studio generated resource script, // but now maintained manually because we want to build with MinGW32+MSYS. // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 103 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1000 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif // Include resource info from the openMSX Debugger build process. #include "resource-info.h" #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 2 resource. // #include ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // English (U.S.) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) #ifdef _WIN32 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US #pragma code_page(1252) #endif //_WIN32 ///////////////////////////////////////////////////////////////////////////// // // Icon // // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. OPENMSX ICON DISCARDABLE "icons/openmsx-debugger.ico" #ifndef _MAC ///////////////////////////////////////////////////////////////////////////// // // Version // VS_VERSION_INFO VERSIONINFO FILEVERSION OPENMSXDEBUGGER_VERSION_INT PRODUCTVERSION OPENMSXDEBUGGER_VERSION_INT FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L #else FILEFLAGS 0x0L #endif FILEOS 0x40004L FILETYPE 0x1L FILESUBTYPE 0x0L BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "080004b0" BEGIN VALUE "Comments", "\0" VALUE "CompanyName", " \0" VALUE "FileDescription", "openMSX Debugger\0" VALUE "FileVersion", OPENMSXDEBUGGER_VERSION_STR VALUE "InternalName", "openmsx-debugger\0" VALUE "LegalCopyright", "Copyright 2006\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "openmsx-debugger.exe\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "openMSX Debugger\0" VALUE "ProductVersion", OPENMSXDEBUGGER_VERSION_STR VALUE "SpecialBuild", "\0" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x800, 1200 END END #endif // !_MAC #endif // English (U.S.) resources ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // English (U.S.) (unknown sub-lang: 0xC) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) #ifdef _WIN32 LANGUAGE LANG_ENGLISH, 0xC #pragma code_page(1252) #endif //_WIN32 #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // TEXTINCLUDE // 1 TEXTINCLUDE DISCARDABLE BEGIN "resource.h\0" END 2 TEXTINCLUDE DISCARDABLE BEGIN "#include ""afxres.h""\r\n" "\0" END 3 TEXTINCLUDE DISCARDABLE BEGIN "\r\n" "\0" END #endif // APSTUDIO_INVOKED #endif // English (U.S.) (unknown sub-lang: 0xC) resources ///////////////////////////////////////////////////////////////////////////// #ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 3 resource. // ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED openmsx-debugger-0.0.0.svn20141006.orig/resources/node.mk0000644000175000017500000000020012414415132022155 0ustar shevekshevek# $Id$ include build/node-start.mk SUBDIRS:=\ icons DIST:= \ resources.qrc openmsx-debugger.rc include build/node-end.mk openmsx-debugger-0.0.0.svn20141006.orig/resources/resources.qrc0000644000175000017500000000125212414415132023430 0ustar shevekshevek icons/openMSX-debugger-logo-256.png icons/connect.png icons/disconnect.png icons/pause.png icons/break.png icons/run.png icons/stepinto.png icons/stepover.png icons/runto.png icons/stepout.png icons/stepback.png icons/breakpoint.png icons/watchpoint.png icons/pcarrow.png icons/symmanager.png icons/symman.png icons/symfil.png openmsx-debugger-0.0.0.svn20141006.orig/.pc/0000755000175000017500000000000012414640014017354 5ustar shevekshevekopenmsx-debugger-0.0.0.svn20141006.orig/.pc/.quilt_patches0000644000175000017500000000001712414637753022240 0ustar shevekshevekdebian/patches openmsx-debugger-0.0.0.svn20141006.orig/.pc/.version0000644000175000017500000000000212414637753021052 0ustar shevekshevek2 openmsx-debugger-0.0.0.svn20141006.orig/.pc/.dpkg-source-unapply0000644000175000017500000000000012414637753023274 0ustar shevekshevekopenmsx-debugger-0.0.0.svn20141006.orig/.pc/.quilt_series0000644000175000017500000000000712414637753022102 0ustar shevekshevekseries openmsx-debugger-0.0.0.svn20141006.orig/README0000644000175000017500000000106312414415132017555 0ustar shevekshevek---------------- openMSX debugger ---------------- The openMSX debugger is a separate program that interfaces with openMSX and controls its debugger from within a graphical user interface. * Requirements The debugger requires the Qt4 GUI library to be installed. If you are installing from binary packages, make sure you install the development package (name ending with "-dev" or "-devel") as well. A (reasonably) new CVS version of openMSX. * Building Build with: make * Installing Install derived/bin/openmsx-debugger manually in any place you want. openmsx-debugger-0.0.0.svn20141006.orig/GNUmakefile0000644000175000017500000000002612414415132020745 0ustar shevekshevekinclude build/main.mk openmsx-debugger-0.0.0.svn20141006.orig/TODO0000644000175000017500000000011612414415132017363 0ustar shevekshevek$Id$ - add slot layout widget - add other debuggables - too much to mention