cpu.c 93 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465
  1. /****************************************************************************
  2. * *
  3. * Third Year Project *
  4. * *
  5. * An IBM PC Emulator *
  6. * For Unix and X Windows *
  7. * *
  8. * By David Hedley *
  9. * *
  10. * *
  11. * This program is Copyrighted. Consult the file COPYRIGHT for more details *
  12. * *
  13. ****************************************************************************/
  14. /* This is CPU.C It emulates the 8086 processor */
  15. #include "../mmage/mmage.h"
  16. #include "global.h"
  17. #include <stdio.h>
  18. #include "mytypes.h"
  19. #include "cpu.h"
  20. #include "instr.h"
  21. #include "hardware.h"
  22. #ifdef DEBUGGER
  23. # include "debugger.h"
  24. #endif
  25. #ifdef DEBUG
  26. # include <stdlib.h>
  27. #endif
  28. WORD wregs[8]; /* Always little-endian */
  29. BYTE *bregs[16]; /* Points to bytes within wregs[] */
  30. unsigned sregs[4]; /* Always native machine word order */
  31. unsigned ip; /* Always native machine word order */
  32. /* All the byte flags will either be 1 or 0 */
  33. BYTE CF, PF, ZF, TF, IF, DF;
  34. /* All the word flags may be either none-zero (true) or zero (false) */
  35. unsigned AF, OF, SF;
  36. static UINT8 parity_table[256];
  37. static BYTE *ModRMRegB[256];
  38. static WORD *ModRMRegW[256];
  39. /* 'Shadows' of the segment registers. Point directly into the start of the
  40. segment within memory[] */
  41. BYTE *c_cs,*c_ds,*c_es,*c_ss,*c_stack;
  42. volatile int int_pending; /* Interrupt pending */
  43. volatile int int_blocked; /* Blocked pending */
  44. static struct
  45. {
  46. BYTE **segment;
  47. WORD *reg1;
  48. WORD *reg2;
  49. int offset;
  50. int offset16;
  51. int pad[3]; /* Make structure power of 2 bytes wide for speed */
  52. } ModRMRM[256];
  53. static WORD zero_word = 0;
  54. static WORD *ModRMRMWRegs[256];
  55. static BYTE *ModRMRMBRegs[256];
  56. void trap(void);
  57. #define PushSeg(Seg) \
  58. { \
  59. register unsigned tmp = (WORD)(ReadWord(&wregs[SP])-2); \
  60. WriteWord(&wregs[SP],tmp); \
  61. PutMemW(c_stack,tmp,sregs[Seg]); \
  62. }
  63. #define PopSeg(seg, Seg) \
  64. { \
  65. register unsigned tmp = ReadWord(&wregs[SP]); \
  66. sregs[Seg] = GetMemW(c_stack,tmp); \
  67. seg = SegToMemPtr(Seg); \
  68. tmp += 2; \
  69. WriteWord(&wregs[SP],tmp); \
  70. }
  71. #define PushWordReg(Reg) \
  72. { \
  73. register unsigned tmp1 = (WORD)(ReadWord(&wregs[SP])-2); \
  74. WORD tmp2; \
  75. WriteWord(&wregs[SP],tmp1); \
  76. tmp2 = ReadWord(&wregs[Reg]); \
  77. PutMemW(c_stack,tmp1,tmp2); \
  78. }
  79. #define PopWordReg(Reg) \
  80. { \
  81. register unsigned tmp = ReadWord(&wregs[SP]); \
  82. WORD tmp2 = GetMemW(c_stack,tmp); \
  83. tmp += 2; \
  84. WriteWord(&wregs[SP],tmp); \
  85. WriteWord(&wregs[Reg],tmp2); \
  86. }
  87. #define XchgAXReg(Reg) \
  88. { \
  89. register unsigned tmp; \
  90. tmp = wregs[Reg]; \
  91. wregs[Reg] = wregs[AX]; \
  92. wregs[AX] = tmp; \
  93. }
  94. #define IncWordReg(Reg) \
  95. { \
  96. register unsigned tmp = (unsigned)ReadWord(&wregs[Reg]); \
  97. register unsigned tmp1 = tmp+1; \
  98. SetOFW_Add(tmp1,tmp,1); \
  99. SetAF(tmp1,tmp,1); \
  100. SetZFW(tmp1); \
  101. SetSFW(tmp1); \
  102. SetPF(tmp1); \
  103. WriteWord(&wregs[Reg],tmp1); \
  104. }
  105. #define DecWordReg(Reg) \
  106. { \
  107. register unsigned tmp = (unsigned)ReadWord(&wregs[Reg]); \
  108. register unsigned tmp1 = tmp-1; \
  109. SetOFW_Sub(tmp1,1,tmp); \
  110. SetAF(tmp1,tmp,1); \
  111. SetZFW(tmp1); \
  112. SetSFW(tmp1); \
  113. SetPF(tmp1); \
  114. WriteWord(&wregs[Reg],tmp1); \
  115. }
  116. #define Logical_br8(op) \
  117. { \
  118. unsigned ModRM = (unsigned)GetMemInc(c_cs,ip); \
  119. register unsigned src = (unsigned)*GetModRMRegB(ModRM); \
  120. BYTE *dest = GetModRMRMB(ModRM); \
  121. register unsigned tmp = (unsigned) *dest; \
  122. tmp op ## = src; \
  123. CF = OF = AF = 0; \
  124. SetZFB(tmp); \
  125. SetSFB(tmp); \
  126. SetPF(tmp); \
  127. *dest = (BYTE)tmp; \
  128. }
  129. #define Logical_r8b(op) \
  130. { \
  131. unsigned ModRM = (unsigned)GetMemInc(c_cs,ip); \
  132. register unsigned src = (unsigned)*GetModRMRMB(ModRM); \
  133. BYTE *dest = GetModRMRegB(ModRM); \
  134. register unsigned tmp = (unsigned) *dest; \
  135. tmp op ## = src; \
  136. CF = OF = AF = 0; \
  137. SetZFB(tmp); \
  138. SetSFB(tmp); \
  139. SetPF(tmp); \
  140. *dest = (BYTE)tmp; \
  141. }
  142. #define Logical_wr16(op) \
  143. { \
  144. unsigned ModRM = GetMemInc(c_cs,ip); \
  145. WORD *src = GetModRMRegW(ModRM); \
  146. WORD *dest = GetModRMRMW(ModRM); \
  147. register unsigned tmp1 = (unsigned)ReadWord(src); \
  148. register unsigned tmp2 = (unsigned)ReadWord(dest); \
  149. register unsigned tmp3 = tmp1 op tmp2; \
  150. CF = OF = AF = 0; \
  151. SetZFW(tmp3); \
  152. SetSFW(tmp3); \
  153. SetPF(tmp3); \
  154. WriteWord(dest,tmp3); \
  155. }
  156. #define Logical_r16w(op) \
  157. { \
  158. unsigned ModRM = GetMemInc(c_cs,ip); \
  159. WORD *dest = GetModRMRegW(ModRM); \
  160. WORD *src = GetModRMRMW(ModRM); \
  161. register unsigned tmp1 = (unsigned)ReadWord(src); \
  162. register unsigned tmp2 = (unsigned)ReadWord(dest); \
  163. register unsigned tmp3 = tmp1 op tmp2; \
  164. CF = OF = AF = 0; \
  165. SetZFW(tmp3); \
  166. SetSFW(tmp3); \
  167. SetPF(tmp3); \
  168. WriteWord(dest,tmp3); \
  169. }
  170. #define Logical_ald8(op) \
  171. { \
  172. register unsigned tmp = *bregs[AL]; \
  173. tmp op ## = (unsigned)GetMemInc(c_cs,ip); \
  174. CF = OF = AF = 0; \
  175. SetZFB(tmp); \
  176. SetSFB(tmp); \
  177. SetPF(tmp); \
  178. *bregs[AL] = (BYTE)tmp; \
  179. }
  180. #define Logical_axd16(op) \
  181. { \
  182. register unsigned src; \
  183. register unsigned tmp = ReadWord(&wregs[AX]); \
  184. src = GetMemInc(c_cs,ip); \
  185. src += GetMemInc(c_cs,ip) << 8; \
  186. tmp op ## = src; \
  187. CF = OF = AF = 0; \
  188. SetZFW(tmp); \
  189. SetSFW(tmp); \
  190. SetPF(tmp); \
  191. WriteWord(&wregs[AX],tmp); \
  192. }
  193. #define LogicalOp(name,symbol) \
  194. static INLINE2 void i_ ## name ## _br8(void) \
  195. { Logical_br8(symbol); } \
  196. static INLINE2 void i_ ## name ## _wr16(void) \
  197. { Logical_wr16(symbol); } \
  198. static INLINE2 void i_ ## name ## _r8b(void) \
  199. { Logical_r8b(symbol); } \
  200. static INLINE2 void i_ ## name ## _r16w(void) \
  201. { Logical_r16w(symbol); } \
  202. static INLINE2 void i_ ## name ## _ald8(void) \
  203. { Logical_ald8(symbol); } \
  204. static INLINE2 void i_ ## name ## _axd16(void) \
  205. { Logical_axd16(symbol); }
  206. #define JumpCond(name, cond) \
  207. static INLINE2 void i_j ## name ## (void) \
  208. { \
  209. register int tmp = (int)((INT8)GetMemInc(c_cs,ip)); \
  210. if (cond) ip = (WORD)(ip+tmp); \
  211. }
  212. // WW BIOS �ˆ—�ƒ‹�[ƒ`ƒ“
  213. void int_handler(int no);
  214. void init_cpu(void)
  215. {
  216. unsigned int i,j,c;
  217. for (i = 0; i < 4; i++)
  218. {
  219. wregs[i] = 0;
  220. sregs[i] = 0x70;
  221. }
  222. for (; i < 8; i++)
  223. wregs[i] = 0;
  224. wregs[SP] = 0;
  225. ip = 0x100;
  226. for (i = 0;i < 256; i++)
  227. {
  228. for (j = i, c = 0; j > 0; j >>= 1)
  229. if (j & 1) c++;
  230. parity_table[i] = !(c & 1);
  231. }
  232. CF = PF = AF = ZF = SF = TF = IF = DF = OF = 0;
  233. bregs[AL] = (BYTE *)&wregs[AX];
  234. bregs[AH] = (BYTE *)&wregs[AX]+1;
  235. bregs[CL] = (BYTE *)&wregs[CX];
  236. bregs[CH] = (BYTE *)&wregs[CX]+1;
  237. bregs[DL] = (BYTE *)&wregs[DX];
  238. bregs[DH] = (BYTE *)&wregs[DX]+1;
  239. bregs[BL] = (BYTE *)&wregs[BX];
  240. bregs[BH] = (BYTE *)&wregs[BX]+1;
  241. bregs[SPL] = (BYTE *)&wregs[SP];
  242. bregs[SPH] = (BYTE *)&wregs[SP]+1;
  243. bregs[BPL] = (BYTE *)&wregs[BP];
  244. bregs[BPH] = (BYTE *)&wregs[BP]+1;
  245. bregs[SIL] = (BYTE *)&wregs[SI];
  246. bregs[SIH] = (BYTE *)&wregs[SI]+1;
  247. bregs[DIL] = (BYTE *)&wregs[DI];
  248. bregs[DIH] = (BYTE *)&wregs[DI]+1;
  249. for (i = 0; i < 256; i++)
  250. {
  251. ModRMRegB[i] = bregs[(i & 0x38) >> 3];
  252. ModRMRegW[i] = &wregs[(i & 0x38) >> 3];
  253. }
  254. for (i = 0; i < 0x40; i++)
  255. {
  256. switch (i & 7)
  257. {
  258. case 0:
  259. ModRMRM[i].segment = &c_ds;
  260. ModRMRM[i].reg1 = &wregs[BX];
  261. ModRMRM[i].reg2 = &wregs[SI];
  262. ModRMRM[i].offset = ModRMRM[i].offset16 = 0;
  263. break;
  264. case 1:
  265. ModRMRM[i].segment = &c_ds;
  266. ModRMRM[i].reg1 = &wregs[BX];
  267. ModRMRM[i].reg2 = &wregs[DI];
  268. ModRMRM[i].offset = ModRMRM[i].offset16 = 0;
  269. break;
  270. case 2:
  271. ModRMRM[i].segment = &c_ss;
  272. ModRMRM[i].reg1 = &wregs[BP];
  273. ModRMRM[i].reg2 = &wregs[SI];
  274. ModRMRM[i].offset = ModRMRM[i].offset16 = 0;
  275. break;
  276. case 3:
  277. ModRMRM[i].segment = &c_ss;
  278. ModRMRM[i].reg1 = &wregs[BP];
  279. ModRMRM[i].reg2 = &wregs[DI];
  280. ModRMRM[i].offset = ModRMRM[i].offset16 = 0;
  281. break;
  282. case 4:
  283. ModRMRM[i].segment = &c_ds;
  284. ModRMRM[i].reg1 = &zero_word;
  285. ModRMRM[i].reg2 = &wregs[SI];
  286. ModRMRM[i].offset = ModRMRM[i].offset16 = 0;
  287. break;
  288. case 5:
  289. ModRMRM[i].segment = &c_ds;
  290. ModRMRM[i].reg1 = &zero_word;
  291. ModRMRM[i].reg2 = &wregs[DI];
  292. ModRMRM[i].offset = ModRMRM[i].offset16 = 0;
  293. break;
  294. case 6:
  295. ModRMRM[i].segment = &c_ds;
  296. ModRMRM[i].reg1 = &zero_word;
  297. ModRMRM[i].reg2 = &zero_word;
  298. ModRMRM[i].offset = 1;
  299. ModRMRM[i].offset16 = 1;
  300. break;
  301. default:
  302. ModRMRM[i].segment = &c_ds;
  303. ModRMRM[i].reg1 = &wregs[BX];
  304. ModRMRM[i].reg2 = &zero_word;
  305. ModRMRM[i].offset = ModRMRM[i].offset16 = 0;
  306. break;
  307. }
  308. }
  309. for (i = 0x40; i < 0x80; i++)
  310. {
  311. switch (i & 7)
  312. {
  313. case 0:
  314. ModRMRM[i].segment = &c_ds;
  315. ModRMRM[i].reg1 = &wregs[BX];
  316. ModRMRM[i].reg2 = &wregs[SI];
  317. ModRMRM[i].offset = 1;
  318. ModRMRM[i].offset16 = 0;
  319. break;
  320. case 1:
  321. ModRMRM[i].segment = &c_ds;
  322. ModRMRM[i].reg1 = &wregs[BX];
  323. ModRMRM[i].reg2 = &wregs[DI];
  324. ModRMRM[i].offset = 1;
  325. ModRMRM[i].offset16 = 0;
  326. break;
  327. case 2:
  328. ModRMRM[i].segment = &c_ss;
  329. ModRMRM[i].reg1 = &wregs[BP];
  330. ModRMRM[i].reg2 = &wregs[SI];
  331. ModRMRM[i].offset = 1;
  332. ModRMRM[i].offset16 = 0;
  333. break;
  334. case 3:
  335. ModRMRM[i].segment = &c_ss;
  336. ModRMRM[i].reg1 = &wregs[BP];
  337. ModRMRM[i].reg2 = &wregs[DI];
  338. ModRMRM[i].offset = 1;
  339. ModRMRM[i].offset16 = 0;
  340. break;
  341. case 4:
  342. ModRMRM[i].segment = &c_ds;
  343. ModRMRM[i].reg1 = &zero_word;
  344. ModRMRM[i].reg2 = &wregs[SI];
  345. ModRMRM[i].offset = 1;
  346. ModRMRM[i].offset16 = 0;
  347. break;
  348. case 5:
  349. ModRMRM[i].segment = &c_ds;
  350. ModRMRM[i].reg1 = &zero_word;
  351. ModRMRM[i].reg2 = &wregs[DI];
  352. ModRMRM[i].offset = 1;
  353. ModRMRM[i].offset16 = 0;
  354. break;
  355. case 6:
  356. ModRMRM[i].segment = &c_ss;
  357. ModRMRM[i].reg1 = &wregs[BP];
  358. ModRMRM[i].reg2 = &zero_word;
  359. ModRMRM[i].offset = 1;
  360. ModRMRM[i].offset16 = 0;
  361. break;
  362. default:
  363. ModRMRM[i].segment = &c_ds;
  364. ModRMRM[i].reg1 = &wregs[BX];
  365. ModRMRM[i].reg2 = &zero_word;
  366. ModRMRM[i].offset = 1;
  367. ModRMRM[i].offset16 = 0;
  368. break;
  369. }
  370. }
  371. for (i = 0x80; i < 0xc0; i++)
  372. {
  373. switch (i & 7)
  374. {
  375. case 0:
  376. ModRMRM[i].segment = &c_ds;
  377. ModRMRM[i].reg1 = &wregs[BX];
  378. ModRMRM[i].reg2 = &wregs[SI];
  379. ModRMRM[i].offset = 1;
  380. ModRMRM[i].offset16 = 1;
  381. break;
  382. case 1:
  383. ModRMRM[i].segment = &c_ds;
  384. ModRMRM[i].reg1 = &wregs[BX];
  385. ModRMRM[i].reg2 = &wregs[DI];
  386. ModRMRM[i].offset = 1;
  387. ModRMRM[i].offset16 = 1;
  388. break;
  389. case 2:
  390. ModRMRM[i].segment = &c_ss;
  391. ModRMRM[i].reg1 = &wregs[BP];
  392. ModRMRM[i].reg2 = &wregs[SI];
  393. ModRMRM[i].offset = 1;
  394. ModRMRM[i].offset16 = 1;
  395. break;
  396. case 3:
  397. ModRMRM[i].segment = &c_ss;
  398. ModRMRM[i].reg1 = &wregs[BP];
  399. ModRMRM[i].reg2 = &wregs[DI];
  400. ModRMRM[i].offset = 1;
  401. ModRMRM[i].offset16 = 1;
  402. break;
  403. case 4:
  404. ModRMRM[i].segment = &c_ds;
  405. ModRMRM[i].reg1 = &zero_word;
  406. ModRMRM[i].reg2 = &wregs[SI];
  407. ModRMRM[i].offset = 1;
  408. ModRMRM[i].offset16 = 1;
  409. break;
  410. case 5:
  411. ModRMRM[i].segment = &c_ds;
  412. ModRMRM[i].reg1 = &zero_word;
  413. ModRMRM[i].reg2 = &wregs[DI];
  414. ModRMRM[i].offset = 1;
  415. ModRMRM[i].offset16 = 1;
  416. break;
  417. case 6:
  418. ModRMRM[i].segment = &c_ss;
  419. ModRMRM[i].reg1 = &wregs[BP];
  420. ModRMRM[i].reg2 = &zero_word;
  421. ModRMRM[i].offset = 1;
  422. ModRMRM[i].offset16 = 1;
  423. break;
  424. default:
  425. ModRMRM[i].segment = &c_ds;
  426. ModRMRM[i].reg1 = &wregs[BX];
  427. ModRMRM[i].reg2 = &zero_word;
  428. ModRMRM[i].offset = 1;
  429. ModRMRM[i].offset16 = 1;
  430. break;
  431. }
  432. }
  433. for (i = 0xc0; i < 0x100; i++)
  434. {
  435. ModRMRMWRegs[i] = &wregs[i & 7];
  436. ModRMRMBRegs[i] = bregs[i & 7];
  437. }
  438. }
  439. #ifdef DEBUG2
  440. void loc(void)
  441. {
  442. printf("%04X:%04X ", sregs[CS], ip);
  443. }
  444. #endif
  445. static void interrupt(unsigned int_num)
  446. {
  447. // unsigned dest_seg, dest_off,tmp1;
  448. int_handler(int_num);
  449. /*
  450. i_pushf();
  451. dest_off = GetMemW(memory,int_num*4);
  452. dest_seg = GetMemW(memory,int_num*4+2);
  453. tmp1 = (WORD)(ReadWord(&wregs[SP])-2);
  454. PutMemW(c_stack,tmp1,sregs[CS]);
  455. tmp1 = (WORD)(tmp1-2);
  456. PutMemW(c_stack,tmp1,ip);
  457. WriteWord(&wregs[SP],tmp1);
  458. ip = (WORD)dest_off;
  459. sregs[CS] = (WORD)dest_seg;
  460. c_cs = SegToMemPtr(CS);
  461. */
  462. TF = IF = 0; /* Turn of trap and interrupts... */
  463. }
  464. static void external_int(void)
  465. {
  466. disable();
  467. #ifdef DEBUGGER
  468. call_debugger(D_INT);
  469. #endif
  470. D2(printf("Interrupt 0x%02X\n", int_pending););
  471. interrupt(int_pending);
  472. int_pending = 0;
  473. enable();
  474. }
  475. #define GetModRMRegW(ModRM) (ModRMRegW[ModRM])
  476. #define GetModRMRegB(ModRM) (ModRMRegB[ModRM])
  477. static INLINE WORD *GetModRMRMW(unsigned ModRM)
  478. {
  479. register unsigned dest;
  480. if (ModRM >= 0xc0)
  481. return ModRMRMWRegs[ModRM];
  482. dest = 0;
  483. if (ModRMRM[ModRM].offset)
  484. {
  485. dest = (WORD)((INT16)((INT8)GetMemInc(c_cs,ip)));
  486. if (ModRMRM[ModRM].offset16)
  487. dest = (GetMemInc(c_cs,ip) << 8) + (BYTE)dest;
  488. }
  489. return (WORD *)(*ModRMRM[ModRM].segment +
  490. (WORD)(ReadWord(ModRMRM[ModRM].reg1) +
  491. ReadWord(ModRMRM[ModRM].reg2) + dest));
  492. }
  493. static INLINE BYTE *GetModRMRMB(unsigned ModRM)
  494. {
  495. register unsigned dest;
  496. if (ModRM >= 0xc0)
  497. return ModRMRMBRegs[ModRM];
  498. dest = 0;
  499. if (ModRMRM[ModRM].offset)
  500. {
  501. dest = (WORD)((INT16)((INT8)GetMemInc(c_cs,ip)));
  502. if (ModRMRM[ModRM].offset16)
  503. dest = (GetMemInc(c_cs,ip) << 8) + (BYTE)dest;
  504. }
  505. return (*ModRMRM[ModRM].segment +
  506. (WORD)(ReadWord(ModRMRM[ModRM].reg1) +
  507. ReadWord(ModRMRM[ModRM].reg2) + dest));
  508. }
  509. /* i186 instructions */
  510. #include "i186.h"
  511. static INLINE2 void i_add_br8(void)
  512. {
  513. /* Opcode 0x00 */
  514. unsigned ModRM = (unsigned)GetMemInc(c_cs,ip);
  515. register unsigned src = (unsigned)*GetModRMRegB(ModRM);
  516. BYTE *dest = GetModRMRMB(ModRM);
  517. register unsigned tmp = (unsigned) *dest;
  518. register unsigned tmp2 = tmp;
  519. tmp += src;
  520. SetCFB_Add(tmp,tmp2);
  521. SetOFB_Add(tmp,src,tmp2);
  522. SetAF(tmp,src,tmp2);
  523. SetZFB(tmp);
  524. SetSFB(tmp);
  525. SetPF(tmp);
  526. *dest = (BYTE)tmp;
  527. }
  528. static INLINE2 void i_add_wr16(void)
  529. {
  530. /* Opcode 0x01 */
  531. unsigned ModRM = GetMemInc(c_cs,ip);
  532. WORD *src = GetModRMRegW(ModRM);
  533. WORD *dest = GetModRMRMW(ModRM);
  534. register unsigned tmp1 = (unsigned)ReadWord(dest);
  535. register unsigned tmp2 = (unsigned)ReadWord(src);
  536. register unsigned tmp3;
  537. tmp3 = tmp1+tmp2;
  538. SetCFW_Add(tmp3,tmp1);
  539. SetOFW_Add(tmp3,tmp2,tmp1);
  540. SetAF(tmp3,tmp2,tmp1);
  541. SetZFW(tmp3);
  542. SetSFW(tmp3);
  543. SetPF(tmp3);
  544. WriteWord(dest, tmp3);
  545. }
  546. static INLINE2 void i_add_r8b(void)
  547. {
  548. /* Opcode 0x02 */
  549. unsigned ModRM = (unsigned)GetMemInc(c_cs,ip);
  550. register unsigned src = (unsigned)*GetModRMRMB(ModRM);
  551. BYTE *dest = GetModRMRegB(ModRM);
  552. register unsigned tmp = (unsigned) *dest;
  553. register unsigned tmp2 = tmp;
  554. tmp += src;
  555. SetCFB_Add(tmp,tmp2);
  556. SetOFB_Add(tmp,src,tmp2);
  557. SetAF(tmp,src,tmp2);
  558. SetZFB(tmp);
  559. SetSFB(tmp);
  560. SetPF(tmp);
  561. *dest = (BYTE)tmp;
  562. }
  563. static INLINE2 void i_add_r16w(void)
  564. {
  565. /* Opcode 0x03 */
  566. unsigned ModRM = GetMemInc(c_cs,ip);
  567. WORD *dest = GetModRMRegW(ModRM);
  568. WORD *src = GetModRMRMW(ModRM);
  569. register unsigned tmp1 = (unsigned)ReadWord(dest);
  570. register unsigned tmp2 = (unsigned)ReadWord(src);
  571. register unsigned tmp3;
  572. tmp3 = tmp1 + tmp2;
  573. SetCFW_Add(tmp3,tmp1);
  574. SetOFW_Add(tmp3,tmp2,tmp1);
  575. SetAF(tmp3,tmp2,tmp1);
  576. SetZFW(tmp3);
  577. SetSFW(tmp3);
  578. SetPF(tmp3);
  579. WriteWord(dest, tmp3);
  580. }
  581. static INLINE2 void i_add_ald8(void)
  582. {
  583. /* Opcode 0x04 */
  584. register unsigned src = (unsigned)GetMemInc(c_cs,ip);
  585. register unsigned tmp = (unsigned)*bregs[AL];
  586. register unsigned tmp2 = tmp;
  587. tmp2 += src;
  588. SetCFB_Add(tmp2,tmp);
  589. SetOFB_Add(tmp2,src,tmp);
  590. SetAF(tmp2,src,tmp);
  591. SetZFB(tmp2);
  592. SetSFB(tmp2);
  593. SetPF(tmp2);
  594. *bregs[AL] = (BYTE)tmp2;
  595. }
  596. static INLINE2 void i_add_axd16(void)
  597. {
  598. /* Opcode 0x05 */
  599. register unsigned src;
  600. register unsigned tmp = ReadWord(&wregs[AX]);
  601. register unsigned tmp2 = tmp;
  602. src = GetMemInc(c_cs,ip);
  603. src += GetMemInc(c_cs,ip) << 8;
  604. tmp2 += src;
  605. SetCFW_Add(tmp2,tmp);
  606. SetOFW_Add(tmp2,tmp,src);
  607. SetAF(tmp2,tmp,src);
  608. SetZFW(tmp2);
  609. SetSFW(tmp2);
  610. SetPF(tmp2);
  611. WriteWord(&wregs[AX],tmp2);
  612. }
  613. static INLINE2 void i_push_es(void)
  614. {
  615. /* Opcode 0x06 */
  616. PushSeg(ES);
  617. }
  618. static INLINE2 void i_pop_es(void)
  619. {
  620. /* Opcode 0x07 */
  621. PopSeg(c_es,ES);
  622. }
  623. /* most OR instructions go here... */
  624. LogicalOp(or,|)
  625. static INLINE2 void i_push_cs(void)
  626. {
  627. /* Opcode 0x0e */
  628. PushSeg(CS);
  629. }
  630. static INLINE2 void i_adc_br8(void)
  631. {
  632. /* Opcode 0x10 */
  633. unsigned ModRM = (unsigned)GetMemInc(c_cs,ip);
  634. register unsigned src = (unsigned)*GetModRMRegB(ModRM)+CF;
  635. BYTE *dest = GetModRMRMB(ModRM);
  636. register unsigned tmp = (unsigned) *dest;
  637. register unsigned tmp2 = tmp;
  638. tmp += src;
  639. CF = tmp >> 8;
  640. /* SetCFB_Add(tmp,tmp2); */
  641. SetOFB_Add(tmp,src,tmp2);
  642. SetAF(tmp,src,tmp2);
  643. SetZFB(tmp);
  644. SetSFB(tmp);
  645. SetPF(tmp);
  646. *dest = (BYTE)tmp;
  647. }
  648. static INLINE2 void i_adc_wr16(void)
  649. {
  650. /* Opcode 0x11 */
  651. unsigned ModRM = GetMemInc(c_cs,ip);
  652. WORD *src = GetModRMRegW(ModRM);
  653. WORD *dest = GetModRMRMW(ModRM);
  654. register unsigned tmp1 = (unsigned)ReadWord(dest);
  655. register unsigned tmp2 = (unsigned)ReadWord(src)+CF;
  656. register unsigned tmp3;
  657. tmp3 = tmp1+tmp2;
  658. CF = tmp3 >> 16;
  659. /* SetCFW_Add(tmp3,tmp1); */
  660. SetOFW_Add(tmp3,tmp2,tmp1);
  661. SetAF(tmp3,tmp2,tmp1);
  662. SetZFW(tmp3);
  663. SetSFW(tmp3);
  664. SetPF(tmp3);
  665. WriteWord(dest, tmp3);
  666. }
  667. static INLINE2 void i_adc_r8b(void)
  668. {
  669. /* Opcode 0x12 */
  670. unsigned ModRM = (unsigned)GetMemInc(c_cs,ip);
  671. register unsigned src = (unsigned)*GetModRMRMB(ModRM)+CF;
  672. BYTE *dest = GetModRMRegB(ModRM);
  673. register unsigned tmp = (unsigned) *dest;
  674. register unsigned tmp2 = tmp;
  675. tmp += src;
  676. CF = tmp >> 8;
  677. /* SetCFB_Add(tmp,tmp2); */
  678. SetOFB_Add(tmp,src,tmp2);
  679. SetAF(tmp,src,tmp2);
  680. SetZFB(tmp);
  681. SetSFB(tmp);
  682. SetPF(tmp);
  683. *dest = (BYTE)tmp;
  684. }
  685. static INLINE2 void i_adc_r16w(void)
  686. {
  687. /* Opcode 0x13 */
  688. unsigned ModRM = GetMemInc(c_cs,ip);
  689. WORD *dest = GetModRMRegW(ModRM);
  690. WORD *src = GetModRMRMW(ModRM);
  691. register unsigned tmp1 = (unsigned)ReadWord(dest);
  692. register unsigned tmp2 = (unsigned)ReadWord(src)+CF;
  693. register unsigned tmp3;
  694. tmp3 = tmp1+tmp2;
  695. CF = tmp3 >> 16;
  696. /* SetCFW_Add(tmp3,tmp1); */
  697. SetOFW_Add(tmp3,tmp2,tmp1);
  698. SetAF(tmp3,tmp2,tmp1);
  699. SetZFW(tmp3);
  700. SetSFW(tmp3);
  701. SetPF(tmp3);
  702. WriteWord(dest, tmp3);
  703. }
  704. static INLINE2 void i_adc_ald8(void)
  705. {
  706. /* Opcode 0x14 */
  707. register unsigned src = (unsigned)GetMemInc(c_cs,ip)+CF;
  708. register unsigned tmp = (unsigned)*bregs[AL];
  709. register unsigned tmp2 = tmp;
  710. tmp2 += src;
  711. CF = tmp2 >> 8;
  712. /* SetCFB_Add(tmp2,tmp); */
  713. SetOFB_Add(tmp2,src,tmp);
  714. SetAF(tmp2,src,tmp);
  715. SetZFB(tmp2);
  716. SetSFB(tmp2);
  717. SetPF(tmp2);
  718. *bregs[AL] = (BYTE)tmp2;
  719. }
  720. static INLINE2 void i_adc_axd16(void)
  721. {
  722. /* Opcode 0x15 */
  723. register unsigned src;
  724. register unsigned tmp = ReadWord(&wregs[AX]);
  725. register unsigned tmp2 = tmp;
  726. src = GetMemInc(c_cs,ip);
  727. src += (GetMemInc(c_cs,ip) << 8)+CF;
  728. tmp2 += src;
  729. CF = tmp2 >> 16;
  730. /* SetCFW_Add(tmp2,tmp); */
  731. SetOFW_Add(tmp2,tmp,src);
  732. SetAF(tmp2,tmp,src);
  733. SetZFW(tmp2);
  734. SetSFW(tmp2);
  735. SetPF(tmp2);
  736. WriteWord(&wregs[AX],tmp2);
  737. }
  738. static INLINE2 void i_push_ss(void)
  739. {
  740. /* Opcode 0x16 */
  741. PushSeg(SS);
  742. }
  743. static INLINE2 void i_pop_ss(void)
  744. {
  745. /* Opcode 0x17 */
  746. static int multiple = 0;
  747. PopSeg(c_ss,SS);
  748. c_stack = c_ss;
  749. if (multiple == 0) /* prevent unlimited recursion */
  750. {
  751. multiple = 1;
  752. /*
  753. #ifdef DEBUGGER
  754. call_debugger(D_TRACE);
  755. #endif
  756. */
  757. instruction[GetMemInc(c_cs,ip)]();
  758. multiple = 0;
  759. }
  760. }
  761. static INLINE2 void i_sbb_br8(void)
  762. {
  763. /* Opcode 0x18 */
  764. unsigned ModRM = (unsigned)GetMemInc(c_cs,ip);
  765. register unsigned src = (unsigned)*GetModRMRegB(ModRM)+CF;
  766. BYTE *dest = GetModRMRMB(ModRM);
  767. register unsigned tmp = (unsigned) *dest;
  768. register unsigned tmp2 = tmp;
  769. tmp -= src;
  770. CF = (tmp & 0x100) == 0x100;
  771. /* SetCFB_Sub(tmp,tmp2); */
  772. SetOFB_Sub(tmp,src,tmp2);
  773. SetAF(tmp,src,tmp2);
  774. SetZFB(tmp);
  775. SetSFB(tmp);
  776. SetPF(tmp);
  777. *dest = (BYTE)tmp;
  778. }
  779. static INLINE2 void i_sbb_wr16(void)
  780. {
  781. /* Opcode 0x19 */
  782. unsigned ModRM = GetMemInc(c_cs,ip);
  783. WORD *src = GetModRMRegW(ModRM);
  784. WORD *dest = GetModRMRMW(ModRM);
  785. register unsigned tmp1 = ReadWord(dest);
  786. register unsigned tmp2 = ReadWord(src)+CF;
  787. register unsigned tmp3;
  788. tmp3 = tmp1-tmp2;
  789. CF = (tmp3 & 0x10000) == 0x10000;
  790. /* SetCFW_Sub(tmp2,tmp1); */
  791. SetOFW_Sub(tmp3,tmp2,tmp1);
  792. SetAF(tmp3,tmp2,tmp1);
  793. SetZFW(tmp3);
  794. SetSFW(tmp3);
  795. SetPF(tmp3);
  796. WriteWord(dest, tmp3);
  797. }
  798. static INLINE2 void i_sbb_r8b(void)
  799. {
  800. /* Opcode 0x1a */
  801. unsigned ModRM = (unsigned)GetMemInc(c_cs,ip);
  802. register unsigned src = (unsigned)*GetModRMRMB(ModRM)+CF;
  803. BYTE *dest = GetModRMRegB(ModRM);
  804. register unsigned tmp = (unsigned) *dest;
  805. register unsigned tmp2 = tmp;
  806. tmp -= src;
  807. CF = (tmp & 0x100) == 0x100;
  808. /* SetCFB_Sub(tmp,tmp2); */
  809. SetOFB_Sub(tmp,src,tmp2);
  810. SetAF(tmp,src,tmp2);
  811. SetZFB(tmp);
  812. SetSFB(tmp);
  813. SetPF(tmp);
  814. *dest = (BYTE)tmp;
  815. }
  816. static INLINE2 void i_sbb_r16w(void)
  817. {
  818. /* Opcode 0x1b */
  819. unsigned ModRM = GetMemInc(c_cs,ip);
  820. WORD *dest = GetModRMRegW(ModRM);
  821. WORD *src = GetModRMRMW(ModRM);
  822. register unsigned tmp1 = ReadWord(dest);
  823. register unsigned tmp2 = ReadWord(src)+CF;
  824. register unsigned tmp3;
  825. tmp3 = tmp1-tmp2;
  826. CF = (tmp3 & 0x10000) == 0x10000;
  827. /* SetCFW_Sub(tmp2,tmp1); */
  828. SetOFW_Sub(tmp3,tmp2,tmp1);
  829. SetAF(tmp3,tmp2,tmp1);
  830. SetZFW(tmp3);
  831. SetSFW(tmp3);
  832. SetPF(tmp3);
  833. WriteWord(dest, tmp3);
  834. }
  835. static INLINE2 void i_sbb_ald8(void)
  836. {
  837. /* Opcode 0x1c */
  838. register unsigned src = GetMemInc(c_cs,ip)+CF;
  839. register unsigned tmp = *bregs[AL];
  840. register unsigned tmp1 = tmp;
  841. tmp1 -= src;
  842. CF = (tmp1 & 0x100) == 0x100;
  843. /* SetCFB_Sub(src,tmp); */
  844. SetOFB_Sub(tmp1,src,tmp);
  845. SetAF(tmp1,src,tmp);
  846. SetZFB(tmp1);
  847. SetSFB(tmp1);
  848. SetPF(tmp1);
  849. *bregs[AL] = (BYTE)tmp1;
  850. }
  851. static INLINE2 void i_sbb_axd16(void)
  852. {
  853. /* Opcode 0x1d */
  854. register unsigned src;
  855. register unsigned tmp = ReadWord(&wregs[AX]);
  856. register unsigned tmp2 = tmp;
  857. src = GetMemInc(c_cs,ip);
  858. src += (GetMemInc(c_cs,ip) << 8)+CF;
  859. tmp2 -= src;
  860. CF = (tmp2 & 0x10000) == 0x10000;
  861. /* SetCFW_Sub(src,tmp); */
  862. SetOFW_Sub(tmp2,src,tmp);
  863. SetAF(tmp2,tmp,src);
  864. SetZFW(tmp2);
  865. SetSFW(tmp2);
  866. SetPF(tmp2);
  867. WriteWord(&wregs[AX],tmp2);
  868. }
  869. static INLINE2 void i_push_ds(void)
  870. {
  871. /* Opcode 0x1e */
  872. PushSeg(DS);
  873. }
  874. static INLINE2 void i_pop_ds(void)
  875. {
  876. /* Opcode 0x1f */
  877. PopSeg(c_ds,DS);
  878. }
  879. /* most AND instructions go here... */
  880. LogicalOp(and,&)
  881. static INLINE2 void i_es(void)
  882. {
  883. /* Opcode 0x26 */
  884. c_ds = c_ss = c_es;
  885. instruction[GetMemInc(c_cs,ip)]();
  886. c_ds = SegToMemPtr(DS);
  887. c_ss = SegToMemPtr(SS);
  888. }
  889. static INLINE2 void i_daa(void)
  890. {
  891. if (AF || ((*bregs[AL] & 0xf) > 9))
  892. {
  893. *bregs[AL] += 6;
  894. AF = 1;
  895. }
  896. else
  897. AF = 0;
  898. if (CF || (*bregs[AL] > 0x9f))
  899. {
  900. *bregs[AL] += 0x60;
  901. CF = 1;
  902. }
  903. else
  904. CF = 0;
  905. SetPF(*bregs[AL]);
  906. SetSFB(*bregs[AL]);
  907. SetZFB(*bregs[AL]);
  908. }
  909. static INLINE2 void i_sub_br8(void)
  910. {
  911. /* Opcode 0x28 */
  912. unsigned ModRM = (unsigned)GetMemInc(c_cs,ip);
  913. register unsigned src = (unsigned)*GetModRMRegB(ModRM);
  914. BYTE *dest = GetModRMRMB(ModRM);
  915. register unsigned tmp = (unsigned) *dest;
  916. register unsigned tmp2 = tmp;
  917. tmp -= src;
  918. SetCFB_Sub(tmp,tmp2);
  919. SetOFB_Sub(tmp,src,tmp2);
  920. SetAF(tmp,src,tmp2);
  921. SetZFB(tmp);
  922. SetSFB(tmp);
  923. SetPF(tmp);
  924. *dest = (BYTE)tmp;
  925. }
  926. static INLINE2 void i_sub_wr16(void)
  927. {
  928. /* Opcode 0x29 */
  929. unsigned ModRM = GetMemInc(c_cs,ip);
  930. WORD *src = GetModRMRegW(ModRM);
  931. WORD *dest = GetModRMRMW(ModRM);
  932. register unsigned tmp1 = ReadWord(dest);
  933. register unsigned tmp2 = ReadWord(src);
  934. register unsigned tmp3;
  935. tmp3 = tmp1-tmp2;
  936. SetCFW_Sub(tmp2,tmp1);
  937. SetOFW_Sub(tmp3,tmp2,tmp1);
  938. SetAF(tmp3,tmp2,tmp1);
  939. SetZFW(tmp3);
  940. SetSFW(tmp3);
  941. SetPF(tmp3);
  942. WriteWord(dest, tmp3);
  943. }
  944. static INLINE2 void i_sub_r8b(void)
  945. {
  946. /* Opcode 0x2a */
  947. unsigned ModRM = (unsigned)GetMemInc(c_cs,ip);
  948. BYTE *dest = GetModRMRegB(ModRM);
  949. register unsigned src = *GetModRMRMB(ModRM);
  950. register unsigned tmp = *dest;
  951. register unsigned tmp2 = tmp;
  952. tmp -= src;
  953. SetCFB_Sub(tmp,tmp2);
  954. SetOFB_Sub(tmp,src,tmp2);
  955. SetAF(tmp,src,tmp2);
  956. SetZFB(tmp);
  957. SetSFB(tmp);
  958. SetPF(tmp);
  959. *dest = (BYTE)tmp;
  960. }
  961. static INLINE2 void i_sub_r16w(void)
  962. {
  963. /* Opcode 0x2b */
  964. unsigned ModRM = GetMemInc(c_cs,ip);
  965. WORD *dest = GetModRMRegW(ModRM);
  966. WORD *src = GetModRMRMW(ModRM);
  967. register unsigned tmp1 = ReadWord(dest);
  968. register unsigned tmp2 = ReadWord(src);
  969. register unsigned tmp3;
  970. tmp3 = tmp1-tmp2;
  971. SetCFW_Sub(tmp2,tmp1);
  972. SetOFW_Sub(tmp3,tmp2,tmp1);
  973. SetAF(tmp3,tmp2,tmp1);
  974. SetZFW(tmp3);
  975. SetSFW(tmp3);
  976. SetPF(tmp3);
  977. WriteWord(dest, tmp3);
  978. }
  979. static INLINE2 void i_sub_ald8(void)
  980. {
  981. /* Opcode 0x2c */
  982. register unsigned src = GetMemInc(c_cs,ip);
  983. register unsigned tmp = *bregs[AL];
  984. register unsigned tmp1 = tmp;
  985. tmp1 -= src;
  986. SetCFB_Sub(src,tmp);
  987. SetOFB_Sub(tmp1,src,tmp);
  988. SetAF(tmp1,src,tmp);
  989. SetZFB(tmp1);
  990. SetSFB(tmp1);
  991. SetPF(tmp1);
  992. *bregs[AL] = (unsigned) tmp1;
  993. }
  994. static INLINE2 void i_sub_axd16(void)
  995. {
  996. /* Opcode 0x2d */
  997. register unsigned src;
  998. register unsigned tmp = ReadWord(&wregs[AX]);
  999. register unsigned tmp2 = tmp;
  1000. src = GetMemInc(c_cs,ip);
  1001. src += (GetMemInc(c_cs,ip) << 8);
  1002. tmp2 -= src;
  1003. SetCFW_Sub(src,tmp);
  1004. SetOFW_Sub(tmp2,src,tmp);
  1005. SetAF(tmp2,tmp,src);
  1006. SetZFW(tmp2);
  1007. SetSFW(tmp2);
  1008. SetPF(tmp2);
  1009. WriteWord(&wregs[AX],tmp2);
  1010. }
  1011. static INLINE2 void i_cs(void)
  1012. {
  1013. /* Opcode 0x2e */
  1014. c_ds = c_ss = c_cs;
  1015. instruction[GetMemInc(c_cs,ip)]();
  1016. c_ds = SegToMemPtr(DS);
  1017. c_ss = SegToMemPtr(SS);
  1018. }
  1019. /* most XOR instructions go here */
  1020. LogicalOp(xor,^)
  1021. static INLINE2 void i_ss(void)
  1022. {
  1023. /* Opcode 0x36 */
  1024. c_ds = c_ss;
  1025. instruction[GetMemInc(c_cs,ip)]();
  1026. c_ds = SegToMemPtr(DS);
  1027. }
  1028. static INLINE2 void i_cmp_br8(void)
  1029. {
  1030. /* Opcode 0x38 */
  1031. unsigned ModRM = (unsigned)GetMemInc(c_cs,ip);
  1032. register unsigned src = (unsigned)*GetModRMRegB(ModRM);
  1033. register unsigned tmp = *GetModRMRMB(ModRM);
  1034. register unsigned tmp2 = tmp;
  1035. tmp -= src;
  1036. SetCFB_Sub(tmp,tmp2);
  1037. SetOFB_Sub(tmp,src,tmp2);
  1038. SetAF(tmp,src,tmp2);
  1039. SetZFB(tmp);
  1040. SetSFB(tmp);
  1041. SetPF(tmp);
  1042. }
  1043. static INLINE2 void i_cmp_wr16(void)
  1044. {
  1045. /* Opcode 0x39 */
  1046. unsigned ModRM = GetMemInc(c_cs,ip);
  1047. WORD *src = GetModRMRegW(ModRM);
  1048. WORD *dest = GetModRMRMW(ModRM);
  1049. register unsigned tmp1 = ReadWord(dest);
  1050. register unsigned tmp2 = ReadWord(src);
  1051. register unsigned tmp3;
  1052. tmp3 = tmp1-tmp2;
  1053. SetCFW_Sub(tmp2,tmp1);
  1054. SetOFW_Sub(tmp3,tmp2,tmp1);
  1055. SetAF(tmp3,tmp2,tmp1);
  1056. SetZFW(tmp3);
  1057. SetSFW(tmp3);
  1058. SetPF(tmp3);
  1059. }
  1060. static INLINE2 void i_cmp_r8b(void)
  1061. {
  1062. /* Opcode 0x3a */
  1063. unsigned ModRM = (unsigned)GetMemInc(c_cs,ip);
  1064. register unsigned tmp = (unsigned)*GetModRMRegB(ModRM);
  1065. register unsigned src = *GetModRMRMB(ModRM);
  1066. register unsigned tmp2 = tmp;
  1067. tmp -= src;
  1068. SetCFB_Sub(tmp,tmp2);
  1069. SetOFB_Sub(tmp,src,tmp2);
  1070. SetAF(tmp,src,tmp2);
  1071. SetZFB(tmp);
  1072. SetSFB(tmp);
  1073. SetPF(tmp);
  1074. }
  1075. static INLINE2 void i_cmp_r16w(void)
  1076. {
  1077. /* Opcode 0x3b */
  1078. unsigned ModRM = GetMemInc(c_cs,ip);
  1079. WORD *dest = GetModRMRegW(ModRM);
  1080. WORD *src = GetModRMRMW(ModRM);
  1081. register unsigned tmp1 = ReadWord(dest);
  1082. register unsigned tmp2 = ReadWord(src);
  1083. register unsigned tmp3;
  1084. tmp3 = tmp1-tmp2;
  1085. SetCFW_Sub(tmp2,tmp1);
  1086. SetOFW_Sub(tmp3,tmp2,tmp1);
  1087. SetAF(tmp3,tmp2,tmp1);
  1088. SetZFW(tmp3);
  1089. SetSFW(tmp3);
  1090. SetPF(tmp3);
  1091. }
  1092. static INLINE2 void i_cmp_ald8(void)
  1093. {
  1094. /* Opcode 0x3c */
  1095. register unsigned src = GetMemInc(c_cs,ip);
  1096. register unsigned tmp = *bregs[AL];
  1097. register unsigned tmp1 = tmp;
  1098. tmp1 -= src;
  1099. SetCFB_Sub(src,tmp);
  1100. SetOFB_Sub(tmp1,src,tmp);
  1101. SetAF(tmp1,src,tmp);
  1102. SetZFB(tmp1);
  1103. SetSFB(tmp1);
  1104. SetPF(tmp1);
  1105. }
  1106. static INLINE2 void i_cmp_axd16(void)
  1107. {
  1108. /* Opcode 0x3d */
  1109. register unsigned src;
  1110. register unsigned tmp = ReadWord(&wregs[AX]);
  1111. register unsigned tmp2 = tmp;
  1112. src = GetMemInc(c_cs,ip);
  1113. src += (GetMemInc(c_cs,ip) << 8);
  1114. tmp2 -= src;
  1115. SetCFW_Sub(src,tmp);
  1116. SetOFW_Sub(tmp2,src,tmp);
  1117. SetAF(tmp2,tmp,src);
  1118. SetZFW(tmp2);
  1119. SetSFW(tmp2);
  1120. SetPF(tmp2);
  1121. }
  1122. static INLINE2 void i_ds(void)
  1123. {
  1124. /* Opcode 0x3e */
  1125. c_ss = c_ds;
  1126. instruction[GetMemInc(c_cs,ip)]();
  1127. c_ss = SegToMemPtr(SS);
  1128. }
  1129. static INLINE2 void i_inc_ax(void)
  1130. {
  1131. /* Opcode 0x40 */
  1132. IncWordReg(AX);
  1133. }
  1134. static INLINE2 void i_inc_cx(void)
  1135. {
  1136. /* Opcode 0x41 */
  1137. IncWordReg(CX);
  1138. }
  1139. static INLINE2 void i_inc_dx(void)
  1140. {
  1141. /* Opcode 0x42 */
  1142. IncWordReg(DX);
  1143. }
  1144. static INLINE2 void i_inc_bx(void)
  1145. {
  1146. /* Opcode 0x43 */
  1147. IncWordReg(BX);
  1148. }
  1149. static INLINE2 void i_inc_sp(void)
  1150. {
  1151. /* Opcode 0x44 */
  1152. IncWordReg(SP);
  1153. }
  1154. static INLINE2 void i_inc_bp(void)
  1155. {
  1156. /* Opcode 0x45 */
  1157. IncWordReg(BP);
  1158. }
  1159. static INLINE2 void i_inc_si(void)
  1160. {
  1161. /* Opcode 0x46 */
  1162. IncWordReg(SI);
  1163. }
  1164. static INLINE2 void i_inc_di(void)
  1165. {
  1166. /* Opcode 0x47 */
  1167. IncWordReg(DI);
  1168. }
  1169. static INLINE2 void i_dec_ax(void)
  1170. {
  1171. /* Opcode 0x48 */
  1172. DecWordReg(AX);
  1173. }
  1174. static INLINE2 void i_dec_cx(void)
  1175. {
  1176. /* Opcode 0x49 */
  1177. DecWordReg(CX);
  1178. }
  1179. static INLINE2 void i_dec_dx(void)
  1180. {
  1181. /* Opcode 0x4a */
  1182. DecWordReg(DX);
  1183. }
  1184. static INLINE2 void i_dec_bx(void)
  1185. {
  1186. /* Opcode 0x4b */
  1187. DecWordReg(BX);
  1188. }
  1189. static INLINE2 void i_dec_sp(void)
  1190. {
  1191. /* Opcode 0x4c */
  1192. DecWordReg(SP);
  1193. }
  1194. static INLINE2 void i_dec_bp(void)
  1195. {
  1196. /* Opcode 0x4d */
  1197. DecWordReg(BP);
  1198. }
  1199. static INLINE2 void i_dec_si(void)
  1200. {
  1201. /* Opcode 0x4e */
  1202. DecWordReg(SI);
  1203. }
  1204. static INLINE2 void i_dec_di(void)
  1205. {
  1206. /* Opcode 0x4f */
  1207. DecWordReg(DI);
  1208. }
  1209. static INLINE2 void i_push_ax(void)
  1210. {
  1211. /* Opcode 0x50 */
  1212. PushWordReg(AX);
  1213. }
  1214. static INLINE2 void i_push_cx(void)
  1215. {
  1216. /* Opcode 0x51 */
  1217. PushWordReg(CX);
  1218. }
  1219. static INLINE2 void i_push_dx(void)
  1220. {
  1221. /* Opcode 0x52 */
  1222. PushWordReg(DX);
  1223. }
  1224. static INLINE2 void i_push_bx(void)
  1225. {
  1226. /* Opcode 0x53 */
  1227. PushWordReg(BX);
  1228. }
  1229. static INLINE2 void i_push_sp(void)
  1230. {
  1231. /* Opcode 0x54 */
  1232. PushWordReg(SP);
  1233. }
  1234. static INLINE2 void i_push_bp(void)
  1235. {
  1236. /* Opcode 0x55 */
  1237. PushWordReg(BP);
  1238. }
  1239. static INLINE2 void i_push_si(void)
  1240. {
  1241. /* Opcode 0x56 */
  1242. PushWordReg(SI);
  1243. }
  1244. static INLINE2 void i_push_di(void)
  1245. {
  1246. /* Opcode 0x57 */
  1247. PushWordReg(DI);
  1248. }
  1249. static INLINE2 void i_pop_ax(void)
  1250. {
  1251. /* Opcode 0x58 */
  1252. PopWordReg(AX);
  1253. }
  1254. static INLINE2 void i_pop_cx(void)
  1255. {
  1256. /* Opcode 0x59 */
  1257. PopWordReg(CX);
  1258. }
  1259. static INLINE2 void i_pop_dx(void)
  1260. {
  1261. /* Opcode 0x5a */
  1262. PopWordReg(DX);
  1263. }
  1264. static INLINE2 void i_pop_bx(void)
  1265. {
  1266. /* Opcode 0x5b */
  1267. PopWordReg(BX);
  1268. }
  1269. static INLINE2 void i_pop_sp(void)
  1270. {
  1271. /* Opcode 0x5c */
  1272. PopWordReg(SP);
  1273. }
  1274. static INLINE2 void i_pop_bp(void)
  1275. {
  1276. /* Opcode 0x5d */
  1277. PopWordReg(BP);
  1278. }
  1279. static INLINE2 void i_pop_si(void)
  1280. {
  1281. /* Opcode 0x5e */
  1282. PopWordReg(SI);
  1283. }
  1284. static INLINE2 void i_pop_di(void)
  1285. {
  1286. /* Opcode 0x5f */
  1287. PopWordReg(DI);
  1288. }
  1289. /* Conditional jumps from 0x70 to 0x7f */
  1290. JumpCond(o, OF) /* 0x70 = Jump if overflow */
  1291. JumpCond(no, !OF) /* 0x71 = Jump if no overflow */
  1292. JumpCond(b, CF) /* 0x72 = Jump if below */
  1293. JumpCond(nb, !CF) /* 0x73 = Jump if not below */
  1294. JumpCond(z, ZF) /* 0x74 = Jump if zero */
  1295. JumpCond(nz, !ZF) /* 0x75 = Jump if not zero */
  1296. JumpCond(be, CF || ZF) /* 0x76 = Jump if below or equal */
  1297. JumpCond(nbe, !(CF || ZF)) /* 0x77 = Jump if not below or equal */
  1298. JumpCond(s, SF) /* 0x78 = Jump if sign */
  1299. JumpCond(ns, !SF) /* 0x79 = Jump if no sign */
  1300. JumpCond(p, PF) /* 0x7a = Jump if parity */
  1301. JumpCond(np, !PF) /* 0x7b = Jump if no parity */
  1302. JumpCond(l,(!(!SF)!=!(!OF))&&!ZF) /* 0x7c = Jump if less */
  1303. JumpCond(nl, ZF||(!(!SF) == !(!OF))) /* 0x7d = Jump if not less */
  1304. JumpCond(le, ZF||(!(!SF) != !(!OF))) /* 0x7e = Jump if less than or equal */
  1305. JumpCond(nle,(!(!SF)==!(!OF))&&!ZF) /* 0x7f = Jump if not less than or equal*/
  1306. static INLINE2 void i_80pre(void)
  1307. {
  1308. /* Opcode 0x80 */
  1309. unsigned ModRM = GetMemInc(c_cs,ip);
  1310. BYTE *dest = GetModRMRMB(ModRM);
  1311. register unsigned src = GetMemInc(c_cs,ip);
  1312. register unsigned tmp = *dest;
  1313. register unsigned tmp2;
  1314. switch (ModRM & 0x38)
  1315. {
  1316. case 0x00: /* ADD eb,d8 */
  1317. tmp2 = src + tmp;
  1318. SetCFB_Add(tmp2,tmp);
  1319. SetOFB_Add(tmp2,src,tmp);
  1320. SetAF(tmp2,src,tmp);
  1321. SetZFB(tmp2);
  1322. SetSFB(tmp2);
  1323. SetPF(tmp2);
  1324. *dest = (BYTE)tmp2;
  1325. break;
  1326. case 0x08: /* OR eb,d8 */
  1327. tmp |= src;
  1328. CF = OF = AF = 0;
  1329. SetZFB(tmp);
  1330. SetSFB(tmp);
  1331. SetPF(tmp);
  1332. *dest = (BYTE)tmp;
  1333. break;
  1334. case 0x10: /* ADC eb,d8 */
  1335. src += CF;
  1336. tmp2 = src + tmp;
  1337. CF = tmp2 >> 8;
  1338. /* SetCFB_Add(tmp2,tmp); */
  1339. SetOFB_Add(tmp2,src,tmp);
  1340. SetAF(tmp2,src,tmp);
  1341. SetZFB(tmp2);
  1342. SetSFB(tmp2);
  1343. SetPF(tmp2);
  1344. *dest = (BYTE)tmp2;
  1345. break;
  1346. case 0x18: /* SBB eb,b8 */
  1347. src += CF;
  1348. tmp2 = tmp;
  1349. tmp -= src;
  1350. CF = (tmp & 0x100) == 0x100;
  1351. /* SetCFB_Sub(tmp,tmp2); */
  1352. SetOFB_Sub(tmp,src,tmp2);
  1353. SetAF(tmp,src,tmp2);
  1354. SetZFB(tmp);
  1355. SetSFB(tmp);
  1356. SetPF(tmp);
  1357. *dest = (BYTE)tmp;
  1358. break;
  1359. case 0x20: /* AND eb,d8 */
  1360. tmp &= src;
  1361. CF = OF = AF = 0;
  1362. SetZFB(tmp);
  1363. SetSFB(tmp);
  1364. SetPF(tmp);
  1365. *dest = (BYTE)tmp;
  1366. break;
  1367. case 0x28: /* SUB eb,d8 */
  1368. tmp2 = tmp;
  1369. tmp -= src;
  1370. SetCFB_Sub(tmp,tmp2);
  1371. SetOFB_Sub(tmp,src,tmp2);
  1372. SetAF(tmp,src,tmp2);
  1373. SetZFB(tmp);
  1374. SetSFB(tmp);
  1375. SetPF(tmp);
  1376. *dest = (BYTE)tmp;
  1377. break;
  1378. case 0x30: /* XOR eb,d8 */
  1379. tmp ^= src;
  1380. CF = OF = AF = 0;
  1381. SetZFB(tmp);
  1382. SetSFB(tmp);
  1383. SetPF(tmp);
  1384. *dest = (BYTE)tmp;
  1385. break;
  1386. case 0x38: /* CMP eb,d8 */
  1387. tmp2 = tmp;
  1388. tmp -= src;
  1389. SetCFB_Sub(tmp,tmp2);
  1390. SetOFB_Sub(tmp,src,tmp2);
  1391. SetAF(tmp,src,tmp2);
  1392. SetZFB(tmp);
  1393. SetSFB(tmp);
  1394. SetPF(tmp);
  1395. break;
  1396. }
  1397. }
  1398. static INLINE2 void i_81pre(void)
  1399. {
  1400. /* Opcode 0x81 */
  1401. unsigned ModRM = GetMemInc(c_cs,ip);
  1402. WORD *dest = GetModRMRMW(ModRM);
  1403. register unsigned src = GetMemInc(c_cs,ip);
  1404. register unsigned tmp = ReadWord(dest);
  1405. register unsigned tmp2;
  1406. src += GetMemInc(c_cs,ip) << 8;
  1407. switch (ModRM & 0x38)
  1408. {
  1409. case 0x00: /* ADD ew,d16 */
  1410. tmp2 = src + tmp;
  1411. SetCFW_Add(tmp2,tmp);
  1412. SetOFW_Add(tmp2,src,tmp);
  1413. SetAF(tmp2,src,tmp);
  1414. SetZFW(tmp2);
  1415. SetSFW(tmp2);
  1416. SetPF(tmp2);
  1417. WriteWord(dest,tmp2);
  1418. break;
  1419. case 0x08: /* OR ew,d16 */
  1420. tmp |= src;
  1421. CF = OF = AF = 0;
  1422. SetZFW(tmp);
  1423. SetSFW(tmp);
  1424. SetPF(tmp);
  1425. WriteWord(dest,tmp);
  1426. break;
  1427. case 0x10: /* ADC ew,d16 */
  1428. src += CF;
  1429. tmp2 = src + tmp;
  1430. CF = tmp2 >> 16;
  1431. /* SetCFW_Add(tmp2,tmp); */
  1432. SetOFW_Add(tmp2,src,tmp);
  1433. SetAF(tmp2,src,tmp);
  1434. SetZFW(tmp2);
  1435. SetSFW(tmp2);
  1436. SetPF(tmp2);
  1437. WriteWord(dest,tmp2);
  1438. break;
  1439. case 0x18: /* SBB ew,d16 */
  1440. src += CF;
  1441. tmp2 = tmp;
  1442. tmp -= src;
  1443. CF = (tmp & 0x10000) == 0x10000;
  1444. /* SetCFW_Sub(tmp,tmp2); */
  1445. SetOFW_Sub(tmp,src,tmp2);
  1446. SetAF(tmp,src,tmp2);
  1447. SetZFW(tmp);
  1448. SetSFW(tmp);
  1449. SetPF(tmp);
  1450. WriteWord(dest,tmp);
  1451. break;
  1452. case 0x20: /* AND ew,d16 */
  1453. tmp &= src;
  1454. CF = OF = AF = 0;
  1455. SetZFW(tmp);
  1456. SetSFW(tmp);
  1457. SetPF(tmp);
  1458. WriteWord(dest,tmp);
  1459. break;
  1460. case 0x28: /* SUB ew,d16 */
  1461. tmp2 = tmp;
  1462. tmp -= src;
  1463. SetCFW_Sub(tmp,tmp2);
  1464. SetOFW_Sub(tmp,src,tmp2);
  1465. SetAF(tmp,src,tmp2);
  1466. SetZFW(tmp);
  1467. SetSFW(tmp);
  1468. SetPF(tmp);
  1469. WriteWord(dest,tmp);
  1470. break;
  1471. case 0x30: /* XOR ew,d16 */
  1472. tmp ^= src;
  1473. CF = OF = AF = 0;
  1474. SetZFW(tmp);
  1475. SetSFW(tmp);
  1476. SetPF(tmp);
  1477. WriteWord(dest,tmp);
  1478. break;
  1479. case 0x38: /* CMP ew,d16 */
  1480. tmp2 = tmp;
  1481. tmp -= src;
  1482. SetCFW_Sub(tmp,tmp2);
  1483. SetOFW_Sub(tmp,src,tmp2);
  1484. SetAF(tmp,src,tmp2);
  1485. SetZFW(tmp);
  1486. SetSFW(tmp);
  1487. SetPF(tmp);
  1488. break;
  1489. }
  1490. }
  1491. static INLINE2 void i_83pre(void)
  1492. {
  1493. /* Opcode 0x83 */
  1494. unsigned ModRM = GetMemInc(c_cs,ip);
  1495. WORD *dest = GetModRMRMW(ModRM);
  1496. register unsigned src = (WORD)((INT16)((INT8)GetMemInc(c_cs,ip)));
  1497. register unsigned tmp = ReadWord(dest);
  1498. register unsigned tmp2;
  1499. switch (ModRM & 0x38)
  1500. {
  1501. case 0x00: /* ADD ew,d8 */
  1502. tmp2 = src + tmp;
  1503. SetCFW_Add(tmp2,tmp);
  1504. SetOFW_Add(tmp2,src,tmp);
  1505. SetAF(tmp2,src,tmp);
  1506. SetZFW(tmp2);
  1507. SetSFW(tmp2);
  1508. SetPF(tmp2);
  1509. WriteWord(dest,tmp2);
  1510. break;
  1511. case 0x08: /* OR ew,d8 */
  1512. tmp |= src;
  1513. CF = OF = AF = 0;
  1514. SetZFW(tmp);
  1515. SetSFW(tmp);
  1516. SetPF(tmp);
  1517. WriteWord(dest,tmp);
  1518. break;
  1519. case 0x10: /* ADC ew,d8 */
  1520. src += CF;
  1521. tmp2 = src + tmp;
  1522. CF = tmp2 >> 16;
  1523. /* SetCFW_Add(tmp2,tmp); */
  1524. SetOFW_Add(tmp2,src,tmp);
  1525. SetAF(tmp2,src,tmp);
  1526. SetZFW(tmp2);
  1527. SetSFW(tmp2);
  1528. SetPF(tmp2);
  1529. WriteWord(dest,tmp2);
  1530. break;
  1531. case 0x18: /* SBB ew,d8 */
  1532. src += CF;
  1533. tmp2 = tmp;
  1534. tmp -= src;
  1535. CF = (tmp & 0x10000) == 0x10000;
  1536. /* SetCFW_Sub(tmp,tmp2); */
  1537. SetOFW_Sub(tmp,src,tmp2);
  1538. SetAF(tmp,src,tmp2);
  1539. SetZFW(tmp);
  1540. SetSFW(tmp);
  1541. SetPF(tmp);
  1542. WriteWord(dest,tmp);
  1543. break;
  1544. case 0x20: /* AND ew,d8 */
  1545. tmp &= src;
  1546. CF = OF = AF = 0;
  1547. SetZFW(tmp);
  1548. SetSFW(tmp);
  1549. SetPF(tmp);
  1550. WriteWord(dest,tmp);
  1551. break;
  1552. case 0x28: /* SUB ew,d8 */
  1553. tmp2 = tmp;
  1554. tmp -= src;
  1555. SetCFW_Sub(tmp,tmp2);
  1556. SetOFW_Sub(tmp,src,tmp2);
  1557. SetAF(tmp,src,tmp2);
  1558. SetZFW(tmp);
  1559. SetSFW(tmp);
  1560. SetPF(tmp);
  1561. WriteWord(dest,tmp);
  1562. break;
  1563. case 0x30: /* XOR ew,d8 */
  1564. tmp ^= src;
  1565. CF = OF = AF = 0;
  1566. SetZFW(tmp);
  1567. SetSFW(tmp);
  1568. SetPF(tmp);
  1569. WriteWord(dest,tmp);
  1570. break;
  1571. case 0x38: /* CMP ew,d8 */
  1572. tmp2 = tmp;
  1573. tmp -= src;
  1574. SetCFW_Sub(tmp,tmp2);
  1575. SetOFW_Sub(tmp,src,tmp2);
  1576. SetAF(tmp,src,tmp2);
  1577. SetZFW(tmp);
  1578. SetSFW(tmp);
  1579. SetPF(tmp);
  1580. break;
  1581. }
  1582. }
  1583. static INLINE2 void i_test_br8(void)
  1584. {
  1585. /* Opcode 0x84 */
  1586. unsigned ModRM = (unsigned)GetMemInc(c_cs,ip);
  1587. register unsigned src = (unsigned)*GetModRMRegB(ModRM);
  1588. BYTE *dest = GetModRMRMB(ModRM);
  1589. register unsigned tmp = (unsigned) *dest;
  1590. tmp &= src;
  1591. CF = OF = AF = 0;
  1592. SetZFB(tmp);
  1593. SetSFB(tmp);
  1594. SetPF(tmp);
  1595. }
  1596. static INLINE2 void i_test_wr16(void)
  1597. {
  1598. /* Opcode 0x85 */
  1599. unsigned ModRM = GetMemInc(c_cs,ip);
  1600. WORD *src = GetModRMRegW(ModRM);
  1601. WORD *dest = GetModRMRMW(ModRM);
  1602. register unsigned tmp1 = (unsigned)ReadWord(src);
  1603. register unsigned tmp2 = (unsigned)ReadWord(dest);
  1604. register unsigned tmp3 = tmp1 & tmp2;
  1605. CF = OF = AF = 0;
  1606. SetZFW(tmp3);
  1607. SetSFW(tmp3);
  1608. SetPF(tmp3);
  1609. }
  1610. static INLINE2 void i_xchg_br8(void)
  1611. {
  1612. /* Opcode 0x86 */
  1613. unsigned ModRM = (unsigned)GetMemInc(c_cs,ip);
  1614. register BYTE *src = GetModRMRegB(ModRM);
  1615. register BYTE *dest = GetModRMRMB(ModRM);
  1616. BYTE tmp;
  1617. tmp = *src;
  1618. *src = *dest;
  1619. *dest = tmp;
  1620. }
  1621. static INLINE2 void i_xchg_wr16(void)
  1622. {
  1623. /* Opcode 0x87 */
  1624. unsigned ModRM = GetMemInc(c_cs,ip);
  1625. register BYTE *src = (BYTE *)GetModRMRegW(ModRM);
  1626. register BYTE *dest = (BYTE *)GetModRMRMW(ModRM);
  1627. BYTE tmp1,tmp2;
  1628. tmp1 = src[0];
  1629. tmp2 = src[1];
  1630. src[0] = dest[0];
  1631. src[1] = dest[1];
  1632. dest[0] = tmp1;
  1633. dest[1] = tmp2;
  1634. }
  1635. static INLINE2 void i_mov_br8(void)
  1636. {
  1637. /* Opcode 0x88 */
  1638. register unsigned ModRM = GetMemInc(c_cs,ip);
  1639. register BYTE src = *GetModRMRegB(ModRM);
  1640. register BYTE *dest = GetModRMRMB(ModRM);
  1641. *dest = src;
  1642. }
  1643. static INLINE2 void i_mov_wr16(void)
  1644. {
  1645. /* Opcode 0x89 */
  1646. register unsigned ModRM = GetMemInc(c_cs,ip);
  1647. register WORD *src = GetModRMRegW(ModRM);
  1648. register WORD *dest = GetModRMRMW(ModRM);
  1649. CopyWord(dest,src);
  1650. }
  1651. static INLINE2 void i_mov_r8b(void)
  1652. {
  1653. /* Opcode 0x8a */
  1654. register unsigned ModRM = GetMemInc(c_cs,ip);
  1655. register BYTE *dest = GetModRMRegB(ModRM);
  1656. register BYTE src = *GetModRMRMB(ModRM);
  1657. *dest = src;
  1658. }
  1659. static INLINE2 void i_mov_r16w(void)
  1660. {
  1661. /* Opcode 0x8b */
  1662. register unsigned ModRM = GetMemInc(c_cs,ip);
  1663. register WORD *dest = GetModRMRegW(ModRM);
  1664. register WORD *src = GetModRMRMW(ModRM);
  1665. CopyWord(dest,src);
  1666. }
  1667. static INLINE2 void i_mov_wsreg(void)
  1668. {
  1669. /* Opcode 0x8c */
  1670. register unsigned ModRM = GetMemInc(c_cs,ip);
  1671. register WORD *dest = GetModRMRMW(ModRM);
  1672. WriteWord(dest,sregs[(ModRM & 0x38) >> 3]);
  1673. }
  1674. static INLINE2 void i_lea(void)
  1675. {
  1676. /* Opcode 0x8d */
  1677. register unsigned ModRM = GetMemInc(c_cs,ip);
  1678. register unsigned src = 0;
  1679. register WORD *dest = GetModRMRegW(ModRM);
  1680. if (ModRMRM[ModRM].offset)
  1681. {
  1682. src = (WORD)((INT16)((INT8)GetMemInc(c_cs,ip)));
  1683. if (ModRMRM[ModRM].offset16)
  1684. src = (GetMemInc(c_cs,ip) << 8) + (BYTE)(src);
  1685. }
  1686. src += ReadWord(ModRMRM[ModRM].reg1)+ReadWord(ModRMRM[ModRM].reg2);
  1687. WriteWord(dest,src);
  1688. }
  1689. static INLINE2 void i_mov_sregw(void)
  1690. {
  1691. /* Opcode 0x8e */
  1692. static int multiple = 0;
  1693. register unsigned ModRM = GetMemInc(c_cs,ip);
  1694. register WORD *src = GetModRMRMW(ModRM);
  1695. switch (ModRM & 0x38)
  1696. {
  1697. case 0x00: /* mov es,... */
  1698. sregs[ES] = ReadWord(src);
  1699. c_es = SegToMemPtr(ES);
  1700. break;
  1701. case 0x18: /* mov ds,... */
  1702. sregs[DS] = ReadWord(src);
  1703. c_ds = SegToMemPtr(DS);
  1704. break;
  1705. case 0x10: /* mov ss,... */
  1706. sregs[SS] = ReadWord(src);
  1707. c_stack = c_ss = SegToMemPtr(SS);
  1708. if (multiple == 0) /* Prevent unlimited recursion.. */
  1709. {
  1710. multiple = 1;
  1711. /*
  1712. #ifdef DEBUGGER
  1713. call_debugger(D_TRACE);
  1714. #endif
  1715. */
  1716. instruction[GetMemInc(c_cs,ip)]();
  1717. multiple = 0;
  1718. }
  1719. break;
  1720. case 0x08: /* mov cs,... (hangs 486, but we'll let it through) */
  1721. break;
  1722. }
  1723. }
  1724. static INLINE2 void i_popw(void)
  1725. {
  1726. /* Opcode 0x8f */
  1727. unsigned ModRM = GetMemInc(c_cs,ip);
  1728. register WORD *dest = GetModRMRMW(ModRM);
  1729. register unsigned tmp = ReadWord(&wregs[SP]);
  1730. WORD tmp2 = GetMemW(c_stack,tmp);
  1731. tmp += 2;
  1732. WriteWord(&wregs[SP],tmp);
  1733. WriteWord(dest,tmp2);
  1734. }
  1735. static INLINE2 void i_nop(void)
  1736. {
  1737. /* Opcode 0x90 */
  1738. }
  1739. static INLINE2 void i_xchg_axcx(void)
  1740. {
  1741. /* Opcode 0x91 */
  1742. XchgAXReg(CX);
  1743. }
  1744. static INLINE2 void i_xchg_axdx(void)
  1745. {
  1746. /* Opcode 0x92 */
  1747. XchgAXReg(DX);
  1748. }
  1749. static INLINE2 void i_xchg_axbx(void)
  1750. {
  1751. /* Opcode 0x93 */
  1752. XchgAXReg(BX);
  1753. }
  1754. static INLINE2 void i_xchg_axsp(void)
  1755. {
  1756. /* Opcode 0x94 */
  1757. XchgAXReg(SP);
  1758. }
  1759. static INLINE2 void i_xchg_axbp(void)
  1760. {
  1761. /* Opcode 0x95 */
  1762. XchgAXReg(BP);
  1763. }
  1764. static INLINE2 void i_xchg_axsi(void)
  1765. {
  1766. /* Opcode 0x96 */
  1767. XchgAXReg(SI);
  1768. }
  1769. static INLINE2 void i_xchg_axdi(void)
  1770. {
  1771. /* Opcode 0x97 */
  1772. XchgAXReg(DI);
  1773. }
  1774. static INLINE2 void i_cbw(void)
  1775. {
  1776. /* Opcode 0x98 */
  1777. *bregs[AH] = (*bregs[AL] & 0x80) ? 0xff : 0;
  1778. }
  1779. static INLINE2 void i_cwd(void)
  1780. {
  1781. /* Opcode 0x99 */
  1782. wregs[DX] = (*bregs[AH] & 0x80) ? ChangeE(0xffff) : ChangeE(0);
  1783. }
  1784. static INLINE2 void i_call_far(void)
  1785. {
  1786. register unsigned tmp, tmp1, tmp2;
  1787. tmp = GetMemInc(c_cs,ip);
  1788. tmp += GetMemInc(c_cs,ip) << 8;
  1789. tmp2 = GetMemInc(c_cs,ip);
  1790. tmp2 += GetMemInc(c_cs,ip) << 8;
  1791. tmp1 = (WORD)(ReadWord(&wregs[SP])-2);
  1792. PutMemW(c_stack,tmp1,sregs[CS]);
  1793. tmp1 = (WORD)(tmp1-2);
  1794. PutMemW(c_stack,tmp1,ip);
  1795. WriteWord(&wregs[SP],tmp1);
  1796. ip = (WORD)tmp;
  1797. sregs[CS] = (WORD)tmp2;
  1798. c_cs = SegToMemPtr(CS);
  1799. }
  1800. static INLINE2 void i_wait(void)
  1801. {
  1802. /* Opcode 0x9b */
  1803. return;
  1804. }
  1805. static INLINE2 void i_pushf(void)
  1806. {
  1807. /* Opcode 0x9c */
  1808. register unsigned tmp1 = (ReadWord(&wregs[SP])-2);
  1809. WORD tmp2 = CompressFlags() | 0xf000;
  1810. PutMemW(c_stack,tmp1,tmp2);
  1811. WriteWord(&wregs[SP],tmp1);
  1812. }
  1813. static INLINE2 void i_popf(void)
  1814. {
  1815. /* Opcode 0x9d */
  1816. register unsigned tmp = ReadWord(&wregs[SP]);
  1817. unsigned tmp2 = (unsigned)GetMemW(c_stack,tmp);
  1818. ExpandFlags(tmp2);
  1819. tmp += 2;
  1820. WriteWord(&wregs[SP],tmp);
  1821. if (IF && int_blocked)
  1822. {
  1823. int_pending = int_blocked;
  1824. int_blocked = 0;
  1825. D2(printf("Unblocking interrupt\n"););
  1826. }
  1827. if (TF) trap();
  1828. }
  1829. static INLINE2 void i_sahf(void)
  1830. {
  1831. /* Opcode 0x9e */
  1832. unsigned tmp = (CompressFlags() & 0xff00) | (*bregs[AH] & 0xd5);
  1833. ExpandFlags(tmp);
  1834. }
  1835. static INLINE2 void i_lahf(void)
  1836. {
  1837. /* Opcode 0x9f */
  1838. *bregs[AH] = CompressFlags() & 0xff;
  1839. }
  1840. static INLINE2 void i_mov_aldisp(void)
  1841. {
  1842. /* Opcode 0xa0 */
  1843. register unsigned addr;
  1844. addr = GetMemInc(c_cs,ip);
  1845. addr += GetMemInc(c_cs, ip) << 8;
  1846. *bregs[AL] = GetMemB(c_ds, addr);
  1847. }
  1848. static INLINE2 void i_mov_axdisp(void)
  1849. {
  1850. /* Opcode 0xa1 */
  1851. register unsigned addr;
  1852. addr = GetMemInc(c_cs, ip);
  1853. addr += GetMemInc(c_cs, ip) << 8;
  1854. *bregs[AL] = GetMemB(c_ds, addr);
  1855. *bregs[AH] = GetMemB(c_ds, addr+1);
  1856. }
  1857. static INLINE2 void i_mov_dispal(void)
  1858. {
  1859. /* Opcode 0xa2 */
  1860. register unsigned addr;
  1861. addr = GetMemInc(c_cs,ip);
  1862. addr += GetMemInc(c_cs, ip) << 8;
  1863. PutMemB(c_ds, addr, *bregs[AL]);
  1864. }
  1865. static INLINE2 void i_mov_dispax(void)
  1866. {
  1867. /* Opcode 0xa3 */
  1868. register unsigned addr;
  1869. addr = GetMemInc(c_cs, ip);
  1870. addr += GetMemInc(c_cs, ip) << 8;
  1871. PutMemB(c_ds, addr, *bregs[AL]);
  1872. PutMemB(c_ds, addr+1, *bregs[AH]);
  1873. }
  1874. static INLINE2 void i_movsb(void)
  1875. {
  1876. /* Opcode 0xa4 */
  1877. register unsigned di = ReadWord(&wregs[DI]);
  1878. register unsigned si = ReadWord(&wregs[SI]);
  1879. BYTE tmp = GetMemB(c_ds,si);
  1880. PutMemB(c_es,di, tmp);
  1881. di += -2*DF +1;
  1882. si += -2*DF +1;
  1883. WriteWord(&wregs[DI],di);
  1884. WriteWord(&wregs[SI],si);
  1885. }
  1886. static INLINE2 void i_movsw(void)
  1887. {
  1888. /* Opcode 0xa5 */
  1889. register unsigned di = ReadWord(&wregs[DI]);
  1890. register unsigned si = ReadWord(&wregs[SI]);
  1891. WORD tmp = GetMemW(c_ds,si);
  1892. PutMemW(c_es,di, tmp);
  1893. di += -4*DF +2;
  1894. si += -4*DF +2;
  1895. WriteWord(&wregs[DI],di);
  1896. WriteWord(&wregs[SI],si);
  1897. }
  1898. static INLINE2 void i_cmpsb(void)
  1899. {
  1900. /* Opcode 0xa6 */
  1901. unsigned di = ReadWord(&wregs[DI]);
  1902. unsigned si = ReadWord(&wregs[SI]);
  1903. unsigned src = GetMemB(c_es, di);
  1904. unsigned tmp = GetMemB(c_ds, si);
  1905. unsigned tmp2 = tmp;
  1906. tmp -= src;
  1907. SetCFB_Sub(tmp,tmp2);
  1908. SetOFB_Sub(tmp,src,tmp2);
  1909. SetAF(tmp,src,tmp2);
  1910. SetZFB(tmp);
  1911. SetSFB(tmp);
  1912. SetPF(tmp);
  1913. di += -2*DF +1;
  1914. si += -2*DF +1;
  1915. WriteWord(&wregs[DI],di);
  1916. WriteWord(&wregs[SI],si);
  1917. }
  1918. static INLINE2 void i_cmpsw(void)
  1919. {
  1920. /* Opcode 0xa7 */
  1921. unsigned di = ReadWord(&wregs[DI]);
  1922. unsigned si = ReadWord(&wregs[SI]);
  1923. unsigned src = GetMemW(c_es, di);
  1924. unsigned tmp = GetMemW(c_ds, si);
  1925. unsigned tmp2 = tmp;
  1926. tmp -= src;
  1927. SetCFW_Sub(tmp,tmp2);
  1928. SetOFW_Sub(tmp,src,tmp2);
  1929. SetAF(tmp,src,tmp2);
  1930. SetZFW(tmp);
  1931. SetSFW(tmp);
  1932. SetPF(tmp);
  1933. di += -4*DF +2;
  1934. si += -4*DF +2;
  1935. WriteWord(&wregs[DI],di);
  1936. WriteWord(&wregs[SI],si);
  1937. }
  1938. static INLINE2 void i_test_ald8(void)
  1939. {
  1940. /* Opcode 0xa8 */
  1941. register unsigned tmp1 = (unsigned)*bregs[AL];
  1942. register unsigned tmp2 = (unsigned) GetMemInc(c_cs,ip);
  1943. tmp1 &= tmp2;
  1944. CF = OF = AF = 0;
  1945. SetZFB(tmp1);
  1946. SetSFB(tmp1);
  1947. SetPF(tmp1);
  1948. }
  1949. static INLINE2 void i_test_axd16(void)
  1950. {
  1951. /* Opcode 0xa9 */
  1952. register unsigned tmp1 = (unsigned)ReadWord(&wregs[AX]);
  1953. register unsigned tmp2;
  1954. tmp2 = (unsigned) GetMemInc(c_cs,ip);
  1955. tmp2 += GetMemInc(c_cs,ip) << 8;
  1956. tmp1 &= tmp2;
  1957. CF = OF = AF = 0;
  1958. SetZFW(tmp1);
  1959. SetSFW(tmp1);
  1960. SetPF(tmp1);
  1961. }
  1962. static INLINE2 void i_stosb(void)
  1963. {
  1964. /* Opcode 0xaa */
  1965. register unsigned di = ReadWord(&wregs[DI]);
  1966. PutMemB(c_es,di,*bregs[AL]);
  1967. di += -2*DF +1;
  1968. WriteWord(&wregs[DI],di);
  1969. }
  1970. static INLINE2 void i_stosw(void)
  1971. {
  1972. /* Opcode 0xab */
  1973. register unsigned di = ReadWord(&wregs[DI]);
  1974. PutMemB(c_es,di,*bregs[AL]);
  1975. PutMemB(c_es,di+1,*bregs[AH]);
  1976. di += -4*DF +2;;
  1977. WriteWord(&wregs[DI],di);
  1978. }
  1979. static INLINE2 void i_lodsb(void)
  1980. {
  1981. /* Opcode 0xac */
  1982. register unsigned si = ReadWord(&wregs[SI]);
  1983. *bregs[AL] = GetMemB(c_ds,si);
  1984. si += -2*DF +1;
  1985. WriteWord(&wregs[SI],si);
  1986. }
  1987. static INLINE2 void i_lodsw(void)
  1988. {
  1989. /* Opcode 0xad */
  1990. register unsigned si = ReadWord(&wregs[SI]);
  1991. register unsigned tmp = GetMemW(c_ds,si);
  1992. si += -4*DF+2;
  1993. WriteWord(&wregs[SI],si);
  1994. WriteWord(&wregs[AX],tmp);
  1995. }
  1996. static INLINE2 void i_scasb(void)
  1997. {
  1998. /* Opcode 0xae */
  1999. unsigned di = ReadWord(&wregs[DI]);
  2000. unsigned src = GetMemB(c_es, di);
  2001. unsigned tmp = *bregs[AL];
  2002. unsigned tmp2 = tmp;
  2003. tmp -= src;
  2004. SetCFB_Sub(tmp,tmp2);
  2005. SetOFB_Sub(tmp,src,tmp2);
  2006. SetAF(tmp,src,tmp2);
  2007. SetZFB(tmp);
  2008. SetSFB(tmp);
  2009. SetPF(tmp);
  2010. di += -2*DF +1;
  2011. WriteWord(&wregs[DI],di);
  2012. }
  2013. static INLINE2 void i_scasw(void)
  2014. {
  2015. /* Opcode 0xaf */
  2016. unsigned di = ReadWord(&wregs[DI]);
  2017. unsigned src = GetMemW(c_es, di);
  2018. unsigned tmp = ReadWord(&wregs[AX]);
  2019. unsigned tmp2 = tmp;
  2020. tmp -= src;
  2021. SetCFW_Sub(tmp,tmp2);
  2022. SetOFW_Sub(tmp,src,tmp2);
  2023. SetAF(tmp,src,tmp2);
  2024. SetZFW(tmp);
  2025. SetSFW(tmp);
  2026. SetPF(tmp);
  2027. di += -4*DF +2;
  2028. WriteWord(&wregs[DI],di);
  2029. }
  2030. static INLINE2 void i_mov_ald8(void)
  2031. {
  2032. /* Opcode 0xb0 */
  2033. *bregs[AL] = GetMemInc(c_cs,ip);
  2034. }
  2035. static INLINE2 void i_mov_cld8(void)
  2036. {
  2037. /* Opcode 0xb1 */
  2038. *bregs[CL] = GetMemInc(c_cs,ip);
  2039. }
  2040. static INLINE2 void i_mov_dld8(void)
  2041. {
  2042. /* Opcode 0xb2 */
  2043. *bregs[DL] = GetMemInc(c_cs,ip);
  2044. }
  2045. static INLINE2 void i_mov_bld8(void)
  2046. {
  2047. /* Opcode 0xb3 */
  2048. *bregs[BL] = GetMemInc(c_cs,ip);
  2049. }
  2050. static INLINE2 void i_mov_ahd8(void)
  2051. {
  2052. /* Opcode 0xb4 */
  2053. *bregs[AH] = GetMemInc(c_cs,ip);
  2054. }
  2055. static INLINE2 void i_mov_chd8(void)
  2056. {
  2057. /* Opcode 0xb5 */
  2058. *bregs[CH] = GetMemInc(c_cs,ip);
  2059. }
  2060. static INLINE2 void i_mov_dhd8(void)
  2061. {
  2062. /* Opcode 0xb6 */
  2063. *bregs[DH] = GetMemInc(c_cs,ip);
  2064. }
  2065. static INLINE2 void i_mov_bhd8(void)
  2066. {
  2067. /* Opcode 0xb7 */
  2068. *bregs[BH] = GetMemInc(c_cs,ip);
  2069. }
  2070. static INLINE2 void i_mov_axd16(void)
  2071. {
  2072. /* Opcode 0xb8 */
  2073. *bregs[AL] = GetMemInc(c_cs,ip);
  2074. *bregs[AH] = GetMemInc(c_cs,ip);
  2075. }
  2076. static INLINE2 void i_mov_cxd16(void)
  2077. {
  2078. /* Opcode 0xb9 */
  2079. *bregs[CL] = GetMemInc(c_cs,ip);
  2080. *bregs[CH] = GetMemInc(c_cs,ip);
  2081. }
  2082. static INLINE2 void i_mov_dxd16(void)
  2083. {
  2084. /* Opcode 0xba */
  2085. *bregs[DL] = GetMemInc(c_cs,ip);
  2086. *bregs[DH] = GetMemInc(c_cs,ip);
  2087. }
  2088. static INLINE2 void i_mov_bxd16(void)
  2089. {
  2090. /* Opcode 0xbb */
  2091. *bregs[BL] = GetMemInc(c_cs,ip);
  2092. *bregs[BH] = GetMemInc(c_cs,ip);
  2093. }
  2094. static INLINE2 void i_mov_spd16(void)
  2095. {
  2096. /* Opcode 0xbc */
  2097. *bregs[SPL] = GetMemInc(c_cs,ip);
  2098. *bregs[SPH] = GetMemInc(c_cs,ip);
  2099. }
  2100. static INLINE2 void i_mov_bpd16(void)
  2101. {
  2102. /* Opcode 0xbd */
  2103. *bregs[BPL] = GetMemInc(c_cs,ip);
  2104. *bregs[BPH] = GetMemInc(c_cs,ip);
  2105. }
  2106. static INLINE2 void i_mov_sid16(void)
  2107. {
  2108. /* Opcode 0xbe */
  2109. *bregs[SIL] = GetMemInc(c_cs,ip);
  2110. *bregs[SIH] = GetMemInc(c_cs,ip);
  2111. }
  2112. static INLINE2 void i_mov_did16(void)
  2113. {
  2114. /* Opcode 0xbf */
  2115. *bregs[DIL] = GetMemInc(c_cs,ip);
  2116. *bregs[DIH] = GetMemInc(c_cs,ip);
  2117. }
  2118. static INLINE2 void i_ret_d16(void)
  2119. {
  2120. /* Opcode 0xc2 */
  2121. register unsigned tmp = ReadWord(&wregs[SP]);
  2122. register unsigned count;
  2123. count = GetMemInc(c_cs,ip);
  2124. count += GetMemInc(c_cs,ip) << 8;
  2125. ip = GetMemW(c_stack,tmp);
  2126. tmp += count+2;
  2127. WriteWord(&wregs[SP],tmp);
  2128. }
  2129. static INLINE2 void i_ret(void)
  2130. {
  2131. /* Opcode 0xc3 */
  2132. register unsigned tmp = ReadWord(&wregs[SP]);
  2133. ip = GetMemW(c_stack,tmp);
  2134. tmp += 2;
  2135. WriteWord(&wregs[SP],tmp);
  2136. }
  2137. static INLINE2 void i_les_dw(void)
  2138. {
  2139. /* Opcode 0xc4 */
  2140. unsigned ModRM = GetMemInc(c_cs,ip);
  2141. register WORD *dest = GetModRMRegW(ModRM);
  2142. register WORD *src = GetModRMRMW(ModRM);
  2143. WORD tmp = ReadWord(src);
  2144. WriteWord(dest, tmp);
  2145. src += 1;
  2146. sregs[ES] = ReadWord(src);
  2147. c_es = SegToMemPtr(ES);
  2148. }
  2149. static INLINE2 void i_lds_dw(void)
  2150. {
  2151. /* Opcode 0xc5 */
  2152. unsigned ModRM = GetMemInc(c_cs,ip);
  2153. register WORD *dest = GetModRMRegW(ModRM);
  2154. register WORD *src = GetModRMRMW(ModRM);
  2155. WORD tmp = ReadWord(src);
  2156. WriteWord(dest,tmp);
  2157. src += 1;
  2158. sregs[DS] = ReadWord(src);
  2159. c_ds = SegToMemPtr(DS);
  2160. }
  2161. static INLINE2 void i_mov_bd8(void)
  2162. {
  2163. /* Opcode 0xc6 */
  2164. unsigned ModRM = GetMemInc(c_cs,ip);
  2165. register BYTE *dest = GetModRMRMB(ModRM);
  2166. *dest = GetMemInc(c_cs,ip);
  2167. }
  2168. static INLINE2 void i_mov_wd16(void)
  2169. {
  2170. /* Opcode 0xc7 */
  2171. unsigned ModRM = GetMemInc(c_cs,ip);
  2172. register BYTE *dest = (BYTE *)GetModRMRMW(ModRM);
  2173. *dest++ = GetMemInc(c_cs,ip);
  2174. *dest = GetMemInc(c_cs,ip);
  2175. }
  2176. static INLINE2 void i_retf_d16(void)
  2177. {
  2178. /* Opcode 0xca */
  2179. register unsigned tmp = ReadWord(&wregs[SP]);
  2180. register unsigned count;
  2181. count = GetMemInc(c_cs,ip);
  2182. count += GetMemInc(c_cs,ip) << 8;
  2183. ip = GetMemW(c_stack,tmp);
  2184. tmp = (WORD)(tmp+2);
  2185. sregs[CS] = GetMemW(c_stack,tmp);
  2186. c_cs = SegToMemPtr(CS);
  2187. tmp += count+2;
  2188. WriteWord(&wregs[SP],tmp);
  2189. }
  2190. static INLINE2 void i_retf(void)
  2191. {
  2192. /* Opcode 0xcb */
  2193. register unsigned tmp = ReadWord(&wregs[SP]);
  2194. ip = GetMemW(c_stack,tmp);
  2195. tmp = (WORD)(tmp+2);
  2196. sregs[CS] = GetMemW(c_stack,tmp);
  2197. c_cs = SegToMemPtr(CS);
  2198. tmp += 2;
  2199. WriteWord(&wregs[SP],tmp);
  2200. }
  2201. static INLINE2 void i_int3(void)
  2202. {
  2203. /* Opcode 0xcc */
  2204. interrupt(3);
  2205. }
  2206. static INLINE2 void i_int(void)
  2207. {
  2208. /* Opcode 0xcd */
  2209. unsigned int_num = GetMemInc(c_cs,ip);
  2210. interrupt(int_num);
  2211. }
  2212. static INLINE2 void i_into(void)
  2213. {
  2214. /* Opcode 0xce */
  2215. if (OF)
  2216. interrupt(4);
  2217. }
  2218. static INLINE2 void i_iret(void)
  2219. {
  2220. /* Opcode 0xcf */
  2221. register unsigned tmp = ReadWord(&wregs[SP]);
  2222. ip = GetMemW(c_stack,tmp);
  2223. tmp = (WORD)(tmp+2);
  2224. sregs[CS] = GetMemW(c_stack,tmp);
  2225. c_cs = SegToMemPtr(CS);
  2226. tmp += 2;
  2227. WriteWord(&wregs[SP],tmp);
  2228. i_popf();
  2229. #ifdef DEBUGGER
  2230. call_debugger(D_TRACE);
  2231. #endif
  2232. }
  2233. static INLINE2 void i_d0pre(void)
  2234. {
  2235. /* Opcode 0xd0 */
  2236. unsigned ModRM = GetMemInc(c_cs,ip);
  2237. register BYTE *dest = GetModRMRMB(ModRM);
  2238. register unsigned tmp = *dest;
  2239. register unsigned tmp2 = tmp;
  2240. switch (ModRM & 0x38)
  2241. {
  2242. case 0x00: /* ROL eb,1 */
  2243. CF = (tmp & 0x80) != 0;
  2244. *dest = (tmp << 1) + CF;
  2245. OF = !(!(tmp & 0x40)) != CF;
  2246. break;
  2247. case 0x08: /* ROR eb,1 */
  2248. CF = (tmp & 0x01) != 0;
  2249. *dest = (tmp >> 1) + (CF << 7);
  2250. OF = !(!(tmp & 0x80)) != CF;
  2251. break;
  2252. case 0x10: /* RCL eb,1 */
  2253. OF = (tmp ^ (tmp << 1)) & 0x80;
  2254. *dest = (tmp << 1) + CF;
  2255. CF = (tmp & 0x80) != 0;
  2256. break;
  2257. case 0x18: /* RCR eb,1 */
  2258. *dest = (tmp >> 1) + (CF << 7);
  2259. OF = !(!(tmp & 0x80)) != CF;
  2260. CF = (tmp & 0x01) != 0;
  2261. break;
  2262. case 0x20: /* SHL eb,1 */
  2263. case 0x30:
  2264. tmp += tmp;
  2265. SetCFB_Add(tmp,tmp2);
  2266. SetOFB_Add(tmp,tmp2,tmp2);
  2267. AF = 1;
  2268. SetZFB(tmp);
  2269. SetSFB(tmp);
  2270. SetPF(tmp);
  2271. *dest = (BYTE)tmp;
  2272. break;
  2273. case 0x28: /* SHR eb,1 */
  2274. CF = (tmp & 0x01) != 0;
  2275. OF = tmp & 0x80;
  2276. tmp2 = tmp >> 1;
  2277. SetSFB(tmp2);
  2278. SetPF(tmp2);
  2279. SetZFB(tmp2);
  2280. AF = 1;
  2281. *dest = (BYTE)tmp2;
  2282. break;
  2283. case 0x38: /* SAR eb,1 */
  2284. CF = (tmp & 0x01) != 0;
  2285. OF = 0;
  2286. tmp2 = (tmp >> 1) | (tmp & 0x80);
  2287. SetSFB(tmp2);
  2288. SetPF(tmp2);
  2289. SetZFB(tmp2);
  2290. AF = 1;
  2291. *dest = (BYTE)tmp2;
  2292. break;
  2293. }
  2294. }
  2295. static INLINE2 void i_d1pre(void)
  2296. {
  2297. /* Opcode 0xd1 */
  2298. unsigned ModRM = GetMemInc(c_cs,ip);
  2299. register WORD *dest = GetModRMRMW(ModRM);
  2300. register unsigned tmp = ReadWord(dest);
  2301. register unsigned tmp2 = tmp;
  2302. switch (ModRM & 0x38)
  2303. {
  2304. case 0x00: /* ROL ew,1 */
  2305. CF = (tmp & 0x8000) != 0;
  2306. tmp2 = (tmp << 1) + CF;
  2307. OF = !(!(tmp & 0x4000)) != CF;
  2308. WriteWord(dest,tmp2);
  2309. break;
  2310. case 0x08: /* ROR ew,1 */
  2311. CF = (tmp & 0x01) != 0;
  2312. tmp2 = (tmp >> 1) + ((unsigned)CF << 15);
  2313. OF = !(!(tmp & 0x8000)) != CF;
  2314. WriteWord(dest,tmp2);
  2315. break;
  2316. case 0x10: /* RCL ew,1 */
  2317. tmp2 = (tmp << 1) + CF;
  2318. OF = (tmp ^ (tmp << 1)) & 0x8000;
  2319. CF = (tmp & 0x8000) != 0;
  2320. WriteWord(dest,tmp2);
  2321. break;
  2322. case 0x18: /* RCR ew,1 */
  2323. tmp2 = (tmp >> 1) + ((unsigned)CF << 15);
  2324. OF = !(!(tmp & 0x8000)) != CF;
  2325. CF = (tmp & 0x01) != 0;
  2326. WriteWord(dest,tmp2);
  2327. break;
  2328. case 0x20: /* SHL ew,1 */
  2329. case 0x30:
  2330. tmp += tmp;
  2331. SetCFW_Add(tmp,tmp2);
  2332. SetOFW_Add(tmp,tmp2,tmp2);
  2333. AF = 1;
  2334. SetZFW(tmp);
  2335. SetSFW(tmp);
  2336. SetPF(tmp);
  2337. WriteWord(dest,tmp);
  2338. break;
  2339. case 0x28: /* SHR ew,1 */
  2340. CF = (tmp & 0x01) != 0;
  2341. OF = tmp & 0x8000;
  2342. tmp2 = tmp >> 1;
  2343. SetSFW(tmp2);
  2344. SetPF(tmp2);
  2345. SetZFW(tmp2);
  2346. AF = 1;
  2347. WriteWord(dest,tmp2);
  2348. break;
  2349. case 0x38: /* SAR ew,1 */
  2350. CF = (tmp & 0x01) != 0;
  2351. OF = 0;
  2352. tmp2 = (tmp >> 1) | (tmp & 0x8000);
  2353. SetSFW(tmp2);
  2354. SetPF(tmp2);
  2355. SetZFW(tmp2);
  2356. AF = 1;
  2357. WriteWord(dest,tmp2);
  2358. break;
  2359. }
  2360. }
  2361. static INLINE2 void i_d2pre(void)
  2362. {
  2363. /* Opcode 0xd2 */
  2364. unsigned ModRM;
  2365. register BYTE *dest;
  2366. register unsigned tmp;
  2367. register unsigned tmp2;
  2368. unsigned count;
  2369. if (*bregs[CL] == 1)
  2370. {
  2371. i_d0pre();
  2372. D(printf("Skipping CL processing\n"););
  2373. return;
  2374. }
  2375. ModRM = GetMemInc(c_cs,ip);
  2376. dest = GetModRMRMB(ModRM);
  2377. tmp = (unsigned)*dest;
  2378. count = (unsigned)*bregs[CL];
  2379. switch (ModRM & 0x38)
  2380. {
  2381. case 0x00: /* ROL eb,CL */
  2382. for (; count > 0; count--)
  2383. {
  2384. CF = (tmp & 0x80) != 0;
  2385. tmp = (tmp << 1) + CF;
  2386. }
  2387. *dest = (BYTE)tmp;
  2388. break;
  2389. case 0x08: /* ROR eb,CL */
  2390. for (; count > 0; count--)
  2391. {
  2392. CF = (tmp & 0x01) != 0;
  2393. tmp = (tmp >> 1) + (CF << 7);
  2394. }
  2395. *dest = (BYTE)tmp;
  2396. break;
  2397. case 0x10: /* RCL eb,CL */
  2398. for (; count > 0; count--)
  2399. {
  2400. tmp2 = CF;
  2401. CF = (tmp & 0x80) != 0;
  2402. tmp = (tmp << 1) + tmp2;
  2403. }
  2404. *dest = (BYTE)tmp;
  2405. break;
  2406. case 0x18: /* RCR eb,CL */
  2407. for (; count > 0; count--)
  2408. {
  2409. tmp2 = (tmp >> 1) + (CF << 7);
  2410. CF = (tmp & 0x01) != 0;
  2411. tmp = tmp2;
  2412. }
  2413. *dest = (BYTE)tmp;
  2414. break;
  2415. case 0x20:
  2416. case 0x30: /* SHL eb,CL */
  2417. if (count >= 9)
  2418. {
  2419. CF = 0; /* Not sure about this... */
  2420. tmp = 0;
  2421. }
  2422. else
  2423. {
  2424. CF = ((tmp << (count-1)) & 0x80) != 0;
  2425. tmp <<= count;
  2426. }
  2427. AF = 1;
  2428. SetZFB(tmp);
  2429. SetSFB(tmp);
  2430. SetPF(tmp);
  2431. *dest = (BYTE)tmp;
  2432. break;
  2433. case 0x28: /* SHR eb,CL */
  2434. if (count >= 9)
  2435. {
  2436. CF = 0; /* Not sure about this... */
  2437. tmp = 0;
  2438. }
  2439. else
  2440. {
  2441. CF = ((tmp >> (count-1)) & 0x1) != 0;
  2442. tmp >>= count;
  2443. }
  2444. SetSFB(tmp);
  2445. SetPF(tmp);
  2446. SetZFB(tmp);
  2447. AF = 1;
  2448. *dest = (BYTE)tmp;
  2449. break;
  2450. case 0x38: /* SAR eb,CL */
  2451. tmp2 = tmp & 0x80;
  2452. CF = (((INT8)tmp >> (count-1)) & 0x01) != 0;
  2453. for (; count > 0; count--)
  2454. tmp = (tmp >> 1) | tmp2;
  2455. SetSFB(tmp);
  2456. SetPF(tmp);
  2457. SetZFB(tmp);
  2458. AF = 1;
  2459. *dest = (BYTE)tmp;
  2460. break;
  2461. }
  2462. }
  2463. static INLINE2 void i_d3pre(void)
  2464. {
  2465. /* Opcode 0xd3 */
  2466. unsigned ModRM;
  2467. register WORD *dest;
  2468. register unsigned tmp;
  2469. register unsigned tmp2;
  2470. unsigned count;
  2471. if (*bregs[CL] == 1)
  2472. {
  2473. i_d1pre();
  2474. return;
  2475. }
  2476. ModRM = GetMemInc(c_cs,ip);
  2477. dest = GetModRMRMW(ModRM);
  2478. tmp = ReadWord(dest);
  2479. count = (unsigned)*bregs[CL];
  2480. switch (ModRM & 0x38)
  2481. {
  2482. case 0x00: /* ROL ew,CL */
  2483. for (; count > 0; count--)
  2484. {
  2485. CF = (tmp & 0x8000) != 0;
  2486. tmp = (tmp << 1) + CF;
  2487. }
  2488. WriteWord(dest,tmp);
  2489. break;
  2490. case 0x08: /* ROR ew,CL */
  2491. for (; count > 0; count--)
  2492. {
  2493. CF = (tmp & 0x01) != 0;
  2494. tmp = (tmp >> 1) + (CF << 15);
  2495. }
  2496. WriteWord(dest, tmp);
  2497. break;
  2498. case 0x10: /* RCL ew,CL */
  2499. for (; count > 0; count--)
  2500. {
  2501. tmp2 = CF;
  2502. CF = (tmp & 0x8000) != 0;
  2503. tmp = (tmp << 1) + tmp2;
  2504. }
  2505. WriteWord(dest, tmp);
  2506. break;
  2507. case 0x18: /* RCR ew,CL */
  2508. for (; count > 0; count--)
  2509. {
  2510. tmp2 = (tmp >> 1) + (CF << 15);
  2511. CF = (tmp & 0x01) != 0;
  2512. tmp = tmp2;
  2513. }
  2514. WriteWord(dest, tmp);
  2515. break;
  2516. case 0x20:
  2517. case 0x30: /* SHL ew,CL */
  2518. if (count >= 17)
  2519. {
  2520. CF = 0; /* Not sure about this... */
  2521. tmp = 0;
  2522. }
  2523. else
  2524. {
  2525. CF = ((tmp << (count-1)) & 0x8000) != 0;
  2526. tmp <<= count;
  2527. }
  2528. AF = 1;
  2529. SetZFW(tmp);
  2530. SetSFW(tmp);
  2531. SetPF(tmp);
  2532. WriteWord(dest, tmp);
  2533. break;
  2534. case 0x28: /* SHR ew,CL */
  2535. if (count >= 17)
  2536. {
  2537. CF = 0; /* Not sure about this... */
  2538. tmp = 0;
  2539. }
  2540. else
  2541. {
  2542. CF = ((tmp >> (count-1)) & 0x1) != 0;
  2543. tmp >>= count;
  2544. }
  2545. SetSFW(tmp);
  2546. SetPF(tmp);
  2547. SetZFW(tmp);
  2548. AF = 1;
  2549. WriteWord(dest, tmp);
  2550. break;
  2551. case 0x38: /* SAR ew,CL */
  2552. tmp2 = tmp & 0x8000;
  2553. CF = (((INT16)tmp >> (count-1)) & 0x01) != 0;
  2554. for (; count > 0; count--)
  2555. tmp = (tmp >> 1) | tmp2;
  2556. SetSFW(tmp);
  2557. SetPF(tmp);
  2558. SetZFW(tmp);
  2559. AF = 1;
  2560. WriteWord(dest, tmp);
  2561. break;
  2562. }
  2563. }
  2564. static INLINE2 void i_aam(void)
  2565. {
  2566. /* Opcode 0xd4 */
  2567. unsigned mult = GetMemInc(c_cs,ip);
  2568. if (mult == 0)
  2569. interrupt(0);
  2570. else
  2571. {
  2572. *bregs[AH] = *bregs[AL] / mult;
  2573. *bregs[AL] %= mult;
  2574. SetPF(*bregs[AL]);
  2575. SetZFW(wregs[AX]);
  2576. SetSFB(*bregs[AH]);
  2577. }
  2578. }
  2579. static INLINE2 void i_aad(void)
  2580. {
  2581. /* Opcode 0xd5 */
  2582. unsigned mult = GetMemInc(c_cs,ip);
  2583. *bregs[AL] = *bregs[AH] * mult + *bregs[AL];
  2584. *bregs[AH] = 0;
  2585. SetPF(*bregs[AL]);
  2586. SetZFB(*bregs[AL]);
  2587. SF = 0;
  2588. }
  2589. static INLINE2 void i_xlat(void)
  2590. {
  2591. /* Opcode 0xd7 */
  2592. unsigned dest = ReadWord(&wregs[BX])+*bregs[AL];
  2593. *bregs[AL] = GetMemB(c_ds, dest);
  2594. }
  2595. static INLINE2 void i_escape(void)
  2596. {
  2597. /* Opcodes 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde and 0xdf */
  2598. unsigned ModRM = GetMemInc(c_cs,ip);
  2599. GetModRMRMB(ModRM);
  2600. }
  2601. static INLINE2 void i_loopne(void)
  2602. {
  2603. /* Opcode 0xe0 */
  2604. register int disp = (int)((INT8)GetMemInc(c_cs,ip));
  2605. register unsigned tmp = ReadWord(&wregs[CX])-1;
  2606. WriteWord(&wregs[CX],tmp);
  2607. if (!ZF && tmp) ip = (WORD)(ip+disp);
  2608. }
  2609. static INLINE2 void i_loope(void)
  2610. {
  2611. /* Opcode 0xe1 */
  2612. register int disp = (int)((INT8)GetMemInc(c_cs,ip));
  2613. register unsigned tmp = ReadWord(&wregs[CX])-1;
  2614. WriteWord(&wregs[CX],tmp);
  2615. if (ZF && tmp) ip = (WORD)(ip+disp);
  2616. }
  2617. static INLINE2 void i_loop(void)
  2618. {
  2619. /* Opcode 0xe2 */
  2620. register int disp = (int)((INT8)GetMemInc(c_cs,ip));
  2621. register unsigned tmp = ReadWord(&wregs[CX])-1;
  2622. WriteWord(&wregs[CX],tmp);
  2623. if (tmp) ip = (WORD)(ip+disp);
  2624. }
  2625. static INLINE2 void i_jcxz(void)
  2626. {
  2627. /* Opcode 0xe3 */
  2628. register int disp = (int)((INT8)GetMemInc(c_cs,ip));
  2629. if (wregs[CX] == 0)
  2630. ip = (WORD)(ip+disp);
  2631. }
  2632. static INLINE2 void i_inal(void)
  2633. {
  2634. /* Opcode 0xe4 */
  2635. unsigned port = GetMemInc(c_cs,ip);
  2636. *bregs[AL] = read_port(port);
  2637. }
  2638. static INLINE2 void i_inax(void)
  2639. {
  2640. /* Opcode 0xe5 */
  2641. unsigned port = GetMemInc(c_cs,ip);
  2642. *bregs[AL] = read_port(port);
  2643. *bregs[AH] = read_port(port+1);
  2644. }
  2645. static INLINE2 void i_outal(void)
  2646. {
  2647. /* Opcode 0xe6 */
  2648. unsigned port = GetMemInc(c_cs,ip);
  2649. write_port(port, *bregs[AL]);
  2650. }
  2651. static INLINE2 void i_outax(void)
  2652. {
  2653. /* Opcode 0xe7 */
  2654. unsigned port = GetMemInc(c_cs,ip);
  2655. write_port(port, *bregs[AL]);
  2656. write_port(port+1, *bregs[AH]);
  2657. }
  2658. static INLINE2 void i_call_d16(void)
  2659. {
  2660. /* Opcode 0xe8 */
  2661. register unsigned tmp;
  2662. register unsigned tmp1 = (WORD)(ReadWord(&wregs[SP])-2);
  2663. tmp = GetMemInc(c_cs,ip);
  2664. tmp += GetMemInc(c_cs,ip) << 8;
  2665. PutMemW(c_stack,tmp1,ip);
  2666. WriteWord(&wregs[SP],tmp1);
  2667. ip = (WORD)(ip+(INT16)tmp);
  2668. }
  2669. static INLINE2 void i_jmp_d16(void)
  2670. {
  2671. /* Opcode 0xe9 */
  2672. register int tmp = GetMemInc(c_cs,ip);
  2673. tmp += GetMemInc(c_cs,ip) << 8;
  2674. ip = (WORD)(ip+(INT16)tmp);
  2675. }
  2676. static INLINE2 void i_jmp_far(void)
  2677. {
  2678. /* Opcode 0xea */
  2679. register unsigned tmp,tmp1;
  2680. tmp = GetMemInc(c_cs,ip);
  2681. tmp += GetMemInc(c_cs,ip) << 8;
  2682. tmp1 = GetMemInc(c_cs,ip);
  2683. tmp1 += GetMemInc(c_cs,ip) << 8;
  2684. sregs[CS] = (WORD)tmp1;
  2685. c_cs = SegToMemPtr(CS);
  2686. ip = (WORD)tmp;
  2687. }
  2688. static INLINE2 void i_jmp_d8(void)
  2689. {
  2690. /* Opcode 0xeb */
  2691. register int tmp = (int)((INT8)GetMemInc(c_cs,ip));
  2692. ip = (WORD)(ip+tmp);
  2693. }
  2694. static INLINE2 void i_inaldx(void)
  2695. {
  2696. /* Opcode 0xec */
  2697. *bregs[AL] = read_port(ReadWord(&wregs[DX]));
  2698. }
  2699. static INLINE2 void i_inaxdx(void)
  2700. {
  2701. /* Opcode 0xed */
  2702. unsigned port = ReadWord(&wregs[DX]);
  2703. *bregs[AL] = read_port(port);
  2704. *bregs[AH] = read_port(port+1);
  2705. }
  2706. static INLINE2 void i_outdxal(void)
  2707. {
  2708. /* Opcode 0xee */
  2709. write_port(ReadWord(&wregs[DX]), *bregs[AL]);
  2710. }
  2711. static INLINE2 void i_outdxax(void)
  2712. {
  2713. /* Opcode 0xef */
  2714. unsigned port = ReadWord(&wregs[DX]);
  2715. write_port(port, *bregs[AL]);
  2716. write_port(port+1, *bregs[AH]);
  2717. }
  2718. static INLINE2 void i_lock(void)
  2719. {
  2720. /* Opcode 0xf0 */
  2721. }
  2722. static INLINE2 void i_gobios(void)
  2723. {
  2724. /* Opcode 0xf1 */
  2725. void (*routine)(void);
  2726. unsigned dest;
  2727. if (GetMemInc(c_cs,ip) != 0xf1)
  2728. i_notdone();
  2729. dest = GetMemInc(c_cs,ip); /* Must be re-coded sometime.... */
  2730. dest += (GetMemInc(c_cs,ip) << 8);
  2731. dest += (GetMemInc(c_cs,ip) << 16);
  2732. dest += (GetMemInc(c_cs,ip) << 24);
  2733. routine = (void (*)(void))dest;
  2734. routine();
  2735. }
  2736. static void rep(int flagval)
  2737. {
  2738. /* Handles rep- and repnz- prefixes. flagval is the value of ZF for the
  2739. loop to continue for CMPS and SCAS instructions. */
  2740. unsigned next = GetMemInc(c_cs,ip);
  2741. unsigned count = ReadWord(&wregs[CX]);
  2742. switch(next)
  2743. {
  2744. case 0x26: /* ES: */
  2745. c_ss = c_ds = c_es;
  2746. rep(flagval);
  2747. c_ds = SegToMemPtr(DS);
  2748. c_ss = SegToMemPtr(SS);
  2749. break;
  2750. case 0x2e: /* CS: */
  2751. c_ss = c_ds = c_cs;
  2752. rep(flagval);
  2753. c_ds = SegToMemPtr(DS);
  2754. c_ss = SegToMemPtr(SS);
  2755. break;
  2756. case 0x36: /* SS: */
  2757. c_ds = c_ss;
  2758. rep(flagval);
  2759. c_ds = SegToMemPtr(DS);
  2760. break;
  2761. case 0x3e: /* DS: */
  2762. c_ss = c_ds;
  2763. rep(flagval);
  2764. c_ss = SegToMemPtr(SS);
  2765. break;
  2766. case 0xa4: /* REP MOVSB */
  2767. for (; count > 0; count--)
  2768. i_movsb();
  2769. WriteWord(&wregs[CX],count);
  2770. break;
  2771. case 0xa5: /* REP MOVSW */
  2772. for (; count > 0; count--)
  2773. i_movsw();
  2774. WriteWord(&wregs[CX],count);
  2775. break;
  2776. case 0xa6: /* REP(N)E CMPSB */
  2777. for (ZF = flagval; (ZF == flagval) && (count > 0); count--)
  2778. i_cmpsb();
  2779. WriteWord(&wregs[CX],count);
  2780. break;
  2781. case 0xa7: /* REP(N)E CMPSW */
  2782. for (ZF = flagval; (ZF == flagval) && (count > 0); count--)
  2783. i_cmpsw();
  2784. WriteWord(&wregs[CX],count);
  2785. break;
  2786. case 0xaa: /* REP STOSB */
  2787. for (; count > 0; count--)
  2788. i_stosb();
  2789. WriteWord(&wregs[CX],count);
  2790. break;
  2791. case 0xab: /* REP LODSW */
  2792. for (; count > 0; count--)
  2793. i_stosw();
  2794. WriteWord(&wregs[CX],count);
  2795. break;
  2796. case 0xac: /* REP LODSB */
  2797. for (; count > 0; count--)
  2798. i_lodsb();
  2799. WriteWord(&wregs[CX],count);
  2800. break;
  2801. case 0xad: /* REP LODSW */
  2802. for (; count > 0; count--)
  2803. i_lodsw();
  2804. WriteWord(&wregs[CX],count);
  2805. break;
  2806. case 0xae: /* REP(N)E SCASB */
  2807. for (ZF = flagval; (ZF == flagval) && (count > 0); count--)
  2808. i_scasb();
  2809. WriteWord(&wregs[CX],count);
  2810. break;
  2811. case 0xaf: /* REP(N)E SCASW */
  2812. for (ZF = flagval; (ZF == flagval) && (count > 0); count--)
  2813. i_scasw();
  2814. WriteWord(&wregs[CX],count);
  2815. break;
  2816. default:
  2817. instruction[next]();
  2818. }
  2819. }
  2820. static INLINE2 void i_repne(void)
  2821. {
  2822. /* Opcode 0xf2 */
  2823. rep(0);
  2824. }
  2825. static INLINE2 void i_repe(void)
  2826. {
  2827. /* Opcode 0xf3 */
  2828. rep(1);
  2829. }
  2830. static INLINE2 void i_cmc(void)
  2831. {
  2832. /* Opcode 0xf5 */
  2833. CF = !CF;
  2834. }
  2835. static INLINE2 void i_f6pre(void)
  2836. {
  2837. /* Opcode 0xf6 */
  2838. unsigned ModRM = GetMemInc(c_cs,ip);
  2839. register BYTE *byte = GetModRMRMB(ModRM);
  2840. register unsigned tmp = (unsigned)*byte;
  2841. register unsigned tmp2;
  2842. switch (ModRM & 0x38)
  2843. {
  2844. case 0x00: /* TEST Eb, data8 */
  2845. case 0x08: /* ??? */
  2846. tmp &= GetMemInc(c_cs,ip);
  2847. CF = OF = AF = 0;
  2848. SetZFB(tmp);
  2849. SetSFB(tmp);
  2850. SetPF(tmp);
  2851. break;
  2852. case 0x10: /* NOT Eb */
  2853. *byte = ~tmp;
  2854. break;
  2855. case 0x18: /* NEG Eb */
  2856. tmp2 = tmp;
  2857. tmp = -tmp;
  2858. CF = (int)tmp2 > 0;
  2859. SetAF(tmp,0,tmp2);
  2860. SetZFB(tmp);
  2861. SetSFB(tmp);
  2862. SetPF(tmp);
  2863. *byte = tmp;
  2864. break;
  2865. case 0x20: /* MUL AL, Eb */
  2866. {
  2867. UINT16 result;
  2868. tmp2 = *bregs[AL];
  2869. SetSFB(tmp2);
  2870. SetPF(tmp2);
  2871. result = (UINT16)tmp2*tmp;
  2872. WriteWord(&wregs[AX],(WORD)result);
  2873. SetZFW(wregs[AX]);
  2874. CF = OF = (*bregs[AH] != 0);
  2875. }
  2876. break;
  2877. case 0x28: /* IMUL AL, Eb */
  2878. {
  2879. INT16 result;
  2880. tmp2 = (unsigned)*bregs[AL];
  2881. SetSFB(tmp2);
  2882. SetPF(tmp2);
  2883. result = (INT16)((INT8)tmp2)*(INT16)((INT8)tmp);
  2884. WriteWord(&wregs[AX],(WORD)result);
  2885. SetZFW(wregs[AX]);
  2886. OF = (result >> 7 != 0) && (result >> 7 != -1);
  2887. CF = !(!OF);
  2888. }
  2889. break;
  2890. case 0x30: /* DIV AL, Ew */
  2891. {
  2892. UINT16 result;
  2893. result = ReadWord(&wregs[AX]);
  2894. if (tmp)
  2895. {
  2896. if ((result / tmp) > 0xff)
  2897. {
  2898. interrupt(0);
  2899. break;
  2900. }
  2901. else
  2902. {
  2903. *bregs[AH] = result % tmp;
  2904. *bregs[AL] = result / tmp;
  2905. }
  2906. }
  2907. else
  2908. {
  2909. interrupt(0);
  2910. break;
  2911. }
  2912. }
  2913. break;
  2914. case 0x38: /* IDIV AL, Ew */
  2915. {
  2916. INT16 result;
  2917. result = ReadWord(&wregs[AX]);
  2918. if (tmp)
  2919. {
  2920. tmp2 = result % (INT16)((INT8)tmp);
  2921. if ((result /= (INT16)((INT8)tmp)) > 0xff)
  2922. {
  2923. interrupt(0);
  2924. break;
  2925. }
  2926. else
  2927. {
  2928. *bregs[AL] = result;
  2929. *bregs[AH] = tmp2;
  2930. }
  2931. }
  2932. else
  2933. {
  2934. interrupt(0);
  2935. break;
  2936. }
  2937. }
  2938. break;
  2939. }
  2940. }
  2941. static INLINE2 void i_f7pre(void)
  2942. {
  2943. /* Opcode 0xf7 */
  2944. unsigned ModRM = GetMemInc(c_cs,ip);
  2945. WORD *wrd = GetModRMRMW(ModRM);
  2946. register unsigned tmp = ReadWord(wrd);
  2947. register unsigned tmp2;
  2948. switch (ModRM & 0x38)
  2949. {
  2950. case 0x00: /* TEST Ew, data16 */
  2951. case 0x08: /* ??? */
  2952. tmp2 = GetMemInc(c_cs,ip);
  2953. tmp2 += GetMemInc(c_cs,ip) << 8;
  2954. tmp &= tmp2;
  2955. CF = OF = AF = 0;
  2956. SetZFW(tmp);
  2957. SetSFW(tmp);
  2958. SetPF(tmp);
  2959. break;
  2960. case 0x10: /* NOT Ew */
  2961. tmp = ~tmp;
  2962. WriteWord(wrd,tmp);
  2963. break;
  2964. case 0x18: /* NEG Ew */
  2965. tmp2 = tmp;
  2966. tmp = -tmp;
  2967. CF = (int)tmp2 > 0;
  2968. SetAF(tmp,0,tmp2);
  2969. SetZFW(tmp);
  2970. SetSFW(tmp);
  2971. SetPF(tmp);
  2972. WriteWord(wrd,tmp);
  2973. break;
  2974. case 0x20: /* MUL AX, Ew */
  2975. {
  2976. UINT32 result;
  2977. tmp2 = ReadWord(&wregs[AX]);
  2978. SetSFW(tmp2);
  2979. SetPF(tmp2);
  2980. result = (UINT32)tmp2*tmp;
  2981. WriteWord(&wregs[AX],(WORD)result);
  2982. result >>= 16;
  2983. WriteWord(&wregs[DX],result);
  2984. SetZFW(wregs[AX] | wregs[DX]);
  2985. CF = OF = (wregs[DX] != ChangeE(0));
  2986. }
  2987. break;
  2988. case 0x28: /* IMUL AX, Ew */
  2989. {
  2990. INT32 result;
  2991. tmp2 = ReadWord(&wregs[AX]);
  2992. SetSFW(tmp2);
  2993. SetPF(tmp2);
  2994. result = (INT32)((INT16)tmp2)*(INT32)((INT16)tmp);
  2995. OF = (result >> 15 != 0) && (result >> 15 != -1);
  2996. WriteWord(&wregs[AX],(WORD)result);
  2997. result = (WORD)(result >> 16);
  2998. WriteWord(&wregs[DX],result);
  2999. SetZFW(wregs[AX] | wregs[DX]);
  3000. CF = !(!OF);
  3001. }
  3002. break;
  3003. case 0x30: /* DIV AX, Ew */
  3004. {
  3005. UINT32 result;
  3006. result = (ReadWord(&wregs[DX]) << 16) + ReadWord(&wregs[AX]);
  3007. if (tmp)
  3008. {
  3009. tmp2 = result % tmp;
  3010. if ((result / tmp) > 0xffff)
  3011. {
  3012. interrupt(0);
  3013. break;
  3014. }
  3015. else
  3016. {
  3017. WriteWord(&wregs[DX],tmp2);
  3018. result /= tmp;
  3019. WriteWord(&wregs[AX],result);
  3020. }
  3021. }
  3022. else
  3023. {
  3024. interrupt(0);
  3025. break;
  3026. }
  3027. }
  3028. break;
  3029. case 0x38: /* IDIV AX, Ew */
  3030. {
  3031. INT32 result;
  3032. result = (ReadWord(&wregs[DX]) << 16) + ReadWord(&wregs[AX]);
  3033. if (tmp)
  3034. {
  3035. tmp2 = result % (INT32)((INT16)tmp);
  3036. if ((result /= (INT32)((INT16)tmp)) > 0xffff)
  3037. {
  3038. interrupt(0);
  3039. break;
  3040. }
  3041. else
  3042. {
  3043. WriteWord(&wregs[AX],result);
  3044. WriteWord(&wregs[DX],tmp2);
  3045. }
  3046. }
  3047. else
  3048. {
  3049. interrupt(0);
  3050. break;
  3051. }
  3052. }
  3053. break;
  3054. }
  3055. }
  3056. static INLINE2 void i_clc(void)
  3057. {
  3058. /* Opcode 0xf8 */
  3059. CF = 0;
  3060. }
  3061. static INLINE2 void i_stc(void)
  3062. {
  3063. /* Opcode 0xf9 */
  3064. CF = 1;
  3065. }
  3066. static INLINE2 void i_cli(void)
  3067. {
  3068. /* Opcode 0xfa */
  3069. IF = 0;
  3070. }
  3071. static INLINE2 void i_sti(void)
  3072. {
  3073. /* Opcode 0xfb */
  3074. IF = 1;
  3075. if (int_blocked)
  3076. {
  3077. int_pending = int_blocked;
  3078. int_blocked = 0;
  3079. D2(printf("Unblocking interrupt\n"););
  3080. }
  3081. }
  3082. static INLINE2 void i_cld(void)
  3083. {
  3084. /* Opcode 0xfc */
  3085. DF = 0;
  3086. }
  3087. static INLINE2 void i_std(void)
  3088. {
  3089. /* Opcode 0xfd */
  3090. DF = 1;
  3091. }
  3092. static INLINE2 void i_fepre(void)
  3093. {
  3094. /* Opcode 0xfe */
  3095. unsigned ModRM = GetMemInc(c_cs,ip);
  3096. register BYTE *dest = GetModRMRMB(ModRM);
  3097. register unsigned tmp = *dest;
  3098. register unsigned tmp1;
  3099. if ((ModRM & 0x38) == 0)
  3100. {
  3101. tmp1 = tmp+1;
  3102. SetOFB_Add(tmp1,tmp,1);
  3103. }
  3104. else
  3105. {
  3106. tmp1 = tmp-1;
  3107. SetOFB_Sub(tmp1,1,tmp);
  3108. }
  3109. SetAF(tmp1,tmp,1);
  3110. SetZFB(tmp1);
  3111. SetSFB(tmp1);
  3112. SetPF(tmp1);
  3113. *dest = (BYTE)tmp1;
  3114. }
  3115. static INLINE2 void i_ffpre(void)
  3116. {
  3117. /* Opcode 0xff */
  3118. unsigned ModRM = GetMemInc(c_cs,ip);
  3119. register WORD *dest = GetModRMRMW(ModRM);
  3120. register unsigned tmp;
  3121. register unsigned tmp1;
  3122. switch(ModRM & 0x38)
  3123. {
  3124. case 0x00: /* INC ew */
  3125. tmp = ReadWord(dest);
  3126. tmp1 = tmp+1;
  3127. SetOFW_Add(tmp1,tmp,1);
  3128. SetAF(tmp1,tmp,1);
  3129. SetZFW(tmp1);
  3130. SetSFW(tmp1);
  3131. SetPF(tmp1);
  3132. WriteWord(dest,(WORD)tmp1);
  3133. break;
  3134. case 0x08: /* DEC ew */
  3135. tmp = ReadWord(dest);
  3136. tmp1 = tmp-1;
  3137. SetOFW_Sub(tmp1,1,tmp);
  3138. SetAF(tmp1,tmp,1);
  3139. SetZFW(tmp1);
  3140. SetSFW(tmp1);
  3141. SetPF(tmp1);
  3142. WriteWord(dest,(WORD)tmp1);
  3143. break;
  3144. case 0x10: /* CALL ew */
  3145. tmp = ReadWord(dest);
  3146. tmp1 = (WORD)(ReadWord(&wregs[SP])-2);
  3147. PutMemW(c_stack,tmp1,ip);
  3148. WriteWord(&wregs[SP],tmp1);
  3149. ip = (WORD)tmp;
  3150. break;
  3151. case 0x18: /* CALL FAR ea */
  3152. tmp1 = (WORD)(ReadWord(&wregs[SP])-2);
  3153. PutMemW(c_stack,tmp1,sregs[CS]);
  3154. tmp1 = (WORD)(tmp1-2);
  3155. PutMemW(c_stack,tmp1,ip);
  3156. WriteWord(&wregs[SP],tmp1);
  3157. ip = ReadWord(dest);
  3158. dest++;
  3159. sregs[CS] = ReadWord(dest);
  3160. c_cs = SegToMemPtr(CS);
  3161. break;
  3162. case 0x20: /* JMP ea */
  3163. ip = ReadWord(dest);
  3164. break;
  3165. case 0x28: /* JMP FAR ea */
  3166. ip = ReadWord(dest);
  3167. dest++;
  3168. sregs[CS] = ReadWord(dest);
  3169. c_cs = SegToMemPtr(CS);
  3170. break;
  3171. case 0x30: /* PUSH ea */
  3172. tmp1 = (WORD)(ReadWord(&wregs[SP])-2);
  3173. tmp = ReadWord(dest);
  3174. PutMemW(c_stack,tmp1,tmp);
  3175. WriteWord(&wregs[SP],tmp1);
  3176. break;
  3177. }
  3178. }
  3179. static INLINE2 void i_notdone(void)
  3180. {
  3181. /*
  3182. fprintf(stderr,"Error: Unimplemented opcode %02X at cs:ip = %04X:%04X\n",
  3183. c_cs[ip-1],sregs[CS],ip-1);
  3184. exit(1);
  3185. */
  3186. TCHAR msg[256];
  3187. wsprintf(msg, "Error: Unimplemented opcode %02X at cs:ip = %04X:%04X", c_cs[ip-1], sregs[CS], ip-1);
  3188. MessageBox(wonw32ctx->hWnd, msg, NULL, MB_OK);
  3189. wonw32ctx->running = FALSE;
  3190. }
  3191. void trap(void)
  3192. {
  3193. instruction[GetMemInc(c_cs,ip)]();
  3194. interrupt(1);
  3195. }
  3196. void execute(void)
  3197. {
  3198. c_cs = SegToMemPtr(CS);
  3199. c_ds = SegToMemPtr(DS);
  3200. c_es = SegToMemPtr(ES);
  3201. c_stack = c_ss = SegToMemPtr(SS);
  3202. if (int_pending)
  3203. external_int();
  3204. #ifdef DEBUGGER
  3205. call_debugger(D_TRACE);
  3206. #endif
  3207. #if defined(BIGCASE) && !defined(RS6000)
  3208. /* Some compilers cannot handle large case statements */
  3209. switch(GetMemInc(c_cs,ip))
  3210. {
  3211. case 0x00: i_add_br8(); break;
  3212. case 0x01: i_add_wr16(); break;
  3213. case 0x02: i_add_r8b(); break;
  3214. case 0x03: i_add_r16w(); break;
  3215. case 0x04: i_add_ald8(); break;
  3216. case 0x05: i_add_axd16(); break;
  3217. case 0x06: i_push_es(); break;
  3218. case 0x07: i_pop_es(); break;
  3219. case 0x08: i_or_br8(); break;
  3220. case 0x09: i_or_wr16(); break;
  3221. case 0x0a: i_or_r8b(); break;
  3222. case 0x0b: i_or_r16w(); break;
  3223. case 0x0c: i_or_ald8(); break;
  3224. case 0x0d: i_or_axd16(); break;
  3225. case 0x0e: i_push_cs(); break;
  3226. case 0x0f: i_notdone(); break;
  3227. case 0x10: i_adc_br8(); break;
  3228. case 0x11: i_adc_wr16(); break;
  3229. case 0x12: i_adc_r8b(); break;
  3230. case 0x13: i_adc_r16w(); break;
  3231. case 0x14: i_adc_ald8(); break;
  3232. case 0x15: i_adc_axd16(); break;
  3233. case 0x16: i_push_ss(); break;
  3234. case 0x17: i_pop_ss(); break;
  3235. case 0x18: i_sbb_br8(); break;
  3236. case 0x19: i_sbb_wr16(); break;
  3237. case 0x1a: i_sbb_r8b(); break;
  3238. case 0x1b: i_sbb_r16w(); break;
  3239. case 0x1c: i_sbb_ald8(); break;
  3240. case 0x1d: i_sbb_axd16(); break;
  3241. case 0x1e: i_push_ds(); break;
  3242. case 0x1f: i_pop_ds(); break;
  3243. case 0x20: i_and_br8(); break;
  3244. case 0x21: i_and_wr16(); break;
  3245. case 0x22: i_and_r8b(); break;
  3246. case 0x23: i_and_r16w(); break;
  3247. case 0x24: i_and_ald8(); break;
  3248. case 0x25: i_and_axd16(); break;
  3249. case 0x26: i_es(); break;
  3250. case 0x27: i_daa(); break;
  3251. case 0x28: i_sub_br8(); break;
  3252. case 0x29: i_sub_wr16(); break;
  3253. case 0x2a: i_sub_r8b(); break;
  3254. case 0x2b: i_sub_r16w(); break;
  3255. case 0x2c: i_sub_ald8(); break;
  3256. case 0x2d: i_sub_axd16(); break;
  3257. case 0x2e: i_cs(); break;
  3258. case 0x2f: i_das(); break; // added
  3259. case 0x30: i_xor_br8(); break;
  3260. case 0x31: i_xor_wr16(); break;
  3261. case 0x32: i_xor_r8b(); break;
  3262. case 0x33: i_xor_r16w(); break;
  3263. case 0x34: i_xor_ald8(); break;
  3264. case 0x35: i_xor_axd16(); break;
  3265. case 0x36: i_ss(); break;
  3266. case 0x37: i_notdone(); break;
  3267. case 0x38: i_cmp_br8(); break;
  3268. case 0x39: i_cmp_wr16(); break;
  3269. case 0x3a: i_cmp_r8b(); break;
  3270. case 0x3b: i_cmp_r16w(); break;
  3271. case 0x3c: i_cmp_ald8(); break;
  3272. case 0x3d: i_cmp_axd16(); break;
  3273. case 0x3e: i_ds(); break;
  3274. case 0x3f: i_aas(); break; // added
  3275. case 0x40: i_inc_ax(); break;
  3276. case 0x41: i_inc_cx(); break;
  3277. case 0x42: i_inc_dx(); break;
  3278. case 0x43: i_inc_bx(); break;
  3279. case 0x44: i_inc_sp(); break;
  3280. case 0x45: i_inc_bp(); break;
  3281. case 0x46: i_inc_si(); break;
  3282. case 0x47: i_inc_di(); break;
  3283. case 0x48: i_dec_ax(); break;
  3284. case 0x49: i_dec_cx(); break;
  3285. case 0x4a: i_dec_dx(); break;
  3286. case 0x4b: i_dec_bx(); break;
  3287. case 0x4c: i_dec_sp(); break;
  3288. case 0x4d: i_dec_bp(); break;
  3289. case 0x4e: i_dec_si(); break;
  3290. case 0x4f: i_dec_di(); break;
  3291. case 0x50: i_push_ax(); break;
  3292. case 0x51: i_push_cx(); break;
  3293. case 0x52: i_push_dx(); break;
  3294. case 0x53: i_push_bx(); break;
  3295. case 0x54: i_push_sp(); break;
  3296. case 0x55: i_push_bp(); break;
  3297. case 0x56: i_push_si(); break;
  3298. case 0x57: i_push_di(); break;
  3299. case 0x58: i_pop_ax(); break;
  3300. case 0x59: i_pop_cx(); break;
  3301. case 0x5a: i_pop_dx(); break;
  3302. case 0x5b: i_pop_bx(); break;
  3303. case 0x5c: i_pop_sp(); break;
  3304. case 0x5d: i_pop_bp(); break;
  3305. case 0x5e: i_pop_si(); break;
  3306. case 0x5f: i_pop_di(); break;
  3307. case 0x60: i_pusha(); break; /* added */
  3308. case 0x61: i_popa(); break; /* added */
  3309. case 0x62: i_bound(); break; /* added */
  3310. case 0x63: i_notdone(); break;
  3311. case 0x64: i_notdone(); break;
  3312. case 0x65: i_notdone(); break;
  3313. case 0x66: i_notdone(); break;
  3314. case 0x67: i_notdone(); break;
  3315. case 0x68: i_push_d16(); break; /* added */
  3316. case 0x69: i_imul_d16(); break; /* added */
  3317. case 0x6a: i_push_d8(); break; /* added */
  3318. case 0x6b: i_imul_d8(); break; /* added */
  3319. case 0x6c: i_insb(); break; /* added */
  3320. case 0x6d: i_insw(); break; /* added */
  3321. case 0x6e: i_outsb(); break; /* added */
  3322. case 0x6f: i_outsw(); break; /* added */
  3323. case 0x70: i_jo(); break;
  3324. case 0x71: i_jno(); break;
  3325. case 0x72: i_jb(); break;
  3326. case 0x73: i_jnb(); break;
  3327. case 0x74: i_jz(); break;
  3328. case 0x75: i_jnz(); break;
  3329. case 0x76: i_jbe(); break;
  3330. case 0x77: i_jnbe(); break;
  3331. case 0x78: i_js(); break;
  3332. case 0x79: i_jns(); break;
  3333. case 0x7a: i_jp(); break;
  3334. case 0x7b: i_jnp(); break;
  3335. case 0x7c: i_jl(); break;
  3336. case 0x7d: i_jnl(); break;
  3337. case 0x7e: i_jle(); break;
  3338. case 0x7f: i_jnle(); break;
  3339. case 0x80: i_80pre(); break;
  3340. case 0x81: i_81pre(); break;
  3341. case 0x82: i_notdone(); break;
  3342. case 0x83: i_83pre(); break;
  3343. case 0x84: i_test_br8(); break;
  3344. case 0x85: i_test_wr16(); break;
  3345. case 0x86: i_xchg_br8(); break;
  3346. case 0x87: i_xchg_wr16(); break;
  3347. case 0x88: i_mov_br8(); break;
  3348. case 0x89: i_mov_wr16(); break;
  3349. case 0x8a: i_mov_r8b(); break;
  3350. case 0x8b: i_mov_r16w(); break;
  3351. case 0x8c: i_mov_wsreg(); break;
  3352. case 0x8d: i_lea(); break;
  3353. case 0x8e: i_mov_sregw(); break;
  3354. case 0x8f: i_popw(); break;
  3355. case 0x90: i_nop(); break;
  3356. case 0x91: i_xchg_axcx(); break;
  3357. case 0x92: i_xchg_axdx(); break;
  3358. case 0x93: i_xchg_axbx(); break;
  3359. case 0x94: i_xchg_axsp(); break;
  3360. case 0x95: i_xchg_axbp(); break;
  3361. case 0x96: i_xchg_axsi(); break;
  3362. case 0x97: i_xchg_axdi(); break;
  3363. case 0x98: i_cbw(); break;
  3364. case 0x99: i_cwd(); break;
  3365. case 0x9a: i_call_far(); break;
  3366. case 0x9b: i_wait(); break;
  3367. case 0x9c: i_pushf(); break;
  3368. case 0x9d: i_popf(); break;
  3369. case 0x9e: i_sahf(); break;
  3370. case 0x9f: i_lahf(); break;
  3371. case 0xa0: i_mov_aldisp(); break;
  3372. case 0xa1: i_mov_axdisp(); break;
  3373. case 0xa2: i_mov_dispal(); break;
  3374. case 0xa3: i_mov_dispax(); break;
  3375. case 0xa4: i_movsb(); break;
  3376. case 0xa5: i_movsw(); break;
  3377. case 0xa6: i_cmpsb(); break;
  3378. case 0xa7: i_cmpsw(); break;
  3379. case 0xa8: i_test_ald8(); break;
  3380. case 0xa9: i_test_axd16(); break;
  3381. case 0xaa: i_stosb(); break;
  3382. case 0xab: i_stosw(); break;
  3383. case 0xac: i_lodsb(); break;
  3384. case 0xad: i_lodsw(); break;
  3385. case 0xae: i_scasb(); break;
  3386. case 0xaf: i_scasw(); break;
  3387. case 0xb0: i_mov_ald8(); break;
  3388. case 0xb1: i_mov_cld8(); break;
  3389. case 0xb2: i_mov_dld8(); break;
  3390. case 0xb3: i_mov_bld8(); break;
  3391. case 0xb4: i_mov_ahd8(); break;
  3392. case 0xb5: i_mov_chd8(); break;
  3393. case 0xb6: i_mov_dhd8(); break;
  3394. case 0xb7: i_mov_bhd8(); break;
  3395. case 0xb8: i_mov_axd16(); break;
  3396. case 0xb9: i_mov_cxd16(); break;
  3397. case 0xba: i_mov_dxd16(); break;
  3398. case 0xbb: i_mov_bxd16(); break;
  3399. case 0xbc: i_mov_spd16(); break;
  3400. case 0xbd: i_mov_bpd16(); break;
  3401. case 0xbe: i_mov_sid16(); break;
  3402. case 0xbf: i_mov_did16(); break;
  3403. case 0xc0: i_rotshft_bd8(); break; /* added */
  3404. case 0xc1: i_rotshft_wd8(); break; /* added */
  3405. case 0xc2: i_ret_d16(); break;
  3406. case 0xc3: i_ret(); break;
  3407. case 0xc4: i_les_dw(); break;
  3408. case 0xc5: i_lds_dw(); break;
  3409. case 0xc6: i_mov_bd8(); break;
  3410. case 0xc7: i_mov_wd16(); break;
  3411. case 0xc8: i_enter(); break; /* added */
  3412. case 0xc9: i_leave(); break; /* added */
  3413. case 0xca: i_retf_d16(); break;
  3414. case 0xcb: i_retf(); break;
  3415. case 0xcc: i_int3(); break;
  3416. case 0xcd: i_int(); break;
  3417. case 0xce: i_into(); break;
  3418. case 0xcf: i_iret(); break;
  3419. case 0xd0: i_d0pre(); break;
  3420. case 0xd1: i_d1pre(); break;
  3421. case 0xd2: i_d2pre(); break;
  3422. case 0xd3: i_d3pre(); break;
  3423. case 0xd4: i_aam(); break;
  3424. case 0xd5: i_aad(); break;
  3425. case 0xd6: i_notdone(); break;
  3426. case 0xd7: i_xlat(); break;
  3427. case 0xd8: i_escape(); break;
  3428. case 0xd9: i_escape(); break;
  3429. case 0xda: i_escape(); break;
  3430. case 0xdb: i_escape(); break;
  3431. case 0xdc: i_escape(); break;
  3432. case 0xdd: i_escape(); break;
  3433. case 0xde: i_escape(); break;
  3434. case 0xdf: i_escape(); break;
  3435. case 0xe0: i_loopne(); break;
  3436. case 0xe1: i_loope(); break;
  3437. case 0xe2: i_loop(); break;
  3438. case 0xe3: i_jcxz(); break;
  3439. case 0xe4: i_inal(); break;
  3440. case 0xe5: i_inax(); break;
  3441. case 0xe6: i_outal(); break;
  3442. case 0xe7: i_outax(); break;
  3443. case 0xe8: i_call_d16(); break;
  3444. case 0xe9: i_jmp_d16(); break;
  3445. case 0xea: i_jmp_far(); break;
  3446. case 0xeb: i_jmp_d8(); break;
  3447. case 0xec: i_inaldx(); break;
  3448. case 0xed: i_inaxdx(); break;
  3449. case 0xee: i_outdxal(); break;
  3450. case 0xef: i_outdxax(); break;
  3451. case 0xf0: i_lock(); break;
  3452. case 0xf1: i_gobios(); break;
  3453. case 0xf2: i_repne(); break;
  3454. case 0xf3: i_repe(); break;
  3455. case 0xf4: i_notdone(); break;
  3456. case 0xf5: i_cmc(); break;
  3457. case 0xf6: i_f6pre(); break;
  3458. case 0xf7: i_f7pre(); break;
  3459. case 0xf8: i_clc(); break;
  3460. case 0xf9: i_stc(); break;
  3461. case 0xfa: i_cli(); break;
  3462. case 0xfb: i_sti(); break;
  3463. case 0xfc: i_cld(); break;
  3464. case 0xfd: i_std(); break;
  3465. case 0xfe: i_fepre(); break;
  3466. case 0xff: i_ffpre(); break;
  3467. };
  3468. #else
  3469. instruction[GetMemInc(c_cs,ip)]();
  3470. #endif
  3471. }
  3472. BYTE read_port(unsigned port) {
  3473. return 0;
  3474. }
  3475. void write_port(unsigned port, BYTE value) {
  3476. }
  3477. void disable() {
  3478. }
  3479. void enable() {
  3480. }