0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JavaScriptによるPC-8001エミュレータでのタートルグラフィックス円描画

Last updated at Posted at 2025-09-25

9月16日の記事の続きだが、各辺dドットの正p角形で、半径r=d×p/2πの円をエミュレートすることを考える場合、pが4の倍数である方がうれしい。第1象限だけ計算しつつタートルグラフィックス化して、残りはタートルグラフィックスをπ/2ずつ回転させて描画すればいいからだ。

すぐ思いつくのは正12角形で、sin(2π/12)=1/2, cos(2π/12)≒7/8だが、d≦3まで頑張ってもr≦18/π<6までしか描けない。次は正36角形だが、sin(2π/36)≒89/512, cos(2π/36)≒63/64と使いにくく、しかもd≦3まで頑張ってもr≦17である。一方、大きなpとしては正284角形があるが、sin(2π/284)≒181/8192, cos(2π/284)≒4095/4096というクセの強い値で、d≦3だとr≦135まで大丈夫である。

DEレジスタに中心のXY座標、Bレジスタに半径rを渡すと、PC-8001の160×100ドット画面に円を描くZ80プログラムを、以下に示す。XY座標は画面中心を(0,0)としており、左上隅が(B0H,32H)である。なお、円は正284角形でエミュレートしたが、0≦r≦3に関しては事前にタートルグラフィックスを準備した。

E750 3EB0     LD A,B0H      # 円描画
E752 21
E753 3EB5     LD A,B5H      # 円消去
E755 3264E7   LD (E764H),A
E758 78       LD A,B
E759 82      ADD A,D
E75A 57       LD D,A
E75B D5     PUSH DE
E75C CD00E8 CALL E800H
E75F 227BE7   LD (E77BH),HL
E762 D1      POP DE
E763 CDB0E7 CALL E7B0H
E766 D9      EXX
E767 0604     LD B,04H
E769 3E0C     LD A,0CH
E76B 90      SUB A,B
E76C 87      ADD A,A
E76D 87      ADD A,A
E76E 87      ADD A,A
E76F 87      ADD A,A
E770 328BE7   LD (E78BH),A
E773 C610    ADD A,10H
E775 E6B0    AND A,B0H
E777 3299E7   LD (E799H),A
E77A 21F9E5   LD HL,E5F9H
E77D 4E       LD C,(HL)
E77E 79       LD A,C
E77F B7       OR A,A
E780 2003     JR NZ,E785H
E782 10E5   DJNZ E769H
E784 C9      RET
E785 E6F0    AND A,F0H
E787 2809     JR Z,E792H
E789 D9      EXX
E78A CD80E8 CALL E880H
E78D D9      EXX
E78E 79       LD A,C
E78F D610    SUB A,10H
E791 4F       LD C,A
E792 79       LD A,C
E793 E60F    AND A,0FH
E795 2806     JR Z,E79DH
E797 D9      EXX
E798 CD90E8 CALL E890H
E79B D9      EXX
E79C 0D      DEC C
E79D D9      EXX
E79E CDE0E7 CALL E7E0H
E7A1 D9      EXX
E7A2 79       LD A,C
E7A3 B7       OR A,A
E7A4 20DF     JR NZ,E785H
E7A6 2B      DEC HL
E7A7 18D4     JR E77DH

E7B0 2177C9   LD HL,C977H   # 1ドット描画
E7B3 1803     JR E7B8H
E7B5 21A877   LD HL,77A8H   # 1ドット消去
E7B8 22EEE7   LD (E7EEH),HL
E7BB D5     PUSH DE
E7BC 7A       LD A,D
E7BD EE80    XOR A,80H
E7BF 1F      RRA
E7C0 4F       LD C,A
E7C1 7B       LD A,E
E7C2 17      RLA
E7C3 F6F8     OR A,F8H
E7C5 6F       LD L,A
E7C6 26E7     LD H,E7H
E7C8 46       LD B,(HL)
E7C9 3E7E     LD A,7EH
E7CB 93      SUB A,E
E7CC E6FC    AND A,FCH
E7CE 5F       LD E,A
E7CF 2EF7     LD L,F7H
E7D1 73       LD (HL),E
E7D2 AF      XOR A,A
E7D3 57       LD D,A
E7D4 ED6F    RLD
E7D6 6E       LD L,(HL)
E7D7 67       LD H,A
E7D8 ED52    SBC HL,DE
E7DA 29      ADD HL,HL
E7DB 59       LD E,C
E7DC 16EA     LD D,EAH
E7DE 19      ADD HL,DE
E7DF D1      POP DE
E7E0 3ECE     LD A,CEH      # 画面外チェック
E7E2 93      SUB A,E
E7E3 FE9C     CP A,9CH
E7E5 D8      RET C
E7E6 7A       LD A,D
E7E7 C6B0    ADD A,B0H
E7E9 D660    SUB A,60H
E7EB D8      RET C
E7EC 7E       LD A,(HL)
E7ED B0       OR A,B
E7EE 77       LD (HL),A
E7EF C9      RET
E7F0 C9      RET

E7F7 00 04 40 02 20 01 10 08 80

E5F0 00 00 00 00 00 00 00 00 00 00 01 11 11 11 00 11
E600 F9 E5 FF E5 FC E5 FD E5 00 00 00 00 00 00 00 00
E610 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
E620 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
E630 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
E640 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
E650 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
E660 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
E670 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
E680 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
E690 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
E6A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
E6B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
E6C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
E6D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
E6E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
E6F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

E800 78       LD A,B        # タートル作成
E801 87      ADD A,A
E802 6F       LD L,A
E803 26E6     LD H,E6H
E805 5E       LD E.(HL)
E806 2C      INC L
E807 56       LD D,(HL)
E808 EB       EX DE,HL
E809 7C       LD A,H
E80A B5       OR A,L
E80B C0      RET NZ
E80C 2A00E6   LD HL,(E600H)
E80F 2B      DEC HL
E810 2231E8   LD (E831H),HL
E813 EB       EX DE,HL
E814 72       LD (HL),D
E815 2D      DEC L
E816 73       LD (HL),E
E817 111000   LD DE,0010H
E81A 60       LD H,B
E81B 6B       LD L,E
E81C 3E47     LD A,47H
E81E 323CE8   LD (E83CH),A
E821 44       LD B,H
E822 4A       LD C,D
E823 C5     PUSH BC
E824 CD50E8 CALL E850H
E827 C1      POP BC
E828 7A       LD A,D
E829 91      SUB A,C
E82A 87      ADD A,A
E82B 87      ADD A,A
E82C 87      ADD A,A
E82D 87      ADD A,A
E82E 80      ADD A,B
E82F 94      SUB A,H
E830 01F9E5   LD BC,E5F9H
E833 02       LD (BC),A
E834 2805     JR Z,E83BH
E836 0B      DEC BC
E837 ED4331E8 LD (E831H),BC
E83B 3E01     LD A,01H
E83D 3D      DEC A
E83E 20DE     JR NZ,E81EH
E840 02       LD (BC),A
E841 2A00E6   LD HL,(E600H)
E844 ED4300E6 LD (E600H),BC
E848 2B      DEC HL
E849 C9      RET

E850 0602     LD B,02H      # 2π/284回転
E852 E5     PUSH HL
E853 D9      EXX
E854 E1      POP HL
E855 4C       LD C,H
E856 29      ADD HL,HL
E857 9F      SBC A,A
E858 47       LD B,A
E859 29      ADD HL,HL
E85A 17      RLA
E85B 6C       LD L,H
E85C 67       LD H,A
E85D 09      ADD HL,BC
E85E CB29    SRA C
E860 09      ADD HL,BC
E861 CB29    SRA C
E863 CB29    SRA C
E865 09      ADD HL,BC
E866 CB29    SRA C
E868 C5     PUSH BC
E869 CB29    SRA C
E86B 09      ADD HL,BC
E86C E5     PUSH HL
E86D D9      EXX
E86E EB       EX DE,HL
E86F 10E1   DJNZ E852H
E871 C1      POP BC
E872 ED42    SBC HL,BC
E874 EB       EX DE,HL
E875 C1      POP BC
E876 ED42    SBC HL,BC
E878 C1      POP BC
E879 09      ADD HL,BC
E87A EB       EX DE,HL
E87B C1      POP BC
E87C ED42    SBC HL,BC
E87E C9      RET

E880 1C      INC E          # 上1ドット移動
E881 78       LD A,B
E882 CB08    RRC B
E884 E611    AND A,11H
E886 C8      RET Z
E887 0188FF   LD BC,FF88H
E88A 09      ADD HL,BC
E88B 07     RLCA
E88C 07     RLCA
E88D 07     RLCA
E88E 47       LD B,A
E88F C9      RET

E890 15      DEC D          # 左1ドット移動
E891 78       LD A,B
E892 0F     RRCA
E893 0F     RRCA
E894 0F     RRCA
E895 0F     RRCA
E896 47       LD B,A
E897 E6F0    AND A,F0H
E899 C8      RET Z
E89A 2B      DEC HL
E89B C9      RET

E8A0 1D      DEC E          # 下1ドット移動
E8A1 78       LD A,B
E8A2 CB00    RLC B
E8A4 E688    AND A,88H
E8A6 C8      RET Z
E8A7 017800   LD BC,0078H
E8AA 09      ADD HL,BC
E8AB 0F     RRCA
E8AC 0F     RRCA
E8AD 0F     RRCA
E8AE 47       LD B,A
E8AF C9      RET

E8B0 14      INC D          # 右1ドット移動
E8B1 78       LD A,B
E8B2 07     RLCA
E8B3 07     RLCA
E8B4 07     RLCA
E8B5 07     RLCA
E8B6 47       LD B,A
E8B7 E60F    AND A,0FH
E8B9 C8      RET Z
E8BA 23      INC HL
E8BB C9      RET

以下のJavaScriptによるPC-8001エミュレータでは、スペースキーを押すと円の半径を大きくしていくプログラムを書いてみた。半径が大きくなるにつれ、徐々にスピードが遅くなってしまうのだが、ぜひ試してみてほしい。

