notice: Flash editor updated! Join the development! Thanks to MiniBuilder


embed

FAVORITE BY
:
amazing all the emulation going on in flash
:
Incredible. o_O
:
gameboyGame Boy Emulator
:
:
:
:
ゲームボーイのエミュレータ
:
:
すごい
:
gameemulatorエミュとは!!!
:
ゲームボーイってシンプルなんだなぁ。・・・スゲー
:
emulatorgameうわーーー
:
なんということでしょう。試せないけど
:
gameemulatorえ、こんなこともできるんだ・・・すげーーー!!
:
game
:
:
:
検証できないけど、スゴそう
:
ナニコレー
:
:
要検証だけどスプライト周りが怪しい?
:
ゲームボーイのデータなんてないよおおおおおお
:
うぉっ!
:
gameうはー
:
すげー!
FORKED
  1. // forked from hikipuro's 2009-3-18 Gameboy Emulator
  2. package
  3. {
  4. /**
  5. * ゲームボーイエミュレータのテスト
  6. * 32KB 程度のサイズの、初期のゲームしか動きません。
  7. * 音も出ません。
  8. *
  9. * Load Cartridge ボタンを押して、.gb ファイルをロードしてください。
  10. * 選択したファイルはサーバにはアップロードされません。
  11. * Flash 内に読み込まれるだけです。
  12. *
  13. * CPU のコードは TGB Dual のものを使用させていただきました。
  14. *
  15. */
  16. import flash.display.Bitmap;
  17. import flash.display.BitmapData;
  18. import flash.display.SimpleButton;
  19. import flash.display.Sprite;
  20. import flash.events.Event;
  21. import flash.events.KeyboardEvent;
  22. import flash.events.MouseEvent;
  23. import flash.events.TextEvent;
  24. import flash.net.FileFilter;
  25. import flash.net.FileReference;
  26. import flash.text.TextField;
  27. import flash.text.TextFieldAutoSize;
  28. import flash.text.TextFieldType;
  29. import flash.ui.Keyboard;
  30. import flash.utils.ByteArray;
  31. import flash.utils.getTimer;
  32. [SWF(backgroundColor=0xFFFFFF,frameRate=60)]
  33. public class Main extends Sprite
  34. {
  35. private var data:ByteArray;
  36. private var textField:TextField;
  37. private var output:BitmapData;
  38. private var gb:GB;
  39. private var fileReference:FileReference;
  40. private var buttonLoad:Button;
  41. private var buttonReset:Button;
  42. private var stop:Boolean = false;
  43. private var keys:Vector.;
  44. private var prevKeys:Vector.;
  45. public function Main():void
  46. {
  47. if (stage) init();
  48. else addEventListener(Event.ADDED_TO_STAGE, init);
  49. }
  50. private function prepare():void
  51. {
  52. var frame:GbFrame = new GbFrame();
  53. frame.x = 10;
  54. frame.y = 10;
  55. addChild(frame);
  56. // Load ボタンの作成
  57. buttonLoad = new Button("Load Cartridge");
  58. buttonLoad.addEventListener(MouseEvent.MOUSE_DOWN, onButtonLoadDown);
  59. buttonLoad.x = 350;
  60. buttonLoad.y = 10;
  61. addChild(buttonLoad);
  62. // Reset ボタンの作成
  63. buttonReset = new Button("Reset");
  64. buttonReset.addEventListener(MouseEvent.MOUSE_DOWN, onButtonResetDown);
  65. buttonReset.x = 350;
  66. buttonReset.y = 40;
  67. addChild(buttonReset);
  68. // 画面の準備
  69. output = new BitmapData(160, 144);
  70. var bitmap:Bitmap = new Bitmap(output);
  71. bitmap.x = 85;
  72. bitmap.y = 48;
  73. addChild(bitmap);
  74. // GBの準備
  75. gb = new GB();
  76. stop = true;
  77. // キー入力情報の初期化
  78. keys = new Vector.();
  79. prevKeys = new Vector.();
  80. for (var i:int = 0; i < 230; i++) {
  81. keys[i] = new Boolean(false);
  82. prevKeys[i] = new Boolean(false);
  83. }
  84. }
  85. private function init(e:Event = null):void
  86. {
  87. removeEventListener(Event.ADDED_TO_STAGE, init);
  88. // entry point
  89. prepare();
  90. gb.output = output;
  91. addEventListener(Event.ENTER_FRAME, onEnterFrame);
  92. stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
  93. stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
  94. }
  95. private function onButtonResetDown(event:MouseEvent):void
  96. {
  97. if (data == null)
  98. return;
  99. gb = new GB();
  100. gb.loadRom(data);
  101. }
  102. private function onButtonLoadDown(event:MouseEvent):void
  103. {
  104. stop = true;
  105. fileReference = new FileReference();
  106. // イベントの登録
  107. fileReference.addEventListener(Event.SELECT, onFileSelect);
  108. fileReference.addEventListener(Event.CANCEL, onFileCancel);
  109. fileReference.addEventListener(Event.COMPLETE, onFileLoadComplete);
  110. // ファイル選択ダイアログを表示する
  111. var fileFilter:FileFilter = new FileFilter("GB Cartridge (gb)", "*.gb");
  112. fileReference.browse([fileFilter]);
  113. }
  114. private function onFileSelect(event:Event):void
  115. {
  116. fileReference.load();
  117. stop = false;
  118. }
  119. private function onFileCancel(event:Event):void
  120. {
  121. stop = false;
  122. }
  123. private function onFileLoadComplete(event:Event):void
  124. {
  125. gb = new GB();
  126. data = fileReference.data;
  127. gb.loadRom(fileReference.data);
  128. }
  129. private function onKeyDown(event:KeyboardEvent):void
  130. {
  131. keys[event.keyCode] = true;
  132. }
  133. private function onKeyUp(event:KeyboardEvent):void
  134. {
  135. keys[event.keyCode] = false;
  136. }
  137. private function onEnterFrame(e:Event):void
  138. {
  139. if (stop || gb == null || !gb.dataLoaded)
  140. return;
  141. gb.setPad(Keyboard.LEFT, keys[Keyboard.LEFT]);
  142. gb.setPad(Keyboard.RIGHT, keys[Keyboard.RIGHT]);
  143. gb.setPad(Keyboard.UP, keys[Keyboard.UP]);
  144. gb.setPad(Keyboard.DOWN, keys[Keyboard.DOWN]);
  145. gb.setPad(88, keys[88]);
  146. gb.setPad(90, keys[90]);
  147. gb.setPad(83, keys[83]);
  148. gb.setPad(65, keys[65]);
  149. gb.exec();
  150. gb.render(output);
  151. }
  152. }
  153. }
  154. import flash.display.Sprite;
  155. class GbFrame extends Sprite
  156. {
  157. import flash.display.Graphics;
  158. import flash.display.Sprite;
  159. import flash.text.TextField;
  160. import flash.text.TextFormat;
  161. public function GbFrame()
  162. {
  163. var s:Sprite = new Sprite();
  164. var g:Graphics = s.graphics;
  165. s.cacheAsBitmap = true;
  166. // 外枠
  167. g.lineStyle(3, 0x808090, 1.0, true);
  168. g.beginFill(0xF0F0F0);
  169. g.drawRoundRect(0, 0, 317, 317, 10, 10);
  170. g.endFill();
  171. g.lineStyle(3, 0x808090, 1.0, true);
  172. g.moveTo(1, 15);
  173. g.lineTo(316, 15);
  174. g.moveTo(30, 1);
  175. g.lineTo(30, 15);
  176. g.moveTo(286, 1);
  177. g.lineTo(286, 15);
  178. // 中心
  179. g.lineStyle(3, 0x808090, 1.0, true);
  180. g.beginFill(0x606066);
  181. g.drawRoundRect(30, 20, 255, 170, 20, 20);
  182. g.endFill();
  183. g.lineStyle(1, 0xB08090);
  184. g.moveTo(40, 26);
  185. g.lineTo(115, 26);
  186. g.moveTo(235, 26);
  187. g.lineTo(275, 26);
  188. g.lineStyle(0);
  189. g.lineStyle(1, 0x000050);
  190. g.moveTo(40, 29);
  191. g.lineTo(115, 29);
  192. g.moveTo(235, 29);
  193. g.lineTo(275, 29);
  194. g.lineStyle(0);
  195. g.lineStyle(0);
  196. g.beginFill(0xFF0000);
  197. g.drawCircle(52, 75, 3);
  198. g.endFill();
  199. g.lineStyle(6, 0x505050);
  200. g.beginFill(0);
  201. g.drawRect(75, 38, 160, 144);
  202. g.endFill();
  203. // ボタン
  204. g.lineStyle(2, 0x505050);
  205. g.beginFill(0xC000C0);
  206. g.drawCircle(230, 250, 13);
  207. g.drawCircle(270, 250, 13);
  208. g.endFill();
  209. g.beginFill(0xC0C0C0);
  210. g.drawRoundRect(160, 245, 30, 8, 5, 5);
  211. g.drawRoundRect(115, 245, 30, 8, 5, 5);
  212. g.endFill();
  213. addChild(s);
  214. var text1:TextField;
  215. text1 = new TextField();
  216. text1.selectable = false;
  217. text1.x = 36;
  218. text1.y = 80;
  219. text1.htmlText = 'BATTERY';
  220. addChild(text1);
  221. var text2:TextField;
  222. text2 = new TextField();
  223. text2.selectable = false;
  224. text2.width = 120;
  225. text2.height = 10;
  226. text2.x = 118;
  227. text2.y = 23;
  228. text2.htmlText = 'DOT MATRIX WITHOUT STEREO SOUND';
  229. addChild(text2);
  230. var text3:TextField;
  231. text3 = new TextField();
  232. text3.selectable = false;
  233. text3.x = 32;
  234. text3.y = 193;
  235. text3.htmlText = 'Nintonde';
  236. addChild(text3);
  237. var text4:TextField;
  238. text4 = new TextField();
  239. text4.selectable = false;
  240. text4.x = 70;
  241. text4.y = 190;
  242. text4.htmlText = 'GAME BOY';
  243. addChild(text4);
  244. var text5:TextField;
  245. text5 = new TextField();
  246. text5.selectable = false;
  247. text5.x = 264;
  248. text5.y = 270;
  249. text5.htmlText = 'X';
  250. addChild(text5);
  251. var text6:TextField;
  252. text6 = new TextField();
  253. text6.selectable = false;
  254. text6.x = 224;
  255. text6.y = 270;
  256. text6.htmlText = 'Z';
  257. addChild(text6);
  258. var text7:TextField;
  259. text7 = new TextField();
  260. text7.selectable = false;
  261. text7.x = 169;
  262. text7.y = 270;
  263. text7.htmlText = 'S';
  264. addChild(text7);
  265. var text8:TextField;
  266. text8 = new TextField();
  267. text8.selectable = false;
  268. text8.x = 124;
  269. text8.y = 270;
  270. text8.htmlText = 'A';
  271. addChild(text8);
  272. }
  273. }
  274. import flash.display.SimpleButton;
  275. class Button extends SimpleButton
  276. {
  277. import flash.display.SimpleButton;
  278. import flash.display.Sprite;
  279. import flash.events.MouseEvent;
  280. import flash.text.TextField;
  281. import flash.text.TextFieldAutoSize;
  282. public function Button(caption:String = "ボタン", width:uint = 100, height:uint = 20)
  283. {
  284. upState = makeButton(0xDDDDDD, width, height, height / 2, caption);
  285. overState = makeButton(0xEEEEEE, width, height, height / 2, caption);
  286. downState = makeButton(0xCCCCCC, width, height, height / 2, caption);
  287. hitTestState = upState;
  288. }
  289. /**
  290. * ボタンを作って返す
  291. * @param color 色
  292. * @param width 幅
  293. * @param height 高さ
  294. * @param round 角丸の大きさ
  295. * @param text ボタンのテキスト
  296. * @return ボタン
  297. */
  298. private function makeButton(color:uint, width:int, height:int, round:int, text:String):Sprite
  299. {
  300. var t:TextField = new TextField();
  301. var s:Sprite = new Sprite();
  302. s.graphics.lineStyle(2);
  303. s.graphics.beginFill(color);
  304. s.graphics.drawRoundRect(0, 0, width, height, round);
  305. s.graphics.endFill();
  306. t.text = text;
  307. t.selectable = false;
  308. t.width = width;
  309. t.autoSize = TextFieldAutoSize.CENTER;
  310. s.addChild(t);
  311. return s;
  312. }
  313. }
  314. /**
  315. * ...
  316. * @author Hikipuro
  317. */
  318. class GbCart
  319. {
  320. import flash.utils.ByteArray;
  321. public var title:String = "";
  322. public var type:String = "";
  323. public var typeCode:uint = 0;
  324. public var romBanks:uint = 0;
  325. public var ramBanks:uint = 0;
  326. public var haveSram:Boolean = false;
  327. public var sram:Vector.;
  328. private var rom_bank:uint;
  329. private var rom:Vector.;
  330. private var mbc1type:uint = 0;
  331. private var mbc1_0x2000:uint = 0;
  332. private var mbc1_0x4000:uint = 0;
  333. private var mbc1_ram_bank:uint = 0;
  334. public function GbCart(byteArray:ByteArray)
  335. {
  336. if (byteArray.length < 0x150)
  337. return;
  338. mbc1type = 0;
  339. mbc1_0x2000 = 0;
  340. mbc1_0x4000 = 0;
  341. mbc1_ram_bank = 0;
  342. rom_bank = 0;
  343. rom = new Vector.();
  344. rom.fixed = false;
  345. rom.length = byteArray.length;
  346. rom.fixed = true;
  347. byteArray.position = 0;
  348. for (var i:uint = 0; i < byteArray.length; i++)
  349. rom[i] = (byteArray.readByte() & 0xFF);
  350. sram = new Vector.();
  351. sram.fixed = false;
  352. sram.length = 8192 * 4;
  353. sram.fixed = true;
  354. byteArray.position = 0x134;
  355. title = byteArray.readUTFBytes(15);
  356. byteArray.position = 0x147;
  357. typeCode = byteArray.readByte();
  358. switch (typeCode)
  359. {
  360. case 0x00: type = "ROM Only"; break;
  361. case 0x01: type = "ROM+MBC1"; break;
  362. case 0x02: type = "ROM+MBC1+RAM"; haveSram = true; break;
  363. case 0x03: type = "ROM+MBC1+RAM+BATTERY"; haveSram = true; break;
  364. case 0x05: type = "ROM+MBC2"; break;
  365. case 0x06: type = "ROM+MBC2+BATTERY"; break;
  366. case 0x08: type = "ROM+RAM"; haveSram = true; break;
  367. case 0x09: type = "ROM+RAM+BATTERY"; haveSram = true; break;
  368. case 0x0B: type = "ROM+MMM01"; break;
  369. case 0x0C: type = "ROM+MMM01+SRAM"; haveSram = true; break;
  370. case 0x0D: type = "ROM+MMM01+SRAM+BATT"; haveSram = true; break;
  371. case 0x0F: type = "ROM+MBC3+TIMER+BATT"; break;
  372. case 0x10: type = "ROM+MBC3+TIMER+RAM+BATT"; haveSram = true; break;
  373. case 0x11: type = "ROM+MBC3"; break;
  374. case 0x12: type = "ROM+MBC3+RAM"; haveSram = true; break;
  375. case 0x13: type = "ROM+MBC3+RAM+BATT"; haveSram = true; break;
  376. case 0x19: type = "ROM+MBC5"; break;
  377. case 0x1A: type = "ROM+MBC5+RAM"; haveSram = true; break;
  378. case 0x1B: type = "ROM+MBC5+RAM+BATT"; haveSram = true; break;
  379. case 0x1C: type = "ROM+MBC5+RUMBLE"; break;
  380. case 0x1D: type = "ROM+MBC5+RUMBLE+SRAM"; haveSram = true; break;
  381. case 0x1E: type = "ROM+MBC5+RUMBLE+SRAM+BATT"; haveSram = true; break;
  382. case 0x1F: type = "Pocket Camera"; break;
  383. case 0xFD: type = "Bandai TAMA5"; break;
  384. case 0xFE: type = "Hudson HuC3"; break;
  385. case 0xFF: type = "ROM+HuC1+RAM+BATTERY"; haveSram = true; break;
  386. }
  387. byteArray.position = 0x148;
  388. switch (byteArray.readByte())
  389. {
  390. case 0x00: romBanks = 2; break;
  391. case 0x01: romBanks = 4; break;
  392. case 0x02: romBanks = 8; break;
  393. case 0x03: romBanks = 16; break;
  394. case 0x04: romBanks = 32; break;
  395. case 0x05: romBanks = 64; break;
  396. case 0x06: romBanks = 128; break;
  397. case 0x52: romBanks = 72; break;
  398. case 0x53: romBanks = 80; break;
  399. case 0x54: romBanks = 96; break;
  400. }
  401. byteArray.position = 0x149;
  402. switch (byteArray.readByte())
  403. {
  404. case 0x00: ramBanks = 0; break;
  405. case 0x01: ramBanks = 1; break;
  406. case 0x02: ramBanks = 1; break;
  407. case 0x03: ramBanks = 4; break;
  408. case 0x04: ramBanks = 16; break;
  409. }
  410. }
  411. public function read(adr:uint):uint
  412. {
  413. return rom[adr];
  414. }
  415. public function readBank(adr:uint):uint
  416. {
  417. switch (typeCode)
  418. {
  419. case 0x00: // "ROM Only"
  420. return rom[adr];
  421. case 0x01: // "ROM+MBC1"
  422. return readMBC1(adr);
  423. case 0x02: // "ROM+MBC1+RAM"
  424. return readMBC1(adr);
  425. break;
  426. case 0x03: // "ROM+MBC1+RAM+BATTERY"
  427. return readMBC1(adr);
  428. break;
  429. case 0x05: // "ROM+MBC2"
  430. return readMBC2(adr);
  431. break;
  432. case 0x06: // "ROM+MBC2+BATTERY"
  433. return readMBC2(adr);
  434. break;
  435. case 0x08: // "ROM+RAM"
  436. break;
  437. case 0x09: // "ROM+RAM+BATTERY"
  438. break;
  439. case 0x0B: // "ROM+MMM01"
  440. break;
  441. case 0x0C: // "ROM+MMM01+SRAM"
  442. break;
  443. case 0x0D: // "ROM+MMM01+SRAM+BATT"
  444. break;
  445. case 0x0F: // "ROM+MBC3+TIMER+BATT"
  446. break;
  447. case 0x10: // "ROM+MBC3+TIMER+RAM+BATT"
  448. break;
  449. case 0x11: // "ROM+MBC3"
  450. break;
  451. case 0x12: // "ROM+MBC3+RAM"
  452. break;
  453. case 0x13: // "ROM+MBC3+RAM+BATT"
  454. break;
  455. case 0x19: // "ROM+MBC5"
  456. break;
  457. case 0x1A: // "ROM+MBC5+RAM"
  458. break;
  459. case 0x1B: // "ROM+MBC5+RAM+BATT"
  460. break;
  461. case 0x1C: // "ROM+MBC5+RUMBLE"
  462. break;
  463. case 0x1D: // "ROM+MBC5+RUMBLE+SRAM"
  464. break;
  465. case 0x1E: // "ROM+MBC5+RUMBLE+SRAM+BATT"
  466. break;
  467. case 0x1F: // "Pocket Camera"
  468. break;
  469. case 0xFD: // "Bandai TAMA5"
  470. break;
  471. case 0xFE: // "Hudson HuC3"
  472. break;
  473. case 0xFF: // "ROM+HuC1+RAM+BATTERY"
  474. break;
  475. }
  476. return 0;
  477. }
  478. public function write(adr:uint, dat:uint):void
  479. {
  480. switch (typeCode)
  481. {
  482. case 0x00: // "ROM Only"
  483. break;
  484. case 0x01: // "ROM+MBC1"
  485. writeMBC1(adr, dat);
  486. break;
  487. case 0x02: // "ROM+MBC1+RAM"
  488. writeMBC1(adr, dat);
  489. break;
  490. case 0x03: // "ROM+MBC1+RAM+BATTERY"
  491. writeMBC1(adr, dat);
  492. break;
  493. case 0x05: // "ROM+MBC2"
  494. writeMBC2(adr, dat);
  495. break;
  496. case 0x06: // "ROM+MBC2+BATTERY"
  497. writeMBC2(adr, dat);
  498. break;
  499. case 0x08: // "ROM+RAM"
  500. break;
  501. case 0x09: // "ROM+RAM+BATTERY"
  502. break;
  503. case 0x0B: // "ROM+MMM01"
  504. break;
  505. case 0x0C: // "ROM+MMM01+SRAM"
  506. break;
  507. case 0x0D: // "ROM+MMM01+SRAM+BATT"
  508. break;
  509. case 0x0F: // "ROM+MBC3+TIMER+BATT"
  510. break;
  511. case 0x10: // "ROM+MBC3+TIMER+RAM+BATT"
  512. break;
  513. case 0x11: // "ROM+MBC3"
  514. break;
  515. case 0x12: // "ROM+MBC3+RAM"
  516. break;
  517. case 0x13: // "ROM+MBC3+RAM+BATT"
  518. break;
  519. case 0x19: // "ROM+MBC5"
  520. break;
  521. case 0x1A: // "ROM+MBC5+RAM"
  522. break;
  523. case 0x1B: // "ROM+MBC5+RAM+BATT"
  524. break;
  525. case 0x1C: // "ROM+MBC5+RUMBLE"
  526. break;
  527. case 0x1D: // "ROM+MBC5+RUMBLE+SRAM"
  528. break;
  529. case 0x1E: // "ROM+MBC5+RUMBLE+SRAM+BATT"
  530. break;
  531. case 0x1F: // "Pocket Camera"
  532. break;
  533. case 0xFD: // "Bandai TAMA5"
  534. break;
  535. case 0xFE: // "Hudson HuC3"
  536. break;
  537. case 0xFF: // "ROM+HuC1+RAM+BATTERY"
  538. break;
  539. }
  540. }
  541. public function readSram(adr:uint):uint
  542. {
  543. var offset:uint;
  544. switch (typeCode)
  545. {
  546. case 0x03: // "ROM+MBC1+RAM+BATTERY"
  547. if (adr < 0x1000)
  548. return sram[adr];
  549. offset = mbc1_ram_bank * 0x1000;
  550. return sram[adr + offset];
  551. break;
  552. }
  553. return sram[adr];
  554. }
  555. public function writeSram(adr:uint, dat:uint):void
  556. {
  557. var offset:uint;
  558. switch (typeCode)
  559. {
  560. case 0x03: // "ROM+MBC1+RAM+BATTERY"
  561. if (adr < 0x1000)
  562. sram[adr] = dat;
  563. offset = mbc1_ram_bank * 0x1000;
  564. sram[adr + offset] = dat;
  565. break;
  566. }
  567. sram[adr] = dat;
  568. }
  569. public function readMBC1(adr:uint):uint
  570. {
  571. var offset:uint;
  572. if (mbc1type == 0) {
  573. offset = mbc1_0x4000 | mbc1_0x2000;
  574. offset *= 0x4000;
  575. } else {
  576. offset = mbc1_0x2000;
  577. offset *= 0x4000;
  578. }
  579. adr &= 0x3FFF;
  580. return rom[adr + offset];
  581. }
  582. public function writeMBC1(adr:uint, dat:uint):void
  583. {
  584. if (adr >= 0x6000 && adr <= 0x7FFF) {
  585. mbc1type = dat & 0x01;
  586. return;
  587. }
  588. if (adr >= 0x2000 && adr <= 0x3FFF)
  589. mbc1_0x2000 = (dat & 0x1F);
  590. if (adr >= 0x4000 && adr <= 0x5FFF) {
  591. mbc1_0x4000 = ((dat & 0x03) << 5);
  592. mbc1_ram_bank = (dat & 0x03);
  593. }
  594. }
  595. public function readMBC2(adr:uint):uint
  596. {
  597. var offset:uint;
  598. offset = mbc1_0x4000 | mbc1_0x2000;
  599. offset *= 0x4000;
  600. adr &= 0x3FFF;
  601. return rom[adr + offset];
  602. }
  603. public function writeMBC2(adr:uint, dat:uint):void
  604. {
  605. if (adr >= 0x6000 && adr <= 0x7FFF) {
  606. mbc1type = dat & 0x01;
  607. mbc1_0x2000 = 0;
  608. mbc1_0x4000 = 0;
  609. return;
  610. }
  611. if (mbc1type == 0) {
  612. if (adr >= 0x2000 && adr <= 0x3FFF)
  613. mbc1_0x2000 = (dat & 0x1F);
  614. if (adr >= 0x4000 && adr <= 0x5FFF)
  615. mbc1_0x4000 = ((dat & 0x03) << 5);
  616. }
  617. else {
  618. if (adr >= 0x2000 && adr <= 0x3FFF)
  619. mbc1_0x2000 = (dat & 0x1F);
  620. mbc1_0x4000 = 0;
  621. }
  622. }
  623. }
  624. /**
  625. * ...
  626. */
  627. class GbApu
  628. {
  629. import flash.events.SampleDataEvent;
  630. import flash.media.Sound;
  631. import flash.utils.ByteArray;
  632. private var NR10:uint, NR11:uint, NR12:uint, NR13:uint, NR14:uint;
  633. private var NR21:uint, NR22:uint, NR23:uint, NR24:uint;
  634. private var NR30:uint, NR31:uint, NR32:uint, NR33:uint, NR34:uint;
  635. private var NR41:uint, NR42:uint, NR43:uint, NR44:uint;
  636. private var NR50:uint, NR51:uint, NR52:uint;
  637. private var WaveRAM:Vector.;
  638. //private var sound:Sound;
  639. private var counter1:int;
  640. private var length1:uint;
  641. private var sweep1:uint;
  642. private var duty1:uint;
  643. private var volume1:uint;
  644. private var decay1:uint;
  645. private var env_counter1:uint;
  646. private var total_clock:int;
  647. private var div_clock:int;
  648. private var tick1d256:int;
  649. private var ringBuffer:Vector.;
  650. private var pointer:int;
  651. private var pointerPlay:int;
  652. private const duty12:Array = [0, 15, 15, 15, 15, 15, 15, 15];
  653. private const duty25:Array = [0, 15, 15, 15];
  654. private const duty50:Array = [0, 15];
  655. private const duty75:Array = [0, 0, 0, 15];
  656. public function GbApu()
  657. {
  658. WaveRAM = new Vector.();
  659. WaveRAM.length = 0x10;
  660. WaveRAM.fixed = true;
  661. NR10 = 0x80; NR11 = 0xBF; NR12 = 0xF3; NR14 = 0xBF;
  662. NR21 = 0x3F; NR22 = 0x00; NR24 = 0xBF;
  663. NR30 = 0x7F; NR31 = 0xFF; NR32 = 0x9F; NR33 = 0xBF;
  664. NR41 = 0xFF; NR42 = 0x00; NR43 = 0x00; NR44 = 0xBF;
  665. NR50 = 0x77; NR51 = 0xF3; NR52 = 0xF1;
  666. counter1 = 0;
  667. length1 = 0;
  668. sweep1 = 0;
  669. volume1 = 0;
  670. decay1 = 0;
  671. env_counter1 = 0;
  672. total_clock = 0;
  673. div_clock = 0;
  674. tick1d256 = 0;
  675. ringBuffer = new Vector.();
  676. ringBuffer.length = 8192 * 4;
  677. ringBuffer.fixed = true;
  678. pointer = 0;
  679. pointerPlay = 0;
  680. //sound = new Sound();
  681. //sound.addEventListener(SampleDataEvent.SAMPLE_DATA, onSampleData);
  682. //sound.play(0, 1);
  683. }
  684. public function read(adr:uint):uint
  685. {
  686. adr &= 0x2F;
  687. switch (adr)
  688. {
  689. case 0x00: return NR10 & 0xFF;
  690. case 0x01: return NR11 & 0xC0;
  691. case 0x02: return NR12 & 0xFF;
  692. case 0x03: return 0;
  693. case 0x04: return NR14 & 0x40;
  694. case 0x05: return 0xFF;
  695. case 0x06: return NR21 & 0xC0;
  696. case 0x07: return NR22 & 0xFF;
  697. case 0x08: return NR23 & 0xFF;
  698. case 0x09: return NR24 & 0x40;
  699. case 0x0A: return NR30 & 0x80;
  700. case 0x0B: return NR31 & 0xFF;
  701. case 0x0C: return NR32 & 0x60;
  702. case 0x0D: return NR33 & 0xFF;
  703. case 0x0E: return NR34 & 0x40;
  704. case 0x0F: return 0xFF;
  705. case 0x10: return NR41 & 0xFF;
  706. case 0x11: return NR42 & 0xFF;
  707. case 0x12: return NR43 & 0xFF;
  708. case 0x13: return NR44 & 0x40;
  709. case 0x14: return NR50 & 0xFF;
  710. case 0x15: return NR51 & 0xFF;
  711. case 0x16: return NR52 & 0x8F;
  712. case 0x17: return 0xFF;
  713. case 0x18: return 0xFF;
  714. case 0x19: return 0xFF;
  715. case 0x1A: return 0xFF;
  716. case 0x1B: return 0xFF;
  717. case 0x1C: return 0xFF;
  718. case 0x1D: return 0xFF;
  719. case 0x1E: return 0xFF;
  720. case 0x1F: return 0xFF;
  721. case 0x20: return WaveRAM[0x00] & 0xFF;
  722. case 0x21: return WaveRAM[0x01] & 0xFF;
  723. case 0x22: return WaveRAM[0x02] & 0xFF;
  724. case 0x23: return WaveRAM[0x03] & 0xFF;
  725. case 0x24: return WaveRAM[0x04] & 0xFF;
  726. case 0x25: return WaveRAM[0x05] & 0xFF;
  727. case 0x26: return WaveRAM[0x06] & 0xFF;
  728. case 0x27: return WaveRAM[0x07] & 0xFF;
  729. case 0x28: return WaveRAM[0x08] & 0xFF;
  730. case 0x29: return WaveRAM[0x09] & 0xFF;
  731. case 0x2A: return WaveRAM[0x0A] & 0xFF;
  732. case 0x2B: return WaveRAM[0x0B] & 0xFF;
  733. case 0x2C: return WaveRAM[0x0C] & 0xFF;
  734. case 0x2D: return WaveRAM[0x0D] & 0xFF;
  735. case 0x2E: return WaveRAM[0x0E] & 0xFF;
  736. case 0x2F: return WaveRAM[0x0F] & 0xFF;
  737. }
  738. return 0xFF;
  739. }
  740. public function write(adr:uint, dat:uint):void
  741. {
  742. adr &= 0x2F;
  743. dat &= 0xFF;
  744. switch (adr)
  745. {
  746. case 0x00:
  747. NR10 = dat;
  748. break;
  749. case 0x01:
  750. NR11 = dat;
  751. length1 = soundLength1;
  752. break;
  753. case 0x02:
  754. NR12 = dat;
  755. decay1 = ((NR12 >> 4) & 0x0F);
  756. break;
  757. case 0x03:
  758. NR13 = dat;
  759. break;
  760. case 0x04:
  761. NR14 = dat;
  762. if (NR14 & 0x80)
  763. counter1 = 0;
  764. break;
  765. case 0x05:
  766. return;
  767. case 0x06:
  768. NR21 = dat;
  769. break;
  770. case 0x07:
  771. NR22 = dat;
  772. break;
  773. case 0x08:
  774. NR23 = dat;
  775. break;
  776. case 0x09:
  777. NR24 = dat;
  778. break;
  779. case 0x0A:
  780. NR30 = dat;
  781. break;
  782. case 0x0B:
  783. NR31 = dat;
  784. break;
  785. case 0x0C:
  786. NR32 = dat;
  787. break;
  788. case 0x0D:
  789. NR33 = dat;
  790. break;
  791. case 0x0E:
  792. NR34 = dat;
  793. break;
  794. case 0x0F:
  795. return;
  796. case 0x10:
  797. NR41 = dat;
  798. break;
  799. case 0x11:
  800. NR42 = dat;
  801. break;
  802. case 0x12:
  803. NR43 = dat;
  804. break;
  805. case 0x13:
  806. NR44 = dat;
  807. break;
  808. case 0x14:
  809. NR50 = dat;
  810. break;
  811. case 0x15:
  812. NR51 = dat;
  813. break;
  814. case 0x16:
  815. NR52 = dat;
  816. break;
  817. case 0x17:
  818. return;
  819. case 0x18:
  820. return;
  821. case 0x19:
  822. return;
  823. case 0x1A:
  824. return;
  825. case 0x1B:
  826. return;
  827. case 0x1C:
  828. return;
  829. case 0x1D:
  830. return;
  831. case 0x1E:
  832. return;
  833. case 0x1F:
  834. return;
  835. case 0x20:
  836. WaveRAM[0x00] = dat;
  837. break;
  838. case 0x21:
  839. WaveRAM[0x01] = dat;
  840. break;
  841. case 0x22:
  842. WaveRAM[0x02] = dat;
  843. break;
  844. case 0x23:
  845. WaveRAM[0x03] = dat;
  846. break;
  847. case 0x24:
  848. WaveRAM[0x04] = dat;
  849. break;
  850. case 0x25:
  851. WaveRAM[0x05] = dat;
  852. break;
  853. case 0x26:
  854. WaveRAM[0x06] = dat;
  855. break;
  856. case 0x27:
  857. WaveRAM[0x07] = dat;
  858. break;
  859. case 0x28:
  860. WaveRAM[0x08] = dat;
  861. break;
  862. case 0x29:
  863. WaveRAM[0x09] = dat;
  864. break;
  865. case 0x2A:
  866. WaveRAM[0x0A] = dat;
  867. break;
  868. case 0x2B:
  869. WaveRAM[0x0B] = dat;
  870. break;
  871. case 0x2C:
  872. WaveRAM[0x0C] = dat;
  873. break;
  874. case 0x2D:
  875. WaveRAM[0x0D] = dat;
  876. break;
  877. case 0x2E:
  878. WaveRAM[0x0E] = dat;
  879. break;
  880. case 0x2F:
  881. WaveRAM[0x0F] = dat;
  882. break;
  883. }
  884. }
  885. private function get initialEnvelopeVolume1():uint
  886. {
  887. return ((NR12 >> 4) & 0x0F);
  888. }
  889. private function get envelopeDirection1():int
  890. {
  891. return ((NR12 >> 3) & 0x01) == 1 ? 1 : -1;
  892. }
  893. private function get envelopeWait1():uint
  894. {
  895. return (NR12 & 0x07);
  896. }
  897. private function get soundLength1():uint
  898. {
  899. return 64 - (NR11 & 0x3F);
  900. }
  901. private function get sweepWait1():uint
  902. {
  903. return ((NR10 >> 4) & 0x07);
  904. }
  905. private function get sweepDirection1():uint
  906. {
  907. return ((NR10 >> 3) & 0x01);
  908. }
  909. private function get sweepShift1():uint
  910. {
  911. return (NR10 & 0x07);
  912. }
  913. private function get wavePatternDuty1():uint
  914. {
  915. switch ((NR11 >> 6) & 0x03) {
  916. case 0: return 2;
  917. case 1: return 4;
  918. case 2: return 8;
  919. case 3: return 12;
  920. }
  921. return 0;
  922. }
  923. public function exec(clock:uint):void
  924. {
  925. if (!(NR52 & 0x80)) // sound off
  926. return;
  927. return;
  928. total_clock += clock;
  929. div_clock += clock;
  930. var count:uint;
  931. var i:uint;
  932. if (NR52 & 0x01) { // Channel 1 enabled
  933. counter1 += clock;
  934. count = NR13 | ((NR14 & 0x07) << 8);
  935. // programable counter & duty cycle
  936. if (counter1 > count) {
  937. counter1 -= count;
  938. duty1++;
  939. if (duty1 == 16)
  940. duty1 = 0;
  941. }
  942. //for (i = 0; i < clock; i++)
  943. //{
  944. if (duty1 < wavePatternDuty1) {
  945. if ((NR12 & 0x07) == 0) { // decay off
  946. volume1 += (((NR12 >> 4) & 0x0F) * clock);
  947. } else { // decay on
  948. volume1 += (decay1 * clock);
  949. }
  950. }
  951. //}
  952. }
  953. // 1/256 second
  954. if (total_clock > 4096) {
  955. total_clock -= 4096;
  956. tick1d256++;
  957. tick256();
  958. switch (tick1d256) {
  959. case 2:
  960. tick128();
  961. break;
  962. case 4:
  963. tick128();
  964. tick64();
  965. tick1d256 = 0;
  966. break;
  967. }
  968. }
  969. // 1/32768 (32) second
  970. if (div_clock > 23) {
  971. var v:Number;
  972. v = 0;
  973. div_clock -= 23;
  974. // sound 1 enabled
  975. if (NR52 & 0x01) {
  976. if (length1 != 0)
  977. v += volume1;
  978. volume1 = 0;
  979. }
  980. v /= (23 * 16);
  981. ringBuffer[pointer] = v;
  982. pointer++;
  983. if (pointer >= ringBuffer.length)
  984. pointer = 0;
  985. }
  986. }
  987. private function tick256():void
  988. {
  989. if (NR52 & 0x01) {
  990. if (length1 > 0)
  991. length1--;
  992. /*if (soundLength1 <= length1) {
  993. length1 = 0;
  994. // sound1 off
  995. if (NR14 & 0x40)
  996. NR52 &= 0xFE;
  997. }*/
  998. }
  999. }
  1000. private function tick128():void
  1001. {
  1002. var waveLen:int;
  1003. if ((NR52 & 0x01) && (length1 != 0) && (sweepShift1 != 0)) {
  1004. sweep1++;
  1005. if (sweep1 >= sweepWait1) {
  1006. sweep1 = 0;
  1007. waveLen = NR13 | ((NR14 & 0x07) << 8);
  1008. //if (waveLen <= 8)
  1009. // return;
  1010. switch (sweepDirection1) {
  1011. case 0: // positive
  1012. waveLen = waveLen + (waveLen >> sweepShift1);
  1013. //if (waveLen >= 0x800)
  1014. // waveLen = 0;
  1015. break;
  1016. case 1: // negative
  1017. waveLen = waveLen - (waveLen >> sweepShift1);
  1018. //if (newWaveLen < 0)
  1019. // newWaveLen = 0;
  1020. break;
  1021. }
  1022. NR13 = (waveLen & 0xFF);
  1023. NR14 &= 0xF8;
  1024. NR14 |= ((waveLen >> 8) & 0x07);
  1025. }
  1026. }
  1027. }
  1028. private function tick64():void
  1029. {
  1030. if (NR52 & 0x01) {
  1031. env_counter1++;
  1032. // decay calc & decay reload
  1033. if (env_counter1 >= envelopeWait1) {
  1034. env_counter1 = 0;
  1035. decay1 += envelopeDirection1;
  1036. //decay1 &= 0x0F;
  1037. if (decay1 <= 0)
  1038. decay1 = 0;
  1039. if (decay1 >= 16)
  1040. decay1 = 15;
  1041. //if (!(NR14 & 0x40)) {
  1042. // decay1 = initialEnvelopeVolume1;
  1043. //} else {
  1044. // ;//decay1 = 0;
  1045. //}
  1046. //}
  1047. //}
  1048. }
  1049. }
  1050. }
  1051. }
  1052. /**
  1053. * ...
  1054. */
  1055. class GB
  1056. {
  1057. import flash.display.BitmapData;
  1058. import flash.geom.Point;
  1059. import flash.geom.Rectangle;
  1060. import flash.ui.Keyboard;
  1061. import flash.utils.ByteArray;
  1062. private const CY:Array =
  1063. [
  1064. // 0 1 2 3 4 5 6 7 8 9 A B C D E F
  1065. 4,12, 8, 8, 4, 4, 8, 4,20, 8, 8, 8, 4, 4, 8, 4,//0
  1066. 4,12, 8, 8, 4, 4, 8, 4,12, 8, 8, 8, 4, 4, 8, 4,//1
  1067. 8,12, 8, 8, 4, 4, 8, 4, 8, 8, 8, 8, 4, 4, 8, 4,//2
  1068. 8,12, 8, 8,12,12,12, 4, 8, 8, 8, 8, 4, 4, 8, 4,//3
  1069. 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,//4
  1070. 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,//5
  1071. 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,//6
  1072. 8, 8, 8, 8, 8, 8, 4, 8, 4, 4, 4, 4, 4, 4, 8, 4,//7
  1073. 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,//8
  1074. 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,//9
  1075. 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,//A
  1076. 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,//B
  1077. 8,12,12,16,12,16, 8,16, 8,16,12, 0,12,24, 8,16,//C
  1078. 8,12,12, 0,12,16, 8,16, 8,16,12, 0,12, 0, 8,16,//D
  1079. 12,12, 8, 0, 0,16, 8,16,16, 4,16, 0, 0, 0, 8,16,//E
  1080. 12,12, 8, 4, 0,16, 8,16,12, 8,16, 4, 0, 0, 8,16 //F
  1081. ];
  1082. private const CY_CB:Array =
  1083. [
  1084. // 0 1 2 3 4 5 6 7 8 9 A B C D E F
  1085. 8, 8, 8, 8, 8, 8,16, 8, 8, 8, 8, 8, 8, 8,16, 8,
  1086. 8, 8, 8, 8, 8, 8,16, 8, 8, 8, 8, 8, 8, 8,16, 8,
  1087. 8, 8, 8, 8, 8, 8,16, 8, 8, 8, 8, 8, 8, 8,16, 8,
  1088. 8, 8, 8, 8, 8, 8,16, 8, 8, 8, 8, 8, 8, 8,16, 8,
  1089. 8, 8, 8, 8, 8, 8,12, 8, 8, 8, 8, 8, 8, 8,12, 8,
  1090. 8, 8, 8, 8, 8, 8,12, 8, 8, 8, 8, 8, 8, 8,12, 8,
  1091. 8, 8, 8, 8, 8, 8,12, 8, 8, 8, 8, 8, 8, 8,12, 8,
  1092. 8, 8, 8, 8, 8, 8,12, 8, 8, 8, 8, 8, 8, 8,12, 8,
  1093. 8, 8, 8, 8, 8, 8,16, 8, 8, 8, 8, 8, 8, 8,16, 8,
  1094. 8, 8, 8, 8, 8, 8,16, 8, 8, 8, 8, 8, 8, 8,16, 8,
  1095. 8, 8, 8, 8, 8, 8,16, 8, 8, 8, 8, 8, 8, 8,16, 8,
  1096. 8, 8, 8, 8, 8, 8,16, 8, 8, 8, 8, 8, 8, 8,16, 8,
  1097. 8, 8, 8, 8, 8, 8,16, 8, 8, 8, 8, 8, 8, 8,16, 8,
  1098. 8, 8, 8, 8, 8, 8,16, 8, 8, 8, 8, 8, 8, 8,16, 8,
  1099. 8, 8, 8, 8, 8, 8,16, 8, 8, 8, 8, 8, 8, 8,16, 8,
  1100. 8, 8, 8, 8, 8, 8,16, 8, 8, 8, 8, 8, 8, 8,16, 8
  1101. ];
  1102. private const ZT:Array =
  1103. [
  1104. ZF,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  1105. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  1106. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  1107. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  1108. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  1109. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  1110. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  1111. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  1112. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  1113. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  1114. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  1115. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  1116. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  1117. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  1118. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  1119. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  1120. ];
  1121. private function io_read(adr:uint):uint
  1122. {
  1123. adr &= 0xFFFF;
  1124. var ret:uint;
  1125. switch (adr) {
  1126. case 0xFF00://P1(パッド制御)
  1127. if (P1 == 0x03) {
  1128. return 0xFF;
  1129. }
  1130. switch ((P1 >> 4) & 0x3) {
  1131. case 0:
  1132. return 0xC0|((padData&0x81?0:1)|(padData&0x42?0:2)|(padData&0x24?0:4)|(padData&0x18?0:8));
  1133. case 1:
  1134. return 0xD0|((padData&0x01?0:1)|(padData&0x02?0:2)|(padData&0x04?0:4)|(padData&0x08?0:8));
  1135. case 2:
  1136. return 0xE0|((padData&0x80?0:1)|(padData&0x40?0:2)|(padData&0x20?0:4)|(padData&0x10?0:8));
  1137. case 3:
  1138. return 0xFF;
  1139. }
  1140. return 0xDF;
  1141. case 0xFF01://SB(シリアル通信送受信)
  1142. return SB;
  1143. case 0xFF02://SC(シリアルコントロール)
  1144. return (SC & 0x83) | 0x7C;
  1145. case 0xFF03://不明
  1146. return 0xFF;
  1147. case 0xFF04: return DIV; //DIV(ディバイダー?)
  1148. case 0xFF05: return TIMA; //TIMA(タイマカウンタ)
  1149. case 0xFF06: return TMA; //TMA(タイマ調整)
  1150. case 0xFF07: return TAC | 0xF8; //TAC(タイマコントロール)
  1151. case 0xFF08: // 不明
  1152. case 0xFF09:
  1153. case 0xFF0A:
  1154. case 0xFF0B:
  1155. case 0xFF0C:
  1156. case 0xFF0D:
  1157. case 0xFF0E:
  1158. return 0xFF;
  1159. case 0xFF0F: return IF; //IF(割りこみフラグ)
  1160. case 0xFF40: return LCDC; //LCDC(LCDコントロール)
  1161. case 0xFF41: return STAT | 0x80; //STAT(LCDステータス)
  1162. case 0xFF42: return SCY; //SCY(スクロールY)
  1163. case 0xFF43: return SCX; //SCX(スクロールX)
  1164. case 0xFF44: return LY; //LY(LCDC Y座標)
  1165. case 0xFF45: return LYC; //LYC(LY比較)
  1166. case 0xFF46: return 0; //DMA(DMA転送)
  1167. case 0xFF47: return BGP; //BGP(背景パレット)
  1168. case 0xFF48: return OBP1; //OBP1(オブジェクトパレット1)
  1169. case 0xFF49: return OBP2; //OBP2(オブジェクトパレット2)
  1170. case 0xFF4A: return WY; //WY(ウインドウY座標)
  1171. case 0xFF4B: return WX; //WX(ウインドウX座標)
  1172. case 0xFF4C: return 0xFF;
  1173. //以下カラーでの追加
  1174. case 0xFF4D://KEY1システムクロック変更
  1175. return 0;
  1176. case 0xFF4F: return VBK; //VBK(内部VRAMバンク切り替え)
  1177. case 0xFF50: return 0xFF;// 不明
  1178. case 0xFF51: return dma_src >> 8; //HDMA1(転送元上位)
  1179. case 0xFF52: return dma_src & 0xff; //HDMA2(転送元下位)
  1180. case 0xFF53: return dma_dest >> 8; //HDMA3(転送先上位)
  1181. case 0xFF54: return dma_dest & 0xff; //HDMA4(転送先下位)
  1182. case 0xFF55://HDMA5(転送実行)
  1183. return 0xFF;
  1184. case 0xFF56://RP(赤外線)
  1185. return 0;
  1186. case 0xFF68: return BCPS; //BCPS(BGパレット書き込み指定)
  1187. case 0xFF69://BCPD(BGパレット書きこみデータ)
  1188. return ret;
  1189. case 0xFF6A: return OCPS; //OCPS(OBJパレット書きこみ指定)
  1190. case 0xFF6B://OCPD(OBJパレット書きこみデータ)
  1191. return ret;
  1192. case 0xFF70: return SVBK; //SVBK(内部RAMバンク切り替え)
  1193. case 0xFFFF: return IE; //IE(割りこみマスク)
  1194. // undocumented register
  1195. case 0xFF6C: return _ff6c & 1;
  1196. case 0xFF72: return _ff72;
  1197. case 0xFF73: return _ff73;
  1198. case 0xFF74: return _ff74;
  1199. case 0xFF75: return _ff75 & 0x70;
  1200. case 0xFF76: return 0;
  1201. case 0xFF77: return 0;
  1202. default:
  1203. if (adr > 0xFF0F && adr < 0xFF40) {
  1204. return apu.read(adr - 0xFF10);
  1205. }
  1206. else if ((adr > 0xff70) && (adr < 0xff80)) {
  1207. return ext_mem[adr - 0xff71] & 0xFF;
  1208. } else
  1209. return 0xFF;
  1210. }
  1211. return 0xFF;
  1212. }
  1213. private function io_write(adr:uint, dat:uint):void
  1214. {
  1215. adr &= 0xFFFF;
  1216. dat &= 0xFF;
  1217. switch(adr){
  1218. case 0xFF00://P1(パッド制御)
  1219. P1 = dat;
  1220. return;
  1221. case 0xFF01://SB(シリアルシリアル通信送受信)
  1222. SB = dat;
  1223. return;
  1224. case 0xFF02://SC(コントロール)
  1225. if (gb_type==1){
  1226. SC = dat & 0x81;
  1227. }
  1228. else{ // GBCでの拡張
  1229. SC = dat & 0x83;
  1230. }
  1231. return;
  1232. case 0xFF04://DIV(ディバイダー)
  1233. DIV = 0;
  1234. return;
  1235. case 0xFF05://TIMA(タイマカウンタ)
  1236. TIMA = dat;
  1237. return;
  1238. case 0xFF06://TMA(タイマ調整)
  1239. TMA = dat;
  1240. return;
  1241. case 0xFF07://TAC(タイマコントロール)
  1242. if ((dat & 0x04) && !(TAC & 0x04))
  1243. sys_clock=0;
  1244. TAC = dat;
  1245. return;
  1246. case 0xFF0F://IF(割りこみフラグ)
  1247. IF = dat;
  1248. return;
  1249. case 0xFF40://LCDC(LCDコントロール)
  1250. if ((dat & 0x80) && (!(LCDC & 0x80))) {
  1251. LY = 0;
  1252. //ref_gb->get_lcd()->clear_win_count();
  1253. }
  1254. LCDC = dat;
  1255. return;
  1256. case 0xFF41://STAT(LCDステータス)
  1257. if (gb_type == 1) // オリジナルGBにおいてこのような現象が起こるらしい
  1258. if (!(STAT & 0x02))
  1259. IF |= INT_LCDC;
  1260. STAT = (STAT & 0x7) | (dat & 0x78);
  1261. return;
  1262. case 0xFF42://SCY(スクロールY)
  1263. SCY = dat;
  1264. return;
  1265. case 0xFF43://SCX(スクロールX)
  1266. SCX = dat;
  1267. return;
  1268. case 0xFF44://LY(LCDC Y座標)
  1269. //ref_gb->get_lcd()->clear_win_count();
  1270. return;
  1271. case 0xFF45://LYC(LY比較)
  1272. LYC = dat;
  1273. return;
  1274. case 0xFF46://DMA(DMA転送)
  1275. if (dat > 0xF1)
  1276. return;
  1277. var i:uint;
  1278. dat *= 256;
  1279. for (i = 0; i < 0xA0; i++)
  1280. oam[i] = read(dat + i);
  1281. dma_remain = 167;
  1282. return;
  1283. case 0xFF47://BGP(背景パレット)
  1284. BGP = dat;
  1285. return;
  1286. case 0xFF48://OBP1(オブジェクトパレット1)
  1287. OBP1 = dat;
  1288. return;
  1289. case 0xFF49://OBP2(オブジェクトパレット2)
  1290. OBP2 = dat;
  1291. return;
  1292. case 0xFF4A://WY(ウインドウY座標)
  1293. WY = dat;
  1294. return;
  1295. case 0xFF4B://WX(ウインドウX座標)
  1296. WX = dat;
  1297. return;
  1298. //以下カラーでの追加
  1299. case 0xFF4D://KEY1システムクロック変更
  1300. KEY1 = dat & 1;
  1301. return;
  1302. case 0xFF4F://VBK(内部VRAMバンク切り替え)
  1303. return;
  1304. case 0xFF51://HDMA1(転送元上位)
  1305. dma_src &= 0x00F0;
  1306. dma_src |= (dat << 8);
  1307. return;
  1308. case 0xFF52://HDMA2(転送元下位)
  1309. dma_src &= 0xFF00;
  1310. dma_src |= (dat & 0xF0);
  1311. return;
  1312. case 0xFF53://HDMA3(転送先上位)
  1313. dma_dest &= 0x00F0;
  1314. dma_dest |= ((dat & 0xFF) << 8);
  1315. return;
  1316. case 0xFF54://HDMA4(転送先下位)
  1317. dma_dest &= 0xFF00;
  1318. dma_dest |= (dat & 0xF0);
  1319. return;
  1320. case 0xFF55://HDMA5(転送実行)
  1321. return;
  1322. case 0xFF56://RP(赤外線)
  1323. return;
  1324. case 0xFF68://BCPS(BGパレット書き込み指定)
  1325. BCPS = dat;
  1326. return;
  1327. case 0xFF69://BCPD(BGパレット書きこみデータ xBBBBBGG GGGRRRRR)
  1328. return;
  1329. case 0xFF6A://OCPS(OBJパレット書きこみ指定)
  1330. OCPS = dat;
  1331. return;
  1332. case 0xFF6B://OCPD(OBJパレット書きこみデータ)
  1333. return;
  1334. case 0xFF70://SVBK(内部RAMバンク切り替え)
  1335. return;
  1336. case 0xFFFF://IE(割りこみマスク)
  1337. IE = dat;
  1338. return;
  1339. // undocumented register
  1340. case 0xFF6C: _ff6c = dat & 1; return;
  1341. case 0xFF72: _ff72 = dat; return;
  1342. case 0xFF73: _ff73 = dat; return;
  1343. case 0xFF74: _ff74 = dat; return;
  1344. case 0xff75: _ff75 = dat & 0x70; return;
  1345. default:
  1346. if (adr > 0xFF0F && adr < 0xFF40) {
  1347. apu.write(adr - 0xFF10, dat);
  1348. //apu.write(adr,dat,total_clock);
  1349. return;
  1350. }
  1351. else if ((adr > 0xff70) && (adr < 0xff80))
  1352. ext_mem[adr - 0xff71] = dat;
  1353. }
  1354. }
  1355. public function ADD(arg:uint):void
  1356. {
  1357. A &= 0xFF;
  1358. arg &= 0xFF;
  1359. var tmp:uint = A + arg;
  1360. var tmpl:uint = tmp & 0xFF;
  1361. var tmph:uint = (tmp >> 8) & 0x01;
  1362. F = tmph | ZTable[tmpl] | ((A ^ arg ^ tmpl) & HF);
  1363. A = tmpl;
  1364. }
  1365. private function ADC(arg:uint):void
  1366. {
  1367. A &= 0xFF;
  1368. arg &= 0xFF;
  1369. var tmp:uint = A + arg + (F & CF);
  1370. var tmpl:uint = tmp & 0xFF;
  1371. var tmph:uint = (tmp >> 8) & 0x01;
  1372. F = tmph | ZTable[tmpl] | ((A ^ arg ^ tmpl) & HF);
  1373. A = tmpl;
  1374. }
  1375. private function SUB(arg:uint):void
  1376. {
  1377. A &= 0xFF;
  1378. arg &= 0xFF;
  1379. var tmp:uint = (A - arg) & 0x1FF;
  1380. var tmpl:uint = tmp & 0xFF;
  1381. var tmph:uint = (tmp >> 8) & 0x01;
  1382. F = NF | tmph | ZTable[tmpl] | ((A ^ arg ^ tmpl) & HF);
  1383. A = tmpl;
  1384. }
  1385. private function SBC(arg:uint):void
  1386. {
  1387. A &= 0xFF;
  1388. arg &= 0xFF;
  1389. var tmp:uint = (A - arg - (F & CF)) & 0x1FF;
  1390. var tmpl:uint = tmp & 0xFF;
  1391. var tmph:uint = (tmp >> 8) & 0x01;
  1392. F = NF | tmph | ZTable[tmpl] | ((A ^ arg ^ tmpl) & HF);
  1393. A = tmpl;
  1394. }
  1395. private function CP(arg:uint):void
  1396. {
  1397. A &= 0xFF;
  1398. arg &= 0xFF;
  1399. var tmp:uint = (A - arg) & 0x1FF;
  1400. var tmpl:uint = tmp & 0xFF;
  1401. var tmph:uint = (tmp >> 8) & 0x01;
  1402. F = NF | tmph | ZTable[tmpl] | ((A ^ arg ^ tmpl) & HF);
  1403. }
  1404. private function AND(arg:uint):void
  1405. {
  1406. A &= arg;
  1407. A &= 0xFF;
  1408. F = HF | ZTable[A];
  1409. }
  1410. private function OR(arg:uint):void
  1411. {
  1412. A |= arg;
  1413. A &= 0xFF;
  1414. F = ZTable[A];
  1415. }
  1416. private function XOR(arg:uint):void
  1417. {
  1418. A ^= arg;
  1419. A &= 0xFF;
  1420. F = ZTable[A];
  1421. }
  1422. private function INC(arg:uint):uint
  1423. {
  1424. arg++;
  1425. arg &= 0xFF;
  1426. F = (F & CF) | ZTable[arg] | ((arg & 0x0F) ? 0 : HF);
  1427. return arg;
  1428. }
  1429. private function DEC(arg:uint):uint
  1430. {
  1431. arg--;
  1432. arg &= 0xFF;
  1433. F = NF | (F & CF) | ZTable[arg] | (((arg & 0x0F) == 0x0F) ? HF : 0);
  1434. return arg;
  1435. }
  1436. private function ADDW(arg:uint):void
  1437. {
  1438. arg &= 0xFFFF;
  1439. var hl:uint = (HL & 0xFFFF);
  1440. var tmp:uint = hl + arg;
  1441. F = (F & ZF) | (((hl ^ arg ^ tmp) & 0x1000) ? HF : 0) | ((tmp & 0x10000) ? CF : 0);
  1442. H = (tmp >> 8) & 0xFF;
  1443. L = (tmp & 0xFF);
  1444. }
  1445. public var dataLoaded:Boolean = false;
  1446. public var output:BitmapData;
  1447. public var cart:GbCart;
  1448. private var apu:GbApu = new GbApu();
  1449. // VRAM のタイルを入れる
  1450. private var tile:Vector.;
  1451. private var gb_type:uint = 1;
  1452. public var padData:uint;
  1453. public var stopPC:uint = 0;
  1454. public var stepFlag:Boolean = false;
  1455. public var A:uint, B:uint, C:uint, D:uint, E:uint, F:uint;
  1456. public var H:uint, L:uint, SP:uint, PC:uint, cycles:uint, I:uint;
  1457. private var int_desable:Boolean, halt:Boolean, tmp_clocks:uint;
  1458. private var last_int:uint;
  1459. public var count:uint = 0;
  1460. private var sys_clock:uint, rest_clock:int, div_clock:uint, total_clock:uint;
  1461. private var P1:uint, SB:uint, SC:uint, DIV:uint, TIMA:uint, TMA:uint, TAC:uint;
  1462. private var IF:uint, LCDC:uint, STAT:uint, SCY:uint, SCX:uint, LY:uint, LYC:uint;
  1463. private var DMA:uint, BGP:uint, OBP1:uint, OBP2:uint, WY:uint, WX:uint, IE:uint;
  1464. private var KEY1:uint, VBK:uint, HDMA1:uint, HDMA2:uint, HDMA3:uint, HDMA4:uint;
  1465. private var HDMA5:uint, RP:uint, BCPS:uint, BCPD:uint, OCPS:uint, OCPD:uint, SVBK:uint;
  1466. private var _ff6c:uint, _ff72:uint, _ff73:uint, _ff74:uint, _ff75:uint;
  1467. private var ext_mem:Vector.;
  1468. private var dma_src:uint, dma_dest:uint;
  1469. private var dma_remain:uint;
  1470. private var z802gb:Vector., gb2z80:Vector.;
  1471. private var ram:Vector.;
  1472. private var vram:Vector.;
  1473. private var stack:Vector.;
  1474. private var oam:Vector.;
  1475. private var spare_oam:Vector.;
  1476. public const ZF:uint = 0x40;
  1477. public const HF:uint = 0x10;
  1478. public const NF:uint = 0x02;
  1479. public const CF:uint = 0x01;
  1480. public const INT_VBLANK:uint = 1;
  1481. public const INT_LCDC:uint = 2;
  1482. public const INT_TIMER:uint = 4;
  1483. public const INT_SERIAL:uint = 8;
  1484. public const INT_PAD:uint = 16;
  1485. private var cys:Vector.;
  1486. private var cys_cb:Vector.;
  1487. private var ZTable:Vector.;
  1488. public function GB()
  1489. {
  1490. initTables();
  1491. initRegisters();
  1492. initRam();
  1493. initRom();
  1494. }
  1495. private function get2digit(n:uint):String
  1496. {
  1497. var s:String = n.toString(16).toUpperCase();
  1498. if (s.length == 1)
  1499. s = "0" + s;
  1500. return s;
  1501. }
  1502. private function get4digit(n:uint):String
  1503. {
  1504. var s:String = n.toString(16).toUpperCase();
  1505. for (var i:uint = 4; i > s.length; i--)
  1506. s = "0" + s;
  1507. return s;
  1508. }
  1509. public function setPad(key:uint, value:Boolean):void
  1510. {
  1511. var padOld:uint;
  1512. padOld = padData;
  1513. switch (key) {
  1514. case Keyboard.RIGHT:
  1515. if (value) padData |= 0x80; else padData &= 0x7F;
  1516. break;
  1517. case Keyboard.LEFT:
  1518. if (value) padData |= 0x40; else padData &= 0xBF;
  1519. break;
  1520. case Keyboard.UP:
  1521. if (value) padData |= 0x20; else padData &= 0xDF;
  1522. break;
  1523. case Keyboard.DOWN:
  1524. if (value) padData |= 0x10; else padData &= 0xEF;
  1525. break;
  1526. case 88: // X (A Button)
  1527. if (value) padData |= 0x01; else padData &= 0xFE;
  1528. break;
  1529. case 90: // Z (B Button)
  1530. if (value) padData |= 0x02; else padData &= 0xFD;
  1531. break;
  1532. case 83: // S (Start Button)
  1533. if (value) padData |= 0x08; else padData &= 0xF7;
  1534. break;
  1535. case 65: // A (Select Button)
  1536. if (value) padData |= 0x04; else padData &= 0xFB;
  1537. break;
  1538. }
  1539. if ((padOld & 0x80) != (padData & 0x80))
  1540. irq(INT_PAD);
  1541. }
  1542. private function initRegisters():void
  1543. {
  1544. A = 0x01; B = 0x00; C = 0x13; D = 0x00;
  1545. E = 0xD8; F = 0xB0; H = 0x01; L = 0x4D;
  1546. SP = 0xFFFE; PC = 0x100; cycles = 0;
  1547. I = 0;
  1548. IF = 0;
  1549. int_desable = false;
  1550. halt = false;
  1551. tmp_clocks = 0;
  1552. sys_clock = 0;
  1553. rest_clock = 0;
  1554. div_clock = 0;
  1555. total_clock = 0;
  1556. DIV = 0x72;
  1557. TIMA = 0x00; TMA = 0x00; TAC = 0x00;
  1558. LCDC = 0x91; SCY = 0x00; SCX = 0x00; LYC = 0x00;
  1559. BGP = 0xFC; OBP1 = 0xFF; OBP2 = 0xFF;
  1560. WY = 0x00; WX = 0x00; IE = 0x00;
  1561. P1 = 0x00;
  1562. }
  1563. /**
  1564. * 配列になっているデータの初期化
  1565. */
  1566. private function initTables():void
  1567. {
  1568. var i:uint;
  1569. z802gb = new Vector.();
  1570. gb2z80 = new Vector.();
  1571. z802gb.length = 256;
  1572. z802gb.fixed = true;
  1573. gb2z80.length = 256;
  1574. gb2z80.fixed = true;
  1575. for (i = 0; i < 256; i++) {
  1576. z802gb[i] = ((i & 0x40)?0x80:0) | ((i & 0x10)?0x20:0) | ((i & 0x02)?0x40:0) | ((i & 0x01)?0x10:0);
  1577. gb2z80[i] = ((i & 0x80)?0x40:0) | ((i & 0x40)?0x02:0) | ((i & 0x20)?0x10:0) | ((i & 0x10)?0x01:0);
  1578. }
  1579. ext_mem = new Vector.();
  1580. ext_mem.length = 0x10;
  1581. ext_mem.fixed = true;
  1582. cys = new Vector.();
  1583. cys.length = 0x102;
  1584. cys.fixed = true;
  1585. cys_cb = new Vector.();
  1586. cys_cb.length = 0x101;
  1587. cys_cb.fixed = true;
  1588. ZTable = new Vector.();
  1589. ZTable.length = 0x104;
  1590. ZTable.fixed = true;
  1591. for (i = 0; i < 256; i++) {
  1592. cys[i] = CY[i];
  1593. cys_cb[i] = CY_CB[i];
  1594. ZTable[i] = ZT[i];
  1595. }
  1596. tile = new Vector.();
  1597. tile.length = 384;
  1598. tile.fixed = true;
  1599. for (i = 0; i < 384; i++) {
  1600. tile[i] = new BitmapData(8, 8);
  1601. }
  1602. }
  1603. public function read_debug_memory(adr:uint):String
  1604. {
  1605. var s:String = "";
  1606. adr &= 0xFFF0;
  1607. for (var j:uint = 0; j < 16; j++)
  1608. {
  1609. s += get4digit(adr + j * 16) + ":";
  1610. for (var i:uint = 0; i < 16; i++)
  1611. s += get2digit(read(adr + i + j * 16));
  1612. s += "\n";
  1613. }
  1614. return s;
  1615. }
  1616. private function writeVram(adr:uint, dat:uint):void
  1617. {
  1618. var i:uint = adr >> 4;
  1619. if (i >= 384)
  1620. return;
  1621. tile[i].lock();
  1622. var x:uint;
  1623. var y:uint = adr & 0x0F;
  1624. var dat2:uint;
  1625. var color:uint;
  1626. if (y % 2 == 0) {
  1627. dat2 = vram[i * 16 + y + 1];
  1628. for (x = 0; x < 8; x++)
  1629. {
  1630. color = 0;
  1631. if (dat & (0x80 >> x))
  1632. color = 0x555555;
  1633. if (dat2 & (0x80 >> x))
  1634. color |= 0xAAAAAA;
  1635. tile[i].setPixel(x, y / 2, 0xFFFFFF - color);
  1636. }
  1637. } else {
  1638. dat2 = vram[i * 16 + y - 1];
  1639. for (x = 0; x < 8; x++)
  1640. {
  1641. color = 0;
  1642. if (dat2 & (0x80 >> x))
  1643. color = 0x555555;
  1644. if (dat & (0x80 >> x))
  1645. color |= 0xAAAAAA;
  1646. tile[i].setPixel(x, y / 2, 0xFFFFFF - color);
  1647. }
  1648. }
  1649. tile[i].unlock();
  1650. }
  1651. public function render(output:BitmapData):void
  1652. {
  1653. if (!(LCDC & 0x80))
  1654. return;
  1655. var rect:Rectangle = new Rectangle(0, 0, 8, 8);
  1656. output.lock();
  1657. // 背景の転送
  1658. var x1:int;
  1659. var y1:int;
  1660. var dx:int;
  1661. var dy:int;
  1662. var ti:uint;
  1663. var ti2:uint;
  1664. if (LCDC & 0x01) { // 背景表示
  1665. for (y1 = 0; y1 < 32; y1++)
  1666. {
  1667. if (LCDC & 0x08)
  1668. ti = 0x1C00 + y1 * 32;
  1669. else
  1670. ti = 0x1800 + y1 * 32;
  1671. dy = y1 * 8 - SCY;
  1672. if (dy < -8)
  1673. dy += 256;
  1674. if (dy >= 144)
  1675. continue;
  1676. for (x1 = 0; x1 < 32; x1++)
  1677. {
  1678. dx = x1 * 8 - SCX;
  1679. if (dx < -8)
  1680. dx += 256;
  1681. if (dx >= 160)
  1682. continue;
  1683. if (LCDC & 0x10) {
  1684. ti2 = vram[ti + x1];
  1685. } else {
  1686. if (vram[ti + x1] < 128)
  1687. ti2 = vram[ti + x1] + 256;
  1688. else
  1689. ti2 = vram[ti + x1];
  1690. }
  1691. output.copyPixels(tile[ti2], rect, new Point(dx, dy));
  1692. }
  1693. }
  1694. }
  1695. if (LCDC & 0x20 && WX >= 0 && WX <= 166 && WY >= 0 && WY <= 143) { // ウインドウ表示
  1696. for (y1 = 0; y1 < 32; y1++)
  1697. {
  1698. if (LCDC & 0x40)
  1699. ti = 0x1C00 + y1 * 32;
  1700. else
  1701. ti = 0x1800 + y1 * 32;
  1702. dy = y1 * 8 + WY;
  1703. if (dy <= -8 || dy >= 144)
  1704. continue;
  1705. for (x1 = 0; x1 < 32; x1++)
  1706. {
  1707. dx = x1 * 8 + WX - 7;
  1708. if (dx <= -8 || dx >= 160)
  1709. continue;
  1710. if (LCDC & 0x10) {
  1711. ti2 = vram[ti + x1];
  1712. } else {
  1713. if (vram[ti + x1] < 128)
  1714. ti2 = vram[ti + x1] + 256;
  1715. else
  1716. ti2 = vram[ti + x1];
  1717. }
  1718. //copyPixel(output, tile[ti2], dx, dy, false, false);
  1719. output.copyPixels(tile[ti2], rect, new Point(dx, dy));
  1720. }
  1721. }
  1722. }
  1723. // スプライトの転送
  1724. if (LCDC & 0x02) { // スプライト表示
  1725. var y:int;
  1726. var x:int;
  1727. var p:uint;
  1728. var rx:Boolean;
  1729. var ry:Boolean;
  1730. if (LCDC & 0x04) { // 8x16
  1731. for (x1 = 0; x1 < 20; x1++)
  1732. {
  1733. y = oam[x1 * 8] - 16;
  1734. x = oam[x1 * 8 + 1] - 8;
  1735. p = oam[x1 * 8 + 2];
  1736. rx = (oam[x1 * 8 + 3] & 0x20) ? true : false;
  1737. ry = (oam[x1 * 8 + 3] & 0x40) ? true : false;
  1738. if (x <= -8 || y <= -8 || x >= 160 || y >= 144)
  1739. continue;
  1740. copyPixel(output, tile[p], x, y, rx, ry);
  1741. p = oam[x1 * 8 + 4 + 2];
  1742. copyPixel(output, tile[p], x, y + 8, rx, ry);
  1743. //output.copyPixels(tile[p], rect, new Point(x, y));
  1744. }
  1745. } else {
  1746. for (x1 = 0; x1 < 40; x1++)
  1747. {
  1748. y = oam[x1 * 4] - 16;
  1749. x = oam[x1 * 4 + 1] - 8;
  1750. p = oam[x1 * 4 + 2];
  1751. rx = (oam[x1 * 4 + 3] & 0x20) ? true : false;
  1752. ry = (oam[x1 * 4 + 3] & 0x40) ? true : false;
  1753. if (x <= -8 || y <= -8 || x >= 160 || y >= 144)
  1754. continue;
  1755. copyPixel(output, tile[p], x, y, rx, ry);
  1756. //output.copyPixels(tile[p], rect, new Point(x, y));
  1757. }
  1758. }
  1759. }
  1760. output.unlock();
  1761. }
  1762. private function copyPixel(dest:BitmapData, source:BitmapData, dx:int, dy:int, rx:Boolean, ry:Boolean):void
  1763. {
  1764. dest.lock();
  1765. //source.lock();
  1766. var y:int;
  1767. var x:int;
  1768. var color:uint;
  1769. for (y = 0; y < 8; y++)
  1770. {
  1771. for (x = 0; x < 8; x++)
  1772. {
  1773. var drx:int = x;
  1774. var dry:int = y;
  1775. if (rx)
  1776. drx = 7 - x;
  1777. if (ry)
  1778. dry = 7 - y;
  1779. color = source.getPixel(x, y);
  1780. if (color == 0xFFFFFF)
  1781. continue;
  1782. dest.setPixel(drx + dx, dry + dy, color);
  1783. }
  1784. }
  1785. //source.unlock();
  1786. dest.unlock();
  1787. }
  1788. private function initRam():void
  1789. {
  1790. ram = new Vector.();
  1791. ram.length = 0x2000; // 8KB
  1792. ram.fixed = true;
  1793. vram = new Vector.();
  1794. vram.length = 0x2000; // 8KB
  1795. vram.fixed = true;
  1796. stack = new Vector.();
  1797. stack.length = 0x80;
  1798. stack.fixed = true;
  1799. oam = new Vector.();
  1800. oam.length = 0xA0;
  1801. oam.fixed = true;
  1802. spare_oam = new Vector.();
  1803. spare_oam.length = 0xA0;
  1804. spare_oam.fixed = true;
  1805. }
  1806. private function initRom():void
  1807. {
  1808. }
  1809. public function loadRom(byteArray:ByteArray):void
  1810. {
  1811. cart = new GbCart(byteArray);
  1812. dataLoaded = true;
  1813. //trace("Title : " + cart.title);
  1814. //trace("Type : " + cart.type);
  1815. //trace("typeCode : " + cart.typeCode);
  1816. }
  1817. public function get AF():uint
  1818. {
  1819. A = (A & 0xFF);
  1820. F = (F & 0xFF);
  1821. return (A << 8) | z802gb[F];
  1822. }
  1823. public function set AF(arg:uint):void
  1824. {
  1825. A = ((arg >> 8) & 0xFF);
  1826. F = gb2z80[arg & 0xFF];
  1827. }
  1828. public function get BC():uint
  1829. {
  1830. B = (B & 0xFF);
  1831. C = (C & 0xFF);
  1832. return (B << 8) | C;
  1833. }
  1834. public function set BC(arg:uint):void
  1835. {
  1836. B = ((arg >> 8) & 0xFF);
  1837. C = (arg & 0xFF);
  1838. }
  1839. public function get DE():uint
  1840. {
  1841. D = (D & 0xFF);
  1842. E = (E & 0xFF);
  1843. return (D << 8) | E;
  1844. }
  1845. public function set DE(arg:uint):void
  1846. {
  1847. D = ((arg >> 8) & 0xFF);
  1848. E = (arg & 0xFF);
  1849. }
  1850. public function get HL():uint
  1851. {
  1852. H = (H & 0xFF);
  1853. L = (L & 0xFF);
  1854. return (H << 8) | L;
  1855. }
  1856. public function set HL(arg:uint):void
  1857. {
  1858. H = ((arg >> 8) & 0xFF);
  1859. L = (arg & 0xFF);
  1860. }
  1861. public function read(adr:uint):uint
  1862. {
  1863. //adr = (adr & 0xFFFF);
  1864. switch (adr >> 13)
  1865. {
  1866. case 0:
  1867. case 1:
  1868. return cart.read(adr);//ROM領域
  1869. case 2:
  1870. case 3:
  1871. return cart.readBank(adr);//バンク可能ROM
  1872. case 4:
  1873. return vram[adr & 0x1FFF];//8KBVRAM
  1874. case 5:
  1875. return cart.readSram(adr & 0x1FFF) & 0xFF;
  1876. break;
  1877. case 6:
  1878. return ram[adr & 0x1fff];// & 0xFF;
  1879. case 7:
  1880. if (adr < 0xFE00){
  1881. return ram[adr & 0x1fff];// & 0xFF; // ram_bank
  1882. }
  1883. else if (adr < 0xFEA0)
  1884. return oam[adr - 0xFE00];// & 0xFF;//object attribute memory
  1885. else if (adr < 0xFF00) {
  1886. var index:uint;
  1887. index = (adr - 0xFEA0) >> 5;
  1888. index <<= 3;
  1889. index |= (adr & 7);
  1890. return spare_oam[index];// & 0xFF;
  1891. }
  1892. else if (adr < 0xFF80)
  1893. return io_read(adr) & 0xFF;//I/O
  1894. else if (adr < 0xFFFF)
  1895. return stack[adr - 0xFF80];// & 0xFF;//stack
  1896. else
  1897. return IE;// & 0xFF;//I/O
  1898. }
  1899. return 0;
  1900. }
  1901. private function write(adr:uint, dat:uint):void
  1902. {
  1903. //adr = (adr & 0xFFFF);
  1904. dat = (dat & 0xFF);
  1905. switch ( adr >> 13 )
  1906. {
  1907. case 0: // ROMバンク 0
  1908. case 1: // ROMバンク 0
  1909. case 2: // ROMバンク 1
  1910. case 3: // ROMバンク 1
  1911. cart.write(adr, dat);
  1912. break;
  1913. case 4: // VRAM
  1914. vram[adr & 0x1FFF] = dat;
  1915. writeVram(adr & 0x1FFF, dat);
  1916. break;
  1917. case 5: // RAM バンク
  1918. cart.writeSram(adr & 0x1FFF, dat);
  1919. //if (ref_gb->get_mbc()->is_ext_ram())
  1920. // ref_gb->get_mbc()->get_sram()[adr&0x1FFF]=dat;//カートリッジRAM
  1921. //else
  1922. // ref_gb->get_mbc()->ext_write(adr,dat);
  1923. break;
  1924. case 6: // 内部 RAM
  1925. //if (adr&0x1000)
  1926. // ram_bank[adr&0x0fff]=dat;
  1927. //else
  1928. ram[adr & 0x1fff] = dat;
  1929. break;
  1930. case 7:
  1931. if (adr < 0xFE00) {
  1932. // if (adr&0x1000)
  1933. // ram_bank[adr&0x0fff]=dat;
  1934. // else
  1935. ram[adr & 0x1fff] = dat;
  1936. }
  1937. else if (adr < 0xFEA0)
  1938. oam[adr - 0xFE00] = dat;
  1939. else if (adr < 0xFF00) {
  1940. var index:uint;
  1941. index = (adr - 0xFEA0) >> 5;
  1942. index <<= 3;
  1943. index |= (adr & 7);
  1944. spare_oam[index] = dat;
  1945. } else if (adr < 0xFF80)
  1946. io_write(adr,dat);//I/O
  1947. else if (adr < 0xFFFF) {
  1948. //if (adr == 0xFF8F)
  1949. // stopPC = PC;
  1950. stack[adr - 0xFF80] = dat;//stack
  1951. } else
  1952. IE = dat;//I/O
  1953. break;
  1954. }
  1955. }
  1956. public function readw(adr:uint):uint
  1957. {
  1958. return read(adr) | (read(adr + 1) << 8);
  1959. }
  1960. public function writew(adr:uint, dat:uint):void
  1961. {
  1962. write(adr, dat);
  1963. write(adr + 1, dat >> 8);
  1964. }
  1965. private function op_read():uint
  1966. {
  1967. return read(PC++);
  1968. }
  1969. private function op_read_s():int
  1970. {
  1971. var dat:uint = read(PC++);
  1972. if (dat & 0x80)
  1973. return (dat | 0xFFFFFF00);
  1974. return dat;
  1975. }
  1976. private function op_readw():uint
  1977. {
  1978. PC += 2; return readw(PC - 2);
  1979. }
  1980. public function irq(irq_type:uint):void
  1981. {
  1982. if (!((irq_type == INT_VBLANK || irq_type == INT_LCDC) && (!(LCDC & 0x80))))
  1983. IF |= irq_type;
  1984. }
  1985. public function irq_process():void
  1986. {
  1987. if (int_desable) {
  1988. int_desable=false;
  1989. return;
  1990. }
  1991. if ((IF & IE) && (I || halt)) {//割りこみがかかる時
  1992. if (halt)
  1993. PC++;
  1994. write(SP - 2, PC & 0xFF);
  1995. write(SP - 1, (PC >> 8));
  1996. SP -= 2;
  1997. if (IF & IE & INT_VBLANK) {//VBlank
  1998. PC = 0x40;
  1999. IF &= 0xFE;
  2000. last_int = INT_VBLANK;
  2001. }
  2002. else if (IF & IE & INT_LCDC) {//LCDC
  2003. PC = 0x48;
  2004. IF &= 0xFD;
  2005. last_int = INT_LCDC;
  2006. }
  2007. else if (IF & IE & INT_TIMER) {//Timer
  2008. PC = 0x50;
  2009. IF &= 0xFB;
  2010. last_int = INT_TIMER;
  2011. }
  2012. else if (IF & IE & INT_SERIAL) {//Serial
  2013. PC = 0x58;
  2014. IF &= 0xF7;
  2015. last_int = INT_SERIAL;
  2016. }
  2017. else if (IF & IE & INT_PAD) {//Pad
  2018. PC = 0x60;
  2019. IF &= 0xEF;
  2020. last_int = INT_PAD;
  2021. }
  2022. else {}
  2023. halt = false;
  2024. I = 0;
  2025. }
  2026. }
  2027. public function ex(clocks:uint):void
  2028. {
  2029. var timer_clocks:Array = [1024, 16, 64, 256];
  2030. var opcode:uint;
  2031. var tmpb:uint = 0;
  2032. var tmps:int = 0;
  2033. rest_clock += clocks;
  2034. if (dma_remain > 0) {
  2035. rest_clock -= dma_remain;
  2036. dma_remain = 0;
  2037. }
  2038. while (rest_clock > 0)
  2039. {
  2040. if (stopPC == PC)
  2041. return;
  2042. irq_process();
  2043. opcode = read(PC++);
  2044. tmp_clocks = cys[opcode];
  2045. // 0x00-0x0F
  2046. switch (opcode)
  2047. {
  2048. case 0x00: break; // NOP
  2049. case 0x01: BC = op_readw(); break; //LD BC,(mn)
  2050. case 0x02: write(BC, A); break; // LD (BC),A : 00 000 010 :state 7
  2051. case 0x03: BC++; break; //INC BC
  2052. case 0x04: B = INC(B); break; //INC B
  2053. case 0x05: B = DEC(B); break; //DEC B
  2054. case 0x06: B = op_read(); break; // LD B,n
  2055. case 0x07: F = (A >> 7) & 0x01; A = ((A << 1) & 0xFE) | ((A >> 7) & 1); A &= 0xFF; break; //RLCA :state 4
  2056. case 0x08: writew(op_readw(), SP); break; //LD (mn),SP
  2057. case 0x09: ADDW(BC); break; //ADD HL,BC
  2058. case 0x0A: A = read(BC); break; // LD A,(BC) :00 001 010 :state 7
  2059. case 0x0B: BC--; break; //DEC BC
  2060. case 0x0C: C = INC(C); break; //INC C
  2061. case 0x0D: C = DEC(C); break; //DEC C
  2062. case 0x0E: C = op_read(); break; // LD C,n
  2063. case 0x0F: F = (A & 1); A = ((A >> 1) & 0x7F) | ((A << 7) & 0x80); A &= 0xFF; break; //RRCA :state 4
  2064. // 0x10-0x1F
  2065. case 0x10: halt=true;PC--;break; //STOP(HALT?)
  2066. case 0x11: DE = op_readw(); break; //LD DE,(mn)
  2067. case 0x12: write(DE, A); break; // LD (DE),A : 00 010 010 :state 7
  2068. case 0x13: DE++; break; //INC DE
  2069. case 0x14: D = INC(D); break; //INC D
  2070. case 0x15: D = DEC(D); break; //DEC D
  2071. case 0x16: D = op_read(); break; // LD D,n
  2072. case 0x17: tmpb = (A >> 7) & 0x01; A = ((A << 1) & 0xFE) | (F & CF); A &= 0xFF; F = tmpb; break; //RLA :state 4
  2073. case 0x18: {tmps=op_read_s();PC+=tmps;} break;//JR e : state 12
  2074. case 0x19: ADDW(DE); break; //ADD HL,DE
  2075. case 0x1A: A = read(DE); break; // LD A,(DE) :00 011 010 : state 7
  2076. case 0x1B: DE--; break; //DEC DE
  2077. case 0x1C: E = INC(E); break; //INC E
  2078. case 0x1D: E = DEC(E); break; //DEC E
  2079. case 0x1E: E = op_read(); break; // LD E,n
  2080. case 0x1F: tmpb = A & 1; A = ((A >> 1) & 0x7F) | ((F << 7) & 0x80); A &= 0xFF; F = tmpb; break; //RRA :state 4
  2081. // 0x20-0x2F
  2082. case 0x20: if (F & ZF) PC += 1; else {tmps=op_read_s();PC+=tmps; tmp_clocks = 12; } break;// JRNZ
  2083. case 0x21: HL = op_readw(); break; //LD HL,(mn)
  2084. case 0x22: write(HL, A); HL++; break; // LD (HLI),A : 00 110 010 :state 13
  2085. case 0x23: HL++; break; //INC HL
  2086. case 0x24: H = INC(H); break; //INC H
  2087. case 0x25: H = DEC(H); break; //DEC H
  2088. case 0x26: H = op_read(); break; // LD H,n
  2089. case 0x27://DAA :state 4
  2090. {
  2091. var tmp:uint = (A & 0x0F);
  2092. tmp = (F & NF)?
  2093. (
  2094. (F & CF)?
  2095. (((F & HF)? 0x9A00:0xA000) + CF):
  2096. ((F & HF)? 0xFA00:0x0000)
  2097. )
  2098. :
  2099. (
  2100. (F & CF)?
  2101. (((F & HF)? 0x6600:((tmp < 0x0A)? 0x6000:0x6600)) + CF):
  2102. (
  2103. (F & HF)?
  2104. ((A < 0xA0)? 0x0600:(0x6600 + CF)):
  2105. (
  2106. (tmp < 0x0A)?
  2107. ((A < 0xA0)? 0x0000:(0x6000 + CF)):
  2108. ((A < 0x90)? 0x0600:(0x6600 + CF))
  2109. )
  2110. )
  2111. );
  2112. A += (tmp >> 8);
  2113. A = (A & 0xFF);
  2114. F = ZTable[A] | ((tmp & 0xFF) | (F & NF));
  2115. }
  2116. break;
  2117. case 0x28: if (F & ZF) {tmps=op_read_s();PC+=tmps; tmp_clocks = 12;} else PC += 1; break;// JRZ
  2118. case 0x29: ADDW(HL); break; //ADD HL,HL
  2119. case 0x2A: A = read(HL); HL++; break; // LD A,(HLI) : 00 111 010 :state 13
  2120. case 0x2B: HL--; break; //DEC HL
  2121. case 0x2C: L = INC(L); break; //INC L
  2122. case 0x2D: L = DEC(L); break; //DEC L
  2123. case 0x2E: L = op_read(); break; // LD L,n
  2124. case 0x2F: //CPL(1の補数) :state4
  2125. A = ~A;
  2126. A &= 0xFF;
  2127. F |= (NF | HF);
  2128. break;
  2129. // 0x30-0x3F
  2130. case 0x30: if (F & CF) PC += 1; else {tmps=op_read_s();PC+=tmps;tmp_clocks = 12;} break;// JRNC
  2131. case 0x31: SP = op_readw(); break; //LD SP,(mn)
  2132. case 0x32: write(HL, A); HL--; break; // LD (HLD),A : 00 110 010 :state 13
  2133. case 0x33: SP++; break; //INC SP
  2134. case 0x34: tmpb = read(HL); tmpb = INC(tmpb); write(HL, tmpb); break; //INC (HL) : 00 110 100 : state 11
  2135. case 0x35: tmpb = read(HL); tmpb = DEC(tmpb); write(HL, tmpb); break; //DEC (HL) : 00 110 101 : state 11
  2136. case 0x36: write(HL, op_read()); break; // LD (HL),n :00 110 110 :state 10
  2137. case 0x37: //SCF(set carry) :state 4
  2138. F = (F & ~(NF | HF)) | CF;
  2139. break;
  2140. case 0x38: if (F & CF) {tmps=op_read_s();PC+=tmps; tmp_clocks = 12;} else PC += 1; break;// JRC
  2141. case 0x39: ADDW(SP); break; //ADD HL,SP
  2142. case 0x3A: A = read(HL); HL--; break; // LD A,(HLD) : 00 111 010 :state 13
  2143. case 0x3B: SP--; break; //DEC SP
  2144. case 0x3C: A = INC(A); break; //INC A
  2145. case 0x3D: A = DEC(A); break; //DEC A
  2146. case 0x3E: A = op_read(); break; // LD A,n
  2147. case 0x3F: //CCF(not carry) :state 4
  2148. F ^= 0x01;
  2149. F = F & ~(NF | HF);
  2150. break;
  2151. // 0x40-0x4F
  2152. case 0x40: break; // LD B,B
  2153. case 0x41: B = C; break; // LD B,C
  2154. case 0x42: B = D; break; // LD B,D
  2155. case 0x43: B = E; break; // LD B,E
  2156. case 0x44: B = H; break; // LD B,H
  2157. case 0x45: B = L; break; // LD B,L
  2158. case 0x46: B = read(HL); break; // LD B,(HL)
  2159. case 0x66: H = read(HL); break; // LD H,(HL)
  2160. case 0x47: B = A; break; // LD B,A
  2161. case 0x48: C = B; break; // LD C,B
  2162. case 0x49: break; // LD C,C
  2163. case 0x4A: C = D; break; // LD C,D
  2164. case 0x4B: C = E; break; // LD C,E
  2165. case 0x4C: C = H; break; // LD C,H
  2166. case 0x4D: C = L; break; // LD C,L
  2167. case 0x4E: C = read(HL); break; // LD C,(HL)
  2168. case 0x4F: C = A; break; // LD C,A
  2169. // 0x50-0x5F
  2170. case 0x50: D = B;break; // LD D,B
  2171. case 0x51: D = C;break; // LD D,C
  2172. case 0x52: break; // LD D,D
  2173. case 0x53: D = E; break; // LD D,E
  2174. case 0x54: D = H; break; // LD D,H
  2175. case 0x55: D = L; break; // LD D,L
  2176. case 0x56: D = read(HL); break; // LD D,(HL)
  2177. case 0x57: D = A; break; // LD D,A
  2178. case 0x58: E = B;break; // LD E,B
  2179. case 0x59: E = C;break; // LD E,C
  2180. case 0x5A: E = D;break; // LD E,D
  2181. case 0x5B: break; // LD E,E
  2182. case 0x5C: E = H;break; // LD E,H
  2183. case 0x5D: E = L;break; // LD E,L
  2184. case 0x5E: E = read(HL); break; // LD E,(HL)
  2185. case 0x5F: E = A;break; // LD E,A
  2186. // 0x60-0x6F
  2187. case 0x60: H = B; break; // LD H,B
  2188. case 0x61: H = C; break; // LD H,C
  2189. case 0x62: H = D; break; // LD H,D
  2190. case 0x63: H = E; break; // LD H,E
  2191. case 0x64: break; // LD H,H
  2192. case 0x65: H = L; break; // LD H,L
  2193. case 0x67: H = A; break; // LD H,A
  2194. case 0x68: L = B; break; // LD L,B
  2195. case 0x69: L = C; break; // LD L,C
  2196. case 0x6A: L = D; break; // LD L,D
  2197. case 0x6B: L = E; break; // LD L,E
  2198. case 0x6C: L = H; break; // LD L,H
  2199. case 0x6D: break; // LD L,L
  2200. case 0x6E: L = read(HL); break; // LD L,(HL)
  2201. case 0x6F: L = A; break; // LD L,A
  2202. // 0x70-0x7F
  2203. case 0x70: write(HL, B); break; // LD (HL),B
  2204. case 0x71: write(HL, C); break; // LD (HL),C
  2205. case 0x72: write(HL, D); break; // LD (HL),D
  2206. case 0x73: write(HL, E); break; // LD (HL),E
  2207. case 0x74: write(HL, H); break; // LD (HL),H
  2208. case 0x75: write(HL, L); break; // LD (HL),L
  2209. case 0x76:
  2210. if (TAC & 0x04) {//タイマ割りこみ
  2211. //var tmp:uint;
  2212. tmpb = TIMA + (sys_clock + rest_clock) / timer_clocks[TAC & 0x03];
  2213. if (tmpb & 0xFF00) {//HALT中に割りこみがかかる場合
  2214. //total_clock += (256 - TIMA) * timer_clocks[TAC & 0x03] - sys_clock;
  2215. rest_clock -= (256 - TIMA) * timer_clocks[TAC & 0x03] - sys_clock;
  2216. TIMA = TMA;
  2217. halt = true;
  2218. PC--;
  2219. irq(INT_TIMER);
  2220. sys_clock = (sys_clock + rest_clock) & (timer_clocks[TAC & 0x03] - 1);
  2221. }
  2222. else{
  2223. TIMA = tmpb & 0xFF;
  2224. sys_clock = (sys_clock + rest_clock) & (timer_clocks[TAC & 0x03] - 1);
  2225. halt = true;
  2226. //total_clock += rest_clock;
  2227. rest_clock = 0;
  2228. PC--;
  2229. }
  2230. }
  2231. else{
  2232. halt = true;
  2233. //total_clock += rest_clock;
  2234. div_clock += rest_clock;
  2235. rest_clock = 0;
  2236. PC--;
  2237. }
  2238. tmp_clocks = 0;
  2239. break; //HALT : state 4
  2240. case 0x77: write(HL, A); break; // LD (HL),A
  2241. case 0x78: A = B; break; // LD A,B
  2242. case 0x79: A = C; break; // LD A,C
  2243. case 0x7A: A = D; break; // LD A,D
  2244. case 0x7B: A = E; break; // LD A,E
  2245. case 0x7C: A = H; break; // LD A,H
  2246. case 0x7D: A = L; break; // LD A,L
  2247. case 0x7E: A = read(HL); break; // LD A,(HL)
  2248. case 0x7F: break; // LD A,A
  2249. // 0x80-0x8F
  2250. case 0x80: ADD(B); break; //ADD A,B
  2251. case 0x81: ADD(C); break; //ADD A,C
  2252. case 0x82: ADD(D); break; //ADD A,D
  2253. case 0x83: ADD(E); break; //ADD A,E
  2254. case 0x84: ADD(H); break; //ADD A,H
  2255. case 0x85: ADD(L); break; //ADD A,L
  2256. case 0x86: tmpb = read(HL); ADD(tmpb); break; //ADD A,(HL) : 10 000 110 :state 7
  2257. case 0x87: ADD(A); break; //ADD A,A
  2258. case 0x88: ADC(B); break; //ADC A,B
  2259. case 0x89: ADC(C); break; //ADC A,C
  2260. case 0x8A: ADC(D); break; //ADC A,D
  2261. case 0x8B: ADC(E); break; //ADC A,E
  2262. case 0x8C: ADC(H); break; //ADC A,H
  2263. case 0x8D: ADC(L); break; //ADC A,L
  2264. case 0x8E: tmpb = read(HL); ADC(tmpb); break; //ADC A,(HL) : 10 001 110 :state 7
  2265. case 0x8F: ADC(A); break; //ADC A,A
  2266. // 0x90-0x9F
  2267. case 0x90: SUB(B); break; //SUB A,B
  2268. case 0x91: SUB(C); break; //SUB A,C
  2269. case 0x92: SUB(D); break; //SUB A,D
  2270. case 0x93: SUB(E); break; //SUB A,E
  2271. case 0x94: SUB(H); break; //SUB A,H
  2272. case 0x95: SUB(L); break; //SUB A,L
  2273. case 0x96: tmpb = read(HL); SUB(tmpb); break; //SUB A,(HL) : 10 010 110 :state 7
  2274. case 0x97: SUB(A); break; //SUB A,A
  2275. case 0x98: SBC(B); break; //SBC A,B
  2276. case 0x99: SBC(C); break; //SBC A,C
  2277. case 0x9A: SBC(D); break; //SBC A,D
  2278. case 0x9B: SBC(E); break; //SBC A,E
  2279. case 0x9C: SBC(H); break; //SBC A,H
  2280. case 0x9D: SBC(L); break; //SBC A,L
  2281. case 0x9E: tmpb = read(HL); SBC(tmpb); break; //SBC A,(HL) : 10 011 110 :state 7
  2282. case 0x9F: SBC(A); break; //SBC A,A
  2283. // 0xA0-0xAF
  2284. case 0xA0: AND(B); break; //AND A,B
  2285. case 0xA1: AND(C); break; //AND A,C
  2286. case 0xA2: AND(D); break; //AND A,D
  2287. case 0xA3: AND(E); break; //AND A,E
  2288. case 0xA4: AND(H); break; //AND A,H
  2289. case 0xA5: AND(L); break; //AND A,L
  2290. case 0xA6: tmpb = read(HL); AND(tmpb); break; //AND A,(HL) : 10 100 110 :state 7
  2291. case 0xA7: AND(A); break; //AND A,A
  2292. case 0xA8: XOR(B); break; //XOR A,B
  2293. case 0xA9: XOR(C); break; //XOR A,C
  2294. case 0xAA: XOR(D); break; //XOR A,D
  2295. case 0xAB: XOR(E); break; //XOR A,E
  2296. case 0xAC: XOR(H); break; //XOR A,H
  2297. case 0xAD: XOR(L); break; //XOR A,L
  2298. case 0xAE: tmpb = read(HL); XOR(tmpb); break; //XOR A,(HL) : 10 101 110 :state 7
  2299. case 0xAF: XOR(A); break; //XOR A,A
  2300. // 0xB0-0xBF
  2301. case 0xB0: OR(B); break; //OR A,B
  2302. case 0xB1: OR(C); break; //OR A,C
  2303. case 0xB2: OR(D); break; //OR A,D
  2304. case 0xB3: OR(E); break; //OR A,E
  2305. case 0xB4: OR(H); break; //OR A,H
  2306. case 0xB5: OR(L); break; //OR A,L
  2307. case 0xB6: tmpb = read(HL); OR(tmpb); break; //OR A,(HL) : 10 110 110 :state 7
  2308. case 0xB7: OR(A); break; //OR A,A
  2309. case 0xB8: CP(B); break; //CP A,B
  2310. case 0xB9: CP(C); break; //CP A,C
  2311. case 0xBA: CP(D); break; //CP A,D
  2312. case 0xBB: CP(E); break; //CP A,E
  2313. case 0xBC: CP(H); break; //CP A,H
  2314. case 0xBD: CP(L); break; //CP A,L
  2315. case 0xBE: tmpb = read(HL); CP(tmpb); break; //CP A,(HL) : 10 111 110 :state 7
  2316. case 0xBF: CP(A); break; //CP A,A
  2317. // 0xC0-0xCF
  2318. case 0xC0: if (!(F & ZF)) {PC = readw(SP); SP += 2; tmp_clocks = 20;} break; //RETNZ
  2319. case 0xC1: B = read(SP + 1); C = read(SP); SP += 2; break; //POP BC
  2320. case 0xC2: if (F & ZF) PC += 2; else { PC = op_readw(); tmp_clocks=16; }; break; // JPNZ mn
  2321. case 0xC3: PC = op_readw(); break;//JP mn : state 10 (16?)
  2322. case 0xC4: if (F & ZF) PC += 2; else {SP -= 2; writew(SP, PC + 2); PC = op_readw(); tmp_clocks = 24;} break; //CALLNZ mn
  2323. case 0xC5: SP -= 2; writew(SP, BC); break; //PUSH BC
  2324. case 0xC6: tmpb = op_read(); ADD(tmpb); break; //ADD A,n : 11 000 110 :state 7
  2325. case 0xC7: SP -= 2; writew(SP, PC); PC = 0x00;break; //RST 0x00
  2326. case 0xC8: if (F & ZF) {PC = readw(SP);SP += 2; tmp_clocks = 20;} break; //RETZ
  2327. case 0xC9: PC = readw(SP); SP += 2; break; //RET state 16
  2328. case 0xCA: if (F & ZF) { PC = op_readw(); tmp_clocks=16; } else PC += 2; break; // JPZ mn
  2329. case 0xCB:
  2330. exec_0xCB();
  2331. break;
  2332. case 0xCC: if (F & ZF) {SP -= 2; writew(SP, PC + 2); PC = op_readw(); tmp_clocks = 24;} else PC += 2; break; //CALLZ mn
  2333. case 0xCD: SP -= 2; writew(SP, PC + 2); PC = op_readw(); break; //CALL mn :state 24
  2334. case 0xCE: tmpb = op_read(); ADC(tmpb); break; //ADC A,n : 11 001 110 :state 7
  2335. case 0xCF: SP -= 2; writew(SP, PC); PC = 0x08;break; //RST 0x08
  2336. // 0xD0-0xDF
  2337. case 0xD0: if (!(F & CF)) {PC = readw(SP); SP += 2; tmp_clocks = 20;} break; //RETNC
  2338. case 0xD1: D = read(SP + 1); E = read(SP); SP += 2; break; //POP DE
  2339. case 0xD2: if (F & CF) PC += 2; else { PC = op_readw(); tmp_clocks=16; }; break; // JPNC mn
  2340. case 0xD4: if (F & CF) PC += 2; else {SP -= 2; writew(SP, PC + 2); PC = op_readw(); tmp_clocks = 24;} break; //CALLNC mn
  2341. case 0xD5: SP -= 2; writew(SP, DE); break; //PUSH DE
  2342. case 0xD6: tmpb = op_read(); SUB(tmpb); break; //SUB A,n : 11 010 110 :state 7
  2343. case 0xD7: SP -= 2; writew(SP, PC); PC = 0x10;break; //RST 0x10
  2344. case 0xD8: if (F & CF) {PC = readw(SP); SP += 2; tmp_clocks = 20;} break; //RETC
  2345. case 0xD9: I = 1; PC = readw(SP); SP += 2; int_desable = true; break;//RETI state 16
  2346. case 0xDA: if (F & CF) { PC = op_readw(); tmp_clocks=16; } else PC += 2; break; // JPC mn
  2347. case 0xDC: if (F & CF) {SP -= 2; writew(SP, PC + 2); PC = op_readw(); tmp_clocks = 24;} else PC += 2; break; //CALLC mn
  2348. case 0xDE: tmpb = op_read(); SBC(tmpb); break; //SBC A,n : 11 011 110 :state 7
  2349. case 0xDF: SP -= 2; writew(SP, PC); PC = 0x18;break; //RST 0x18
  2350. // 0xE0-0xEF
  2351. case 0xE0: write(0xFF00 + op_read(), A); break;//LDH (n),A
  2352. case 0xE1: H = read(SP + 1); L = read(SP); SP += 2; break; //POP HL
  2353. case 0xE2: write(0xFF00 + C, A); break;//LDH (C),A
  2354. case 0xE5: SP -= 2; writew(SP, HL); break; //PUSH HL
  2355. case 0xE6: tmpb = op_read(); AND(tmpb); break; //AND A,n : 11 100 110 :state 7
  2356. case 0xE7: SP -= 2; writew(SP, PC); PC = 0x20;break; //RST 0x20
  2357. case 0xE8: SP += op_read_s(); break;//ADD SP,n
  2358. case 0xE9: PC = HL; break; //JP HL : state 4
  2359. case 0xEA: write(op_readw(), A); break;//LD (mn),A
  2360. case 0xEE: tmpb = op_read(); XOR(tmpb); break; //XOR A,n : 11 101 110 :state 7
  2361. case 0xEF: SP -= 2; writew(SP, PC); PC = 0x28;break; //RST 0x28
  2362. // 0xF0-0xFF
  2363. case 0xF0: A = read(0xFF00 + op_read()); break;//LDH A,(n)
  2364. case 0xF1: A = read(SP + 1); F = gb2z80[read(SP) & 0xF0]; SP += 2; break; //POP AF
  2365. case 0xF2: A = read(0xFF00 + C); break;//LDH A,(c)
  2366. case 0xF3: I = 0; break; //DI : state 4
  2367. case 0xF5: write(SP - 2, z802gb[F] | 0xE); write(SP - 1, A); SP -= 2; break; //PUSH AF
  2368. case 0xF6: tmpb = op_read(); OR(tmpb); break; //OR A,n : 11 110 110 :state 7
  2369. case 0xF7: SP -= 2; writew(SP, PC); PC = 0x30;break; //RST 0x30
  2370. case 0xF8: HL = SP + op_read_s(); break;//LD HL,SP+n
  2371. case 0xF9: SP = HL; break; //LD SP,HL : 11 111 001 :state 6
  2372. case 0xFA: A = read(op_readw()); break;//LD A,(mn);
  2373. case 0xFB: I = 1; int_desable = true; break; //EI : state 4
  2374. case 0xFE: tmpb = op_read(); CP(tmpb); break; //CP A,n : 11 111 110 :state 7
  2375. case 0xFF: SP -= 2; writew(SP, PC); PC = 0x38;break; //RST 0x38
  2376. }
  2377. rest_clock -= tmp_clocks;
  2378. div_clock += tmp_clocks;
  2379. total_clock += tmp_clocks;
  2380. if (TAC & 0x04) { //タイマ割りこみ
  2381. sys_clock += tmp_clocks;
  2382. if (sys_clock > timer_clocks[TAC & 0x03]) {
  2383. sys_clock &= timer_clocks[TAC & 0x03] - 1;
  2384. TIMA++;
  2385. if (!TIMA) {
  2386. irq(INT_TIMER);
  2387. TIMA= TMA;
  2388. }
  2389. }
  2390. }
  2391. if (div_clock >= 0x100) {
  2392. DIV -= div_clock >> 8;
  2393. div_clock &= 0xff;
  2394. }
  2395. }
  2396. }
  2397. public function exec():void
  2398. {
  2399. for (var line:uint = 0; line < 154; line++) {
  2400. if (LCDC & 0x80) { // LCDC 起動時
  2401. LY = (LY + 1) % 154;
  2402. STAT &= 0xF8;
  2403. if (LYC == LY) {
  2404. STAT |= 4;
  2405. if (STAT & 0x40)
  2406. irq(INT_LCDC);
  2407. }
  2408. if (LY == 0) {
  2409. return;
  2410. }
  2411. if (LY >= 144) { // VBlank 期間中
  2412. STAT |= 1;
  2413. if (LY == 144) {
  2414. ex(72);
  2415. irq(INT_VBLANK);
  2416. if (STAT & 0x10)
  2417. irq(INT_LCDC);
  2418. ex(456 - 80);
  2419. }
  2420. else if (LY == 153) {
  2421. ex(80);
  2422. LY = 0;
  2423. ex(456 - 80);
  2424. LY = 153;
  2425. }
  2426. else
  2427. ex(456);
  2428. }
  2429. else{ // VBlank 期間外
  2430. STAT |= 2;
  2431. if (STAT & 0x20)
  2432. irq(INT_LCDC);
  2433. ex(80); // state=2
  2434. STAT |= 3;
  2435. ex(169); // state=3
  2436. STAT &= 0xfc;
  2437. if (STAT & 0x08)
  2438. irq(INT_LCDC);
  2439. ex(207); // state=0
  2440. }
  2441. }
  2442. else{ // LCDC 停止時
  2443. LY = 0;
  2444. STAT &= 0xF8;
  2445. ex(456);
  2446. }
  2447. }
  2448. }
  2449. private function exec_0xCB():void
  2450. {
  2451. var opcode:uint;
  2452. var tmpb:uint = 0;
  2453. opcode = read(PC++);
  2454. tmp_clocks = cys_cb[opcode];
  2455. switch (opcode)
  2456. {
  2457. case 0x40: F=((F&CF)|HF)|(((B<<6)&0x40)^0x40);break; //BIT 0,B
  2458. case 0x41: F=((F&CF)|HF)|(((C<<6)&0x40)^0x40);break; //BIT 0,C
  2459. case 0x42: F=((F&CF)|HF)|(((D<<6)&0x40)^0x40);break; //BIT 0,D
  2460. case 0x43: F=((F&CF)|HF)|(((E<<6)&0x40)^0x40);break; //BIT 0,E
  2461. case 0x44: F=((F&CF)|HF)|(((H<<6)&0x40)^0x40);break; //BIT 0,H
  2462. case 0x45: F=((F&CF)|HF)|(((L<<6)&0x40)^0x40);break; //BIT 0,L
  2463. case 0x47: F=((F&CF)|HF)|(((A<<6)&0x40)^0x40);break; //BIT 0,A
  2464. case 0x48: F=((F&CF)|HF)|(((B<<5)&0x40)^0x40);break; //BIT 1,B
  2465. case 0x49: F=((F&CF)|HF)|(((C<<5)&0x40)^0x40);break; //BIT 1,C
  2466. case 0x4A: F=((F&CF)|HF)|(((D<<5)&0x40)^0x40);break; //BIT 1,D
  2467. case 0x4B: F=((F&CF)|HF)|(((E<<5)&0x40)^0x40);break; //BIT 1,E
  2468. case 0x4C: F=((F&CF)|HF)|(((H<<5)&0x40)^0x40);break; //BIT 1,H
  2469. case 0x4D: F=((F&CF)|HF)|(((L<<5)&0x40)^0x40);break; //BIT 1,L
  2470. case 0x4F: F=((F&CF)|HF)|(((A<<5)&0x40)^0x40);break; //BIT 1,A
  2471. case 0x50: F=((F&CF)|HF)|(((B<<4)&0x40)^0x40);break; //BIT 2,B
  2472. case 0x51: F=((F&CF)|HF)|(((C<<4)&0x40)^0x40);break; //BIT 2,C
  2473. case 0x52: F=((F&CF)|HF)|(((D<<4)&0x40)^0x40);break; //BIT 2,D
  2474. case 0x53: F=((F&CF)|HF)|(((E<<4)&0x40)^0x40);break; //BIT 2,E
  2475. case 0x54: F=((F&CF)|HF)|(((H<<4)&0x40)^0x40);break; //BIT 2,H
  2476. case 0x55: F=((F&CF)|HF)|(((L<<4)&0x40)^0x40);break; //BIT 2,L
  2477. case 0x57: F=((F&CF)|HF)|(((A<<4)&0x40)^0x40);break; //BIT 2,A
  2478. case 0x58: F=((F&CF)|HF)|(((B<<3)&0x40)^0x40);break; //BIT 3,B
  2479. case 0x59: F=((F&CF)|HF)|(((C<<3)&0x40)^0x40);break; //BIT 3,C
  2480. case 0x5A: F=((F&CF)|HF)|(((D<<3)&0x40)^0x40);break; //BIT 3,D
  2481. case 0x5B: F=((F&CF)|HF)|(((E<<3)&0x40)^0x40);break; //BIT 3,E
  2482. case 0x5C: F=((F&CF)|HF)|(((H<<3)&0x40)^0x40);break; //BIT 3,H
  2483. case 0x5D: F=((F&CF)|HF)|(((L<<3)&0x40)^0x40);break; //BIT 3,L
  2484. case 0x5F: F=((F&CF)|HF)|(((A<<3)&0x40)^0x40);break; //BIT 3,A
  2485. case 0x60: F=((F&CF)|HF)|(((B<<2)&0x40)^0x40);break; //BIT 4,B
  2486. case 0x61: F=((F&CF)|HF)|(((C<<2)&0x40)^0x40);break; //BIT 4,C
  2487. case 0x62: F=((F&CF)|HF)|(((D<<2)&0x40)^0x40);break; //BIT 4,D
  2488. case 0x63: F=((F&CF)|HF)|(((E<<2)&0x40)^0x40);break; //BIT 4,E
  2489. case 0x64: F=((F&CF)|HF)|(((H<<2)&0x40)^0x40);break; //BIT 4,H
  2490. case 0x65: F=((F&CF)|HF)|(((L<<2)&0x40)^0x40);break; //BIT 4,L
  2491. case 0x67: F=((F&CF)|HF)|(((A<<2)&0x40)^0x40);break; //BIT 4,A
  2492. case 0x68: F=((F&CF)|HF)|(((B<<1)&0x40)^0x40);break; //BIT 5,B
  2493. case 0x69: F=((F&CF)|HF)|(((C<<1)&0x40)^0x40);break; //BIT 5,C
  2494. case 0x6A: F=((F&CF)|HF)|(((D<<1)&0x40)^0x40);break; //BIT 5,D
  2495. case 0x6B: F=((F&CF)|HF)|(((E<<1)&0x40)^0x40);break; //BIT 5,E
  2496. case 0x6C: F=((F&CF)|HF)|(((H<<1)&0x40)^0x40);break; //BIT 5,H
  2497. case 0x6D: F=((F&CF)|HF)|(((L<<1)&0x40)^0x40);break; //BIT 5,L
  2498. case 0x6F: F=((F&CF)|HF)|(((A<<1)&0x40)^0x40);break; //BIT 5,A
  2499. case 0x70: F=((F&CF)|HF)|(((B)&0x40)^0x40);break; //BIT 6,B
  2500. case 0x71: F=((F&CF)|HF)|(((C)&0x40)^0x40);break; //BIT 6,C
  2501. case 0x72: F=((F&CF)|HF)|(((D)&0x40)^0x40);break; //BIT 6,D
  2502. case 0x73: F=((F&CF)|HF)|(((E)&0x40)^0x40);break; //BIT 6,E
  2503. case 0x74: F=((F&CF)|HF)|(((H)&0x40)^0x40);break; //BIT 6,H
  2504. case 0x75: F=((F&CF)|HF)|(((L)&0x40)^0x40);break; //BIT 6,L
  2505. case 0x77: F=((F&CF)|HF)|(((A)&0x40)^0x40);break; //BIT 6,A
  2506. case 0x78: F=((F&CF)|HF)|(((B>>1)&0x40)^0x40);break; //BIT 7,B
  2507. case 0x79: F=((F&CF)|HF)|(((C>>1)&0x40)^0x40);break; //BIT 7,C
  2508. case 0x7A: F=((F&CF)|HF)|(((D>>1)&0x40)^0x40);break; //BIT 7,D
  2509. case 0x7B: F=((F&CF)|HF)|(((E>>1)&0x40)^0x40);break; //BIT 7,E
  2510. case 0x7C: F=((F&CF)|HF)|(((H>>1)&0x40)^0x40);break; //BIT 7,H
  2511. case 0x7D: F=((F&CF)|HF)|(((L>>1)&0x40)^0x40);break; //BIT 7,L
  2512. case 0x7F: F=((F&CF)|HF)|(((A>>1)&0x40)^0x40);break; //BIT 7,A
  2513. //state 12
  2514. case 0x46: tmpb=read(HL);F=((F&CF)|HF)|(((tmpb<<6)&0x40)^0x40);break; //BIT 0,(HL)
  2515. case 0x4E: tmpb=read(HL);F=((F&CF)|HF)|(((tmpb<<5)&0x40)^0x40);break; //BIT 1,(HL)
  2516. case 0x56: tmpb=read(HL);F=((F&CF)|HF)|(((tmpb<<4)&0x40)^0x40);break; //BIT 2,(HL)
  2517. case 0x5E: tmpb=read(HL);F=((F&CF)|HF)|(((tmpb<<3)&0x40)^0x40);break; //BIT 3,(HL)
  2518. case 0x66: tmpb=read(HL);F=((F&CF)|HF)|(((tmpb<<2)&0x40)^0x40);break; //BIT 4,(HL)
  2519. case 0x6E: tmpb=read(HL);F=((F&CF)|HF)|(((tmpb<<1)&0x40)^0x40);break; //BIT 5,(HL)
  2520. case 0x76: tmpb=read(HL);F=((F&CF)|HF)|(((tmpb)&0x40)^0x40);break; //BIT 6,(HL)
  2521. case 0x7E: tmpb=read(HL);F=((F&CF)|HF)|(((tmpb>>1)&0x40)^0x40);break; //BIT 7,(HL)
  2522. //bit set opcode
  2523. //SET b,r :11 b r : state 8
  2524. case 0xC0: B|=0x01;break; //SET 0,B
  2525. case 0xC1: C|=0x01;break; //SET 0,C
  2526. case 0xC2: D|=0x01;break; //SET 0,D
  2527. case 0xC3: E|=0x01;break; //SET 0,E
  2528. case 0xC4: H|=0x01;break; //SET 0,H
  2529. case 0xC5: L|=0x01;break; //SET 0,L
  2530. case 0xC7: A|=0x01;break; //SET 0,A
  2531. case 0xC8: B|=0x02;break; //SET 1,B
  2532. case 0xC9: C|=0x02;break; //SET 1,C
  2533. case 0xCA: D|=0x02;break; //SET 1,D
  2534. case 0xCB: E|=0x02;break; //SET 1,E
  2535. case 0xCC: H|=0x02;break; //SET 1,H
  2536. case 0xCD: L|=0x02;break; //SET 1,L
  2537. case 0xCF: A|=0x02;break; //SET 1,A
  2538. case 0xD0: B|=0x04;break; //SET 2,B
  2539. case 0xD1: C|=0x04;break; //SET 2,C
  2540. case 0xD2: D|=0x04;break; //SET 2,D
  2541. case 0xD3: E|=0x04;break; //SET 2,E
  2542. case 0xD4: H|=0x04;break; //SET 2,H
  2543. case 0xD5: L|=0x04;break; //SET 2,L
  2544. case 0xD7: A|=0x04;break; //SET 2,A
  2545. case 0xD8: B|=0x08;break; //SET 3,B
  2546. case 0xD9: C|=0x08;break; //SET 3,C
  2547. case 0xDA: D|=0x08;break; //SET 3,D
  2548. case 0xDB: E|=0x08;break; //SET 3,E
  2549. case 0xDC: H|=0x08;break; //SET 3,H
  2550. case 0xDD: L|=0x08;break; //SET 3,L
  2551. case 0xDF: A|=0x08;break; //SET 3,A
  2552. case 0xE0: B|=0x10;break; //SET 4,B
  2553. case 0xE1: C|=0x10;break; //SET 4,C
  2554. case 0xE2: D|=0x10;break; //SET 4,D
  2555. case 0xE3: E|=0x10;break; //SET 4,E
  2556. case 0xE4: H|=0x10;break; //SET 4,H
  2557. case 0xE5: L|=0x10;break; //SET 4,L
  2558. case 0xE7: A|=0x10;break; //SET 4,A
  2559. case 0xE8: B|=0x20;break; //SET 5,B
  2560. case 0xE9: C|=0x20;break; //SET 5,C
  2561. case 0xEA: D|=0x20;break; //SET 5,D
  2562. case 0xEB: E|=0x20;break; //SET 5,E
  2563. case 0xEC: H|=0x20;break; //SET 5,H
  2564. case 0xED: L|=0x20;break; //SET 5,L
  2565. case 0xEF: A|=0x20;break; //SET 5,A
  2566. case 0xF0: B|=0x40;break; //SET 6,B
  2567. case 0xF1: C|=0x40;break; //SET 6,C
  2568. case 0xF2: D|=0x40;break; //SET 6,D
  2569. case 0xF3: E|=0x40;break; //SET 6,E
  2570. case 0xF4: H|=0x40;break; //SET 6,H
  2571. case 0xF5: L|=0x40;break; //SET 6,L
  2572. case 0xF7: A|=0x40;break; //SET 6,A
  2573. case 0xF8: B|=0x80;break; //SET 7,B
  2574. case 0xF9: C|=0x80;break; //SET 7,C
  2575. case 0xFA: D|=0x80;break; //SET 7,D
  2576. case 0xFB: E|=0x80;break; //SET 7,E
  2577. case 0xFC: H|=0x80;break; //SET 7,H
  2578. case 0xFD: L|=0x80;break; //SET 7,L
  2579. case 0xFF: A|=0x80;break; //SET 7,A
  2580. //state 16
  2581. case 0xC6: tmpb=read(HL);tmpb|=0x01;write(HL,tmpb);break; //SET 0,(HL)
  2582. case 0xCE: tmpb=read(HL);tmpb|=0x02;write(HL,tmpb);break; //SET 1,(HL)
  2583. case 0xD6: tmpb=read(HL);tmpb|=0x04;write(HL,tmpb);break; //SET 2,(HL)
  2584. case 0xDE: tmpb=read(HL);tmpb|=0x08;write(HL,tmpb);break; //SET 3,(HL)
  2585. case 0xE6: tmpb=read(HL);tmpb|=0x10;write(HL,tmpb);break; //SET 4,(HL)
  2586. case 0xEE: tmpb=read(HL);tmpb|=0x20;write(HL,tmpb);break; //SET 5,(HL)
  2587. case 0xF6: tmpb=read(HL);tmpb|=0x40;write(HL,tmpb);break; //SET 6,(HL)
  2588. case 0xFE: tmpb=read(HL);tmpb|=0x80;write(HL,tmpb);break; //SET 7,(HL)
  2589. //bit reset opcode
  2590. //RES b,r : 10 b r : state 8
  2591. case 0x80: B&=0xFE;break; //RES 0,B
  2592. case 0x81: C&=0xFE;break; //RES 0,C
  2593. case 0x82: D&=0xFE;break; //RES 0,D
  2594. case 0x83: E&=0xFE;break; //RES 0,E
  2595. case 0x84: H&=0xFE;break; //RES 0,H
  2596. case 0x85: L&=0xFE;break; //RES 0,L
  2597. case 0x87: A&=0xFE;break; //RES 0,A
  2598. case 0x88: B&=0xFD;break; //RES 1,B
  2599. case 0x89: C&=0xFD;break; //RES 1,C
  2600. case 0x8A: D&=0xFD;break; //RES 1,D
  2601. case 0x8B: E&=0xFD;break; //RES 1,E
  2602. case 0x8C: H&=0xFD;break; //RES 1,H
  2603. case 0x8D: L&=0xFD;break; //RES 1,L
  2604. case 0x8F: A&=0xFD;break; //RES 1,A
  2605. case 0x90: B&=0xFB;break; //RES 2,B
  2606. case 0x91: C&=0xFB;break; //RES 2,C
  2607. case 0x92: D&=0xFB;break; //RES 2,D
  2608. case 0x93: E&=0xFB;break; //RES 2,E
  2609. case 0x94: H&=0xFB;break; //RES 2,H
  2610. case 0x95: L&=0xFB;break; //RES 2,L
  2611. case 0x97: A&=0xFB;break; //RES 2,A
  2612. case 0x98: B&=0xF7;break; //RES 3,B
  2613. case 0x99: C&=0xF7;break; //RES 3,C
  2614. case 0x9A: D&=0xF7;break; //RES 3,D
  2615. case 0x9B: E&=0xF7;break; //RES 3,E
  2616. case 0x9C: H&=0xF7;break; //RES 3,H
  2617. case 0x9D: L&=0xF7;break; //RES 3,L
  2618. case 0x9F: A&=0xF7;break; //RES 3,A
  2619. case 0xA0: B&=0xEF;break; //RES 4,B
  2620. case 0xA1: C&=0xEF;break; //RES 4,C
  2621. case 0xA2: D&=0xEF;break; //RES 4,D
  2622. case 0xA3: E&=0xEF;break; //RES 4,E
  2623. case 0xA4: H&=0xEF;break; //RES 4,H
  2624. case 0xA5: L&=0xEF;break; //RES 4,L
  2625. case 0xA7: A&=0xEF;break; //RES 4,A
  2626. case 0xA8: B&=0xDF;break; //RES 5,B
  2627. case 0xA9: C&=0xDF;break; //RES 5,C
  2628. case 0xAA: D&=0xDF;break; //RES 5,D
  2629. case 0xAB: E&=0xDF;break; //RES 5,E
  2630. case 0xAC: H&=0xDF;break; //RES 5,H
  2631. case 0xAD: L&=0xDF;break; //RES 5,L
  2632. case 0xAF: A&=0xDF;break; //RES 5,A
  2633. case 0xB0: B&=0xBF;break; //RES 6,B
  2634. case 0xB1: C&=0xBF;break; //RES 6,C
  2635. case 0xB2: D&=0xBF;break; //RES 6,D
  2636. case 0xB3: E&=0xBF;break; //RES 6,E
  2637. case 0xB4: H&=0xBF;break; //RES 6,H
  2638. case 0xB5: L&=0xBF;break; //RES 6,L
  2639. case 0xB7: A&=0xBF;break; //RES 6,A
  2640. case 0xB8: B&=0x7F;break; //RES 7,B
  2641. case 0xB9: C&=0x7F;break; //RES 7,C
  2642. case 0xBA: D&=0x7F;break; //RES 7,D
  2643. case 0xBB: E&=0x7F;break; //RES 7,E
  2644. case 0xBC: H&=0x7F;break; //RES 7,H
  2645. case 0xBD: L&=0x7F;break; //RES 7,L
  2646. case 0xBF: A&=0x7F;break; //RES 7,A
  2647. //state 16
  2648. case 0x86: tmpb=read(HL);tmpb&=0xFE;write(HL,tmpb);break; //RES 0,(HL)
  2649. case 0x8E: tmpb=read(HL);tmpb&=0xFD;write(HL,tmpb);break; //RES 1,(HL)
  2650. case 0x96: tmpb=read(HL);tmpb&=0xFB;write(HL,tmpb);break; //RES 2,(HL)
  2651. case 0x9E: tmpb=read(HL);tmpb&=0xF7;write(HL,tmpb);break; //RES 3,(HL)
  2652. case 0xA6: tmpb=read(HL);tmpb&=0xEF;write(HL,tmpb);break; //RES 4,(HL)
  2653. case 0xAE: tmpb=read(HL);tmpb&=0xDF;write(HL,tmpb);break; //RES 5,(HL)
  2654. case 0xB6: tmpb=read(HL);tmpb&=0xBF;write(HL,tmpb);break; //RES 6,(HL)
  2655. case 0xBE: tmpb=read(HL);tmpb&=0x7F;write(HL,tmpb);break; //RES 7,(HL)
  2656. //shift rotate opcode
  2657. //RLC s : 00 000 r : state 8
  2658. case 0x00: F = (B >> 7); B = (B << 1) | (F); B &= 0xFF; F |= ZTable[B]; break;//RLC B
  2659. case 0x01: F = (C >> 7); C = (C << 1) | (F); C &= 0xFF; F |= ZTable[C]; break;//RLC C
  2660. case 0x02: F = (D >> 7); D = (D << 1) | (F); D &= 0xFF; F |= ZTable[D]; break;//RLC D
  2661. case 0x03: F = (E >> 7); E = (E << 1) | (F); E &= 0xFF; F |= ZTable[E]; break;//RLC E
  2662. case 0x04: F = (H >> 7); H = (H << 1) | (F); H &= 0xFF; F |= ZTable[H]; break;//RLC H
  2663. case 0x05: F = (L >> 7); L = (L << 1) | (F); L &= 0xFF; F |= ZTable[L]; break;//RLC L
  2664. case 0x07: F = (A >> 7); A = (A << 1) | (F); A &= 0xFF; F |= ZTable[A]; break;//RLC A
  2665. case 0x06: tmpb = read(HL); F = (tmpb >> 7); tmpb = (tmpb << 1) | (F); tmpb &= 0xFF; F |= ZTable[tmpb]; write(HL, tmpb); break;//RLC (HL) : state 16
  2666. //RRC s : 00 001 r : state 8
  2667. case 0x08: F=(B&0x01);B=(B>>1)|(F<<7);B &= 0xFF;F|=ZTable[B];break;//RRC B
  2668. case 0x09: F=(C&0x01);C=(C>>1)|(F<<7);C &= 0xFF;F|=ZTable[C];break;//RRC C
  2669. case 0x0A: F=(D&0x01);D=(D>>1)|(F<<7);D &= 0xFF;F|=ZTable[D];break;//RRC D
  2670. case 0x0B: F=(E&0x01);E=(E>>1)|(F<<7);E &= 0xFF;F|=ZTable[E];break;//RRC E
  2671. case 0x0C: F=(H&0x01);H=(H>>1)|(F<<7);H &= 0xFF;F|=ZTable[H];break;//RRC H
  2672. case 0x0D: F=(L&0x01);L=(L>>1)|(F<<7);L &= 0xFF;F|=ZTable[L];break;//RRC L
  2673. case 0x0F: F=(A&0x01);A=(A>>1)|(F<<7);A &= 0xFF;F|=ZTable[A];break;//RRC A
  2674. case 0x0E: tmpb=read(HL);F=(tmpb&0x01);tmpb=(tmpb>>1)|(F<<7);tmpb &= 0xFF;F|=ZTable[tmpb];write(HL,tmpb);break;//RRC (HL) :state 16
  2675. //RL s : 00 010 r : state 8
  2676. case 0x10: tmpb = F & 0x01; F = (B >> 7); B = (B << 1) | tmpb; B &= 0xFF; F |= ZTable[B]; break;//RL B
  2677. case 0x11: tmpb = F & 0x01; F = (C >> 7); C = (C << 1) | tmpb; C &= 0xFF; F |= ZTable[C]; break;//RL C
  2678. case 0x12: tmpb = F & 0x01; F = (D >> 7); D = (D << 1) | tmpb; D &= 0xFF; F |= ZTable[D]; break;//RL D
  2679. case 0x13: tmpb = F & 0x01; F = (E >> 7); E = (E << 1) | tmpb; E &= 0xFF; F |= ZTable[E]; break;//RL E
  2680. case 0x14: tmpb = F & 0x01; F = (H >> 7); H = (H << 1) | tmpb; H &= 0xFF; F |= ZTable[H]; break;//RL H
  2681. case 0x15: tmpb = F & 0x01; F = (L >> 7); L = (L << 1) | tmpb; L &= 0xFF; F |= ZTable[L]; break;//RL L
  2682. case 0x17: tmpb = F & 0x01; F = (A >> 7); A = (A << 1) | tmpb; A &= 0xFF; F |= ZTable[A]; break;//RL A
  2683. case 0x16: //RL (HL) :state 16
  2684. tmpb = read(HL);
  2685. tmpb |= ((F & 0x01) << 8);
  2686. F = ((tmpb >> 7) & 0x01);
  2687. tmpb = ((tmpb << 1) & 0xFE) | ((tmpb >> 8) & 0x01);
  2688. tmpb &= 0xFF;
  2689. F |= ZTable[tmpb];
  2690. write(HL, tmpb);
  2691. break;
  2692. //RR s : 00 011 r : state 8
  2693. case 0x18: tmpb=F&0x01;F=(B&0x01);B=(B>>1)|(tmpb<<7);F|=ZTable[B];break;//RR B
  2694. case 0x19: tmpb=F&0x01;F=(C&0x01);C=(C>>1)|(tmpb<<7);F|=ZTable[C];break;//RR C
  2695. case 0x1A: tmpb=F&0x01;F=(D&0x01);D=(D>>1)|(tmpb<<7);F|=ZTable[D];break;//RR D
  2696. case 0x1B: tmpb=F&0x01;F=(E&0x01);E=(E>>1)|(tmpb<<7);F|=ZTable[E];break;//RR E
  2697. case 0x1C: tmpb=F&0x01;F=(H&0x01);H=(H>>1)|(tmpb<<7);F|=ZTable[H];break;//RR H
  2698. case 0x1D: tmpb=F&0x01;F=(L&0x01);L=(L>>1)|(tmpb<<7);F|=ZTable[L];break;//RR L
  2699. case 0x1F: tmpb=F&0x01;F=(A&0x01);A=(A>>1)|(tmpb<<7);F|=ZTable[A];break;//RR A
  2700. case 0x1E: //RR (HL) :state 16
  2701. tmpb = read(HL);
  2702. tmpb |= ((F & 0x01) << 8);
  2703. F = (tmpb & 0x01);
  2704. tmpb = ((tmpb >> 1) & 0xFF);
  2705. F |= ZTable[tmpb];
  2706. write(HL, tmpb);
  2707. break;
  2708. //SLA s : 00 100 r : state 8
  2709. case 0x20: F = B >> 7; B <<= 1; B &= 0xFF; F |= ZTable[B]; break;//SLA B
  2710. case 0x21: F = C >> 7; C <<= 1; C &= 0xFF; F |= ZTable[C]; break;//SLA C
  2711. case 0x22: F = D >> 7; D <<= 1; D &= 0xFF; F |= ZTable[D]; break;//SLA D
  2712. case 0x23: F = E >> 7; E <<= 1; E &= 0xFF; F |= ZTable[E]; break;//SLA E
  2713. case 0x24: F = H >> 7; H <<= 1; H &= 0xFF; F |= ZTable[H]; break;//SLA H
  2714. case 0x25: F = L >> 7; L <<= 1; L &= 0xFF; F |= ZTable[L]; break;//SLA L
  2715. case 0x27: F = A >> 7; A <<= 1; A &= 0xFF; F |= ZTable[A]; break;//SLA A
  2716. case 0x26: tmpb = read(HL); F = tmpb >> 7; tmpb <<= 1; tmpb &= 0xFF; F |= ZTable[tmpb]; write(HL, tmpb); break;//SLA (HL) :state 16
  2717. //SRA s : 00 101 r : state 8
  2718. case 0x28: F=B&0x01;B=(B>>1)|(B&0x80);F|=ZTable[B];break;//SRA B
  2719. case 0x29: F=C&0x01;C=(C>>1)|(C&0x80);F|=ZTable[C];break;//SRA C
  2720. case 0x2A: F=D&0x01;D=(D>>1)|(D&0x80);F|=ZTable[D];break;//SRA D
  2721. case 0x2B: F=E&0x01;E=(E>>1)|(E&0x80);F|=ZTable[E];break;//SRA E
  2722. case 0x2C: F=H&0x01;H=(H>>1)|(H&0x80);F|=ZTable[H];break;//SRA H
  2723. case 0x2D: F=L&0x01;L=(L>>1)|(L&0x80);F|=ZTable[L];break;//SRA L
  2724. case 0x2F: F=A&0x01;A=(A>>1)|(A&0x80);F|=ZTable[A];break;//SRA A
  2725. case 0x2E: tmpb=read(HL);F=tmpb&0x01;tmpb>>=1;tmpb|=(tmpb<<1)&0x80;F|=ZTable[tmpb];write(HL,tmpb);break;//SRA (HL) :state 16
  2726. //SRL s : 00 111 r : state 8
  2727. case 0x38: F=B&0x01;B>>=1;F|=ZTable[B];break;//SRL B
  2728. case 0x39: F=C&0x01;C>>=1;F|=ZTable[C];break;//SRL C
  2729. case 0x3A: F=D&0x01;D>>=1;F|=ZTable[D];break;//SRL D
  2730. case 0x3B: F=E&0x01;E>>=1;F|=ZTable[E];break;//SRL E
  2731. case 0x3C: F=H&0x01;H>>=1;F|=ZTable[H];break;//SRL H
  2732. case 0x3D: F=L&0x01;L>>=1;F|=ZTable[L];break;//SRL L
  2733. case 0x3F: F=A&0x01;A>>=1;F|=ZTable[A];break;//SRL A
  2734. case 0x3E: tmpb=read(HL);F=tmpb&0x01;tmpb>>=1;F|=ZTable[tmpb];write(HL,tmpb);break;//SRL (HL) :state 16
  2735. //swap opcode
  2736. //SWAP n : 00 110 r :state 8
  2737. case 0x30: B = (B >> 4) | (B << 4); B &= 0xFF; F = ZTable[B]; break;//SWAP B
  2738. case 0x31: C = (C >> 4) | (C << 4); C &= 0xFF; F = ZTable[C]; break;//SWAP C
  2739. case 0x32: D = (D >> 4) | (D << 4); D &= 0xFF; F = ZTable[D]; break;//SWAP D
  2740. case 0x33: E = (E >> 4) | (E << 4); E &= 0xFF; F = ZTable[E]; break;//SWAP E
  2741. case 0x34: H = (H >> 4) | (H << 4); H &= 0xFF; F = ZTable[H]; break;//SWAP H
  2742. case 0x35: L = (L >> 4) | (L << 4); L &= 0xFF; F = ZTable[L]; break;//SWAP L
  2743. case 0x37: A = (A >> 4) | (A << 4); A &= 0xFF; F = ZTable[A]; break;//SWAP A
  2744. case 0x36: tmpb = read(HL); tmpb = (tmpb >> 4) | (tmpb << 4); tmpb &= 0xFF; F = ZTable[tmpb]; write(HL, tmpb); break;//SWAP (HL) : state 16
  2745. }
  2746. }
  2747. }
noswf
Get Adobe Flash Player