From af27a070d6a36e5590c5d24ba255300825c25cf9 Mon Sep 17 00:00:00 2001 From: Shamus Hammons Date: Tue, 29 May 2007 03:39:35 +0000 Subject: [PATCH] Moving to trunk... --- Makefile | 135 ++ ROMs/01 | Bin 0 -> 4096 bytes ROMs/02 | Bin 0 -> 4096 bytes ROMs/03 | Bin 0 -> 4096 bytes ROMs/04 | Bin 0 -> 4096 bytes ROMs/05 | Bin 0 -> 4096 bytes ROMs/06 | Bin 0 -> 4096 bytes ROMs/07 | Bin 0 -> 4096 bytes ROMs/08 | Bin 0 -> 4096 bytes ROMs/09 | Bin 0 -> 4096 bytes ROMs/10 | Bin 0 -> 4096 bytes ROMs/11 | Bin 0 -> 4096 bytes ROMs/12 | Bin 0 -> 4096 bytes ROMs/sg.snd | Bin 0 -> 2048 bytes res/icon1.bmp | Bin 0 -> 2102 bytes res/stargem2.ico | Bin 0 -> 766 bytes res/stargem2.rc | 9 + src/dis6808.cpp | 141 ++ src/dis6808.h | 15 + src/dis6809.cpp | 374 ++++++ src/dis6809.h | 15 + src/icon.h | 38 + src/log.cpp | 54 + src/log.h | 24 + src/sdlemu_config.cpp | 149 ++ src/sdlemu_config.h | 17 + src/sdlemu_opengl.c | 535 ++++++++ src/sdlemu_opengl.h | 43 + src/settings.cpp | 122 ++ src/settings.h | 60 + src/sound.cpp | 96 ++ src/sound.h | 14 + src/stargem2.cpp | 1067 +++++++++++++++ src/timing.cpp | 130 ++ src/timing.h | 35 + src/types.h | 33 + src/v6808.cpp | 1922 ++++++++++++++++++++++++++ src/v6808.h | 55 + src/v6809.cpp | 2989 +++++++++++++++++++++++++++++++++++++++++ src/v6809.cpp.bak | 2840 +++++++++++++++++++++++++++++++++++++++ src/v6809.h | 59 + src/video.cpp | 477 +++++++ src/video.h | 50 + stargem2.cfg | 99 ++ 44 files changed, 11597 insertions(+) create mode 100755 Makefile create mode 100755 ROMs/01 create mode 100755 ROMs/02 create mode 100755 ROMs/03 create mode 100755 ROMs/04 create mode 100755 ROMs/05 create mode 100755 ROMs/06 create mode 100755 ROMs/07 create mode 100755 ROMs/08 create mode 100755 ROMs/09 create mode 100755 ROMs/10 create mode 100755 ROMs/11 create mode 100755 ROMs/12 create mode 100755 ROMs/sg.snd create mode 100755 res/icon1.bmp create mode 100755 res/stargem2.ico create mode 100755 res/stargem2.rc create mode 100755 src/dis6808.cpp create mode 100755 src/dis6808.h create mode 100755 src/dis6809.cpp create mode 100755 src/dis6809.h create mode 100755 src/icon.h create mode 100755 src/log.cpp create mode 100755 src/log.h create mode 100755 src/sdlemu_config.cpp create mode 100755 src/sdlemu_config.h create mode 100755 src/sdlemu_opengl.c create mode 100755 src/sdlemu_opengl.h create mode 100755 src/settings.cpp create mode 100755 src/settings.h create mode 100755 src/sound.cpp create mode 100755 src/sound.h create mode 100755 src/stargem2.cpp create mode 100755 src/timing.cpp create mode 100755 src/timing.h create mode 100755 src/types.h create mode 100755 src/v6808.cpp create mode 100755 src/v6808.h create mode 100755 src/v6809.cpp create mode 100755 src/v6809.cpp.bak create mode 100755 src/v6809.h create mode 100755 src/video.cpp create mode 100755 src/video.h create mode 100755 stargem2.cfg diff --git a/Makefile b/Makefile new file mode 100755 index 0000000..40b8c56 --- /dev/null +++ b/Makefile @@ -0,0 +1,135 @@ +# +# Makefile for StarGem 2 SDL +# +# by James L. Hammons +# (C) 2005 Underground Software +# This software is licensed under the GPL v2 +# + +ifeq "$(OSTYPE)" "msys" # Win32 + +SYSTYPE = __GCCWIN32__ +EXESUFFIX = .exe +GLLIB = -lopengl32 +ICON = obj/icon.o +SDLLIBTYPE = --libs +MSG = Win32 on MinGW + +else +#ifeq "$(OSTYPE)" "darwin" +ifeq "darwin" "$(findstring darwin,$(OSTYPE))" # Should catch both 'darwin' and 'darwin7.0' + +SYSTYPE = __GCCUNIX__ -D_OSX_ +EXESUFFIX = +GLLIB = +ICON = +SDLLIBTYPE = --static-libs +MSG = Mac OS X + +else # *nix + +SYSTYPE = __GCCUNIX__ +EXESUFFIX = +GLLIB = -lGL +ICON = +SDLLIBTYPE = --libs +MSG = generic Unix/Linux + +endif +endif + +CC = gcc +LD = gcc +TARGET = stargem2 + +CFLAGS = -MMD -Wall -Wno-switch -Wno-uninitialized -O2 -D$(SYSTYPE) -fomit-frame-pointer `sdl-config --cflags` +CPPFLAGS = -MMD -Wall -Wno-switch -Wno-non-virtual-dtor -Wno-uninitialized -O2 -D$(SYSTYPE) \ + -fomit-frame-pointer `sdl-config --cflags` +# -fomit-frame-pointer `sdl-config --cflags` -g +# -fomit-frame-pointer `sdl-config --cflags` -DLOG_UNMAPPED_MEMORY_ACCESSES + +LDFLAGS = + +LIBS = -L/usr/local/lib `sdl-config $(SDLLIBTYPE)` -lstdc++ -lz $(GLLIB) + +INCS = -I. -Isrc -I/usr/local/include + +#THECC = $(CC) $(CFLAGS) $(INCS) + +OBJS = \ + obj/dis6808.o \ + obj/dis6809.o \ + obj/log.o \ + obj/v6808.o \ + obj/v6809.o \ + obj/video.o \ + obj/settings.o \ + obj/sound.o \ + obj/sdlemu_config.o \ + obj/sdlemu_opengl.o \ + obj/timing.o \ + obj/stargem2.o \ + $(ICON) + +all: checkenv message obj $(TARGET)$(EXESUFFIX) + @echo + @echo "*** Looks like it compiled OK... Give it a whirl!" + +# Check the compilation environment, barf if not appropriate + +checkenv: + @echo + @echo -n "*** Checking compilation environment... " +ifeq "" "$(shell which sdl-config)" + @echo + @echo + @echo "It seems that you don't have the SDL development libraries installed. If you" + @echo "have installed them, make sure that the sdl-config file is somewhere in your" + @echo "path and is executable." + @echo +#Is there a better way to break out of the makefile? + @break +else + @echo "OK" +endif + +message: + @echo + @echo "*** Building StarGem 2 for $(MSG)..." + @echo + +clean: + @echo -n "*** Cleaning out the garbage..." + @rm -rf obj + @rm -f ./$(TARGET)$(EXESUFFIX) + @echo "done!" + +obj: + @mkdir obj + +# This is only done for Win32 at the moment... + +ifneq "" "$(ICON)" +$(ICON): res/$(TARGET).rc res/$(TARGET).ico + @echo "*** Processing icon..." + @windres -i res/$(TARGET).rc -o $(ICON) --include-dir=./res +endif + +obj/%.o: src/%.c + @echo "*** Compiling $<..." + @$(CC) $(CFLAGS) $(INCS) -c $< -o $@ + +obj/%.o: src/%.cpp + @echo "*** Compiling $<..." + @$(CC) $(CPPFLAGS) $(INCS) -c $< -o $@ + +$(TARGET)$(EXESUFFIX): $(OBJS) + @echo "*** Linking it all together..." + @$(LD) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) +# strip --strip-all $(TARGET)$(EXESUFFIX) +# upx -9 $(TARGET)$(EXESUFFIX) + +# Pull in dependencies autogenerated by gcc's -MMD switch +# The "-" in front in there just in case they haven't been created yet + +-include obj/*.d diff --git a/ROMs/01 b/ROMs/01 new file mode 100755 index 0000000000000000000000000000000000000000..ebbf7e14ed38ff9a3ece7f9803becc01339d1917 GIT binary patch literal 4096 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 literal 0 HcmV?d00001 diff --git a/ROMs/03 b/ROMs/03 new file mode 100755 index 0000000000000000000000000000000000000000..ddcc9de7cc1a4b3d5174a37558be8dd44ef3d9c7 GIT binary patch literal 4096 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

ie-K0>eTtJ}gFkDz$Bwol<6H zd&`~~m4@u4QR%FGV^sRa{t}j?dzd8Y1g6+>Q=yno)+9;pNxCU7H)FmN(oG5HNeCVY bMDRo-V~etbQWEkY67MG`NGHH4=iU4-N6hza literal 0 HcmV?d00001 diff --git a/ROMs/05 b/ROMs/05 new file mode 100755 index 0000000000000000000000000000000000000000..3cc86d8fc556a0f02853c82393cc532b813b44e6 GIT binary patch literal 4096 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 literal 0 HcmV?d00001 diff --git a/ROMs/06 b/ROMs/06 new file mode 100755 index 0000000000000000000000000000000000000000..004f1fc8c761a6f7874385c5c19de71f5b271e27 GIT binary patch literal 4096 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 literal 0 HcmV?d00001 diff --git a/ROMs/08 b/ROMs/08 new file mode 100755 index 0000000000000000000000000000000000000000..9718adf95f9e1f00ad22eec5f50a8d76b5c55dc5 GIT binary patch literal 4096 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 literal 0 HcmV?d00001 diff --git a/ROMs/09 b/ROMs/09 new file mode 100755 index 0000000000000000000000000000000000000000..ece946ca72cef9bc99576c811dfb847f226455d6 GIT binary patch literal 4096 zcmeHJL2qP75w4&IYezyeZW4hIhmK>dQ4WsnWsNcGo#}b6XQuIcuOHq0Y>%>$EFlF6 ztzebQo`{BIKz4){heM)Bdsr#RL5mQ+At4UCw;=KZxP${paN)u)Sib5v<8g%cj!=B? zysoaUs;>I#tJb+rgRv#$x*uBO6-sp(wBs*l2E!Z@iVk z6bMK=>4&DGLYK1CI)j~HVcu2IS>uS8Qsucl&>2z}5WeSIwSMAB4v{$RgY>C&T9&HN zEmxP8jP z2Nc~zArv35?3_5MSe^4~y#eH#e-gLXdEK1>lOz+b*lE+ExKk5|JHfaWWeMy<`(Tc@-yoL1q%#a^sEpbD4sa(aITy*@;r#|*|4d70?|x&WSF^`$YDwl!Ji?-%%6riJw^;9ow~ zI{7;#%VKLxtqJ&IawNWfN+`*JGst@7EE|)3W%Al-KzH)^xydgnf#ze_{PH<}i-aeo7!*)h>yzK(FsW95S;oK2x+6`j=U#QG-E1!rQvcWNu20Y*F$FSBWd4 zU3c^Px|A{skgV>;`Z^^~MtQD!MwK#FN)GC(8g(~$>$n<%$oM;XB70_lR%%w)5J8y^ zjrQH^(0e}{fdDKk!hB<9SQm}`Pv*W+lAc0Z5D1%Ju589S@eul=z{UpK%W_p_v&F|n z9aI^borhN#GXn;+l)BUfLZIYfYO7HL<&AG`Z_t6sbE5zRkYoz3EltXuknU2l)DXGv z>~L-_lSO7cW31BvWDZ>#fZL?kI2inNcM4f}UTl9F%*hi-8XuAm!XpHc9SFY{?cuSS zGIBF>U}{b}H!f-3nCV64R>%{xHTTR&wmEqfx)(z$Irhn2oxGMNwM#OcTnouEOGUem zq|;eoCQNIfVo9PpsSZ-E$nMUL zMONJb+FAbBVbOUH6GGamvYxrZ8w@`TcbG0U2k?7z!W=QE-}J&L8kla1eu??+0XSXa z#0Qkr7x8q&<_EOUSOd#dIfg6BFa%}r`3pUnTTG74-_TqFpztKmrp0c+c0CMZ+3A(^ zmgGK@Pwz9aeg{>KPnyV0^Fh=BU9?VK7dxksul)$GB6RA&f)7~U<=NRCV@0i#bI>^m zwjDns*YfAtTzb|paGRR>CKpL`?tt?arvU9h{a?vLv3X1vG?&>ypT}O@`dF+T$2r!p z6gt%&@DxHK!BOkq20w~#uHw0K(J)RI3Rf!!QwkB=s{|qgg7|&ZJTzrjuH&M|;?-4p zwoPBU|5wpnrJLZ!RFx&*EpNhs*uu$JZ0T#)$C$*s5{SbC34Uuf%!O*mkmpi_yUwtA zSFEqnV(aa{wOeohTbIPm1+2%HC*C!fZ+N}p>4#@PG1Z3h29y=9wlqaAQ{cl$Zx(dI zGwvG|?e6YIYk+2aZnDyn*ur=X0X;qwiW^6Gd=wSlg*+;si0xBqp33r2$|YKP8H8d` zcYi@Aas@)%!VF4gu){R3z1i3KD2_1fJq=G1dp-1dJpkxswI;u#93HcgyK;5lG@de2 zufaC>HG287}<98X2JkNbS~_gM!1e==~r{k!7By`NqAFhAS7_Y3g` z{rcYh)%LwVzJ50O$7FKlJ$v@6$(48Pi_hFTn@qOjavRIf{dwUm|LHSV+mJqr(nnF+ c{pWb&g`eNwy87q``PJY4@GoEdU(eKk0BD>)LjV8( literal 0 HcmV?d00001 diff --git a/ROMs/10 b/ROMs/10 new file mode 100755 index 0000000000000000000000000000000000000000..d93d561796a9a5e7870ee08eb616c33ac20f42a8 GIT binary patch literal 4096 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 AdjJ3c literal 0 HcmV?d00001 diff --git a/ROMs/11 b/ROMs/11 new file mode 100755 index 0000000000000000000000000000000000000000..5dd94dff71390d951c9484d37ebbc9c9cc195de3 GIT binary patch literal 4096 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 WK2B3F<;ZtuV7s$`TbS(sANW82gWqca literal 0 HcmV?d00001 diff --git a/ROMs/12 b/ROMs/12 new file mode 100755 index 0000000000000000000000000000000000000000..8fea102d935f99aa52942e127b8fba0ccca37a55 GIT binary patch literal 4096 zcmeHJeNY?M5r20&AutdQf5oVTI}7Oq{yZ$HV|g+GA_T#J!PETF z)}1+vL0m&DogJeDXA1tP6^SG@t<%=n<6aG|VdNTXGI7Vwv>0Py>EE$5b8q+U?%RF8w{Q0$^z`=>fu{(3QxRZm>q?y!rFC|8Eo*aZ{f@J;;-xy4 zEwB}`Mb?c)?Dop)>dMlZTGn1|x79fvTPkg}Y~>c)I+iW1u4WbWTGnZ=wL7=j%h>-L zMq%O|VdAhbab1YMD8!DNmx}~TnwMYB+F_=4d^Ic$&Tf*I=9;NTpN~dzf+K;~T2W5$ zwZLu|c&)rtZ=o!typ*?)mUp!YI(#W{FqC;Plp#LfgU2kfw)-=L(XTPid(a zjW$J2d6-*IVs;+aGEA zxsIDI($k))quiL74T8&_5^n@I z^_``z`>s<_UsR=0MVDxnMDsQIQIp0LwP|e8T1{&tDWjH zdx|rq%&u{2kUiCzYO<#}(@gep=eWr};hZqpqs}O@$DFY;`=oQSj1p{uu1;tZbYvqb zQL09j#J4rJNyyjelgyTsq2fplK6w+q9j;&nXbg;sAXcc?n+O*-taklbEvrCvrNbaT8h^vGa_)3X^k{PGE6^82HF!p zzzthT6-BRLOI#?CeNXp=X|U|#%O8I4y&t>@sRrmnYQ?R|5XD8oDjeoY2s7M?8hf*w zI~V0og{NQea`=vDybP{j8gBu>ooMLOEknWjrW7fM-u8%TBju+_X&xvzKqcl@_UzVvhS?H7$Y zv4kN8`4oA{1&a^(#h4$sc#|HzEbn)U&%%|q_(B<-C`5IVp_EPvVJZcvRD^VBO+GT| z(Ix{b<ttWoM6H*cJ&IY36$>vc=o?bhCH8?t|u??KNFW#QuShZLJgN3ZlZoal5Ka2~}FaoE8^F*WqawAgn zu$s<%46c=Gile)PnT0w#GYHIRgz&j8vQ1np{Rr4a3u1qF$+t4Sqha%YB!q;WRrriYM7KVZ`Ur*gZnV#e8c5nL>1S zGvf2_g%QpE!&F*fP;WPoY>eTRc1(xoUWJB$;zopaJKk_R}X12C}*S7yxu4PBiN%Tw9i#}OD%#0D}`6uhdH+N=2 LO#VAwPmccvv@3f) literal 0 HcmV?d00001 diff --git a/ROMs/sg.snd b/ROMs/sg.snd new file mode 100755 index 0000000000000000000000000000000000000000..9a87d9840f73426a9b8b78814202bf6795460a12 GIT binary patch literal 2048 zcmZWpZ)_9i8Gqipv-6%4+jstRw&NHdv2#aZ>%ychv(|wb+2W?qAT`@sAPSqNYK>IE z1g#KtV|zlktxcw-qIYS-2R>BJhjbEZ1yw&-fe*E+vRPC@@qpGQAJ$}5l@(En=Y5|)zvs`rRrlW@Q{vz#Im&A0JRD`Tfq7PYVxAcMh|ytihRv`W)Frp2 zR4NrNfw$@|wVo(6SBm^({gxj7fCJrY^yoe#QVHrk$2s6tVOXi-LXYsO4VUujMGkh5 zy|05M+%xA#@yMKHL}miY6}?-v&v^~6@?kSs@8Qq6g zD-v(1FE9D7dR4w6Q9Y<$mH(M2k}@}9gk&Fn5RMaJg-YzIwrMk1Myna{S0oHd8XX<| zw_|h@(~|d92&v39-tsx)==Jcbf^Kg5-}3cIGmhBTvcRjB~Be62f>l|Nhx zsuy(cl7H~m*4%sGPbMmP%YMwt?Bx#SOhRiJ?h^dI+Ih1}7vJhM#7bu$CxgsVRjhWN zcE5ha5GwAxm0$U@#0U~Y9GMXnD@#SsL8Y~C`)ypNLEOHYz#1L}It5{+rX>w8vRc*< z$Ma+X=E-*Erg#EGx^e#1Jxj-ptz#(q{Zk;S_I=nV@@-mmBdt0ugoZy))|jey+EsB=998#Or?Q$rP*RqO`E#tw z7s(3HEF<48&a7ZxQd*o`fnt4y6yIB6D&CQA!E?Cmx#l1JD?Ivyu}f1aOaQO4lOQF2 zoCnMCJfNqFlO9z5_rt`9)zyg%aJubuCKpl2$UfvXSE2D6-Ihx2Ei~O}2o##4T+`S> zZTph_a#SJXhs$D2q$tEW~8xDs{ z?JqIzJV>YAh7UVswCv3jt7S&Ze%!*!mD*2Xo_5eYY-H+AHCSjqRq4z#Mt7k(h6~n^ z@|+RK+oZg`WIluD0@ZK^VpcvQ3HMTKA--W5%@24N&WdL2&g|p8?j1wT#vm9(hmCq^ijEU0aT{X zHl|Y9J*KeL@L_s3qI^E4kVG}2`&Iii)w`#q$wmQ77{?q3zW`dO->SH)(ZqgrM;EDl1fB=9D>$T6?4qZ$xKKah^!9O{9p}+b`SJF z7K;QtPRh~Db@O^A4si-ej2yB_A#?uvUGwhs^O>jPJn-?Sh0I4^tt?KzIFUK?#vhXb zPeL$p0FDPV_1c@~7A`D){OOJ5)wMhK8m+e3ZZ+=RSzBGc@#)8l7Z%RF`C8_siSg0l z?_X=gzR7s4dmkJM%wAI zb(^5RDB48gCPU&*Am9vt6;28S$85S7( znF)bG@^;h%rodSur~n>2n1tVUZuakg$(}s+ha=A(7)%nvFdRpzAoL%(bj#vc&SvkR zyrV0dK6&EUiIeH5CG6MkRm|JG%nLQJpmseeXhZK_!x5!6@tz%y^k|_L&>%TTS9;!fVp_o zinAn#pI^Tpziz8Me%ZF4-hQ0iZKr_t@86ELJHe(5CP7kk<6sgbMSnP$1WD1I2a_Nv zdceUXNQ$0hFbR@E>w2a-NQzEoFbR^P6C6x}r0ApvlOQR2A%jVf6ur2?BuEMqn0>A% z)Jf5sFqi~M(Hk?E1WD1GHJAiR(Hl6J1WD1GI+z4WVIcW*Cb6DW7rps|NsttMAcIMe z6n#j8NsttMaDz#Z6n&V3Nstse$ftLuGs*Rox(|IY36i2O!eA04MPH7=BuI+BFoQ{u z6e{^>CrAnb`Sc0(u5>1~9v{m`J3&$yKt9?DlER?!(N2&QCX$bKf}}9HDYO$LMVJ2l zte#itERSy=*W2OniQ|%&-}M!2`~Bgt-(Ow9e~)M0-`|@5Z{oMs*Zr@q?)iDUSNVS& tXpit#PCc*3&-cK`-ScfWZy&|a+s@y&-R}0?Uh(rDm+!}kFWb)l{Q*#AV?qD` literal 0 HcmV?d00001 diff --git a/res/stargem2.ico b/res/stargem2.ico new file mode 100755 index 0000000000000000000000000000000000000000..d172beaceb73ad806d7fc0426b74805ff545789c GIT binary patch literal 766 zcmb`FF%H5o3`O0-KvkhKF-J@+oT04TDq|4~BN@0v#Q|~zR&K!910b1iXw}B4Dk0(Y zJ9%~;H&uud3}aR#_DqS^n75FD_E17|cp{73xLG8TvGzN`V@ck7%#z^GL(H;*FeD@{ zw(K0n{>;nA^*(IyE9dntsE^qUx2L=gIo(WiP#nXes*cX}zesWBE>&mpo@VL-r`zGP ziQ>$))^^a0`o6b(onnPL9i8V@GLNY#m?wq0W+0E-B#Igkm54zFa*$j)Xx8ctgU_fA literal 0 HcmV?d00001 diff --git a/res/stargem2.rc b/res/stargem2.rc new file mode 100755 index 0000000..f7a9217 --- /dev/null +++ b/res/stargem2.rc @@ -0,0 +1,9 @@ +#include "winresrc.h" + +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_ICON1 ICON DISCARDABLE "stargem2.ico" diff --git a/src/dis6808.cpp b/src/dis6808.cpp new file mode 100755 index 0000000..98b1bf4 --- /dev/null +++ b/src/dis6808.cpp @@ -0,0 +1,141 @@ +// +// 6808 disassembler +// +// by James L. Hammons +// +// (c) 2004 Underground Software +// + +#include "dis6808.h" + +#include +#include +#include "v6808.h" +#include "log.h" + +using namespace std; + +// External shit + +extern V6808REGS soundCPU;//Hm. + +// Private globals variables + +static char op_mat[256] = { + 0, 5, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 0, 0, 0, 0, 5, 5, 0, 5, 0, 5, 0, 0, 0, 0, + 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 0, 5, 0, 0, 5, 5, + 5, 0, 0, 5, 5, 0, 5, 5, 5, 5, 5, 0, 5, 5, 0, 5, + 5, 0, 0, 5, 5, 0, 5, 5, 5, 5, 5, 0, 5, 5, 0, 5, + 7, 0, 0, 7, 7, 0, 7, 7, 7, 7, 7, 0, 7, 7, 7, 7, + 2, 0, 0, 2, 2, 0, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, + 8, 8, 8, 0, 8, 8, 8, 0, 8, 8, 8, 8, 9, 3, 9, 0, + 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, + 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 8, 8, 8, 0, 8, 8, 8, 0, 8, 8, 8, 8, 0, 0, 9, 0, + 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, + 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 7, 7, + 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 2, 2 +}; + +static char mnemonics[256][6] = { + "??? ","NOP ","??? ","??? ","??? ","??? ","TAP ","TPA ", + "INX ","DEX ","CLV ","SEV ","CLC ","SEC ","CLI ","SEI ", + "SBA ","CBA ","??? ","??? ","??? ","??? ","TAB ","TBA ", + "??? ","DAA ","??? ","ABA ","??? ","??? ","??? ","??? ", + "BRA ","??? ","BHI ","BLS ","BCC ","BCS ","BNE ","BEQ ", + "BVC ","BVS ","BPL ","BMI ","BGE ","BLT ","BGT ","BLE ", + "TSX ","INS ","PULA ","PULB ","DES ","TXS ","PSHA ","PSHB ", + "??? ","RTS ","??? ","RTI ","??? ","??? ","WAI ","SWI ", + "NEGA ","??? ","??? ","COMA ","LSRA ","??? ","RORA ","ASRA ", + "ASLA ","ROLA ","DECA ","??? ","INCA ","TSTA ","??? ","CLRA ", + "NEGB ","??? ","??? ","COMB ","LSRB ","??? ","RORB ","ASRB ", + "ASLB ","ROLB ","DECB ","??? ","INCB ","TSTB ","??? ","CLRB ", + "NEG ","??? ","??? ","COM ","LSR ","??? ","ROR ","ASR ", + "ASL ","ROL ","DEC ","??? ","INC ","TST ","JMP ","CLR ", + "NEG ","??? ","??? ","COM ","LSR ","??? ","ROR ","ASR ", + "ASL ","ROL ","DEC ","??? ","INC ","TST ","JMP ","CLR ", + "SUBA ","CMPA ","SBCA ","??? ","ANDA ","BITA ","LDAA ","??? ", + "EORA ","ADCA ","ORAA ","ADDA ","CPX ","BSR ","LDS ","??? ", + "SUBA ","CMPA ","SBCA ","??? ","ANDA ","BITA ","LDAA ","STAA ", + "EORA ","ADCA ","ORAA ","ADDA ","CPX ","??? ","LDS ","STS ", + "SUBA ","CMPA ","SBCA ","??? ","ANDA ","BITA ","LDAA ","STAA ", + "EORA ","ADCA ","ORAA ","ADDA ","CPX ","JSR ","LDS ","STS ", + "SUBA ","CMPA ","SBCA ","??? ","ANDA ","BITA ","LDAA ","STAA ", + "EORA ","ADCA ","ORAA ","ADDA ","CPX ","JSR ","LDS ","STS ", + "SUBB ","CMPB ","SBCB ","??? ","ANDB ","BITB ","LDAB ","??? ", + "EORB ","ADCB ","ORAB ","ADDB ","??? ","??? ","LDX ","??? ", + "SUBB ","CMPB ","SBCB ","??? ","ANDB ","BITB ","LDAB ","STAB ", + "EORB ","ADCB ","ORAB ","ADDB ","??? ","??? ","LDX ","STX ", + "SUBB ","CMPB ","SBCB ","??? ","ANDB ","BITB ","LDAB ","STAB ", + "EORB ","ADCB ","ORAB ","ADDB ","??? ","??? ","LDX ","STX ", + "SUBB ","CMPB ","SBCB ","??? ","ANDB ","BITB ","LDAB ","STAB ", + "EORB ","ADCB ","ORAB ","ADDB ","??? ","??? ","LDX ","STX " +}; + +// +// Display bytes in mem in hex +// +static void DisplayBytes(uint16 src, uint32 dst) +{ + WriteLog("%04X: ", src); + uint8 cnt = 0; // Init counter... + + if (src > dst) + dst += 0x10000; // That should fix the FFFF bug... + + for(uint32 i=src; i +#include +#include "v6809.h" +#include "log.h" + +using namespace std; + +// External shit + +extern V6809REGS mainCPU;//Hm. + +static char op_mat1[256] = { + 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, + 0, 0, 5, 5, 0, 0, 4, 4, 0, 5, 8, 0, 8, 5, 6, 6, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 7, 7, 7, 7, 6, 6, 6, 6, 0, 5, 5, 5, 8, 5, 5, 5, + 5, 0, 0, 5, 5, 0, 5, 5, 5, 5, 5, 0, 5, 5, 0, 5, + 5, 0, 0, 5, 5, 0, 5, 5, 5, 5, 5, 0, 5, 5, 0, 5, + 7, 0, 0, 7, 7, 0, 7, 7, 7, 7, 7, 0, 7, 7, 7, 7, + 2, 0, 0, 2, 2, 0, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, + 8, 8, 8, 9, 8, 8, 8, 0, 8, 8, 8, 8, 9, 3, 9, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 8, 8, 8, 9, 8, 8, 8, 0, 8, 8, 8, 8, 9, 0, 9, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 +}, + +op_mat2[256] = { + 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, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, + 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, 0, + 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 9, 0, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 7, + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2 +}, + +op_mat3[256] = { + 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, 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, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 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, 0, 0, 0, 0 +}; + +static char mnemonics[256][6] = { + "NEG ","??? ","??? ","COM ","LSR ","??? ","ROR ","ASR ", + "LSL ","ROL ","DEC ","??? ","INC ","TST ","JMP ","CLR ", + "PAGE1","PAGE2","NOP ","SYNC ","??? ","??? ","LBRA ","LBSR ", + "??? ","DAA ","ORCC ","??? ","ANDCC","SEX ","EXG ","TFR ", + "BRA ","BRN ","BHI ","BLS ","BHS ","BLO ","BNE ","BEQ ", + "BVC ","BVS ","BPL ","BMI ","BGE ","BLT ","BGT ","BLE ", + "LEAX ","LEAY ","LEAS ","LEAU ","PSHS ","PULS ","PSHU ","PULU ", + "??? ","RTS ","ABX ","RTI ","CWAI ","MUL ","RESET","SWI ", + "NEGA ","??? ","??? ","COMA ","LSRA ","??? ","RORA ","ASRA ", + "LSLA ","ROLA ","DECA ","??? ","INCA ","TSTA ","??? ","CLRA ", + "NEGB ","??? ","??? ","COMB ","LSRB ","??? ","RORB ","ASRB ", + "LSLB ","ROLB ","DECB ","??? ","INCB ","TSTB ","??? ","CLRB ", + "NEG ","??? ","??? ","COM ","LSR ","??? ","ROR ","ASR ", + "LSL ","ROL ","DEC ","??? ","INC ","TST ","JMP ","CLR ", + "NEG ","??? ","??? ","COM ","LSR ","??? ","ROR ","ASR ", + "LSL ","ROL ","DEC ","??? ","INC ","TST ","JMP ","CLR ", + "SUBA ","CMPA ","SCBA ","SUBD ","ANDA ","BITA ","LDA ","??? ", + "EORA ","ADCA ","ORA ","ADDA ","CMPX ","BSR ","LDX ","??? ", + "SUBA ","CMPA ","SBCA ","SUBD ","ANDA ","BITA ","LDA ","STA ", + "EORA ","ADCA ","ORA ","ADDA ","CMPX ","JSR ","LDX ","STX ", + "SUBA ","CMPA ","SBCA ","SUBD ","ANDA ","BITA ","LDA ","STA ", + "EORA ","ADCA ","ORA ","ADDA ","CMPX ","JSR ","LDX ","STX ", + "SUBA ","CMPA ","SBCA ","SUBD ","ANDA ","BITA ","LDA ","STA ", + "EORA ","ADCA ","ORA ","ADDA ","CMPX ","JSR ","LDX ","STX ", + "SUBB ","CMPB ","SCBB ","ADDD ","ANDB ","BITB ","LDB ","??? ", + "EORB ","ADCB ","ORB ","ADDB ","LDD ","??? ","LDU ","??? ", + "SUBB ","CMPB ","SBCB ","ADDD ","ANDB ","BITB ","LDB ","STB ", + "EORB ","ADCB ","ORB ","ADDB ","LDD ","STD ","LDU ","STU ", + "SUBB ","CMPB ","SBCB ","ADDD ","ANDB ","BITB ","LDB ","STB ", + "EORB ","ADCB ","ORB ","ADDB ","LDD ","STD ","LDU ","STU ", + "SUBB ","CMPB ","SBCB ","ADDD ","ANDB ","BITB ","LDB ","STB ", + "EORB ","ADCB ","ORB ","ADDB ","LDD ","STD ","LDU ","STU " +}, + +mnemonics2[256][6] = { + "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", + "??? ","LBRN ","LBHI ","LBLS ","LBHS ","LBLO ","LBNE ","LBEQ ", + "LBVC ","LBVS ","LBPL ","LBMI ","LBGE ","LBLT ","LBGT ","LBLE ", + "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","??? ","??? ","??? ","SWI2 ", + "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","CMPD ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","CMPY ","??? ","LDY ","??? ", + "??? ","??? ","??? ","CMPD ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","CMPY ","??? ","LDY ","STY ", + "??? ","??? ","??? ","CMPD ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","CMPY ","??? ","LDY ","STY ", + "??? ","??? ","??? ","CMPD ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","CMPY ","??? ","LDY ","STY ", + "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","??? ","??? ","LDS ","??? ", + "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","??? ","??? ","LDS ","STS ", + "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","??? ","??? ","LDS ","STS ", + "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","??? ","??? ","LDS ","STS " +}, + +mnemonics3[256][6] = { + "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","??? ","??? ","??? ","SWI3 ", + "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","CMPU ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","CMPS ","??? ","??? ","??? ", + "??? ","??? ","??? ","CMPU ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","CMPS ","??? ","??? ","??? ", + "??? ","??? ","??? ","CMPU ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","CMPS ","??? ","??? ","??? ", + "??? ","??? ","??? ","CMPU ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","CMPS ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", + "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? " +}, + +tregs[16][3] = { + "D", "X", "Y", "U", "S", "PC", "??", "??", + "A", "B", "CC", "DP", "??", "??", "??", "??" +}, + +iregs[4][2] = {"X", "Y", "U", "S" }; + +// +// Display bytes in mem in hex +// +static void DisplayBytes(uint16 src, uint32 dst) +{ + WriteLog("%04X: ", src); + uint8 cnt = 0; // Init counter... + + if (src > dst) + dst += 0x10000; // That should fix the FFFF bug... + + for(uint32 i=src; i> 4], tregs[operand & 0x0F]); + else + { + tmp[0] = 0; + if (operand & 0x01) strcat(tmp, "CC "); + if (operand & 0x02) strcat(tmp, "A "); + if (operand & 0x04) strcat(tmp, "B "); + if (operand & 0x08) strcat(tmp, "DP "); + if (operand & 0x10) strcat(tmp, "X "); + if (operand & 0x20) strcat(tmp, "Y "); + if (operand & 0x40) (((opcode == 0x34) || (opcode == 0x35)) ? strcat(tmp, "U ") : strcat(tmp, "S ")); + if (operand & 0x80) strcat(tmp, "PC"); + } + + sprintf(outbuf, "%s %s", mnem, tmp); + break; + case 7: // Indexed (the tough one!) + { + operand = mainCPU.RdMem(addr++); // Get IDX byte + uint8 reg = ((operand & 0x60) >> 5), idxind = ((operand & 0x10) >> 4), + lo_nyb = (operand & 0x0F), boff; + uint16 woff; + + strcpy(tmp, "??"); + if (!(operand & 0x80)) // Hi bit set? Then decode 4 bit offset + sprintf(tmp, "(%d),%s", (idxind ? -(16-lo_nyb) : lo_nyb), iregs[reg]); + else // Add the ($nnnn,R) code dude... + { + if (idxind) + { + switch(lo_nyb) + { + case 1: sprintf(tmp, "(,%s++)", iregs[reg]); break; + case 3: sprintf(tmp, "(,--%s)", iregs[reg]); break; + case 4: sprintf(tmp, "(,%s)", iregs[reg]); break; + case 5: sprintf(tmp, "(B,%s)", iregs[reg]); break; + case 6: sprintf(tmp, "(A,%s)", iregs[reg]); break; + case 8: + boff = mainCPU.RdMem(addr++); + sprintf(tmp, "($%02X,%s)", boff, iregs[reg]); + break; + case 9: + woff = (mainCPU.RdMem(addr++) << 8) | mainCPU.RdMem(addr++); + sprintf(tmp, "($%04X,%s)", woff, iregs[reg]); + break; + case 11: sprintf(tmp, "(D,%s)", iregs[reg]); break; + case 12: + boff = mainCPU.RdMem(addr++); + sprintf(tmp, "($%02X,PC)", boff); + break; + case 13: + woff = (mainCPU.RdMem(addr++) << 8) | mainCPU.RdMem(addr++); + sprintf(tmp, "($%04X,PC)", woff); + break; + case 15: + woff = (mainCPU.RdMem(addr++) << 8) | mainCPU.RdMem(addr++); + sprintf(tmp, "[$%04X]", woff); + break; + default: + strcpy(tmp, "??"); + } + } + else + { + switch(lo_nyb) + { + case 0: sprintf(tmp, ",%s+", iregs[reg]); break; + case 1: sprintf(tmp, ",%s++", iregs[reg]); break; + case 2: sprintf(tmp, ",-%s", iregs[reg]); break; + case 3: sprintf(tmp, ",--%s", iregs[reg]); break; + case 4: sprintf(tmp, ",%s", iregs[reg]); break; + case 5: sprintf(tmp, "(B),%s", iregs[reg]); break; + case 6: sprintf(tmp, "(A),%s", iregs[reg]); break; + case 8: + boff = mainCPU.RdMem(addr++); + sprintf(tmp, "($%02X),%s", boff, iregs[reg]); + break; + case 9: + woff = (mainCPU.RdMem(addr++) << 8) | mainCPU.RdMem(addr++); + sprintf(tmp, "($%04X),%s", woff, iregs[reg]); + break; + case 11: + sprintf(tmp, "(D),%s", iregs[reg]); + break; + case 12: + boff = mainCPU.RdMem(addr++); + sprintf(tmp, "($%02X),PC", boff); + break; + case 13: + woff = (mainCPU.RdMem(addr++) << 8) | mainCPU.RdMem(addr++); + sprintf(tmp, "($%04X),PC", woff); + break; + default: + strcpy(tmp, "??"); + } + } + } + sprintf(outbuf, "%s %s", mnem, tmp); + break; + } + case 8: // Immediate + sprintf(outbuf, "%s #$%02X", mnem, mainCPU.RdMem(addr++)); + break; + case 9: // Long Immediate + sprintf(outbuf, "%s #$%04X", mnem, (mainCPU.RdMem(addr++) << 8) | mainCPU.RdMem(addr++)); + break; + } + + DisplayBytes(pc, addr); // Show bytes + WriteLog("%s", outbuf); // Display opcode & addressing, etc. + + return addr - pc; +} diff --git a/src/dis6809.h b/src/dis6809.h new file mode 100755 index 0000000..26664de --- /dev/null +++ b/src/dis6809.h @@ -0,0 +1,15 @@ +// +// DIS6809.H +// +// by James L. Hammons +// (C) 2004 Underground Software +// + +#ifndef __DIS6809_H__ +#define __DIS6809_H__ + +#include "types.h" + +int Decode6809(uint16); + +#endif // __DIS6809_H__ diff --git a/src/icon.h b/src/icon.h new file mode 100755 index 0000000..1852969 --- /dev/null +++ b/src/icon.h @@ -0,0 +1,38 @@ +// +// This file was automagically generated by raw2c (by James L. Hammons) +// + +char icon[0x1000] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x80, 0xFF, 0x00, 0x00, 0x80, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x80, 0xFF, 0x00, 0x00, 0x80, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x80, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x80, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; diff --git a/src/log.cpp b/src/log.cpp new file mode 100755 index 0000000..236d563 --- /dev/null +++ b/src/log.cpp @@ -0,0 +1,54 @@ +// +// Log handler +// +// by James L. Hammons +// + +#include "types.h" +#include "log.h" + +#define MAX_LOG_SIZE 10000000 // Maximum size of log file (10 MB) + +static FILE * log_stream = NULL; +static uint32 logSize = 0; + +bool InitLog(char * path) +{ + log_stream = fopen(path, "wrt"); + + if (log_stream == NULL) + return false; + + return true; +} + +void LogDone(void) +{ + if (log_stream) + fclose(log_stream); +} + +// +// This logger is used mainly to ensure that text gets written to the log file +// even if the program crashes. The performance hit is acceptable in this case! +// +void WriteLog(const char * text, ...) +{ + if (!log_stream) + return; + + va_list arg; + + va_start(arg, text); + logSize += vfprintf(log_stream, text, arg); + + if (logSize > MAX_LOG_SIZE) + { + fflush(log_stream); + fclose(log_stream); + exit(1); + }//*/ + + va_end(arg); + fflush(log_stream); // Make sure that text is written! +} diff --git a/src/log.h b/src/log.h new file mode 100755 index 0000000..4b39b36 --- /dev/null +++ b/src/log.h @@ -0,0 +1,24 @@ +// +// LOG.H +// + +#ifndef __LOG_H__ +#define __LOG_H__ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +bool InitLog(char *); +void LogDone(void); +void WriteLog(const char * text, ...); + +#ifdef __cplusplus +} +#endif + +#endif // __LOG_H__ diff --git a/src/sdlemu_config.cpp b/src/sdlemu_config.cpp new file mode 100755 index 0000000..75d7644 --- /dev/null +++ b/src/sdlemu_config.cpp @@ -0,0 +1,149 @@ +/* + * SDLEMU library - Free sdl related functions library + * Copyrigh(c) 1999-2002 sdlemu development crew + * + * 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 + */ + +#include +#include +#include +#include "sdlemu_config.h" + +using namespace std; + +class token_list +{ +public: + token_list(const string &name) : m_name(name), m_value(""), m_token("") {} + void add_token_variable(const string &var) { m_token = var; } + void add_token_value(const string &value) { m_value = value; } + const string &LineName() const { return m_name; } + const string &Token() const { return m_token; } + const string &Value() const { return m_value; } +private: + std::string m_name; + std::string m_value; + std::string m_token; +}; + +std::list vec; + +void string_tokenize_variable() +{ + list::iterator p; + const string delim = " "; + for(p = vec.begin(); p != vec.end(); p++) { + string::size_type lastPos = (*p).LineName().find_first_not_of(delim, 0); + string::size_type pos = (*p).LineName().find_first_of(delim, lastPos); + + if(string::npos != pos && string::npos != lastPos) { + string s = (*p).LineName().substr(lastPos, pos - lastPos); + (*p).add_token_variable(s); + } + } +} + +void string_tokenize_value() +{ + list::iterator p; + const string delim = " =\n\t\r"; // "\r" needed for Win32 compatibility... + + for(p = vec.begin(); p != vec.end(); p++) { + string::size_type lastPos = (*p).LineName().find_first_of(delim, 0); + string::size_type pos = (*p).LineName().find_first_not_of(delim, lastPos); + + if(string::npos != pos && string::npos != lastPos) { + string s = (*p).LineName().substr(pos); + (*p).add_token_value(s); + } + } +} + +int sdlemu_init_config(const char *filename) +{ + FILE *f = fopen(filename, "r"); + if(!f) return 0; + + fseek(f, 0, SEEK_END); + int len = ftell(f); + fseek(f, 0, SEEK_SET); + + char *s = new char[len]; + fread(s, 1, len, f); + string str(s); + + const string delim = "\n\r"; // "\r" needed for Win32 compatibility... + string::size_type lastPos = str.find_first_not_of(delim, 0); + string::size_type pos = str.find_first_of(delim, lastPos); + + while (string::npos != pos || string::npos != lastPos) { + string string = str.substr(lastPos, pos - lastPos); + if(string[0] == '#') + { + } + else if(string[0] == '[') + { + } + else + { + vec.push_back(string); + } + lastPos = str.find_first_not_of(delim, pos); + pos = str.find_first_of(delim, lastPos); + } + string_tokenize_variable(); + string_tokenize_value(); + delete [] s; + fclose(f); + return 1; +} + +const char *sdlemu_getval_string(const char *key_string, const char *default_string) +{ + list::iterator p; + for(p = vec.begin(); p != vec.end(); p++) { + + if(strcmp((*p).Token().c_str(), key_string) == 0) + return (*p).Value().c_str(); + } + return default_string; +} + +int sdlemu_getval_int(const char *key_string, int default_int) +{ + list::iterator p; + for(p = vec.begin(); p != vec.end(); p++) { + + if(strcmp((*p).Token().c_str(), key_string) == 0) { + const char *ret = (*p).Value().c_str(); + if(ret) return atoi(ret); + } + } + return default_int; +} + +int sdlemu_getval_bool(const char *key_string, int default_int) +{ + list::iterator p; + for(p = vec.begin(); p != vec.end(); p++) { + + if(strcmp((*p).Token().c_str(), key_string) == 0) { + const char *ret = (*p).Value().c_str(); + if(ret) return atoi(ret)>0; + } + } + return default_int; +} diff --git a/src/sdlemu_config.h b/src/sdlemu_config.h new file mode 100755 index 0000000..2c2e6d5 --- /dev/null +++ b/src/sdlemu_config.h @@ -0,0 +1,17 @@ +#ifndef __SDL_CONFIG_H__ +#define __SDL_CONFIG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +int sdlemu_init_config(const char * filename); +const char * sdlemu_getval_string(const char * key_string, const char * default_string); +int sdlemu_getval_int(const char * key_string, int default_int); +int sdlemu_getval_bool(const char * key_string, int default_int); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/sdlemu_opengl.c b/src/sdlemu_opengl.c new file mode 100755 index 0000000..7ea9faf --- /dev/null +++ b/src/sdlemu_opengl.c @@ -0,0 +1,535 @@ +/* + * SDLEMU library - Free sdl related functions library + * Copyrigh(c) 1999-2004 sdlemu development crew + * + * 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 + */ + +/* SDLEMU_OPENGL.C + SDLEMU related sources for using OpenGL with SDL. + By Niels Wagenaar | http://sdlemu.ngemu.com | shalafi@xs4all.nl + + Version 1.0.001 - 4-10-2004 + + - Added support for 16, 24 and 32 bit textures; + - Added support for 16, 24 and 32 bit texture rendering; + + Version 1.0.002 - 6-10-2004 + + - Cleaned up a lot of code and removed non functional and obsolete code; + - Removed sdlemu_resize_texture function because of double code; + - Removed the texture creation from the sdlemu_init_opengl; + - Added sdlemu_create_texture function to replace the sdlemu_resize_texture function + and the texture creation in sdlemu_init_opengl; + - Added the usage of OPENGL_16BPP_CORRECT_RGBA for activating the correct 16bpp RGBA masks; + - Added the usage of WANT_OPENGL_ALPHA for using ALPHA blending with 32bpp textures; + - Added automatic and override texture bpp depth setting (based upon the src surface); + +*/ + +#include "sdlemu_opengl.h" + +static SDL_Surface *texture = 0; +static GLuint texid = 0; +static GLfloat texcoord[4]; +static unsigned int glFilter; +static unsigned int texturebpp = 0; // 16, 24 or 32 bpp + +static SDL_Surface * overlay = 0; +static GLuint overlayID = 0; +static GLfloat overlayCoord[4]; +void sdlemu_create_overlay(SDL_Surface * dst, int src_bpp); + +static int showOverlay = 0; + +static inline int power_of_two(int input) +{ + int value = 1; + + while (value < input) + value <<= 1; + + return value; +} + +void sdlemu_init_opengl(SDL_Surface * src, SDL_Surface * dst, int texturetype, int filter, int src_bpp) +{ + printf("\nOpenGL driver information :\n"); + printf("\n"); + printf("Vendor: %s\n", glGetString(GL_VENDOR)); + printf("Renderer: %s\n", glGetString(GL_RENDERER)); + printf("Version: %s\n", glGetString(GL_VERSION)); + printf("OpenGL drawmethod: "); + + switch (texturetype) + { + case 1: + printf("GL_QUAD rendering\n\n"); + break; + default: + printf("GL_TRIANGLE rendering\n\n"); + break; + } + + glFilter = filter; + + // Let us create the texture information : + sdlemu_create_texture(src, dst, filter, src_bpp); + sdlemu_create_overlay(dst, src_bpp); +} + +void sdlemu_draw_texture(SDL_Surface * dst, SDL_Surface * src, int texturetype) +{ +/* + This is needed when we want to render OpenGL textures with the Alpha mask set. + Be warned! This only works with the bpp of texture en *src set to 32. +*/ +#ifdef WANT_OPENGL_ALPHA + Uint32 saved_flags; + Uint8 saved_alpha; + + /* Save the alpha blending attributes */ + saved_flags = src->flags&(SDL_SRCALPHA|SDL_RLEACCELOK); + saved_alpha = src->format->alpha; + if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) { + SDL_SetAlpha(src, 0, 0); + } + + // Blit the src display to the texture. + SDL_BlitSurface(src, NULL, texture, NULL); + + /* Restore the alpha blending attributes */ + if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) { + SDL_SetAlpha(src, saved_flags, saved_alpha); + } +#else + SDL_BlitSurface(src, NULL, texture, NULL); +#endif +// SDL_BlitSurface(src, NULL, overlay, NULL); +/*Uint32 * pix = (Uint32 *)overlay->pixels; +Uint32 y,x; +for(y=10; y<200; y++) +for(x=30; x<250; x++) +pix[x+(y*1024)] = 0x800000FF;//*/ + +glBlendFunc(GL_ONE, GL_ZERO); +glBindTexture(GL_TEXTURE_2D, texid); + // Texturemap complete texture to surface so we have free scaling + // and antialiasing + switch (texturebpp) + { + case 16: + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texture->w, texture->h, + GL_RGB, GL_UNSIGNED_SHORT_5_6_5, texture->pixels); + break; + case 24: + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texture->w, texture->h, + GL_RGB, GL_UNSIGNED_BYTE, texture->pixels); + break; + case 32: + default: + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texture->w, texture->h, + GL_RGBA, GL_UNSIGNED_BYTE, texture->pixels); + break; + } + + // Render the texture to the screen using OpenGL! + switch (texturetype) + { + case 1: + glBegin(GL_QUADS); + glTexCoord2f(texcoord[0], texcoord[1]); + glVertex2f(0, 0); + glTexCoord2f(texcoord[2], texcoord[1]); + glVertex2f(dst->w, 0); + glTexCoord2f(texcoord[2], texcoord[3]); + glVertex2f(dst->w, dst->h); + glTexCoord2f(texcoord[0], texcoord[3]); + glVertex2f(0, dst->h); + glEnd(); + + default: + glBegin(GL_TRIANGLE_STRIP); + glTexCoord2f(texcoord[0], texcoord[1]); glVertex3i(0, 0, 0); + glTexCoord2f(texcoord[2], texcoord[1]); glVertex3i(dst->w, 0, 0); + glTexCoord2f(texcoord[0], texcoord[3]); glVertex3i(0, dst->h, 0); + glTexCoord2f(texcoord[2], texcoord[3]); glVertex3i(dst->w, dst->h, 0); + glEnd(); + }//*/ + + if (showOverlay) + { + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBindTexture(GL_TEXTURE_2D, overlayID); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, overlay->w, overlay->h, GL_RGBA, GL_UNSIGNED_BYTE, overlay->pixels); + glBegin(GL_QUADS); + glTexCoord2f(overlayCoord[0], overlayCoord[1]); + glVertex2f(0, 0); + glTexCoord2f(overlayCoord[2], overlayCoord[1]); + glVertex2f(dst->w, 0); + glTexCoord2f(overlayCoord[2], overlayCoord[3]); + glVertex2f(dst->w, dst->h); + glTexCoord2f(overlayCoord[0], overlayCoord[3]); + glVertex2f(0, dst->h); + glEnd(); + } + +//Do some OpenGL stuff here... +//Doesn't work... +/*unsigned long int map[25] = { + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF +}; +glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +glRasterPos2i(10, 10); +glDrawPixels(5, 5, GL_RGBA, GL_UNSIGNED_INT, map);//*/ + +// glFlush(); + SDL_GL_SwapBuffers(); +// glFinish(); + +} + +void sdlemu_close_opengl(void) +{ + if (texture) + SDL_FreeSurface(texture); + + if (overlay) + SDL_FreeSurface(overlay); +} + +void sdlemu_create_overlay(SDL_Surface * dst, int src_bpp) +{ + // Local variables. + Uint32 rmask, gmask, bmask, amask; // Needed for creating RGBA masks. + + // Delete old texture (if allocated). Useful when there is a screen resize. + if (overlay) + SDL_FreeSurface(overlay); + + // Texture width/height should be power of 2 of the SDL_Surface *src when using OpenGL. + // So, find the largest power of two that will contain both the width and height + int w = power_of_two(dst->w); + int h = power_of_two(dst->h); + + printf("OpenGL - Overlay size : %d x %d\n", w, h); + + // Setting bpp based upon src_bpp. + int bpp = src_bpp; + + // We allow the developer to set its own texture bpp. But if the value is NULL or + // not equal to 16, 24 or 32, we make the texturebpp the same as the BPP from src. + if (bpp == 16 || bpp == 24 || bpp == 32) + texturebpp = bpp; + else + texturebpp = dst->format->BitsPerPixel; + + printf("OpenGL - Overlay depth : %d bpp\n", texturebpp); + + // Now were are going to create a SDL_Surface named texture. This will be our surface + // which will function as a buffer between the SDL_Surface *src and SDL_Surface *dst. + // This buffer is needed because we need to convert the SDL_Surface *src to an OpenGL + // texture with a depth of 16, 24 or 32 bpp, before we can blit the pixels to *dst + // using OpenGL. + // + // NOTE: Seems the byte order here *is* important! + switch (texturebpp) + { + case 16: // *src has depth of 16 bpp +/* + According to information on the SDL mailinglist and on internet, the following + rgba masks should be the ones to use. But somehow the screen gets f*cked up and + the RGB colours are incorrect (at least in Virtual Jaguar/SDL). + + Compile with -DOPENGL_16BPP_CORRECT_RGBA to use this RGBA values. +*/ +#ifdef OPENGL_16BPP_CORRECT_RGBA + rmask = 0x7C00; + gmask = 0x03E0; + bmask = 0x001F; + amask = 0x0000; +#else + rmask = 0x0000; + gmask = 0x0000; + bmask = 0x0000; + amask = 0x0000; +#endif + break; + case 24: // *src has depth of 24 bpp + #if SDL_BYTEORDER == SDL_BIG_ENDIAN + rmask = 0x00FF0000; + gmask = 0x0000FF00; + bmask = 0x000000FF; + amask = 0x00000000; // IMPORTANT! 24 bpp doesn't use Alpha (at least in our case). + #else + rmask = 0x000000FF; + gmask = 0x0000FF00; + bmask = 0x00FF0000; + amask = 0x00000000; // IMPORTANT! 24 bpp doesn't use Alpha (at least in our case). + #endif + break; + case 32: //*src has depth of 32 bpp + default: //which is also the default. + #if SDL_BYTEORDER == SDL_BIG_ENDIAN + rmask = 0xFF000000; + gmask = 0x00FF0000; + bmask = 0x0000FF00; + amask = 0x000000FF; + #else + rmask = 0x000000FF; + gmask = 0x0000FF00; + bmask = 0x00FF0000; + amask = 0xFF000000; + #endif + break; + } + + // Creating SDL_Surface texture based upon the above settings. + overlay = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, texturebpp, rmask, gmask, bmask, amask); + + // Setting up the texture coordinates. + overlayCoord[0] = 0.0f; + overlayCoord[1] = 0.0f; + overlayCoord[2] = (GLfloat)(dst->w) / overlay->w; + overlayCoord[3] = (GLfloat)(dst->h) / overlay->h; + + // create a RGB(A) texture for the texture surface + glGenTextures(1, &overlayID); + glBindTexture(GL_TEXTURE_2D, overlayID); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + // Setting texture mode. + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + + // Generate the texture using the above information. + switch (texturebpp) + { + case 16: + // Normal 16bpp depth based textures consist out of GL_RGB5 and doesn't have support for Alpha channels. + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5, overlay->w, overlay->h, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); + break; + case 24: + // The 24bpp depth based textures consist out of GL_RGB8 and doesn't have support for Alpha channels. + // + // IMPORTANT : If you don't use Alpha. Use textures with a depth of 16bpp. + // If you use Alpha. Use textures with a depth of 32bpp. + // 24bpp textures are SLOW and avoid them at all costs! + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, overlay->w, overlay->h, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); + break; + case 32: + default: + // The 32bpp depth based textures consist out of GL_RGBA8 and has support for Alpha channels. + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, overlay->w, overlay->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + break; + } +} + +void * sdlemuGetOverlayPixels(void) +{ + return overlay->pixels; +} + +Uint32 sdlemuGetOverlayWidthInPixels(void) +{ + return overlay->pitch / 4; +} + +void sdlemuEnableOverlay(void) +{ + showOverlay = 1; +} + +void sdlemuDisableOverlay(void) +{ + showOverlay = 0; +} + +void sdlemu_create_texture(SDL_Surface * src, SDL_Surface * dst, int filter, int src_bpp) +{ + // Local variables. + int w , h; // w and h contain the width and height of the OpenGL texture. + Uint32 rmask, gmask, bmask, amask; // Needed for creating RGBA masks. + int bpp; + + // Delete old texture (if allocated). Useful when there is a screen resize. + if (texture) + SDL_FreeSurface(texture); + + // Texture width/height should be power of 2 of the SDL_Surface *src when using OpenGL. + // So, find the largest power of two that will contain both the width and height + w = power_of_two(src->w); + h = power_of_two(src->h); + + printf("OpenGL - Texture size : %d x %d\n", w, h); + + // Setting bpp based upon src_bpp. + bpp = src_bpp; + + // We allow the developer to set its own texture bpp. But if the value is NULL or + // not equal to 16, 24 or 32, we make the texturebpp the same as the BPP from src. + if (bpp == 16 || bpp == 24 || bpp == 32) + texturebpp = bpp; + else + texturebpp = src->format->BitsPerPixel; + + printf("OpenGL - Texture depth : %d bpp\n", texturebpp); + + // Now were are going to create a SDL_Surface named texture. This will be our surface + // which will function as a buffer between the SDL_Surface *src and SDL_Surface *dst. + // This buffer is needed because we need to convert the SDL_Surface *src to an OpenGL + // texture with a depth of 16, 24 or 32 bpp, before we can blit the pixels to *dst + // using OpenGL. + // + // NOTE: Seems the byte order here *is* important! + switch (texturebpp) + { + case 16: // *src has depth of 16 bpp +/* + According to information on the SDL mailinglist and on internet, the following + rgba masks should be the ones to use. But somehow the screen gets f*cked up and + the RGB colours are incorrect (at least in Virtual Jaguar/SDL). + + Compile with -DOPENGL_16BPP_CORRECT_RGBA to use this RGBA values. +*/ +#ifdef OPENGL_16BPP_CORRECT_RGBA + rmask = 0x7C00; + gmask = 0x03E0; + bmask = 0x001F; + amask = 0x0000; +#else + rmask = 0x0000; + gmask = 0x0000; + bmask = 0x0000; + amask = 0x0000; +#endif + break; + case 24: // *src has depth of 24 bpp + #if SDL_BYTEORDER == SDL_BIG_ENDIAN + rmask = 0x00FF0000; + gmask = 0x0000FF00; + bmask = 0x000000FF; + amask = 0x00000000; // IMPORTANT! 24 bpp doesn't use Alpha (at least in our case). + #else + rmask = 0x000000FF; + gmask = 0x0000FF00; + bmask = 0x00FF0000; + amask = 0x00000000; // IMPORTANT! 24 bpp doesn't use Alpha (at least in our case). + #endif + break; + case 32: //*src has depth of 32 bpp + default: //which is also the default. + #if SDL_BYTEORDER == SDL_BIG_ENDIAN + rmask = 0xFF000000; + gmask = 0x00FF0000; + bmask = 0x0000FF00; + amask = 0x000000FF; + #else + rmask = 0x000000FF; + gmask = 0x0000FF00; + bmask = 0x00FF0000; + amask = 0xFF000000; + #endif + break; + } + + // Creating SDL_Surface texture based upon the above settings. + texture = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, texturebpp, rmask, gmask, bmask, amask); + + // Setting up OpenGL + glDisable(GL_FOG); + glDisable(GL_LIGHTING); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); +// glDisable(GL_BLEND); + glEnable(GL_BLEND); + glDisable(GL_NORMALIZE); + glDisable(GL_ALPHA_TEST); + glEnable(GL_TEXTURE_2D); +// glBlendFunc(GL_SRC_ALPHA, GL_ONE); +// glBlendFunc(GL_ONE, GL_SRC_ALPHA); +//This works, but in a wrong way... +// glBlendFunc(GL_ONE, GL_ONE); + + // Definitely needed for screen resolution larger then the *src. + // This way we can have automatic scaling functionality. + glViewport(0, 0, dst->w, dst->h); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0.0, (GLdouble)dst->w, (GLdouble)dst->h, 0.0, 0.0, 1.0); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + // Setting up the texture coordinates. + texcoord[0] = 0.0f; + texcoord[1] = 0.0f; + texcoord[2] = (GLfloat)(src->w) / texture->w; + texcoord[3] = (GLfloat)(src->h) / texture->h; + + // create a RGB(A) texture for the texture surface + glGenTextures(1, &texid); + glBindTexture(GL_TEXTURE_2D, texid); + + // Setting up the OpenGL Filters. These filters are important when we/you + // want to scale the texture. + if (filter) + { + // Textures are rendered in best quality. + printf("OpenGL filters: enabled\n"); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } + else + { + // Textures are rendered in normal quality. + printf("OpenGL filters: disabled\n"); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + } + + // Setting texture mode. + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + + // Generate the texture using the above information. + switch (texturebpp) + { + case 16: + // Normal 16bpp depth based textures consist out of GL_RGB5 and doesn't have support for Alpha channels. + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5, texture->w, texture->h, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); + break; + case 24: + // The 24bpp depth based textures consist out of GL_RGB8 and doesn't have support for Alpha channels. + // + // IMPORTANT : If you don't use Alpha. Use textures with a depth of 16bpp. + // If you use Alpha. Use textures with a depth of 32bpp. + // 24bpp textures are SLOW and avoid them at all costs! + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, texture->w, texture->h, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); + break; + case 32: + default: + // The 32bpp depth based textures consist out of GL_RGBA8 and has support for Alpha channels. + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, texture->w, texture->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + break; + } +} diff --git a/src/sdlemu_opengl.h b/src/sdlemu_opengl.h new file mode 100755 index 0000000..22e0f9a --- /dev/null +++ b/src/sdlemu_opengl.h @@ -0,0 +1,43 @@ +/* + * SDLEMU library - Free sdl related functions library + * Copyrigh(c) 1999-2002 sdlemu development crew + * + * 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 + */ + +#ifndef __SDLEMU_OPENGL_H__ +#define __SDLEMU_OPENGL_H__ + +#include "SDL.h" +#include "SDL_opengl.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void sdlemu_init_opengl(SDL_Surface * src, SDL_Surface * dst, int texturetype, int filter, int src_bpp); +void sdlemu_draw_texture(SDL_Surface * dst, SDL_Surface * src, int texturetype); +void sdlemu_close_opengl(void); +void sdlemu_create_texture(SDL_Surface * src, SDL_Surface * dst, int filter, int src_bpp); +void * sdlemuGetOverlayPixels(void); +Uint32 sdlemuGetOverlayWidthInPixels(void); +void sdlemuEnableOverlay(void); +void sdlemuDisableOverlay(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/settings.cpp b/src/settings.cpp new file mode 100755 index 0000000..888c083 --- /dev/null +++ b/src/settings.cpp @@ -0,0 +1,122 @@ +// +// SETTINGS.CPP: Game configuration loading/saving support +// +// by James L. Hammons +// (C) 2005 Underground Software +// +// JLH = James L. Hammons +// +// WHO WHEN WHAT +// --- ---------- ------------------------------------------------------------ +// JLH 01/04/2006 Added changelog ;-) +// + +#include "settings.h" + +#include +#include +#include "SDL.h" +#include "sdlemu_config.h" +#include "log.h" + +using namespace std; + +// Global variables + +Settings settings; + +// Private function prototypes + +static void CheckForTrailingSlash(char * path); + +// +// Load StarGem2's settings +// +void LoadSettings(void) +{ + if (sdlemu_init_config("./stargem2.cfg") == 0 // CWD + && sdlemu_init_config("~/stargem2.cfg") == 0 // Home + && sdlemu_init_config("~/.stargem2/stargem2.cfg") == 0 // Home under .stargem2 directory + && sdlemu_init_config("stargem2.cfg") == 0) // Somewhere in the path + WriteLog("Settings: Couldn't find configuration file. Using defaults...\n"); + + settings.useJoystick = sdlemu_getval_bool("useJoystick", false); + settings.joyport = sdlemu_getval_int("joyport", 0); + settings.hardwareTypeNTSC = sdlemu_getval_bool("hardwareTypeNTSC", true); + settings.frameSkip = sdlemu_getval_int("frameSkip", 0); + settings.fullscreen = sdlemu_getval_bool("fullscreen", false); + settings.useOpenGL = sdlemu_getval_bool("useOpenGL", true); + settings.glFilter = sdlemu_getval_int("glFilterType", 0); + settings.renderType = sdlemu_getval_int("renderType", 0); + settings.autoStateSaving = sdlemu_getval_bool("autoSaveState", true); + + // Keybindings in order of U, D, L, R, C, B, A, Op, Pa, 0-9, #, * + settings.p1KeyBindings[0] = sdlemu_getval_int("p1k_up", SDLK_UP); + settings.p1KeyBindings[1] = sdlemu_getval_int("p1k_down", SDLK_DOWN); + settings.p1KeyBindings[2] = sdlemu_getval_int("p1k_left", SDLK_LEFT); + settings.p1KeyBindings[3] = sdlemu_getval_int("p1k_right", SDLK_RIGHT); + settings.p1KeyBindings[4] = sdlemu_getval_int("p1k_c", SDLK_z); + settings.p1KeyBindings[5] = sdlemu_getval_int("p1k_b", SDLK_x); + settings.p1KeyBindings[6] = sdlemu_getval_int("p1k_a", SDLK_c); + settings.p1KeyBindings[7] = sdlemu_getval_int("p1k_option", SDLK_QUOTE); + settings.p1KeyBindings[8] = sdlemu_getval_int("p1k_pause", SDLK_RETURN); + settings.p1KeyBindings[9] = sdlemu_getval_int("p1k_0", SDLK_KP0); + settings.p1KeyBindings[10] = sdlemu_getval_int("p1k_1", SDLK_KP1); + settings.p1KeyBindings[11] = sdlemu_getval_int("p1k_2", SDLK_KP2); + settings.p1KeyBindings[12] = sdlemu_getval_int("p1k_3", SDLK_KP3); + settings.p1KeyBindings[13] = sdlemu_getval_int("p1k_4", SDLK_KP4); + settings.p1KeyBindings[14] = sdlemu_getval_int("p1k_5", SDLK_KP5); + settings.p1KeyBindings[15] = sdlemu_getval_int("p1k_6", SDLK_KP6); + settings.p1KeyBindings[16] = sdlemu_getval_int("p1k_7", SDLK_KP7); + settings.p1KeyBindings[17] = sdlemu_getval_int("p1k_8", SDLK_KP8); + settings.p1KeyBindings[18] = sdlemu_getval_int("p1k_9", SDLK_KP9); + settings.p1KeyBindings[19] = sdlemu_getval_int("p1k_pound", SDLK_KP_DIVIDE); + settings.p1KeyBindings[20] = sdlemu_getval_int("p1k_star", SDLK_KP_MULTIPLY); + + settings.p2KeyBindings[0] = sdlemu_getval_int("p2k_up", SDLK_UP); + settings.p2KeyBindings[1] = sdlemu_getval_int("p2k_down", SDLK_DOWN); + settings.p2KeyBindings[2] = sdlemu_getval_int("p2k_left", SDLK_LEFT); + settings.p2KeyBindings[3] = sdlemu_getval_int("p2k_right", SDLK_RIGHT); + settings.p2KeyBindings[4] = sdlemu_getval_int("p2k_c", SDLK_z); + settings.p2KeyBindings[5] = sdlemu_getval_int("p2k_b", SDLK_x); + settings.p2KeyBindings[6] = sdlemu_getval_int("p2k_a", SDLK_c); + settings.p2KeyBindings[7] = sdlemu_getval_int("p2k_option", SDLK_QUOTE); + settings.p2KeyBindings[8] = sdlemu_getval_int("p2k_pause", SDLK_RETURN); + settings.p2KeyBindings[9] = sdlemu_getval_int("p2k_0", SDLK_KP0); + settings.p2KeyBindings[10] = sdlemu_getval_int("p2k_1", SDLK_KP1); + settings.p2KeyBindings[11] = sdlemu_getval_int("p2k_2", SDLK_KP2); + settings.p2KeyBindings[12] = sdlemu_getval_int("p2k_3", SDLK_KP3); + settings.p2KeyBindings[13] = sdlemu_getval_int("p2k_4", SDLK_KP4); + settings.p2KeyBindings[14] = sdlemu_getval_int("p2k_5", SDLK_KP5); + settings.p2KeyBindings[15] = sdlemu_getval_int("p2k_6", SDLK_KP6); + settings.p2KeyBindings[16] = sdlemu_getval_int("p2k_7", SDLK_KP7); + settings.p2KeyBindings[17] = sdlemu_getval_int("p2k_8", SDLK_KP8); + settings.p2KeyBindings[18] = sdlemu_getval_int("p2k_9", SDLK_KP9); + settings.p2KeyBindings[19] = sdlemu_getval_int("p2k_pound", SDLK_KP_DIVIDE); + settings.p2KeyBindings[20] = sdlemu_getval_int("p2k_star", SDLK_KP_MULTIPLY); + + strcpy(settings.BIOSPath, sdlemu_getval_string("BIOSROM", "./ROMs/")); + strcpy(settings.disksPath, sdlemu_getval_string("disks", "./disks/")); + strcpy(settings.diskImagePath1, sdlemu_getval_string("floppyImage1", "./disks/bt1_boot.dsk")); + strcpy(settings.diskImagePath2, sdlemu_getval_string("floppyImage2", "./disks/bt1_char.dsk")); + strcpy(settings.autoStatePath, sdlemu_getval_string("autoStateFilename", "./apple2auto.state")); + CheckForTrailingSlash(settings.disksPath); + CheckForTrailingSlash(settings.BIOSPath); +} + +// +// Save StarGem2's settings +// +void SaveSettings(void) +{ +} + +// +// Check path for a trailing slash, and append if not present +// +static void CheckForTrailingSlash(char * path) +{ + if (strlen(path) > 0) + if (path[strlen(path) - 1] != '/') + strcat(path, "/"); // NOTE: Possible buffer overflow +} diff --git a/src/settings.h b/src/settings.h new file mode 100755 index 0000000..1fcca61 --- /dev/null +++ b/src/settings.h @@ -0,0 +1,60 @@ +// +// SETTINGS.H: Header file +// + +#ifndef __SETTINGS_H__ +#define __SETTINGS_H__ + +// MAX_PATH isn't defined in stdlib.h on *nix, so we do it here... +#ifdef __GCCUNIX__ +#include +#define MAX_PATH _POSIX_PATH_MAX +#else +#include // for MAX_PATH on MinGW/Darwin +#endif +#include "types.h" + +// Settings struct + +struct Settings +{ + bool useJoystick; + int32 joyport; // Joystick port + bool hardwareTypeNTSC; // Set to false for PAL + bool fullscreen; + bool useOpenGL; + uint32 glFilter; + uint32 frameSkip; + uint32 renderType; + bool autoStateSaving; // Auto-state loading/saving on entry/exit + + // Keybindings in order of U, D, L, R, C, B, A, Op, Pa, 0-9, #, * + + uint16 p1KeyBindings[21]; + uint16 p2KeyBindings[21]; + + // Paths + + char BIOSPath[MAX_PATH]; + char disksPath[MAX_PATH]; + char diskImagePath1[MAX_PATH]; + char diskImagePath2[MAX_PATH]; + char autoStatePath[MAX_PATH]; +// char CDBootPath[MAX_PATH]; +// char EEPROMPath[MAX_PATH]; +}; + +// Render types + +//enum { RT_NORMAL = 0, RT_TV = 1 }; + +// Exported functions + +void LoadSettings(void); +void SaveSettings(void); + +// Exported variables + +extern Settings settings; + +#endif // __SETTINGS_H__ diff --git a/src/sound.cpp b/src/sound.cpp new file mode 100755 index 0000000..6cc1860 --- /dev/null +++ b/src/sound.cpp @@ -0,0 +1,96 @@ +// +// Sound Interface v2.0 +// +// by James L. Hammons +// (c) 2006 Underground Software +// +// JLH = James L. Hammons +// +// WHO WHEN WHAT +// --- ---------- ------------------------------------------------------------ +// JLH 06/15/2006 Added changelog ;-) +// JLH 06/15/2006 Scrubbed all BYTE, WORD & DWORD references from the code +// +// Notes: +// The sound CPU (6808) runs at 894,750 (3,579,000 / 4) Hz. +// At 44.1 KHz, this works out to 894750 / 44100 = 20.289115646... cycles per sample. +// + +// Still need to add volume control... + +#include "sound.h" + +#include "SDL.h" +#include "types.h" +#include "log.h" +#include "v6808.h" + +//using namespace std; + +// Local variables + +SDL_AudioSpec desired; +bool soundInitialized = false; + +// Private function prototypes + +void SDLSoundCallback(void * userdata, Uint8 * buffer, int length); + +// +// Initialize the SDL sound system +// +void SoundInit(void) +{ +// memory_malloc_secure((void **)&DACBuffer, BUFFER_SIZE * sizeof(uint16), "DAC buffer"); + + desired.freq = 44100; // SDL will do conversion on the fly, if it can't get the exact rate. Nice! + desired.format = AUDIO_U8; // This uses the native endian (for portability)... + desired.channels = 1; +// desired.samples = 4096; // Let's try a 4K buffer (can always go lower) + desired.samples = 2048; // Let's try a 2K buffer (can always go lower) + desired.callback = SDLSoundCallback; + + if (SDL_OpenAudio(&desired, NULL) < 0) // NULL means SDL guarantees what we want + { + WriteLog("Sound: Failed to initialize SDL sound.\n"); +// exit(1); + return; + } + + SDL_PauseAudio(false); // Start playback! + soundInitialized = true; + WriteLog("Sound: Successfully initialized.\n"); +} + +// +// Close down the SDL sound subsystem +// +void SoundDone(void) +{ + if (soundInitialized) + { + SDL_PauseAudio(true); + SDL_CloseAudio(); + WriteLog("Sound: Done.\n"); + } +} + +// +// Sound card callback handler +// +void SDLSoundCallback(void * userdata, Uint8 * buffer, int length) +{ + extern V6808REGS soundCPU; + extern uint8 * sram; + int cnt = 0; + + while (cnt != length) + { + // This is close, but not cycle exact (exact would be 20.289115646...) + +//Need to figure out how to get that fraction to execute... !!! FIX !!! + Execute6808(&soundCPU, 20); + soundCPU.clock -= 20; + buffer[cnt++] = sram[0x0400]; // Fill the buffer with the PIA output value + } +} diff --git a/src/sound.h b/src/sound.h new file mode 100755 index 0000000..2a7b48c --- /dev/null +++ b/src/sound.h @@ -0,0 +1,14 @@ +// +// SOUND.H +// +// by James L. Hammons +// (C) 2004 Underground Software +// + +#ifndef __SOUND_H__ +#define __SOUND_H__ + +void SoundInit(void); +void SoundDone(void); + +#endif // __SOUND_H__ diff --git a/src/stargem2.cpp b/src/stargem2.cpp new file mode 100755 index 0000000..ee1b814 --- /dev/null +++ b/src/stargem2.cpp @@ -0,0 +1,1067 @@ +// +// Stargate Emulator (StarGem2) v2.0 SDL +// +// by James L. Hammons +// (C) 2006 Underground Software +// +// JLH = James L. Hammons +// +// WHO WHEN WHAT +// --- ---------- ------------------------------------------------------------ +// JLH 06/15/2006 Added changelog ;-) +// JLH 06/15/2006 Switched over to timeslice execution code +// + +#include "SDL.h" +#include +#include +#include +#include +#include +#include +#include +#include "types.h" +#include "log.h" +#include "v6808.h" +#include "v6809.h" +#include "video.h" +#include "sound.h" +#include "timing.h" +#include "settings.h" +#include "dis6809.h" +#include "dis6808.h" + +using namespace std; + +#define ROM1 "01" +#define ROM2 "02" +#define ROM3 "03" +#define ROM4 "04" +#define ROM5 "05" +#define ROM6 "06" +#define ROM7 "07" +#define ROM8 "08" +#define ROM9 "09" +#define ROM10 "10" +#define ROM11 "11" +#define ROM12 "12" +#define SOUNDROM "sg.snd" +#define CMOS "cmos.ram" +#define SAVESTATE "sg2.state" + +// Global variables + +uint8 * gram, * grom, * sram, * srom; // RAM & ROM pointers +V6809REGS mainCPU; +V6808REGS soundCPU; +uint8 color[16]; +uint32 palette[256]; + +// Local variables + +//static uint8 lastKeyPressed = 0; +//static bool keyDown = false; + +//static FloppyDrive floppyDrive; + +//enum { LC_BANK_1, LC_BANK_2 }; + +//static uint8 visibleBank = LC_BANK_1; +//static bool readRAM = false; +//static bool writeRAM = false; + +static bool running = true; // Machine running state flag... +static uint32 startTicks; +static uint8 * keys; // SDL raw keyboard matrix + +// Local timer callback functions + +static void FrameCallback(void); +static void ScanlineCallback(void); + + +// +// 6809 memory functions +// + +uint8 RdMem6809(uint16 addr) +{ + uint8 b; + + if (addr >= 0x9000 && addr <= 0xCFFF) // No ROM between $9000 - $CFFF... + b = gram[addr]; + else + { + if (!gram[0xC900] && addr <= 0x8FFF) // Check RAM $C900 bank switch + b = gram[addr]; + else + b = grom[addr]; + } + +//Is $C80E COUNT240? Hmm... No. + +//temp... +/*extern uint16 pcr; +//if (addr >= 0xC000 && addr <= 0xCBFF) +if (addr == 0x9C59) + WriteLog("RdMem: Reading address %04X [=%02X, PC=%04X]\n", addr, b, pcr);//*/ +/*if (addr >= 0xC80D && addr <= 0xC80F) + WriteLog("V6809 RdMem: Reading address %04X [=%02X, PC=%04X]\n", addr, b, mainCPU.pc);//*/ + + return b; +} + +void WrMem6809(uint16 addr, uint8 b) +{ +//temp... +//extern V6809REGS regs; +//if (addr >= 0xC800 && addr <= 0xCBFE) +//if (addr == 0xC80F || addr == 0xC80D) +// WriteLog("WrMem: Writing address %04X with %02X [PC=%04X, $CB00=%02X]\n", addr, b, regs.pc, gram[0xCB00]);//*/ +//if (addr == 0xC80E) +/*if (addr >= 0xC800 && addr <= 0xC80F) + WriteLog("V6809 WrMem: Writing address %04X with %02X [PC=%04X, $CB00=%02X]\n", addr, b, mainCPU.pc, gram[0xCB00]);//*/ + + gram[addr] = b; + + if (addr > 0x0006 && addr < 0x97F7) // 304 pixels 152-128=24-16=8 + { + // NOTE: Screen was 304 x 256, but we truncate the vertical dimension here... + uint16 sx = (addr >> 7) & 0x01FE, sy = addr & 0x00FF; + + if (sy > 5 && sy < 246) + { + uint32 saddr = 8 + sx + ((sy - 6) * 320); // Calc screen address +//Hmm. This approach won't work with palette color cycling... +#if 0 + scrBuffer[saddr + 0] = b >> 4; + scrBuffer[saddr + 1] = b & 0x0F; +#else + scrBuffer[saddr + 0] = palette[color[b >> 4]]; + scrBuffer[saddr + 1] = palette[color[b & 0x0F]]; +#endif + } + } + else if (addr >= 0xC000 && addr <= 0xC00F) +//Let's see if we can fix the color cycling here... [DONE] +#if 0 + color[addr - 0xC000] = b; // color[] from VIDEO.CPP (not any more!) +#else + { +// A better strategy here would probably be to set a flag when the color register changes, +// then change it before doing the render. +// ALSO: This approach doesn't take the color to the edges of the screen + color[addr - 0xC000] = b; + + for(uint32 addr=0x0007; addr<0x97F7; addr++) + { + uint16 sx = (addr >> 7) & 0x01FE, sy = addr & 0x00FF; + + if (sy > 5 && sy < 246) + { + uint32 saddr = 8 + sx + ((sy - 6) * 320); // Calc screen address + uint8 sb = gram[addr]; + + scrBuffer[saddr + 0] = palette[color[sb >> 4]]; + scrBuffer[saddr + 1] = palette[color[sb & 0x0F]]; + } + } + } +#endif + else if (addr == 0xC80E) + { + sram[0x0402] = b; // Connect PIAs in 6809 & 6808 + soundCPU.cpuFlags |= V6808_ASSERT_LINE_IRQ; // Start sound IRQ + } +} + +// +// 6808 memory functions +// + +uint8 RdMem6808(uint16 addr) +{ + return (addr < 0xF000 ? sram[addr] : srom[addr]); +} + +void WrMem6808(uint16 addr, uint8 b) +{ + sram[addr] = b; +} + +// +// Load a file into RAM/ROM image space +// +bool LoadImg(char * filename, uint8 * ram, int size) +{ + char pathname[4096]; + + strcpy(pathname, settings.BIOSPath); + strcat(pathname, filename); + + FILE * fp = fopen(pathname, "rb"); + + if (fp == NULL) + { + WriteLog("Could not open file '%s'!\n", pathname); + return false; + } + + fread(ram, 1, size, fp); + fclose(fp); + + return true; +} + +// +// Save CMOS ram +// +void SaveCMOS(void) +{ + FILE * fp = fopen(CMOS, "wb"); + + if (fp != NULL) + { + fwrite(gram + 0xCC00, 1, 1024, fp); + fclose(fp); + } + else + WriteLog("CMOS RAM not saved!\n"); +} + +// +// Load state save file +// +bool LoadMachineState(void) +{ + FILE * fp = fopen(SAVESTATE, "rb"); + + if (fp == NULL) + return false; + + // This is kinda crappy--we don't do any sanity checking here!!! + fread(gram, 1, 0x10000, fp); + fread(sram, 1, 0x10000, fp); + fread(&mainCPU, 1, sizeof(V6809REGS), fp); + fread(&soundCPU, 1, sizeof(V6808REGS), fp); + fclose(fp); + + for(int i=0x0006; i<0x97F8; i++) // Set up backbuffer... ;-) + WrMem6809(i, gram[i]); + + mainCPU.RdMem = RdMem6809; // Make sure our function pointers are + mainCPU.WrMem = WrMem6809; // pointing to the right places! + soundCPU.RdMem = RdMem6808; + soundCPU.WrMem = WrMem6808; + + return true; +} + +// +// Save state save file +// +void SaveMachineState(void) +{ + FILE * fp = fopen(SAVESTATE, "wb"); + + if (fp != NULL) + { + fwrite(gram, 1, 0x10000, fp); + fwrite(sram, 1, 0x10000, fp); + fwrite(&mainCPU, 1, sizeof(V6809REGS), fp); + fwrite(&soundCPU, 1, sizeof(V6808REGS), fp); + fclose(fp); + } + else + WriteLog("Machine state not saved!\n"); +} + +// +// Main loop +// +int main(int /*argc*/, char * /*argv*/[]) +{ +// bool running; // Machine running state flag... + + LoadSettings(); + InitLog("stargem2.log"); + WriteLog("StarGem2 - A portable Stargate emulator by James L. Hammons\n"); + + // Initialize Williams' palette (RGB coded as: 3 bits red, 3 bits green, 2 bits blue) + for(uint32 i=0; i<256; i++) + palette[i] = +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + (((i & 0x01) * 33 + ((i & 0x02) >> 1) * 71 + ((i & 0x04) >> 2) * 151) << 24) + | ((((i & 0x08) >> 3) * 33 + ((i & 0x10) >> 4) * 71 + ((i & 0x20) >> 5) * 151) << 16) + | ((((i & 0x40) >> 6) * 71 + ((i & 0x80) >> 7) * 151) << 8) | 0xFF; +#else + ((i & 0x01) * 33 + ((i & 0x02) >> 1) * 71 + ((i & 0x04) >> 2) * 151) + | ((((i & 0x08) >> 3) * 33 + ((i & 0x10) >> 4) * 71 + ((i & 0x20) >> 5) * 151) << 8) + | ((((i & 0x40) >> 6) * 71 + ((i & 0x80) >> 7) * 151) << 16) | 0xFF000000; +#endif + + gram = new uint8[0x10000]; + grom = new uint8[0x10000]; + sram = new uint8[0x10000]; + srom = new uint8[0x10000]; + + if (gram == NULL) + { + WriteLog("Could not allocate RAM space!\nAborting!\n"); + return -1; + } + else if (grom == NULL) + { + WriteLog("Could not allocate ROM space!\nAborting!\n"); + return -1; + } + else if (sram == NULL) + { + WriteLog("Could not allocate sRAM space!\nAborting!\n"); + return -1; + } + else if (srom == NULL) + { + WriteLog("Could not allocate sROM space!\nAborting!\n"); + return -1; + } + + // Zero out memory + for(long i=0; i<0x10000; i++) + gram[i] = grom[i] = sram[i] = srom[i] = 0; + + // Set up V6809 & V6808 execution contexts + + memset(&mainCPU, sizeof(V6809REGS), 0); + mainCPU.RdMem = RdMem6809; + mainCPU.WrMem = WrMem6809; + mainCPU.cpuFlags |= V6809_ASSERT_LINE_RESET; + + memset(&soundCPU, sizeof(V6808REGS), 0); + soundCPU.RdMem = RdMem6808; + soundCPU.WrMem = WrMem6808; + soundCPU.cpuFlags |= V6808_ASSERT_LINE_RESET; + + if (!LoadImg(CMOS, gram + 0xCC00, 0x400)) + WriteLog("CMOS RAM not found!\n"); + + if (!LoadImg(ROM1, grom + 0x0000, 0x1000)) + return -1; + + if (!LoadImg(ROM2, grom + 0x1000, 0x1000)) + return -1; + + if (!LoadImg(ROM3, grom + 0x2000, 0x1000)) + return -1; + + if (!LoadImg(ROM4, grom + 0x3000, 0x1000)) + return -1; + + if (!LoadImg(ROM5, grom + 0x4000, 0x1000)) + return -1; + + if (!LoadImg(ROM6, grom + 0x5000, 0x1000)) + return -1; + + if (!LoadImg(ROM7, grom + 0x6000, 0x1000)) + return -1; + + if (!LoadImg(ROM8, grom + 0x7000, 0x1000)) + return -1; + + if (!LoadImg(ROM9, grom + 0x8000, 0x1000)) + return -1; + + if (!LoadImg(ROM10, grom + 0xD000, 0x1000)) + return -1; + + if (!LoadImg(ROM11, grom + 0xE000, 0x1000)) + return -1; + + if (!LoadImg(ROM12, grom + 0xF000, 0x1000)) + return -1; + + if (!LoadImg(SOUNDROM, srom + 0xF800, 0x800)) + return -1; + + WriteLog("Stargate ROM images loaded...\n"); + WriteLog("About to initialize video...\n"); + + if (!InitVideo()) + { + cout << "Aborting!" << endl; + return -1; + } + + // Have to do this *after* video init but *before* sound init...! + if (!LoadMachineState()) + WriteLog("Machine state file not found!\n"); + + WriteLog("About to intialize audio...\n"); + SoundInit(); +// uint8 * keys = SDL_GetKeyState(NULL); + keys = SDL_GetKeyState(NULL); + +// running = true; // Set running status... + srom[0xF800] = 0x37; // Fix checksum so ST works... + +#if 0 + +//kludge... +//This didn't work--it still acted like the old way (interrupt @ VC = 0) +//gram[0xCB00] = 64*3; + + WriteLog("Entering main loop...\n"); + while (running) + { + SDL_PumpEvents(); // Force key events into the buffer. + gram[0xC804] = gram[0xC806] = gram[0xC80C] = 0; // Reset PIA ports... + + if (keys[SDLK_ESCAPE]) + running = false; // ESC to exit... + + if (keys[SDLK_SEMICOLON]) + gram[0xC804] |= 0x01; // Fire (;) + if (keys[SDLK_l]) + gram[0xC804] |= 0x02; // Thrust (L) + if (keys[SDLK_SPACE]) + gram[0xC804] |= 0x04; // Smart Bomb (space) + if (keys[SDLK_BACKSPACE]) + gram[0xC804] |= 0x08; // Hyperspace (BkSp) + if (keys[SDLK_2]) + gram[0xC804] |= 0x10; // Two Player Start (2) + if (keys[SDLK_1]) + gram[0xC804] |= 0x20; // One Player Start (1) + if (keys[SDLK_RETURN]) + gram[0xC804] |= 0x40; // Reverse (Enter) + if (keys[SDLK_f]) + gram[0xC804] |= 0x80; // Down (F) + + if (keys[SDLK_r]) + gram[0xC806] |= 0x01; // Up (R) + if (keys[SDLK_a]) + gram[0xC806] |= 0x02; // Inviso (A) + + if (keys[SDLK_F1]) + gram[0xC80C] |= 0x01; // Auto up (F1) + if (keys[SDLK_F2]) + gram[0xC80C] |= 0x02; // Advance (F2) + if (keys[SDLK_5]) + gram[0xC80C] |= 0x04; // Right Coin (5) + if (keys[SDLK_F3]) + gram[0xC80C] |= 0x08; // High Score Reset (F3) + if (keys[SDLK_3]) + gram[0xC80C] |= 0x10; // Left Coin (3) + if (keys[SDLK_4]) + gram[0xC80C] |= 0x20; // Center Coin (4) + if (keys[SDLK_F4]) + gram[0xC80C] |= 0x40; // Slam Switch (F4) + + if (keys[SDLK_F5]) // Sound CPU self-test (F5) + soundCPU.cpuFlags |= V6808_ASSERT_LINE_NMI; + if (keys[SDLK_F6]) // Reset the 6808 (F6) + soundCPU.cpuFlags |= V6808_ASSERT_LINE_RESET; + +/* +$CB00 is scanline counter, bits 2-7 (1 frame/240 =69.44... usec) + +Some places of interest to look at: + +RdMem: Reading address C80E [=0C, PC=15C3] <- Inside interrupt (read, then discarded)... +RdMem: Reading address CB00 [=43, PC=15C6] <- interrupt +RdMem: Reading address C80C [=00, PC=0758] <- input (?) +RdMem: Reading address C80C [=00, PC=07B9] <- input (?) +RdMem: Reading address C806 [=00, PC=078C] <- input +RdMem: Reading address C804 [=00, PC=2679] <- input +*/ + uint32 startTicks = SDL_GetTicks(); +// long video_clk = 0; +// gram[0xCB00] = 0; + +/* +//This is where the interrupt mask is restored in CC... Hmm... +//This enables interrupts *after* the previous interrupt has occurred... Hmm. +//Could $C80F (rom_pia_ctrlb) be the IRQ inhibit? Yes, it is! + + // the IRQ signal comes into CB1, and is set to VA11 + pia_1_cb1_w(0, scanline & 0x20); +... + // the COUNT240 signal comes into CA1, and is set to the logical AND of VA10-VA13 + pia_1_ca1_w(0, 0); +... + // the COUNT240 signal comes into CA1, and is set to the logical AND of VA10-VA13 + pia_1_ca1_w(0, 1); +*/ + +//WriteLog("--> Start of frame...\n"); + for(int i=0; i<3; i++) + { +//Not sure, but this *might* fix IRQ problem... +//Checking the PIA IRQ mask for an IRQ seems to work OK. Now if only the timing elsewhere was right... + if (gram[0xC80F] & 0x01) + mainCPU.cpuFlags |= V6809_ASSERT_LINE_IRQ;//*/ + + Execute6809(&mainCPU, 4000); + mainCPU.clock -= 4000; // Remove 4K ticks from clock (in case it overflowed) +//Not sure, but this *might* fix IRQ problem... +//Checking the PIA IRQ mask for an IRQ seems to work OK. Now if only the timing elsewhere was right... +/* if (gram[0xC80F] & 0x01) + mainCPU.cpuFlags |= V6809_ASSERT_LINE_IRQ;//*/ + + gram[0xCB00] += 64; // Update video counter... + } + +//Hmm. +/*if (gram[0xC80E] & 0x01) + mainCPU.cpuFlags |= V6809_ASSERT_LINE_IRQ;//*/ +//48 lines... (+ 16) +//gram[0xCB00] = 0; + Execute6809(&mainCPU, 3000); + mainCPU.clock -= 3000; // Remove 3K ticks from clock (in case it overflowed) +//Not sure, but this *might* fix IRQ problem... +//if (gram[0xC80F] & 0x01) +//This isn't the right port on the PIA, but it does seem to make it through the demo now... +//Lesse if this works... Seems to! + if (gram[0xC80D] & 0x01) // Do COUNT240 IRQ (if enabled!) + mainCPU.cpuFlags |= V6809_ASSERT_LINE_IRQ; + +/*if (gram[0xC80F] & 0x01) + mainCPU.cpuFlags |= V6809_ASSERT_LINE_IRQ; +gram[0xCB00] = 0; //*/ + + gram[0xCB00] += 48; // Update video counter... + + Execute6809(&mainCPU, 1000); + mainCPU.clock -= 1000; // Remove 1K ticks from clock (in case it overflowed) +//Eh? +//Ok, this is the interrupt it's looking for, but still... +//if (gram[0xC80F] & 0x01) +// mainCPU.cpuFlags |= V6809_ASSERT_LINE_IRQ; + + gram[0xCB00] += 16; // Update video counter... + +// RenderScreenBuffer(); + RenderScreenBuffer2(); // 1 frame = 16667 cycles +// WriteLog("Main: Rendered back buffer. [6809 PC=%04X]\n", pcr); + + Execute6809(&mainCPU, 667); // Do QnD VBLANK + + // 1/60 sec = ? ms (16.6 ms) + while (SDL_GetTicks() - startTicks < 16); // Wait for next frame... + +//kludge, temp... +//Very interesting! It's the palette rotation that's slowing it down! +//Fixed now, but this allows the color rotation while the wrong timing is in effect... +/*for(int i=0; i<16; i++) + WrMem(0xC000 + i, gram[0x9C26 + i]);//*/ + } + +/*uint16 pc = 0x15BA; +for(int i=0; i<200; i++) +//while (pc < 0x9000) + pc += Decode6809(pc);//*/ + +#else + + running = true; // Set running status... + + InitializeEventList(); // Clear the event list before we use it... + SetCallbackTime(FrameCallback, 16666.66666667); // Set frame to fire at 1/60 s interval +// SetCallbackTime(BlinkTimer, 250000); // Set up blinking at 1/4 s intervals + SetCallbackTime(ScanlineCallback, 520.83333334); // Set scanline callback at 1/32 of frame +// SetCallbackTime(ScanlineCallback, 520.83333334*32.00); // Set scanline callback at 1/32 of frame + startTicks = SDL_GetTicks(); + + WriteLog("Entering main loop...\n"); + + while (running) + { + double timeToNextEvent = GetTimeToNextEvent(); + Execute6809(&mainCPU, USEC_TO_M6809_CYCLES(timeToNextEvent)); +//We MUST remove a frame's worth of time in order for the CPU to function... !!! FIX !!! +//(Fix so that this is not a requirement!) + mainCPU.clock -= USEC_TO_M6809_CYCLES(timeToNextEvent); + HandleNextEvent(); + } + +#endif + + SoundDone(); + VideoDone(); + SaveCMOS(); + SaveMachineState(); + LogDone(); + + delete[] gram; // Deallocate RAM & ROM spaces + delete[] grom; + delete[] sram; + delete[] srom; + + return 0; +} + +static void FrameCallback(void) +{ + SDL_PumpEvents(); // Force key events into the buffer. + gram[0xC804] = gram[0xC806] = gram[0xC80C] = 0; // Reset PIA ports... + + if (keys[SDLK_ESCAPE]) + running = false; // ESC to exit... + +//Convert this stuff to use the settings module... !!! FIX !!! + if (keys[SDLK_SEMICOLON]) + gram[0xC804] |= 0x01; // Fire (;) + if (keys[SDLK_l]) + gram[0xC804] |= 0x02; // Thrust (L) + if (keys[SDLK_SPACE]) + gram[0xC804] |= 0x04; // Smart Bomb (space) + if (keys[SDLK_BACKSPACE]) + gram[0xC804] |= 0x08; // Hyperspace (BkSp) + if (keys[SDLK_2]) + gram[0xC804] |= 0x10; // Two Player Start (2) + if (keys[SDLK_1]) + gram[0xC804] |= 0x20; // One Player Start (1) + if (keys[SDLK_RETURN]) + gram[0xC804] |= 0x40; // Reverse (Enter) + if (keys[SDLK_f]) + gram[0xC804] |= 0x80; // Down (F) + + if (keys[SDLK_r]) + gram[0xC806] |= 0x01; // Up (R) + if (keys[SDLK_a]) + gram[0xC806] |= 0x02; // Inviso (A) + + if (keys[SDLK_F1]) + gram[0xC80C] |= 0x01; // Auto up (F1) + if (keys[SDLK_F2]) + gram[0xC80C] |= 0x02; // Advance (F2) + if (keys[SDLK_5]) + gram[0xC80C] |= 0x04; // Right Coin (5) + if (keys[SDLK_F3]) + gram[0xC80C] |= 0x08; // High Score Reset (F3) + if (keys[SDLK_3]) + gram[0xC80C] |= 0x10; // Left Coin (3) + if (keys[SDLK_4]) + gram[0xC80C] |= 0x20; // Center Coin (4) + if (keys[SDLK_F4]) + gram[0xC80C] |= 0x40; // Slam Switch (F4) + + if (keys[SDLK_F5]) // Sound CPU self-test (F5) + soundCPU.cpuFlags |= V6808_ASSERT_LINE_NMI; + if (keys[SDLK_F6]) // Reset the 6808 (F6) + soundCPU.cpuFlags |= V6808_ASSERT_LINE_RESET; + + RenderScreenBuffer2(); // 1 frame = 1/60 sec ~ 16667 cycles + SetCallbackTime(FrameCallback, 16666.66666667); + + while (SDL_GetTicks() - startTicks < 16); // Wait for next frame... + startTicks = SDL_GetTicks(); +} + +static void ScanlineCallback(void) +{ +// CA1 of PIA 1 maps to $C80C-F... <-- Count240 is in PIA1... +// What about COUNT240??? + +//wil wok? Yes, but still screws up on the demo... +/* if (gram[0xCB00] & 0x20) + if (gram[0xC80F] & 0x01) + mainCPU.cpuFlags |= V6809_ASSERT_LINE_IRQ;//*/ + if ((gram[0xCB00] & 0x20) && (gram[0xC80F] & 0x01)) + mainCPU.cpuFlags |= V6809_ASSERT_LINE_IRQ;//*/ + +//Is $C80E COUNT240? Hmm... Doesn't seem to be. Bleh. +/* if (gram[0xCB00] >= 240) + gram[0xC80E] = 0xFF; + else + gram[0xC80E] = 0x00;//*/ +// gram[0xC80E] = (gram[0xCB00] >= 240 ? 0xFF : 0x00); + + gram[0xCB00] += 8; // Update video counter... + + SetCallbackTime(ScanlineCallback, 520.83333334); // Set scanline callback at 1/32 of frame +} + + +/* +; With correct timing, but no color cycling + +--> Start of frame... +WrMem: Writing address C80F with 34 [PC=15C3, $CB00=40] +At $07AD. $6E: 00 +At $0B66. $6E: 00 +At $0CF4. $6E: 00 +At $0CCB. $6E: 00 +WrMem: Writing address C80F with 35 [PC=1644, $CB00=40] +WrMem: Writing address C80F with 34 [PC=15C3, $CB00=80] +At $0718. $6E: 01 +At $07AD. $6E: 01 +At $0BB8. $6E: 01 +At $0927. $6E: 01 +At $0CF4. $6E: 01 +At $0B66. $6E: 01 +At $16C8. $6E: 01 +WrMem: Writing address C80F with 35 [PC=1644, $CB00=80] +WrMem: Writing address C80F with 34 [PC=15C3, $CB00=C0] +WrMem: Writing address C80F with 35 [PC=1644, $CB00=C0] + + +; With incorrect timing, but has color cycling + +--> Start of frame... +WrMem: Writing address C80F with 34 [PC=15C3, $CB00=00] +At $1609. $6E: 00 ; Color cycling... +At $07AD. $6E: 00 +At $0B66. $6E: 00 +At $0CF4. $6E: 00 +At $0CCB. $6E: 00 +WrMem: Writing address C80F with 35 [PC=1644, $CB00=00] +WrMem: Writing address C80F with 34 [PC=15C3, $CB00=40] +WrMem: Writing address C80F with 35 [PC=1644, $CB00=40] +WrMem: Writing address C80F with 34 [PC=15C3, $CB00=80] +At $0718. $6E: 01 +At $07AD. $6E: 01 +At $0BB8. $6E: 01 +At $0927. $6E: 01 +At $0CF4. $6E: 01 +At $0B66. $6E: 01 +At $16C8. $6E: 01 +WrMem: Writing address C80F with 35 [PC=1644, $CB00=80] +WrMem: Writing address C80F with 34 [PC=15C3, $CB00=C0] +WrMem: Writing address C80F with 35 [PC=1644, $CB00=C0] + + + + Stargate + -------- + + 0000-8FFF ROM (for Blaster, 0000-3FFF is a bank of 12 ROMs) + 0000-97FF Video RAM Bank switched with ROM (96FF for Blaster) + 9800-BFFF RAM + 0xBB00 Blaster only, Color 0 for each line (256 entry) + 0xBC00 Blaster only, Color 0 flags, latch color only if bit 0 = 1 (256 entry) + Do something else with the bit 1, I do not know what + C000-CFFF I/O + D000-FFFF ROM + + C000-C00F color_registers (16 bytes of BBGGGRRR) + + C804 widget_pia_dataa (widget = I/O board) + C805 widget_pia_ctrla + C806 widget_pia_datab + C807 widget_pia_ctrlb (CB2 select between player 1 and player 2 + controls if Table or Joust) + bits 5-3 = 110 = player 2 + bits 5-3 = 111 = player 1 + + C80C rom_pia_dataa + C80D rom_pia_ctrla + C80E rom_pia_datab + bit 0 \ + bit 1 | + bit 2 |-6 bits to sound board + bit 3 | + bit 4 | + bit 5 / + bit 6 \ + bit 7 /Plus CA2 and CB2 = 4 bits to drive the LED 7 segment + C80F rom_pia_ctrlb + + C900 rom_enable_scr_ctrl Switch between video ram and rom at 0000-97FF + + Stargate + -------- + C804 widget_pia_dataa (widget = I/O board) + bit 0 Fire + bit 1 Thrust + bit 2 Smart Bomb + bit 3 HyperSpace + bit 4 2 Players + bit 5 1 Player + bit 6 Reverse + bit 7 Down + + C806 widget_pia_datab + bit 0 Up + bit 1 Inviso + bit 2 + bit 3 + bit 4 + bit 5 + bit 6 + bit 7 0 = Upright 1 = Table + + C80C rom_pia_dataa + bit 0 Auto Up + bit 1 Advance + bit 2 Right Coin (High Score Reset in schematics) + bit 3 High Score Reset (Left Coin in schematics) + bit 4 Left Coin (Center Coin in schematics) + bit 5 Center Coin (Right Coin in schematics) + bit 6 Slam Door Tilt + bit 7 Hand Shake from sound board +*/ + + +/* + +static MEMORY_READ_START( williams_readmem ) + { 0x0000, 0x97ff, MRA_BANK1 }, + { 0x9800, 0xbfff, MRA_RAM }, + { 0xc804, 0xc807, pia_0_r }, + { 0xc80c, 0xc80f, pia_1_r }, + { 0xcb00, 0xcb00, williams_video_counter_r }, + { 0xcc00, 0xcfff, MRA_RAM }, + { 0xd000, 0xffff, MRA_ROM }, +MEMORY_END + + +static MEMORY_WRITE_START( williams_writemem ) + { 0x0000, 0x97ff, williams_videoram_w, &williams_bank_base, &videoram_size }, + { 0x9800, 0xbfff, MWA_RAM }, + { 0xc000, 0xc00f, paletteram_BBGGGRRR_w, &paletteram }, + { 0xc804, 0xc807, pia_0_w }, + { 0xc80c, 0xc80f, pia_1_w }, + { 0xc900, 0xc900, williams_vram_select_w }, + { 0xca00, 0xca07, williams_blitter_w, &williams_blitterram }, + { 0xcbff, 0xcbff, watchdog_reset_w }, + { 0xcc00, 0xcfff, MWA_RAM }, + { 0xd000, 0xffff, MWA_ROM }, +MEMORY_END + +static MEMORY_READ_START( sound_readmem ) + { 0x0000, 0x007f, MRA_RAM }, + { 0x0400, 0x0403, pia_2_r }, + { 0x8400, 0x8403, pia_2_r }, // used by Colony 7, perhaps others? + { 0xb000, 0xffff, MRA_ROM }, // most games start at $F000, Sinistar starts at $B000 +MEMORY_END + + +static MEMORY_WRITE_START( sound_writemem ) + { 0x0000, 0x007f, MWA_RAM }, + { 0x0400, 0x0403, pia_2_w }, + { 0x8400, 0x8403, pia_2_w }, // used by Colony 7, perhaps others? + { 0xb000, 0xffff, MWA_ROM }, // most games start at $F000, Sinistar starts at $B000 +MEMORY_END + +MACHINE_INIT( williams ) +{ + // reset the PIAs + pia_reset(); + + // reset the ticket dispenser (Lotto Fun) + ticket_dispenser_init(70, TICKET_MOTOR_ACTIVE_LOW, TICKET_STATUS_ACTIVE_HIGH); + + // set a timer to go off every 16 scanlines, to toggle the VA11 line and update the screen + timer_set(cpu_getscanlinetime(0), 0, williams_va11_callback); + + // also set a timer to go off on scanline 240 + timer_set(cpu_getscanlinetime(240), 0, williams_count240_callback); +} + + +static void williams_va11_callback(int scanline) +{ + // the IRQ signal comes into CB1, and is set to VA11 + pia_1_cb1_w(0, scanline & 0x20); + + // update the screen while we're here + force_partial_update(scanline - 1); + + // set a timer for the next update + scanline += 8; + if (scanline >= 256) scanline = 0; + timer_set(cpu_getscanlinetime(scanline), scanline, williams_va11_callback); +} + + +static void williams_count240_off_callback(int param) +{ + // the COUNT240 signal comes into CA1, and is set to the logical AND of VA10-VA13 + pia_1_ca1_w(0, 0); +} + + +static void williams_count240_callback(int param) +{ + // the COUNT240 signal comes into CA1, and is set to the logical AND of VA10-VA13 + pia_1_ca1_w(0, 1); + + // set a timer to turn it off once the scanline counter resets + timer_set(cpu_getscanlinetime(0), 0, williams_count240_off_callback); + + // set a timer for next frame + timer_set(cpu_getscanlinetime(240), 0, williams_count240_callback); +} + + +static void williams_main_irq(int state) +{ + // IRQ to the main CPU + cpu_set_irq_line(0, M6809_IRQ_LINE, state ? ASSERT_LINE : CLEAR_LINE); +} + + +static void williams_main_firq(int state) +{ + // FIRQ to the main CPU + cpu_set_irq_line(0, M6809_FIRQ_LINE, state ? ASSERT_LINE : CLEAR_LINE); +} + + +static void williams_snd_irq(int state) +{ + // IRQ to the sound CPU + cpu_set_irq_line(1, M6800_IRQ_LINE, state ? ASSERT_LINE : CLEAR_LINE); +} + + +READ_HANDLER( williams_video_counter_r ) +{ + return cpu_getscanline() & 0xFC; +} + + +// Special PIA 0 for Stargate, to handle the controls +struct pia6821_interface stargate_pia_0_intf = +{ + //inputs : A/B,CA/B1,CA/B2 / stargate_input_port_0_r, input_port_1_r, 0, 0, 0, 0, + //outputs: A/B,CA/B2 / 0, 0, 0, 0, + //irqs : A/B / 0, 0 +}; + +// Generic PIA 1, maps to input port 2, sound command out, and IRQs +struct pia6821_interface williams_pia_1_intf = +{ + //inputs : A/B,CA/B1,CA/B2 / input_port_2_r, 0, 0, 0, 0, 0, + //outputs: A/B,CA/B2 / 0, williams_snd_cmd_w, 0, 0, + //irqs : A/B / williams_main_irq, williams_main_irq +}; + +// Generic PIA 2, maps to DAC data in and sound IRQs +struct pia6821_interface williams_snd_pia_intf = +{ + //inputs : A/B,CA/B1,CA/B2 / 0, 0, 0, 0, 0, 0, + //outputs: A/B,CA/B2 / DAC_0_data_w, 0, 0, 0, + //irqs : A/B / williams_snd_irq, williams_snd_irq +}; + +static DRIVER_INIT( stargate ) +{ + // CMOS configuration + CONFIGURE_CMOS(0xCC00, 0x400); + + // PIA configuration + CONFIGURE_PIAS(stargate_pia_0_intf, williams_pia_1_intf, williams_snd_pia_intf); +} + + +int cpu_getscanline(void) +{ + return (int)(timer_timeelapsed(refresh_timer) * scanline_period_inv); +} + + ************************************* + * + * Returns time until given scanline + * + ************************************* + +double cpu_getscanlinetime(int scanline) +{ + double scantime = timer_starttime(refresh_timer) + (double)scanline * scanline_period; + double abstime = timer_get_time(); + double result; + + // if we're already past the computed time, count it for the next frame + if (abstime >= scantime) + scantime += TIME_IN_HZ(Machine->drv->frames_per_second); + + // compute how long from now until that time + result = scantime - abstime; + + // if it's small, just count a whole frame + if (result < TIME_IN_NSEC(1)) + result = TIME_IN_HZ(Machine->drv->frames_per_second); + return result; +} + + ************************************* + * + * Returns time for one scanline + * + ************************************* + +double cpu_getscanlineperiod(void) +{ + return scanline_period; +} + + +V6809 WrMem: Writing address C80D with 00 [PC=0000, $CB00=00] +V6809 WrMem: Writing address C80C with 00 [PC=0000, $CB00=00] +V6809 WrMem: Writing address C80D with 3C [PC=0000, $CB00=00] + +V6809 WrMem: Writing address C80F with 00 [PC=0000, $CB00=00] +V6809 WrMem: Writing address C80E with C0 [PC=0000, $CB00=00] +V6809 WrMem: Writing address C80F with 3C [PC=0000, $CB00=00] + +V6809 WrMem: Writing address C80E with C0 [PC=0000, $CB00=00] +V6809 WrMem: Writing address C80D with 34 [PC=FE61, $CB00=48] +V6809 WrMem: Writing address C80F with 34 [PC=FE61, $CB00=48] +V6809 WrMem: Writing address C80E with 00 [PC=FE61, $CB00=48] + +V6809 WrMem: Writing address C80C with 00 [PC=FD92, $CB00=C8] +V6809 WrMem: Writing address C80D with 00 [PC=FD92, $CB00=C8] +V6809 WrMem: Writing address C80C with 00 [PC=FD92, $CB00=C8] +V6809 WrMem: Writing address C80D with 34 [PC=FD92, $CB00=C8] + +V6809 WrMem: Writing address C80E with 00 [PC=FD92, $CB00=C8] +V6809 WrMem: Writing address C80F with 00 [PC=FD92, $CB00=C8] +V6809 WrMem: Writing address C80E with FF [PC=FD92, $CB00=C8] +V6809 WrMem: Writing address C80F with 35 [PC=FD92, $CB00=C8] + +V6809 WrMem: Writing address C804 with 00 [PC=607B, $CB00=D0] +V6809 WrMem: Writing address C805 with 00 [PC=607B, $CB00=D0] +V6809 WrMem: Writing address C804 with 00 [PC=607B, $CB00=D0] +V6809 WrMem: Writing address C805 with 34 [PC=607B, $CB00=D0] + +V6809 WrMem: Writing address C806 with 00 [PC=607B, $CB00=D0] +V6809 WrMem: Writing address C807 with 00 [PC=607B, $CB00=D0] +V6809 WrMem: Writing address C806 with 00 [PC=607B, $CB00=D0] +V6809 WrMem: Writing address C807 with 3E [PC=607B, $CB00=D0] + +V6809 WrMem: Writing address C80E with 3F [PC=13CB, $CB00=A8] +V6809 WrMem: Writing address C807 with 3C [PC=60B4, $CB00=90] +V6809 WrMem: Writing address C80E with 0C [PC=014D, $CB00=80] + +V6809 WrMem: Writing address C80F with 34 [PC=014D, $CB00=80] +V6809 WrMem: Writing address C80F with 35 [PC=014D, $CB00=80] +V6809 WrMem: Writing address C80F with 34 [PC=0013, $CB00=A8] +V6809 WrMem: Writing address C80F with 35 [PC=0013, $CB00=A8] + + C80C rom_pia_dataa + C80D rom_pia_ctrla + C80E rom_pia_datab + bit 0 \ + bit 1 | + bit 2 |-6 bits to sound board + bit 3 | + bit 4 | + bit 5 / + bit 6 \ + bit 7 /Plus CA2 and CB2 = 4 bits to drive the LED 7 segment + C80F rom_pia_ctrlb + +CTRLA = IRQA1 (1 bit) IRQA2 (1 bit) CA2 (3 bits) DDR (1 bit) CA1 (2 bits) + + +PIA initialization: + +00 -> $C80D = PIA2 -> DDR active +00 -> $C80C = PIA2 DDR -> All input? + + + +*/ + diff --git a/src/timing.cpp b/src/timing.cpp new file mode 100755 index 0000000..331e342 --- /dev/null +++ b/src/timing.cpp @@ -0,0 +1,130 @@ +// +// System time handlers +// +// by James L. Hammons +// (C) 2005 Underground Software +// +// JLH = James L. Hammons +// +// WHO WHEN WHAT +// --- ---------- ------------------------------------------------------------ +// JLH 01/04/2006 Cosmetic changes (like this one ;-) +// + +// STILL TO DO: +// +// - Handling for an event that occurs NOW +// + +#include "timing.h" + +#include "log.h" + +#define EVENT_LIST_SIZE 512 + +// NOTE ABOUT TIMING SYSTEM DATA STRUCTURES: + +// A queue won't work for this system because we can't guarantee that an event will go +// in with a time that is later than the ones already queued up. So we just use a simple +// list. + +// Although if we used an insertion sort we could, but it wouldn't work for adjusting +// times... +// [In that case, we could pull the event out, close the gap, then do insertion sort] + +struct Event +{ + bool valid; + double eventTime; + void (* timerCallback)(void); +}; + +static Event eventList[EVENT_LIST_SIZE]; +static uint32 nextEvent; + +void InitializeEventList(void) +{ + for(uint32 i=0; i +// +// WHO WHEN WHAT +// --- ---------- ------------------------------------------------------------ +// JLH 06/15/2006 Added changelog ;-) +// JLH 06/15/2006 Scrubbed all BYTE, WORD & DWORD references from the code +// + +// Mebbe someday I'll get around to fixing the core to be more like V65C02... + +//#define __DEBUG__ + +#include "v6808.h" + +#ifdef __DEBUG__ +#include "dis6808.h" +#include "log.h" +#endif + +// Private global variables + +static V6808REGS regs; +static uint16 addr; +static uint8 tmp; + +static uint8 CPUCycles[256] = { + 1, 2, 1, 1, 1, 1, 2, 2, 4, 4, 2, 2, 2, 2, 2, 2, + 2, 2, 1, 1, 1, 1, 2, 2, 1, 2, 1, 2, 1, 1, 1, 1, + 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 1, 5, 1, 10, 1, 1, 9, 12, + 2, 1, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, + 2, 1, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, + 7, 1, 1, 8, 7, 1, 7, 7, 7, 7, 7, 1, 7, 7, 4, 7, + 6, 1, 1, 7, 6, 1, 6, 6, 6, 6, 6, 1, 6, 6, 3, 6, + 2, 2, 2, 1, 2, 2, 2, 1, 2, 2, 2, 2, 3, 8, 3, 1, + 3, 3, 3, 1, 3, 3, 3, 4, 3, 3, 3, 3, 4, 1, 4, 5, + 5, 5, 5, 1, 5, 5, 5, 6, 5, 5, 5, 5, 6, 8, 6, 7, + 4, 4, 4, 1, 4, 4, 4, 5, 4, 4, 4, 4, 5, 9, 5, 6, + 2, 2, 2, 1, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 3, 1, + 3, 3, 3, 1, 3, 3, 3, 4, 3, 3, 3, 3, 1, 1, 4, 5, + 5, 5, 5, 1, 5, 5, 5, 6, 5, 5, 5, 5, 1, 1, 6, 7, + 4, 4, 4, 1, 4, 4, 4, 5, 4, 4, 4, 4, 1, 1, 5, 6 +}; + +// Private function prototypes + +static uint16 FetchW(void); +static uint16 RdMemW(uint16); +static void WrMemW(uint16, uint16); + +// +// Fetch a word out of 6808 memory (little endian format) +// This is a leftover from when fetches were separated from garden variety reads... +// +static uint16 FetchW() +{ + uint16 w = RdMemW(regs.pc); + regs.pc += 2; + return w; +} + +// +// Read a word out of 6808 memory (little endian format) +// +static uint16 RdMemW(uint16 address) +{ + return (uint16)(regs.RdMem(address) << 8) | regs.RdMem(address + 1); +} + +// +// Write a word into 6808 memory (little endian format) +// +static void WrMemW(uint16 address, uint16 w) +{ + regs.WrMem(address + 0, w >> 8); + regs.WrMem(address + 1, w & 0xFF); +} + +// +// Function to decode IDX data +// +inline uint16 DecodeIDX(uint8 code) +{ + return regs.x + code; +} + + +// +// Opcode Functions (Mostly correct... Yikes!) +// + +static void Op01(void) // NOP +{ +} + +static void Op06(void) // TAP +{ + regs.cc = regs.a; +} + +static void Op07(void) // TPA +{ + regs.a = regs.cc; +} + +static void Op08(void) // INX +{ + regs.x++; + + (regs.x == 0 ? regs.cc |= FLAG_Z : regs.cc &= ~FLAG_Z); +} + +static void Op09(void) // DEX +{ + regs.x--; + + (regs.x == 0 ? regs.cc |= FLAG_Z : regs.cc &= ~FLAG_Z); +} + +static void Op0A(void) // CLV +{ + regs.cc &= ~FLAG_V; +} + +static void Op0B(void) // SEV +{ + regs.cc |= FLAG_V; +} + +static void Op0C(void) // CLC +{ + regs.cc &= ~FLAG_C; +} + +static void Op0D(void) // SEC +{ + regs.cc |= FLAG_C; +} + +static void Op0E(void) // CLI +{ + regs.cc &= ~FLAG_I; +} + +static void Op0F(void) // SEI +{ + regs.cc |= FLAG_I; +} + +static void Op10(void) // SBA +{ + uint8 as = regs.a; + regs.a -= regs.b; + + regs.cc &= ~(FLAG_N | FLAG_Z | FLAG_V | FLAG_C); // Clear NZVC + + if (as < regs.b) + regs.cc |= FLAG_C; + + if ((as ^ regs.b ^ regs.a ^ (regs.cc << 7)) & 0x80) + regs.cc |= FLAG_V; + + if (regs.a == 0) + regs.cc |= FLAG_Z; + + if (regs.a & 0x80) + regs.cc |= FLAG_N; +} + +static void Op11(void) // CBA (Compare B to A) +{ + tmp = regs.a - regs.b; + + regs.cc &= ~(FLAG_N | FLAG_Z | FLAG_V | FLAG_C); // Clear NZVC + + if (regs.a < regs.b) + regs.cc |= FLAG_C; + + if ((tmp ^ regs.b ^ regs.a ^ (regs.cc << 7)) & 0x80) + regs.cc |= FLAG_V; + + if (regs.a == 0) + regs.cc |= FLAG_Z; + + if (regs.a & 0x80) + regs.cc |= FLAG_N; +} + +static void Op16(void) // TAB +{ + regs.b = regs.a; + + regs.cc &= ~(FLAG_N | FLAG_Z | FLAG_V); // Clear NZV + + if (regs.b == 0) + regs.cc |= FLAG_Z; + + if (regs.b & 0x80) + regs.cc |= FLAG_N; +} + +static void Op17(void) // TBA +{ + regs.a = regs.b; + + regs.cc &= ~(FLAG_N | FLAG_Z | FLAG_V); // Clear NZV + + if (regs.a == 0) + regs.cc |= FLAG_Z; + + if (regs.a & 0x80) + regs.cc |= FLAG_N; +} + +static void Op19(void) // DAA +{ + addr = regs.a; +// if (regs.cc&0x20) addr += 6; // H set? adjust + if ((addr&0x000F) > 9) addr += 6; + if (regs.cc&0x01) addr += 0x60; // C set? adjust + if ((addr&0x00F0) > 0x90) addr += 0x60; + regs.cc &= 0xFD; // CLV + (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + regs.a = addr; + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op1B(void) // ABA +{ + addr = regs.a + regs.b; + regs.cc &= 0xF0; + if (addr > 0xFF) regs.cc |= 0x01; // Set Carry flag + if ((regs.a^regs.b^addr^(regs.cc<<7))&0x80) regs.cc |= 0x02; // Set oVerflow + regs.a = addr; // Set accumulator + if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag + if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag +} + +static void Op20(void) // BRA (BRanch Always) +{ + regs.pc += (int16)(int8)regs.RdMem(regs.pc++); +} + +static void Op22(void) // BHI +{ + tmp = regs.RdMem(regs.pc++); + + if (!(regs.cc & (FLAG_C | FLAG_Z))) + regs.pc += (signed short int)(signed char)tmp; +} + +static void Op23(void) // BLS +{ + tmp = regs.RdMem(regs.pc++); + + if (regs.cc & (FLAG_C | FLAG_Z)) + regs.pc += (signed short int)(signed char)tmp; +} + +static void Op24(void) // BCC (BHS) +{ + tmp = regs.RdMem(regs.pc++); + if (!(regs.cc&0x01)) regs.pc += (signed short int)(signed char)tmp; +} + +static void Op25(void) // BCS (BLO) +{ + tmp = regs.RdMem(regs.pc++); + if (regs.cc&0x01) regs.pc += (signed short int)(signed char)tmp; +} + +static void Op26(void) // BNE +{ + tmp = regs.RdMem(regs.pc++); + if (!(regs.cc&0x04)) regs.pc += (signed short int)(signed char)tmp; +} + +static void Op27(void) // BEQ +{ + tmp = regs.RdMem(regs.pc++); + if (regs.cc&0x04) regs.pc += (signed short int)(signed char)tmp; +} + +static void Op28(void) // BVC +{ + tmp = regs.RdMem(regs.pc++); + if (!(regs.cc&0x02)) regs.pc += (signed short int)(signed char)tmp; +} + +static void Op29(void) // BVS +{ + tmp = regs.RdMem(regs.pc++); + if (regs.cc&0x02) regs.pc += (signed short int)(signed char)tmp; +} + +static void Op2A(void) // BPL +{ + tmp = regs.RdMem(regs.pc++); + if (!(regs.cc&0x08)) regs.pc += (signed short int)(signed char)tmp; +} + +static void Op2B(void) // BMI +{ + tmp = regs.RdMem(regs.pc++); + if (regs.cc&0x08) regs.pc += (signed short int)(signed char)tmp; +} + +static void Op2C(void) // BGE +{ + tmp = regs.RdMem(regs.pc++); + if (!(((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))) regs.pc += (signed short int)(signed char)tmp; +} + +static void Op2D(void) // BLT +{ + tmp = regs.RdMem(regs.pc++); + if (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02)) regs.pc += (signed short int)(signed char)tmp; +} + +static void Op2E(void) // BGT +{ + tmp = regs.RdMem(regs.pc++); + if (!((regs.cc&0x04) | (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02)))) regs.pc += (signed short int)(signed char)tmp; +} + +static void Op2F(void) // BLE +{ + tmp = regs.RdMem(regs.pc++); + if ((regs.cc&0x04) | (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))) regs.pc += (signed short int)(signed char)tmp; +} + +static void Op30(void) // TSX +{ + regs.x = regs.s; +} + +static void Op31(void) // INS +{ + regs.s++; +} + +static void Op32(void) // PULA +{ + regs.a = regs.RdMem(regs.s++); +} + +static void Op33(void) // PULB +{ + regs.b = regs.RdMem(regs.s++); +} + +static void Op34(void) // DES +{ + regs.s--; +} + +static void Op35(void) // TXS +{ + regs.s = regs.x; +} + +static void Op36(void) // PSHA +{ + regs.WrMem(--regs.s, regs.a); +} + +static void Op37(void) // PSHB +{ + regs.WrMem(--regs.s, regs.b); +} + +static void Op39(void) // RTS +{ + regs.pc = (regs.RdMem(regs.s++) << 8) | regs.RdMem(regs.s++); +} + +static void Op3B(void) // RTI +{ + regs.cc = regs.RdMem(regs.s++); + regs.a = regs.RdMem(regs.s++); + regs.b = regs.RdMem(regs.s++); + regs.x = (regs.RdMem(regs.s++) << 8) | regs.RdMem(regs.s++); + regs.pc = (regs.RdMem(regs.s++) << 8) | regs.RdMem(regs.s++); +} + +static void Op3E(void) // WAI (wait for interrupt) +{ + regs.cc &= regs.RdMem(regs.pc++); + regs.cc |= 0x80;//???Is this right??? +} + +static void Op3F(void) // SWI (software interrupt) +{ +//Does this respect the I flag??? + regs.WrMem(--regs.s, regs.pc & 0xFF); // Save all regs... + regs.WrMem(--regs.s, regs.pc >> 8); + regs.WrMem(--regs.s, regs.x & 0xFF); + regs.WrMem(--regs.s, regs.x >> 8); + regs.WrMem(--regs.s, regs.b); + regs.WrMem(--regs.s, regs.a); + regs.WrMem(--regs.s, regs.cc); + regs.pc = RdMemW(0xFFFA); // And do it! + + regs.cc |= FLAG_I; // Also, set IRQ inhibit +} + +static void Op40(void) // NEGA +{ + regs.a = 256 - regs.a; regs.cc &= 0xF0; + if (regs.a > 0x7F) regs.cc |= 0x01; // Set Carry + if (regs.a == 0x80) regs.cc |= 0x02; // Set oVerflow + if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag + if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag +} + +static void Op43(void) // COMA +{ + regs.a ^= 0xFF; + regs.cc &= 0xF0; regs.cc |= 0x01; // CLV, SEC + if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag + if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag +} + +static void Op44(void) // LSRA +{ + (regs.a&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into Carry + regs.a >>= 1; + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op46(void) // RORA +{ + tmp = regs.a; regs.a = (tmp>>1) + (regs.cc&0x01)*128; + (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into Carry + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op47(void) // ASRA +{ + (regs.a&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into Carry + regs.a >>= 1; // Do the shift + if (regs.a&0x40) regs.a |= 0x80; // Set neg if it was set + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op48(void) // LSLA (ASLA) [Keep checking from here...] +{ + (regs.a&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into Carry + regs.a <<= 1; + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op49(void) // ROLA +{ + tmp = regs.a; regs.a = (tmp<<1) + (regs.cc&0x01); + (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into Carry + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op4A(void) // DECA +{ + regs.a--; + (regs.a == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op4C(void) // INCA +{ +regs.a++; +(regs.a == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag +(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op4D(void) // TSTA +{ +regs.cc &= 0xFD; // Clear oVerflow flag +(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op4F(void) // CLRA +{ + regs.a = 0; + regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC +} + +static void Op50(void) // NEGB +{ +regs.b = 256 - regs.b; +// ((regs.b^tmp)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Adjust H Carry +(regs.b == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow +(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +(regs.b > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry +} + +static void Op53(void) // COMB +{ +regs.b ^= 0xFF; +regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC +(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op54(void) // LSRB +{ +(regs.b&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into Carry +regs.b >>= 1; +(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op56(void) // RORB +{ +tmp = regs.b; regs.b = (regs.b >> 1) + (regs.cc&0x01)*128; +(tmp&0x01 ? regs.cc |=0x01 : regs.cc &= 0xFE); // Shift bit into Carry +(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op57(void) // ASRB +{ +(regs.b&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into Carry +regs.b >>= 1; // Do the shift +if (regs.b&0x40) regs.b |= 0x80; // Set neg if it was set +(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op58(void) // LSLB +{ +(regs.b&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into Carry +regs.b <<= 1; +(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op59(void) // ROLB +{ + tmp = regs.b; + regs.b = (tmp<<1) + (regs.cc&0x01); + (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into Carry + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op5A(void) // DECB +{ +regs.b--; +(regs.b == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag +(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op5C(void) // INCB +{ +regs.b++; +(regs.b == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag +(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op5D(void) // TSTB +{ +regs.cc &= 0xFD; // Cleregs.a oVerflow flag +(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op5F(void) // CLRB +{ +regs.b = 0; +regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC +} + +static void Op60(void) // NEG IDX +{ +addr = DecodeIDX(regs.RdMem(regs.pc++)); +tmp = regs.RdMem(addr); uint8 res = 256 - tmp; +regs.WrMem(addr, res); +// ((res^tmp)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Adjust H Carry +(res == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow +(res == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(res&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +(res > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry +} + +static void Op63(void) // COM IDX +{ +addr = DecodeIDX(regs.RdMem(regs.pc++)); +tmp = regs.RdMem(addr) ^ 0xFF; +regs.WrMem(addr, tmp); +regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC +(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op64(void) // LSR IDX +{ +addr = DecodeIDX(regs.RdMem(regs.pc++)); +tmp = regs.RdMem(addr); +(tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into Carry +tmp >>= 1; regs.WrMem(addr, tmp); +regs.cc &= 0xF7; // CLN +(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +} + +static void Op66(void) // ROR IDX +{ +addr = DecodeIDX(regs.RdMem(regs.pc++)); +tmp = regs.RdMem(addr); uint8 tmp2 = tmp; +tmp = (tmp >> 1) + (regs.cc&0x01)*128; +regs.WrMem(addr, tmp); +(tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into Carry +(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op67(void) // ASR IDX +{ +addr = DecodeIDX(regs.RdMem(regs.pc++)); +tmp = regs.RdMem(addr); +(tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into Carry +tmp >>= 1; +if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set +regs.WrMem(addr, tmp); +(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op68(void) // LSL IDX +{ +addr = DecodeIDX(regs.RdMem(regs.pc++)); +tmp = regs.RdMem(addr); +(tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into Carry +tmp <<= 1; +regs.WrMem(addr, tmp); +(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op69(void) // ROL IDX +{ + uint8 tmp2 = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); + tmp = (tmp2<<1) + (regs.cc&0x01); + regs.WrMem(addr, tmp); + (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into Carry + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op6A(void) // DEC IDX +{ +uint8 tmp; uint16 addr; +addr = DecodeIDX(regs.RdMem(regs.pc++)); +tmp = regs.RdMem(addr) - 1; +regs.WrMem(addr, tmp); +(tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag +(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op6C(void) // INC IDX +{ +addr = DecodeIDX(regs.RdMem(regs.pc++)); +tmp = regs.RdMem(addr) + 1; +regs.WrMem(addr, tmp); +(tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag +(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op6D(void) // TST IDX +{ +tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); +(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op6E(void) // JMP IDX +{ + regs.pc = DecodeIDX(regs.RdMem(regs.pc++)); +} + +static void Op6F(void) // CLR IDX +{ + addr = DecodeIDX(regs.RdMem(regs.pc++)); + regs.WrMem(addr, 0); + regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC +} + +static void Op70(void) // NEG ABS +{ +addr = FetchW(); +tmp = regs.RdMem(addr); uint8 res = 256 - tmp; +regs.WrMem(addr, res); +(res == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow +(res == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(res&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +(res > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry +} + +static void Op73(void) // COM ABS +{ +addr = FetchW(); +tmp = regs.RdMem(addr) ^ 0xFF; +regs.WrMem(addr, tmp); +regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC +(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op74(void) // LSR ABS +{ +addr = FetchW(); +tmp = regs.RdMem(addr); +(tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into Carry +tmp >>= 1; regs.WrMem(addr, tmp); +regs.cc &= 0xF7; // CLN +(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +} + +static void Op76(void) // ROR ABS +{ +uint8 tmp; uint16 addr; +addr = FetchW(); +tmp = regs.RdMem(addr); uint8 tmp2 = tmp; +tmp = (tmp >> 1) + (regs.cc&0x01)*128; +regs.WrMem(addr, tmp); +(tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into Carry +(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op77(void) // ASR ABS +{ +uint8 tmp; uint16 addr; +addr = FetchW(); +tmp = regs.RdMem(addr); +(tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into Carry +tmp >>= 1; +if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set +regs.WrMem(addr, tmp); +(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op78(void) // LSL ABS +{ +uint8 tmp; uint16 addr; +addr = FetchW(); +tmp = regs.RdMem(addr); +(tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into Carry +tmp <<= 1; +regs.WrMem(addr, tmp); +(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op79(void) // ROL ABS +{ + uint8 tmp2 = regs.RdMem(FetchW()); + tmp = (tmp2<<1) + (regs.cc&0x01); + regs.WrMem(addr, tmp); + (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into Carry + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op7A(void) // DEC ABS +{ +uint8 tmp; uint16 addr; +addr = FetchW(); +tmp = regs.RdMem(addr) - 1; +regs.WrMem(addr, tmp); +(tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag +(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op7C(void) // INC ABS +{ + addr = FetchW(); + tmp = regs.RdMem(addr) + 1; + regs.WrMem(addr, tmp); + + (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op7D(void) // TST ABS +{ + uint8 tmp = regs.RdMem(FetchW()); + + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp & 0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op7E(void) // JMP ABS +{ + regs.pc = FetchW(); +} + +static void Op7F(void) // CLR ABS +{ +regs.WrMem(FetchW(), 0); +regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC +} + +static void Op80(void) // SUBA # +{ + uint8 tmp = regs.RdMem(regs.pc++); uint8 as = regs.a; + regs.a -= tmp; + (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op81(void) // CMPA # +{ + tmp = regs.RdMem(regs.pc++); + uint8 db = regs.a - tmp; + (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op82(void) // SBCA # +{ + tmp = regs.RdMem(regs.pc++); uint8 as = regs.a; + regs.a = regs.a - tmp - (regs.cc&0x01); + (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op84(void) // ANDA # +{ +regs.a &= regs.RdMem(regs.pc++); +regs.cc &= 0xFD; // Cleregs.a oVerflow flag +(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op85(void) // BITA # +{ +tmp = regs.a & regs.RdMem(regs.pc++); +regs.cc &= 0xFD; // Cleregs.a oVerflow flag +(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op86(void) // LDAA # +{ +regs.a = regs.RdMem(regs.pc++); +regs.cc &= 0xFD; // CLV +(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op88(void) // EORA # +{ +regs.a ^= regs.RdMem(regs.pc++); +regs.cc &= 0xFD; // CLV +(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op89(void) // ADCA # +{ + tmp = regs.RdMem(regs.pc++); + addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01); + (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry +// ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half Carry + ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.a = addr & 0xFF; // Set accumulator + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative +} + +static void Op8A(void) // ORAA # +{ +regs.a |= regs.RdMem(regs.pc++); +regs.cc &= 0xFD; // CLV +(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op8B(void) // ADDA # +{ + tmp = regs.RdMem(regs.pc++); addr = regs.a + tmp; + (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag + ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.a = addr & 0xFF; // Set accumulator + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag +} + +static void Op8C(void) // CPX # +{ + addr = FetchW(); + uint16 dw = regs.x - addr; + (regs.x < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((regs.x^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl + (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op8D(void) // BSR +{ + tmp = regs.RdMem(regs.pc++); + + regs.s -= 2; + WrMemW(regs.s, regs.pc); + + regs.pc += (signed short int)(signed char)tmp; +} + +static void Op8E(void) // LDS # +{ +regs.s = FetchW(); +regs.cc &= 0xFD; // CLV +(regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op90(void) // SUBA ZP +{ + tmp = regs.RdMem(regs.RdMem(regs.pc++)); uint8 as = regs.a; + regs.a -= tmp; + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow +} + +static void Op91(void) // CMPA ZP +{ +tmp = regs.RdMem(regs.RdMem(regs.pc++)); +uint8 db = regs.a - tmp; +(db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +(regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag +((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow +} + +static void Op92(void) // SBCA ZP +{ + tmp = regs.RdMem(regs.RdMem(regs.pc++)); uint8 as = regs.a; + regs.a = regs.a - tmp - (regs.cc&0x01); + (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op94(void) // ANDA ZP +{ + regs.a &= regs.RdMem(regs.RdMem(regs.pc++)); + regs.cc &= 0xF1; // CLV CLZ CLN + if (regs.a == 0) regs.cc |= 0x04; // Adjust Zero flag + if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag +} + +static void Op95(void) // BITA ZP +{ +tmp = regs.a & regs.RdMem(regs.RdMem(regs.pc++)); +regs.cc &= 0xFD; // Cleregs.a oVerflow flag +(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op96(void) // LDAA ZP +{ + regs.a = regs.RdMem(regs.RdMem(regs.pc++)); + regs.cc &= 0xF1; // CLN CLZ CLV + if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag + if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag +} + +static void Op97(void) // STAA ZP +{ +regs.WrMem(regs.RdMem(regs.pc++), regs.a); +regs.cc &= 0xFD; // CLV +(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op98(void) // EORA ZP +{ +regs.a ^= regs.RdMem(regs.RdMem(regs.pc++)); +regs.cc &= 0xFD; // CLV +(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op99(void) // ADCA ZP +{ + tmp = regs.RdMem(regs.RdMem(regs.pc++)); + addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01); + (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry + ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.a = addr & 0xFF; // Set accumulator + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative +} + +static void Op9A(void) // ORAA ZP +{ +regs.a |= regs.RdMem(regs.RdMem(regs.pc++)); +regs.cc &= 0xFD; // CLV +(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op9B(void) // ADDA ZP +{ + tmp = regs.RdMem(regs.RdMem(regs.pc++)); + addr = (uint16)regs.a + (uint16)tmp; + (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag + ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo + regs.a = addr & 0xFF; // Set accumulator + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag +} + +static void Op9C(void) // CPX ZP +{ +addr = regs.RdMem(regs.pc++); +uint16 adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); +uint16 dw = regs.x - adr2; +(dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +(regs.x < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag +((regs.x^adr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl +} + +static void Op9E(void) // LDS ZP +{ + regs.s = RdMemW(regs.RdMem(regs.pc++)); + + regs.cc &= 0xFD; // CLV + (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op9F(void) // STS ZP +{ + WrMemW(regs.RdMem(regs.pc++), regs.s); + + regs.cc &= 0xFD; // CLV + (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void OpA0(void) // SUBA IDX +{ +tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 as = regs.a; +regs.a -= tmp; +(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +(as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag +((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow +} + +static void OpA1(void) // CMPA IDX +{ +tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); +uint8 db = regs.a - tmp; +(db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +(regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag +((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow +} + +static void OpA2(void) // SBCA IDX +{ + tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 as = regs.a; + regs.a = regs.a - tmp - (regs.cc&0x01); + (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void OpA4(void) // ANDA IDX +{ +regs.a &= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); +regs.cc &= 0xFD; // Cleregs.a oVerflow flag +(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void OpA5(void) // BITA IDX +{ +tmp = regs.a & regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); +regs.cc &= 0xFD; // Cleregs.a oVerflow flag +(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void OpA6(void) // LDAA IDX +{ + regs.a = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); + regs.cc &= 0xF1; // CLV CLZ CLN + if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag + if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag +} + +static void OpA7(void) // STAA IDX +{ + regs.WrMem(DecodeIDX(regs.RdMem(regs.pc++)), regs.a); + regs.cc &= 0xF1; // CLV CLZ CLN + if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag + if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag +} + +static void OpA8(void) // EORA IDX +{ +regs.a ^= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); +regs.cc &= 0xFD; // CLV +(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void OpA9(void) // ADCA IDX +{ + tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); + addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01); + (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag + ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo + regs.a = addr & 0xFF; // Set accumulator + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag +} + +static void OpAA(void) // ORAA IDX +{ + regs.a |= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); + regs.cc &= 0xFD; // CLV + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void OpAB(void) // ADDA IDX +{ + tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); + addr = (uint16)regs.a + (uint16)tmp; + (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag + ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo + regs.a = addr & 0xFF; // Set accumulator + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag +} + +static void OpAC(void) // CPX IDX +{ + addr = DecodeIDX(regs.RdMem(regs.pc++)); + uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); + uint16 dw = regs.x - addr2; + (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.x < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((regs.x^addr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow +} + +static void OpAD(void) // JSR IDX +{ + addr = DecodeIDX(regs.RdMem(regs.pc++)); + + regs.s -= 2; + WrMemW(regs.s, regs.pc); + + regs.pc = addr; // JSR directly to IDX ptr +} + +static void OpAE(void) // LDS IDX +{ + regs.s = RdMemW(DecodeIDX(regs.RdMem(regs.pc++))); + + regs.cc &= ~FLAG_V; + (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void OpAF(void) // STS IDX +{ + WrMemW(DecodeIDX(regs.RdMem(regs.pc++)), regs.s); + + regs.cc &= ~(FLAG_N | FLAG_Z | FLAG_V); // Clear NZV + if (regs.s & 0x8000) regs.cc |= FLAG_N; // Set Negative flag + if (regs.s == 0) regs.cc |= FLAG_Z; // Set Zero flag +} + +static void OpB0(void) // SUBA ABS +{ +tmp = regs.RdMem(FetchW()); uint8 as = regs.a; +regs.a -= tmp; +(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +(as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag +((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow +} + +static void OpB1(void) // CMPA ABS +{ +tmp = regs.RdMem(FetchW()); +uint8 db = regs.a - tmp; +(db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +(regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag +((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow +} + +static void OpB2(void) // SBCA ABS +{ + tmp = regs.RdMem(FetchW()); uint8 as = regs.a; + regs.a = regs.a - tmp - (regs.cc&0x01); + (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void OpB4(void) // ANDA ABS +{ + regs.a &= regs.RdMem(FetchW()); + regs.cc &= 0xFD; // Cleregs.a oVerflow flag + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void OpB5(void) // BITA ABS +{ + tmp = regs.a & regs.RdMem(FetchW()); + regs.cc &= 0xFD; // Cleregs.a oVerflow flag + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void OpB6(void) // LDAA ABS +{ + regs.a = regs.RdMem(FetchW()); + regs.cc &= 0xFD; // CLV + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void OpB7(void) // STAA ABS +{ + regs.WrMem(FetchW(), regs.a); + regs.cc &= 0xFD; // CLV + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void OpB8(void) // EORA ABS +{ + regs.a ^= regs.RdMem(FetchW()); + regs.cc &= 0xFD; // CLV + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void OpB9(void) // ADCA ABS +{ + tmp = regs.RdMem(FetchW()); + addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01); + (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag + ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.a = addr; // Set accumulator + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag +} + +static void OpBA(void) // ORAA ABS +{ + regs.a |= regs.RdMem(FetchW()); + regs.cc &= 0xFD; // CLV + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void OpBB(void) // ADDA ABS +{ + tmp = regs.RdMem(FetchW()); + addr = (uint16)regs.a + (uint16)tmp; + (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag + ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo + regs.a = addr & 0xFF; // Set accumulator + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag +} + +static void OpBC(void) // CPX ABS +{ + addr = FetchW(); uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); + uint16 dw = regs.x - addr2; + (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.x < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((regs.x^addr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow +} + +static void OpBD(void) // JSR ABS +{ + addr = FetchW(); + + regs.s -= 2; + WrMemW(regs.s, regs.pc); + + regs.pc = addr; // Go to absolute address (Not indir) +} + +static void OpBE(void) // LDS ABS +{ + addr = FetchW(); + regs.s = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1); + regs.cc &= 0xFD; // CLV + (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void OpBF(void) // STS ABS +{ +addr = FetchW(); +regs.WrMem(addr, regs.s>>8); regs.WrMem(addr+1, regs.s&0xFF); +regs.cc &= 0xFD; // CLV +(regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void OpC0(void) // SUBB # +{ +tmp = regs.RdMem(regs.pc++); uint8 bs = regs.b; +regs.b -= tmp; +(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +(bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag +((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow +} + +static void OpC1(void) // CMPB # +{ +tmp = regs.RdMem(regs.pc++); +uint8 db = regs.b - tmp; +(regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag +((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow +(db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void OpC2(void) // SBCB # +{ + tmp = regs.RdMem(regs.pc++); uint8 bs = regs.b; + regs.b = regs.b - tmp - (regs.cc&0x01); + (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void OpC4(void) // ANDB # +{ +regs.b &= regs.RdMem(regs.pc++); +regs.cc &= 0xFD; // Cleregs.a oVerflow flag +(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void OpC5(void) // BITB # +{ + tmp = regs.b & regs.RdMem(regs.pc++); + regs.cc &= 0xF1; // CLV CLZ CLN + if (tmp == 0) regs.cc |= 0x04; // Set Zero flag + if (tmp&0x80) regs.cc |= 0x08; // Set Negative flag +} + +static void OpC6(void) // LDAB # +{ + regs.b = regs.RdMem(regs.pc++); + regs.cc &= 0xF1; // CLV CLZ CLN + if (regs.b == 0) regs.cc |= 0x04; // Set Zero flag + if (regs.b&0x80) regs.cc |= 0x08; // Set Negative flag +} + +static void OpC8(void) // EORB # +{ +regs.b ^= regs.RdMem(regs.pc++); +regs.cc &= 0xFD; // CLV +(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void OpC9(void) // ADCB # +{ + tmp = regs.RdMem(regs.pc++); + addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01); + (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag + ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo + regs.b = addr & 0xFF; // Set accumulator + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag +} + +static void OpCA(void) // ORAB # +{ +regs.b |= regs.RdMem(regs.pc++); +regs.cc &= 0xFD; // CLV +(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void OpCB(void) // ADDB # +{ + tmp = regs.RdMem(regs.pc++); addr = regs.b + tmp; + (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag + ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo + regs.b = addr & 0xFF; // Set accumulator + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag +} + +static void OpCE(void) // LDX # +{ + regs.x = FetchW(); + regs.cc &= 0xFD; // CLV + (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void OpD0(void) // SUBB ZP +{ + tmp = regs.RdMem(regs.RdMem(regs.pc++)); uint8 bs = regs.b; + regs.b -= tmp; + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow +} + +static void OpD1(void) // CMPB ZP +{ + tmp = regs.RdMem(regs.RdMem(regs.pc++)); + uint8 db = regs.b - tmp; + (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow +} + +static void OpD2(void) // SBCB ZP +{ + tmp = regs.RdMem(regs.RdMem(regs.pc++)); uint8 bs = regs.b; + regs.b = regs.b - tmp - (regs.cc&0x01); + (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void OpD4(void) // ANDB ZP +{ +regs.b &= regs.RdMem(regs.RdMem(regs.pc++)); +regs.cc &= 0xFD; // Clear oVerflow flag +(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void OpD5(void) // BITB ZP +{ +tmp = regs.b & regs.RdMem(regs.RdMem(regs.pc++)); +regs.cc &= 0xFD; // Clear oVerflow flag +(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void OpD6(void) // LDAB ZP +{ + regs.b = regs.RdMem(regs.RdMem(regs.pc++)); + regs.cc &= 0xFD; // CLV + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void OpD7(void) // STAB ZP +{ +regs.WrMem(regs.RdMem(regs.pc++), regs.b); +regs.cc &= 0xFD; // CLV +(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void OpD8(void) // EORB ZP +{ +regs.b ^= regs.RdMem(regs.RdMem(regs.pc++)); +regs.cc &= 0xFD; // CLV +(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void OpD9(void) // ADCB ZP +{ + tmp = regs.RdMem(regs.RdMem(regs.pc++)); + addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01); + (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag + ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.b = addr; // Set accumulator + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag +} + +static void OpDA(void) // ORAB ZP +{ +regs.b |= regs.RdMem(regs.RdMem(regs.pc++)); +regs.cc &= 0xFD; // CLV +(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void OpDB(void) // ADDB ZP +{ + tmp = regs.RdMem(regs.RdMem(regs.pc++)); + addr = (uint16)regs.b + (uint16)tmp; + (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag + ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.b = addr & 0xFF; // Set accumulator + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag +} + +static void OpDE(void) // LDX ZP +{ + addr = regs.RdMem(regs.pc++); + regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1); + regs.cc &= 0xFD; // CLV + (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void OpDF(void) // STX ZP +{ + addr = regs.RdMem(regs.pc++); + regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF); + regs.cc &= 0xFD; // CLV + (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void OpE0(void) // SUBB IDX +{ + tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 bs = regs.b; + regs.b -= tmp; + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow +} + +static void OpE1(void) // CMPB IDX +{ + tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); + uint8 db = regs.b - tmp; + (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow +} + +static void OpE2(void) // SBCB IDX +{ + tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 bs = regs.b; + regs.b = regs.b - tmp - (regs.cc&0x01); + (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void OpE4(void) // ANDB IDX +{ +regs.b &= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); +regs.cc &= 0xFD; // Clear oVerflow flag +(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void OpE5(void) // BITB IDX +{ +tmp = regs.b & regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); +regs.cc &= 0xFD; // Clear oVerflow flag +(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void OpE6(void) // LDB IDX +{ +regs.b = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); +regs.cc &= 0xFD; // CLV +(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void OpE7(void) // STB IDX +{ + regs.WrMem(DecodeIDX(regs.RdMem(regs.pc++)), regs.b); + regs.cc &= 0xF1; // CLV CLZ CLN + if (regs.b == 0) regs.cc |= 0x04; // Adjust Zero flag + if (regs.b&0x80) regs.cc |= 0x08; // Adjust Negative flag +} + +static void OpE8(void) // EORB IDX +{ +regs.b ^= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); +regs.cc &= 0xFD; // CLV +(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void OpE9(void) // ADCB IDX +{ + tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); + addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01); + (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag + ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.b = addr; // Set accumulator + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag +} + +static void OpEA(void) // ORB IDX +{ +regs.b |= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); +regs.cc &= 0xFD; // CLV +(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void OpEB(void) // ADDB IDX +{ + tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); + addr = (uint16)regs.b + (uint16)tmp; + (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag + ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.b = addr; // Set accumulator + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag +} + +static void OpEE(void) // LDX IDX +{ + addr = DecodeIDX(regs.RdMem(regs.pc++)); + regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1); + regs.cc &= 0xF1; // CLV CLZ CLN + if (regs.x == 0) regs.cc |= 0x04; // Set Zero flag + if (regs.x&0x8000) regs.cc |= 0x08; // Set Negative flag +} + +static void OpEF(void) // STX IDX +{ + addr = DecodeIDX(regs.RdMem(regs.pc++)); + regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF); + regs.cc &= 0xF1; // CLV CLZ CLN + if (regs.x == 0) regs.cc |= 0x04; // Set Zero flag + if (regs.x&0x8000) regs.cc |= 0x08; // Set Negative flag +} + +static void OpF0(void) // SUBB ABS +{ +tmp = regs.RdMem(FetchW()); uint8 bs = regs.b; +regs.b -= tmp; +(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +(bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag +((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow +} + +static void OpF1(void) // CMPB ABS +{ +tmp = regs.RdMem(FetchW()); +uint8 db = regs.b - tmp; +(db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +(regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag +((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow +} + +static void OpF2(void) // SBCB ABS +{ + tmp = regs.RdMem(FetchW()); uint8 bs = regs.b; + regs.b = regs.b - tmp - (regs.cc&0x01); + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow +} + +static void OpF4(void) // ANDB ABS +{ +regs.b &= regs.RdMem(FetchW()); +regs.cc &= 0xFD; // Clear oVerflow flag +(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void OpF5(void) // BITB ABS +{ +tmp = regs.b & regs.RdMem(FetchW()); +regs.cc &= 0xFD; // Clear oVerflow flag +(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void OpF6(void) // LDB ABS +{ +regs.b = regs.RdMem(FetchW()); +regs.cc &= 0xFD; // CLV +(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void OpF7(void) // STB ABS +{ +regs.WrMem(FetchW(), regs.b); +regs.cc &= 0xFD; // CLV +(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void OpF8(void) // EORB ABS +{ +regs.b ^= regs.RdMem(FetchW()); +regs.cc &= 0xFD; // CLV +(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void OpF9(void) // ADCB ABS +{ + tmp = regs.RdMem(FetchW()); + addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01); + (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag + ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo + regs.b = addr & 0xFF; // Set accumulator + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag +} + +static void OpFA(void) // ORB ABS +{ +regs.b |= regs.RdMem(FetchW()); +regs.cc &= 0xFD; // CLV +(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void OpFB(void) // ADDB ABS +{ + tmp = regs.RdMem(FetchW()); + addr = (uint16)regs.b + (uint16)tmp; + (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag + ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo + regs.b = addr & 0xFF; // Set accumulator + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag +} + +static void OpFE(void) // LDX ABS +{ +addr = FetchW(); +regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1); +regs.cc &= 0xFD; // CLV +(regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void OpFF(void) // STX ABS +{ +addr = FetchW(); +regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF); +regs.cc &= 0xFD; // CLV +(regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag +(regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +} + +static void Op__(void) +{ + regs.cpuFlags |= V6808_STATE_ILLEGAL_INST; +} + + +// +// Ok, the exec_op[] array is globally defined here basically to save +// a LOT of unnecessary typing. Sure it's ugly, but hey, it works! +// +void (* exec_op[256])() = { + Op__, Op01, Op__, Op__, Op__, Op__, Op06, Op07, Op08, Op09, Op0A, Op0B, Op0C, Op0D, Op0E, Op0F, + Op10, Op11, Op__, Op__, Op__, Op__, Op16, Op17, Op__, Op19, Op__, Op1B, Op__, Op__, Op__, Op__, + Op20, Op__, Op22, Op23, Op24, Op25, Op26, Op27, Op28, Op29, Op2A, Op2B, Op2C, Op2D, Op2E, Op2F, + Op30, Op31, Op32, Op33, Op34, Op35, Op36, Op37, Op__, Op39, Op__, Op3B, Op__, Op__, Op3E, Op3F, + Op40, Op__, Op__, Op43, Op44, Op__, Op46, Op47, Op48, Op49, Op4A, Op__, Op4C, Op4D, Op__, Op4F, + Op50, Op__, Op__, Op53, Op54, Op__, Op56, Op57, Op58, Op59, Op5A, Op__, Op5C, Op5D, Op__, Op5F, + Op60, Op__, Op__, Op63, Op64, Op__, Op66, Op67, Op68, Op69, Op6A, Op__, Op6C, Op6D, Op6E, Op6F, + Op70, Op__, Op__, Op73, Op74, Op__, Op76, Op77, Op78, Op79, Op7A, Op__, Op7C, Op7D, Op7E, Op7F, + Op80, Op81, Op82, Op__, Op84, Op85, Op86, Op__, Op88, Op89, Op8A, Op8B, Op8C, Op8D, Op8E, Op__, + Op90, Op91, Op92, Op__, Op94, Op95, Op96, Op97, Op98, Op99, Op9A, Op9B, Op9C, Op__, Op9E, Op9F, + OpA0, OpA1, OpA2, Op__, OpA4, OpA5, OpA6, OpA7, OpA8, OpA9, OpAA, OpAB, OpAC, OpAD, OpAE, OpAF, + OpB0, OpB1, OpB2, Op__, OpB4, OpB5, OpB6, OpB7, OpB8, OpB9, OpBA, OpBB, OpBC, OpBD, OpBE, OpBF, + OpC0, OpC1, OpC2, Op__, OpC4, OpC5, OpC6, Op__, OpC8, OpC9, OpCA, OpCB, Op__, Op__, OpCE, Op__, + OpD0, OpD1, OpD2, Op__, OpD4, OpD5, OpD6, OpD7, OpD8, OpD9, OpDA, OpDB, Op__, Op__, OpDE, OpDF, + OpE0, OpE1, OpE2, Op__, OpE4, OpE5, OpE6, OpE7, OpE8, OpE9, OpEA, OpEB, Op__, Op__, OpEE, OpEF, + OpF0, OpF1, OpF2, Op__, OpF4, OpF5, OpF6, OpF7, OpF8, OpF9, OpFA, OpFB, Op__, Op__, OpFE, OpFF +}; + + +// +// Internal "memcpy" (so we don't have to link with any external libraries!) +// +static void myMemcpy(void * dst, void * src, uint32 size) +{ + uint8 * d = (uint8 *)dst, * s = (uint8 *)src; + + for(uint32 i=0; icpuFlags &= ~V6808_ASSERT_LINE_RESET; + regs.cpuFlags &= ~V6808_ASSERT_LINE_RESET; + } + else if (regs.cpuFlags & V6808_ASSERT_LINE_NMI) + { + regs.WrMem(--regs.s, regs.pc & 0xFF); // Save all regs... + regs.WrMem(--regs.s, regs.pc >> 8); + regs.WrMem(--regs.s, regs.x & 0xFF); + regs.WrMem(--regs.s, regs.x >> 8); + regs.WrMem(--regs.s, regs.b); + regs.WrMem(--regs.s, regs.a); + regs.WrMem(--regs.s, regs.cc); + regs.pc = RdMemW(0xFFFC); // And do it! + + regs.clock += 0; // How many??? + context->cpuFlags &= ~V6808_ASSERT_LINE_NMI;// Reset the asserted line (NMI)... + regs.cpuFlags &= ~V6808_ASSERT_LINE_NMI; // Reset the asserted line (NMI)... + } + else if (regs.cpuFlags & V6808_ASSERT_LINE_IRQ) + { + if (!(regs.cc & FLAG_I)) // Process an interrupt (I=0)? + { + regs.WrMem(--regs.s, regs.pc & 0xFF); // Save all regs... + regs.WrMem(--regs.s, regs.pc >> 8); + regs.WrMem(--regs.s, regs.x & 0xFF); + regs.WrMem(--regs.s, regs.x >> 8); + regs.WrMem(--regs.s, regs.b); + regs.WrMem(--regs.s, regs.a); + regs.WrMem(--regs.s, regs.cc); + regs.pc = RdMemW(0xFFF8); // And do it! + + regs.clock += 0; // How many??? + context->cpuFlags &= ~V6808_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)... + regs.cpuFlags &= ~V6808_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)... + } + } + } + + myMemcpy(context, ®s, sizeof(V6808REGS)); +} + +// +// Get the clock of the currently executing CPU +// +uint32 GetCurrentV6808Clock(void) +{ + return regs.clock; +} diff --git a/src/v6808.h b/src/v6808.h new file mode 100755 index 0000000..a3d6d90 --- /dev/null +++ b/src/v6808.h @@ -0,0 +1,55 @@ +// +// Virtual 6808 Header file +// +// by James L. Hammons +// +// (c) 2004 Underground Software +// + +#ifndef __V6808_H__ +#define __V6808_H__ + +#include "types.h" + +// Useful defines + +#define FLAG_E 0x80 // ??? Entire ??? +#define FLAG_F 0x40 // ??? Fast IRQ ??? + +#define FLAG_H 0x20 // Half carry +#define FLAG_I 0x10 // IRQ +#define FLAG_N 0x08 // Negative +#define FLAG_Z 0x04 // Zero +#define FLAG_V 0x02 // oVerflow +#define FLAG_C 0x01 // Carry + +#define V6808_ASSERT_LINE_RESET 0x0001 // v6808 RESET line +#define V6808_ASSERT_LINE_IRQ 0x0002 // v6808 IRQ line +#define V6808_ASSERT_LINE_NMI 0x0004 // v6808 NMI line +#define V6808_STATE_SYNC 0x0008 // ??? v6808 SYNC line ??? +#define V6808_STATE_ILLEGAL_INST 0x0010 // Illegal instruction executed flag +//#define V6809_START_DEBUG_LOG 0x0020 // Debug log go (temporary!) + +// Useful structs + +struct V6808REGS +{ + uint16 pc; // 6808 PC register + uint16 x; // 6808 X index register + uint16 s; // 6808 System stack pointer + uint8 cc; // 6808 Condition Code register + uint8 a; // 6808 A register + uint8 b; // 6808 B register + uint32 clock; // 6808 clock +//uint32 _reserved;// uint8 (* Fetch)(uint16&); // Address of uint8 fetch routine + uint8 (* RdMem)(uint16); // Address of uint8 read routine + void (* WrMem)(uint16, uint8); // Address of uint8 write routine + uint32 cpuFlags; // v6808 IRQ/RESET flags +}; + +// Function prototypes + +void Execute6808(V6808REGS *, uint32); // Function to execute 6808 instructions +uint32 GetCurrentV6808Clock(void); // Get the clock of the currently executing CPU + +#endif // __V6808_H__ diff --git a/src/v6809.cpp b/src/v6809.cpp new file mode 100755 index 0000000..494b9f1 --- /dev/null +++ b/src/v6809.cpp @@ -0,0 +1,2989 @@ +// +// Virtual 6809 v1.3 +// +// by James L. Hammons +// (c) 1997, 2006 Underground Software +// +// JLH = James L. Hammons +// +// WHO WHEN WHAT +// --- ---------- ------------------------------------------------------------ +// JLH 06/15/2006 Added changelog ;-) +// JLH 06/15/2006 Scrubbed all BYTE, WORD & DWORD references from the code +// + +// Mebbe someday I'll get around to fixing the core to be more like V65C02... +// + +#include "v6809.h" + +#ifdef __DEBUG__ +#include "dis6809.h" // Temporary... +#include "log.h" // Temporary... +#endif + +// Private global variables + +static V6809REGS regs; +static uint16 addr; // Temporary variables common to all funcs... +static uint8 tmp; + +// Private function prototypes + +static int SignedB(uint8); // Return signed byte from unsigned +static int SignedW(uint16); // Return signed word from unsigned +static uint16 FetchW(void); +static uint16 RdMemW(uint16 addr); +static void WrMemW(uint16 addr, uint16 w); +static uint16 ReadEXG(uint8); // Read TFR/EXG post byte +static void WriteEXG(uint8, uint16); // Set TFR/EXG data +static uint16 DecodeReg(uint8); // Decode register data +static uint16 DecodeIDX(uint8); // Decode IDX data + +//static void (* exec_op1[256])(); +//static void (* exec_op2[256])(); +#if 1 + +// This is here because of the stupid forward declaration rule that C++ forces (the C++ compiler +// isn't smart enough to know that the identifiers in the arrays are declared later, it doesn't +// even *try* to see if they're there). + +#define FD(x) static void Op##x(); // FD -> "Forward Declaration" +#define FE(x) static void Op10##x(); +#define FF(x) static void Op11##x(); + +FD(00) FD(03) FD(04) FD(06) FD(07) FD(08) FD(09) FD(0A) FD(0C) FD(0D) FD(0E) FD(0F) FD(10) FD(11) +FD(12) FD(13) FD(16) FD(17) FD(19) FD(1A) FD(1C) FD(1D) FD(1E) FD(1F) FD(20) FD(21) FD(22) FD(23) +FD(24) FD(25) FD(26) FD(27) FD(28) FD(29) FD(2A) FD(2B) FD(2C) FD(2D) FD(2E) FD(2F) FD(30) FD(31) +FD(32) FD(33) FD(34) FD(35) FD(36) FD(37) FD(39) FD(3A) FD(3B) FD(3C) FD(3D) FD(3E) FD(3F) FD(40) +FD(43) FD(44) FD(46) FD(47) FD(48) FD(49) FD(4A) FD(4C) FD(4D) FD(4F) FD(50) FD(53) FD(54) FD(56) +FD(57) FD(58) FD(59) FD(5A) FD(5C) FD(5D) FD(5F) FD(60) FD(63) FD(64) FD(66) FD(67) FD(68) FD(69) +FD(6A) FD(6C) FD(6D) FD(6E) FD(6F) FD(70) FD(73) FD(74) FD(76) FD(77) FD(78) FD(79) FD(7A) FD(7C) +FD(7D) FD(7E) FD(7F) FD(80) FD(81) FD(82) FD(83) FD(84) FD(85) FD(86) FD(88) FD(89) FD(8A) FD(8B) +FD(8C) FD(8D) FD(8E) FD(90) FD(91) FD(92) FD(93) FD(94) FD(95) FD(96) FD(97) FD(98) FD(99) FD(9A) +FD(9B) FD(9C) FD(9D) FD(9E) FD(9F) FD(A0) FD(A1) FD(A2) FD(A3) FD(A4) FD(A5) FD(A6) FD(A7) FD(A8) +FD(A9) FD(AA) FD(AB) FD(AC) FD(AD) FD(AE) FD(AF) FD(B0) FD(B1) FD(B2) FD(B3) FD(B4) FD(B5) FD(B6) +FD(B7) FD(B8) FD(B9) FD(BA) FD(BB) FD(BC) FD(BD) FD(BE) FD(BF) FD(C0) FD(C1) FD(C2) FD(C3) FD(C4) +FD(C5) FD(C6) FD(C8) FD(C9) FD(CA) FD(CB) FD(CC) FD(CE) FD(D0) FD(D1) FD(D2) FD(D3) FD(D4) FD(D5) +FD(D6) FD(D7) FD(D8) FD(D9) FD(DA) FD(DB) FD(DC) FD(DD) FD(DE) FD(DF) FD(E0) FD(E1) FD(E2) FD(E3) +FD(E4) FD(E5) FD(E6) FD(E7) FD(E8) FD(E9) FD(EA) FD(EB) FD(EC) FD(ED) FD(EE) FD(EF) FD(F0) FD(F1) +FD(F2) FD(F3) FD(F4) FD(F5) FD(F6) FD(F7) FD(F8) FD(F9) FD(FA) FD(FB) FD(FC) FD(FD) FD(FE) FD(FF) +FD(__) FD(01) + +FE(21) FE(22) FE(23) FE(24) FE(25) FE(26) FE(27) FE(28) FE(29) FE(2A) FE(2B) FE(2C) FE(2D) FE(2E) +FE(2F) FE(3F) FE(83) FE(8C) FE(8E) FE(93) FE(9C) FE(9E) FE(9F) FE(A3) FE(AC) FE(AE) FE(AF) FE(B3) +FE(BC) FE(BE) FE(BF) FE(CE) FE(DE) FE(DF) FE(EE) FE(EF) FE(FE) FE(FF) + +FF(3F) FF(83) FF(8C) FF(93) FF(9C) FF(A3) FF(AC) FF(B3) FF(BC) + +#undef FD +#undef FE +#undef FF + +#endif + +// We can move these down and do away with the forward declarations... !!! FIX !!! +// Actually, we can't because these are used in a couple of the opcode functions. +// Have to think about how to fix that... + +// +// Function arrays +// + +// Array of page zero opcode functions... +static void (* exec_op0[256])() = { + Op00, Op01, Op__, Op03, Op04, Op__, Op06, Op07, Op08, Op09, Op0A, Op__, Op0C, Op0D, Op0E, Op0F, + Op10, Op11, Op12, Op13, Op__, Op__, Op16, Op17, Op__, Op19, Op1A, Op__, Op1C, Op1D, Op1E, Op1F, + Op20, Op21, Op22, Op23, Op24, Op25, Op26, Op27, Op28, Op29, Op2A, Op2B, Op2C, Op2D, Op2E, Op2F, + Op30, Op31, Op32, Op33, Op34, Op35, Op36, Op37, Op__, Op39, Op3A, Op3B, Op3C, Op3D, Op3E, Op3F, + Op40, Op__, Op__, Op43, Op44, Op__, Op46, Op47, Op48, Op49, Op4A, Op__, Op4C, Op4D, Op__, Op4F, + Op50, Op__, Op__, Op53, Op54, Op__, Op56, Op57, Op58, Op59, Op5A, Op__, Op5C, Op5D, Op__, Op5F, + Op60, Op__, Op__, Op63, Op64, Op__, Op66, Op67, Op68, Op69, Op6A, Op__, Op6C, Op6D, Op6E, Op6F, + Op70, Op__, Op__, Op73, Op74, Op__, Op76, Op77, Op78, Op79, Op7A, Op__, Op7C, Op7D, Op7E, Op7F, + Op80, Op81, Op82, Op83, Op84, Op85, Op86, Op__, Op88, Op89, Op8A, Op8B, Op8C, Op8D, Op8E, Op__, + Op90, Op91, Op92, Op93, Op94, Op95, Op96, Op97, Op98, Op99, Op9A, Op9B, Op9C, Op9D, Op9E, Op9F, + OpA0, OpA1, OpA2, OpA3, OpA4, OpA5, OpA6, OpA7, OpA8, OpA9, OpAA, OpAB, OpAC, OpAD, OpAE, OpAF, + OpB0, OpB1, OpB2, OpB3, OpB4, OpB5, OpB6, OpB7, OpB8, OpB9, OpBA, OpBB, OpBC, OpBD, OpBE, OpBF, + OpC0, OpC1, OpC2, OpC3, OpC4, OpC5, OpC6, Op__, OpC8, OpC9, OpCA, OpCB, OpCC, Op__, OpCE, Op__, + OpD0, OpD1, OpD2, OpD3, OpD4, OpD5, OpD6, OpD7, OpD8, OpD9, OpDA, OpDB, OpDC, OpDD, OpDE, OpDF, + OpE0, OpE1, OpE2, OpE3, OpE4, OpE5, OpE6, OpE7, OpE8, OpE9, OpEA, OpEB, OpEC, OpED, OpEE, OpEF, + OpF0, OpF1, OpF2, OpF3, OpF4, OpF5, OpF6, OpF7, OpF8, OpF9, OpFA, OpFB, OpFC, OpFD, OpFE, OpFF +}; + +// Array of page one opcode functions... +static void (* exec_op1[256])() = { + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op1021, Op1022, Op1023, Op1024, Op1025, Op1026, Op1027, Op1028, Op1029, Op102A, Op102B, Op102C, Op102D, Op102E, Op102F, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op103F, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op1083, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op108C, Op__, Op108E, Op__, + Op__, Op__, Op__, Op1093, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op109C, Op__, Op109E, Op109F, + Op__, Op__, Op__, Op10A3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10AC, Op__, Op10AE, Op10AF, + Op__, Op__, Op__, Op10B3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10BC, Op__, Op10BE, Op10BF, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10CE, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10DE, Op10DF, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10EE, Op10EF, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10FE, Op10FF +}; + +// Array of page two opcode functions... +static void (* exec_op2[256])() = { + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op113F, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op1183, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op118C, Op__, Op__, Op__, + Op__, Op__, Op__, Op1193, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op119C, Op__, Op__, Op__, + Op__, Op__, Op__, Op11A3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op11AC, Op__, Op__, Op__, + Op__, Op__, Op__, Op11B3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op11BC, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__ +}; + + +// +// Fetch a word out of 6809 memory (little endian format) +// This is a leftover from when fetches were separated from garden variety reads... +// +static uint16 FetchW() +{ + uint16 w = RdMemW(regs.pc); + regs.pc += 2; + return w; +} +// +// Fetch word function +// +/*uint16 FetchW(void) +{ + return (uint16)(regs.RdMem(regs.pc++) << 8) | regs.RdMem(regs.pc++); +}*/ + +// +// Read word from memory function +// +uint16 RdMemW(uint16 addr) +{ + return (uint16)(regs.RdMem(addr) << 8) | regs.RdMem(addr + 1); +} + +// +// Write word to memory function +// +void WrMemW(uint16 addr, uint16 w) +{ + regs.WrMem(addr + 0, w >> 8); + regs.WrMem(addr + 1, w & 0xFF); +} + +// +// return signed byte from unsigned +// +int SignedB(uint8 b) +{ + return (b & 0x80 ? b - 256 : b); +} + +// +// return signed word from unsigned +// +int SignedW(uint16 w) +{ + return (w & 0x8000 ? w - 65536 : w); +} + +// +// Function to read TFR/EXG post byte +// +uint16 ReadEXG(uint8 code) +{ + uint16 retval; + + switch (code) + { + case 0: + retval = (regs.a << 8) | regs.b; + break; + case 1: + retval = regs.x; + break; + case 2: + retval = regs.y; + break; + case 3: + retval = regs.u; + break; + case 4: + retval = regs.s; + break; + case 5: + retval = regs.pc; + break; + case 8: + retval = regs.a; + break; + case 9: + retval = regs.b; + break; + case 10: + retval = regs.cc; + break; + case 11: + retval = regs.dp; + break; + default: + retval = 0xFF; + } + + return retval; +} + +// +// Function to set TFR/EXG data +// +void WriteEXG(uint8 code, uint16 data) +{ + switch (code) + { + case 0: + regs.a = data >> 8, regs.b = data & 0xFF; break; + case 1: + regs.x = data; break; + case 2: + regs.y = data; break; + case 3: + regs.u = data; break; + case 4: + regs.s = data; break; + case 5: + regs.pc = data; break; + case 8: + regs.a = data & 0xFF; break; + case 9: + regs.b = data & 0xFF; break; + case 10: + regs.cc = data & 0xFF; break; + case 11: + regs.dp = data & 0xFF; break; + } +} + +// +// Function to decode register data +// +uint16 DecodeReg(uint8 reg) +{ + uint16 retval; + + switch (reg) + { + case 0: + retval = regs.x; break; + case 1: + retval = regs.y; break; + case 2: + retval = regs.u; break; + case 3: + retval = regs.s; break; + } + + return retval; +} + +// +// Function to decode IDX data +// +uint16 DecodeIDX(uint8 code) +{ + uint16 addr, woff; + uint8 reg = (code & 0x60) >> 5, idxind = (code & 0x10) >> 4, lo_nyb = code & 0x0F; + + if (!(code & 0x80)) // Hi bit unset? Then decode 4 bit offset + addr = DecodeReg(reg) + (idxind ? lo_nyb - 16 : lo_nyb); + else + { + if (idxind) + { + switch (lo_nyb) + { + case 1: + woff = DecodeReg(reg); + addr = RdMemW(woff); + switch (reg) + { + case 0: regs.x += 2; break; + case 1: regs.y += 2; break; + case 2: regs.u += 2; break; + case 3: regs.s += 2; break; + } + break; + case 3: + switch (reg) + { + case 0: regs.x -= 2; break; + case 1: regs.y -= 2; break; + case 2: regs.u -= 2; break; + case 3: regs.s -= 2; break; + } + woff = DecodeReg(reg); + addr = RdMemW(woff); + break; + case 4: + woff = DecodeReg(reg); + addr = RdMemW(woff); + break; + case 5: + woff = DecodeReg(reg) + SignedB(regs.b); + addr = RdMemW(woff); + break; + case 6: + woff = DecodeReg(reg) + SignedB(regs.a); + addr = RdMemW(woff); + break; + case 8: + woff = DecodeReg(reg) + SignedB(regs.RdMem(regs.pc++)); + addr = RdMemW(woff); + break; + case 9: + woff = DecodeReg(reg) + SignedW(FetchW()); + addr = RdMemW(woff); + break; + case 11: + woff = DecodeReg(reg) + SignedW((regs.a << 8) | regs.b); + addr = RdMemW(woff); + break; + case 12: + woff = regs.pc + SignedB(regs.RdMem(regs.pc++)); + addr = RdMemW(woff); + break; + case 13: + woff = regs.pc + SignedW(FetchW()); + addr = RdMemW(woff); + break; + case 15: + woff = FetchW(); + addr = RdMemW(woff); + break; + } + } + else + { + switch (lo_nyb) + { + case 0: + addr = DecodeReg(reg); + switch (reg) + { + case 0: regs.x++; break; + case 1: regs.y++; break; + case 2: regs.u++; break; + case 3: regs.s++; break; + } + break; + case 1: + addr = DecodeReg(reg); + switch (reg) + { + case 0: regs.x += 2; break; + case 1: regs.y += 2; break; + case 2: regs.u += 2; break; + case 3: regs.s += 2; break; + } + break; + case 2: { switch(reg) + { + case 0: regs.x--; break; + case 1: regs.y--; break; + case 2: regs.u--; break; + case 3: regs.s--; break; + } + addr = DecodeReg(reg); break; } + case 3: { switch(reg) + { + case 0: regs.x--; regs.x--; break; + case 1: regs.y--; regs.y--; break; + case 2: regs.u--; regs.u--; break; + case 3: regs.s--; regs.s--; break; + } + addr = DecodeReg(reg); break; } + case 4: { addr = DecodeReg(reg); break; } + case 5: { addr = DecodeReg(reg) + SignedB(regs.b); break; } + case 6: { addr = DecodeReg(reg) + SignedB(regs.a); break; } + case 8: { addr = DecodeReg(reg) + SignedB(regs.RdMem(regs.pc++)); break; } + case 9: { addr = DecodeReg(reg) + SignedW(FetchW()); break; } + case 11: { addr = DecodeReg(reg) + SignedW((regs.a << 8) | regs.b); break; } + case 12: { addr = regs.pc + SignedB(regs.RdMem(regs.pc++)); break; } + case 13: { addr = regs.pc + SignedW(FetchW()); break; } + } + } + } + + return addr; +} + +// +// Page zero instructions... +// + +static void Op00(void) // NEG DP +{ + addr = (regs.dp << 8) | regs.RdMem(regs.pc++); + tmp = 256 - regs.RdMem(addr); + regs.WrMem(addr, tmp); + + (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp & 0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (tmp > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry + + regs.clock += 6; +} + +static void Op01(void) // NEG DP (Undocumented) +{ + Op00(); +} + +static void Op03(void) // COM DP +{ + addr = (regs.dp << 8) | regs.RdMem(regs.pc++); + tmp = 0xFF ^ regs.RdMem(addr); + regs.WrMem(addr, tmp); + + regs.cc &= 0xFD; regs.cc |= 0x01; // CLV SEC + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + + regs.clock += 6; +} + +static void Op04(void) // LSR DP +{ + addr = (regs.dp<<8) | regs.RdMem(regs.pc++); + tmp = regs.RdMem(addr); + (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry + tmp >>= 1; regs.WrMem(addr, tmp); + regs.cc &= 0xF7; // CLN + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + regs.clock += 6; +} +static void Op06(void) // ROR DP +{ + addr = (regs.dp<<8) | regs.RdMem(regs.pc++); uint8 tmp2 = regs.RdMem(addr); + tmp = (tmp2>>1) + (regs.cc&0x01)*128; + regs.WrMem(addr, tmp); + (tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; +} +static void Op07(void) // ASR DP +{ + addr = (regs.dp<<8) | regs.RdMem(regs.pc++); tmp = regs.RdMem(addr); + (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry + tmp >>= 1; + if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set + regs.WrMem(addr, tmp); + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; +} +static void Op08(void) // LSL DP +{ + addr = (regs.dp<<8) | regs.RdMem(regs.pc++); // NEEDS OVERFLOW ADJUSTMENT + tmp = regs.RdMem(addr); + (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry + tmp <<= 1; + regs.WrMem(addr, tmp); + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; +} +static void Op09(void) // ROL DP +{ + addr = (regs.dp<<8) | regs.RdMem(regs.pc++); uint8 tmp2 = regs.RdMem(addr); + tmp = (tmp2<<1) + (regs.cc&0x01); + regs.WrMem(addr, tmp); + (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry + ((tmp2&0x80)^((tmp2<<1)&0x80) ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; +} +static void Op0A(void) // DEC DP +{ + addr = (regs.dp<<8) | regs.RdMem(regs.pc++); + tmp = regs.RdMem(addr) - 1; + regs.WrMem(addr, tmp); + (tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; +} +static void Op0C(void) // INC DP +{ + addr = (regs.dp<<8) | regs.RdMem(regs.pc++); + tmp = regs.RdMem(addr) + 1; + regs.WrMem(addr, tmp); + (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; +} +static void Op0D(void) // TST DP +{ + tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); + regs.cc &= 0xFD; // CLV + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; +} +static void Op0E(void) // JMP DP +{ + regs.pc = (regs.dp<<8) | regs.RdMem(regs.pc++); + regs.clock += 3; +} +static void Op0F(void) // CLR DP +{ + regs.WrMem((regs.dp<<8)|regs.RdMem(regs.pc++), 0); + regs.cc &= 0xF0; regs.cc |= 0x04; // CLN, SEZ, CLV, CLC + regs.clock += 6; +} + +static void Op10(void) // Page 1 opcode +{ + exec_op1[regs.RdMem(regs.pc++)](); +} + +static void Op11(void) // Page 2 opcode +{ + exec_op2[regs.RdMem(regs.pc++)](); +} + +static void Op12(void) // NOP +{ + regs.clock += 2; +} + +static void Op13(void) // SYNC +{ + regs.clock += 2; +} +static void Op16(void) // LBRA +{ + regs.pc += SignedW(FetchW()); + regs.clock += 5; +} +static void Op17(void) // LBSR +{ + addr = FetchW(); + regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8); + regs.pc += SignedW(addr); + regs.clock += 9; +} +static void Op19(void) // DAA +{ + if ((regs.cc&0x20) || ((regs.a&0x0F) > 0x09)) // H set or lo nyb too big? + { + regs.a += 0x06; regs.cc |= 0x20; // Then adjust & set half carry + } + if ((regs.cc&0x01) || (regs.a > 0x9F)) // C set or hi nyb too big? + { + regs.a += 0x60; regs.cc |= 0x01; // Then adjust & set carry + } + regs.cc &= 0xF1; // CL NZV + if (regs.a == 0) regs.cc |= 0x04; // Adjust Zero flag + if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag + regs.clock += 2; +} + +static void Op1A(void) // ORCC # +{ + regs.cc |= regs.RdMem(regs.pc++); + + regs.clock += 3; +} + +static void Op1C(void) // ANDCC # +{ + regs.cc &= regs.RdMem(regs.pc++); + + regs.clock += 3; +} + +static void Op1D(void) // SEX +{ + (regs.b & 0x80 ? regs.a = 0xFF : regs.a = 0x00); + + ((regs.a | regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a & 0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + + regs.clock += 2; +} + +static void Op1E(void) // EXG +{ + tmp = regs.RdMem(regs.pc++); + addr = ReadEXG(tmp >> 4); + WriteEXG(tmp >> 4, ReadEXG(tmp & 0xF)); + WriteEXG(tmp & 0xF, addr); + + regs.clock += 8; +} + +static void Op1F(void) // TFR +{ + tmp = regs.RdMem(regs.pc++); + WriteEXG(tmp&0xF, ReadEXG(tmp>>4)); + regs.clock += 7; +} +static void Op20(void) // BRA +{ + regs.pc += SignedB(regs.RdMem(regs.pc++)); // Branch always + regs.clock += 3; +} +static void Op21(void) // BRN +{ + regs.RdMem(regs.pc++); + regs.clock += 3; +} +static void Op22(void) // BHI +{ + tmp = regs.RdMem(regs.pc++); + if (!(regs.cc&0x05)) regs.pc += SignedB(tmp); + regs.clock += 3; +} +static void Op23(void) // BLS +{ + tmp = regs.RdMem(regs.pc++); + if (regs.cc&0x05) regs.pc += SignedB(tmp); + regs.clock += 3; +} +static void Op24(void) // BCC (BHS) +{ + tmp = regs.RdMem(regs.pc++); + if (!(regs.cc&0x01)) regs.pc += SignedB(tmp); + regs.clock += 3; +} +static void Op25(void) // BCS (BLO) +{ + tmp = regs.RdMem(regs.pc++); + if (regs.cc&0x01) regs.pc += SignedB(tmp); + regs.clock += 3; +} +static void Op26(void) // BNE +{ + tmp = regs.RdMem(regs.pc++); + if (!(regs.cc&0x04)) regs.pc += SignedB(tmp); + regs.clock += 3; +} +static void Op27(void) // BEQ +{ + tmp = regs.RdMem(regs.pc++); + if (regs.cc&0x04) regs.pc += SignedB(tmp); + regs.clock += 3; +} +static void Op28(void) // BVC +{ + tmp = regs.RdMem(regs.pc++); + if (!(regs.cc&0x02)) regs.pc += SignedB(tmp); + regs.clock += 3; +} +static void Op29(void) // BVS +{ + tmp = regs.RdMem(regs.pc++); + if (regs.cc&0x02) regs.pc += SignedB(tmp); + regs.clock += 3; +} +static void Op2A(void) // BPL +{ + tmp = regs.RdMem(regs.pc++); + if (!(regs.cc&0x08)) regs.pc += SignedB(tmp); + regs.clock += 3; +} +static void Op2B(void) // BMI +{ + tmp = regs.RdMem(regs.pc++); + if (regs.cc&0x08) regs.pc += SignedB(tmp); + regs.clock += 3; +} +static void Op2C(void) // BGE +{ + tmp = regs.RdMem(regs.pc++); + if (!(((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))) regs.pc += SignedB(tmp); + regs.clock += 3; +} +static void Op2D(void) // BLT +{ + tmp = regs.RdMem(regs.pc++); + if (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02)) regs.pc += SignedB(tmp); + regs.clock += 3; +} +static void Op2E(void) // BGT +{ + tmp = regs.RdMem(regs.pc++); + if (!((regs.cc&0x04) | (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02)))) regs.pc += SignedB(tmp); + regs.clock += 3; +} +static void Op2F(void) // BLE +{ + tmp = regs.RdMem(regs.pc++); + if ((regs.cc&0x04) | (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))) regs.pc += SignedB(tmp); + regs.clock += 3; +} +static void Op30(void) // LEAX +{ + regs.x = DecodeIDX(regs.RdMem(regs.pc++)); + (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + regs.clock += 4; +} +static void Op31(void) // LEAY +{ + regs.y = DecodeIDX(regs.RdMem(regs.pc++)); + (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + regs.clock += 4; +} +static void Op32(void) // LEAS +{ + regs.s = DecodeIDX(regs.RdMem(regs.pc++)); + (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + regs.clock += 4; +} +static void Op33(void) // LEAU +{ + regs.u = DecodeIDX(regs.RdMem(regs.pc++)); + (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + regs.clock += 4; +} +static void Op34(void) // PSHS +{ + tmp = regs.RdMem(regs.pc++); + if (tmp&0x80) { regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8); } + if (tmp&0x40) { regs.WrMem(--regs.s, regs.u&0xFF); regs.WrMem(--regs.s, regs.u>>8); } + if (tmp&0x20) { regs.WrMem(--regs.s, regs.y&0xFF); regs.WrMem(--regs.s, regs.y>>8); } + if (tmp&0x10) { regs.WrMem(--regs.s, regs.x&0xFF); regs.WrMem(--regs.s, regs.x>>8); } + if (tmp&0x08) regs.WrMem(--regs.s, regs.dp); + if (tmp&0x04) regs.WrMem(--regs.s, regs.b); + if (tmp&0x02) regs.WrMem(--regs.s, regs.a); + if (tmp&0x01) regs.WrMem(--regs.s, regs.cc); + regs.clock += 5; +} +static void Op35(void) // PULS +{ + tmp = regs.RdMem(regs.pc++); + if (tmp&0x01) regs.cc = regs.RdMem(regs.s++); + if (tmp&0x02) regs.a = regs.RdMem(regs.s++); + if (tmp&0x04) regs.b = regs.RdMem(regs.s++); + if (tmp&0x08) regs.dp = regs.RdMem(regs.s++); + if (tmp&0x10) regs.x = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++); + if (tmp&0x20) regs.y = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++); + if (tmp&0x40) regs.u = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++); + if (tmp&0x80) regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++); + regs.clock += 5; +} + +static void Op36(void) // PSHU +{ + tmp = regs.RdMem(regs.pc++); + + if (tmp & 0x80) { regs.WrMem(--regs.u, regs.pc & 0xFF); regs.WrMem(--regs.u, regs.pc >> 8); } + if (tmp & 0x40) { regs.WrMem(--regs.u, regs.s & 0xFF); regs.WrMem(--regs.u, regs.s >> 8); } + if (tmp & 0x20) { regs.WrMem(--regs.u, regs.y & 0xFF); regs.WrMem(--regs.u, regs.y >> 8); } + if (tmp & 0x10) { regs.WrMem(--regs.u, regs.x & 0xFF); regs.WrMem(--regs.u, regs.x >> 8); } + if (tmp & 0x08) regs.WrMem(--regs.u, regs.dp); + if (tmp & 0x04) regs.WrMem(--regs.u, regs.b); + if (tmp & 0x02) regs.WrMem(--regs.u, regs.a); + if (tmp & 0x01) regs.WrMem(--regs.u, regs.cc); + + regs.clock += 5; +} + +static void Op37(void) // PULU +{ + tmp = regs.RdMem(regs.pc++); + if (tmp&0x01) regs.cc = regs.RdMem(regs.u++); + if (tmp&0x02) regs.a = regs.RdMem(regs.u++); + if (tmp&0x04) regs.b = regs.RdMem(regs.u++); + if (tmp&0x08) regs.dp = regs.RdMem(regs.u++); + if (tmp&0x10) regs.x = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++); + if (tmp&0x20) regs.y = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++); + if (tmp&0x40) regs.s = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++); + if (tmp&0x80) regs.pc = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++); + regs.clock += 5; +} +static void Op39(void) // RTS +{ + regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++); + regs.clock += 5; +} +static void Op3A(void) // ABX +{ + regs.x += regs.b; + regs.clock += 3; +} +static void Op3B(void) // RTI +{ + regs.cc = regs.RdMem(regs.s++); + if (regs.cc&0x80) // If E flag set, pull all regs + { + regs.a = regs.RdMem(regs.s++); regs.b = regs.RdMem(regs.s++); regs.dp = regs.RdMem(regs.s++); + regs.x = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++); + regs.y = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++); + regs.u = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++); + regs.clock += 15; + } + else + { + regs.clock += 6; + } + regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++); +} +static void Op3C(void) // CWAI +{ + regs.cc &= regs.RdMem(regs.pc++); regs.cc |= 0x80; + regs.clock += 1000000; // Force interrupt +} +static void Op3D(void) // MUL +{ + addr = regs.a * regs.b; regs.a = addr>>8; regs.b = addr&0xFF; + (addr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero + (regs.b&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry + regs.clock += 11; +} +static void Op3E(void) // RESET +{ +} +static void Op3F(void) // SWI +{ +} +static void Op40(void) // NEGA +{ + regs.a = 256 - regs.a; + (regs.a > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry + (regs.a == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; +} +static void Op43(void) // COMA +{ + regs.a ^= 0xFF; + regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; +} +static void Op44(void) // LSRA +{ + (regs.a&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry + regs.a >>= 1; + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; +} +static void Op46(void) // RORA +{ + tmp = regs.a; regs.a = (tmp>>1) + (regs.cc&0x01)*128; + (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; +} +static void Op47(void) // ASRA +{ + (regs.a&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry + regs.a >>= 1; // Do the shift + if (regs.a&0x40) regs.a |= 0x80; // Set neg if it was set + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; +} +static void Op48(void) // LSLA [Keep checking from here...] +{ + (regs.a&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry + regs.a <<= 1; + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; +} +static void Op49(void) // ROLA +{ + tmp = regs.a; regs.a = (tmp<<1) + (regs.cc&0x01); + (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; +} +static void Op4A(void) // DECA +{ + regs.a--; + (regs.a == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; +} +static void Op4C(void) // INCA + { + regs.a++; + (regs.a == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; + } +static void Op4D(void) // TSTA + { + regs.cc &= 0xFD; // Clear oVerflow flag + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; + } +static void Op4F(void) // CLRA +{ + regs.a = 0; + regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC + regs.clock += 2; +} +static void Op50(void) // NEGB + { + regs.b = 256 - regs.b; +// ((regs.b^tmp)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Adjust H carry + (regs.b == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.b > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry + regs.clock += 2; + } +static void Op53(void) // COMB + { + regs.b ^= 0xFF; + regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; + } +static void Op54(void) // LSRB + { + (regs.b&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry + regs.b >>= 1; + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; + } +static void Op56(void) // RORB + { + tmp = regs.b; regs.b = (regs.b >> 1) + (regs.cc&0x01)*128; + (tmp&0x01 ? regs.cc |=0x01 : regs.cc &= 0xFE); // Shift bit into carry + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; + } +static void Op57(void) // ASRB + { + (regs.b&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry + regs.b >>= 1; // Do the shift + if (regs.b&0x40) regs.b |= 0x80; // Set neg if it was set + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; + } +static void Op58(void) // LSLB + { + (regs.b&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry + regs.b <<= 1; + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; + } +static void Op59(void) // ROLB +{ + tmp = regs.b; + regs.b = (tmp<<1) + (regs.cc&0x01); + (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; +} +static void Op5A(void) // DECB + { + regs.b--; + (regs.b == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; + } +static void Op5C(void) // INCB + { + regs.b++; + (regs.b == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; + } +static void Op5D(void) // TSTB + { + regs.cc &= 0xFD; // Clear oVerflow flag + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; + } +static void Op5F(void) // CLRB + { + regs.b = 0; + regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC + regs.clock += 2; + } +static void Op60(void) // NEG IDX + { + addr = DecodeIDX(regs.RdMem(regs.pc++)); + tmp = regs.RdMem(addr); uint8 res = 256 - tmp; + regs.WrMem(addr, res); +// ((res^tmp)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Adjust H carry + (res == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (res == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (res&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (res > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry + regs.clock += 6; + } +static void Op63(void) // COM IDX + { + addr = DecodeIDX(regs.RdMem(regs.pc++)); + tmp = regs.RdMem(addr) ^ 0xFF; + regs.WrMem(addr, tmp); + regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; + } +static void Op64(void) // LSR IDX + { + addr = DecodeIDX(regs.RdMem(regs.pc++)); + tmp = regs.RdMem(addr); + (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry + tmp >>= 1; regs.WrMem(addr, tmp); + regs.cc &= 0xF7; // CLN + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + regs.clock += 6; + } +static void Op66(void) // ROR IDX + { + addr = DecodeIDX(regs.RdMem(regs.pc++)); + tmp = regs.RdMem(addr); uint8 tmp2 = tmp; + tmp = (tmp >> 1) + (regs.cc&0x01)*128; + regs.WrMem(addr, tmp); + (tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; + } +static void Op67(void) // ASR IDX + { + addr = DecodeIDX(regs.RdMem(regs.pc++)); + tmp = regs.RdMem(addr); + (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry + tmp >>= 1; + if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set + regs.WrMem(addr, tmp); + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; + } +static void Op68(void) // LSL IDX + { + addr = DecodeIDX(regs.RdMem(regs.pc++)); + tmp = regs.RdMem(addr); + (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry + tmp <<= 1; + regs.WrMem(addr, tmp); + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; + } +static void Op69(void) // ROL IDX +{ + uint8 tmp2 = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); + tmp = (tmp2<<1) + (regs.cc&0x01); + regs.WrMem(addr, tmp); + (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; +} +static void Op6A(void) // DEC IDX + { + uint8 tmp; uint16 addr; + addr = DecodeIDX(regs.RdMem(regs.pc++)); + tmp = regs.RdMem(addr) - 1; + regs.WrMem(addr, tmp); + (tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; + } +static void Op6C(void) // INC IDX + { + addr = DecodeIDX(regs.RdMem(regs.pc++)); + tmp = regs.RdMem(addr) + 1; + regs.WrMem(addr, tmp); + (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; + } +static void Op6D(void) // TST IDX + { + tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; + } +static void Op6E(void) // JMP IDX +{ + regs.pc = DecodeIDX(regs.RdMem(regs.pc++)); + regs.clock += 3; +} +static void Op6F(void) // CLR IDX +{ + addr = DecodeIDX(regs.RdMem(regs.pc++)); + regs.WrMem(addr, 0); + regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC + regs.clock += 6; +} +static void Op70(void) // NEG ABS + { + addr = FetchW(); + tmp = regs.RdMem(addr); uint8 res = 256 - tmp; + regs.WrMem(addr, res); + (res == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (res == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (res&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (res > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry + regs.clock += 7; + } +static void Op73(void) // COM ABS + { + addr = FetchW(); + tmp = regs.RdMem(addr) ^ 0xFF; + regs.WrMem(addr, tmp); + regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 7; + } +static void Op74(void) // LSR ABS + { + addr = FetchW(); + tmp = regs.RdMem(addr); + (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into carry + tmp >>= 1; regs.WrMem(addr, tmp); + regs.cc &= 0xF7; // CLN + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + regs.clock += 7; + } +static void Op76(void) // ROR ABS + { + uint8 tmp; uint16 addr; + addr = FetchW(); + tmp = regs.RdMem(addr); uint8 tmp2 = tmp; + tmp = (tmp >> 1) + (regs.cc&0x01)*128; + regs.WrMem(addr, tmp); + (tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 7; + } +static void Op77(void) // ASR ABS + { + uint8 tmp; uint16 addr; + addr = FetchW(); + tmp = regs.RdMem(addr); + (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into carry + tmp >>= 1; + if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set + regs.WrMem(addr, tmp); + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 7; + } +static void Op78(void) // LSL ABS + { + uint8 tmp; uint16 addr; + addr = FetchW(); + tmp = regs.RdMem(addr); + (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry + tmp <<= 1; + regs.WrMem(addr, tmp); + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 7; + } +static void Op79(void) // ROL ABS +{ + uint8 tmp2 = regs.RdMem(FetchW()); + tmp = (tmp2<<1) + (regs.cc&0x01); + regs.WrMem(addr, tmp); + (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 7; +} +static void Op7A(void) // DEC ABS + { + uint8 tmp; uint16 addr; + addr = FetchW(); + tmp = regs.RdMem(addr) - 1; + regs.WrMem(addr, tmp); + (tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 7; + } +static void Op7C(void) // INC ABS + { + uint8 tmp; uint16 addr; + addr = FetchW(); + tmp = regs.RdMem(addr) + 1; + regs.WrMem(addr, tmp); + (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 7; + } + +static void Op7D(void) // TST ABS +{ + uint8 tmp = regs.RdMem(FetchW()); + + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + + regs.clock += 7; +} + +static void Op7E(void) // JMP ABS +{ + regs.pc = FetchW(); + regs.clock += 3; +} +static void Op7F(void) // CLR ABS + { + regs.WrMem(FetchW(), 0); + regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC + regs.clock += 7; + } +static void Op80(void) // SUBA # +{ + uint8 tmp = regs.RdMem(regs.pc++); uint8 as = regs.a; + regs.a -= tmp; + (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; +} +static void Op81(void) // CMPA # +{ + tmp = regs.RdMem(regs.pc++); + uint8 db = regs.a - tmp; + (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; +} +static void Op82(void) // SBCA # +{ + tmp = regs.RdMem(regs.pc++); uint8 as = regs.a; + regs.a = regs.a - tmp - (regs.cc&0x01); + (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; +} +static void Op83(void) // SUBD # +{ + addr = FetchW(); uint16 dr = (regs.a<<8)|regs.b, ds = dr; + dr -= addr; + (ds < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((ds^addr^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.a = dr>>8; regs.b = dr&0xFF; + regs.clock += 4; +} +static void Op84(void) // ANDA # + { + regs.a &= regs.RdMem(regs.pc++); + regs.cc &= 0xFD; // Clear oVerflow flag + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; + } +static void Op85(void) // BITA # + { + tmp = regs.a & regs.RdMem(regs.pc++); + regs.cc &= 0xFD; // Clear oVerflow flag + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; + } +static void Op86(void) // LDA # + { + regs.a = regs.RdMem(regs.pc++); + regs.cc &= 0xFD; // CLV + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; + } +static void Op88(void) // EORA # + { + regs.a ^= regs.RdMem(regs.pc++); + regs.cc &= 0xFD; // CLV + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; + } +static void Op89(void) // ADCA # +{ + tmp = regs.RdMem(regs.pc++); + addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01); + (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry + ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry + ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.a = addr & 0xFF; // Set accumulator + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative + regs.clock += 2; +} +static void Op8A(void) // ORA # + { + regs.a |= regs.RdMem(regs.pc++); + regs.cc &= 0xFD; // CLV + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; + } +static void Op8B(void) // ADDA # +{ + tmp = regs.RdMem(regs.pc++); addr = regs.a + tmp; + (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag + ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry + ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.a = addr & 0xFF; // Set accumulator + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag + regs.clock += 2; +} +static void Op8C(void) // CMPX # +{ + addr = FetchW(); + uint16 dw = regs.x - addr; + (regs.x < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((regs.x^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl + (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; +} +static void Op8D(void) // Bregs.s + { + tmp = regs.RdMem(regs.pc++); + regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8); + regs.pc += SignedB(tmp); + regs.clock += 7; + } +static void Op8E(void) // LDX # + { + regs.x = FetchW(); + regs.cc &= 0xFD; // CLV + (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 3; + } +static void Op90(void) // SUBA DP + { + tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8 as = regs.a; + regs.a -= tmp; + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.clock += 4; + } +static void Op91(void) // CMPA DP + { + tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); + uint8 db = regs.a - tmp; + (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.clock += 4; + } +static void Op92(void) // SBCA DP +{ + tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8 as = regs.a; + regs.a = regs.a - tmp - (regs.cc&0x01); + (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; +} +static void Op93(void) // SUBD DP +{ + addr = (regs.dp<<8)|regs.RdMem(regs.pc++); uint16 dr = (regs.a<<8)|regs.b, ds = dr; + uint16 adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); + dr -= adr2; + (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.a = dr>>8; regs.b = dr&0xFF; + regs.clock += 6; +} +static void Op94(void) // ANDA DP +{ + regs.a &= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); + regs.cc &= 0xF1; // CLV CLZ CLN + if (regs.a == 0) regs.cc |= 0x04; // Adjust Zero flag + if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag + regs.clock += 4; +} +static void Op95(void) // BITA DP + { + tmp = regs.a & regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); + regs.cc &= 0xFD; // Clear oVerflow flag + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; + } +static void Op96(void) // LDA DP +{ + regs.a = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); + regs.cc &= 0xF1; // CLN CLZ CLV + if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag + if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag + regs.clock += 4; +} +static void Op97(void) // STA DP + { + regs.WrMem((regs.dp<<8)|regs.RdMem(regs.pc++), regs.a); + regs.cc &= 0xFD; // CLV + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; + } +static void Op98(void) // EORA DP + { + regs.a ^= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); + regs.cc &= 0xFD; // CLV + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; + } +static void Op99(void) // ADCA DP +{ + tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); + addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01); + (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry + ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry + ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.a = addr & 0xFF; // Set accumulator + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative + regs.clock += 4; +} +static void Op9A(void) // ORA DP + { + regs.a |= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); + regs.cc &= 0xFD; // CLV + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; + } +static void Op9B(void) // ADDA DP +{ + tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); + addr = (uint16)regs.a + (uint16)tmp; + (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag + ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry + ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo + regs.a = addr & 0xFF; // Set accumulator + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag + regs.clock += 4; +} +static void Op9C(void) // CMPX DP + { + addr = (regs.dp<<8)|regs.RdMem(regs.pc++); + uint16 adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); + uint16 dw = regs.x - adr2; + (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.x < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((regs.x^adr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl + regs.clock += 6; + } +static void Op9D(void) // JSR DP + { + addr = (regs.dp<<8) | regs.RdMem(regs.pc++); + regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8); + regs.pc = addr; // JSR to DP location... + regs.clock += 7; + } +static void Op9E(void) // LDX DP + { + addr = (regs.dp<<8) | regs.RdMem(regs.pc++); + regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1); + regs.cc &= 0xFD; // CLV + (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 5; + } +static void Op9F(void) // STX DP + { + addr = (regs.dp<<8) | regs.RdMem(regs.pc++); + regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF); + regs.cc &= 0xFD; // CLV + (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 5; + } +static void OpA0(void) // SUBA IDX + { + tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 as = regs.a; + regs.a -= tmp; + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.clock += 4; + } +static void OpA1(void) // CMPA IDX + { + tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); + uint8 db = regs.a - tmp; + (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.clock += 4; + } +static void OpA2(void) // SBCA IDX +{ + tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 as = regs.a; + regs.a = regs.a - tmp - (regs.cc&0x01); + (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; +} +static void OpA3(void) // SUBD IDX +{ + addr = DecodeIDX(regs.RdMem(regs.pc++)); uint16 dr = (regs.a<<8)|regs.b, ds = dr; + uint16 adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); + dr -= adr2; + (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.a = dr>>8; regs.b = dr&0xFF; + regs.clock += 6; +} +static void OpA4(void) // ANDA IDX + { + regs.a &= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); + regs.cc &= 0xFD; // Clear oVerflow flag + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; + } +static void OpA5(void) // BITA IDX + { + tmp = regs.a & regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); + regs.cc &= 0xFD; // Clear oVerflow flag + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; + } +static void OpA6(void) // LDA IDX +{ + regs.a = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); + regs.cc &= 0xF1; // CLV CLZ CLN + if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag + if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag + regs.clock += 4; +} +static void OpA7(void) // STA IDX +{ + regs.WrMem(DecodeIDX(regs.RdMem(regs.pc++)), regs.a); + regs.cc &= 0xF1; // CLV CLZ CLN + if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag + if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag + regs.clock += 4; +} +static void OpA8(void) // EORA IDX + { + regs.a ^= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); + regs.cc &= 0xFD; // CLV + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; + } +static void OpA9(void) // ADCA IDX +{ + tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); + addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01); + (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag + ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry + ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo + regs.a = addr & 0xFF; // Set accumulator + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag + regs.clock += 4; +} +static void OpAA(void) // ORA IDX +{ + regs.a |= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); + regs.cc &= 0xFD; // CLV + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; +} +static void OpAB(void) // ADDA IDX +{ + tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); + addr = (uint16)regs.a + (uint16)tmp; + (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag + ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry + ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo + regs.a = addr & 0xFF; // Set accumulator + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag + regs.clock += 4; +} +static void OpAC(void) // CMPX IDX +{ + addr = DecodeIDX(regs.RdMem(regs.pc++)); + uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); + uint16 dw = regs.x - addr2; + (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.x < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((regs.x^addr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.clock += 6; +} +static void OpAD(void) // JSR IDX +{ + addr = DecodeIDX(regs.RdMem(regs.pc++)); + regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8); + regs.pc = addr; // Jregs.s directly to IDX ptr + regs.clock += 7; +} +static void OpAE(void) // LDX IDX +{ + addr = DecodeIDX(regs.RdMem(regs.pc++)); + regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1); + regs.cc &= 0xFD; // CLV + (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 5; +} +static void OpAF(void) // STX IDX +{ + addr = DecodeIDX(regs.RdMem(regs.pc++)); + regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF); + regs.cc &= 0xF1; // CLV CLZ CLN + if (regs.x == 0) regs.cc |= 0x04; // Set Zero flag + if (regs.x&0x8000) regs.cc |= 0x08; // Set Negative flag + regs.clock += 5; +} +static void OpB0(void) // SUBA ABS + { + tmp = regs.RdMem(FetchW()); uint8 as = regs.a; + regs.a -= tmp; + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.clock += 5; + } +static void OpB1(void) // CMPA ABS + { + tmp = regs.RdMem(FetchW()); + uint8 db = regs.a - tmp; + (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.clock += 5; + } +static void OpB2(void) // SBCA ABS +{ + tmp = regs.RdMem(FetchW()); uint8 as = regs.a; + regs.a = regs.a - tmp - (regs.cc&0x01); + (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 5; +} +static void OpB3(void) // SUBD ABS +{ + addr = FetchW(); uint16 dr = (regs.a<<8)|regs.b, ds = dr; + uint16 adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); + dr -= adr2; + (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl + (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.a = dr>>8; regs.b = dr&0xFF; + regs.clock += 7; +} +static void OpB4(void) // ANDA ABS +{ + regs.a &= regs.RdMem(FetchW()); + regs.cc &= 0xFD; // Clear oVerflow flag + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 5; +} +static void OpB5(void) // BITA ABS +{ + tmp = regs.a & regs.RdMem(FetchW()); + regs.cc &= 0xFD; // Clear oVerflow flag + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 5; +} +static void OpB6(void) // LDA ABS +{ + regs.a = regs.RdMem(FetchW()); + regs.cc &= 0xFD; // CLV + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 5; +} +static void OpB7(void) // STA ABS +{ + regs.WrMem(FetchW(), regs.a); + regs.cc &= 0xFD; // CLV + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 5; +} +static void OpB8(void) // EORA ABS +{ + regs.a ^= regs.RdMem(FetchW()); + regs.cc &= 0xFD; // CLV + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 5; +} +static void OpB9(void) // ADCA ABS +{ + tmp = regs.RdMem(FetchW()); + addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01); + (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag + ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry + ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.a = addr; // Set accumulator + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag + regs.clock += 5; +} +static void OpBA(void) // ORA ABS +{ + regs.a |= regs.RdMem(FetchW()); + regs.cc &= 0xFD; // CLV + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 5; +} +static void OpBB(void) // ADDA ABS +{ + tmp = regs.RdMem(FetchW()); + addr = (uint16)regs.a + (uint16)tmp; + (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag + ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry + ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo + regs.a = addr & 0xFF; // Set accumulator + (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag + regs.clock += 5; +} +static void OpBC(void) // CMPX ABS +{ + addr = FetchW(); uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); + uint16 dw = regs.x - addr2; + (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.x < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((regs.x^addr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.clock += 7; +} +static void OpBD(void) // JSR ABS +{ + addr = FetchW(); + regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8); + regs.pc = addr; // Go to absolute address (Not indir) + regs.clock += 8; +} + +static void OpBE(void) // LDX ABS +{ +// addr = FetchW(); +// regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1); + regs.x = RdMemW(FetchW()); + + regs.cc &= 0xFD; // CLV + (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + + regs.clock += 6; +} + +static void OpBF(void) // STX ABS +{ +// addr = FetchW(); +// regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF); + WrMemW(FetchW(), regs.x); + + regs.cc &= 0xFD; // CLV + (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + + regs.clock += 6; +} + +static void OpC0(void) // SUBB # + { + tmp = regs.RdMem(regs.pc++); uint8 bs = regs.b; + regs.b -= tmp; + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.clock += 2; + } +static void OpC1(void) // CMPB # + { + tmp = regs.RdMem(regs.pc++); + uint8 db = regs.b - tmp; + (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; + } +static void OpC2(void) // SBCB # +{ + tmp = regs.RdMem(regs.pc++); uint8 bs = regs.b; + regs.b = regs.b - tmp - (regs.cc&0x01); + (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; +} +static void OpC3(void) // ADDD # +{ + addr = FetchW(); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr; + dr += addr; + (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + dr &= 0xFFFF; + (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + ((ds^addr^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl + regs.a = dr>>8; regs.b = dr&0xFF; + regs.clock += 4; +} +static void OpC4(void) // ANDB # + { + regs.b &= regs.RdMem(regs.pc++); + regs.cc &= 0xFD; // Clear oVerflow flag + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; + } +static void OpC5(void) // BITB # +{ + tmp = regs.b & regs.RdMem(regs.pc++); + regs.cc &= 0xF1; // CLV CLZ CLN + if (tmp == 0) regs.cc |= 0x04; // Set Zero flag + if (tmp&0x80) regs.cc |= 0x08; // Set Negative flag + regs.clock += 2; +} +static void OpC6(void) // LDB # +{ + regs.b = regs.RdMem(regs.pc++); + regs.cc &= 0xF1; // CLV CLZ CLN + if (regs.b == 0) regs.cc |= 0x04; // Set Zero flag + if (regs.b&0x80) regs.cc |= 0x08; // Set Negative flag + regs.clock += 2; +} +static void OpC8(void) // EORB # + { + regs.b ^= regs.RdMem(regs.pc++); + regs.cc &= 0xFD; // CLV + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; + } +static void OpC9(void) // ADCB # +{ + tmp = regs.RdMem(regs.pc++); + addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01); + (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag + ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry + ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo + regs.b = addr & 0xFF; // Set accumulator + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag + regs.clock += 2; +} +static void OpCA(void) // ORB # + { + regs.b |= regs.RdMem(regs.pc++); + regs.cc &= 0xFD; // CLV + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 2; + } +static void OpCB(void) // ADDB # +{ + tmp = regs.RdMem(regs.pc++); addr = regs.b + tmp; + (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag + ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry + ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo + regs.b = addr & 0xFF; // Set accumulator + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag + regs.clock += 2; +} +static void OpCC(void) // LDD # +{ + regs.a = regs.RdMem(regs.pc++); regs.b = regs.RdMem(regs.pc++); + regs.cc &= 0xFD; // CLV + ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 3; +} +static void OpCE(void) // LDU # +{ + regs.u = FetchW(); + regs.cc &= 0xFD; // CLV + (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 3; +} +static void OpD0(void) // SUBB DP +{ + tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8 bs = regs.b; + regs.b -= tmp; + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.clock += 4; +} +static void OpD1(void) // CMPB DP +{ + tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); + uint8 db = regs.b - tmp; + (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.clock += 4; +} +static void OpD2(void) // SBCB DP +{ + tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8 bs = regs.b; + regs.b = regs.b - tmp - (regs.cc&0x01); + (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; +} +static void OpD3(void) // ADDD DP +{ + addr = (regs.dp<<8)|regs.RdMem(regs.pc++); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr; + uint16 adr2 = (regs.RdMem(addr)<<8)|regs.RdMem(addr+1); + dr += adr2; + (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + dr &= 0xFFFF; + (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.a = dr>>8; regs.b = dr&0xFF; + regs.clock += 6; +} +static void OpD4(void) // ANDB DP + { + regs.b &= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); + regs.cc &= 0xFD; // Clear oVerflow flag + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; + } +static void OpD5(void) // BITB DP + { + tmp = regs.b & regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); + regs.cc &= 0xFD; // Clear oVerflow flag + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; + } +static void OpD6(void) // LDB DP +{ + regs.b = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); + regs.cc &= 0xFD; // CLV + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; +} +static void OpD7(void) // STB DP + { + regs.WrMem((regs.dp<<8)|regs.RdMem(regs.pc++), regs.b); + regs.cc &= 0xFD; // CLV + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; + } +static void OpD8(void) // EORB DP + { + regs.b ^= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); + regs.cc &= 0xFD; // CLV + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; + } +static void OpD9(void) // ADCB DP +{ + tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); + addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01); + (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag + ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry + ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.b = addr; // Set accumulator + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag + regs.clock += 4; +} +static void OpDA(void) // ORB DP + { + regs.b |= regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); + regs.cc &= 0xFD; // CLV + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; + } +static void OpDB(void) // ADDB DP +{ + tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); + addr = (uint16)regs.b + (uint16)tmp; + (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag + ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry + ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.b = addr & 0xFF; // Set accumulator + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag + regs.clock += 4; +} +static void OpDC(void) // LDD DP +{ + addr = (regs.dp<<8)|regs.RdMem(regs.pc++); + regs.a = regs.RdMem(addr); regs.b = regs.RdMem(addr+1); + regs.cc &= 0xFD; // CLV + ((regs.a|regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 5; +} +static void OpDD(void) // STD DP +{ + addr = (regs.dp<<8)|regs.RdMem(regs.pc++); + regs.WrMem(addr, regs.a); regs.WrMem(addr+1, regs.b); + regs.cc &= 0xFD; // CLV + ((regs.a|regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 5; +} +static void OpDE(void) // LDU DP +{ + addr = (regs.dp<<8)|regs.RdMem(regs.pc++); + regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1); + regs.cc &= 0xFD; // CLV + (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 5; +} +static void OpDF(void) // STU DP +{ + addr = (regs.dp<<8)|regs.RdMem(regs.pc++); + regs.WrMem(addr, regs.u>>8); regs.WrMem(addr+1, regs.u&0xFF); + regs.cc &= 0xFD; // CLV + (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 5; +} +static void OpE0(void) // SUBB IDX +{ + tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 bs = regs.b; + regs.b -= tmp; + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.clock += 4; +} +static void OpE1(void) // CMPB IDX +{ + tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); + uint8 db = regs.b - tmp; + (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.clock += 4; +} +static void OpE2(void) // SBCB IDX +{ + tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 bs = regs.b; + regs.b = regs.b - tmp - (regs.cc&0x01); + (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; +} +static void OpE3(void) // ADDD IDX +{ + addr = DecodeIDX(regs.RdMem(regs.pc++)); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr; + uint16 adr2 = (regs.RdMem(addr)<<8)|regs.RdMem(addr+1); + dr += adr2; + (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + dr &= 0xFFFF; + (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.a = dr>>8; regs.b = dr&0xFF; + regs.clock += 6; +} +static void OpE4(void) // ANDB IDX + { + regs.b &= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); + regs.cc &= 0xFD; // Clear oVerflow flag + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; + } +static void OpE5(void) // BITB IDX + { + tmp = regs.b & regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); + regs.cc &= 0xFD; // Clear oVerflow flag + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; + } +static void OpE6(void) // LDB IDX + { + regs.b = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); + regs.cc &= 0xFD; // CLV + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; + } +static void OpE7(void) // STB IDX +{ + regs.WrMem(DecodeIDX(regs.RdMem(regs.pc++)), regs.b); + regs.cc &= 0xF1; // CLV CLZ CLN + if (regs.b == 0) regs.cc |= 0x04; // Adjust Zero flag + if (regs.b&0x80) regs.cc |= 0x08; // Adjust Negative flag + regs.clock += 4; +} +static void OpE8(void) // EORB IDX + { + regs.b ^= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); + regs.cc &= 0xFD; // CLV + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; + } +static void OpE9(void) // ADCB IDX +{ + tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); + addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01); + (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag + ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry + ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.b = addr; // Set accumulator + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag + regs.clock += 4; +} +static void OpEA(void) // ORB IDX + { + regs.b |= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); + regs.cc &= 0xFD; // CLV + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; + } +static void OpEB(void) // ADDB IDX +{ + tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); + addr = (uint16)regs.b + (uint16)tmp; + (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag + ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry + ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.b = addr; // Set accumulator + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag + regs.clock += 4; +} +static void OpEC(void) // LDD IDX +{ + addr = DecodeIDX(regs.RdMem(regs.pc++)); + regs.a = regs.RdMem(addr); regs.b = regs.RdMem(addr+1); + regs.cc &= 0xF1; // CLV CLZ CLN + if (!(regs.a|regs.b)) regs.cc |= 0x04; // Adjust Zero flag + if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag + regs.clock += 5; +} +static void OpED(void) // STD IDX +{ + addr = DecodeIDX(regs.RdMem(regs.pc++)); + regs.WrMem(addr, regs.a); regs.WrMem(addr+1, regs.b); + regs.cc &= 0xF1; // CLV CLZ CLZ + if (!(regs.a|regs.b)) regs.cc |= 0x04; // Adjust Zero flag + if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag + regs.clock += 5; +} +static void OpEE(void) // LDU IDX +{ + addr = DecodeIDX(regs.RdMem(regs.pc++)); + regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1); + regs.cc &= 0xF1; // CLV CLZ CLN + if (regs.u == 0) regs.cc |= 0x04; // Set Zero flag + if (regs.u&0x8000) regs.cc |= 0x08; // Set Negative flag + regs.clock += 5; +} +static void OpEF(void) // STU IDX +{ + addr = DecodeIDX(regs.RdMem(regs.pc++)); + regs.WrMem(addr, regs.u>>8); regs.WrMem(addr+1, regs.u&0xFF); + regs.cc &= 0xF1; // CLV CLZ CLN + if (regs.u == 0) regs.cc |= 0x04; // Set Zero flag + if (regs.u&0x8000) regs.cc |= 0x08; // Set Negative flag + regs.clock += 5; +} +static void OpF0(void) // SUBB ABS + { + tmp = regs.RdMem(FetchW()); uint8 bs = regs.b; + regs.b -= tmp; + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + } +static void OpF1(void) // CMPB ABS + { + tmp = regs.RdMem(FetchW()); + uint8 db = regs.b - tmp; + (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.clock += 5; + } +static void OpF2(void) // SBCB ABS +{ + tmp = regs.RdMem(FetchW()); uint8 bs = regs.b; + regs.b = regs.b - tmp - (regs.cc&0x01); + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.clock += 5; +} +static void OpF3(void) // ADDD ABS +{ + addr = FetchW(); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr; + uint16 adr2 = (regs.RdMem(addr)<<8)|regs.RdMem(addr+1); + dr += adr2; + (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + dr &= 0xFFFF; + (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl + regs.a = dr>>8; regs.b = dr&0xFF; + regs.clock += 7; +} +static void OpF4(void) // ANDB ABS + { + regs.b &= regs.RdMem(FetchW()); + regs.cc &= 0xFD; // Clear oVerflow flag + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 5; + } +static void OpF5(void) // BITB ABS + { + tmp = regs.b & regs.RdMem(FetchW()); + regs.cc &= 0xFD; // Clear oVerflow flag + (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 5; + } +static void OpF6(void) // LDB ABS + { + regs.b = regs.RdMem(FetchW()); + regs.cc &= 0xFD; // CLV + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 5; + } +static void OpF7(void) // STB ABS + { + regs.WrMem(FetchW(), regs.b); + regs.cc &= 0xFD; // CLV + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 5; + } +static void OpF8(void) // EORB ABS + { + regs.b ^= regs.RdMem(FetchW()); + regs.cc &= 0xFD; // CLV + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 5; + } +static void OpF9(void) // ADCB ABS +{ + tmp = regs.RdMem(FetchW()); + addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01); + (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag + ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry + ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo + regs.b = addr & 0xFF; // Set accumulator + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag + regs.clock += 5; +} +static void OpFA(void) // ORB ABS + { + regs.b |= regs.RdMem(FetchW()); + regs.cc &= 0xFD; // CLV + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 5; + } +static void OpFB(void) // ADDB ABS +{ + tmp = regs.RdMem(FetchW()); + addr = (uint16)regs.b + (uint16)tmp; + (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag + ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry + ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo + regs.b = addr & 0xFF; // Set accumulator + (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag + (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag + regs.clock += 5; +} +static void OpFC(void) // LDD ABS + { + addr = FetchW(); + regs.a = regs.RdMem(addr); regs.b = regs.RdMem(addr+1); + regs.cc &= 0xFD; // CLV + ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; + } +static void OpFD(void) // STD ABS + { + addr = FetchW(); + regs.WrMem(addr, regs.a); regs.WrMem(addr+1, regs.b); + regs.cc &= 0xFD; // CLV + ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; + } +static void OpFE(void) // LDU ABS + { + addr = FetchW(); + regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1); + regs.cc &= 0xFD; // CLV + (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; + } +static void OpFF(void) // STU ABS + { + addr = FetchW(); + regs.WrMem(addr, regs.u>>8); regs.WrMem(addr+1, regs.u&0xFF); + regs.cc &= 0xFD; // CLV + (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; + } + +// +// Page one opcodes' execute code +// + +static void Op1021(void) // LBRN +{ + addr = FetchW(); + regs.clock += 5; +} +static void Op1022(void) // LBHI +{ + addr = FetchW(); + if (!((regs.cc&0x01)|(regs.cc&0x04))) regs.pc += SignedW(addr); + regs.clock += 5; +} +static void Op1023(void) // LBLS +{ + addr = FetchW(); + if ((regs.cc&0x01)|(regs.cc&0x04)) regs.pc += SignedW(addr); + regs.clock += 5; +} +static void Op1024(void) // LBCC (LBHS) +{ + addr = FetchW(); + if (!(regs.cc&0x01)) regs.pc += SignedW(addr); + regs.clock += 5; +} +static void Op1025(void) // LBCS (LBLO) +{ + addr = FetchW(); + if (regs.cc&0x01) regs.pc += SignedW(addr); + regs.clock += 5; +} +static void Op1026(void) // LBNE +{ + addr = FetchW(); + if (!(regs.cc&0x04)) regs.pc += SignedW(addr); + regs.clock += 5; +} +static void Op1027(void) // LBEQ +{ + addr = FetchW(); + if (regs.cc&0x04) regs.pc += SignedW(addr); + regs.clock += 5; +} +static void Op1028(void) // LBVC +{ + addr = FetchW(); + if (!(regs.cc&0x02)) regs.pc += SignedW(addr); + regs.clock += 5; +} +static void Op1029(void) // LBVS +{ + addr = FetchW(); + if (regs.cc&0x02) regs.pc += SignedW(addr); + regs.clock += 5; +} +static void Op102A(void) // LBPL +{ + addr = FetchW(); + if (!(regs.cc&0x08)) regs.pc += SignedW(addr); + regs.clock += 5; +} +static void Op102B(void) // LBMI +{ + addr = FetchW(); + if (regs.cc&0x08) regs.pc += SignedW(addr); + regs.clock += 5; +} +static void Op102C(void) // LBGE +{ + addr = FetchW(); + if (!(((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))) regs.pc += SignedW(addr); + regs.clock += 5; +} +static void Op102D(void) // LBLT +{ + addr = FetchW(); + if (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02)) regs.pc += SignedW(addr); + regs.clock += 5; +} +static void Op102E(void) // LBGT +{ + addr = FetchW(); + if (!((regs.cc&0x04) | (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02)))) regs.pc += SignedW(addr); + regs.clock += 5; +} +static void Op102F(void) // LBLE +{ + addr = FetchW(); + if ((regs.cc&0x04) | (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))) regs.pc += SignedW(addr); + regs.clock += 5; +} +static void Op103F(void) // SWI2 (Not yet implemented) +{ + regs.clock += 20; +} +static void Op1083(void) // CMPD # + { + addr = FetchW(); uint16 dr = (regs.a<<8)|regs.b; + uint16 dw = dr - addr; + (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (dr < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((dr^addr^dw^((uint16)regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl + regs.clock += 5; + } +static void Op108C(void) // CMPY # + { + addr = FetchW(); + uint16 dw = regs.y - addr; + (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((regs.y^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl + regs.clock += 5; + } +static void Op108E(void) // LDY # + { + regs.y = FetchW(); + regs.cc &= 0xFD; // CLV + (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; + } +static void Op1093(void) // CMPD DP + { + uint16 adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++), dr = (regs.a<<8)|regs.b; + addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1); + uint16 dw = dr - addr; + (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (dr < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((dr^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl + regs.clock += 7; + } +static void Op109C(void) // CMPY DP + { + uint16 adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++); + addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1); + uint16 dw = regs.y - addr; + (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + ((regs.y^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl + regs.clock += 7; + } + +static void Op109E(void) // LDY DP + { + addr = (regs.dp<<8)|regs.RdMem(regs.pc++); + regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); + regs.cc &= 0xFD; // CLV + (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; + } + +static void Op109F(void) // STY DP + { + addr = (regs.dp<<8)|regs.RdMem(regs.pc++); + regs.WrMem(addr, regs.y>>8); regs.WrMem(addr+1, regs.y&0xFF); + regs.cc &= 0xFD; // CLV + (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; + } +static void Op10A3(void) // CMPD IDX +{ + uint16 adr2 = DecodeIDX(regs.RdMem(regs.pc++)), dr = (regs.a<<8)|regs.b; + addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1); + uint16 dw = dr - addr; + regs.cc &= 0xF0; // CLC CLV CLZ CLN + if (dr < addr) regs.cc |= 0x01; // Set Carry flag + if ((dr^addr^dw^(regs.cc<<15))&0x8000) regs.cc |= 0x02; // Set oVerflow + if (dw == 0) regs.cc |= 0x04; // Set Zero flag + if (dw&0x8000) regs.cc |= 0x08; // Set Negative flag + regs.clock += 7; +} +static void Op10AC(void) // CMPY IDX + { + uint16 adr2 = DecodeIDX(regs.RdMem(regs.pc++)); + addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1); + uint16 dw = regs.y - addr; + (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + (((regs.cc<<15)^regs.y^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl + regs.clock += 7; + } +static void Op10AE(void) // LDY IDX +{ + addr = DecodeIDX(regs.RdMem(regs.pc++)); + regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); + regs.cc &= 0xF1; // CLV CLZ CLN + if (regs.y == 0) regs.cc |= 0x04; // Adjust Zero flag + if (regs.y&0x8000) regs.cc |= 0x08; // Adjust Negative flag + regs.clock += 6; +} +static void Op10AF(void) // STY IDX + { + addr = DecodeIDX(regs.RdMem(regs.pc++)); + regs.WrMem(addr, regs.y>>8); regs.WrMem(addr+1, regs.y&0xFF); + regs.cc &= 0xFD; // CLV + (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; + } +static void Op10B3(void) // CMPD ABS + { + addr = FetchW(); uint16 dr = (regs.a<<8)|regs.b; + uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); + uint16 dw = dr - addr2; + (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (dr < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + (((regs.cc<<15)^dr^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl + regs.clock += 8; + } +static void Op10BC(void) // CMPY ABS + { + addr = FetchW(); uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); + uint16 dw = regs.y - addr2; + (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.y < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + (((regs.cc<<15)^regs.y^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl + regs.clock += 8; + } +static void Op10BE(void) // LDY ABS + { + addr = FetchW(); + regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); + regs.cc &= 0xFD; // CLV + (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 7; + } +static void Op10BF(void) // STY ABS + { + addr = FetchW(); + regs.WrMem(addr, regs.y>>8); regs.WrMem(addr+1, regs.y&0xFF); + regs.cc &= 0xFD; // CLV + (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 7; + } +static void Op10CE(void) // LDS # + { + regs.s = FetchW(); + regs.cc &= 0xFD; // CLV + (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 4; + } +static void Op10DE(void) // LDS DP + { + addr = (regs.dp<<8)|regs.RdMem(regs.pc++); + regs.s = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); + regs.cc &= 0xFD; // CLV + (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; + } +static void Op10DF(void) // STS DP + { + addr = (regs.dp<<8)|regs.RdMem(regs.pc++); + regs.WrMem(addr, regs.s>>8); regs.WrMem(addr+1, regs.s&0xFF); + regs.cc &= 0xFD; // CLV + (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; + } +static void Op10EE(void) // LDS IDX + { + addr = DecodeIDX(regs.RdMem(regs.pc++)); + regs.s = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); + regs.cc &= 0xFD; // CLV + (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; + } +static void Op10EF(void) // STS IDX + { + addr = DecodeIDX(regs.RdMem(regs.pc++)); + regs.WrMem(addr, regs.s>>8); regs.WrMem(addr+1, regs.s&0xFF); + regs.cc &= 0xFD; // CLV + (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 6; + } +static void Op10FE(void) // LDS ABS + { + addr = FetchW(); + regs.s = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); + regs.cc &= 0xFD; // CLV + (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 7; + } +static void Op10FF(void) // STS ABS +{ + addr = FetchW(); + regs.WrMem(addr, regs.s>>8); regs.WrMem(addr+1, regs.s&0xFF); + regs.cc &= 0xFD; // CLV + (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.clock += 7; +} + +// +// Page two opcodes' execute code +// + +static void Op113F(void) // SWI3 + { + regs.clock += 20; + } +static void Op1183(void) // CMPU # + { + addr = FetchW(); + uint16 dw = regs.u - addr; + (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl + regs.clock += 5; + } +static void Op118C(void) // CMPS # + { + addr = FetchW(); + uint16 dw = regs.s - addr; + (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl + regs.clock += 5; + } +static void Op1193(void) // CMPU DP + { + uint16 adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++); + addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1); + uint16 dw = regs.u - addr; + (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl + regs.clock += 7; + } +static void Op119C(void) // CMPS DP + { + uint16 adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++); + addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1); + uint16 dw = regs.s - addr; + (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl + regs.clock += 7; + } +static void Op11A3(void) // CMPU IDX + { + uint16 addr2 = DecodeIDX(regs.RdMem(regs.pc++)); + addr = (regs.RdMem(addr2)<<8) | regs.RdMem(addr2+1); + uint16 dw = regs.u - addr; + (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl + regs.clock += 7; + } +static void Op11AC(void) // CMPS IDX + { + uint16 addr2 = DecodeIDX(regs.RdMem(regs.pc++)); + addr = (regs.RdMem(addr2)<<8) | regs.RdMem(addr2+1); + uint16 dw = regs.s - addr; + (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl + regs.clock += 7; + } +static void Op11B3(void) // CMPU ABS + { + addr = FetchW(); uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); + uint16 dw = regs.u - addr2; + (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.u < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + (((regs.cc<<15)^regs.u^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl + regs.clock += 8; + } + +static void Op11BC(void) // CMPS ABS +{ + addr = FetchW(); uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); + uint16 dw = regs.s - addr2; + (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + (regs.s < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + (((regs.cc<<15)^regs.s^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl + regs.clock += 8; +} + +//temp, for testing... +/*static uint8 backTrace[256]; +static uint16 btPC[256]; +static int btPtr = 0;//*/ +static void Op__(void) // Illegal opcode +{ + regs.clock++; +// illegal = true; + regs.cpuFlags |= V6809_STATE_ILLEGAL_INST; +/*WriteLog("V6809: Executed illegal opcode %02X at PC=%04X...\n\nBacktrace:\n\n", regs.RdMem(regs.pc - 1), regs.pc - 1); +for(int i=0; i<256; i++) +{ + dpc = btPC[(btPtr+i)&0xFF]; + Decode_6809(); +}//*/ +} + + +// +// Internal "memcpy" (so we don't have to link with any external libraries!) +// +static void myMemcpy(void * dst, void * src, uint32 size) +{ + uint8 * d = (uint8 *)dst, * s = (uint8 *)src; + + for(uint32 i=0; icpuFlags; + + if (flags & V6809_ASSERT_LINE_RESET) // *** RESET handler *** + { + regs.cc |= (FLAG_F | FLAG_I); // Set F, I + regs.dp = 0; // Reset direct page register + regs.pc = RdMemW(0xFFFE); // And load PC with the RESET vector + context->cpuFlags &= ~V6809_ASSERT_LINE_RESET; + regs.cpuFlags &= ~V6809_ASSERT_LINE_RESET; + } + else if (flags & V6809_ASSERT_LINE_NMI) // *** NMI handler *** + { + regs.cc |= FLAG_E; // Set the Entire flag + + regs.WrMem(--regs.s, regs.pc & 0xFF); // Save all regs... + regs.WrMem(--regs.s, regs.pc >> 8); + regs.WrMem(--regs.s, regs.u & 0xFF); + regs.WrMem(--regs.s, regs.u >> 8); + regs.WrMem(--regs.s, regs.y & 0xFF); + regs.WrMem(--regs.s, regs.y >> 8); + regs.WrMem(--regs.s, regs.x & 0xFF); + regs.WrMem(--regs.s, regs.x >> 8); + regs.WrMem(--regs.s, regs.dp); + regs.WrMem(--regs.s, regs.b); + regs.WrMem(--regs.s, regs.a); + regs.WrMem(--regs.s, regs.cc); + + regs.cc |= (FLAG_I | FLAG_F); // Set IRQ/FIRQ suppress flags + regs.pc = RdMemW(0xFFFC); // And load PC with the NMI vector + regs.clock += 19; + context->cpuFlags &= ~V6809_ASSERT_LINE_NMI;// Reset the asserted line (NMI)... + regs.cpuFlags &= ~V6809_ASSERT_LINE_NMI; // Reset the asserted line (NMI)... + } + else if (flags & V6809_ASSERT_LINE_FIRQ) // *** FIRQ handler *** + { + if (!(regs.cc & FLAG_F)) // Is the FIRQ masked (F == 1)? + { + regs.cc &= ~FLAG_E; // Clear the Entire flag + + regs.WrMem(--regs.s, regs.pc & 0xFF); // Save PC, CC regs... + regs.WrMem(--regs.s, regs.pc >> 8); + regs.WrMem(--regs.s, regs.cc); + + regs.cc |= (FLAG_I | FLAG_F); // Set IRQ/FIRQ suppress flags + regs.pc = RdMemW(0xFFF6); // And load PC with the IRQ vector + regs.clock += 10; + context->cpuFlags &= ~V6809_ASSERT_LINE_FIRQ; // Reset the asserted line (FIRQ)... + regs.cpuFlags &= ~V6809_ASSERT_LINE_FIRQ; // Reset the asserted line (FIRQ)... + } + } + else if (flags & V6809_ASSERT_LINE_IRQ) // *** IRQ handler *** + { + if (!(regs.cc & FLAG_I)) // Is the IRQ masked (I == 1)? + { + regs.cc |= FLAG_E; // Set the Entire flag + + regs.WrMem(--regs.s, regs.pc & 0xFF); // Save all regs... + regs.WrMem(--regs.s, regs.pc >> 8); + regs.WrMem(--regs.s, regs.u & 0xFF); + regs.WrMem(--regs.s, regs.u >> 8); + regs.WrMem(--regs.s, regs.y & 0xFF); + regs.WrMem(--regs.s, regs.y >> 8); + regs.WrMem(--regs.s, regs.x & 0xFF); + regs.WrMem(--regs.s, regs.x >> 8); + regs.WrMem(--regs.s, regs.dp); + regs.WrMem(--regs.s, regs.b); + regs.WrMem(--regs.s, regs.a); + regs.WrMem(--regs.s, regs.cc); + + regs.cc |= FLAG_I; // Specs say that it doesn't affect FIRQ... or FLAG_F [WAS: Set IRQ/FIRQ suppress flags] + regs.pc = RdMemW(0xFFF8); // And load PC with the IRQ vector + regs.clock += 19; + context->cpuFlags &= ~V6809_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)... + regs.cpuFlags &= ~V6809_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)... + } + } +/*if (disasm) WriteLog("\tA=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n", + regs.a, regs.b, regs.cc, regs.dp, regs.x, regs.y, regs.s, regs.u, regs.pc);//*/ + } + + myMemcpy(context, ®s, sizeof(V6809REGS)); +} + +// +// Get the clock of the currently executing CPU +// +uint32 GetCurrentV6809Clock(void) +{ + return regs.clock; +} diff --git a/src/v6809.cpp.bak b/src/v6809.cpp.bak new file mode 100755 index 0000000..0d503b4 --- /dev/null +++ b/src/v6809.cpp.bak @@ -0,0 +1,2840 @@ +// +// Virtual 6809 v1.2P (Last build: 2/2/2004) +// +// by James L. Hammons +// +// (c) 1997 Underground Software +// + +#include // To make this really clean, we'd have to make our own memcpy, etc... +#include "v6809.h" + +// Global defs (needed because functions can only return one value. +// Maybe you could use a struct to pass multiple values, but +// what a pain in the ass! This way makes a little more sense +// to me.) + +//BYTE * ram, * rom; // RAM & ROM image spaces (64K each) +WORD pcr, xr, yr, sr, ur; // Double byte registers +BYTE ccr, ar, br, dpr; +long iclock; +bool /*color_reg = false,*/ illegal = false, inter; + +// Instead of the above, we can use a private struct for our CPU state... + +static V6809REGS regs; + +static WORD addr; // Temporary variables common to all funcs... +static BYTE tmp; + +extern BYTE Fetch(); // You need to define these functions +//extern WORD FetchW(); // externally because every hardware situation +extern BYTE RdMem(WORD); // is going to be different... +extern void WrMem(WORD, BYTE); + +// Internal function prototypes + +WORD ReadEXG(BYTE); // Read TFR/EXG post byte +void WriteEXG(BYTE, WORD); // Set TFR/EXG data +WORD DecodeReg(BYTE); // Decode register data +WORD DecodeIDX(BYTE); // Decode IDX data + +// +// Fetch word function +// +WORD FetchW(void) +{ + return (WORD)(Fetch() << 8) | Fetch(); +} + +// +// Return signed byte from unsigned +// +int SignedB(BYTE b) +{ + return (b & 0x80 ? b - 256 : b); +} + +// +// Return signed word from unsigned +// +int SignedW(WORD w) +{ + return (w & 0x8000 ? w - 65536 : w); +} + +// +// Function to read TFR/EXG post byte +// +WORD ReadEXG(BYTE code) +{ + WORD retval; + + switch(code) + { + case 0: retval = (ar<<8) | br; break; + case 1: retval = xr; break; + case 2: retval = yr; break; + case 3: retval = ur; break; + case 4: retval = sr; break; + case 5: retval = pcr; break; + case 8: retval = ar; break; + case 9: retval = br; break; + case 10: retval = ccr; break; + case 11: retval = dpr; break; + default: retval = 0xFF; + } + return(retval); +} + +// +// Function to set TFR/EXG data +// +void WriteEXG(BYTE code, WORD data) +{ + switch(code) + { + case 0: + ar = data >> 8, br = data & 0xFF; break; + case 1: + xr = data; break; + case 2: + yr = data; break; + case 3: + ur = data; break; + case 4: + sr = data; break; + case 5: + pcr = data; break; + case 8: + ar = data & 0xFF; break; + case 9: + br = data & 0xFF; break; + case 10: + ccr = data & 0xFF; break; + case 11: + dpr = data & 0xFF; break; + } +} + +// +// Function to decode register data +// +WORD DecodeReg(BYTE reg) +{ + WORD retval; + + switch (reg) + { + case 0: + retval = xr; break; + case 1: + retval = yr; break; + case 2: + retval = ur; break; + case 3: + retval = sr; break; + } + + return retval; +} + +// +// Function to decode IDX data +// +WORD DecodeIDX(BYTE code) +{ + WORD addr, woff; + BYTE reg = (code&0x60)>>5, idxind = (code&0x10)>>4, lo_nyb = code&0x0F; + + if (!(code&0x80)) // Hi bit unset? Then decode 4 bit offset + { + addr = DecodeReg(reg) + (idxind ? lo_nyb-16 : lo_nyb); + } + else + { + if (idxind) + { + switch(lo_nyb) + { + case 1: { woff = DecodeReg(reg); + addr = (RdMem(woff)<<8) | RdMem(woff+1); + switch(reg) + { + case 0: xr++; xr++; break; + case 1: yr++; yr++; break; + case 2: ur++; ur++; break; + case 3: sr++; sr++; break; + } + break; } + case 3: { switch(reg) + { + case 0: xr--; xr--; break; + case 1: yr--; yr--; break; + case 2: ur--; ur--; break; + case 3: sr--; sr--; break; + } + woff = DecodeReg(reg); + addr = (RdMem(woff)<<8) | RdMem(woff+1); break; } + case 4: { woff = DecodeReg(reg); + addr = (RdMem(woff)<<8) | RdMem(woff+1); break; } + case 5: { woff = DecodeReg(reg) + SignedB(br); + addr = (RdMem(woff)<<8) | RdMem(woff+1); break; } + case 6: { woff = DecodeReg(reg) + SignedB(ar); + addr = (RdMem(woff)<<8) | RdMem(woff+1); break; } + case 8: { woff = DecodeReg(reg) + SignedB(Fetch()); + addr = (RdMem(woff)<<8) | RdMem(woff+1); break; } + case 9: { woff = DecodeReg(reg) + SignedW(FetchW()); + addr = (RdMem(woff)<<8) | RdMem(woff+1); break; } + case 11: { woff = DecodeReg(reg) + SignedW((ar<<8) | br); + addr = (RdMem(woff)<<8) | RdMem(woff+1); break; } + case 12: { woff = pcr + SignedB(Fetch()); + addr = (RdMem(woff)<<8) | RdMem(woff+1); break; } + case 13: { woff = pcr + SignedW(FetchW()); + addr = (RdMem(woff)<<8) | RdMem(woff+1); break; } + case 15: { woff = FetchW(); + addr = (RdMem(woff)<<8) | RdMem(woff+1); break; } + } + } + else + { + switch(lo_nyb) + { + case 0: { addr = DecodeReg(reg); + switch(reg) + { + case 0: xr++; break; + case 1: yr++; break; + case 2: ur++; break; + case 3: sr++; break; + } + break; } + case 1: { addr = DecodeReg(reg); + switch(reg) + { + case 0: xr++; xr++; break; + case 1: yr++; yr++; break; + case 2: ur++; ur++; break; + case 3: sr++; sr++; break; + } + break; } + case 2: { switch(reg) + { + case 0: xr--; break; + case 1: yr--; break; + case 2: ur--; break; + case 3: sr--; break; + } + addr = DecodeReg(reg); break; } + case 3: { switch(reg) + { + case 0: xr--; xr--; break; + case 1: yr--; yr--; break; + case 2: ur--; ur--; break; + case 3: sr--; sr--; break; + } + addr = DecodeReg(reg); break; } + case 4: { addr = DecodeReg(reg); break; } + case 5: { addr = DecodeReg(reg) + SignedB(br); break; } + case 6: { addr = DecodeReg(reg) + SignedB(ar); break; } + case 8: { addr = DecodeReg(reg) + SignedB(Fetch()); break; } + case 9: { addr = DecodeReg(reg) + SignedW(FetchW()); break; } + case 11: { addr = DecodeReg(reg) + SignedW((ar<<8) | br); break; } + case 12: { addr = pcr + SignedB(Fetch()); break; } + case 13: { addr = pcr + SignedW(FetchW()); break; } + } + } + } + return(addr); +} + +// +// Page zero instructions... +// + +void Op00(void) // NEG DP +{ + addr = (dpr<<8) | Fetch(); + tmp = 256 - RdMem(addr); + WrMem(addr, tmp); + (tmp == 0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + (tmp > 0x7F ? ccr |= 0x01 : ccr &= 0xFE); // Adjust carry + iclock += 6; +} +void Op03(void) // COM DP +{ + addr = (dpr<<8) | Fetch(); + tmp = 0xFF ^ RdMem(addr); + WrMem(addr, tmp); + ccr &= 0xFD; ccr |= 0x01; // CLV SEC + (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 6; +} +void Op04(void) // LSR DP +{ + addr = (dpr<<8) | Fetch(); + tmp = RdMem(addr); + (tmp&0x01 ? ccr |= 0x01 : ccr &= 0xFE); // Shift low bit into carry + tmp >>= 1; WrMem(addr, tmp); + ccr &= 0xF7; // CLN + (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + iclock += 6; +} +void Op06(void) // ROR DP +{ + addr = (dpr<<8) | Fetch(); BYTE tmp2 = RdMem(addr); + tmp = (tmp2>>1) + (ccr&0x01)*128; + WrMem(addr, tmp); + (tmp2&0x01 ? ccr |= 0x01 : ccr &= 0xFE); // Shift bit into carry + (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 6; +} +void Op07(void) // ASR DP +{ + addr = (dpr<<8) | Fetch(); tmp = RdMem(addr); + (tmp&0x01 ? ccr |= 0x01 : ccr &= 0xFE); // Shift bit into carry + tmp >>= 1; + if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set + WrMem(addr, tmp); + (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 6; +} +void Op08(void) // LSL DP +{ + addr = (dpr<<8) | Fetch(); // NEEDS OVERFLOW ADJUSTMENT + tmp = RdMem(addr); + (tmp&0x80 ? ccr |= 0x01 : ccr &= 0xFE); // Shift hi bit into carry + tmp <<= 1; + WrMem(addr, tmp); + (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 6; +} +void Op09(void) // ROL DP +{ + addr = (dpr<<8) | Fetch(); BYTE tmp2 = RdMem(addr); + tmp = (tmp2<<1) + (ccr&0x01); + WrMem(addr, tmp); + (tmp2&0x80 ? ccr |= 0x01 : ccr &= 0xFE); // Shift hi bit into carry + ((tmp2&0x80)^((tmp2<<1)&0x80) ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 6; +} +void Op0A(void) // DEC DP +{ + addr = (dpr<<8) | Fetch(); + tmp = RdMem(addr) - 1; + WrMem(addr, tmp); + (tmp == 0x7F ? ccr |= 0x02 : ccr &= 0xFD); // Adjust oVerflow flag + (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 6; +} +void Op0C(void) // INC DP +{ + addr = (dpr<<8) | Fetch(); + tmp = RdMem(addr) + 1; + WrMem(addr, tmp); + (tmp == 0x80 ? ccr |= 0x02 : ccr &= 0xFD); // Adjust oVerflow flag + (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 6; +} +void Op0D(void) // TST DP +{ + tmp = RdMem((dpr<<8)|Fetch()); + ccr &= 0xFD; // CLV + (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 6; +} +void Op0E(void) // JMP DP +{ + pcr = (dpr<<8) | Fetch(); + iclock += 3; +} +void Op0F(void) // CLR DP +{ + WrMem((dpr<<8)|Fetch(), 0); + ccr &= 0xF0; ccr |= 0x04; // CLN, SEZ, CLV, CLC + iclock += 6; +} +void Op12(void) // NOP +{ + iclock += 2; +} +void Op13(void) // SYNC +{ + iclock += 2; +} +void Op16(void) // LBRA +{ + pcr += SignedW(FetchW()); + iclock += 5; +} +void Op17(void) // LBSR +{ + addr = FetchW(); + WrMem(--sr, pcr&0xFF); WrMem(--sr, pcr>>8); + pcr += SignedW(addr); + iclock += 9; +} +void Op19(void) // DAA +{ + if ((ccr&0x20) || ((ar&0x0F) > 0x09)) // H set or lo nyb too big? + { + ar += 0x06; ccr |= 0x20; // Then adjust & set half carry + } + if ((ccr&0x01) || (ar > 0x9F)) // C set or hi nyb too big? + { + ar += 0x60; ccr |= 0x01; // Then adjust & set carry + } + ccr &= 0xF1; // CL NZV + if (ar == 0) ccr |= 0x04; // Adjust Zero flag + if (ar&0x80) ccr |= 0x08; // Adjust Negative flag + iclock += 2; +} +void Op1A(void) // ORCC # +{ + ccr |= Fetch(); + iclock += 3; +} +void Op1C(void) // ANDCC # +{ + ccr &= Fetch(); + iclock += 3; +} +void Op1D(void) // SEX +{ + (br&0x80 ? ar = 0xFF : ar = 0x00); + ((ar|br) == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 2; +} +void Op1E(void) // EXG +{ + tmp = Fetch(); + addr = ReadEXG(tmp>>4); WriteEXG(tmp>>4, ReadEXG(tmp&0xF)); + WriteEXG(tmp&0xF, addr); + iclock += 8; +} +void Op1F(void) // TFR +{ + tmp = Fetch(); + WriteEXG(tmp&0xF, ReadEXG(tmp>>4)); + iclock += 7; +} +void Op20(void) // BRA +{ + pcr += SignedB(Fetch()); // Branch always + iclock += 3; +} +void Op21(void) // BRN +{ + Fetch(); + iclock += 3; +} +void Op22(void) // BHI +{ + tmp = Fetch(); + if (!(ccr&0x05)) pcr += SignedB(tmp); + iclock += 3; +} +void Op23(void) // BLS +{ + tmp = Fetch(); + if (ccr&0x05) pcr += SignedB(tmp); + iclock += 3; +} +void Op24(void) // BCC (BHS) +{ + tmp = Fetch(); + if (!(ccr&0x01)) pcr += SignedB(tmp); + iclock += 3; +} +void Op25(void) // BCS (BLO) +{ + tmp = Fetch(); + if (ccr&0x01) pcr += SignedB(tmp); + iclock += 3; +} +void Op26(void) // BNE +{ + tmp = Fetch(); + if (!(ccr&0x04)) pcr += SignedB(tmp); + iclock += 3; +} +void Op27(void) // BEQ +{ + tmp = Fetch(); + if (ccr&0x04) pcr += SignedB(tmp); + iclock += 3; +} +void Op28(void) // BVC +{ + tmp = Fetch(); + if (!(ccr&0x02)) pcr += SignedB(tmp); + iclock += 3; +} +void Op29(void) // BVS +{ + tmp = Fetch(); + if (ccr&0x02) pcr += SignedB(tmp); + iclock += 3; +} +void Op2A(void) // BPL +{ + tmp = Fetch(); + if (!(ccr&0x08)) pcr += SignedB(tmp); + iclock += 3; +} +void Op2B(void) // BMI +{ + tmp = Fetch(); + if (ccr&0x08) pcr += SignedB(tmp); + iclock += 3; +} +void Op2C(void) // BGE +{ + tmp = Fetch(); + if (!(((ccr&0x08) >> 2) ^ (ccr&0x02))) pcr += SignedB(tmp); + iclock += 3; +} +void Op2D(void) // BLT +{ + tmp = Fetch(); + if (((ccr&0x08) >> 2) ^ (ccr&0x02)) pcr += SignedB(tmp); + iclock += 3; +} +void Op2E(void) // BGT +{ + tmp = Fetch(); + if (!((ccr&0x04) | (((ccr&0x08) >> 2) ^ (ccr&0x02)))) pcr += SignedB(tmp); + iclock += 3; +} +void Op2F(void) // BLE +{ + tmp = Fetch(); + if ((ccr&0x04) | (((ccr&0x08) >> 2) ^ (ccr&0x02))) pcr += SignedB(tmp); + iclock += 3; +} +void Op30(void) // LEAX +{ + xr = DecodeIDX(Fetch()); + (xr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + iclock += 4; +} +void Op31(void) // LEAY +{ + yr = DecodeIDX(Fetch()); + (yr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + iclock += 4; +} +void Op32(void) // LEAS +{ + sr = DecodeIDX(Fetch()); + (sr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + iclock += 4; +} +void Op33(void) // LEAU +{ + ur = DecodeIDX(Fetch()); + (ur == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + iclock += 4; +} +void Op34(void) // PSHS +{ + tmp = Fetch(); + if (tmp&0x80) { WrMem(--sr, pcr&0xFF); WrMem(--sr, pcr>>8); } + if (tmp&0x40) { WrMem(--sr, ur&0xFF); WrMem(--sr, ur>>8); } + if (tmp&0x20) { WrMem(--sr, yr&0xFF); WrMem(--sr, yr>>8); } + if (tmp&0x10) { WrMem(--sr, xr&0xFF); WrMem(--sr, xr>>8); } + if (tmp&0x08) WrMem(--sr, dpr); + if (tmp&0x04) WrMem(--sr, br); + if (tmp&0x02) WrMem(--sr, ar); + if (tmp&0x01) WrMem(--sr, ccr); + iclock += 5; +} +void Op35(void) // PULS +{ + tmp = Fetch(); + if (tmp&0x01) ccr = RdMem(sr++); + if (tmp&0x02) ar = RdMem(sr++); + if (tmp&0x04) br = RdMem(sr++); + if (tmp&0x08) dpr = RdMem(sr++); + if (tmp&0x10) xr = (RdMem(sr++)<<8) | RdMem(sr++); + if (tmp&0x20) yr = (RdMem(sr++)<<8) | RdMem(sr++); + if (tmp&0x40) ur = (RdMem(sr++)<<8) | RdMem(sr++); + if (tmp&0x80) pcr = (RdMem(sr++)<<8) | RdMem(sr++); + iclock += 5; +} +void Op36(void) // PSHU +{ + tmp = Fetch(); + if (tmp&0x80) { WrMem(--ur, pcr&0xFF); WrMem(--ur, pcr>>8); } + if (tmp&0x40) { WrMem(--ur, sr&0xFF); WrMem(--ur, sr>>8); } + if (tmp&0x20) { WrMem(--ur, yr&0xFF); WrMem(--ur, yr>>8); } + if (tmp&0x10) { WrMem(--ur, xr&0xFF); WrMem(--ur, xr>>8); } + if (tmp&0x08) WrMem(--ur, dpr); + if (tmp&0x04) WrMem(--ur, br); + if (tmp&0x02) WrMem(--ur, ar); + if (tmp&0x01) WrMem(--ur, ccr); + iclock += 5; +} +void Op37(void) // PULU +{ + tmp = Fetch(); + if (tmp&0x01) ccr = RdMem(ur++); + if (tmp&0x02) ar = RdMem(ur++); + if (tmp&0x04) br = RdMem(ur++); + if (tmp&0x08) dpr = RdMem(ur++); + if (tmp&0x10) xr = (RdMem(ur++)<<8) | RdMem(ur++); + if (tmp&0x20) yr = (RdMem(ur++)<<8) | RdMem(ur++); + if (tmp&0x40) sr = (RdMem(ur++)<<8) | RdMem(ur++); + if (tmp&0x80) pcr = (RdMem(ur++)<<8) | RdMem(ur++); + iclock += 5; +} +void Op39(void) // RTS +{ + pcr = (RdMem(sr++)<<8) | RdMem(sr++); + iclock += 5; +} +void Op3A(void) // ABX +{ + xr += br; + iclock += 3; +} +void Op3B(void) // RTI +{ + ccr = RdMem(sr++); + if (ccr&0x80) // If E flag set, pull all regs + { + ar = RdMem(sr++); br = RdMem(sr++); dpr = RdMem(sr++); + xr = (RdMem(sr++)<<8) | RdMem(sr++); + yr = (RdMem(sr++)<<8) | RdMem(sr++); + ur = (RdMem(sr++)<<8) | RdMem(sr++); + iclock += 15; + } + else + { + iclock += 6; + } + pcr = (RdMem(sr++)<<8) | RdMem(sr++); +} +void Op3C(void) // CWAI +{ + ccr &= Fetch(); ccr |= 0x80; + iclock += 1000000; // Force interrupt +} +void Op3D(void) // MUL +{ + addr = ar * br; ar = addr>>8; br = addr&0xFF; + (addr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero + (br&0x80 ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry + iclock += 11; +} +void Op3E(void) // RESET +{ +} +void Op3F(void) // SWI +{ +} +void Op40(void) // NEGA +{ + ar = 256 - ar; + (ar > 0x7F ? ccr |= 0x01 : ccr &= 0xFE); // Adjust carry + (ar == 0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 2; +} +void Op43(void) // COMA +{ + ar ^= 0xFF; + ccr &= 0xFD; ccr |= 0x01; // CLV, SEC + (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 2; +} +void Op44(void) // LSRA +{ + (ar&0x01 ? ccr |= 0x01 : ccr &= 0xFE); // Shift low bit into carry + ar >>= 1; + (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 2; +} +void Op46(void) // RORA +{ + tmp = ar; ar = (tmp>>1) + (ccr&0x01)*128; + (tmp&0x01 ? ccr |= 0x01 : ccr &= 0xFE); // Shift bit into carry + (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 2; +} +void Op47(void) // ASRA +{ + (ar&0x01 ? ccr |= 0x01 : ccr &= 0xFE); // Shift bit into carry + ar >>= 1; // Do the shift + if (ar&0x40) ar |= 0x80; // Set neg if it was set + (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 2; +} +void Op48(void) // LSLA [Keep checking from here...] +{ + (ar&0x80 ? ccr |= 0x01 : ccr &= 0xFE); // Shift hi bit into carry + ar <<= 1; + (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 2; +} +void Op49(void) // ROLA +{ + tmp = ar; ar = (tmp<<1) + (ccr&0x01); + (tmp&0x80 ? ccr |= 0x01 : ccr &= 0xFE); // Shift hi bit into carry + (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 2; +} +void Op4A(void) // DECA +{ + ar--; + (ar == 0x7F ? ccr |= 0x02 : ccr &= 0xFD); // Adjust oVerflow flag + (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 2; +} +void Op4C(void) // INCA + { + ar++; + (ar == 0x80 ? ccr |= 0x02 : ccr &= 0xFD); // Adjust oVerflow flag + (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 2; + } +void Op4D(void) // TSTA + { + ccr &= 0xFD; // Clear oVerflow flag + (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 2; + } +void Op4F(void) // CLRA +{ + ar = 0; + ccr &= 0xF0; ccr |= 0x04; // Set NZVC + iclock += 2; +} +void Op50(void) // NEGB + { + br = 256 - br; +// ((br^tmp)&0x10 ? ccr |= 0x20 : ccr &= 0xDF); // Adjust H carry + (br == 0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + (br > 0x7F ? ccr |= 0x01 : ccr &= 0xFE); // Adjust carry + iclock += 2; + } +void Op53(void) // COMB + { + br ^= 0xFF; + ccr &= 0xFD; ccr |= 0x01; // CLV, SEC + (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 2; + } +void Op54(void) // LSRB + { + (br&0x01 ? ccr |= 0x01 : ccr &= 0xFE); // Shift low bit into carry + br >>= 1; + (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 2; + } +void Op56(void) // RORB + { + tmp = br; br = (br >> 1) + (ccr&0x01)*128; + (tmp&0x01 ? ccr |=0x01 : ccr &= 0xFE); // Shift bit into carry + (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 2; + } +void Op57(void) // ASRB + { + (br&0x01 ? ccr |= 0x01 : ccr &= 0xFE); // Shift bit into carry + br >>= 1; // Do the shift + if (br&0x40) br |= 0x80; // Set neg if it was set + (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 2; + } +void Op58(void) // LSLB + { + (br&0x80 ? ccr |= 0x01 : ccr &= 0xFE); // Shift hi bit into carry + br <<= 1; + (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 2; + } +void Op59(void) // ROLB +{ + tmp = br; + br = (tmp<<1) + (ccr&0x01); + (tmp&0x80 ? ccr |= 0x01 : ccr &= 0xFE); // Shift hi bit into carry + (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 2; +} +void Op5A(void) // DECB + { + br--; + (br == 0x7F ? ccr |= 0x02 : ccr &= 0xFD); // Adjust oVerflow flag + (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 2; + } +void Op5C(void) // INCB + { + br++; + (br == 0x80 ? ccr |= 0x02 : ccr &= 0xFD); // Adjust oVerflow flag + (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 2; + } +void Op5D(void) // TSTB + { + ccr &= 0xFD; // Clear oVerflow flag + (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 2; + } +void Op5F(void) // CLRB + { + br = 0; + ccr &= 0xF0; ccr |= 0x04; // Set NZVC + iclock += 2; + } +void Op60(void) // NEG IDX + { + addr = DecodeIDX(Fetch()); + tmp = RdMem(addr); BYTE res = 256 - tmp; + WrMem(addr, res); +// ((res^tmp)&0x10 ? ccr |= 0x20 : ccr &= 0xDF); // Adjust H carry + (res == 0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + (res == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (res&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + (res > 0x7F ? ccr |= 0x01 : ccr &= 0xFE); // Adjust carry + iclock += 6; + } +void Op63(void) // COM IDX + { + addr = DecodeIDX(Fetch()); + tmp = RdMem(addr) ^ 0xFF; + WrMem(addr, tmp); + ccr &= 0xFD; ccr |= 0x01; // CLV, SEC + (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 6; + } +void Op64(void) // LSR IDX + { + addr = DecodeIDX(Fetch()); + tmp = RdMem(addr); + (tmp&0x01 ? ccr |= 0x01 : ccr &= 0xFE); // Shift low bit into carry + tmp >>= 1; WrMem(addr, tmp); + ccr &= 0xF7; // CLN + (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + iclock += 6; + } +void Op66(void) // ROR IDX + { + addr = DecodeIDX(Fetch()); + tmp = RdMem(addr); BYTE tmp2 = tmp; + tmp = (tmp >> 1) + (ccr&0x01)*128; + WrMem(addr, tmp); + (tmp2&0x01 ? ccr |= 0x01 : ccr &= 0xFE); // Shift bit into carry + (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 6; + } +void Op67(void) // ASR IDX + { + addr = DecodeIDX(Fetch()); + tmp = RdMem(addr); + (tmp&0x01 ? ccr |= 0x01 : ccr &= 0xFE); // Shift bit into carry + tmp >>= 1; + if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set + WrMem(addr, tmp); + (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 6; + } +void Op68(void) // LSL IDX + { + addr = DecodeIDX(Fetch()); + tmp = RdMem(addr); + (tmp&0x80 ? ccr |= 0x01 : ccr &= 0xFE); // Shift hi bit into carry + tmp <<= 1; + WrMem(addr, tmp); + (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 6; + } +void Op69(void) // ROL IDX +{ + BYTE tmp2 = RdMem(DecodeIDX(Fetch())); + tmp = (tmp2<<1) + (ccr&0x01); + WrMem(addr, tmp); + (tmp2&0x80 ? ccr |= 0x01 : ccr &= 0xFE); // Shift hi bit into carry + (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 6; +} +void Op6A(void) // DEC IDX + { + BYTE tmp; WORD addr; + addr = DecodeIDX(Fetch()); + tmp = RdMem(addr) - 1; + WrMem(addr, tmp); + (tmp == 0x7F ? ccr |= 0x02 : ccr &= 0xFD); // Adjust oVerflow flag + (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 6; + } +void Op6C(void) // INC IDX + { + addr = DecodeIDX(Fetch()); + tmp = RdMem(addr) + 1; + WrMem(addr, tmp); + (tmp == 0x80 ? ccr |= 0x02 : ccr &= 0xFD); // Adjust oVerflow flag + (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 6; + } +void Op6D(void) // TST IDX + { + tmp = RdMem(DecodeIDX(Fetch())); + (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 6; + } +void Op6E(void) // JMP IDX +{ + pcr = DecodeIDX(Fetch()); + iclock += 3; +} +void Op6F(void) // CLR IDX +{ + addr = DecodeIDX(Fetch()); + WrMem(addr, 0); + ccr &= 0xF0; ccr |= 0x04; // Set NZVC + iclock += 6; +} +void Op70(void) // NEG ABS + { + addr = FetchW(); + tmp = RdMem(addr); BYTE res = 256 - tmp; + WrMem(addr, res); + (res == 0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + (res == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (res&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + (res > 0x7F ? ccr |= 0x01 : ccr &= 0xFE); // Adjust carry + iclock += 7; + } +void Op73(void) // COM ABS + { + addr = FetchW(); + tmp = RdMem(addr) ^ 0xFF; + WrMem(addr, tmp); + ccr &= 0xFD; ccr |= 0x01; // CLV, SEC + (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 7; + } +void Op74(void) // LSR ABS + { + addr = FetchW(); + tmp = RdMem(addr); + (tmp&0x01 ? ccr |= 0x01 : ccr &= 0xFE); // Shift low bit into carry + tmp >>= 1; WrMem(addr, tmp); + ccr &= 0xF7; // CLN + (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + iclock += 7; + } +void Op76(void) // ROR ABS + { + BYTE tmp; WORD addr; + addr = FetchW(); + tmp = RdMem(addr); BYTE tmp2 = tmp; + tmp = (tmp >> 1) + (ccr&0x01)*128; + WrMem(addr, tmp); + (tmp2&0x01 ? ccr |= 0x01 : ccr &= 0xFE); // Shift bit into carry + (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 7; + } +void Op77(void) // ASR ABS + { + BYTE tmp; WORD addr; + addr = FetchW(); + tmp = RdMem(addr); + (tmp&0x01 ? ccr |= 0x01 : ccr &= 0xFE); // Shift bit into carry + tmp >>= 1; + if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set + WrMem(addr, tmp); + (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 7; + } +void Op78(void) // LSL ABS + { + BYTE tmp; WORD addr; + addr = FetchW(); + tmp = RdMem(addr); + (tmp&0x80 ? ccr |= 0x01 : ccr &= 0xFE); // Shift hi bit into carry + tmp <<= 1; + WrMem(addr, tmp); + (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 7; + } +void Op79(void) // ROL ABS +{ + BYTE tmp2 = RdMem(FetchW()); + tmp = (tmp2<<1) + (ccr&0x01); + WrMem(addr, tmp); + (tmp2&0x80 ? ccr |= 0x01 : ccr &= 0xFE); // Shift hi bit into carry + (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 7; +} +void Op7A(void) // DEC ABS + { + BYTE tmp; WORD addr; + addr = FetchW(); + tmp = RdMem(addr) - 1; + WrMem(addr, tmp); + (tmp == 0x7F ? ccr |= 0x02 : ccr &= 0xFD); // Adjust oVerflow flag + (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 7; + } +void Op7C(void) // INC ABS + { + BYTE tmp; WORD addr; + addr = FetchW(); + tmp = RdMem(addr) + 1; + WrMem(addr, tmp); + (tmp == 0x80 ? ccr |= 0x02 : ccr &= 0xFD); // Adjust oVerflow flag + (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 7; + } + +void Op7D(void) // TST ABS +{ + BYTE tmp = RdMem(FetchW()); + + (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + + iclock += 7; +} + +void Op7E(void) // JMP ABS +{ + pcr = FetchW(); + iclock += 3; +} +void Op7F(void) // CLR ABS + { + WrMem(FetchW(), 0); + ccr &= 0xF0; ccr |= 0x04; // Set NZVC + iclock += 7; + } +void Op80(void) // SUBA # +{ + BYTE tmp = Fetch(); BYTE as = ar; + ar -= tmp; + (as < tmp ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + ((as^tmp^ar^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 2; +} +void Op81(void) // CMPA # +{ + tmp = Fetch(); + BYTE db = ar - tmp; + (ar < tmp ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + ((ar^tmp^db^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + (db == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (db&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 2; +} +void Op82(void) // SBCA # +{ + tmp = Fetch(); BYTE as = ar; + ar = ar - tmp - (ccr&0x01); + (as < (tmp+(ccr&0x01)) ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + ((as^tmp^ar^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 2; +} +void Op83(void) // SUBD # +{ + addr = FetchW(); WORD dr = (ar<<8)|br, ds = dr; + dr -= addr; + (ds < addr ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + ((ds^addr^dr^(ccr<<15))&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + (dr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (dr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + ar = dr>>8; br = dr&0xFF; + iclock += 4; +} +void Op84(void) // ANDA # + { + ar &= Fetch(); + ccr &= 0xFD; // Clear oVerflow flag + (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 2; + } +void Op85(void) // BITA # + { + tmp = ar & Fetch(); + ccr &= 0xFD; // Clear oVerflow flag + (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 2; + } +void Op86(void) // LDA # + { + ar = Fetch(); + ccr &= 0xFD; // CLV + (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 2; + } +void Op88(void) // EORA # + { + ar ^= Fetch(); + ccr &= 0xFD; // CLV + (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 2; + } +void Op89(void) // ADCA # +{ + tmp = Fetch(); + addr = (WORD)ar + (WORD)tmp + (WORD)(ccr&0x01); + (addr > 0x00FF ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry + ((ar^tmp^addr)&0x10 ? ccr |= 0x20 : ccr &= 0xDF); // Set Half carry + ((ar^tmp^addr^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + ar = addr & 0xFF; // Set accumulator + (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative + iclock += 2; +} +void Op8A(void) // ORA # + { + ar |= Fetch(); + ccr &= 0xFD; // CLV + (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 2; + } +void Op8B(void) // ADDA # +{ + tmp = Fetch(); addr = ar + tmp; + (addr > 0xFF ? ccr |= 0x01 : ccr &= 0xFE); // Set Carry flag + ((ar^tmp^addr)&0x10 ? ccr |= 0x20 : ccr &= 0xDF); // Set Half carry + ((ar^tmp^addr^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + ar = addr & 0xFF; // Set accumulator + (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Set Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Set Negative flag + iclock += 2; +} +void Op8C(void) // CMPX # +{ + addr = FetchW(); + WORD dw = xr - addr; + (xr < addr ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + ((xr^addr^dw^(ccr<<15))&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerfl + (dw == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 4; +} +void Op8D(void) // BSR + { + tmp = Fetch(); + WrMem(--sr, pcr&0xFF); WrMem(--sr, pcr>>8); + pcr += SignedB(tmp); + iclock += 7; + } +void Op8E(void) // LDX # + { + xr = FetchW(); + ccr &= 0xFD; // CLV + (xr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (xr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 3; + } +void Op90(void) // SUBA DP + { + tmp = RdMem((dpr<<8)|Fetch()); BYTE as = ar; + ar -= tmp; + (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + (as < tmp ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + ((as^tmp^ar^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + iclock += 4; + } +void Op91(void) // CMPA DP + { + tmp = RdMem((dpr<<8)|Fetch()); + BYTE db = ar - tmp; + (db == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (db&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + (ar < tmp ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + ((ar^tmp^db^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + iclock += 4; + } +void Op92(void) // SBCA DP +{ + tmp = RdMem((dpr<<8)|Fetch()); BYTE as = ar; + ar = ar - tmp - (ccr&0x01); + (as < (tmp+(ccr&0x01)) ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + ((as^tmp^ar^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 4; +} +void Op93(void) // SUBD DP +{ + addr = (dpr<<8)|Fetch(); WORD dr = (ar<<8)|br, ds = dr; + WORD adr2 = (RdMem(addr)<<8) | RdMem(addr+1); + dr -= adr2; + (ds < adr2 ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + ((ds^adr2^dr^(ccr<<15))&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + (dr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (dr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + ar = dr>>8; br = dr&0xFF; + iclock += 6; +} +void Op94(void) // ANDA DP +{ + ar &= RdMem((dpr<<8)|Fetch()); + ccr &= 0xF1; // CLV CLZ CLN + if (ar == 0) ccr |= 0x04; // Adjust Zero flag + if (ar&0x80) ccr |= 0x08; // Adjust Negative flag + iclock += 4; +} +void Op95(void) // BITA DP + { + tmp = ar & RdMem((dpr<<8)|Fetch()); + ccr &= 0xFD; // Clear oVerflow flag + (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 4; + } +void Op96(void) // LDA DP +{ + ar = RdMem((dpr<<8)|Fetch()); + ccr &= 0xF1; // CLN CLZ CLV + if (ar == 0) ccr |= 0x04; // Set Zero flag + if (ar&0x80) ccr |= 0x08; // Set Negative flag + iclock += 4; +} +void Op97(void) // STA DP + { + WrMem((dpr<<8)|Fetch(), ar); + ccr &= 0xFD; // CLV + (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 4; + } +void Op98(void) // EORA DP + { + ar ^= RdMem((dpr<<8)|Fetch()); + ccr &= 0xFD; // CLV + (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 4; + } +void Op99(void) // ADCA DP +{ + tmp = RdMem((dpr<<8)|Fetch()); + addr = (WORD)ar + (WORD)tmp + (WORD)(ccr&0x01); + (addr > 0x00FF ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry + ((ar^tmp^addr)&0x10 ? ccr |= 0x20 : ccr &= 0xDF); // Set Half carry + ((ar^tmp^addr^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + ar = addr & 0xFF; // Set accumulator + (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative + iclock += 4; +} +void Op9A(void) // ORA DP + { + ar |= RdMem((dpr<<8)|Fetch()); + ccr &= 0xFD; // CLV + (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 4; + } +void Op9B(void) // ADDA DP +{ + tmp = RdMem((dpr<<8)|Fetch()); + addr = (WORD)ar + (WORD)tmp; + (addr > 0x00FF ? ccr |= 0x01 : ccr &= 0xFE); // Set Carry flag + ((ar^tmp^addr)&0x10 ? ccr |= 0x20 : ccr &= 0xDF); // Set Half carry + ((ar^tmp^addr^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflo + ar = addr & 0xFF; // Set accumulator + (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Set Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Set Negative flag + iclock += 4; +} +void Op9C(void) // CMPX DP + { + addr = (dpr<<8)|Fetch(); + WORD adr2 = (RdMem(addr)<<8) | RdMem(addr+1); + WORD dw = xr - adr2; + (dw == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + (xr < adr2 ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + ((xr^adr2^dw^(ccr<<15))&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerfl + iclock += 6; + } +void Op9D(void) // JSR DP + { + addr = (dpr<<8) | Fetch(); + WrMem(--sr, pcr&0xFF); WrMem(--sr, pcr>>8); + pcr = addr; // JSR to DP location... + iclock += 7; + } +void Op9E(void) // LDX DP + { + addr = (dpr<<8) | Fetch(); + xr = (RdMem(addr) << 8) | RdMem(addr+1); + ccr &= 0xFD; // CLV + (xr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (xr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 5; + } +void Op9F(void) // STX DP + { + addr = (dpr<<8) | Fetch(); + WrMem(addr, xr>>8); WrMem(addr+1, xr&0xFF); + ccr &= 0xFD; // CLV + (xr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (xr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 5; + } +void OpA0(void) // SUBA IDX + { + tmp = RdMem(DecodeIDX(Fetch())); BYTE as = ar; + ar -= tmp; + (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + (as < tmp ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + ((as^tmp^ar^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + iclock += 4; + } +void OpA1(void) // CMPA IDX + { + tmp = RdMem(DecodeIDX(Fetch())); + BYTE db = ar - tmp; + (db == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (db&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + (ar < tmp ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + ((ar^tmp^db^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + iclock += 4; + } +void OpA2(void) // SBCA IDX +{ + tmp = RdMem(DecodeIDX(Fetch())); BYTE as = ar; + ar = ar - tmp - (ccr&0x01); + (as < (tmp+(ccr&0x01)) ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + ((as^tmp^ar^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 4; +} +void OpA3(void) // SUBD IDX +{ + addr = DecodeIDX(Fetch()); WORD dr = (ar<<8)|br, ds = dr; + WORD adr2 = (RdMem(addr)<<8) | RdMem(addr+1); + dr -= adr2; + (ds < adr2 ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + ((ds^adr2^dr^(ccr<<15))&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + (dr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (dr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + ar = dr>>8; br = dr&0xFF; + iclock += 6; +} +void OpA4(void) // ANDA IDX + { + ar &= RdMem(DecodeIDX(Fetch())); + ccr &= 0xFD; // Clear oVerflow flag + (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 4; + } +void OpA5(void) // BITA IDX + { + tmp = ar & RdMem(DecodeIDX(Fetch())); + ccr &= 0xFD; // Clear oVerflow flag + (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 4; + } +void OpA6(void) // LDA IDX +{ + ar = RdMem(DecodeIDX(Fetch())); + ccr &= 0xF1; // CLV CLZ CLN + if (ar == 0) ccr |= 0x04; // Set Zero flag + if (ar&0x80) ccr |= 0x08; // Set Negative flag + iclock += 4; +} +void OpA7(void) // STA IDX +{ + WrMem(DecodeIDX(Fetch()), ar); + ccr &= 0xF1; // CLV CLZ CLN + if (ar == 0) ccr |= 0x04; // Set Zero flag + if (ar&0x80) ccr |= 0x08; // Set Negative flag + iclock += 4; +} +void OpA8(void) // EORA IDX + { + ar ^= RdMem(DecodeIDX(Fetch())); + ccr &= 0xFD; // CLV + (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 4; + } +void OpA9(void) // ADCA IDX +{ + tmp = RdMem(DecodeIDX(Fetch())); + addr = (WORD)ar + (WORD)tmp + (WORD)(ccr&0x01); + (addr > 0x00FF ? ccr |= 0x01 : ccr &= 0xFE); // Set Carry flag + ((ar^tmp^addr)&0x10 ? ccr |= 0x20 : ccr &= 0xDF); // Set Half carry + ((ar^tmp^addr^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflo + ar = addr & 0xFF; // Set accumulator + (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Set Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Set Negative flag + iclock += 4; +} +void OpAA(void) // ORA IDX +{ + ar |= RdMem(DecodeIDX(Fetch())); + ccr &= 0xFD; // CLV + (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 4; +} +void OpAB(void) // ADDA IDX +{ + tmp = RdMem(DecodeIDX(Fetch())); + addr = (WORD)ar + (WORD)tmp; + (addr > 0x00FF ? ccr |= 0x01 : ccr &= 0xFE); // Set Carry flag + ((ar^tmp^addr)&0x10 ? ccr |= 0x20 : ccr &= 0xDF); // Set Half carry + ((ar^tmp^addr^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflo + ar = addr & 0xFF; // Set accumulator + (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Set Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Set Negative flag + iclock += 4; +} +void OpAC(void) // CMPX IDX +{ + addr = DecodeIDX(Fetch()); + WORD addr2 = (RdMem(addr)<<8) | RdMem(addr+1); + WORD dw = xr - addr2; + (dw == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + (xr < addr2 ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + ((xr^addr2^dw^(ccr<<15))&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + iclock += 6; +} +void OpAD(void) // JSR IDX +{ + addr = DecodeIDX(Fetch()); + WrMem(--sr, pcr&0xFF); WrMem(--sr, pcr>>8); + pcr = addr; // JSR directly to IDX ptr + iclock += 7; +} +void OpAE(void) // LDX IDX +{ + addr = DecodeIDX(Fetch()); + xr = (RdMem(addr) << 8) | RdMem(addr+1); + ccr &= 0xFD; // CLV + (xr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (xr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 5; +} +void OpAF(void) // STX IDX +{ + addr = DecodeIDX(Fetch()); + WrMem(addr, xr>>8); WrMem(addr+1, xr&0xFF); + ccr &= 0xF1; // CLV CLZ CLN + if (xr == 0) ccr |= 0x04; // Set Zero flag + if (xr&0x8000) ccr |= 0x08; // Set Negative flag + iclock += 5; +} +void OpB0(void) // SUBA ABS + { + tmp = RdMem(FetchW()); BYTE as = ar; + ar -= tmp; + (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + (as < tmp ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + ((as^tmp^ar^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + iclock += 5; + } +void OpB1(void) // CMPA ABS + { + tmp = RdMem(FetchW()); + BYTE db = ar - tmp; + (db == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (db&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + (ar < tmp ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + ((ar^tmp^db^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + iclock += 5; + } +void OpB2(void) // SBCA ABS +{ + tmp = RdMem(FetchW()); BYTE as = ar; + ar = ar - tmp - (ccr&0x01); + (as < (tmp+(ccr&0x01)) ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + ((as^tmp^ar^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 5; +} +void OpB3(void) // SUBD ABS +{ + addr = FetchW(); WORD dr = (ar<<8)|br, ds = dr; + WORD adr2 = (RdMem(addr)<<8) | RdMem(addr+1); + dr -= adr2; + (ds < adr2 ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + ((ds^adr2^dr^(ccr<<15))&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerfl + (dr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (dr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + ar = dr>>8; br = dr&0xFF; + iclock += 7; +} +void OpB4(void) // ANDA ABS +{ + ar &= RdMem(FetchW()); + ccr &= 0xFD; // Clear oVerflow flag + (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 5; +} +void OpB5(void) // BITA ABS +{ + tmp = ar & RdMem(FetchW()); + ccr &= 0xFD; // Clear oVerflow flag + (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 5; +} +void OpB6(void) // LDA ABS +{ + ar = RdMem(FetchW()); + ccr &= 0xFD; // CLV + (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 5; +} +void OpB7(void) // STA ABS +{ + WrMem(FetchW(), ar); + ccr &= 0xFD; // CLV + (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 5; +} +void OpB8(void) // EORA ABS +{ + ar ^= RdMem(FetchW()); + ccr &= 0xFD; // CLV + (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 5; +} +void OpB9(void) // ADCA ABS +{ + tmp = RdMem(FetchW()); + addr = (WORD)ar + (WORD)tmp + (WORD)(ccr&0x01); + (addr > 0x00FF ? ccr |= 0x01 : ccr &= 0xFE); // Set Carry flag + ((ar^tmp^addr)&0x10 ? ccr |= 0x20 : ccr &= 0xDF); // Set Half carry + ((ar^tmp^addr^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + ar = addr; // Set accumulator + (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Set Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Set Negative flag + iclock += 5; +} +void OpBA(void) // ORA ABS +{ + ar |= RdMem(FetchW()); + ccr &= 0xFD; // CLV + (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 5; +} +void OpBB(void) // ADDA ABS +{ + tmp = RdMem(FetchW()); + addr = (WORD)ar + (WORD)tmp; + (addr > 0x00FF ? ccr |= 0x01 : ccr &= 0xFE); // Set Carry flag + ((ar^tmp^addr)&0x10 ? ccr |= 0x20 : ccr &= 0xDF); // Set Half carry + ((ar^tmp^addr^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflo + ar = addr & 0xFF; // Set accumulator + (ar == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Set Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Set Negative flag + iclock += 5; +} +void OpBC(void) // CMPX ABS +{ + addr = FetchW(); WORD addr2 = (RdMem(addr)<<8) | RdMem(addr+1); + WORD dw = xr - addr2; + (dw == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + (xr < addr2 ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + ((xr^addr2^dw^(ccr<<15))&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + iclock += 7; +} +void OpBD(void) // JSR ABS +{ + addr = FetchW(); + WrMem(--sr, pcr&0xFF); WrMem(--sr, pcr>>8); + pcr = addr; // Go to absolute address (Not indir) + iclock += 8; +} +void OpBE(void) // LDX ABS +{ + addr = FetchW(); + xr = (RdMem(addr) << 8) | RdMem(addr+1); + ccr &= 0xFD; // CLV + (xr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (xr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 6; +} +void OpBF(void) // STX ABS + { + addr = FetchW(); + WrMem(addr, xr>>8); WrMem(addr+1, xr&0xFF); + ccr &= 0xFD; // CLV + (xr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (xr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 6; + } +void OpC0(void) // SUBB # + { + tmp = Fetch(); BYTE bs = br; + br -= tmp; + (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + (bs < tmp ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + ((bs^tmp^br^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + iclock += 2; + } +void OpC1(void) // CMPB # + { + tmp = Fetch(); + BYTE db = br - tmp; + (br < tmp ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + ((br^tmp^db^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + (db == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (db&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 2; + } +void OpC2(void) // SBCB # +{ + tmp = Fetch(); BYTE bs = br; + br = br - tmp - (ccr&0x01); + (bs < (tmp+(ccr&0x01)) ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + ((bs^tmp^br^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 2; +} +void OpC3(void) // ADDD # +{ + addr = FetchW(); long dr = ((ar<<8)|br)&0xFFFF, ds = dr; + dr += addr; + (dr > 0xFFFF ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + dr &= 0xFFFF; + (dr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (dr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + ((ds^addr^dr^(ccr<<15))&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerfl + ar = dr>>8; br = dr&0xFF; + iclock += 4; +} +void OpC4(void) // ANDB # + { + br &= Fetch(); + ccr &= 0xFD; // Clear oVerflow flag + (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 2; + } +void OpC5(void) // BITB # +{ + tmp = br & Fetch(); + ccr &= 0xF1; // CLV CLZ CLN + if (tmp == 0) ccr |= 0x04; // Set Zero flag + if (tmp&0x80) ccr |= 0x08; // Set Negative flag + iclock += 2; +} +void OpC6(void) // LDB # +{ + br = Fetch(); + ccr &= 0xF1; // CLV CLZ CLN + if (br == 0) ccr |= 0x04; // Set Zero flag + if (br&0x80) ccr |= 0x08; // Set Negative flag + iclock += 2; +} +void OpC8(void) // EORB # + { + br ^= Fetch(); + ccr &= 0xFD; // CLV + (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 2; + } +void OpC9(void) // ADCB # +{ + tmp = Fetch(); + addr = (WORD)br + (WORD)tmp + (WORD)(ccr&0x01); + (addr > 0x00FF ? ccr |= 0x01 : ccr &= 0xFE); // Set Carry flag + ((br^tmp^addr)&0x10 ? ccr |= 0x20 : ccr &= 0xDF); // Set Half carry + ((br^tmp^addr^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflo + br = addr & 0xFF; // Set accumulator + (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Set Zero flag + (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Set Negative flag + iclock += 2; +} +void OpCA(void) // ORB # + { + br |= Fetch(); + ccr &= 0xFD; // CLV + (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 2; + } +void OpCB(void) // ADDB # +{ + tmp = Fetch(); addr = br + tmp; + (addr > 0xFF ? ccr |= 0x01 : ccr &= 0xFE); // Set Carry flag + ((br^tmp^addr)&0x10 ? ccr |= 0x20 : ccr &= 0xDF); // Set Half carry + ((br^tmp^addr^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflo + br = addr & 0xFF; // Set accumulator + (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Set Zero flag + (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Set Negative flag + iclock += 2; +} +void OpCC(void) // LDD # +{ + ar = Fetch(); br = Fetch(); + ccr &= 0xFD; // CLV + ((ar+br) == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 3; +} +void OpCE(void) // LDU # +{ + ur = FetchW(); + ccr &= 0xFD; // CLV + (ur == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (ur&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 3; +} +void OpD0(void) // SUBB DP +{ + tmp = RdMem((dpr<<8)|Fetch()); BYTE bs = br; + br -= tmp; + (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + (bs < tmp ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + ((bs^tmp^br^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + iclock += 4; +} +void OpD1(void) // CMPB DP +{ + tmp = RdMem((dpr<<8)|Fetch()); + BYTE db = br - tmp; + (db == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (db&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + (br < tmp ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + ((br^tmp^db^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + iclock += 4; +} +void OpD2(void) // SBCB DP +{ + tmp = RdMem((dpr<<8)|Fetch()); BYTE bs = br; + br = br - tmp - (ccr&0x01); + (bs < (tmp+(ccr&0x01)) ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + ((bs^tmp^br^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 4; +} +void OpD3(void) // ADDD DP +{ + addr = (dpr<<8)|Fetch(); long dr = ((ar<<8)|br)&0xFFFF, ds = dr; + WORD adr2 = (RdMem(addr)<<8)|RdMem(addr+1); + dr += adr2; + (dr > 0xFFFF ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + dr &= 0xFFFF; + (dr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (dr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + ((ds^adr2^dr^(ccr<<15))&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + ar = dr>>8; br = dr&0xFF; + iclock += 6; +} +void OpD4(void) // ANDB DP + { + br &= RdMem((dpr<<8)|Fetch()); + ccr &= 0xFD; // Clear oVerflow flag + (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 4; + } +void OpD5(void) // BITB DP + { + tmp = br & RdMem((dpr<<8)|Fetch()); + ccr &= 0xFD; // Clear oVerflow flag + (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 4; + } +void OpD6(void) // LDB DP +{ + br = RdMem((dpr<<8)|Fetch()); + ccr &= 0xFD; // CLV + (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 4; +} +void OpD7(void) // STB DP + { + WrMem((dpr<<8)|Fetch(), br); + ccr &= 0xFD; // CLV + (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 4; + } +void OpD8(void) // EORB DP + { + br ^= RdMem((dpr<<8)|Fetch()); + ccr &= 0xFD; // CLV + (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 4; + } +void OpD9(void) // ADCB DP +{ + tmp = RdMem((dpr<<8)|Fetch()); + addr = (WORD)br + (WORD)tmp + (WORD)(ccr&0x01); + (addr > 0x00FF ? ccr |= 0x01 : ccr &= 0xFE); // Set Carry flag + ((br^tmp^addr)&0x10 ? ccr |= 0x20 : ccr &= 0xDF); // Set Half carry + ((br^tmp^addr^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + br = addr; // Set accumulator + (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Set Zero flag + (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Set Negative flag + iclock += 4; +} +void OpDA(void) // ORB DP + { + br |= RdMem((dpr<<8)|Fetch()); + ccr &= 0xFD; // CLV + (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 4; + } +void OpDB(void) // ADDB DP +{ + tmp = RdMem((dpr<<8)|Fetch()); + addr = (WORD)br + (WORD)tmp; + (addr > 0x00FF ? ccr |= 0x01 : ccr &= 0xFE); // Set Carry flag + ((br^tmp^addr)&0x10 ? ccr |= 0x20 : ccr &= 0xDF); // Set Half carry + ((br^tmp^addr^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + br = addr & 0xFF; // Set accumulator + (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Set Zero flag + (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Set Negative flag + iclock += 4; +} +void OpDC(void) // LDD DP +{ + addr = (dpr<<8)|Fetch(); + ar = RdMem(addr); br = RdMem(addr+1); + ccr &= 0xFD; // CLV + ((ar|br) == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 5; +} +void OpDD(void) // STD DP +{ + addr = (dpr<<8)|Fetch(); + WrMem(addr, ar); WrMem(addr+1, br); + ccr &= 0xFD; // CLV + ((ar|br) == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 5; +} +void OpDE(void) // LDU DP +{ + addr = (dpr<<8)|Fetch(); + ur = (RdMem(addr) << 8) | RdMem(addr+1); + ccr &= 0xFD; // CLV + (ur == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (ur&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 5; +} +void OpDF(void) // STU DP +{ + addr = (dpr<<8)|Fetch(); + WrMem(addr, ur>>8); WrMem(addr+1, ur&0xFF); + ccr &= 0xFD; // CLV + (ur == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (ur&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 5; +} +void OpE0(void) // SUBB IDX +{ + tmp = RdMem(DecodeIDX(Fetch())); BYTE bs = br; + br -= tmp; + (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + (bs < tmp ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + ((bs^tmp^br^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + iclock += 4; +} +void OpE1(void) // CMPB IDX +{ + tmp = RdMem(DecodeIDX(Fetch())); + BYTE db = br - tmp; + (db == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (db&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + (br < tmp ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + ((br^tmp^db^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + iclock += 4; +} +void OpE2(void) // SBCB IDX +{ + tmp = RdMem(DecodeIDX(Fetch())); BYTE bs = br; + br = br - tmp - (ccr&0x01); + (bs < (tmp+(ccr&0x01)) ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + ((bs^tmp^br^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 4; +} +void OpE3(void) // ADDD IDX +{ + addr = DecodeIDX(Fetch()); long dr = ((ar<<8)|br)&0xFFFF, ds = dr; + WORD adr2 = (RdMem(addr)<<8)|RdMem(addr+1); + dr += adr2; + (dr > 0xFFFF ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + dr &= 0xFFFF; + (dr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (dr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + ((ds^adr2^dr^(ccr<<15))&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + ar = dr>>8; br = dr&0xFF; + iclock += 6; +} +void OpE4(void) // ANDB IDX + { + br &= RdMem(DecodeIDX(Fetch())); + ccr &= 0xFD; // Clear oVerflow flag + (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 4; + } +void OpE5(void) // BITB IDX + { + tmp = br & RdMem(DecodeIDX(Fetch())); + ccr &= 0xFD; // Clear oVerflow flag + (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 4; + } +void OpE6(void) // LDB IDX + { + br = RdMem(DecodeIDX(Fetch())); + ccr &= 0xFD; // CLV + (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 4; + } +void OpE7(void) // STB IDX +{ + WrMem(DecodeIDX(Fetch()), br); + ccr &= 0xF1; // CLV CLZ CLN + if (br == 0) ccr |= 0x04; // Adjust Zero flag + if (br&0x80) ccr |= 0x08; // Adjust Negative flag + iclock += 4; +} +void OpE8(void) // EORB IDX + { + br ^= RdMem(DecodeIDX(Fetch())); + ccr &= 0xFD; // CLV + (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 4; + } +void OpE9(void) // ADCB IDX +{ + tmp = RdMem(DecodeIDX(Fetch())); + addr = (WORD)br + (WORD)tmp + (WORD)(ccr&0x01); + (addr > 0x00FF ? ccr |= 0x01 : ccr &= 0xFE); // Set Carry flag + ((br^tmp^addr)&0x10 ? ccr |= 0x20 : ccr &= 0xDF); // Set Half carry + ((br^tmp^addr^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + br = addr; // Set accumulator + (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Set Zero flag + (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Set Negative flag + iclock += 4; +} +void OpEA(void) // ORB IDX + { + br |= RdMem(DecodeIDX(Fetch())); + ccr &= 0xFD; // CLV + (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 4; + } +void OpEB(void) // ADDB IDX +{ + tmp = RdMem(DecodeIDX(Fetch())); + addr = (WORD)br + (WORD)tmp; + (addr > 0x00FF ? ccr |= 0x01 : ccr &= 0xFE); // Set Carry flag + ((br^tmp^addr)&0x10 ? ccr |= 0x20 : ccr &= 0xDF); // Set Half carry + ((br^tmp^addr^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + br = addr; // Set accumulator + (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Set Zero flag + (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Set Negative flag + iclock += 4; +} +void OpEC(void) // LDD IDX +{ + addr = DecodeIDX(Fetch()); + ar = RdMem(addr); br = RdMem(addr+1); + ccr &= 0xF1; // CLV CLZ CLN + if (!(ar|br)) ccr |= 0x04; // Adjust Zero flag + if (ar&0x80) ccr |= 0x08; // Adjust Negative flag + iclock += 5; +} +void OpED(void) // STD IDX +{ + addr = DecodeIDX(Fetch()); + WrMem(addr, ar); WrMem(addr+1, br); + ccr &= 0xF1; // CLV CLZ CLZ + if (!(ar|br)) ccr |= 0x04; // Adjust Zero flag + if (ar&0x80) ccr |= 0x08; // Adjust Negative flag + iclock += 5; +} +void OpEE(void) // LDU IDX +{ + addr = DecodeIDX(Fetch()); + ur = (RdMem(addr) << 8) | RdMem(addr+1); + ccr &= 0xF1; // CLV CLZ CLN + if (ur == 0) ccr |= 0x04; // Set Zero flag + if (ur&0x8000) ccr |= 0x08; // Set Negative flag + iclock += 5; +} +void OpEF(void) // STU IDX +{ + addr = DecodeIDX(Fetch()); + WrMem(addr, ur>>8); WrMem(addr+1, ur&0xFF); + ccr &= 0xF1; // CLV CLZ CLN + if (ur == 0) ccr |= 0x04; // Set Zero flag + if (ur&0x8000) ccr |= 0x08; // Set Negative flag + iclock += 5; +} +void OpF0(void) // SUBB ABS + { + tmp = RdMem(FetchW()); BYTE bs = br; + br -= tmp; + (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + (bs < tmp ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + ((bs^tmp^br^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + } +void OpF1(void) // CMPB ABS + { + tmp = RdMem(FetchW()); + BYTE db = br - tmp; + (db == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (db&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + (br < tmp ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + ((br^tmp^db^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + iclock += 5; + } +void OpF2(void) // SBCB ABS +{ + tmp = RdMem(FetchW()); BYTE bs = br; + br = br - tmp - (ccr&0x01); + (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + (bs < tmp ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + ((bs^tmp^br^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflow + iclock += 5; +} +void OpF3(void) // ADDD ABS +{ + addr = FetchW(); long dr = ((ar<<8)|br)&0xFFFF, ds = dr; + WORD adr2 = (RdMem(addr)<<8)|RdMem(addr+1); + dr += adr2; + (dr > 0xFFFF ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + dr &= 0xFFFF; + (dr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (dr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + ((ds^adr2^dr^(ccr<<15))&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerfl + ar = dr>>8; br = dr&0xFF; + iclock += 7; +} +void OpF4(void) // ANDB ABS + { + br &= RdMem(FetchW()); + ccr &= 0xFD; // Clear oVerflow flag + (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 5; + } +void OpF5(void) // BITB ABS + { + tmp = br & RdMem(FetchW()); + ccr &= 0xFD; // Clear oVerflow flag + (tmp == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (tmp&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 5; + } +void OpF6(void) // LDB ABS + { + br = RdMem(FetchW()); + ccr &= 0xFD; // CLV + (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 5; + } +void OpF7(void) // STB ABS + { + WrMem(FetchW(), br); + ccr &= 0xFD; // CLV + (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 5; + } +void OpF8(void) // EORB ABS + { + br ^= RdMem(FetchW()); + ccr &= 0xFD; // CLV + (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 5; + } +void OpF9(void) // ADCB ABS +{ + tmp = RdMem(FetchW()); + addr = (WORD)br + (WORD)tmp + (WORD)(ccr&0x01); + (addr > 0x00FF ? ccr |= 0x01 : ccr &= 0xFE); // Set Carry flag + ((br^tmp^addr)&0x10 ? ccr |= 0x20 : ccr &= 0xDF); // Set Half carry + ((br^tmp^addr^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflo + br = addr & 0xFF; // Set accumulator + (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Set Zero flag + (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Set Negative flag + iclock += 5; +} +void OpFA(void) // ORB ABS + { + br |= RdMem(FetchW()); + ccr &= 0xFD; // CLV + (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 5; + } +void OpFB(void) // ADDB ABS +{ + tmp = RdMem(FetchW()); + addr = (WORD)br + (WORD)tmp; + (addr > 0x00FF ? ccr |= 0x01 : ccr &= 0xFE); // Set Carry flag + ((br^tmp^addr)&0x10 ? ccr |= 0x20 : ccr &= 0xDF); // Set Half carry + ((br^tmp^addr^(ccr<<7))&0x80 ? ccr |= 0x02 : ccr &= 0xFD); // oVerflo + br = addr & 0xFF; // Set accumulator + (br == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Set Zero flag + (br&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Set Negative flag + iclock += 5; +} +void OpFC(void) // LDD ABS + { + addr = FetchW(); + ar = RdMem(addr); br = RdMem(addr+1); + ccr &= 0xFD; // CLV + ((ar+br) == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 6; + } +void OpFD(void) // STD ABS + { + addr = FetchW(); + WrMem(addr, ar); WrMem(addr+1, br); + ccr &= 0xFD; // CLV + ((ar+br) == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (ar&0x80 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 6; + } +void OpFE(void) // LDU ABS + { + addr = FetchW(); + ur = (RdMem(addr) << 8) | RdMem(addr+1); + ccr &= 0xFD; // CLV + (ur == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (ur&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 6; + } +void OpFF(void) // STU ABS + { + addr = FetchW(); + WrMem(addr, ur>>8); WrMem(addr+1, ur&0xFF); + ccr &= 0xFD; // CLV + (ur == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (ur&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 6; + } + +// +// Page one opcodes' execute code +// + +void Op1021(void) // LBRN +{ + addr = FetchW(); + iclock += 5; +} +void Op1022(void) // LBHI +{ + addr = FetchW(); + if (!((ccr&0x01)|(ccr&0x04))) pcr += SignedW(addr); + iclock += 5; +} +void Op1023(void) // LBLS +{ + addr = FetchW(); + if ((ccr&0x01)|(ccr&0x04)) pcr += SignedW(addr); + iclock += 5; +} +void Op1024(void) // LBCC (LBHS) +{ + addr = FetchW(); + if (!(ccr&0x01)) pcr += SignedW(addr); + iclock += 5; +} +void Op1025(void) // LBCS (LBLO) +{ + addr = FetchW(); + if (ccr&0x01) pcr += SignedW(addr); + iclock += 5; +} +void Op1026(void) // LBNE +{ + addr = FetchW(); + if (!(ccr&0x04)) pcr += SignedW(addr); + iclock += 5; +} +void Op1027(void) // LBEQ +{ + addr = FetchW(); + if (ccr&0x04) pcr += SignedW(addr); + iclock += 5; +} +void Op1028(void) // LBVC +{ + addr = FetchW(); + if (!(ccr&0x02)) pcr += SignedW(addr); + iclock += 5; +} +void Op1029(void) // LBVS +{ + addr = FetchW(); + if (ccr&0x02) pcr += SignedW(addr); + iclock += 5; +} +void Op102A(void) // LBPL +{ + addr = FetchW(); + if (!(ccr&0x08)) pcr += SignedW(addr); + iclock += 5; +} +void Op102B(void) // LBMI +{ + addr = FetchW(); + if (ccr&0x08) pcr += SignedW(addr); + iclock += 5; +} +void Op102C(void) // LBGE +{ + addr = FetchW(); + if (!(((ccr&0x08) >> 2) ^ (ccr&0x02))) pcr += SignedW(addr); + iclock += 5; +} +void Op102D(void) // LBLT +{ + addr = FetchW(); + if (((ccr&0x08) >> 2) ^ (ccr&0x02)) pcr += SignedW(addr); + iclock += 5; +} +void Op102E(void) // LBGT +{ + addr = FetchW(); + if (!((ccr&0x04) | (((ccr&0x08) >> 2) ^ (ccr&0x02)))) pcr += SignedW(addr); + iclock += 5; +} +void Op102F(void) // LBLE +{ + addr = FetchW(); + if ((ccr&0x04) | (((ccr&0x08) >> 2) ^ (ccr&0x02))) pcr += SignedW(addr); + iclock += 5; +} +void Op103F(void) // SWI2 (Not yet implemented) +{ + iclock += 20; +} +void Op1083(void) // CMPD # + { + addr = FetchW(); WORD dr = (ar<<8)|br; + WORD dw = dr - addr; + (dw == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + (dr < addr ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + ((dr^addr^dw^((WORD)ccr<<15))&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerfl + iclock += 5; + } +void Op108C(void) // CMPY # + { + addr = FetchW(); + WORD dw = yr - addr; + (dw == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + (yr < addr ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + ((yr^addr^dw^(ccr<<15))&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerfl + iclock += 5; + } +void Op108E(void) // LDY # + { + yr = FetchW(); + ccr &= 0xFD; // CLV + (yr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (yr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 4; + } +void Op1093(void) // CMPD DP + { + WORD adr2 = (dpr<<8)|Fetch(), dr = (ar<<8)|br; + addr = (RdMem(adr2)<<8) | RdMem(adr2+1); + WORD dw = dr - addr; + (dw == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + (dr < addr ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + ((dr^addr^dw^(ccr<<15))&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerfl + iclock += 7; + } +void Op109C(void) // CMPY DP + { + WORD adr2 = (dpr<<8)|Fetch(); + addr = (RdMem(adr2)<<8) | RdMem(adr2+1); + WORD dw = yr - addr; + (dw == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + (yr < addr ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + ((yr^addr^dw^(ccr<<15))&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerfl + iclock += 7; + } +void Op109E(void) // LDY DP + { + addr = (dpr<<8)|Fetch(); + yr = (RdMem(addr)<<8) | RdMem(addr+1); + ccr &= 0xFD; // CLV + (yr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (yr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 6; + } +void Op109F(void) // STY DP + { + addr = (dpr<<8)|Fetch(); + WrMem(addr, yr>>8); WrMem(addr+1, yr&0xFF); + ccr &= 0xFD; // CLV + (yr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (yr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 6; + } +void Op10A3(void) // CMPD IDX +{ + WORD adr2 = DecodeIDX(Fetch()), dr = (ar<<8)|br; + addr = (RdMem(adr2)<<8) | RdMem(adr2+1); + WORD dw = dr - addr; + ccr &= 0xF0; // CLC CLV CLZ CLN + if (dr < addr) ccr |= 0x01; // Set Carry flag + if ((dr^addr^dw^(ccr<<15))&0x8000) ccr |= 0x02; // Set oVerflow + if (dw == 0) ccr |= 0x04; // Set Zero flag + if (dw&0x8000) ccr |= 0x08; // Set Negative flag + iclock += 7; +} +void Op10AC(void) // CMPY IDX + { + WORD adr2 = DecodeIDX(Fetch()); + addr = (RdMem(adr2)<<8) | RdMem(adr2+1); + WORD dw = yr - addr; + (dw == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + (yr < addr ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + (((ccr<<15)^yr^addr^dw)&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerfl + iclock += 7; + } +void Op10AE(void) // LDY IDX +{ + addr = DecodeIDX(Fetch()); + yr = (RdMem(addr)<<8) | RdMem(addr+1); + ccr &= 0xF1; // CLV CLZ CLN + if (yr == 0) ccr |= 0x04; // Adjust Zero flag + if (yr&0x8000) ccr |= 0x08; // Adjust Negative flag + iclock += 6; +} +void Op10AF(void) // STY IDX + { + addr = DecodeIDX(Fetch()); + WrMem(addr, yr>>8); WrMem(addr+1, yr&0xFF); + ccr &= 0xFD; // CLV + (yr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (yr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 6; + } +void Op10B3(void) // CMPD ABS + { + addr = FetchW(); WORD dr = (ar<<8)|br; + WORD addr2 = (RdMem(addr)<<8) | RdMem(addr+1); + WORD dw = dr - addr2; + (dw == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + (dr < addr2 ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + (((ccr<<15)^dr^addr2^dw)&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerfl + iclock += 8; + } +void Op10BC(void) // CMPY ABS + { + addr = FetchW(); WORD addr2 = (RdMem(addr)<<8) | RdMem(addr+1); + WORD dw = yr - addr2; + (dw == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + (yr < addr2 ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + (((ccr<<15)^yr^addr2^dw)&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerfl + iclock += 8; + } +void Op10BE(void) // LDY ABS + { + addr = FetchW(); + yr = (RdMem(addr)<<8) | RdMem(addr+1); + ccr &= 0xFD; // CLV + (yr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (yr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 7; + } +void Op10BF(void) // STY ABS + { + addr = FetchW(); + WrMem(addr, yr>>8); WrMem(addr+1, yr&0xFF); + ccr &= 0xFD; // CLV + (yr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (yr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 7; + } +void Op10CE(void) // LDS # + { + sr = FetchW(); + ccr &= 0xFD; // CLV + (sr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (sr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 4; + } +void Op10DE(void) // LDS DP + { + addr = (dpr<<8)|Fetch(); + sr = (RdMem(addr)<<8) | RdMem(addr+1); + ccr &= 0xFD; // CLV + (sr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (sr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 6; + } +void Op10DF(void) // STS DP + { + addr = (dpr<<8)|Fetch(); + WrMem(addr, sr>>8); WrMem(addr+1, sr&0xFF); + ccr &= 0xFD; // CLV + (sr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (sr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 6; + } +void Op10EE(void) // LDS IDX + { + addr = DecodeIDX(Fetch()); + sr = (RdMem(addr)<<8) | RdMem(addr+1); + ccr &= 0xFD; // CLV + (sr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (sr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 6; + } +void Op10EF(void) // STS IDX + { + addr = DecodeIDX(Fetch()); + WrMem(addr, sr>>8); WrMem(addr+1, sr&0xFF); + ccr &= 0xFD; // CLV + (sr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (sr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 6; + } +void Op10FE(void) // LDS ABS + { + addr = FetchW(); + sr = (RdMem(addr)<<8) | RdMem(addr+1); + ccr &= 0xFD; // CLV + (sr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (sr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 7; + } +void Op10FF(void) // STS ABS +{ + addr = FetchW(); + WrMem(addr, sr>>8); WrMem(addr+1, sr&0xFF); + ccr &= 0xFD; // CLV + (sr == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (sr&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + iclock += 7; +} + +// +// Page two opcodes' execute code +// + +void Op113F(void) // SWI3 + { + iclock += 20; + } +void Op1183(void) // CMPU # + { + addr = FetchW(); + WORD dw = ur - addr; + (dw == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + (ur < addr ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + (((ccr<<15)^ur^addr^dw)&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerfl + iclock += 5; + } +void Op118C(void) // CMPS # + { + addr = FetchW(); + WORD dw = sr - addr; + (dw == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + (sr < addr ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + (((ccr<<15)^sr^addr^dw)&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerfl + iclock += 5; + } +void Op1193(void) // CMPU DP + { + WORD adr2 = (dpr<<8)|Fetch(); + addr = (RdMem(adr2)<<8) | RdMem(adr2+1); + WORD dw = ur - addr; + (dw == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + (ur < addr ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + (((ccr<<15)^ur^addr^dw)&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerfl + iclock += 7; + } +void Op119C(void) // CMPS DP + { + WORD adr2 = (dpr<<8)|Fetch(); + addr = (RdMem(adr2)<<8) | RdMem(adr2+1); + WORD dw = sr - addr; + (dw == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + (sr < addr ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + (((ccr<<15)^sr^addr^dw)&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerfl + iclock += 7; + } +void Op11A3(void) // CMPU IDX + { + WORD addr2 = DecodeIDX(Fetch()); + addr = (RdMem(addr2)<<8) | RdMem(addr2+1); + WORD dw = ur - addr; + (dw == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + (ur < addr ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + (((ccr<<15)^ur^addr^dw)&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerfl + iclock += 7; + } +void Op11AC(void) // CMPS IDX + { + WORD addr2 = DecodeIDX(Fetch()); + addr = (RdMem(addr2)<<8) | RdMem(addr2+1); + WORD dw = sr - addr; + (dw == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + (sr < addr ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + (((ccr<<15)^sr^addr^dw)&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerfl + iclock += 7; + } +void Op11B3(void) // CMPU ABS + { + addr = FetchW(); WORD addr2 = (RdMem(addr)<<8) | RdMem(addr+1); + WORD dw = ur - addr2; + (dw == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + (ur < addr2 ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + (((ccr<<15)^ur^addr2^dw)&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerfl + iclock += 8; + } + +void Op11BC(void) // CMPS ABS +{ + addr = FetchW(); WORD addr2 = (RdMem(addr)<<8) | RdMem(addr+1); + WORD dw = sr - addr2; + (dw == 0 ? ccr |= 0x04 : ccr &= 0xFB); // Adjust Zero flag + (dw&0x8000 ? ccr |= 0x08 : ccr &= 0xF7); // Adjust Negative flag + (sr < addr2 ? ccr |= 0x01 : ccr &= 0xFE); // Adjust Carry flag + (((ccr<<15)^sr^addr2^dw)&0x8000 ? ccr |= 0x02 : ccr &= 0xFD); // oVerfl + iclock += 8; +} + +void IllegalOp(void) +{ + iclock++; + illegal = true; +} + +void Op__(void) +{ + iclock++; + illegal = true; +} + +// +// Function arrays +// + +// Array of page zero opcode functions... +void (* exec_op0[256])() = { + Op00, Op__, Op__, Op03, Op04, Op__, Op06, Op07, Op08, Op09, Op0A, Op__, Op0C, Op0D, Op0E, Op0F, + Op__, Op__, Op12, Op13, Op__, Op__, Op16, Op17, Op__, Op19, Op1A, Op__, Op1C, Op1D, Op1E, Op1F, + Op20, Op21, Op22, Op23, Op24, Op25, Op26, Op27, Op28, Op29, Op2A, Op2B, Op2C, Op2D, Op2E, Op2F, + Op30, Op31, Op32, Op33, Op34, Op35, Op36, Op37, Op__, Op39, Op3A, Op3B, Op3C, Op3D, Op3E, Op3F, + Op40, Op__, Op__, Op43, Op44, Op__, Op46, Op47, Op48, Op49, Op4A, Op__, Op4C, Op4D, Op__, Op4F, + Op50, Op__, Op__, Op53, Op54, Op__, Op56, Op57, Op58, Op59, Op5A, Op__, Op5C, Op5D, Op__, Op5F, + Op60, Op__, Op__, Op63, Op64, Op__, Op66, Op67, Op68, Op69, Op6A, Op__, Op6C, Op6D, Op6E, Op6F, + Op70, Op__, Op__, Op73, Op74, Op__, Op76, Op77, Op78, Op79, Op7A, Op__, Op7C, Op7D, Op7E, Op7F, + Op80, Op81, Op82, Op83, Op84, Op85, Op86, Op__, Op88, Op89, Op8A, Op8B, Op8C, Op8D, Op8E, Op__, + Op90, Op91, Op92, Op93, Op94, Op95, Op96, Op97, Op98, Op99, Op9A, Op9B, Op9C, Op9D, Op9E, Op9F, + OpA0, OpA1, OpA2, OpA3, OpA4, OpA5, OpA6, OpA7, OpA8, OpA9, OpAA, OpAB, OpAC, OpAD, OpAE, OpAF, + OpB0, OpB1, OpB2, OpB3, OpB4, OpB5, OpB6, OpB7, OpB8, OpB9, OpBA, OpBB, OpBC, OpBD, OpBE, OpBF, + OpC0, OpC1, OpC2, OpC3, OpC4, OpC5, OpC6, Op__, OpC8, OpC9, OpCA, OpCB, OpCC, Op__, OpCE, Op__, + OpD0, OpD1, OpD2, OpD3, OpD4, OpD5, OpD6, OpD7, OpD8, OpD9, OpDA, OpDB, OpDC, OpDD, OpDE, OpDF, + OpE0, OpE1, OpE2, OpE3, OpE4, OpE5, OpE6, OpE7, OpE8, OpE9, OpEA, OpEB, OpEC, OpED, OpEE, OpEF, + OpF0, OpF1, OpF2, OpF3, OpF4, OpF5, OpF6, OpF7, OpF8, OpF9, OpFA, OpFB, OpFC, OpFD, OpFE, OpFF +}; + +// Array of page one opcode functions... +void (* exec_op1[256])() = { + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op1021, Op1022, Op1023, Op1024, Op1025, Op1026, Op1027, Op1028, Op1029, Op102A, Op102B, Op102C, Op102D, Op102E, Op102F, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op103F, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op1083, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op108C, Op__, Op108E, Op__, + Op__, Op__, Op__, Op1093, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op109C, Op__, Op109E, Op109F, + Op__, Op__, Op__, Op10A3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10AC, Op__, Op10AE, Op10AF, + Op__, Op__, Op__, Op10B3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10BC, Op__, Op10BE, Op10BF, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10CE, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10DE, Op10DF, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10EE, Op10EF, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10FE, Op10FF +}; +// Array of page two opcode functions... +void (* exec_op2[256])() = { + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op113F, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op1183, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op118C, Op__, Op__, Op__, + Op__, Op__, Op__, Op1193, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op119C, Op__, Op__, Op__, + Op__, Op__, Op__, Op11A3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op11AC, Op__, Op__, Op__, + Op__, Op__, Op__, Op11B3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op11BC, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__ +}; + +// +// Initialize 6809 function adressess +// + +void Init_6809(void) +{ + return; +/* + for(int i=0; i<256; i++) // Set all functions to illegal + exec_op0[i] = exec_op1[i] = exec_op2[i] = IllegalOp; + + exec_op0[0x00] = Op00; exec_op0[0x03] = Op03; exec_op0[0x04] = Op04; + exec_op0[0x06] = Op06; exec_op0[0x07] = Op07; exec_op0[0x08] = Op08; + exec_op0[0x09] = Op09; exec_op0[0x0A] = Op0A; exec_op0[0x0C] = Op0C; + exec_op0[0x0D] = Op0D; exec_op0[0x0E] = Op0E; exec_op0[0x0F] = Op0F; + exec_op0[0x12] = Op12; exec_op0[0x13] = Op13; exec_op0[0x16] = Op16; + exec_op0[0x17] = Op17; exec_op0[0x19] = Op19; exec_op0[0x1A] = Op1A; + exec_op0[0x1C] = Op1C; exec_op0[0x1D] = Op1D; exec_op0[0x1E] = Op1E; + exec_op0[0x1F] = Op1F; exec_op0[0x20] = Op20; exec_op0[0x21] = Op21; + exec_op0[0x22] = Op22; exec_op0[0x23] = Op23; exec_op0[0x24] = Op24; + exec_op0[0x25] = Op25; exec_op0[0x26] = Op26; exec_op0[0x27] = Op27; + exec_op0[0x28] = Op28; exec_op0[0x29] = Op29; exec_op0[0x2A] = Op2A; + exec_op0[0x2B] = Op2B; exec_op0[0x2C] = Op2C; exec_op0[0x2D] = Op2D; + exec_op0[0x2E] = Op2E; exec_op0[0x2F] = Op2F; exec_op0[0x30] = Op30; + exec_op0[0x31] = Op31; exec_op0[0x32] = Op32; exec_op0[0x33] = Op33; + exec_op0[0x34] = Op34; exec_op0[0x35] = Op35; exec_op0[0x36] = Op36; + exec_op0[0x37] = Op37; exec_op0[0x39] = Op39; exec_op0[0x3A] = Op3A; + exec_op0[0x3B] = Op3B; exec_op0[0x3C] = Op3C; exec_op0[0x3D] = Op3D; + exec_op0[0x3E] = Op3E; exec_op0[0x3F] = Op3F; exec_op0[0x40] = Op40; + exec_op0[0x43] = Op43; exec_op0[0x44] = Op44; exec_op0[0x46] = Op46; + exec_op0[0x47] = Op47; exec_op0[0x48] = Op48; exec_op0[0x49] = Op49; + exec_op0[0x4A] = Op4A; exec_op0[0x4C] = Op4C; exec_op0[0x4D] = Op4D; + exec_op0[0x4F] = Op4F; exec_op0[0x50] = Op50; exec_op0[0x53] = Op53; + exec_op0[0x54] = Op54; exec_op0[0x56] = Op56; exec_op0[0x57] = Op57; + exec_op0[0x58] = Op58; exec_op0[0x59] = Op59; exec_op0[0x5A] = Op5A; + exec_op0[0x5C] = Op5C; exec_op0[0x5D] = Op5D; exec_op0[0x5F] = Op5F; + exec_op0[0x60] = Op60; exec_op0[0x63] = Op63; exec_op0[0x64] = Op64; + exec_op0[0x66] = Op66; exec_op0[0x67] = Op67; exec_op0[0x68] = Op68; + exec_op0[0x69] = Op69; exec_op0[0x6A] = Op6A; exec_op0[0x6C] = Op6C; + exec_op0[0x6D] = Op6D; exec_op0[0x6E] = Op6E; exec_op0[0x6F] = Op6F; + exec_op0[0x70] = Op70; exec_op0[0x73] = Op73; exec_op0[0x74] = Op74; + exec_op0[0x76] = Op76; exec_op0[0x77] = Op77; exec_op0[0x78] = Op78; + exec_op0[0x79] = Op79; exec_op0[0x7A] = Op7A; exec_op0[0x7C] = Op7C; + exec_op0[0x7D] = Op7D; exec_op0[0x7E] = Op7E; exec_op0[0x7F] = Op7F; + exec_op0[0x80] = Op80; exec_op0[0x81] = Op81; exec_op0[0x82] = Op82; + exec_op0[0x83] = Op83; exec_op0[0x84] = Op84; exec_op0[0x85] = Op85; + exec_op0[0x86] = Op86; exec_op0[0x88] = Op88; exec_op0[0x89] = Op89; + exec_op0[0x8A] = Op8A; exec_op0[0x8B] = Op8B; exec_op0[0x8C] = Op8C; + exec_op0[0x8D] = Op8D; exec_op0[0x8E] = Op8E; exec_op0[0x90] = Op90; + exec_op0[0x91] = Op91; exec_op0[0x92] = Op92; exec_op0[0x93] = Op93; + exec_op0[0x94] = Op94; exec_op0[0x95] = Op95; exec_op0[0x96] = Op96; + exec_op0[0x97] = Op97; exec_op0[0x98] = Op98; exec_op0[0x99] = Op99; + exec_op0[0x9A] = Op9A; exec_op0[0x9B] = Op9B; exec_op0[0x9C] = Op9C; + exec_op0[0x9D] = Op9D; exec_op0[0x9E] = Op9E; exec_op0[0x9F] = Op9F; + exec_op0[0xA0] = OpA0; exec_op0[0xA1] = OpA1; exec_op0[0xA2] = OpA2; + exec_op0[0xA3] = OpA3; exec_op0[0xA4] = OpA4; exec_op0[0xA5] = OpA5; + exec_op0[0xA6] = OpA6; exec_op0[0xA7] = OpA7; exec_op0[0xA8] = OpA8; + exec_op0[0xA9] = OpA9; exec_op0[0xAA] = OpAA; exec_op0[0xAB] = OpAB; + exec_op0[0xAC] = OpAC; exec_op0[0xAD] = OpAD; exec_op0[0xAE] = OpAE; + exec_op0[0xAF] = OpAF; exec_op0[0xB0] = OpB0; exec_op0[0xB1] = OpB1; + exec_op0[0xB2] = OpB2; exec_op0[0xB3] = OpB3; exec_op0[0xB4] = OpB4; + exec_op0[0xB5] = OpB5; exec_op0[0xB6] = OpB6; exec_op0[0xB7] = OpB7; + exec_op0[0xB8] = OpB8; exec_op0[0xB9] = OpB9; exec_op0[0xBA] = OpBA; + exec_op0[0xBB] = OpBB; exec_op0[0xBC] = OpBC; exec_op0[0xBD] = OpBD; + exec_op0[0xBE] = OpBE; exec_op0[0xBF] = OpBF; exec_op0[0xC0] = OpC0; + exec_op0[0xC1] = OpC1; exec_op0[0xC2] = OpC2; exec_op0[0xC3] = OpC3; + exec_op0[0xC4] = OpC4; exec_op0[0xC5] = OpC5; exec_op0[0xC6] = OpC6; + exec_op0[0xC8] = OpC8; exec_op0[0xC9] = OpC9; exec_op0[0xCA] = OpCA; + exec_op0[0xCB] = OpCB; exec_op0[0xCC] = OpCC; exec_op0[0xCE] = OpCE; + exec_op0[0xD0] = OpD0; exec_op0[0xD1] = OpD1; exec_op0[0xD2] = OpD2; + exec_op0[0xD3] = OpD3; exec_op0[0xD4] = OpD4; exec_op0[0xD5] = OpD5; + exec_op0[0xD6] = OpD6; exec_op0[0xD7] = OpD7; exec_op0[0xD8] = OpD8; + exec_op0[0xD9] = OpD9; exec_op0[0xDA] = OpDA; exec_op0[0xDB] = OpDB; + exec_op0[0xDC] = OpDC; exec_op0[0xDD] = OpDD; exec_op0[0xDE] = OpDE; + exec_op0[0xDF] = OpDF; exec_op0[0xE0] = OpE0; exec_op0[0xE1] = OpE1; + exec_op0[0xE2] = OpE2; exec_op0[0xE3] = OpE3; exec_op0[0xE4] = OpE4; + exec_op0[0xE5] = OpE5; exec_op0[0xE6] = OpE6; exec_op0[0xE7] = OpE7; + exec_op0[0xE8] = OpE8; exec_op0[0xE9] = OpE9; exec_op0[0xEA] = OpEA; + exec_op0[0xEB] = OpEB; exec_op0[0xEC] = OpEC; exec_op0[0xED] = OpED; + exec_op0[0xEE] = OpEE; exec_op0[0xEF] = OpEF; exec_op0[0xF0] = OpF0; + exec_op0[0xF1] = OpF1; exec_op0[0xF2] = OpF2; exec_op0[0xF3] = OpF3; + exec_op0[0xF4] = OpF4; exec_op0[0xF5] = OpF5; exec_op0[0xF6] = OpF6; + exec_op0[0xF7] = OpF7; exec_op0[0xF8] = OpF8; exec_op0[0xF9] = OpF9; + exec_op0[0xFA] = OpFA; exec_op0[0xFB] = OpFB; exec_op0[0xFC] = OpFC; + exec_op0[0xFD] = OpFD; exec_op0[0xFE] = OpFE; exec_op0[0xFF] = OpFF; + + exec_op1[0x21] = Op1021; exec_op1[0x22] = Op1022; exec_op1[0x23] = Op1023; + exec_op1[0x24] = Op1024; exec_op1[0x25] = Op1025; exec_op1[0x26] = Op1026; + exec_op1[0x27] = Op1027; exec_op1[0x28] = Op1028; exec_op1[0x29] = Op1029; + exec_op1[0x2A] = Op102A; exec_op1[0x2B] = Op102B; exec_op1[0x2C] = Op102C; + exec_op1[0x2D] = Op102D; exec_op1[0x2E] = Op102E; exec_op1[0x2F] = Op102F; + exec_op1[0x3F] = Op103F; exec_op1[0x83] = Op1083; exec_op1[0x8C] = Op108C; + exec_op1[0x8E] = Op108E; exec_op1[0x93] = Op1093; exec_op1[0x9C] = Op109C; + exec_op1[0x9E] = Op109E; exec_op1[0x9F] = Op109F; exec_op1[0xA3] = Op10A3; + exec_op1[0xAC] = Op10AC; exec_op1[0xAE] = Op10AE; exec_op1[0xAF] = Op10AF; + exec_op1[0xB3] = Op10B3; exec_op1[0xBC] = Op10BC; exec_op1[0xBE] = Op10BE; + exec_op1[0xBF] = Op10BF; exec_op1[0xCE] = Op10CE; exec_op1[0xDE] = Op10DE; + exec_op1[0xDF] = Op10DF; exec_op1[0xEE] = Op10EE; exec_op1[0xEF] = Op10EF; + exec_op1[0xFE] = Op10FE; exec_op1[0xFF] = Op10FF; + + exec_op2[0x3F] = Op113F; exec_op2[0x83] = Op1183; exec_op2[0x8C] = Op118C; + exec_op2[0x93] = Op1193; exec_op2[0x9C] = Op119C; exec_op2[0xA3] = Op11A3; + exec_op2[0xAC] = Op11AC; exec_op2[0xB3] = Op11B3; exec_op2[0xBC] = Op11BC;*/ +} + +// +// Function to execute one 6809 instruction +// + +void Execute_6809(long num_of_instrs_to_exec) +{ + for(long i=0; i 2177) + { + iclock = 0; + if (!(ccr&0x10) && (!inter)) // Process an interrupt? + { + inter = true; + ccr |= 0x80; // Set E + WrMem(--sr, pcr&0xFF); WrMem(--sr, pcr>>8); // Save all regs... + WrMem(--sr, ur&0xFF); WrMem(--sr, ur>>8); + WrMem(--sr, yr&0xFF); WrMem(--sr, yr>>8); + WrMem(--sr, xr&0xFF); WrMem(--sr, xr>>8); + WrMem(--sr, dpr); WrMem(--sr, br); + WrMem(--sr, ar); WrMem(--sr, ccr); + ccr |= 0x50; // Set F,I + pcr = (RdMem(0xFFF8)<<8) | RdMem(0xFFF9); // And do it! +// ram[0xCB00] += 64; // Set to 64 for faster updates... + } + } + } +} + +void Execute6809(V6809REGS * context, DWORD cycles) +{ + memcpy(®s, context, sizeof(V6809REGS)); + + // Execute here... + + memcpy(context, ®s, sizeof(V6809REGS)); +} diff --git a/src/v6809.h b/src/v6809.h new file mode 100755 index 0000000..5a54fe6 --- /dev/null +++ b/src/v6809.h @@ -0,0 +1,59 @@ +// +// Virtual 6809 Header file +// +// by James L. Hammons +// +// (c) 1997, 2004 Underground Software +// + +#ifndef __V6809_H__ +#define __V6809_H__ + +#include "types.h" + +// Useful defines + +#define FLAG_E 0x80 // Entire +#define FLAG_F 0x40 // Fast IRQ +#define FLAG_H 0x20 // Half carry +#define FLAG_I 0x10 // IRQ +#define FLAG_N 0x08 // Negative +#define FLAG_Z 0x04 // Zero +#define FLAG_V 0x02 // oVerflow +#define FLAG_C 0x01 // Carry + +#define V6809_ASSERT_LINE_RESET 0x0001 // v6809 RESET line +#define V6809_ASSERT_LINE_IRQ 0x0002 // v6809 IRQ line +#define V6809_ASSERT_LINE_FIRQ 0x0004 // v6809 FIRQ line +#define V6809_ASSERT_LINE_NMI 0x0008 // v6809 NMI line +#define V6809_STATE_SYNC 0x0010 // v6809 SYNC line +#define V6809_STATE_ILLEGAL_INST 0x0020 // Illegal instruction executed flag + +//#define V6809_START_DEBUG_LOG EQU 0020h // Debug log go (temporary!) + +// Useful structs + +struct V6809REGS +{ + uint16 pc; // 6809 PC register + uint16 x; // 6809 X index register + uint16 y; // 6809 Y index register + uint16 s; // 6809 System stack pointer + uint16 u; // 6809 User stack pointer + uint8 cc; // 6809 Condition Code register + uint8 a; // 6809 A register + uint8 b; // 6809 B register + uint8 dp; // 6809 Direct Page register + uint32 clock; // 6809 clock +//uint32 _reserved;// uint8 (* Fetch)(uint16&); // Address of uint8 fetch routine + uint8 (* RdMem)(uint16); // Address of uint8 read routine + void (* WrMem)(uint16, uint8); // Address of uint8 write routine + uint32 cpuFlags; // v6809 IRQ/RESET flags +}; + +// Function prototypes + +void Execute6809(V6809REGS *, uint32); // Function to execute 6809 instructions +uint32 GetCurrentV6809Clock(void); // Get the clock of the currently executing CPU + +#endif // __V6809_H__ diff --git a/src/video.cpp b/src/video.cpp new file mode 100755 index 0000000..fe552b9 --- /dev/null +++ b/src/video.cpp @@ -0,0 +1,477 @@ +// +// VIDEO.CPP: SDL/local hardware specific video routines +// +// by James L. Hammons +// + +#include "video.h" + +//#include "SDL.h" +#include // Why??? (for memset, etc... Lazy!) Dunno why, but this just strikes me as wrong... +#include +#include "sdlemu_opengl.h" +#include "log.h" +#include "settings.h" +#include "icon.h" + +#if SDL_BYTEORDER == SDL_BIG_ENDIAN +#define MASK_R 0xFF000000 +#define MASK_G 0x00FF0000 +#define MASK_B 0x0000FF00 +#define MASK_A 0x000000FF +#else +#define MASK_R 0x000000FF +#define MASK_G 0x0000FF00 +#define MASK_B 0x00FF0000 +#define MASK_A 0xFF000000 +#endif + +//#define TEST_ALPHA_BLENDING + +// Exported global variables (actually, these are LOCAL global variables, EXPORTED...) + +SDL_Surface * surface, * mainSurface, * someAlphaSurface; +Uint32 mainSurfaceFlags; +uint32 * scrBuffer = NULL; +SDL_Joystick * joystick; + +// +// Prime SDL and create surfaces +// +bool InitVideo(void) +{ + // Set up SDL library + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_AUDIO | SDL_INIT_TIMER | SDL_INIT_NOPARACHUTE) < 0) + { + WriteLog("Video: Could not initialize the SDL library: %s\n", SDL_GetError()); + return false; + } + + // Get proper info about the platform we're running on... + const SDL_VideoInfo * info = SDL_GetVideoInfo(); + + if (!info) + { + WriteLog("Video: SDL is unable to get the video info: %s\n", SDL_GetError()); + return false; + } + + WriteLog("Video: Hardware is%s available...\n", (info->hw_available ? "" : " NOT")); + WriteLog("Video: Hardware blit is%s available...\n", (info->blit_hw ? "" : " NOT")); + + if (settings.useOpenGL) + { + mainSurfaceFlags = SDL_HWSURFACE | SDL_HWPALETTE | SDL_OPENGL; + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); +//We want 32BPP, so force the issue... + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); + } + else + { + mainSurfaceFlags = SDL_DOUBLEBUF; + + if (info->hw_available) + mainSurfaceFlags = SDL_HWSURFACE | SDL_HWPALETTE; + + if (info->blit_hw) + mainSurfaceFlags |= SDL_HWACCEL; + } + + if (settings.fullscreen) + mainSurfaceFlags |= SDL_FULLSCREEN; + + // Create the primary SDL display (32 BPP) + if (settings.useOpenGL) + mainSurface = SDL_SetVideoMode(VIRTUAL_SCREEN_WIDTH * 2, VIRTUAL_SCREEN_HEIGHT * 2, 32, mainSurfaceFlags); + else + mainSurface = SDL_SetVideoMode(VIRTUAL_SCREEN_WIDTH, VIRTUAL_SCREEN_HEIGHT, 32, mainSurfaceFlags); + + if (mainSurface == NULL) + { + WriteLog("Video: SDL is unable to set the video mode: %s\n", SDL_GetError()); + return false; + } + + // Set icon (mainly for Win32 target--though seems to work under KDE as well...!) + SDL_Surface * iconSurf = SDL_CreateRGBSurfaceFrom(icon, 32, 32, 32, 128, + MASK_R, MASK_G, MASK_B, MASK_A); + SDL_WM_SetIcon(iconSurf, NULL); + SDL_FreeSurface(iconSurf); + + SDL_WM_SetCaption("StarGem2", "StarGem2"); + + // Create the secondary SDL display (32 BPP) that we use directly + surface = SDL_CreateRGBSurface(SDL_SWSURFACE, VIRTUAL_SCREEN_WIDTH, VIRTUAL_SCREEN_HEIGHT, 32, + MASK_R, MASK_G, MASK_B, MASK_A); +/*WriteLog("Video: Created secondary surface with attributes:\n\n"); +WriteLog("\tWidth, height: %u x %u\n", surface->w, surface->h); +WriteLog("\t Pitch: %u\n", surface->pitch); +WriteLog("\t Palette: %08X\n", surface->format->palette); +WriteLog("\t BPP: %u\n", surface->format->BitsPerPixel); +WriteLog("\t BytesPP: %u\n", surface->format->BytesPerPixel); +WriteLog("\t RMask: %08X\n", surface->format->Rmask); +WriteLog("\t GMask: %08X\n", surface->format->Gmask); +WriteLog("\t BMask: %08X\n", surface->format->Bmask); +WriteLog("\t AMask: %08X\n", surface->format->Amask); +WriteLog("\n");//*/ + + if (surface == NULL) + { + WriteLog("Video: Could not create secondary SDL surface: %s\n", SDL_GetError()); + return false; + } + + if (settings.useOpenGL) + sdlemu_init_opengl(surface, mainSurface, 1 /*method*/, + settings.glFilter /*texture type (linear, nearest)*/, + 0 /* Automatic bpp selection based upon src */); + + // Initialize Joystick support under SDL +/* if (settings.useJoystick) + { + if (SDL_NumJoysticks() <= 0) + { + settings.useJoystick = false; + WriteLog("Video: No joystick(s) or joypad(s) detected on your system. Using keyboard...\n"); + } + else + { + if ((joystick = SDL_JoystickOpen(settings.joyport)) == 0) + { + settings.useJoystick = false; + WriteLog("Video: Unable to open a Joystick on port: %d\n", (int)settings.joyport); + } + else + WriteLog("Video: Using: %s\n", SDL_JoystickName(settings.joyport)); + } + }//*/ + + // Set up the scrBuffer + scrBuffer = (uint32 *)surface->pixels; // Kludge--And shouldn't have to lock since it's a software surface... +//needed? Dunno. Mebbe an SDL function instead? +// memset(scrBuffer, 0x00, VIRTUAL_SCREEN_WIDTH * VIRTUAL_SCREEN_HEIGHT * sizeof(uint32)); + +#ifdef TEST_ALPHA_BLENDING +//Here's some code to test alpha blending... +//Well whaddya know, it works. :-) + someAlphaSurface = SDL_CreateRGBSurface(SDL_SWSURFACE, 30, 30, 32, + MASK_R, MASK_G, MASK_B, MASK_A); + + for(int i=0; i<30; i++) + { + for(int j=0; j<30; j++) + { + uint32 color = (uint32)(((double)(i * j) / (29.0 * 29.0)) * 255.0); + color = (color << 24) | 0x00FF00FF; + ((uint32 *)someAlphaSurface->pixels)[(j * 30) + i] = color; + } + } +//End test code +#endif + + WriteLog("Video: Successfully initialized.\n"); + return true; +} + +// +// Free various SDL components +// +void VideoDone(void) +{ + if (settings.useOpenGL) + sdlemu_close_opengl(); + + SDL_JoystickClose(joystick); + SDL_FreeSurface(surface); + SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_AUDIO | SDL_INIT_TIMER); + SDL_Quit(); +} + + + +#if 0 +/// + +#include "SDL.h" +#include // Why??? (for memset, etc... Lazy!) Dunno why, but this just strikes me as wrong... +#include +#include "sdlemu_opengl.h" +#include "types.h" +#include "log.h" +#include "settings.h" +#include "video.h" + +// External global variables + +SDL_Surface * surface, * mainSurface; +Uint32 mainSurfaceFlags; +uint8 * backbuffer; +SDL_Joystick * joystick; +uint8 color[16]; +uint32 palette[256]; + +// +// Prime SDL and create surfaces +// +bool InitVideo(void) +{ + // Set up SDL library + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_AUDIO | SDL_INIT_TIMER | SDL_INIT_NOPARACHUTE) < 0) + { + WriteLog("Video: Could not initialize the SDL library: %s\n", SDL_GetError()); + return false; + } + + // Get proper info about the platform we're running on... + const SDL_VideoInfo * info = SDL_GetVideoInfo(); + + if (!info) + { + WriteLog("Video: SDL is unable to get the video info: %s\n", SDL_GetError()); + return false; + } + + if (1)//(vjs.useOpenGL) + { + mainSurfaceFlags = SDL_HWSURFACE | SDL_HWPALETTE | SDL_DOUBLEBUF | SDL_OPENGL; + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + } + else + { + if (info->hw_available) + { + mainSurfaceFlags = SDL_HWSURFACE | SDL_HWPALETTE | SDL_DOUBLEBUF; + WriteLog("Video: Hardware available...\n"); + } + + if (info->blit_hw) + { + mainSurfaceFlags |= SDL_HWACCEL; + WriteLog("Video: Hardware blit available...\n"); + } + } + +// if (vjs.fullscreen) +// mainSurfaceFlags |= SDL_FULLSCREEN; + + if (0)//(!vjs.useOpenGL) + mainSurface = SDL_SetVideoMode(VIRTUAL_SCREEN_WIDTH, VIRTUAL_SCREEN_HEIGHT, 32, mainSurfaceFlags); + else + mainSurface = SDL_SetVideoMode(VIRTUAL_SCREEN_WIDTH * 2, VIRTUAL_SCREEN_HEIGHT * 2, 32, mainSurfaceFlags); + + if (mainSurface == NULL) + { + WriteLog("Video: SDL is unable to set the video mode: %s\n", SDL_GetError()); + return false; + } + + SDL_WM_SetCaption("StarGem2", "StarGem2"); + + // Create the primary SDL display (8 BPP, palettized) +// surface = SDL_CreateRGBSurface(SDL_SWSURFACE, VIRTUAL_SCREEN_WIDTH, VIRTUAL_SCREEN_HEIGHT, +// 8, 0, 0, 0, 0); + // Create the primary SDL display (32 BPP) + surface = SDL_CreateRGBSurface(SDL_SWSURFACE, VIRTUAL_SCREEN_WIDTH, VIRTUAL_SCREEN_HEIGHT, 32, +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF +#else + 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 +#endif + ); +/*WriteLog("Video: Created secondary surface with attributes:\n\n"); +WriteLog("\tWidth, height: %u x %u\n", surface->w, surface->h); +WriteLog("\t Pitch: %u\n", surface->pitch); +WriteLog("\t Palette: %08X\n", surface->format->palette); +WriteLog("\t BPP: %u\n", surface->format->BitsPerPixel); +WriteLog("\t BytesPP: %u\n", surface->format->BytesPerPixel); +WriteLog("\t RMask: %08X\n", surface->format->Rmask); +WriteLog("\t GMask: %08X\n", surface->format->Gmask); +WriteLog("\t BMask: %08X\n", surface->format->Bmask); +WriteLog("\t AMask: %08X\n", surface->format->Amask); +WriteLog("\n");//*/ + + if (surface == NULL) + { + WriteLog("Video: Could not create primary SDL surface: %s\n", SDL_GetError()); + return false; + } + + // Initialize Williams' palette (RGB coded as: 3 bits red, 3 bits green, 2 bits blue) + for(uint32 i=0; i<256; i++) +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + palette[i] = (((i & 0x01) * 33 + ((i & 0x02) >> 1) * 71 + ((i & 0x04) >> 2) * 151) << 24) + | ((((i & 0x08) >> 3) * 33 + ((i & 0x10) >> 4) * 71 + ((i & 0x20) >> 5) * 151) << 16) + | ((((i & 0x40) >> 6) * 71 + ((i & 0x80) >> 7) * 151) << 8) | 0xFF;//*/ +#else + palette[i] = ((i & 0x01) * 33 + ((i & 0x02) >> 1) * 71 + ((i & 0x04) >> 2) * 151) + | ((((i & 0x08) >> 3) * 33 + ((i & 0x10) >> 4) * 71 + ((i & 0x20) >> 5) * 151) << 8) + | ((((i & 0x40) >> 6) * 71 + ((i & 0x80) >> 7) * 151) << 16) | 0xFF000000;//*/ +#endif + +// if (vjs.useOpenGL) + if (1) +//Should make another setting here, for either linear or nearest (instead of just picking one) +//And we have! ;-) Not... ;-( +// sdlemu_init_opengl(surface, 1/*method*/, 2/*size*/, 0);//vjs.glFilter/*texture type (linear, nearest)*/); + sdlemu_init_opengl(surface, mainSurface, 1 /*method*/, + 0 /*vjs.glFilter /texture type (linear, nearest)*/, + 0 /* Automatic bpp selection based upon src */); + + // Initialize Joystick support under SDL +/* if (1)//(vjs.useJoystick) + { + if (SDL_NumJoysticks() <= 0) + { + vjs.useJoystick = false; + WriteLog("Video: No joystick(s) or joypad(s) detected on your system. Using keyboard...\n"); + } + else + { + if ((joystick = SDL_JoystickOpen(vjs.joyport)) == 0) + { + vjs.useJoystick = false; + WriteLog("Video: Unable to open a Joystick on port: %d\n", (int)vjs.joyport); + } + else + WriteLog("Video: Using: %s\n", SDL_JoystickName(vjs.joyport)); + } + }*/ + + // Set up the backbuffer + backbuffer = (uint8 *)malloc(320 * 240 * sizeof(uint8)); + memset(backbuffer, 0x00, VIRTUAL_SCREEN_WIDTH * VIRTUAL_SCREEN_HEIGHT * sizeof(uint8)); + + WriteLog("Video: Successfully initialized.\n"); + return true; +} + +#endif + + + +// +// Render the backbuffer to the primary screen surface +// +void RenderScreenBuffer(void) +{ +//WriteLog("Video: Blitting a %u x %u surface to the main surface...\n", surface->w, surface->h); +//Don't need this crapola--why have a separate buffer just to copy it to THIS +//buffer in order to copy it to the main screen? That's what *I* thought! +/* if (SDL_MUSTLOCK(surface)) + while (SDL_LockSurface(surface) < 0) + SDL_Delay(10); + + memcpy(surface->pixels, scrBuffer, VIRTUAL_SCREEN_WIDTH * VIRTUAL_SCREEN_HEIGHT * sizeof(uint32)); + + if (SDL_MUSTLOCK(surface)) + SDL_UnlockSurface(surface);//*/ +#ifdef TEST_ALPHA_BLENDING +SDL_Rect dstRect = { 100, 100, 30, 30 }; +SDL_BlitSurface(someAlphaSurface, NULL, surface, &dstRect); +#endif + + if (settings.useOpenGL) + sdlemu_draw_texture(mainSurface, surface, 1/*1=GL_QUADS*/); + else + { + SDL_BlitSurface(surface, NULL, mainSurface, NULL); + SDL_Flip(mainSurface); + } +} + +// +// Render the backbuffer to the primary screen surface +// +void RenderScreenBuffer2(void) +{ +#if 0 +//WriteLog("Video: Blitting a %u x %u surface to the main surface...", surface->w, surface->h); + if (SDL_MUSTLOCK(surface)) + while (SDL_LockSurface(surface) < 0) + SDL_Delay(10); + +//This *does* ignore the screen's actual pitch... !!! FIX !!! + uint32 * screen = (uint32 *)surface->pixels; + for(int i=0; i<320*240; i++) + screen[i] = palette[color[scrBuffer[i]]]; +//WriteLog("[blitted backbuffer]..."); + + if (SDL_MUSTLOCK(surface)) + SDL_UnlockSurface(surface); +#endif + + if (settings.useOpenGL) + sdlemu_draw_texture(mainSurface, surface, 1/*1=GL_QUADS*/); + else + { + SDL_BlitSurface(surface, NULL, mainSurface, NULL); + SDL_Flip(mainSurface); + } +//WriteLog("done.\n"); +} + +/* +// +// Resize the main SDL screen & backbuffer +// +void ResizeScreen(uint32 width, uint32 height) +{ + char window_title[256]; + + SDL_FreeSurface(surface); + surface = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 16, + 0x7C00, 0x03E0, 0x001F, 0); + + if (surface == NULL) + { + WriteLog("Video: Could not create primary SDL surface: %s", SDL_GetError()); + exit(1); + } + + if (vjs.useOpenGL) + // This seems to work well for resizing (i.e., changes in the pixel width)... + sdlemu_resize_texture(surface, mainSurface, vjs.glFilter); + else + { + mainSurface = SDL_SetVideoMode(width, height, 16, mainSurfaceFlags); + + if (mainSurface == NULL) + { + WriteLog("Video: SDL is unable to set the video mode: %s\n", SDL_GetError()); + exit(1); + } + } + + sWriteLog(window_title, "Virtual Jaguar (%i x %i)", (int)width, (int)height); + SDL_WM_SetCaption(window_title, window_title); + + // This seems to work well for resizing (i.e., changes in the pixel width)... +// if (vjs.useOpenGL) +// sdlemu_resize_texture(surface, mainSurface); +} + +// +// Fullscreen <-> window switching +// +//NOTE: This does *NOT* work with OpenGL rendering! !!! FIX !!! +void ToggleFullscreen(void) +{ + vjs.fullscreen = !vjs.fullscreen; + mainSurfaceFlags &= ~SDL_FULLSCREEN; + + if (vjs.fullscreen) + mainSurfaceFlags |= SDL_FULLSCREEN; + + mainSurface = SDL_SetVideoMode(tom_width, tom_height, 16, mainSurfaceFlags); + + if (mainSurface == NULL) + { + WriteLog("Video: SDL is unable to set the video mode: %s\n", SDL_GetError()); + exit(1); + } + + SDL_WM_SetCaption("Virtual Jaguar", "Virtual Jaguar"); +} +*/ diff --git a/src/video.h b/src/video.h new file mode 100755 index 0000000..4a355f2 --- /dev/null +++ b/src/video.h @@ -0,0 +1,50 @@ +// +// VIDEO.H: Header file +// + +#ifndef __VIDEO_H__ +#define __VIDEO_H__ + + +#if 0 + +#define VIRTUAL_SCREEN_WIDTH 320 +#define VIRTUAL_SCREEN_HEIGHT 240 + +bool InitVideo(void); +void VideoDone(void); +void RenderBackbuffer(void); +void ResizeScreen(uint32 width, uint32 height); +uint32 GetSDLScreenPitch(void); +void ToggleFullscreen(void); +void RenderBackbuffer2(void); + +// Exported crap + +extern uint8 * backbuffer; +extern uint8 color[16]; +//extern uint32 palette[256]; + +#endif + + +#include "SDL.h" // For SDL_Surface +#include "types.h" // For uint32 + +#define VIRTUAL_SCREEN_WIDTH 320 +#define VIRTUAL_SCREEN_HEIGHT 240 + +bool InitVideo(void); +void VideoDone(void); +void RenderScreenBuffer(void); +void RenderScreenBuffer2(void); +//void ResizeScreen(uint32 width, uint32 height); +//uint32 GetSDLScreenPitch(void); +//void ToggleFullscreen(void); + +// Exported crap + +extern uint32 * scrBuffer; +extern SDL_Surface * surface; + +#endif // __VIDEO_H__ diff --git a/stargem2.cfg b/stargem2.cfg new file mode 100755 index 0000000..76daeb4 --- /dev/null +++ b/stargem2.cfg @@ -0,0 +1,99 @@ +# +# StarGem2 configuration file +# + +# Apple ROM paths + +BIOSROM = ./ROMs +#diskROM = ./ROMs/disk.rom +#ROMs = ./ROMs + +# Auto state loading/saving upon starting/quitting Apple2 (1 - use, 0 - don't use) + +autoSaveState = 1 +#This is the default--we don't advertise it just yet... ;-) +#autoStateFilename = ./apple2auto.state + +# TEMPORARY disk image load paths + +# OpenGL options: 1 - use OpenGL rendering, 0 - use old style rendering + +useOpenGL = 0 + +# OpenGL filtering type: 1 - blurry, 0 - sharp + +glFilterType = 0 + +# Display options: 1 - fullscreen, 0 - windowed + +fullscreen = 0 + +# Backend renderer (OpenGL dependent): 0 - regular, 1 - "TV" style + +#renderType = 0 + +# NTSC/PAL options: 1 - NTSC, 0 - PAL + +hardwareTypeNTSC = 1 + +# Framskip options: 0 - no skip, 1-N - draw every Nth frame +# Note: Skipping frames may cause strange visual side effects--don't bother +# reporting these unless they occur with a frameskip value of 0! + +frameSkip = 0 + +# Joystick options: 1 - use joystick, 0 - don't use + +useJoystick = 0 + +# Joyport option: If joystick is enabled above, set the port (0 - 3) here + +joyport = 0 + +# Jaguar joypad key assignments +# Note: It would be nicer to be able to have a single left side to store all this in... +# E.g. p1keys = 34, 32, 22, etc. instead of what we have here... + +p1k_up = 273 # SDLK_UP +p1k_down = 274 # SDLK_DOWN +p1k_left = 276 # SDLK_LEFT +p1k_right = 275 # SDLK_RIGHT +p1k_c = 122 # SDLK_z +p1k_b = 120 # SDLK_x +p1k_a = 99 # SDLK_c +p1k_option = 39 # SDLK_QUOTE +p1k_pause = 13 # SDLK_RETURN +p1k_0 = 256 # SDLK_KP0 +p1k_1 = 257 # SDLK_KP1 +p1k_2 = 258 # SDLK_KP2 +p1k_3 = 259 # SDLK_KP3 +p1k_4 = 260 # SDLK_KP4 +p1k_5 = 261 # SDLK_KP5 +p1k_6 = 262 # SDLK_KP6 +p1k_7 = 263 # SDLK_KP7 +p1k_8 = 264 # SDLK_KP8 +p1k_9 = 265 # SDLK_KP9 +p1k_pound = 267 # SDLK_KP_DIVIDE +p1k_star = 268 # SDLK_KP_MULTIPLY + +p2k_up = 273 # SDLK_UP +p2k_down = 274 # SDLK_DOWN +p2k_left = 276 # SDLK_LEFT +p2k_right = 275 # SDLK_RIGHT +p2k_c = 122 # SDLK_z +p2k_b = 120 # SDLK_x +p2k_a = 99 # SDLK_c +p2k_option = 39 # SDLK_QUOTE +p2k_pause = 13 # SDLK_RETURN +p2k_0 = 256 # SDLK_KP0 +p2k_1 = 257 # SDLK_KP1 +p2k_2 = 258 # SDLK_KP2 +p2k_3 = 259 # SDLK_KP3 +p2k_4 = 260 # SDLK_KP4 +p2k_5 = 261 # SDLK_KP5 +p2k_6 = 262 # SDLK_KP6 +p2k_7 = 263 # SDLK_KP7 +p2k_8 = 264 # SDLK_KP8 +p2k_9 = 265 # SDLK_KP9 +p2k_pound = 267 # SDLK_KP_DIVIDE +p2k_star = 268 # SDLK_KP_MULTIPLY -- 2.37.2