2120F3 LD HL,F320H
110300 LD DE,0003H
CB7B BIT 7,E
2009 JR NZ,+11
7B LD A,E
D310 OUT (10H),A
1D DEC E
1D DEC E
3E03 LD A,03H
181A JR +28
DB40 IN A,(40H)
E610 AND A,10H
B2 OR A,D
1F RRA
57 LD D,A
7B LD A,E
1D DEC E
E603 AND A,03H
200B JR NZ,+13
B2 OR A,D
27 DAA
C6F0 ADD A,F0H
CE40 ADC A,40H
77 LD (HL),A
2D DEC L
2D DEC L
280E JR Z,+16
3E05 LD A,05H
D340 OUT (40H),A
063A LD B,3AH
10FE DJNZ -0
3E01 LD A,01H
D340 OUT (40H),A
18CD JR -49
75 LD (HL),L
2178F3 LD HL,F378H
010011 LD BC,1100H
71 LD (HL),C
7D LD A,L
D682 SUB A,82H
380B JR C,+13
1F RRA
1F RRA
3804 JR C,+6
FE01 CP A,01H
2003 JR NZ,+5
C6F2 ADD A,F2H
77 LD (HL),A
2C INC L
2C INC L
10EB DJNZ -19
2E88 LD L,88H
36D6 LD (HL),D6H
DB01 IN A,(01H)
07 RLCA
38FB JR C,-3
18A0 JR -94
40年前の記憶を辿りつつ、PC-8001のカレンダークロックμPD1990ACから、64ビット分のデータを(40Hポートの第4ビット経由で1ビットずつ)受け取って、画面左上に4ビットずつ16文字で16進数表示するZ80プログラムを書いてみた。40Hポートの第1・第2ビットへのストローブは、私(安岡孝一)の記憶が確かなら750ステート確保する必要があるので、DJNZを58回でイイセンだろう。ただし、μPD1990ACはシフトレジスタを40ビット分(月に4ビット、曜に4ビット、日・時・分・秒にそれぞれBCD 2桁分8ビット)しか持っておらず、上位24ビット(BCD 6桁)分は何が出てくるかわからない。しかも、PC-8001の場合はバックアップ電池を内蔵していないので、電源を上げるたびに1月01日(日曜日)00時00分00秒になってしまう。これを、40年前そのままの形で、現代のJavaScriptでエミュレートするのは、あまりにもツライ。
以下のPC-8001エミュレータでは、単純に現在時刻を返すことにした。現在時刻をわざわざBCD変換して、それを1ビットずつ渡すのは、かなり無駄な気もするが、μPD1990ACがこういう仕様だったのだから仕方ない。なお、カレンダークロックへの書き込みは、今回は実装していない。リターンキーを押すと時刻を表示しなおすので、ぜひ動かしてみてほしい。
<!DOCTYPE html><head><meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>PC-8001 Emulator by Koichi Yasuoka, June 2, 2025</title>
<script>
var pc8001=new Object();
pc8001.memory=new Array(65536);
pc8001.memory.fill(0x76);
["0000 21 20 F3 11 03 00 CB 7B 20 09 7B D3 10 1D 1D 3E",
"0010 03 18 1A DB 40 E6 10 B2 1F 57 7B 1D E6 03 20 0B",
"0020 B2 27 C6 F0 CE 40 77 2D 2D 28 0E 3E 05 D3 40 06",
"0030 3A 10 FE 3E 01 D3 40 18 CD 75 21 78 F3 01 00 11",
"0040 71 7D D6 82 38 0B 1F 1F 38 04 FE 01 20 03 C6 F2",
"0050 77 2C 2C 10 EB 2E 88 36 D6 DB 01 07 38 FB 18 A0"
].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=40;
pc8001.display.initColor=0xe8;
pc8001.initDisplay=function(svg){
var d=pc8001.display;
var x,y,e,t,c;
d.svg=svg;
d.lines=25;
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=0;
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.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.writeMemory=function(address,data){
var t=pc8001.memory[address];
var d=pc8001.display;
var x,y,f,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;
}
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;
}
for(f=1;f==1;y=(y>d.lines-2)?0:y+1){
i=d.start+80+y*120;
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(pc8001.memory[i]==x){
i++;
t=d.colors[pc8001.memory[i]];
if(t=="control")
j=pc8001.memory[i]&0x3f;
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(0xff);
pc8001.keymap=new Array(256);
pc8001.keymap.fill([]);
pc8001.keymap[13]=[1,0x7f]; // enter-key
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];
}
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);
if(pc8001.beep.counter<0){
pc8001.beep.counter=pc8001.beep.on=0;
pc8001.beep.start=pc8001.z80.states;
pc8001.beep.oscillator.start();
}
}
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 3:
pc8001.calendar.readreg="00000000";
pc8001.calendar.writereg="";
pc8001.calendar.date=new Date();
return 0;
case 1:
d=pc8001.calendar.date;
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;
}
return (pc8001.calendar.readreg.slice(-1)=="1")?0x10:0;
}
pc8001.calendar.command(3);
pc8001.calendar.shift=function(b){
var t;
pc8001.calendar.writereg=((b==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][0x34]=["INC","(JX+d)",23];
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][0x35]=["DEC","(JX+d)",23];
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"]=1;
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"]=1;
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]&0x10);
break;
default:
return;
}
if(t==0)
pc8001.inports[0x40]&=0xef;
else
pc8001.inports[0x40]|=0x10;
}
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>