<!DOCTYPE html><head><meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>PC-8001 Emulator by Koichi Yasuoka, September 25, 2025</title>
<script>
var pc8001=new Object();
pc8001.memory=new Array(65536);
pc8001.memory.fill(0x76);
["0000 C3 00 E7",
 "045A                               C3 50 09",          // clear display
 "093A                               79 32 62 EA 78 32", // init display
 "0940 65 EA C6 B0 3E 14 8F 32 66 EA D3 30 3E 20 D3 51",
 "0950 ED 5B 5A EA 21 00 F3 06 50 73 23 10 FC 70 23 70",
 "0960 23 3A 65 EA C6 B0 9F C6 02 77 23 72 23 01 50 11",
 "0970 71 23 72 23 10 FA 71 23 70 23 11 00 F3 EB 01 B8",
 "0980 0B ED B0 21 01 01 22 63 EA C9",

 "E5F0 00 00 00 00 00 00 00 00 00 00 01 11 11 11 00 11",
 "E600 F9 E5 FF E5 FC E5 FD E5 00 00 00 00 00 00 00 00",
 "E610 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
 "E620 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
 "E630 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
 "E640 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
 "E650 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
 "E660 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
 "E670 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
 "E680 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
 "E690 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
 "E6A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
 "E6B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
 "E6C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
 "E6D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
 "E6E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
 "E6F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",

 "E700 31 FF FF 21 00 B8 22 5A EA 26 FF 22 60 EA AF 32",
 "E710 5F EA 3E 05 32 66 EA 01 19 50 CD 3A 09 11 00 00",
 "E720 06 00 CD 50 E7 DB 09 E6 40 20 FA 11 00 00 3A 21",
 "E730 E7 47 3C FE 60 38 01 AF 32 21 E7 CD 53 E7 18 DD",

 "E750 3E B0 21 3E B5 32 64 E7 78 82 57 D5 CD 00 E8 22",
 "E760 7B E7 D1 CD B0 E7 D9 06 04 3E 0C 90 87 87 87 87",
 "E770 32 8B E7 C6 10 E6 B0 32 99 E7 21 F9 E5 4E 79 B7",
 "E780 20 03 10 E5 C9 E6 F0 28 09 D9 CD 80 E8 D9 79 D6",
 "E790 10 4F 79 E6 0F 28 06 D9 CD 90 E8 D9 0D D9 CD E0",
 "E7A0 E7 D9 79 B7 20 DF 2B 18 D4",
 "E7B0 21 77 C9 18 03 21 A8 77 22 EE E7 D5 7A EE 80 1F",
 "E7C0 4F 7B 17 F6 F8 6F 26 E7 46 3E 7E 93 E6 FC 5F 2E",
 "E7D0 F7 73 AF 57 ED 6F 6E 67 ED 52 29 59 16 EA 19 D1",
 "E7E0 3E CE 93 FE 9C D8 7A C6 B0 D6 60 D8 7E B0 77 C9",
 "E7F0 C9 00 00 00 00 00 00 00 04 40 02 20 01 10 08 80",
 "E800 78 87 6F 26 E6 5E 2C 56 EB 7C B5 C0 2A 00 E6 2B",
 "E810 22 31 E8 EB 72 2D 73 11 10 00 60 6B 3E 47 32 3C",
 "E820 E8 44 4A C5 CD 50 E8 C1 7A 91 87 87 87 87 80 94",
 "E830 01 F9 E5 02 28 05 0B ED 43 31 E8 3E 01 3D 20 DE",
 "E840 02 2A 00 E6 ED 43 00 E6 2B C9",
 "E850 06 02 E5 D9 E1 4C 29 9F 47 29 17 6C 67 09 CB 29",
 "E860 09 CB 29 CB 29 09 CB 29 C5 CB 29 09 E5 D9 EB 10",
 "E870 E1 C1 ED 42 EB C1 ED 42 C1 09 EB C1 ED 42 C9",
 "E880 1C 78 CB 08 E6 11 C8 01 88 FF 09 07 07 07 47 C9",
 "E890 15 78 0F 0F 0F 0F 47 E6 F0 C8 2B C9",
 "E8A0 1D 78 CB 00 E6 88 C8 01 78 00 09 0F 0F 0F 47 C9",
 "E8B0 14 78 07 07 07 07 47 E6 0F C8 23 C9",
 "E8C0 00 00 00 00 00 00 00 00 00 00 00 00 E7 00 00 00"
].forEach(function(v){
  var t=v.split(/ +/);
  var a=parseInt(t[0],16);
  var i;
  for(i=1;i<t.length;i++)
    pc8001.memory[a+i-1]=parseInt(t[i],16);
});
pc8001.font=[
// 0x00 - 0x07
  "-------- -###---- -###---- -###---- -###---- ###----- --#----- -###----",
  "-------- -#------ -#------ -#------ -#------ #------- -#-#---- -#--#---",
  "-------- -###---- -###---- -###---- -###---- ###----- -###---- -###----",
  "-------- ---##-#- ---#--#- -#----#- -#------ #---##-- -#-#--#- -#--#---",
  "-------- -####-#- -###-#-- -###-#-- -######- ####--#- -#-#-#-- -###-#--",
  "-------- ----###- ----#--- ----#--- -----#-- ---#--#- ---##--- -----#--",
  "-------- ----#-#- ---#-#-- ---#-#-- -----#-- ---#--#- ---#-#-- -----#--",
  "-------- ----#-#- --#---#- --#---#- -----#-- ----##-# ---#--#- -----###",
// 0x08 - 0x0f
  "-###---- -#-#---- -#------ -#-#---- --####-- --###--- -###---- -###----",
  "-#--#--- -#-#---- -#------ -#-#---- -#------ -#------ -#------ -#------",
  "-###---- -###---- -#------ -###---- -#------ -#------ -###---- -###----",
  "-#--#### -#-#---- -#--###- -#-#---- -#---#-- --#####- ---#---- ---#----",
  "-###-#-- -#-####- -####--- -#-#---# --###--- ----#--# -#####-- -######-",
  "-----### -----#-- ----##-- ---##-## ----#--- ----###- ---#--#- -----#--",
  "-------# -----#-- ----#--- ---#-#-# ----#--- ----#-#- ---#--#- -----#--",
  "-----### -----#-- ----#--- ---#---# ----#### ----#--# ----##-- ----###-",
// 0x10 - 0x17
  "-###---- -###---- -###---- -###---- -###---- -#--#--- -###---- -###----",
  "-#--#--- -#--#--- -#--#--- -#--#--- -#--#--- -##-#--- -#------ -#------",
  "-#--#--- -#--#--- -#--#--- -#--#--- -#--#--- -#-##--- -###---- -###----",
  "-#--#### -#--#-#- -#--###- -#--#### -#--#-#- -#--#--# ---#---- -#--###-",
  "-###-#-- -###-##- -###---# -###---# -###-##- -#--#-#- -####--# -####--#",
  "-----### ------#- -----##- -----### ----#-#- ----##-- ----##-# ----###-",
  "-----#-- ------#- ----#--- -------# ---##### ----#-#- ----#-## ----#--#",
  "-----### -----### ----#### ----#### ------#- ----#--# ----#--# ----###-",
// 0x18 - 0x1f
  "--###--- -###---- -###---- -###---- -------- -------- -------- --------",
  "-#------ -#------ -#------ -#------ ----#--- ---#---- ----#--- ----#---",
  "-#------ -###---- -###---- -###---- -----#-- --#----- ---###-- ----#---",
  "--###--- -#------ ---###-- -#------ -######- -######- --#-#-#- ----#---",
  "----#--# -###---# -###--#- -######- -----#-- --#----- ----#--- --#-#-#-",
  "----##-# ---##-## ---###-- ---#---- ----#--- ---#---- ----#--- ---###--",
  "----#-## ---#-#-# ---#--#- ---#---- -------- -------- ----#--- ----#---",
  "----#--# ---#---# ---###-- ----###- -------- -------- -------- --------",
// 0x20 - 0x27
  "-------- ----#--- --#--#-- --#--#-- ----#--- -------- --##---- -----#--",
  "-------- ----#--- --#--#-- --#--#-- ---####- -##---#- -#--#--- ----#---",
  "-------- ----#--- --#--#-- -######- --#-#--- -##--#-- -#--#--- ---#----",
  "-------- ----#--- -------- --#--#-- ---###-- ----#--- --##---- --------",
  "-------- -------- -------- -######- ----#-#- ---#---- -#--#-#- --------",
  "-------- -------- -------- --#--#-- --####-- --#--##- -#---#-- --------",
  "-------- ----#--- -------- --#--#-- ----#--- -#---##- --###-#- --------",
  "-------- -------- -------- -------- -------- -------- -------- --------",
// 0x28 - 0x2f
  "-----#-- --#----- ----#--- -------- -------- -------- -------- --------",
  "----#--- ---#---- --#-#-#- ----#--- -------- -------- -------- ------#-",
  "---#---- ----#--- ---###-- ----#--- -------- -------- -------- -----#--",
  "---#---- ----#--- --#####- --#####- -------- -######- -------- ----#---",
  "---#---- ----#--- ---###-- ----#--- -------- -------- -------- ---#----",
  "----#--- ---#---- --#-#-#- ----#--- ----#--- -------- ---##--- --#-----",
  "-----#-- --#----- ----#--- -------- ----#--- -------- ---##--- -#------",
  "-------- -------- -------- -------- ---#---- -------- -------- --------",
// 0x30 - 0x37
  "--####-- ----#--- --####-- --####-- -----#-- -######- ---###-- -######-",
  "-#----#- ---##--- -#----#- -#----#- ----##-- -#------ --#----- -#----#-",
  "-#---##- --#-#--- ------#- ------#- ---#-#-- -####--- -#------ -----#--",
  "-#-##-#- ----#--- ----##-- ---###-- --#--#-- -----#-- -#####-- ----#---",
  "-##---#- ----#--- --##---- ------#- -######- ------#- -#----#- ---#----",
  "-#----#- ----#--- -#------ -#----#- -----#-- -#---#-- -#----#- ---#----",
  "--####-- --#####- -######- --####-- -----#-- --###--- --####-- ---#----",
  "-------- -------- -------- -------- -------- -------- -------- --------",
// 0x38 - 0x3f
  "--####-- --####-- -------- -------- ----###- -------- -###---- --####--",
  "-#----#- -#----#- -------- -------- ---##--- -------- ---##--- -#----#-",
  "-#----#- -#----#- ----#--- ----#--- --##---- -######- ----##-- ------#-",
  "--####-- --#####- -------- -------- -##----- -------- -----##- ----##--",
  "-#----#- ------#- -------- -------- --##---- -######- ----##-- ---#----",
  "-#----#- -----#-- ----#--- ----#--- ---##--- -------- ---##--- --------",
  "--####-- --###--- -------- ----#--- ----###- -------- -###---- ---#----",
  "-------- -------- -------- ---#---- -------- -------- -------- --------",
// 0x40 - 0x47
  "---###-- ---##--- -#####-- ---###-- -####--- -######- -######- ---###--",
  "--#---#- --#--#-- --#---#- --#---#- --#--#-- -#------ -#------ --#---#-",
  "-#--#-#- -#----#- --#---#- -#------ --#---#- -#------ -#------ -#------",
  "-#-#-##- -######- --####-- -#------ --#---#- -####--- -####--- -#--###-",
  "-#--##-- -#----#- --#---#- -#------ --#---#- -#------ -#------ -#----#-",
  "--#----- -#----#- --#---#- --#---#- --#--#-- -#------ -#------ --#---#-",
  "---####- -#----#- -#####-- ---###-- -####--- -######- -#------ ---###--",
  "-------- -------- -------- -------- -------- -------- -------- --------",
// 0x48 - 0x4f
  "-#----#- ---###-- ----###- -#----#- -#------ -#----#- -#----#- ---##---",
  "-#----#- ----#--- -----#-- -#---#-- -#------ -##--##- -##---#- --#--#--",
  "-#----#- ----#--- -----#-- -#--#--- -#------ -#-##-#- -#-#--#- -#----#-",
  "-######- ----#--- -----#-- -###---- -#------ -#-##-#- -#--#-#- -#----#-",
  "-#----#- ----#--- -----#-- -#--#--- -#------ -#----#- -#---##- -#----#-",
  "-#----#- ----#--- -#---#-- -#---#-- -#------ -#----#- -#----#- --#--#--",
  "-#----#- ---###-- --###--- -#----#- -######- -#----#- -#----#- ---##---",
  "-------- -------- -------- -------- -------- -------- -------- --------",
// 0x50 - 0x57
  "-#####-- ---##--- -#####-- --####-- --#####- -#----#- -#----#- -#----#-",
  "-#----#- --#--#-- -#----#- -#----#- ----#--- -#----#- -#----#- -#----#-",
  "-#----#- -#----#- -#----#- -#------ ----#--- -#----#- -#----#- -#----#-",
  "-#####-- -#----#- -#####-- --####-- ----#--- -#----#- --#--#-- -#-##-#-",
  "-#------ -#--#-#- -#--#--- ------#- ----#--- -#----#- --#--#-- -#-##-#-",
  "-#------ --#--#-- -#---#-- -#----#- ----#--- -#----#- ---##--- -##--##-",
  "-#------ ---##-#- -#----#- --####-- ----#--- --####-- ---##--- -#----#-",
  "-------- -------- -------- -------- -------- -------- -------- --------",
// 0x58 - 0x5f
  "-#----#- --#---#- -######- --####-- --#---#- --####-- ----#--- --------",
  "-#----#- --#---#- ------#- --#----- --#---#- -----#-- ---#-#-- --------",
  "--#--#-- --#---#- -----#-- --#----- ---#-#-- -----#-- --#---#- --------",
  "---##--- ---###-- ---##--- --#----- --#####- -----#-- -------- --------",
  "--#--#-- ----#--- --#----- --#----- ----#--- -----#-- -------- --------",
  "-#----#- ----#--- -#------ --#----- --#####- -----#-- -------- --------",
  "-#----#- ----#--- -######- --####-- ----#--- --####-- -------- -######-",
  "-------- -------- -------- -------- -------- -------- -------- --------",
// 0x60 - 0x67
  "-------- -------- -#------ -------- ------#- -------- ----##-- --------",
  "-------- -------- -#------ -------- ------#- -------- ---#--#- --------",
  "-------- --####-- -#-###-- --####-- --###-#- --####-- ---#---- --###-#-",
  "-------- -----#-- -##---#- -#----#- -#---##- -#----#- -#####-- -#---##-",
  "-------- --####-- -#----#- -#------ -#----#- -######- ---#---- -#---##-",
  "-------- -#---#-- -##---#- -#----#- -#---##- -#------ ---#---- --###-#-",
  "-------- --###-#- -#-###-- --####-- --###-#- --####-- ---#---- ------#-",
  "-------- -------- -------- -------- -------- -------- -------- --####--",
// 0x68 - 0x6f
  "-#------ ----#--- -----#-- -#------ ---##--- -------- -------- --------",
  "-#------ -------- -------- -#------ ----#--- -------- -------- --------",
  "-#-###-- ---##--- ----##-- -#---#-- ----#--- -###-##- -#-###-- --####--",
  "-##---#- ----#--- -----#-- -#--#--- ----#--- -#--#--# -##---#- -#----#-",
  "-#----#- ----#--- -----#-- -#-#---- ----#--- -#--#--# -#----#- -#----#-",
  "-#----#- ----#--- -----#-- -##-#--- ----#--- -#--#--# -#----#- -#----#-",
  "-#----#- ---###-- -#---#-- -#---#-- ---###-- -#--#--# -#----#- --####--",
  "-------- -------- --###--- -------- -------- -------- -------- --------",
// 0x70 - 0x77
  "-------- -------- -------- -------- ---#---- -------- -------- --------",
  "-------- -------- -------- -------- ---#---- -------- -------- --------",
  "-#-###-- --###-#- -#-###-- --#####- -#####-- -#----#- -#----#- -#-----#",
  "-##---#- -#---##- -##---#- -#------ ---#---- -#----#- -#----#- -#--#--#",
  "-##---#- -#---##- -#------ --####-- ---#---- -#----#- -#----#- -#--#--#",
  "-#-###-- --###-#- -#------ ------#- ---#--#- -#---##- --#--#-- -#--#--#",
  "-#------ ------#- -#------ -#####-- ----##-- --###-#- ---##--- --##-##-",
  "-#------ ------#- -------- -------- -------- -------- -------- --------",
// 0x78 - 0x7f
  "-------- -------- -------- ----###- ----#--- -###---- --##---- --------",
  "-------- -------- -------- ---#---- ----#--- ----#--- -#--#--# --------",
  "-#----#- -#----#- -######- ---#---- -------- ----#--- -----##- --------",
  "--#--#-- -#----#- -----#-- --#----- -------- -----#-- -------- --------",
  "---##--- -#---##- ---##--- ---#---- -------- ----#--- -------- --------",
  "--#--#-- --###-#- --#----- ---#---- ----#--- ----#--- -------- --------",
  "-#----#- ------#- -######- ----###- ----#--- -###---- -------- --------",
  "-------- --####-- -------- -------- -------- -------- -------- --------",
// 0x80 - 0x87
  "-------- -------- -------- -------- -------- -------- -------- ########",
  "-------- -------- -------- -------- -------- -------- ######## ########",
  "-------- -------- -------- -------- -------- ######## ######## ########",
  "-------- -------- -------- -------- ######## ######## ######## ########",
  "-------- -------- -------- ######## ######## ######## ######## ########",
  "-------- -------- ######## ######## ######## ######## ######## ########",
  "-------- ######## ######## ######## ######## ######## ######## ########",
  "######## ######## ######## ######## ######## ######## ######## ########",
// 0x88 - 0x8f
  "#------- ##------ ###----- ####---- #####--- ######-- #######- ----#---",
  "#------- ##------ ###----- ####---- #####--- ######-- #######- ----#---",
  "#------- ##------ ###----- ####---- #####--- ######-- #######- ----#---",
  "#------- ##------ ###----- ####---- #####--- ######-- #######- ----#---",
  "#------- ##------ ###----- ####---- #####--- ######-- #######- ########",
  "#------- ##------ ###----- ####---- #####--- ######-- #######- ----#---",
  "#------- ##------ ###----- ####---- #####--- ######-- #######- ----#---",
  "#------- ##------ ###----- ####---- #####--- ######-- #######- ----#---",
// 0x90 - 0x97
  "----#--- -------- ----#--- ----#--- ######## -------- ----#--- -------#",
  "----#--- -------- ----#--- ----#--- -------- -------- ----#--- -------#",
  "----#--- -------- ----#--- ----#--- -------- -------- ----#--- -------#",
  "----#--- -------- ----#--- ----#--- -------- -------- ----#--- -------#",
  "######## ######## #####--- ----#### -------- ######## ----#--- -------#",
  "-------- ----#--- ----#--- ----#--- -------- -------- ----#--- -------#",
  "-------- ----#--- ----#--- ----#--- -------- -------- ----#--- -------#",
  "-------- ----#--- ----#--- ----#--- -------- -------- ----#--- -------#",
// 0x98 - 0x9f
  "-------- -------- ----#--- ----#--- -------- -------- ----#--- ----#---",
  "-------- -------- ----#--- ----#--- -------- -------- ----#--- ----#---",
  "-------- -------- ----#--- ----#--- -------- -------- ----#--- ----#---",
  "-------- -------- ----#--- ----#--- -------- -------- -----#-- ---#----",
  "----#### #####--- ----#### #####--- ------## ###----- ------## ###-----",
  "----#--- ----#--- -------- -------- -----#-- ---#---- -------- --------",
  "----#--- ----#--- -------- -------- ----#--- ----#--- -------- --------",
  "----#--- ----#--- -------- -------- ----#--- ----#--- -------- --------",
// 0xa0 - 0xa7
  "-------- -------- ---###-- -------- -------- -------- -------- --------",
  "-------- -------- ---#---- -------- -------- -------- -######- --------",
  "-------- -------- ---#---- -------- -------- -------- ------#- --#####-",
  "-------- -------- ---#---- ----#--- -------- ---##--- -######- ------#-",
  "-------- --###--- -------- ----#--- --#----- ---##--- ------#- ----##--",
  "-------- --#-#--- -------- ----#--- ---#---- -------- -----#-- ----#---",
  "-------- --###--- -------- --###--- ----#--- -------- --###--- ---#----",
  "-------- -------- -------- -------- -------- -------- -------- --------",
// 0xa8 - 0xaf
  "-------- -------- -------- -------- -------- -------- -------- --------",
  "-------- -------- -------- -------- -------- -------- -------- --------",
  "-----#-- ----#--- -------- -----#-- ---#---- -------- --####-- --------",
  "----#--- --#####- --#####- --#####- --#####- ---###-- -----#-- --#-#-#-",
  "---##--- --#---#- ----#--- ----##-- ---#--#- -----#-- --####-- --#-#-#-",
  "--#-#--- ------#- ----#--- ---#-#-- ---#-#-- -----#-- -----#-- ------#-",
  "----#--- ----##-- --#####- --#--#-- ---#---- --#####- --####-- ----##--",
  "-------- -------- -------- -------- -------- -------- -------- --------",
// 0xb0 - 0xb7
  "-------- -######- ------#- ----#--- -------- ----#--- ---#---- ----#---",
  "-------- ------#- -----#-- -######- --#####- -######- -######- --#####-",
  "-------- ------#- ----#--- -#----#- ----#--- ----#--- ---#--#- ----#---",
  "--#####- ---#-#-- ---##--- -#----#- ----#--- ---##--- ---#--#- --#####-",
  "-------- ---##--- --#-#--- ------#- ----#--- --#-#--- ---#--#- ----#---",
  "-------- ---#---- -#--#--- -----#-- ----#--- -#--#--- ---#--#- ----#---",
  "-------- --#----- ----#--- --###--- --#####- ----#--- --#--#-- ----#---",
  "-------- -------- -------- -------- -------- -------- -------- --------",
// 0xb8 - 0xbf
  "---####- --#----- -------- --#--#-- -------- -######- --#----- -#----#-",
  "--#---#- --#####- -######- -######- -###---- ------#- -######- -#----#-",
  "-#----#- -#--#--- ------#- --#--#-- -------- -----#-- --#---#- --#---#-",
  "-----#-- ----#--- ------#- --#--#-- -###--#- ----#--- --#--#-- ------#-",
  "----#--- ----#--- ------#- -----#-- ------#- ---##--- --#----- -----#--",
  "---#---- ----#--- ------#- ----#--- -----#-- --#--#-- --#----- ----#---",
  "-##----- ---#---- -######- ---#---- -####--- -#----#- ---####- --##----",
  "-------- -------- -------- -------- -------- -------- -------- --------",
// 0xc0 - 0xc7
  "---####- -----#-- -------- --####-- ---#---- ----#--- -------- --------",
  "--#---#- --###--- -#-#--#- -------- ---#---- ----#--- --####-- --#####-",
  "-##---#- ----#--- -#-#--#- -######- ---#---- -######- -------- ------#-",
  "---#-#-- -######- -#-#--#- ----#--- ---##--- ----#--- -------- ---#-#--",
  "----#--- ----#--- -----#-- ----#--- ---#-#-- ----#--- -------- ----#---",
  "---#---- ----#--- ----#--- ---#---- ---#---- ---#---- -------- ---#-#--",
  "-##----- -###---- -###---- --#----- ---#---- --#----- -######- --#-----",
  "-------- -------- -------- -------- -------- -------- -------- --------",
// 0xc8 - 0xcf
  "----#--- ------#- ---#---- -#------ -------- -------- ----#--- -######-",
  "--#####- ------#- ----#--- -#------ -######- ---#---- --#####- ------#-",
  "-----#-- ------#- -----#-- -######- ------#- --#-#--- ----#--- ------#-",
  "----#--- -----#-- -#----#- -#------ ------#- -#---#-- ----#--- -----#--",
  "---###-- ----#--- -#----#- -#------ -----#-- ------#- --#-#-#- --#-#---",
  "--#-#-#- ---#---- -#----#- -#------ ----#--- ------#- --#-#-#- ---#----",
  "----#--- --#----- -#----#- --#####- --##---- -------- ----#--- ----#---",
  "-------- -------- -------- -------- -------- -------- -------- --------",
// 0xd0 - 0xd7
  "-------- -----#-- -------- -------- --#----- -------- -######- --####--",
  "--####-- ----#--- ------#- -######- --#----- --###--- ------#- --------",
  "-------- ---#---- ------#- ---#---- -######- ----#--- ------#- -######-",
  "--####-- --#----- ---#-#-- -######- --#---#- ----#--- -######- ------#-",
  "-------- -#--#--- ----#--- ---#---- --#--#-- ----#--- ------#- -----#--",
  "-#####-- -#####-- ---#-#-- ---#---- --#----- ----#--- ------#- ----#---",
  "------#- ------#- -##----- ---####- --#----- -######- -######- ---#----",
  "-------- -------- -------- -------- -------- -------- -------- --------",
// 0xd8 - 0xdf
  "-#----#- --#-#--- --#----- -------- -------- -------- ---#---- -###----",
  "-#----#- --#-#--- --#----- -######- -######- -###---- -#--#--- -#-#----",
  "-#----#- --#-#--- --#----- -#----#- -#----#- ------#- --#----- -###----",
  "-#----#- --#-#-#- --#---#- -#----#- -#----#- ------#- -------- --------",
  "------#- --#-#-#- --#--#-- -#----#- ------#- -----#-- -------- --------",
  "-----#-- --#-##-- --#-#--- -#----#- -----#-- ----#--- -------- --------",
  "---##--- -#--#--- --##---- -######- ---##--- -###---- -------- --------",
  "-------- -------- -------- -------- -------- -------- -------- --------",
// 0xe0 - 0xe7
  "-------- ----#--- ----#--- ----#--- -------# #------- ######## ########",
  "-------- ----#--- ----#--- ----#--- ------## ##------ -####### #######-",
  "######## ----#### ######## #####--- -----### ###----- --###### ######--",
  "-------- ----#--- ----#--- ----#--- ----#### ####---- ---##### #####---",
  "-------- ----#--- ----#--- ----#--- ---##### #####--- ----#### ####----",
  "######## ----#### ######## #####--- --###### ######-- -----### ###-----",
  "-------- ----#--- ----#--- ----#--- -####### #######- ------## ##------",
  "-------- ----#--- ----#--- ----#--- ######## ######## -------# #-------",
// 0xe8 - 0xef
  "----#--- --##-##- ----#--- ---###-- -------- -------- -------# #-------",
  "---###-- -####### ---###-- ---###-- --####-- --####-- ------#- -#------",
  "--#####- -####### --#####- -####### -######- -#----#- -----#-- --#-----",
  "-####### -####### -####### -####### -######- -#----#- ----#--- ---#----",
  "-####### --#####- --#####- -##-#-## -######- -#----#- ---#---- ----#---",
  "---###-- ---###-- ---###-- ----#--- -######- -#----#- --#----- -----#--",
  "--#####- ----#--- ----#--- --#####- --####-- --####-- -#------ ------#-",
  "-------- -------- -------- -------- -------- -------- #------- -------#",
// 0xf0 - 0xf7
  "#------# -####### -#------ --###### -####### -----#-- -------- --###-#-",
  "-#----#- -#--#--# -######- --#----# -#-----# ###-###- ---##--- ---#--#-",
  "--#--#-- -#--#--# -#--#--- --###### -#-----# #-#--#-- --#--#-- -#######",
  "---##--- -####### --####-- --#----# -####### ###-#### -#----#- ---#-###",
  "---##--- -#-----# --#-#--- --###### -#-----# #-#---#- --####-- --###-##",
  "--#--#-- -#-----# -######- --#----# -#-----# ###-#### ---#-#-- -#-#--#-",
  "-#----#- -#-----# ----#--- -#-----# -####### ----#-#- --#--#-- ---#-#--",
  "#------# -------- -------- -------- -------- ------#- -------- --------",
// 0xf8 - 0xff
  "-------- -------- -------- -------- -------- -------- -------- --------",
  "-------- -------- -------- -------- -------- -------- -------- --------",
  "-------- -------- -------- -------- -------- -------- -------- --------",
  "-------- -------- -------- -------- -------- -------- -------- --------",
  "-------- -------- -------- -------- -------- -------- -------- --------",
  "-------- -------- -------- -------- -------- -------- -------- --------",
  "-------- -------- -------- -------- -------- -------- -------- --------",
  "-------- -------- -------- -------- -------- -------- -------- --------"];
