PC-8001の160×100ドット画面は、文字単位でしか色をつけることができない。160×100のドット画面が80×25のキャラクタ画面上に実装されていて、各行ごとに色指定のためのアトリビュートエリアがある、というのがμPD3301の基本設計なのだが、画面上の各1バイトが2×4ドットに分割されていて、この2×4ドットを単位としてしか、色をつけることができないのだ。しかも、各行40バイトのアトリビュートエリアは、2バイト1組の「フリ」をしていながら、実はそうではない。とりあえずμPD3301カラーモードについて、アトリビュートエリアの奇数番地の意味を、色アトリビュート(黒・青・赤・マゼンタ・緑・シアン・黄・白)と制御アトリビュート(ノーマル・シークレット・点滅・反転・上下線)に分けて、見ていくことにしよう。
色アトリビュートは以下の16種類だが、「黒文字」と「黒ドット」は一般に見分けがつかない。
- 08H~0FH: 黒文字
- 18H~1FH: 黒ドット
- 28H~2FH: 青文字
- 38H~3FH: 青ドット
- 48H~4FH: 赤文字
- 58H~5FH: 赤ドット
- 68H~6FH: マゼンタ文字
- 78H~7FH: マゼンタドット
- 88H~8FH: 緑文字
- 98H~9FH: 緑ドット
- A8H~AFH: シアン文字
- B8H~BFH: シアンドット
- C8H~CFH: 黄文字
- D8H~DFH: 黄ドット
- E8H~EFH: 白文字
- F8H~FFH: 白ドット
制御アトリビュートは以下の32種類だが、「シークレット&点滅」は単なる「シークレット」と見分けがつかない。
- 00H,40H,80H,C0H: ノーマル
- 01H,41H,81H,C1H: シークレット
- 02H,42H,82H,C2H: 点滅
- 03H,43H,83H,C3H: シークレット&点滅
- 04H,44H,84H,C4H: 反転
- 05H,45H,85H,C5H: シークレット&反転
- 06H,46H,86H,C6H: 点滅&反転
- 07H,47H,87H,C7H: シークレット&点滅&反転
- 10H,50H,90H,D0H: 上線
- 11H,51H,91H,D1H: シークレット&上線
- 12H,52H,92H,D2H: 点滅&上線
- 13H,53H,93H,D3H: シークレット&点滅&上線
- 14H,54H,94H,D4H: 反転&上線
- 15H,55H,95H,D5H: シークレット&反転&上線
- 16H,56H,96H,D6H: 点滅&反転&上線
- 17H,57H,97H,D7H: シークレット&点滅&反転&上線
- 20H,60H,A0H,E0H: 下線
- 21H,61H,A1H,E1H: シークレット&下線
- 22H,62H,A2H,E2H: 点滅&下線
- 23H,63H,A3H,E3H: シークレット&点滅&下線
- 24H,64H,A4H,E4H: 反転&下線
- 25H,65H,A5H,E5H: シークレット&反転&下線
- 26H,66H,A6H,E6H: 点滅&反転&下線
- 27H,67H,A7H,E7H: シークレット&点滅&反転&下線
- 30H,70H,B0H,F0H: 上下線
- 31H,71H,B1H,F1H: シークレット&上下線
- 32H,72H,B2H,F2H: 点滅&上下線
- 33H,73H,B3H,F3H: シークレット&点滅&上下線
- 34H,74H,B4H,F4H: 反転&上下線
- 35H,75H,B5H,F5H: シークレット&反転&上下線
- 36H,76H,B6H,F6H: 反転&点滅&上下線
- 37H,77H,B7H,F7H: シークレット&点滅&反転&上下線
たとえば、6月29日の記事のドットイートゲームは、12行目のアトリビュートエリア(F8F0H~F917H)を、以下のバイト列で固定して使っている。
00 00 01 38 27 D8 29 38 50 38 50 38 50 38 50 38 50 38 50 38 50 38 50 38 50 38 50 38 50 38 50 38 50 38 50 38 50 38 50 00
この結果12行目は、0文字目が「ノーマル」(色は11行目の行末が引き継がれる)、1~38文字目がノーマル「青ドット」、39~40文字目がノーマル「黄ドット」、41~79文字目がノーマル「青ドット」で表示される。つまり、アトリビュートエリアの偶数番地で「変化点」を指定し、奇数番地で「変化先」の制御・色アトリビュートを指定しているわけである。なお、奇数番地は順番に処理される(シーケンス)が、偶数番地は集合(同じ値があっても1つにまとめる)とみなして値の小さい順に処理されるので、以下のバイト列でも同じ効果が得られる。
29 00 27 38 01 D8 00 38 50 38 50 38 50 38 50 38 50 38 50 38 50 38 50 38 50 38 50 38 50 38 50 38 50 38 50 38 50 38 50 00
この効果を使って、Cレジスタの色アトリビュートで、B行目(00H≦B≦18H)のD文字目からE-1文字目(00H≦D<E≦50H)を塗りつぶすZ80プログラムを書いてみよう。
C5 PUSH BC
78 LD A,B
87 ADD A,A
87 ADD A,A
87 ADD A,A
6F LD L,A
CB38 SRL B
3EA0 LD A,A0H
1F RRA
95 SUB A,L
6F LD L,A
78 LD A,B
DE0D SBC A,0DH
67 LD H,A
FD26EC LD K,ECH
DD210200 LD JX,0002H
4A LD C,D
0614 LD B,14H
7E LD A,(HL)
FE50 CP A,50H
3805 JR C,+7
B9 CP A,C
281C JR Z,+30
1812 JR +20
BB CP A,E
280D JR Z,+15
3804 JR C,+4
DD2C INC X
1811 JR +19
BA CP A,D
3004 JR NC,+6
FD24 INC K
180A JR +12
DD24 INC J
71 LD (HL),C
79 LD A,C
4B LD C,E
BA CP A,D
2802 JR Z,+4
0E50 LD C,50H
2C INC L
23 INC HL
10D8 DJNZ -38
79 LD A,C
FD4C LD C,K
CB31 SLL C
05 DEC B
09 ADD HL,BC
C1 POP BC
FE50 CP A,50H
D8 RET C
7B LD A,E
FE50 CP A,50H
DD7C LD A,J
3819 JR C,+27
B7 OR A,A
281C JR Z,+30
71 LD (HL),C
3D DEC A
C8 RET Z
DD4D LD C,X
0D DEC C
0600 LD B,00H
23 INC HL
2C INC L
EB EX DE,HL
87 ADD A,A
6F LD L,A
60 LD H,B
19 ADD HL,DE
EDA0 LDI
E0 RET NV
2C INC L
1C INC E
18F9 JR -5
B7 OR A,A
280D JR Z,+15
3D DEC A
20E4 JR NZ,-26
DD45 LD B,X
7E LD A,(HL)
71 LD (HL),C
4F LD C,A
23 INC HL
2C INC L
10F9 DJNZ -5
C9 RET
54 LD D,H
5D LD E,L
1D DEC E
1B DEC DE
1A LD A,(DE)
DD45 LD B,X
5E LD E,(HL)
71 LD (HL),C
4F LD C,A
7B LD A,E
23 INC HL
2C INC L
10F8 DJNZ -6
C9 RET
40年前の私(安岡孝一)は、このプログラム(の原型)の動作をPC-8001で確認したものの、その動作に確信が持てずオクラ入りしたものだ。何せ、アトリビュートエリアの偶数番地がグチャグチャな順序になってしまうので、デバッグもやりにくい。でも実際のところ、PC-8801やPC-8001mkⅡSRのN-BASICモードでも、ちゃんと動作した気がする。
以下のPC-8001エミュレータでは、μPD3301のこの動作をエミュレートしつつ、ドットスクロールを用いたドットイートゲームに、赤い「敵」を出現させてみた。赤い「敵」に捕まらないよう、テンキーの8 2 4 6(あるいは上下左右の矢印キー)で遊んでみてほしい。
<!DOCTYPE html><head><meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>PC-8001 Emulator by Koichi Yasuoka, July 5, 2025</title>
<script>
var pc8001=new Object();
pc8001.memory=new Array(65536);
pc8001.memory.fill(0x76);
["0000 C3 00 E0",
"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",
"1602 21 76 EA 11 81 06 7B 07 30 06 D3 10 3E 03", // read date
"1610 18 18 DB 40 B4 C6 10 CB 1E 7B E6 07 20 0A 7D D6",
"1620 7A 20 02 ED 67 2C 15 C8 3E 05 D3 40 06 3A 10 FE",
"1630 3E 01 32 67 EA D3 40 1D 18 CE",
"E000 31 FF FF 21 00 18 22 5A EA 26 FF 22 60 EA AF 32",
"E010 5F EA 3E 05 32 66 EA 01 19 50 CD 3A 09 CD 02 16",
"E020 3E 16 32 D2 E8 21 4C 40 22 D3 E8 CD A0 E0 C3 40",
"E030 E0",
"E040 CD 90 E3 DB 00 F6 AF FE BF CC 50 E5 DB 00 F6 AF",
"E050 FE EF CC 30 E5 DB 00 E6 04 20 0A DB 01 0F 30 E0",
"E060 CD B0 E4 18 08 DB 01 0F 38 D6 CD C0 E4 DB 00 F6",
"E070 AF FE BF 28 D4 FE EF 28 D9 DB 00 E6 04 20 0A DB",
"E080 01 0F 30 BC CD D0 E4 18 E4 DB 01 0F 38 B2 CD 00",
"E090 E5 18 DA",
"E0A0 06 19 C5 05 CD 20 E3 C1 10 F8 CD 50 E2 26 02 2E",
"E0B0 D1 E5 CD 70 E5 E1 7D C6 05 6F FE 35 20 F3 24 24",
"E0C0 2E D8 CB 44 28 02 2E D3 CD 50 E6 7D C6 0A 6F C6",
"E0D0 31 FE 64 38 F3 3E 01 94 67 07 38 D3 0F C6 05 67",
"E0E0 FE 52 20 CB 21 40 01 22 D0 E8 C9",
"E180 21 A3 E1 11 83 FE 01 0C 00 ED B0 01 02 18 11 4F",
"E190 43 CD C0 E3 01 E8 18 11 4F 44 CD C0 E3 DB 01 07",
"E1A0 38 FB C9 20 50 75 73 68 20 52 45 54 55 52 4E",
"E1B0 CD B0 E8 E6 68 C0 21 D2 E8 7E FE 0C C8 9F E6 02",
"E1C0 3D 86 77 C3 50 E2",
"E1D0 2A D3 E8 7D FE 4E D2 B0 E1 FE 28 38 06 CD B0 E8",
"E1E0 E6 08 C0 24 2C 22 D3 E8 C3 50 E2",
"E1F0 2A D3 E8 7C FE 03 DA B0 E1 FE 28 30 06 CD B0 E8",
"E200 E6 08 C0 25 2D 22 D3 E8 C3 50 E2",
"E210 CD B0 E8 E6 08 3A D2 E8 28 03 FE 0C D8 B7 20 02",
"E220 3E 19 3D 32 D2 E8 C3 50 E2",
"E230 CD B0 E8 E6 08 3A D2 E8 28 03 FE 0C D0 3C FE 19",
"E240 20 01 AF 32 D2 E8 C3 50 E2",
"E250 06 05 C5 3A D2 E8 80 D6 03 47 CD 20 E3 C1 10 F2",
"E260 3A D2 E8 B7 20 02 3E 19 3D 47 0E 58 ED 5B D3 E8",
"E270 CD C0 E3 3A D2 E8 47 0E 58 ED 5B D3 E8 CD C0 E3",
"E280 3A D2 E8 3C 47 D6 19 38 01 47 0E 58 ED 5B D3 E8",
"E290 CD C0 E3 3A D2 E8 FE 0E D0 FE 0B D8 2A D3 E8 7C",
"E2A0 FE 29 D0 7D FE 28 D8 16 03 3E 21 D3 51 0E 40 3E",
"E2B0 21 D3 40 06 40 10 FE 3E 01 D3 40 06 40 10 FE 0D",
"E2C0 20 ED 3E 20 D3 51 3E 21 D3 40 06 20 10 FE 3E 01",
"E2D0 D3 40 06 20 10 FE 0D 20 ED 15 20 CD CD 80 E1 21",
"E2E0 00 F3 11 01 F3 01 4F 00 70 ED B0 21 00 F3 11 78",
"E2F0 F3 01 B8 0B ED B0 C3 00 E0",
"E300 20 18 12 0D 0A 08 06 04 03 02 02 01 01 01 02 02",
"E310 03 04 06 08 0A 0D 12 18 20",
"E320 78 FE 19 38 07 C6 19 38 02 D6 32 47 FE 0C 28 2D",
"E330 68 26 E3 56 3E 50 92 5F C5 0E 38 CD C0 E3 C1 68",
"E340 26 E3 3E 50 96 57 1E 50 C5 0E 18 CD C0 E3 C1 68",
"E350 26 E3 5E 1D C8 1C 16 01 0E 18 C3 C0 E3 01 D8 0C",
"E360 11 29 27 CD C0 E3 01 38 0C 11 27 01 CD C0 E3 01",
"E370 38 0C 11 4F 29 CD C0 E3 01 18 0C 11 50 4F CD C0",
"E380 E3 21 5B B5 22 C7 F8 C9",
"E390 2A 7A EA 2B 22 7A EA 7C B5 C0 21 D2 E8 7E FE 0C",
"E3A0 28 06 9F E6 02 3D 86 77 2C 7E 3C FE 4F 30 01 77",
"E3B0 2C 35 20 01 34 C3 50 E2",
"E3C0 C5 78 87 87 87 6F CB 38 3E A0 1F 95 6F 78 DE 0D",
"E3D0 67 FD 26 EC DD 21 02 00 4A 06 14 7E FE 50 38 05",
"E3E0 B9 28 1C 18 12 BB 28 0D 38 04 DD 2C 18 11 BA 30",
"E3F0 04 FD 24 18 0A DD 24 71 79 4B BA 28 02 0E 50 2C",
"E400 23 10 D8 79 FD 4C CB 31 05 09 C1 FE 50 D8 7B FE",
"E410 50 DD 7C 38 19 B7 28 1C 71 3D C8 DD 4D 0D 06 00",
"E420 23 2C EB 87 6F 60 19 ED A0 E0 2C 1C 18 F9 B7 28",
"E430 0D 3D 20 E4 DD 45 7E 71 4F 23 2C 10 F9 C9 54 5D",
"E440 1D 1B 1A DD 45 5E 71 4F 7B 23 2C 10 F8 C9",
"E450 2A D0 E8 2B 22 D0 E8 7C B5 C0 0E 00 3E 21 D3 40",
"E460 41 10 FE 3E 01 D3 40 41 10 FE 3E 21 D3 40 41 10",
"E470 FE 3E 01 D3 40 41 10 FE 3E 21 D3 40 41 10 FE 3E",
"E480 01 D3 40 41 10 FE 0C 20 D3 CD 80 E1 21 00 F3 11",
"E490 01 F3 01 4F 00 70 ED B0 21 00 F3 11 78 F3 01 B8",
"E4A0 0B ED B0 31 FF FF CD A0 E0 C3 40 E0",
"E4B0 2A 3F F9 7C B5 E6 77 FE 33 C2 10 E8 C3 D0 E4",
"E4C0 2A 4F F8 7C B5 E6 EE FE CC C2 60 E8 C3 10 E5",
"E4D0 2A 3F F9 7C B5 FE 66 28 07 E6 77 FE 33 C2 70 E6",
"E4E0 3E 21 D3 40 7C E6 F8 67 7D E6 8F 6F 22 3F F9 CD",
"E4F0 70 E6 3E 01 D3 40 C3 50 E4",
"E500 2A 4F F8 7C B5 FE 66 28 07 E6 EE FE CC C2 B0 E5",
"E510 3E 21 D3 40 7C E6 F1 67 7D E6 1F 6F 22 4F F8 CD",
"E520 B0 E5 3E 01 D3 40 C3 50 E4",
"E530 3A C6 F8 FE 66 28 06 E6 F0 C0 C3 70 E7 3E 21 D3",
"E540 40 AF 32 C6 F8 CD 70 E7 3E 01 D3 40 C3 50 E4",
"E550 3A C9 F8 FE 66 28 06 E6 0F C0 C3 C0 E7 3E 21 D3",
"E560 40 AF 32 C9 F8 CD C0 E7 3E 01 D3 40 C3 50 E4",
"E570 CD C0 E6 D8 1A A0 C0 1A B0 12 CD B0 E8 4F E5 CD",
"E580 40 E6 1A A0 08 E1 CD 50 E7 08 C0 CD B0 E8 4F E5",
"E590 CD 40 E7 E1 1A A0 20 F3 E5 CD 40 E6 E1 1A A0 C0",
"E5A0 CD 50 E7 18 E6",
"E5B0 2A 4F F8 7C B5 E6 CC C2 60 E8 21 40 FE 11 88 F2",
"E5C0 01 50 00 ED B0 21 40 FE 11 C8 FD 06 50 1A E6 CC",
"E5D0 0F 0F 4F 7E E6 33 07 07 B1 77 23 13 10 EF 7D FE",
"E5E0 50 CA 30 E2 21 00 00 FE 68 28 07 FE E0 28 03 21",
"E5F0 5B B5 22 C7 F8 21 38 FF 19 EB 21 78 00 19 18 CB",
"E600 7C C6 05 67 CD C0 E6 D0 7C D6 A0 67 C3 C0 E6",
"E610 7C D6 05 67 CD C0 E6 D0 7C C6 A0 67 C3 C0 E6",
"E620 7D C6 05 6F CD C0 E6 D0 7D D6 64 6F C3 C0 E6",
"E630 7D D6 05 6F CD C0 E6 D0 7D C6 64 6F C3 C0 E6",
"E640 79 E6 30 DD 6F DD 26 E6 DD E9",
"E650 CD 00 E7 1A B0 12 CD 20 E7 1A B0 12 CD 10 E7 1A",
"E660 B0 12 CD 30 E7 1A B0 12 C9",
"E670 2A 3F F9 7C B5 E6 33 C2 10 E8 21 00 F3 11 B8 FE",
"E680 01 50 00 ED B0 21 00 F3 11 78 F3 06 50 1A E6 33",
"E690 07 07 4F 7E E6 CC 0F 0F B1 77 23 13 10 EF 7D FE",
"E6A0 90 CA 10 E2 21 00 00 FE 78 28 06 B7 28 03 21 5B",
"E6B0 B5 22 C7 F8 21 28 00 19 EB 21 88 FF 19 18 CC",
"E6C0 7C C6 B0 D6 60 D8 1F 5F 9F E6 0F 3C 47 3E CE 95",
"E6D0 D6 9C D8 E5 CB 47 28 02 CB 20 CB 4F 28 04 CB 20",
"E6E0 CB 20 E6 7C 57 CB 22 0F 0F 1F 67 9F E6 80 92 6F",
"E6F0 30 01 25 16 F3 19 EB E1 C9",
"E700 24 CD C0 E6 D0 7C D6 A0 67 C3 C0 E6",
"E710 25 CD C0 E6 D0 7C C6 A0 67 C3 C0 E6",
"E720 2C CD C0 E6 D0 7D D6 64 6F C3 C0 E6",
"E730 2D CD C0 E6 D0 7D C6 64 6F C3 C0 E6",
"E740 79 E6 30 DD 6F DD 26 E7 DD E9",
"E750 CD 40 E7 1A B0 12 CD 40 E7 1A B0 12 CD 40 E7 1A",
"E760 B0 12 CD 40 E7 1A B0 12 CD 40 E7 1A B0 12 C9",
"E770 21 00 F3 11 4F F3 1A 0F 0F 0F 0F 06 0A ED 6F 2C",
"E780 ED 6F 2C ED 6F 2C ED 6F 2C ED 6F 2C ED 6F 2C ED",
"E790 6F 2C ED 6F 23 10 E6 7D FE 90 CA D0 E1 21 00 00",
"E7A0 FE 78 28 03 21 5B B5 22 C7 F8 21 78 00 19 EB 21",
"E7B0 B1 FF 19 18 C1",
"E7C0 21 4F F3 11 00 F3 1A 06 0A ED 67 2D ED 67 2D ED",
"E7D0 67 2D ED 67 2D ED 67 2D ED 67 2D ED 67 2D ED 67",
"E7E0 2B 10 E6 7D FE 3F CA F0 E1 21 00 00 FE 27 28 03",
"E7F0 21 5B B5 22 C7 F8 21 78 00 19 EB 21 4F 00 19 18",
"E800 C5",
"E810 2A 3F F9 7C B5 E6 11 C0 21 00 F3 11 B8 FE 01 50",
"E820 00 ED B0 21 00 F3 11 78 F3 06 50 1A E6 11 07 07",
"E830 07 4E CB 39 CB 99 B1 77 23 13 10 EF 7D FE 90 CA",
"E840 10 E2 21 00 00 FE 78 28 06 B7 28 03 21 5B B5 22",
"E850 C7 F8 21 28 00 19 EB 21 88 FF 19 18 CC",
"E860 2A 4F F8 7C B5 E6 88 C0 21 40 FE 11 88 F2 01 50",
"E870 00 ED B0 21 40 FE 11 C8 FD 06 50 1A E6 88 0F 0F",
"E880 0F 4E CB 21 CB A1 B1 77 23 13 10 EF 7D FE 50 CA",
"E890 30 E2 21 00 00 FE 68 28 07 FE E0 28 03 21 5B B5",
"E8A0 22 C7 F8 21 38 FF 19 EB 21 78 00 19 18 CB",
"E8B0 E5 2A 76 EA 7C 07 0F CB 15 1F 8D 3D 67 22 76 EA",
"E8C0 E1 C9 00 00 00 00 00 00 00 00 00 00 E0 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[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>