pc8001.display=new Object();
pc8001.display.columns=80;
pc8001.display.initColor=0x18;
pc8001.initDisplay=function(svg){
  var d=pc8001.display;
  var x,y,e,t,c;
  d.svg=svg;
  d.lines=25;
  d.reverse=0;
  d.colors=new Array(256);
  d.colors.fill("control");
  for(x=0;x<8;x++){
    d.colors[0x08+x]="rgb(0 0 0)";
    d.colors[0x18+x]="#000000";
    d.colors[0x28+x]="rgb(0 0 255)";
    d.colors[0x38+x]="#0000ff";
    d.colors[0x48+x]="rgb(255 0 0)";
    d.colors[0x58+x]="#ff0000";
    d.colors[0x68+x]="rgb(255 0 255)";
    d.colors[0x78+x]="#ff00ff";
    d.colors[0x88+x]="rgb(0 255 0)";
    d.colors[0x98+x]="#00ff00";
    d.colors[0xa8+x]="rgb(0 255 255)";
    d.colors[0xb8+x]="#00ffff";
    d.colors[0xc8+x]="rgb(255 255 0)";
    d.colors[0xd8+x]="#ffff00";
    d.colors[0xe8+x]="rgb(255 255 255)";
    d.colors[0xf8+x]="#ffffff";
  }
  e=document.createElementNS("http://www.w3.org/2000/svg","text");
  e.setAttribute("font-family","monospace");
  e.setAttribute("font-size",2);
  e.setAttribute("fill","none");
  d.svg.appendChild(e);
  e.textContent=String.fromCodePoint(0x2588);
  d.monowidth=(e.getBBox().width<2)?1:2;
  e=[[0x3000,0x2598,0x259d,0x2580],
     [0x2596,0x258c,0x259e,0x259b],
     [0x2597,0x259a,0x2590,0x259c],
     [0x2584,0x2599,0x259f,0x2588]];
  if(pc8001.display.monowidth<2)
    e[0][0]=0xa0;
  d.font=new Array(256);
  d.font.fill("");
  d.font.forEach(function(v,x,a){
    var t=new Array(8);
    var i,j
    for(i=j=0;i<8;i++){
      t[i]=pc8001.font[(x&0xf8)+i].split(" ")[x%8].replace(/-/g,"0").replace(/#/g,"1");
      if(t[i]=="00000000")
        j++;
    }
    if(j!=8){
      for(i=0;i<8;i+=2){
        for(j=0;j<8;j+=2)
          a[x]+=String.fromCodePoint(e[parseInt(t[j+1].substr(i+1,1)+t[j].substr(i+1,1),2)][parseInt(t[j+1].substr(i,1)+t[j].substr(i,1),2)]);
      }
    }
  });
  d.blocks=new Array(256);
  d.blocks.fill("");
  for(x=1;x<256;x++){
    if((x&0xcc)>0)
      d.blocks[x]+=String.fromCodePoint(e[(x>>4)&3][x&3],e[(x>>6)&3][(x>>2)&3]);
    else
      d.blocks[x]+=String.fromCodePoint(e[(x>>4)&3][x&3]);
  }
  d.bgchars=new Array(56);
  d.bgchars.fill("");
  for(x=0;x<4;x++){
    d.bgchars[0x04+x]=d.bgchars[0x14+x]=d.bgchars[0x24+x]=d.bgchars[0x34+x]=String.fromCodePoint(0x2588);
    d.bgchars[0x10+x]=String.fromCodePoint(0x258f);
    d.bgchars[0x20+x]=String.fromCodePoint(0x2595);
    d.bgchars[0x30+x]=String.fromCodePoint(0x258c,e[0][0],e[0][0],0x2590);
  }
  e=document.createElementNS("http://www.w3.org/2000/svg","path");
  e.setAttribute("id","charpath");
  t=(d.monowidth<2)?"2.4":"4";
  e.setAttribute("d","M 0 1 h "+t+" m -"+t+" 1 h "+t+" m -"+t+" 1 h "+t+" m -"+t+" 1 h "+t);
  d.svg.appendChild(e);
  e=document.createElementNS("http://www.w3.org/2000/svg","g");
  e.setAttribute("class","blink");
  d.svg.appendChild(e);
  d.blinker=e;
  d.textArray=t=new Array(80);
  for(x=0;x<80;x++)
    t[x]=new Array(25);
  d.start=d.end=0xf300;
  for(y=0;y<25;y++){
    for(x=0;x<80;x++){
      pc8001.memory[d.end]=0;
      d.end++;
      t[x][y]=new Object();
      t[x][y].color=d.colors[d.initColor];
      c=(x%2==0||d.columns==80)?d.colors[d.initColor]:"none";
      e=document.createElementNS("http://www.w3.org/2000/svg","text");
      e.setAttribute("y",x*2);
      e.setAttribute("x",y*4);
      e.setAttribute("font-size",160/d.columns);
      e.setAttribute("font-family","monospace"); 
      e.setAttribute("fill",c);
      e.setAttribute("transform","matrix(0 1 1 0 "+((d.monowidth<2)?128:144)/d.columns+" 0)");
      e.setAttribute("textLength",4);
      e.setAttribute("lengthAdjust","spacingAndGlyphs");
      d.svg.appendChild(e);
      t[x][y].controlbox=e;
      t[x][y].control=d.reverse;
      e=document.createElementNS("http://www.w3.org/2000/svg","text");
      e.setAttribute("font-family","monospace");
      if(d.colors[d.initColor].substr(0,1)=="#"){
        e.setAttribute("font-size",2);
        e.setAttribute("transform","matrix(0 "+((d.monowidth<2)?5/3:1)+" "+80/d.columns+" 0 "+(x*2+72/d.columns)+" "+y*100/d.lines+")");
      }
      else{
        e.setAttribute("font-size",1);
        e.setAttribute("transform","matrix(0 "+((d.monowidth<2)?5/3:1)+" "+40/d.columns+" 0 "+x*2+" "+y*100/d.lines+")");
      }
      e.setAttribute("fill",c);
      d.svg.appendChild(e);
      t[x][y].textbox=e;
      e=document.createElementNS("http://www.w3.org/2000/svg","textPath");
      e.setAttribute("href","#charpath");
      t[x][y].textbox.appendChild(e);
      t[x][y].textpath=e;
      t[x][y].data=0;
    }
    pc8001.memory[d.end]=0;
    d.end++;
    pc8001.memory[d.end]=0;
    d.end++;
    pc8001.memory[d.end]=(d.columns==40)?2:1;
    d.end++;
    for(x=3;x<39;x++){
      pc8001.memory[d.end]=(x%2==0)?80:d.initColor;
      d.end++;
    }
    pc8001.memory[d.end]=0;
    d.end++;
  }
  d.end--;
  pc8001.outports[0x30]=(d.columns==80)?0x29:0x28;
}
pc8001.resizeDisplay=function(columns,lines){
  var d=pc8001.display;
  var x,y,t;
  if((columns!=40&&columns!=80)||lines<20||lines>25){
    console.log("Unable resizeDisplay",columns,lines);
    return;
  }
  if(columns!=d.columns||lines!=d.lines){
    for(y=0;y<25;y++){
      for(x=0;x<80;x++){
        t=d.textArray[x][y];
        t.controlbox.setAttribute("x",y*100/lines);
        t.controlbox.setAttribute("font-size",160/columns);
        t.controlbox.setAttribute("transform","matrix(0 1 1 0 "+(d.monowidth<2?128:144)/columns+" 0)");
        t.controlbox.textContent=d.bgchars[t.control];
        if(t.color.substr(0,1)=="#"){
          t.textbox.setAttribute("font-size",2);
          t.textbox.setAttribute("transform","matrix(0 "+((d.monowidth<2)?5/3:1)+" "+80/columns+" 0 "+(x*2+72/columns)+" "+y*100/lines+")");
          t.textpath.textContent=d.blocks[t.data];
        }
        else{
          t.textbox.setAttribute("font-size",1);
          t.textbox.setAttribute("transform","matrix(0 "+((d.monowidth<2)?5/3:1)+" "+40/columns+" 0 "+x*2+" "+y*100/lines+")");
          t.textpath.textContent=d.font[t.data];
        }
        if(y>=lines||(x%2==1&&columns==40)){
          t.controlbox.setAttribute("fill","none");
          t.textbox.setAttribute("fill","none");
        }
        else{
          t.controlbox.setAttribute("fill",t.color);
          t.textbox.setAttribute("fill",((t.control&1)==1)?"none":((t.control&4)==4)?"black":t.color);
          if((t.control&2)==2)
            d.blinker.appendChild(t.textbox);
          else
            d.svg.appendChild(t.textbox);
        }
      }
    }
  }
  d.columns=columns;
  d.lines=lines;
}
pc8001.reverseDisplay=function(rev){
  var d=pc8001.display;
  var x,y,t;
  if(rev!=0)
    rev=4;
  if(d.reverse==rev)
    return;
  for(y=0;y<25;y++){
    for(x=0;x<80;x++){
      t=d.textArray[x][y];
      t.control^=4;
      t.controlbox.textContent=d.bgchars[t.control];
      if(y<d.lines&&(x%2==0||d.columns==80))
        t.textbox.setAttribute("fill",((t.control&1)==1)?"none":((t.control&4)==4)?"black":t.color);
    }
  }
  d.reverse=rev;
}
pc8001.writeMemory=function(address,data){
  var t=pc8001.memory[address];
  var d=pc8001.display;
  var x,y,f,g,i,j,k;
  if(data<0||data>0xff){
    console.log("writeMemory",address.toString(16),data);
    Object.keys(pc8001.z80.regs).forEach(function(v){
      console.log(" reg",v,pc8001.z80.regs[v].toString(16).toUpperCase().padStart(v.length*2,"0"));
  });
    console.log(" flags",pc8001.z80.flags);
    data=(data+65536)&0xff;
  }
  if(address<0x6000)
    console.log("write",data,"to ROM",address.toString(16).toUpperCase().padStart(4,"0"),"at",pc8001.z80.regs["PC"].toString(16).toUpperCase().padStart(4,"0"));
  else
    pc8001.memory[address]=data;
  if(address<d.start||d.end<address||t==data)
    return;
  x=(address-d.start)%120;
  y=Math.floor((address-d.start)/120);
  if(x<80){
    t=d.textArray[x][y];
    if(y<d.lines&&(x%2==0||d.columns==80))
      t.textpath.textContent=(t.color.substr(0,1)=="#")?d.blocks[data]:d.font[data];
    t.data=data;
    return;
  }
  g=new Array(20);
  for(f=1;f==1;y=(y>d.lines-2)?0:y+1){
    i=d.start+80+y*120;
    for(j=0;j<20;j++)
      g[j]=pc8001.memory[i+j*2]&0x7f;
    j=d.textArray[79][(y==0)?d.lines-1:y-1].control;
    k=d.textArray[79][(y==0)?d.lines-1:y-1].color;
    for(x=0;x<80;x++){
      if(g.indexOf(x)>=0){
        i++;
        t=d.colors[pc8001.memory[i]];
        if(t=="control")
          j=(pc8001.memory[i]&0x3f)^d.reverse;
        else
          k=t;
        i++;
      }
      t=d.textArray[x][y];
      f=0;
      if(t.color!=k){
        if(x%2==0||d.columns==80){
          t.controlbox.setAttribute("fill",k);
          t.textbox.setAttribute("fill",k);
          if(t.color.substr(0,1)!=k.substr(0,1)){
            if(k.substr(0,1)=="#"){
              t.textbox.setAttribute("font-size",2);
              t.textbox.setAttribute("transform","matrix(0 "+((d.monowidth<2)?5/3:1)+" "+80/d.columns+" 0 "+(x*2+72/d.columns)+" "+y*100/d.lines+")");
              t.textpath.textContent=d.blocks[t.data];
            }
            else{
              t.textbox.setAttribute("font-size",1);
              t.textbox.setAttribute("transform","matrix(0 "+((d.monowidth<2)?5/3:1)+" "+40/d.columns+" 0 "+x*2+" "+y*100/d.lines+")");
              t.textpath.textContent=d.font[t.data];
            }
          }
        }
        t.color=k;
        f=1;
      }
      if(t.control!=j){
        if(x%2==0||d.columns==80){
          t.textbox.setAttribute("fill",((j&1)==1)?"none":((j&4)==4)?"black":k);
          if(((t.control^j)&2)==2){
            if((j&2)==2)
              d.blinker.appendChild(t.textbox);
            else
              d.svg.appendChild(t.textbox);
          }
          t.controlbox.textContent=d.bgchars[j];
        }
        t.control=j;
        f=1;
      }
    }
  }
}
pc8001.inports=new Array(256);
pc8001.inports.fill(0xff);
pc8001.outports=new Array(256);
pc8001.outports.fill(0);
pc8001.keymap=new Array(256);
pc8001.keymap.fill([]);
pc8001.keymap[13]=[1,0x7f];                    // enter-key
pc8001.keymap[32]=[9,0xbf];                    // space-key
pc8001.keymap[98]=pc8001.keymap[40]=[0,0xfb];  // ten-key 2 = downarrow
pc8001.keymap[100]=pc8001.keymap[37]=[0,0xef]; // ten-key 4 = leftarrow
pc8001.keymap[102]=pc8001.keymap[39]=[0,0xbf]; // ten-key 6 = rightarrow
pc8001.keymap[104]=pc8001.keymap[38]=[1,0xfe]; // ten-key 8 = uparrow
pc8001.keydown=function(event){
  var k=pc8001.keymap[event.keyCode]
  var i;
  if(k.length<2)
    return;
  for(i=0;i<k.length;i+=2)
    pc8001.inports[k[i]]&=k[i+1];
  if(pc8001.beep.counter<0){
    pc8001.beep.counter=pc8001.beep.on=0;
    pc8001.beep.start=pc8001.z80.states;
    pc8001.beep.oscillator.start();
  }
}
pc8001.keyup=function(event){
  var k=pc8001.keymap[event.keyCode]
  var i;
  if(k.length<2)
    return;
  for(i=0;i<k.length;i+=2)
    pc8001.inports[k[i]]|=(k[i+1]^0xff);
}
pc8001.beep=new Object();
pc8001.beep.audio=new(window.AudioContext||window.webkitAudioContext)();
pc8001.beep.buffer=pc8001.beep.audio.createBuffer(1,Math.floor(pc8001.beep.audio.sampleRate/60),pc8001.beep.audio.sampleRate);
pc8001.beep.oscillator=pc8001.beep.audio.createBufferSource();
pc8001.beep.oscillator.buffer=pc8001.beep.buffer;
pc8001.beep.wave=pc8001.beep.buffer.getChannelData(0);
pc8001.beep.wave.fill(0);
pc8001.beep.counter=-1;
pc8001.beep.oscillator.loop=true;
pc8001.beep.oscillator.connect(pc8001.beep.audio.destination);
pc8001.beep.refWave=new Array(pc8001.beep.wave.length);
pc8001.beep.refWave.fill(0);
pc8001.beep.refWave.forEach(function(v,i,a){
  a[i]=Math.sin(i*Math.PI*2/pc8001.beep.audio.sampleRate*2400);
});
pc8001.calendar=new Object();
pc8001.calendar.command=function(com){
  var d,j,k;
  switch(com){
    case 4:
      pc8001.calendar.differential=0;
    case 3:
      pc8001.calendar.readreg="00000000";
      pc8001.calendar.writereg="";
      pc8001.calendar.date=new Date();
      return 0;
    case 2:
      d=new Date();
      k=pc8001.calendar.writereg;
      if(k.length>40){
        j=parseInt(parseInt(k.slice(0,-40),2).toString(16),10);
        if(!isNaN(j))
          d.setFullYear(j);
      }
      if(k.length>39){
        j=parseInt(k.slice(-40,-36),2);
        if(!isNaN(j))
          d.setMonth(j-1);
      }
      if(k.length>31){
        j=parseInt(parseInt(k.slice(-32,-24),2).toString(16),10);
        if(!isNaN(j))
          d.setDate(j);
      }
      if(k.length>23){
        j=parseInt(parseInt(k.slice(-24,-16),2).toString(16),10);
        if(!isNaN(j))
          d.setHours(j);
      }
      if(k.length>15){
        j=parseInt(parseInt(k.slice(-16,-8),2).toString(16),10);
        if(!isNaN(j))
          d.setMinutes(j);
      }
      if(k.length>7){
        j=parseInt(parseInt(k.slice(-8),2).toString(16),10);
        if(!isNaN(j))
          d.setSeconds(j);
      }
      pc8001.calendar.date=new Date();
      pc8001.calendar.differential=pc8001.calendar.date-d;
    case 1:
      d=new Date(pc8001.calendar.date-pc8001.calendar.differential);
      j=d.getFullYear().toString()+(d.getMonth()+1).toString(16)+d.getDay().toString()
      k=parseInt(j,16).toString(2).padStart(32,"0");
      j=(d.getDate()*1000000+d.getHours()*10000+d.getMinutes()*100+d.getSeconds()).toString();
      k+=parseInt(j,16).toString(2).padStart(32,"0");
      pc8001.calendar.readreg=k;
      pc8001.calendar.writereg="";
  }
  return (pc8001.calendar.readreg.slice(-1)=="1")?0x10:0;
}
pc8001.calendar.command(4);
pc8001.calendar.shift=function(b){
  var t;
  pc8001.calendar.writereg=(((b&8)==0)?"0":"1")+pc8001.calendar.writereg;
  t=pc8001.calendar.readreg.slice(-1)+pc8001.calendar.readreg.slice(0,-1);
  pc8001.calendar.readreg=t;
  return (t.slice(-1)=="1")?0x10:0;
}
pc8001.z80=new Object();
pc8001.z80.frequency=3000000;                  // down to 3MHz
pc8001.z80.millistates=pc8001.z80.frequency/1000;
pc8001.z80.regs={"PC":0,"SP":0,"A":0,"B":0,"C":0,"D":0,"E":0,"H":0,"L":0,"J":0,"X":0,"K":0,"Y":0,"a":0,"b":0,"c":0,"d":0,"e":0,"h":0,"l":0};
pc8001.z80.flags={"Z":0,"C":0,"V":0,"M":0,"H":0,"N":0,"DUMMY":0,"z":0,"c":0,"v":0,"m":0,"h":0,"n":0,"dummy":0};
pc8001.z80.mnemonics={};
pc8001.z80.halt=pc8001.z80.states=0;
pc8001.z80.ops=new Array(256);
pc8001.z80.ops.fill(["UNDEF","",0]);
pc8001.z80.ops[0xcb]=new Array(257);
pc8001.z80.ops[0xcb].fill(["UNDEF","CB",0]);
pc8001.z80.ops[0xcb][256]=-1;
pc8001.z80.ops[0xdd]=new Array(257);
pc8001.z80.ops[0xdd].fill(["UNDEF","DD",0]);
pc8001.z80.ops[0xdd][256]=-1;
pc8001.z80.ops[0xed]=new Array(257);
pc8001.z80.ops[0xed].fill(["UNDEF","ED",0]);
pc8001.z80.ops[0xed][256]=-1;
pc8001.z80.ops[0xfd]=new Array(257);
pc8001.z80.ops[0xfd].fill(["UNDEF","FD",0]);
pc8001.z80.ops[0xfd][256]=-1;
pc8001.z80.mnemonics["UNDEF"]=function(x,m){
  pc8001.z80.regs["PC"]=(pc8001.z80.regs["PC"]+0xffff)&0xffff;
  pc8001.z80.halt=1;
  console.log(performance.now()-pc8001.z80.millitimer,"milliseconds");
  console.log(pc8001.z80.states,"states");
  console.log(m[0],m[1],x.toString(16).toUpperCase().padStart(2,"0"));
  Object.keys(pc8001.z80.regs).forEach(function(v){
    console.log(" reg",v,pc8001.z80.regs[v].toString(16).toUpperCase().padStart(v.length*2,"0"));
  });
  console.log(" flags",pc8001.z80.flags);
}
pc8001.z80.ops[0x00]=["NOP",4];
pc8001.z80.mnemonics["NOP"]=function(x,m){
}
pc8001.operators=["ADD","ADC","SUB","SBC","AND","XOR","OR","CP"];
pc8001.params=["B","C","D","E","H","L","(HL)","A"];
pc8001.params.forEach(function(v,i,a){
  var j;
  for(j=0;j<8;j++)
    pc8001.z80.ops[i*8+j+0x40]=["LD",v,a[j],(i==6||j==6)?7:4];
  pc8001.z80.ops[i*8+4]=["INC",v,(i==6)?11:4];
  pc8001.z80.ops[i*8+5]=["DEC",v,(i==6)?11:4];
  pc8001.z80.ops[i*8+6]=["LD",v,"n",(i==6)?10:7];
  pc8001.operators.forEach(function(w,j){
    pc8001.z80.ops[i+j*8+0x80]=[w,"A",v,(i==6)?7:4];
  });
  if(i!=6){
    pc8001.z80.ops[0xdd][i*8+0x46]=["LD",v,"(JX+d)",19];
    pc8001.z80.ops[0xdd][i+0x70]=["LD","(JX+d)",v,19];
    pc8001.z80.ops[0xdd][i*8+0x44]=["LD",v,"J",8];
    pc8001.z80.ops[0xdd][i*8+0x45]=["LD",v,"X",8];
    pc8001.z80.ops[0xdd][i+0x60]=["LD","J",v,8];
    pc8001.z80.ops[0xdd][i+0x68]=["LD","X",v,8];
    pc8001.z80.ops[0xfd][i*8+0x46]=["LD",v,"(KY+d)",19];
    pc8001.z80.ops[0xfd][i+0x70]=["LD","(KY+d)",v,19];
    pc8001.z80.ops[0xfd][i*8+0x44]=["LD",v,"K",8];
    pc8001.z80.ops[0xfd][i*8+0x45]=["LD",v,"Y",8];
    pc8001.z80.ops[0xfd][i+0x60]=["LD","K",v,8];
    pc8001.z80.ops[0xfd][i+0x68]=["LD","Y",v,8];
    pc8001.z80.ops[0xed][i*8+0x40]=["IN",v,"(BC)",12];
    pc8001.z80.ops[0xed][i*8+0x41]=["OUT","(BC)",v,12];
  }
  pc8001.z80.ops[0xcb][i+0x00]=["RLC",v,(i==6)?15:8];
  pc8001.z80.ops[0xcb][i+0x08]=["RRC",v,(i==6)?15:8];
  pc8001.z80.ops[0xcb][i+0x10]=["RL",v,(i==6)?15:8];
  pc8001.z80.ops[0xcb][i+0x18]=["RR",v,(i==6)?15:8];
  pc8001.z80.ops[0xcb][i+0x20]=["SLA",v,(i==6)?15:8];
  pc8001.z80.ops[0xcb][i+0x28]=["SRA",v,(i==6)?15:8];
  pc8001.z80.ops[0xcb][i+0x30]=["SLL",v,(i==6)?15:8];
  pc8001.z80.ops[0xcb][i+0x38]=["SRL",v,(i==6)?15:8];
  for(j=0;j<8;j++){
    pc8001.z80.ops[0xcb][i+j*8+0x40]=["BIT",j,v,(i==6)?12:8];
    pc8001.z80.ops[0xcb][i+j*8+0x80]=["RES",j,v,(i==6)?15:8];
    pc8001.z80.ops[0xcb][i+j*8+0xc0]=["SET",j,v,(i==6)?15:8];
  }
});
pc8001.operators.forEach(function(v,i){
  pc8001.z80.ops[i*8+0xc6]=[v,"A","n",7];
  pc8001.z80.ops[0xdd][i*8+0x84]=[v,"A","J",8];
  pc8001.z80.ops[0xdd][i*8+0x85]=[v,"A","X",8];
  pc8001.z80.ops[0xdd][i*8+0x86]=[v,"A","(JX+d)",19];
  pc8001.z80.ops[0xfd][i*8+0x84]=[v,"A","K",8];
  pc8001.z80.ops[0xfd][i*8+0x85]=[v,"A","Y",8];
  pc8001.z80.ops[0xfd][i*8+0x86]=[v,"A","(KY+d)",19];
});
pc8001.z80.ops[0x76]=["HALT","",4];
pc8001.z80.mnemonics["HALT"]=pc8001.z80.mnemonics["UNDEF"];
pc8001.z80.ops[0x02]=["LD","(BC)","A",7];
pc8001.z80.ops[0x0a]=["LD","A","(BC)",7];
pc8001.z80.ops[0x12]=["LD","(DE)","A",7];
pc8001.z80.ops[0x1a]=["LD","A","(DE)",7];
pc8001.z80.ops[0x32]=["LD","(nn)","A",13];
pc8001.z80.ops[0x3a]=["LD","A","(nn)",13];
pc8001.z80.ops[0xdd][0x26]=["LD","J","n",11];
pc8001.z80.ops[0xdd][0x2e]=["LD","X","n",11];
pc8001.z80.ops[0xdd][0x36]=["LD","(JX+d)","n",19];
pc8001.z80.ops[0xdd][0x64]=["LD","J","J",8];
pc8001.z80.ops[0xdd][0x65]=["LD","J","X",8];
pc8001.z80.ops[0xdd][0x6c]=["LD","X","J",8];
pc8001.z80.ops[0xdd][0x6d]=["LD","X","X",8];
pc8001.z80.ops[0xfd][0x26]=["LD","K","n",11];
pc8001.z80.ops[0xfd][0x2e]=["LD","Y","n",11];
pc8001.z80.ops[0xfd][0x36]=["LD","(KY+d)","n",19];
pc8001.z80.ops[0xfd][0x64]=["LD","K","K",8];
pc8001.z80.ops[0xfd][0x65]=["LD","K","Y",8];
pc8001.z80.ops[0xfd][0x6c]=["LD","Y","K",8];
pc8001.z80.ops[0xfd][0x6d]=["LD","Y","Y",8];
pc8001.z80.mnemonics["LD"]=function(x,m){
  var pc=pc8001.z80.regs["PC"];
  var a=-1;
  var b,c;
  switch(m[1].length){
    case 4:
      if(m[1]=="(nn)"){
        a=pc8001.memory[pc]+pc8001.memory[(pc+1)&0xffff]*256;
        pc8001.z80.regs["PC"]=pc=(pc+2)&0xffff;
      }
      else
        a=pc8001.z80.regs[m[1].substr(1,1)]*256+pc8001.z80.regs[m[1].substr(2,1)];
      break;
    case 6:
      a=pc8001.memory[pc];
      pc8001.z80.regs["PC"]=pc=(pc+1)&0xffff;
      if(a>0x7f)
        a+=0xff00;
      a+=pc8001.z80.regs[m[1].substr(1,1)]*256+pc8001.z80.regs[m[1].substr(2,1)];
      a&=0xffff;
  }
  switch(m[2].length){
    case 4:
      if(m[2]=="(nn)"){
        b=pc8001.memory[pc]+pc8001.memory[(pc+1)&0xffff]*256;
        pc8001.z80.regs["PC"]=pc=(pc+2)&0xffff;
      }
      else
        b=pc8001.z80.regs[m[2].substr(1,1)]*256+pc8001.z80.regs[m[2].substr(2,1)];
      c=pc8001.memory[b];
      break;
    case 6:
      b=pc8001.memory[pc];
      pc8001.z80.regs["PC"]=pc=(pc+1)&0xffff;
      if(b>0x7f)
        b+=0xff00;
      b+=pc8001.z80.regs[m[2].substr(1,1)]*256+pc8001.z80.regs[m[2].substr(2,1)];
      c=pc8001.memory[b&0xffff];
      break;
    default:
      if(m[2]=="n"){
        c=pc8001.memory[pc];
        pc8001.z80.regs["PC"]=pc=(pc+1)&0xffff;
      }
      else
        c=pc8001.z80.regs[m[2]];
  }
  if(a<0)
    pc8001.z80.regs[m[1]]=c;
  else
    pc8001.writeMemory(a,c);
}
pc8001.z80.ops[0x01]=["LD16","BC","nn",10];
pc8001.z80.ops[0x11]=["LD16","DE","nn",10];
pc8001.z80.ops[0x21]=["LD16","HL","nn",10];
pc8001.z80.ops[0x22]=["LD16","(nn)","HL",16];
pc8001.z80.ops[0x2a]=["LD16","HL","(nn)",16];
pc8001.z80.ops[0x31]=["LD16","SP","nn",10];
pc8001.z80.ops[0xf9]=["LD16","SP","HL",6];
pc8001.z80.ops[0xed][0x43]=["LD16","(nn)","BC",20];
pc8001.z80.ops[0xed][0x4b]=["LD16","BC","(nn)",20];
pc8001.z80.ops[0xed][0x53]=["LD16","(nn)","DE",20];
pc8001.z80.ops[0xed][0x5b]=["LD16","DE","(nn)",20];
pc8001.z80.ops[0xed][0x63]=["LD16","(nn)","HL",20];
pc8001.z80.ops[0xed][0x6b]=["LD16","HL","(nn)",20];
pc8001.z80.ops[0xed][0x73]=["LD16","(nn)","SP",20];
pc8001.z80.ops[0xed][0x7b]=["LD16","SP","(nn)",20];
pc8001.z80.ops[0xdd][0x21]=["LD16","JX","nn",14];
pc8001.z80.ops[0xdd][0x22]=["LD16","(nn)","JX",20];
pc8001.z80.ops[0xdd][0x2a]=["LD16","JX","(nn)",20];
pc8001.z80.ops[0xdd][0xf9]=["LD16","SP","JX",10];
pc8001.z80.ops[0xfd][0x21]=["LD16","KY","nn",14];
pc8001.z80.ops[0xfd][0x22]=["LD16","(nn)","KY",20];
pc8001.z80.ops[0xfd][0x2a]=["LD16","KY","(nn)",20];
pc8001.z80.ops[0xfd][0xf9]=["LD16","SP","KY",10];
pc8001.z80.mnemonics["LD16"]=function(x,m){
  var pc=pc8001.z80.regs["PC"];
  var h,l,a;
  switch(m[2]){
    case "nn":
      l=pc8001.memory[pc];
      h=pc8001.memory[(pc+1)&0xffff];
      pc=pc8001.z80.regs["PC"]=(pc+2)&0xffff;
      break;
    case "(nn)":
      a=pc8001.memory[pc]+pc8001.memory[(pc+1)&0xffff]*256;
      pc=pc8001.z80.regs["PC"]=(pc+2)&0xffff;
      l=pc8001.memory[a];
      h=pc8001.memory[(a+1)&0xffff];
      break;
    case "SP":
      a=pc8001.z80.regs["SP"];
      h=a>>8;
      l=a&0xff;
      break;
    default:
      h=pc8001.z80.regs[m[2].substr(0,1)];
      l=pc8001.z80.regs[m[2].substr(1)];
  }
  switch(m[1]){
    case "(nn)":
      a=pc8001.memory[pc]+pc8001.memory[(pc+1)&0xffff]*256;
      pc=pc8001.z80.regs["PC"]=(pc+2)&0xffff;
      pc8001.writeMemory(a,l);
      pc8001.writeMemory((a+1)&0xffff,h);
      return;
    case "SP":
      pc8001.z80.regs["SP"]=h*256+l;
      return;
    default:
      pc8001.z80.regs[m[1].substr(0,1)]=h;
      pc8001.z80.regs[m[1].substr(1)]=l;
  }
}
pc8001.z80.ops[0x08]=["EX","AF","af",4];
pc8001.z80.ops[0xe3]=["EX","(SP)","HL",19];
pc8001.z80.ops[0xeb]=["EX","DE","HL",4];
pc8001.z80.mnemonics["EX"]=function(x,m){
  var a,t;
  if(m[1]=="(SP)"){
    a=pc8001.z80.regs["SP"]
    t=pc8001.memory[a];
    pc8001.writeMemory(a,pc8001.z80.regs[m[2].substr(1)]);
    pc8001.z80.regs[m[2].substr(1)]=t;
    a=(a+1)&0xffff;
    t=pc8001.memory[a];
    pc8001.writeMemory(a,pc8001.z80.regs[m[2].substr(0,1)]);
    pc8001.z80.regs[m[2].substr(0,1)]=t;
    return;
  }
  t=pc8001.z80.regs[m[1].substr(0,1)];
  pc8001.z80.regs[m[1].substr(0,1)]=pc8001.z80.regs[m[2].substr(0,1)];
  pc8001.z80.regs[m[2].substr(0,1)]=t;
  if(m[1].substr(1)=="F"){
    a=["Z","C","V","M","H","N","DUMMY"];
    a.forEach(function(v){
      var b=pc8001.z80.flags[v];
      pc8001.z80.flags[v]=pc8001.z80.flags[v.toLowerCase()];
      pc8001.z80.flags[v.toLowerCase()]=b;
    });
    return;
  }
  t=pc8001.z80.regs[m[1].substr(1)];
  pc8001.z80.regs[m[1].substr(1)]=pc8001.z80.regs[m[2].substr(1)];
  pc8001.z80.regs[m[2].substr(1)]=t;
}
pc8001.z80.ops[0xd9]=["EXX",4];
pc8001.z80.mnemonics["EXX"]=function(x,m){
  var r=["B","C","D","E","H","L"];
  r.forEach(function(v){
    var t=pc8001.z80.regs[v];
    pc8001.z80.regs[v]=pc8001.z80.regs[v.toLowerCase()];
    pc8001.z80.regs[v.toLowerCase()]=t;
  });
}
pc8001.z80.ops[0xdd][0x24]=["INC","J",8];
pc8001.z80.ops[0xdd][0x2c]=["INC","X",8];
pc8001.z80.ops[0xdd][0x34]=["INC","(JX+d)",23];
pc8001.z80.ops[0xfd][0x24]=["INC","K",8];
pc8001.z80.ops[0xfd][0x2c]=["INC","Y",8];
pc8001.z80.ops[0xfd][0x34]=["INC","(KY+d)",23];
pc8001.z80.mnemonics["INC"]=function(x,m){
  var pc=pc8001.z80.regs["PC"];
  var a,t;
  switch(m[1].length){
    case 4:
      a=pc8001.z80.regs[m[1].substr(1,1)]*256+pc8001.z80.regs[m[1].substr(2,1)];
      t=pc8001.memory[a];
      break;
    case 6:
      a=pc8001.memory[pc];
      pc8001.z80.regs["PC"]=pc=(pc+1)&0xffff;
      if(a>0x7f)
        a+=0xff00;
      a+=pc8001.z80.regs[m[1].substr(1,1)]*256+pc8001.z80.regs[m[1].substr(2,1)];
      a&=0xffff;
      t=pc8001.memory[a];
      break;
    default:
      a=-1;
      t=pc8001.z80.regs[m[1]];
  }
  t=(t+1)&0xff;
  if(a<0)
    pc8001.z80.regs[m[1]]=t;
  else
    pc8001.writeMemory(a,t);
  pc8001.z80.flags["Z"]=(t==0)?1:0;
  pc8001.z80.flags["M"]=(t>0x7f)?1:0;
  pc8001.z80.flags["V"]=(t==0x80)?1:0;
  pc8001.z80.flags["H"]=((t&0x0f)==0)?1:0;
  pc8001.z80.flags["N"]=0;
}
pc8001.z80.ops[0x03]=["INC16","BC",6];
pc8001.z80.ops[0x13]=["INC16","DE",6];
pc8001.z80.ops[0x23]=["INC16","HL",6];
pc8001.z80.ops[0x33]=["INC16","SP",6];
pc8001.z80.ops[0xdd][0x23]=["INC16","JX",10];
pc8001.z80.ops[0xfd][0x23]=["INC16","KY",10];
pc8001.z80.mnemonics["INC16"]=function(x,m){
  var t;
  if(m[1]=="SP")
    pc8001.z80.regs["SP"]=(pc8001.z80.regs["SP"]+1)&0xffff;
  else{
    pc8001.z80.regs[m[1].substr(1)]=t=(pc8001.z80.regs[m[1].substr(1)]+1)&0xff;
    if(t==0)
      pc8001.z80.regs[m[1].substr(0,1)]=(pc8001.z80.regs[m[1].substr(0,1)]+1)&0xff;
  }
}
pc8001.z80.ops[0xdd][0x25]=["DEC","J",8];
pc8001.z80.ops[0xdd][0x2b]=["DEC","X",8];
pc8001.z80.ops[0xdd][0x35]=["DEC","(JX+d)",23];
pc8001.z80.ops[0xfd][0x25]=["DEC","K",8];
pc8001.z80.ops[0xfd][0x2b]=["DEC","Y",8];
pc8001.z80.ops[0xfd][0x35]=["DEC","(KY+d)",23];
pc8001.z80.mnemonics["DEC"]=function(x,m){
  var pc=pc8001.z80.regs["PC"];
  var a,t;
  switch(m[1].length){
    case 4:
      a=pc8001.z80.regs[m[1].substr(1,1)]*256+pc8001.z80.regs[m[1].substr(2,1)];
      t=pc8001.memory[a];
      break;
    case 6:
      a=pc8001.memory[pc];
      pc8001.z80.regs["PC"]=pc=(pc+1)&0xffff;
      if(a>0x7f)
        a+=0xff00;
      a+=pc8001.z80.regs[m[1].substr(1,1)]*256+pc8001.z80.regs[m[1].substr(2,1)];
      a&=0xffff;
      t=pc8001.memory[a];
      break;
    default:
      a=-1;
      t=pc8001.z80.regs[m[1]];
  }
  t=(t+0xff)&0xff;
  if(a<0)
    pc8001.z80.regs[m[1]]=t;
  else
    pc8001.writeMemory(a,t);
  pc8001.z80.flags["Z"]=(t==0)?1:0;
  pc8001.z80.flags["M"]=(t>0x7f)?1:0;
  pc8001.z80.flags["V"]=(t==0x7f)?1:0;
  pc8001.z80.flags["H"]=((t&0x0f)==0x0f)?1:0;
  pc8001.z80.flags["N"]=1;
}
pc8001.z80.ops[0x0b]=["DEC16","BC",6];
pc8001.z80.ops[0x1b]=["DEC16","DE",6];
pc8001.z80.ops[0x2b]=["DEC16","HL",6];
pc8001.z80.ops[0x3b]=["DEC16","SP",6];
pc8001.z80.ops[0xdd][0x2b]=["DEC16","JX",6];
pc8001.z80.ops[0xfd][0x2b]=["DEC16","KY",6];
pc8001.z80.mnemonics["DEC16"]=function(x,m){
  var t;
  if(m[1]=="SP")
    pc8001.z80.regs["SP"]=(pc8001.z80.regs["SP"]+0xffff)&0xffff;
  else{
    pc8001.z80.regs[m[1].substr(1)]=t=(pc8001.z80.regs[m[1].substr(1)]+0xff)&0xff;
    if(t==0xff)
      pc8001.z80.regs[m[1].substr(0,1)]=(pc8001.z80.regs[m[1].substr(0,1)]+0xff)&0xff;
  }
}
pc8001.z80.ops[0x09]=["ADD16","HL","BC",11];
pc8001.z80.ops[0x19]=["ADD16","HL","DE",11];
pc8001.z80.ops[0x29]=["ADD16","HL","HL",11];
pc8001.z80.ops[0x39]=["ADD16","HL","SP",11];
pc8001.z80.ops[0xdd][0x09]=["ADD16","JX","BC",15];
pc8001.z80.ops[0xdd][0x19]=["ADD16","JX","DE",15];
pc8001.z80.ops[0xdd][0x29]=["ADD16","JX","JX",15];
pc8001.z80.ops[0xdd][0x39]=["ADD16","JX","SP",15];
pc8001.z80.ops[0xfd][0x09]=["ADD16","KY","BC",15];
pc8001.z80.ops[0xfd][0x19]=["ADD16","KY","DE",15];
pc8001.z80.ops[0xfd][0x29]=["ADD16","KY","KY",15];
pc8001.z80.ops[0xfd][0x39]=["ADD16","KY","SP",15];
pc8001.z80.mnemonics["ADD16"]=function(x,m){
  var t;
  t=pc8001.z80.regs[m[1].substr(0,1)]*256+pc8001.z80.regs[m[1].substr(1)];
  if(m[2]=="SP")
    t+=pc8001.z80.regs["SP"];
  else
    t+=pc8001.z80.regs[m[2].substr(0,1)]*256+pc8001.z80.regs[m[2].substr(1)];
  if(t>0xffff){
    pc8001.z80.flags["C"]=1;
    t&=0xffff;
  }
  else
    pc8001.z80.flags["C"]=0;
  pc8001.z80.regs[m[1].substr(0,1)]=t>>8;
  pc8001.z80.regs[m[1].substr(1)]=t&0xff;
}
pc8001.z80.mnemonics["ADD"]=function(x,m){
  var pc=pc8001.z80.regs["PC"];
  var a,t,u,v;
  switch(m[2].length){
    case 4:
      t=pc8001.memory[pc8001.z80.regs[m[2].substr(1,1)]*256+pc8001.z80.regs[m[2].substr(2,1)]];
      break;
    case 6:
      a=pc8001.memory[pc];
      pc8001.z80.regs["PC"]=pc=(pc+1)&0xffff;
      if(a>0x7f)
        a+=0xff00;
      a+=pc8001.z80.regs[m[2].substr(1,1)]*256+pc8001.z80.regs[m[2].substr(2,1)];
      a&=0xffff;
      t=pc8001.memory[a];
      break;
    default:
      if(m[2]=="n"){
        t=pc8001.memory[pc];
        pc8001.z80.regs["PC"]=pc=(pc+1)&0xffff;
      }
      else
        t=pc8001.z80.regs[m[2]];
  }
  u=pc8001.z80.regs[m[1]];
  v=t+u;
  pc8001.z80.flags["C"]=(v>0xff)?1:0;
  v&=0xff;
  pc8001.z80.regs[m[1]]=v;
  pc8001.z80.flags["Z"]=(v==0)?1:0;
  pc8001.z80.flags["M"]=(v>0x7f)?1:0;
  pc8001.z80.flags["V"]=((t>0x7f&&u>0x7f&&v<0x80)||(t<0x80&&u<0x80&&v>0x7f))?1:0;
  pc8001.z80.flags["H"]=((t&0x0f)+(u&0x0f)>0x0f)?1:0;
  pc8001.z80.flags["N"]=0;
}
pc8001.z80.ops[0xed][0x4a]=["ADC16","HL","BC",15]
pc8001.z80.ops[0xed][0x5a]=["ADC16","HL","DE",15]
pc8001.z80.ops[0xed][0x6a]=["ADC16","HL","HL",15]
pc8001.z80.ops[0xed][0x7a]=["ADC16","HL","SP",15]
pc8001.z80.mnemonics["ADC16"]=function(x,m){
  var t,u,v;
  t=pc8001.z80.regs[m[1].substr(0,1)]*256+pc8001.z80.regs[m[1].substr(1)];
  if(m[2]=="SP")
    u=pc8001.z80.regs["SP"];
  else
    u=pc8001.z80.regs[m[2].substr(0,1)]*256+pc8001.z80.regs[m[2].substr(1)];
  v=t+u+pc8001.z80.flags["C"]
  if(v>0xffff){
    pc8001.z80.flags["C"]=1;
    v&=0xffff;
  }
  else
    pc8001.z80.flags["C"]=0;
  pc8001.z80.regs[m[1].substr(0,1)]=v>>8;
  pc8001.z80.regs[m[1].substr(1)]=v&0xff;
  pc8001.z80.flags["Z"]=(v==0)?1:0;
  pc8001.z80.flags["M"]=(v>0x7fff)?1:0;
  pc8001.z80.flags["V"]=((u<0x8000&&t<0x8000&&v>0x7fff)||(u>0x7fff&&t>0x7fff&&v<0x8000))?1:0;
}
pc8001.z80.mnemonics["ADC"]=function(x,m){
  var pc=pc8001.z80.regs["PC"];
  var a,t,u,v,c;
  switch(m[2].length){
    case 4:
      t=pc8001.memory[pc8001.z80.regs[m[2].substr(1,1)]*256+pc8001.z80.regs[m[2].substr(2,1)]];
      break;
    case 6:
      a=pc8001.memory[pc];
      pc8001.z80.regs["PC"]=pc=(pc+1)&0xffff;
      if(a>0x7f)
        a+=0xff00;
      a+=pc8001.z80.regs[m[2].substr(1,1)]*256+pc8001.z80.regs[m[2].substr(2,1)];
      a&=0xffff;
      t=pc8001.memory[a];
      break;
    default:
      if(m[2]=="n"){
        t=pc8001.memory[pc];
        pc8001.z80.regs["PC"]=pc=(pc+1)&0xffff;
      }
      else
        t=pc8001.z80.regs[m[2]];
  }
  u=pc8001.z80.regs[m[1]];
  c=pc8001.z80.flags["C"];
  v=t+u+c;
  pc8001.z80.flags["C"]=(v>0xff)?1:0;
  v&=0xff;
  pc8001.z80.regs[m[1]]=v;
  pc8001.z80.flags["Z"]=(v==0)?1:0;
  pc8001.z80.flags["M"]=(v>0x7f)?1:0;
  pc8001.z80.flags["V"]=((t>0x7f&&u>0x7f&&v<0x80)||(t<0x80&&u<0x80&&v>0x7f))?1:0;
  pc8001.z80.flags["H"]=((t&0x0f)+(u&0x0f)+c>0x0f)?1:0;
  pc8001.z80.flags["N"]=0;
}
pc8001.z80.ops[0xed][0x44]=["NEG","A",8];
pc8001.z80.mnemonics["NEG"]=function(x,m){
  var t=(256-pc8001.z80.regs[m[1]])&0xff;
  pc8001.z80.regs[m[1]]=t;
  pc8001.z80.flags["Z"]=(t==0)?1:0;
  pc8001.z80.flags["C"]=(t==0)?0:1;
  pc8001.z80.flags["M"]=(t>0x7f)?1:0;
  pc8001.z80.flags["V"]=(t==0x80)?1:0;
  pc8001.z80.flags["H"]=((t&0x0f)==0)?0:1;
  pc8001.z80.flags["N"]=1;
}
pc8001.z80.mnemonics["SUB"]=function(x,m){
  var pc=pc8001.z80.regs["PC"];
  var a,t,u,v;
  switch(m[2].length){
    case 4:
      t=pc8001.memory[pc8001.z80.regs[m[2].substr(1,1)]*256+pc8001.z80.regs[m[2].substr(2,1)]];
      break;
    case 6:
      a=pc8001.memory[pc];
      pc8001.z80.regs["PC"]=pc=(pc+1)&0xffff;
      if(a>0x7f)
        a+=0xff00;
      a+=pc8001.z80.regs[m[2].substr(1,1)]*256+pc8001.z80.regs[m[2].substr(2,1)];
      a&=0xffff;
      t=pc8001.memory[a];
      break;
    default:
      if(m[2]=="n"){
        t=pc8001.memory[pc];
        pc8001.z80.regs["PC"]=pc=(pc+1)&0xffff;
      }
      else
        t=pc8001.z80.regs[m[2]];
  }
  u=pc8001.z80.regs[m[1]];
  v=u-t;
  pc8001.z80.flags["C"]=(v<0)?1:0;
  v=(v+256)&0xff;
  pc8001.z80.regs[m[1]]=v;
  pc8001.z80.flags["Z"]=(v==0)?1:0;
  pc8001.z80.flags["M"]=(v>0x7f)?1:0;
  pc8001.z80.flags["V"]=((u<0x80&&t>0x7f&&v>0x7f)||(u>0x7f&&t<0x80&&v<0x80))?1:0;
  pc8001.z80.flags["H"]=((u&0x0f)-(t&0x0f)<0)?1:0;
  pc8001.z80.flags["N"]=1;
}
pc8001.z80.ops[0xed][0x42]=["SBC16","HL","BC",15]
pc8001.z80.ops[0xed][0x52]=["SBC16","HL","DE",15]
pc8001.z80.ops[0xed][0x62]=["SBC16","HL","HL",15]
pc8001.z80.ops[0xed][0x72]=["SBC16","HL","SP",15]
pc8001.z80.mnemonics["SBC16"]=function(x,m){
  var t,u,v;
  t=pc8001.z80.regs[m[1].substr(0,1)]*256+pc8001.z80.regs[m[1].substr(1)];
  if(m[2]=="SP")
    u=pc8001.z80.regs["SP"];
  else
    u=pc8001.z80.regs[m[2].substr(0,1)]*256+pc8001.z80.regs[m[2].substr(1)];
  v=t-u-pc8001.z80.flags["C"]
  if(v<0){
    pc8001.z80.flags["C"]=1;
    v=(v+65536)&0xffff;
  }
  else
    pc8001.z80.flags["C"]=0;
  pc8001.z80.regs[m[1].substr(0,1)]=v>>8;
  pc8001.z80.regs[m[1].substr(1)]=v&0xff;
  pc8001.z80.flags["Z"]=(v==0)?1:0;
  pc8001.z80.flags["M"]=(v>0x7fff)?1:0;
  pc8001.z80.flags["V"]=((u<0x8000&&t>0x7fff&&v>0x7fff)||(u>0x7fff&&t<0x8000&&v<0x8000))?1:0;
}
pc8001.z80.mnemonics["SBC"]=function(x,m){
  var pc=pc8001.z80.regs["PC"];
  var a,t,u,v,c;
  switch(m[2].length){
    case 4:
      t=pc8001.memory[pc8001.z80.regs[m[2].substr(1,1)]*256+pc8001.z80.regs[m[2].substr(2,1)]];
      break;
    case 6:
      a=pc8001.memory[pc];
      pc8001.z80.regs["PC"]=pc=(pc+1)&0xffff;
      if(a>0x7f)
        a+=0xff00;
      a+=pc8001.z80.regs[m[2].substr(1,1)]*256+pc8001.z80.regs[m[2].substr(2,1)];
      a&=0xffff;
      t=pc8001.memory[a];
      break;
    default:
      if(m[2]=="n"){
        t=pc8001.memory[pc];
        pc8001.z80.regs["PC"]=pc=(pc+1)&0xffff;
      }
      else
        t=pc8001.z80.regs[m[2]];
  }
  u=pc8001.z80.regs[m[1]];
  c=pc8001.z80.flags["C"];
  v=u-t-c;
  pc8001.z80.flags["C"]=(v<0)?1:0;
  v=(v+256)&0xff;
  pc8001.z80.regs[m[1]]=v;
  pc8001.z80.flags["Z"]=(v==0)?1:0;
  pc8001.z80.flags["M"]=(v>0x7f)?1:0;
  pc8001.z80.flags["V"]=((u<0x80&&t>0x7f&&v>0x7f)||(u>0x7f&&t<0x80&&v<0x80))?1:0;
  pc8001.z80.flags["H"]=((u&0x0f)-(t&0x0f)-c<0)?1:0;
  pc8001.z80.flags["N"]=1;
}
pc8001.z80.mnemonics["AND"]=function(x,m){
  var pc=pc8001.z80.regs["PC"];
  var a,t;
  switch(m[2].length){
    case 4:
      t=pc8001.memory[pc8001.z80.regs[m[2].substr(1,1)]*256+pc8001.z80.regs[m[2].substr(2,1)]];
      break;
    case 6:
      a=pc8001.memory[pc];
      pc8001.z80.regs["PC"]=pc=(pc+1)&0xffff;
      if(a>0x7f)
        a+=0xff00;
      a+=pc8001.z80.regs[m[2].substr(1,1)]*256+pc8001.z80.regs[m[2].substr(2,1)];
      a&=0xffff;
      t=pc8001.memory[a];
      break;
    default:
      if(m[2]=="n"){
        t=pc8001.memory[pc];
        pc8001.z80.regs["PC"]=pc=(pc+1)&0xffff;
      }
      else
        t=pc8001.z80.regs[m[2]];
  }
  t&=pc8001.z80.regs[m[1]];
  pc8001.z80.regs[m[1]]=t;
  pc8001.z80.flags["Z"]=(t==0)?1:0;
  pc8001.z80.flags["M"]=(t>0x7f)?1:0;
  pc8001.z80.flags["C"]=0;
  pc8001.z80.flags["H"]=1
  pc8001.z80.flags["N"]=0;
  t=(((t>>6)|4)^(t>>3)^t)&3;
  pc8001.z80.flags["V"]=((t>>2)^(t>>1)^t)&1;
}
pc8001.z80.ops[0x2f]=["CPL","A",4];
pc8001.z80.mnemonics["CPL"]=function(x,m){
  pc8001.z80.regs[m[1]]^=0xff;
  pc8001.z80.flags["H"]=1;
  pc8001.z80.flags["N"]=1;
}
pc8001.z80.mnemonics["XOR"]=function(x,m){
  var pc=pc8001.z80.regs["PC"];
  var a,t;
  switch(m[2].length){
    case 4:
      t=pc8001.memory[pc8001.z80.regs[m[2].substr(1,1)]*256+pc8001.z80.regs[m[2].substr(2,1)]];
      break;
    case 6:
      a=pc8001.memory[pc];
      pc8001.z80.regs["PC"]=pc=(pc+1)&0xffff;
      if(a>0x7f)
        a+=0xff00;
      a+=pc8001.z80.regs[m[2].substr(1,1)]*256+pc8001.z80.regs[m[2].substr(2,1)];
      a&=0xffff;
      t=pc8001.memory[a];
      break;
    default:
      if(m[2]=="n"){
        t=pc8001.memory[pc];
        pc8001.z80.regs["PC"]=pc=(pc+1)&0xffff;
      }
      else
        t=pc8001.z80.regs[m[2]];
  }
  t^=pc8001.z80.regs[m[1]];
  pc8001.z80.regs[m[1]]=t;
  pc8001.z80.flags["Z"]=(t==0)?1:0;
  pc8001.z80.flags["M"]=(t>0x7f)?1:0;
  pc8001.z80.flags["C"]=0;
  pc8001.z80.flags["H"]=0;
  pc8001.z80.flags["N"]=0;
  t=(((t>>6)|4)^(t>>3)^t)&3;
  pc8001.z80.flags["V"]=((t>>2)^(t>>1)^t)&1;
}
pc8001.z80.mnemonics["OR"]=function(x,m){
  var pc=pc8001.z80.regs["PC"];
  var a,t;
  switch(m[2].length){
    case 4:
      t=pc8001.memory[pc8001.z80.regs[m[2].substr(1,1)]*256+pc8001.z80.regs[m[2].substr(2,1)]];
      break;
    case 6:
      a=pc8001.memory[pc];
      pc8001.z80.regs["PC"]=pc=(pc+1)&0xffff;
      if(a>0x7f)
        a+=0xff00;
      a+=pc8001.z80.regs[m[2].substr(1,1)]*256+pc8001.z80.regs[m[2].substr(2,1)];
      a&=0xffff;
      t=pc8001.memory[a];
      break;
    default:
      if(m[2]=="n"){
        t=pc8001.memory[pc];
        pc8001.z80.regs["PC"]=pc=(pc+1)&0xffff;
      }
      else
        t=pc8001.z80.regs[m[2]];
  }
  t|=pc8001.z80.regs[m[1]];
  pc8001.z80.regs[m[1]]=t;
  pc8001.z80.flags["Z"]=(t==0)?1:0;
  pc8001.z80.flags["M"]=(t>0x7f)?1:0;
  pc8001.z80.flags["C"]=0;
  pc8001.z80.flags["H"]=0;
  pc8001.z80.flags["N"]=0;
  t=(((t>>6)|4)^(t>>3)^t)&3;
  pc8001.z80.flags["V"]=((t>>2)^(t>>1)^t)&1;
}
pc8001.z80.mnemonics["CP"]=function(x,m){
  var pc=pc8001.z80.regs["PC"];
  var a,t,u,v;
  switch(m[2].length){
    case 4:
      t=pc8001.memory[pc8001.z80.regs[m[2].substr(1,1)]*256+pc8001.z80.regs[m[2].substr(2,1)]];
      break;
    case 6:
      a=pc8001.memory[pc];
      pc8001.z80.regs["PC"]=pc=(pc+1)&0xffff;
      if(a>0x7f)
        a+=0xff00;
      a+=pc8001.z80.regs[m[2].substr(1,1)]*256+pc8001.z80.regs[m[2].substr(2,1)];
      a&=0xffff;
      t=pc8001.memory[a];
      break;
    default:
      if(m[2]=="n"){
        t=pc8001.memory[pc];
        pc8001.z80.regs["PC"]=pc=(pc+1)&0xffff;
      }
      else
        t=pc8001.z80.regs[m[2]];
  }
  u=pc8001.z80.regs[m[1]];
  v=u-t;
  pc8001.z80.flags["C"]=(v<0)?1:0;
  v=(v+256)&0xff;
  pc8001.z80.flags["Z"]=(v==0)?1:0;
  pc8001.z80.flags["M"]=(v>0x7f)?1:0;
  pc8001.z80.flags["V"]=((u<0x80&&t>0x7f&&v>0x7f)||(u>0x7f&&t<0x80&&v<0x80))?1:0;
  pc8001.z80.flags["H"]=((u&0x0f)-(t&0x0f)<0)?1:0;
  pc8001.z80.flags["N"]=1;
}
pc8001.z80.ops[0x37]=["SCF",4];
pc8001.z80.mnemonics["SCF"]=function(x,m){
  pc8001.z80.flags["C"]=1;
  pc8001.z80.flags["H"]=0;
  pc8001.z80.flags["N"]=0;
}
pc8001.z80.ops[0x3f]=["CCF",4];
pc8001.z80.mnemonics["CCF"]=function(x,m){
  pc8001.z80.flags["C"]^=1;
  pc8001.z80.flags["N"]=0;
}
pc8001.z80.ops[0x27]=["DAA",4];
pc8001.z80.mnemonics["DAA"]=function(x,m){
  var t=pc8001.z80.regs["A"];
  var v;
  if(pc8001.z80.flags["N"]==0){
    if(pc8001.z80.flags["C"]==0){
      v=((t>0x99)?0x60:0)+(((pc8001.z80.flags["H"]==1||(t&0x0f)>9))?6:0);
      pc8001.z80.flags["C"]=(t>0x99)?1:0;
    }
    else
      v=((pc8001.z80.flags["H"]==1)||((t&0x0f)>9)?0x66:0x60);
    pc8001.z80.flags["H"]=((t&0x0f)>9)?1:0;
  }
  else{
    if(pc8001.z80.flags["C"]==0){
      if(pc8001.z80.flags["H"]==0)
        v=((t>0x99)?0xa0:0)+(((t&0x0f)>9)?0xfa:0);
      else{
        v=(t>0x99)?0x9a:0xfa;
        pc8001.z80.flags["H"]=((t&0x0f)<6)?1:0;
      }
      pc8001.z80.flags["C"]=(t>0x99)?1:0;
    }
    else{
      v=(pc8001.z80.flags["H"]==0&&((t&0x0f)<10))?0xa0:0x9a;
      pc8001.z80.flags["H"]&=((t&0x0f)<6)?1:0;
    }
  }
  pc8001.z80.regs["A"]=(t+v)&0xff;
}
pc8001.z80.ops[0xc2]=["JP","NZ","nn",10];
pc8001.z80.ops[0xc3]=["JP","","nn",10];
pc8001.z80.ops[0xca]=["JP","Z","nn",10];
pc8001.z80.ops[0xd2]=["JP","NC","nn",10];
pc8001.z80.ops[0xda]=["JP","C","nn",10];
pc8001.z80.ops[0xe2]=["JP","NV","nn",10];
pc8001.z80.ops[0xea]=["JP","V","nn",10];
pc8001.z80.ops[0xf2]=["JP","NM","nn",10];
pc8001.z80.ops[0xfa]=["JP","M","nn",10];
pc8001.z80.ops[0xe9]=["JP","","(HL)",4];
pc8001.z80.ops[0xdd][0xe9]=["JP","","(JX)",8];
pc8001.z80.ops[0xfd][0xe9]=["JP","","(KY)",8];
pc8001.z80.mnemonics["JP"]=function(x,m){
  var pc=pc8001.z80.regs["PC"];
  var c=1;
  switch(m[1].length){
    case 1:
      c=pc8001.z80.flags[m[1]];
      break;
    case 2:
      c=1-pc8001.z80.flags[m[1].substr(1)];
  }
  if(c==0){
    if(m[2]=="nn")
      pc8001.z80.regs["PC"]=(pc+2)&0xffff;
    return;
  }
  switch(m[2].length){
    case 2:
      pc8001.z80.regs["PC"]=pc8001.memory[pc]+pc8001.memory[(pc+1)&0xffff]*256;
      return;
    case 4:
      pc8001.z80.regs["PC"]=pc8001.z80.regs[m[2].substr(1,1)]*256+pc8001.z80.regs[m[2].substr(2,1)];
      return;
  }
}
pc8001.z80.ops[0x10]=["JR","DJNZ","e",13];
pc8001.z80.ops[0x18]=["JR","","e",12];
pc8001.z80.ops[0x20]=["JR","NZ","e",12];
pc8001.z80.ops[0x28]=["JR","Z","e",12];
pc8001.z80.ops[0x30]=["JR","NC","e",12];
pc8001.z80.ops[0x38]=["JR","C","e",12];
pc8001.z80.mnemonics["JR"]=function(x,m){
  var pc=pc8001.z80.regs["PC"];
  var c=1;
  switch(m[1].length){
    case 1:
      c=pc8001.z80.flags[m[1]];
      break;
    case 2:
      c=1-pc8001.z80.flags[m[1].substr(1)];
      break;
    case 4:
      pc8001.z80.regs["B"]=c=(pc8001.z80.regs["B"]+0xff)&0xff;
  }
  if(c==0){
    if(m[2]=="e")
      pc8001.z80.regs["PC"]=(pc+1)&0xffff;
    return;
  }
  c=pc8001.memory[pc];
  pc8001.z80.regs["PC"]=((c>0x7f)?pc+0xff01+c:pc+1+c)&0xffff;
}
pc8001.z80.ops[0xc4]=["CALL","NZ","nn",17];
pc8001.z80.ops[0xc7]=["CALL","","0000",11];
pc8001.z80.ops[0xcc]=["CALL","Z","nn",17];
pc8001.z80.ops[0xcd]=["CALL","","nn",17];
pc8001.z80.ops[0xcf]=["CALL","","0008",11];
pc8001.z80.ops[0xd4]=["CALL","NC","nn",17];
pc8001.z80.ops[0xd7]=["CALL","","0010",11];
pc8001.z80.ops[0xdc]=["CALL","C","nn",17];
pc8001.z80.ops[0xdf]=["CALL","","0018",11];
pc8001.z80.ops[0xe4]=["CALL","NV","nn",17];
pc8001.z80.ops[0xe7]=["CALL","","0020",11];
pc8001.z80.ops[0xec]=["CALL","V","nn",17];
pc8001.z80.ops[0xef]=["CALL","","0028",11];
pc8001.z80.ops[0xf4]=["CALL","NM","nn",17];
pc8001.z80.ops[0xf7]=["CALL","","0030",11];
pc8001.z80.ops[0xfc]=["CALL","M","nn",17];
pc8001.z80.ops[0xff]=["CALL","","0038",11];
pc8001.z80.mnemonics["CALL"]=function(x,m){
  var pc=pc8001.z80.regs["PC"];
  var sp=pc8001.z80.regs["SP"];
  var c=1;
  switch(m[1].length){
    case 1:
      c=pc8001.z80.flags[m[1]];
      break;
    case 2:
      c=1-pc8001.z80.flags[m[1].substr(1)];
  }
  if(c==0){
    if(m[2]=="nn")
      pc8001.z80.regs["PC"]=(pc+2)&0xffff;
    return;
  }
  if(m[2]=="nn"){
    a=pc8001.memory[pc]+pc8001.memory[(pc+1)&0xffff]*256;
    pc=(pc+2)&0xffff;
  }
  else
    a=parseInt(m[2],16);
  pc8001.writeMemory((sp+0xffff)&0xffff,pc>>8);
  pc8001.z80.regs["SP"]=sp=(sp+0xfffe)&0xffff;
  pc8001.writeMemory(sp,pc&0xff);
  pc8001.z80.regs["PC"]=a;
}
pc8001.z80.ops[0xc0]=["RET","NZ",11];
pc8001.z80.ops[0xc8]=["RET","Z",11];
pc8001.z80.ops[0xc9]=["RET","",10];
pc8001.z80.ops[0xd0]=["RET","NC",11];
pc8001.z80.ops[0xd8]=["RET","C",11];
pc8001.z80.ops[0xe0]=["RET","NV",11];
pc8001.z80.ops[0xe8]=["RET","V",11];
pc8001.z80.ops[0xf0]=["RET","NM",11];
pc8001.z80.ops[0xf8]=["RET","M",11];
pc8001.z80.mnemonics["RET"]=function(x,m){
  var sp=pc8001.z80.regs["SP"];
  var c=1;
  switch(m[1].length){
    case 1:
      c=pc8001.z80.flags[m[1]];
      break;
    case 2:
      c=1-pc8001.z80.flags[m[1].substr(1)];
  }
  if(c==0)
    return;
  pc8001.z80.regs["PC"]=pc8001.memory[sp]+pc8001.memory[(sp+1)&0xffff]*256;
  pc8001.z80.regs["SP"]=(sp+2)&0xffff;
}
pc8001.z80.ops[0xc5]=["PUSH","BC",11];
pc8001.z80.ops[0xd5]=["PUSH","DE",11];
pc8001.z80.ops[0xe5]=["PUSH","HL",11];
pc8001.z80.ops[0xf5]=["PUSH","AF",11];
pc8001.z80.ops[0xdd][0xe5]=["PUSH","JX",15];
pc8001.z80.ops[0xfd][0xe5]=["PUSH","KY",15];
pc8001.z80.mnemonics["PUSH"]=function(x,m){
  var sp=pc8001.z80.regs["SP"];
  pc8001.writeMemory((sp+0xffff)&0xffff,pc8001.z80.regs[m[1].substr(0,1)]);
  pc8001.z80.regs["SP"]=sp=(sp+0xfffe)&0xffff;
  if(m[1]=="AF")
    pc8001.writeMemory(sp,(pc8001.z80.flags["DUMMY"]&0x28)|pc8001.z80.flags["C"]|(pc8001.z80.flags["N"]<<1)|(pc8001.z80.flags["V"]<<2)|(pc8001.z80.flags["H"]<<4)|(pc8001.z80.flags["Z"]<<6)|(pc8001.z80.flags["M"]<<7));
  else
    pc8001.writeMemory(sp,pc8001.z80.regs[m[1].substr(1)]);
}
pc8001.z80.ops[0xc1]=["POP","BC",10];
pc8001.z80.ops[0xd1]=["POP","DE",10];
pc8001.z80.ops[0xe1]=["POP","HL",10];
pc8001.z80.ops[0xf1]=["POP","AF",10];
pc8001.z80.ops[0xdd][0xe1]=["POP","JX",14];
pc8001.z80.ops[0xfd][0xe1]=["POP","KY",14];
pc8001.z80.mnemonics["POP"]=function(x,m){
  var sp=pc8001.z80.regs["SP"];
  var t=pc8001.memory[sp];
  if(m[1]=="AF"){
    pc8001.z80.flags["C"]=((t&1)==0)?0:1;
    pc8001.z80.flags["N"]=((t&2)==0)?0:1;
    pc8001.z80.flags["V"]=((t&4)==0)?0:1;
    pc8001.z80.flags["H"]=((t&0x10)==0)?0:1;
    pc8001.z80.flags["Z"]=((t&0x40)==0)?0:1;
    pc8001.z80.flags["M"]=((t&0x80)==0)?0:1;
    pc8001.z80.flags["DUMMY"]=t;
  }
  else
    pc8001.z80.regs[m[1].substr(1)]=t;
  pc8001.z80.regs[m[1].substr(0,1)]=pc8001.memory[(sp+1)&0xffff];
  pc8001.z80.regs["SP"]=(sp+2)&0xffff;
}
pc8001.z80.ops[0x07]=["RLCA",4];
pc8001.z80.mnemonics["RLCA"]=function(x,m){
  var t=pc8001.z80.regs["A"];
  var c=(t>0x7f)?1:0;
  pc8001.z80.regs["A"]=((t<<1)+c)&0xff;
  pc8001.z80.flags["C"]=c;
  pc8001.z80.flags["H"]=0;
  pc8001.z80.flags["N"]=0;
}
pc8001.z80.mnemonics["RLC"]=function(x,m){
  var a,t,c;
  switch(m[1].length){
    case 4:
      a=pc8001.z80.regs[m[1].substr(1,1)]*256+pc8001.z80.regs[m[1].substr(2,1)];
      t=pc8001.memory[a];
      break;
    case 7:
      a=parseInt(m[1].substr(4,2),16);
      if(a>0x7f)
        a+=0xff00;
      a+=pc8001.z80.regs[m[1].substr(1,1)]*256+pc8001.z80.regs[m[1].substr(2,1)];
      a&=0xffff;
      t=pc8001.memory[a];
      break;
    default:
      a=-1;
      t=pc8001.z80.regs[m[1]];
  }
  c=(t>0x7f)?1:0;
  t=((t<<1)+c)&0xff;
  if(a<0)
    pc8001.z80.regs[m[1]]=t;
  else
    pc8001.writeMemory(a,t);
  pc8001.z80.flags["C"]=c;
  pc8001.z80.flags["Z"]=(t==0)?1:0;
  pc8001.z80.flags["M"]=(t>0x7f)?1:0;
  pc8001.z80.flags["H"]=0;
  pc8001.z80.flags["N"]=0;
  t=(((t>>6)|4)^(t>>3)^t)&3;
  pc8001.z80.flags["V"]=((t>>2)^(t>>1)^t)&1;
}
pc8001.z80.ops[0x0f]=["RRCA",4];
pc8001.z80.mnemonics["RRCA"]=function(x,m){
  var t=pc8001.z80.regs["A"];
  var c=t&1;
  pc8001.z80.regs["A"]=(t>>1)+c*0x80;
  pc8001.z80.flags["C"]=c;
  pc8001.z80.flags["H"]=0;
  pc8001.z80.flags["N"]=0;
}
pc8001.z80.mnemonics["RRC"]=function(x,m){
  var a,t,c;
  switch(m[1].length){
    case 4:
      a=pc8001.z80.regs[m[1].substr(1,1)]*256+pc8001.z80.regs[m[1].substr(2,1)];
      t=pc8001.memory[a];
      break;
    case 7:
      a=parseInt(m[1].substr(4,2),16);
      if(a>0x7f)
        a+=0xff00;
      a+=pc8001.z80.regs[m[1].substr(1,1)]*256+pc8001.z80.regs[m[1].substr(2,1)];
      a&=0xffff;
      t=pc8001.memory[a];
      break;
    default:
      a=-1;
      t=pc8001.z80.regs[m[1]];
  }
  c=t&1;
  t=(t>>1)+c*0x80;
  if(a<0)
    pc8001.z80.regs[m[1]]=t;
  else
    pc8001.writeMemory(a,t);
  pc8001.z80.flags["C"]=c;
  pc8001.z80.flags["Z"]=(t==0)?1:0;
  pc8001.z80.flags["M"]=(t>0x7f)?1:0;
  pc8001.z80.flags["H"]=0;
  pc8001.z80.flags["N"]=0;
  t=(((t>>6)|4)^(t>>3)^t)&3;
  pc8001.z80.flags["V"]=((t>>2)^(t>>1)^t)&1;
}
pc8001.z80.ops[0x17]=["RLA",4];
pc8001.z80.mnemonics["RLA"]=function(x,m){
  var t=pc8001.z80.regs["A"];
  var c=(t>0x7f)?1:0;
  pc8001.z80.regs["A"]=((t<<1)+pc8001.z80.flags["C"])&0xff;
  pc8001.z80.flags["C"]=c;
  pc8001.z80.flags["H"]=0;
  pc8001.z80.flags["N"]=0;
}
pc8001.z80.mnemonics["RL"]=function(x,m){
  var a,t,c;
  switch(m[1].length){
    case 4:
      a=pc8001.z80.regs[m[1].substr(1,1)]*256+pc8001.z80.regs[m[1].substr(2,1)];
      t=pc8001.memory[a];
      break;
    case 7:
      a=parseInt(m[1].substr(4,2),16);
      if(a>0x7f)
        a+=0xff00;
      a+=pc8001.z80.regs[m[1].substr(1,1)]*256+pc8001.z80.regs[m[1].substr(2,1)];
      a&=0xffff;
      t=pc8001.memory[a];
      break;
    default:
      a=-1;
      t=pc8001.z80.regs[m[1]];
  }
  c=(t>0x7f)?1:0;
  t=((t<<1)+pc8001.z80.flags["C"])&0xff;
  if(a<0)
    pc8001.z80.regs[m[1]]=t;
  else
    pc8001.writeMemory(a,t);
  pc8001.z80.flags["C"]=c;
  pc8001.z80.flags["Z"]=(t==0)?1:0;
  pc8001.z80.flags["M"]=(t>0x7f)?1:0;
  pc8001.z80.flags["H"]=0;
  pc8001.z80.flags["N"]=0;
  t=(((t>>6)|4)^(t>>3)^t)&3;
  pc8001.z80.flags["V"]=((t>>2)^(t>>1)^t)&1;
}
pc8001.z80.ops[0x1f]=["RRA",4];
pc8001.z80.mnemonics["RRA"]=function(x,m){
  var t=pc8001.z80.regs["A"];
  pc8001.z80.regs["A"]=(t>>1)+pc8001.z80.flags["C"]*0x80;
  pc8001.z80.flags["C"]=t&1;
  pc8001.z80.flags["H"]=0;
  pc8001.z80.flags["N"]=0;
}
pc8001.z80.mnemonics["RR"]=function(x,m){
  var a,t,c;
  switch(m[1].length){
    case 4:
      a=pc8001.z80.regs[m[1].substr(1,1)]*256+pc8001.z80.regs[m[1].substr(2,1)];
      t=pc8001.memory[a];
      break;
    case 7:
      a=parseInt(m[1].substr(4,2),16);
      if(a>0x7f)
        a+=0xff00;
      a+=pc8001.z80.regs[m[1].substr(1,1)]*256+pc8001.z80.regs[m[1].substr(2,1)];
      a&=0xffff;
      t=pc8001.memory[a];
      break;
    default:
      a=-1;
      t=pc8001.z80.regs[m[1]];
  }
  c=t&1;
  t=(t>>1)+pc8001.z80.flags["C"]*0x80;
  if(a<0)
    pc8001.z80.regs[m[1]]=t;
  else
    pc8001.writeMemory(a,t);
  pc8001.z80.flags["C"]=c;
  pc8001.z80.flags["Z"]=(t==0)?1:0;
  pc8001.z80.flags["M"]=(t>0x7f)?1:0;
  pc8001.z80.flags["H"]=0;
  pc8001.z80.flags["N"]=0;
  t=(((t>>6)|4)^(t>>3)^t)&3;
  pc8001.z80.flags["V"]=((t>>2)^(t>>1)^t)&1;
}
pc8001.z80.mnemonics["SLA"]=function(x,m){
  var a,t;
  switch(m[1].length){
    case 4:
      a=pc8001.z80.regs[m[1].substr(1,1)]*256+pc8001.z80.regs[m[1].substr(2,1)];
      t=pc8001.memory[a];
      break;
    case 7:
      a=parseInt(m[1].substr(4,2),16);
      if(a>0x7f)
        a+=0xff00;
      a+=pc8001.z80.regs[m[1].substr(1,1)]*256+pc8001.z80.regs[m[1].substr(2,1)];
      a&=0xffff;
      t=pc8001.memory[a];
      break;
    default:
      a=-1;
      t=pc8001.z80.regs[m[1]];
  }
  t=t<<1;
  pc8001.z80.flags["C"]=(t>0xff)?1:0;
  t&=0xff;
  if(a<0)
    pc8001.z80.regs[m[1]]=t;
  else
    pc8001.writeMemory(a,t);
  pc8001.z80.flags["Z"]=(t==0)?1:0;
  pc8001.z80.flags["M"]=(t>0x7f)?1:0;
  pc8001.z80.flags["H"]=0;
  pc8001.z80.flags["N"]=0;
  t=(((t>>6)|4)^(t>>3)^t)&3;
  pc8001.z80.flags["V"]=((t>>2)^(t>>1)^t)&1;
}
pc8001.z80.mnemonics["SRA"]=function(x,m){
  var a,t;
  switch(m[1].length){
    case 4:
      a=pc8001.z80.regs[m[1].substr(1,1)]*256+pc8001.z80.regs[m[1].substr(2,1)];
      t=pc8001.memory[a];
      break;
    case 7:
      a=parseInt(m[1].substr(4,2),16);
      if(a>0x7f)
        a+=0xff00;
      a+=pc8001.z80.regs[m[1].substr(1,1)]*256+pc8001.z80.regs[m[1].substr(2,1)];
      a&=0xffff;
      t=pc8001.memory[a];
      break;
    default:
      a=-1;
      t=pc8001.z80.regs[m[1]];
  }
  pc8001.z80.flags["C"]=t&1;
  t=((t>>1)|(t&0x80));
  if(a<0)
    pc8001.z80.regs[m[1]]=t;
  else
    pc8001.writeMemory(a,t);
  pc8001.z80.flags["Z"]=(t==0)?1:0;
  pc8001.z80.flags["M"]=(t>0x7f)?1:0;
  pc8001.z80.flags["H"]=0;
  pc8001.z80.flags["N"]=0;
  t=(((t>>6)|4)^(t>>3)^t)&3;
  pc8001.z80.flags["V"]=((t>>2)^(t>>1)^t)&1;
}
pc8001.z80.mnemonics["SLL"]=function(x,m){
  var a,t;
  switch(m[1].length){
    case 4:
      a=pc8001.z80.regs[m[1].substr(1,1)]*256+pc8001.z80.regs[m[1].substr(2,1)];
      t=pc8001.memory[a];
      break;
    case 7:
      a=parseInt(m[1].substr(4,2),16);
      if(a>0x7f)
        a+=0xff00;
      a+=pc8001.z80.regs[m[1].substr(1,1)]*256+pc8001.z80.regs[m[1].substr(2,1)];
      a&=0xffff;
      t=pc8001.memory[a];
      break;
    default:
      a=-1;
      t=pc8001.z80.regs[m[1]];
  }
  t=(t<<1)|1;
  pc8001.z80.flags["C"]=(t>0xff)?1:0;
  t&=0xff;
  if(a<0)
    pc8001.z80.regs[m[1]]=t;
  else
    pc8001.writeMemory(a,t);
  pc8001.z80.flags["Z"]=(t==0)?1:0;
  pc8001.z80.flags["M"]=(t>0x7f)?1:0;
  pc8001.z80.flags["H"]=0;
  pc8001.z80.flags["N"]=0;
  t=(((t>>6)|4)^(t>>3)^t)&3;
  pc8001.z80.flags["V"]=((t>>2)^(t>>1)^t)&1;
}
pc8001.z80.mnemonics["SRL"]=function(x,m){
  var a,t;
  switch(m[1].length){
    case 4:
      a=pc8001.z80.regs[m[1].substr(1,1)]*256+pc8001.z80.regs[m[1].substr(2,1)];
      t=pc8001.memory[a];
      break;
    case 7:
      a=parseInt(m[1].substr(4,2),16);
      if(a>0x7f)
        a+=0xff00;
      a+=pc8001.z80.regs[m[1].substr(1,1)]*256+pc8001.z80.regs[m[1].substr(2,1)];
      a&=0xffff;
      t=pc8001.memory[a];
      break;
    default:
      a=-1;
      t=pc8001.z80.regs[m[1]];
  }
  pc8001.z80.flags["C"]=t&1;
  t=t>>1;
  if(a<0)
    pc8001.z80.regs[m[1]]=t;
  else
    pc8001.writeMemory(a,t);
  pc8001.z80.flags["Z"]=(t==0)?1:0;
  pc8001.z80.flags["M"]=0;
  pc8001.z80.flags["H"]=0;
  pc8001.z80.flags["N"]=0;
  t=(((t>>6)|4)^(t>>3)^t)&3;
  pc8001.z80.flags["V"]=((t>>2)^(t>>1)^t)&1;
}
pc8001.z80.mnemonics["BIT"]=function(x,m){
  var a,t;
  switch(m[2].length){
    case 4:
      a=pc8001.z80.regs[m[2].substr(1,1)]*256+pc8001.z80.regs[m[2].substr(2,1)];
      t=pc8001.memory[a];
      break;
    case 7:
      a=parseInt(m[2].substr(4,2),16);
      if(a>0x7f)
        a+=0xff00;
      a+=pc8001.z80.regs[m[2].substr(1,1)]*256+pc8001.z80.regs[m[2].substr(2,1)];
      a&=0xffff;
      t=pc8001.memory[a];
      break;
    default:
      a=-1;
      t=pc8001.z80.regs[m[2]];
  }
  pc8001.z80.flags["Z"]=((t&(1<<m[1]))==0)?1:0;
  pc8001.z80.flags["H"]=1;
  pc8001.z80.flags["N"]=0;
}
pc8001.z80.mnemonics["RES"]=function(x,m){
  var a,t
  switch(m[2].length){
    case 4:
      a=pc8001.z80.regs[m[2].substr(1,1)]*256+pc8001.z80.regs[m[2].substr(2,1)];
      t=pc8001.memory[a];
      break;
    case 7:
      a=parseInt(m[2].substr(4,2),16);
      if(a>0x7f)
        a+=0xff00;
      a+=pc8001.z80.regs[m[2].substr(1,1)]*256+pc8001.z80.regs[m[2].substr(2,1)];
      a&=0xffff;
      t=pc8001.memory[a];
      break;
    default:
      a=-1;
      t=pc8001.z80.regs[m[2]]
  }
  t&=(1<<m[1])^0xff;
  if(a<0)
    pc8001.z80.regs[m[2]]=t;
  else
    pc8001.writeMemory(a,t);
}
pc8001.z80.mnemonics["SET"]=function(x,m){
  var a,t;
  switch(m[2].length){
    case 4:
      a=pc8001.z80.regs[m[2].substr(1,1)]*256+pc8001.z80.regs[m[2].substr(2,1)];
      t=pc8001.memory[a];
      break;
    case 7:
      a=parseInt(m[2].substr(4,2),16);
      if(a>0x7f)
        a+=0xff00;
      a+=pc8001.z80.regs[m[2].substr(1,1)]*256+pc8001.z80.regs[m[2].substr(2,1)];
      a&=0xffff;
      t=pc8001.memory[a];
      break;
    default:
      a=-1;
      t=pc8001.z80.regs[m[2]]
  }
  t|=1<<m[1];
  if(a<0)
    pc8001.z80.regs[m[2]]=t;
  else
    pc8001.writeMemory(a,t);
}
pc8001.z80.ops[0xed][0x67]=["RRD",18];
pc8001.z80.mnemonics["RRD"]=function(x,m){
  var hl=pc8001.z80.regs["H"]*256+pc8001.z80.regs["L"];
  var c=pc8001.memory[hl];
  var t=pc8001.z80.regs["A"];
  pc8001.writeMemory(hl,(c>>4)|((t<<4)&0xf0))
  pc8001.z80.regs["A"]=t=(t&0xf0)|(c&0x0f);
  pc8001.z80.flags["Z"]=(t==0)?1:0;
  pc8001.z80.flags["M"]=(t>0x7f)?1:0;
  pc8001.z80.flags["H"]=0;
  pc8001.z80.flags["N"]=0;
  t=(((t>>6)|4)^(t>>3)^t)&3;
  pc8001.z80.flags["V"]=((t>>2)^(t>>1)^t)&1;
}
pc8001.z80.ops[0xed][0x6f]=["RLD",18];
pc8001.z80.mnemonics["RLD"]=function(x,m){
  var hl=pc8001.z80.regs["H"]*256+pc8001.z80.regs["L"];
  var c=pc8001.memory[hl];
  var t=pc8001.z80.regs["A"];
  pc8001.writeMemory(hl,((c<<4)&0xf0)|(t&0x0f))
  pc8001.z80.regs["A"]=t=(t&0xf0)|(c>>4);
  pc8001.z80.flags["Z"]=(t==0)?1:0;
  pc8001.z80.flags["M"]=(t>0x7f)?1:0;
  pc8001.z80.flags["H"]=0;
  pc8001.z80.flags["N"]=0;
  t=(((t>>6)|4)^(t>>3)^t)&3;
  pc8001.z80.flags["V"]=((t>>2)^(t>>1)^t)&1;
}
pc8001.z80.ops[0xed][0xa0]=["LDI",16];
pc8001.z80.mnemonics["LDI"]=function(x,m){
  var hl=pc8001.z80.regs["H"]*256+pc8001.z80.regs["L"];
  var de=pc8001.z80.regs["D"]*256+pc8001.z80.regs["E"];
  var bc=pc8001.z80.regs["B"]*256+pc8001.z80.regs["C"];
  pc8001.writeMemory(de,pc8001.memory[hl]);
  hl=(hl+1)&0xffff;
  de=(de+1)&0xffff;
  bc=(bc+0xffff)&0xffff;
  pc8001.z80.regs["H"]=hl>>8;
  pc8001.z80.regs["L"]=hl&0xff;
  pc8001.z80.regs["D"]=de>>8;
  pc8001.z80.regs["E"]=de&0xff;
  pc8001.z80.regs["B"]=bc>>8;
  pc8001.z80.regs["C"]=bc&0xff;
  pc8001.z80.flags["V"]=(bc==0)?0:1;
  pc8001.z80.flags["H"]=0;
  pc8001.z80.flags["N"]=0;
}
pc8001.z80.ops[0xed][0xb0]=["LDIR",21];
pc8001.z80.mnemonics["LDIR"]=function(x,m){
  pc8001.z80.mnemonics["LDI"](x,m);
  if(pc8001.z80.flags["V"]==1)
    pc8001.z80.regs["PC"]=(pc8001.z80.regs["PC"]+0xfffe)&0xffff;
}
pc8001.z80.ops[0xed][0xa8]=["LDD",16];
pc8001.z80.mnemonics["LDD"]=function(x,m){
  var hl=pc8001.z80.regs["H"]*256+pc8001.z80.regs["L"];
  var de=pc8001.z80.regs["D"]*256+pc8001.z80.regs["E"];
  var bc=pc8001.z80.regs["B"]*256+pc8001.z80.regs["C"];
  pc8001.writeMemory(de,pc8001.memory[hl]);
  hl=(hl+0xffff)&0xffff;
  de=(de+0xffff)&0xffff;
  bc=(bc+0xffff)&0xffff;
  pc8001.z80.regs["H"]=hl>>8;
  pc8001.z80.regs["L"]=hl&0xff;
  pc8001.z80.regs["D"]=de>>8;
  pc8001.z80.regs["E"]=de&0xff;
  pc8001.z80.regs["B"]=bc>>8;
  pc8001.z80.regs["C"]=bc&0xff;
  pc8001.z80.flags["V"]=(bc==0)?0:1;
  pc8001.z80.flags["H"]=0;
  pc8001.z80.flags["N"]=0;
}
pc8001.z80.ops[0xed][0xb8]=["LDDR",21];
pc8001.z80.mnemonics["LDDR"]=function(x,m){
  pc8001.z80.mnemonics["LDD"](x,m);
  if(pc8001.z80.flags["V"]==1)
    pc8001.z80.regs["PC"]=(pc8001.z80.regs["PC"]+0xfffe)&0xffff;
}
pc8001.z80.ops[0xed][0xa1]=["CPI",16];
pc8001.z80.mnemonics["CPI"]=function(x,m){
  var hl=pc8001.z80.regs["H"]*256+pc8001.z80.regs["L"];
  var bc=pc8001.z80.regs["B"]*256+pc8001.z80.regs["C"];
  var t=pc8001.z80.regs["A"];
  var u=pc8001.memory[hl];
  var v=(t-u+256)&0xff;
  hl=(hl+1)&0xffff;
  bc=(bc+0xffff)&0xffff;
  pc8001.z80.regs["H"]=hl>>8;
  pc8001.z80.regs["L"]=hl&0xff;
  pc8001.z80.regs["B"]=bc>>8;
  pc8001.z80.regs["C"]=bc&0xff;
  pc8001.z80.flags["Z"]=(v==0)?1:0;
  pc8001.z80.flags["M"]=(v>0x7f)?1:0;
  pc8001.z80.flags["V"]=(bc==0)?0:1;
  pc8001.z80.flags["H"]=((t&0x0f)-(u&0x0f)<0)?1:0;
  pc8001.z80.flags["N"]=1;
}
pc8001.z80.ops[0xed][0xb1]=["CPIR",21];
pc8001.z80.mnemonics["CPIR"]=function(x,m){
  pc8001.z80.mnemonics["CPI"](x,m);
  if(pc8001.z80.flags["V"]==1&&pc8001.z80.flags["Z"]==0)
    pc8001.z80.regs["PC"]=(pc8001.z80.regs["PC"]+0xfffe)&0xffff;
}
pc8001.z80.ops[0xed][0xa9]=["CPD",16];
pc8001.z80.mnemonics["CPD"]=function(x,m){
  var hl=pc8001.z80.regs["H"]*256+pc8001.z80.regs["L"];
  var bc=pc8001.z80.regs["B"]*256+pc8001.z80.regs["C"];
  var t=pc8001.z80.regs["A"];
  var u=pc8001.memory[hl];
  var v=(t-u+256)&0xff;
  hl=(hl+0xffff)&0xffff;
  bc=(bc+0xffff)&0xffff;
  pc8001.z80.regs["H"]=hl>>8;
  pc8001.z80.regs["L"]=hl&0xff;
  pc8001.z80.regs["B"]=bc>>8;
  pc8001.z80.regs["C"]=bc&0xff;
  pc8001.z80.flags["Z"]=(v==0)?1:0;
  pc8001.z80.flags["M"]=(v>0x7f)?1:0;
  pc8001.z80.flags["V"]=(bc==0)?0:1;
  pc8001.z80.flags["H"]=((t&0x0f)-(u&0x0f)<0)?1:0;
  pc8001.z80.flags["N"]=1;
}
pc8001.z80.ops[0xed][0xb9]=["CPDR",21];
pc8001.z80.mnemonics["CPDR"]=function(x,m){
  pc8001.z80.mnemonics["CPD"](x,m);
  if(pc8001.z80.flags["V"]==1&&pc8001.z80.flags["Z"]==0)
    pc8001.z80.regs["PC"]=(pc8001.z80.regs["PC"]+0xfffe)&0xffff;
}
pc8001.z80.ops[0xdb]=["IN","A","(n)",11];
pc8001.z80.mnemonics["IN"]=function(x,m){
  var c,t,pc;
  if(m[2]=="(n)"){
    pc=pc8001.z80.regs["PC"];
    c=pc8001.memory[pc]+pc8001.z80.regs[m[1]]*256;
    pc8001.z80.regs["PC"]=(pc+1)&0xffff;
  }
  else
    c=pc8001.z80.regs[m[2].substr(1,1)]*256+pc8001.z80.regs[m[2].substr(2,1)];
  pc8001.z80.regs[m[1]]=t=pc8001.inport16(c);
  if(m[2]!="(n)"){
    pc8001.z80.flags["Z"]=(t==0)?1:0;
    pc8001.z80.flags["M"]=(t>0x7f)?1:0;
    pc8001.z80.flags["H"]=0;
    pc8001.z80.flags["N"]=0;
    t=(((t>>6)|4)^(t>>3)^t)&3;
    pc8001.z80.flags["V"]=((t>>2)^(t>>1)^t)&1;
  }
}
pc8001.z80.ops[0xed][0xa2]=["INI",16];
pc8001.z80.mnemonics["INI"]=function(x,m){
  var hl=pc8001.z80.regs["H"]*256+pc8001.z80.regs["L"];
  var b=(pc8001.z80.regs["B"]+0xff)&0xff;
  pc8001.writeMemory(hl,pc8001.inport16(b*256+pc8001.z80.regs["C"]));
  hl=(hl+1)&0xffff;
  pc8001.z80.regs["H"]=hl>>8;
  pc8001.z80.regs["L"]=hl&0xff;
  pc8001.z80.regs["B"]=b;
  pc8001.z80.flags["Z"]=(b==0)?1:0;
  pc8001.z80.flags["N"]=1;
}
pc8001.z80.ops[0xed][0xb2]=["INIR",21];
pc8001.z80.mnemonics["INIR"]=function(x,m){
  pc8001.z80.mnemonics["INI"](x,m);
  if(pc8001.z80.flags["Z"]==0)
    pc8001.z80.regs["PC"]=(pc8001.z80.regs["PC"]+0xfffe)&0xffff;
}
pc8001.z80.ops[0xed][0xaa]=["IND",16];
pc8001.z80.mnemonics["IND"]=function(x,m){
  var hl=pc8001.z80.regs["H"]*256+pc8001.z80.regs["L"];
  var b=(pc8001.z80.regs["B"]+0xff)&0xff;
  pc8001.writeMemory(hl,pc8001.inport16(b*256+pc8001.z80.regs["C"]));
  hl=(hl+0xffff)&0xffff;
  pc8001.z80.regs["H"]=hl>>8;
  pc8001.z80.regs["L"]=hl&0xff;
  pc8001.z80.regs["B"]=b;
  pc8001.z80.flags["Z"]=(b==0)?1:0;
  pc8001.z80.flags["N"]=1;
}
pc8001.z80.ops[0xed][0xba]=["INDR",21];
pc8001.z80.mnemonics["INDR"]=function(x,m){
  pc8001.z80.mnemonics["IND"](x,m);
  if(pc8001.z80.flags["Z"]==0)
    pc8001.z80.regs["PC"]=(pc8001.z80.regs["PC"]+0xfffe)&0xffff;
}
pc8001.inport16=function(p){
  return pc8001.inports[p&0xff];
}
pc8001.z80.ops[0xd3]=["OUT","(n)","A",11];
pc8001.z80.mnemonics["OUT"]=function(x,m){
  var c,pc;
  if(m[1]=="(n)"){
    pc=pc8001.z80.regs["PC"];
    c=pc8001.memory[pc]+pc8001.z80.regs[m[2]]*256;
    pc8001.z80.regs["PC"]=(pc+1)&0xffff;
  }
  else
    c=pc8001.z80.regs[m[1].substr(1,1)]*256+pc8001.z80.regs[m[1].substr(2,1)];
  pc8001.outport16(c,pc8001.z80.regs[m[2]]);
}
pc8001.z80.ops[0xed][0xa3]=["OUTI",16];
pc8001.z80.mnemonics["OUTI"]=function(x,m){
  var hl=pc8001.z80.regs["H"]*256+pc8001.z80.regs["L"];
  var b=(pc8001.z80.regs["B"]+0xff)&0xff;
  pc8001.outport16(b*256+pc8001.z80.regs["C"],pc8001.memory[hl]);
  hl=(hl+1)&0xffff;
  pc8001.z80.regs["H"]=hl>>8;
  pc8001.z80.regs["L"]=hl&0xff;
  pc8001.z80.regs["B"]=b;
  pc8001.z80.flags["Z"]=(b==0)?1:0;
  pc8001.z80.flags["N"]=1;
}
pc8001.z80.ops[0xed][0xb3]=["OTIR",21];
pc8001.z80.mnemonics["OTIR"]=function(x,m){
  pc8001.z80.mnemonics["OUTI"](x,m);
  if(pc8001.z80.flags["Z"]==0)
    pc8001.z80.regs["PC"]=(pc8001.z80.regs["PC"]+0xfffe)&0xffff;
}
pc8001.z80.ops[0xed][0xab]=["OUTD",16];
pc8001.z80.mnemonics["OUTD"]=function(x,m){
  var hl=pc8001.z80.regs["H"]*256+pc8001.z80.regs["L"];
  var b=(pc8001.z80.regs["B"]+0xff)&0xff;
  pc8001.outport16(b*256+pc8001.z80.regs["C"],pc8001.memory[hl]);
  hl=(hl+0xffff)&0xffff;
  pc8001.z80.regs["H"]=hl>>8;
  pc8001.z80.regs["L"]=hl&0xff;
  pc8001.z80.regs["B"]=b;
  pc8001.z80.flags["Z"]=(b==0)?1:0;
  pc8001.z80.flags["N"]=1;
}
pc8001.z80.ops[0xed][0xbb]=["OTDR",21];
pc8001.z80.mnemonics["OTDR"]=function(x,m){
  pc8001.z80.mnemonics["OUTD"](x,m);
  if(pc8001.z80.flags["Z"]==0)
    pc8001.z80.regs["PC"]=(pc8001.z80.regs["PC"]+0xfffe)&0xffff;
}
pc8001.outport16=function(p,d){
  var t=pc8001.outports[p&0xff];
  pc8001.outports[p&0xff]=d;
  switch(p&0xff){
    case 0x10:
      return;
    case 0x30:
      if((d^t)==1)
        pc8001.resizeDisplay(((d&1)==1)?80:40,25);
      return;
    case 0x40:
      pc8001.beep.on=((d&0x20)==0)?0:1;
      if(((d^t)&6)!=0){
        switch(d&6){
          case 2:
            t=pc8001.calendar.command(pc8001.outports[0x10]);
            break;
          case 4:
            t=pc8001.calendar.shift(pc8001.outports[0x10]);
            break;
          default:
            return;
        }
        if(t==0)
          pc8001.inports[0x40]&=0xef;
        else
          pc8001.inports[0x40]|=0x10;
      }
      return;
    case 0x51:
      switch(d){
        case 0x20:
          pc8001.reverseDisplay(0);
          return;
        case 0x21:
          pc8001.reverseDisplay(1);
          return;
      }
      console.log("OUT (51H),",d);
      return;
  }
  pc8001.z80.mnemonics["UNDEF"](p&0xff,["UNDEF","OUT",0]);
}
pc8001.z80.ops[0xdd][0xcb]=["EXTCB","DD CB dd","JX",20];
pc8001.z80.ops[0xfd][0xcb]=["EXTCB","FD CB dd","KY",20];
pc8001.z80.mnemonics["EXTCB"]=function(x,m){
  var pc=pc8001.z80.regs["PC"];
  var d=pc8001.memory[pc];
  var e=pc8001.memory[(pc+1)&0xffff];
  var f=pc8001.z80.ops[0xcb][e].slice();
  pc8001.z80.regs["PC"]=(pc+2)&0xffff;
  if(f[f.length-2]=="(HL)"){
    f[f.length-2]="("+m[2]+"+"+d.toString(16).padStart(2,"0")+")";
    pc8001.z80.mnemonics[f[0]](e,f);
    return;
  }
  pc8001.z80.mnemonics["UNDEF"](e,["UNDEF",m[1],0]);
}
pc8001.z80.run=function(){
  var i,pc,v,m,s;
  for(i=0;i<4000;i++){
    pc=pc8001.z80.regs["PC"];
    v=pc8001.memory[pc];
    m=pc8001.z80.ops[v];
    pc8001.z80.regs["PC"]=pc=(pc+1)&0xffff;
    s=m[m.length-1];
    if(s<0){
      v=pc8001.memory[pc];
      m=m[v];
      pc8001.z80.regs["PC"]=pc=(pc+1)&0xffff;
      s=m[m.length-1];
    }
    pc8001.z80.states+=s;
    pc8001.z80.mnemonics[m[0]](v,m);
    if(pc8001.z80.halt==1)
      return;
    if(pc8001.beep.counter!=-1){
      v=Math.floor(pc8001.z80.states*pc8001.beep.audio.sampleRate/pc8001.z80.frequency)%pc8001.beep.refWave.length;
      if(v==pc8001.beep.counter){
        pc8001.beep.wave[v]=pc8001.beep.on*pc8001.beep.refWave[v];
        pc8001.beep.counter=(pc8001.beep.counter+1)%pc8001.beep.refWave.length;
      }
    }
    s=pc8001.z80.states-(performance.now()-pc8001.z80.millitimer)*pc8001.z80.millistates;
    if(s>1000)
      break;
  }
  if(s<0){
    pc8001.z80.states%=pc8001.z80.frequency;
    pc8001.z80.millitimer=performance.now()-pc8001.z80.states/pc8001.z80.millistates;
  }
  pc8001.z80.timer=setTimeout("clearTimeout(pc8001.z80.timer);pc8001.z80.run()",(s>1000)?s/pc8001.z80.millistates:0);
}
pc8001.run=function(){
  document.addEventListener("keydown",pc8001.keydown);
  document.addEventListener("keyup",pc8001.keyup);
  pc8001.z80.millitimer=performance.now();
  pc8001.z80.run();
}
</script>
<style>
.blink{
  animation: blink 1.5s step-end infinite
}
@keyframes blink{
  0% {opacity:1}
  75% {opacity:0}
}
</style>
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg"
 xmlns:xlink="http://www.w3.org/1999/xlink"
 width=984 height=624 viewBox="-2 -2 164 104"
 style="background-color:black"
 onload="pc8001.initDisplay(this);pc8001.run()">
</svg>
</body>
</html>
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?