はじめに
この記事は、伝説のDOSコマンドTRANS.COMを現代に蘇らせてZ80用に書かれたプログラムを8086用に変換してみるというものです(タイトルまんまやな)。
TRANS.COMとは何か
TRANS.COMとは、例えばWikipediaのこの記事『86-DOS』
In July 1981, a month before the PC's release, Microsoft purchased all rights to 86-DOS from SCP for $50,000. It met IBM's main criteria: it looked like CP/M, and it was easy to adapt existing 8-bit CP/M programs to run under it, notably thanks to the TRANS command which would translate source files from 8080 to 8086 machine instructions.
あるいはこの記事『Source-to-source compiler』
A similar, but much less sophisticated program was TRANS.COM, written by Tim Paterson in 1980 as part of 86-DOS. It could translate some Z80 assembly source code into .ASM source code for the 8086, but supported only a subset of opcodes, registers and modes, often still requiring significant manual correction and rework afterwards. Also it did not carry out any register and jump optimizations.
に書かれている通り、CP/M用に書かれたプログラムをMS-DOSの前身である86-DOS用に変換するために用意されたコンバーターです。86-DOSや初期のMS-DOSの一部に付属したもののようですが、同様に初期から用意されたユーティリティーであるEDLIN.COMやDEBUG.COM等程寿命の長かったものではなかったようで、実際に使われたことがある方は少ないのではないかと思います。
蘇るTRANS.COM
過去にはオープンソースに否定的な立場を取っていたMS社ですが、現在は理解を示して過去の一部の製品のソースコードやバイナリをGitHubで研究用に公開してくれたりしており、MS-DOSについても同様の措置が執られています。
https://github.com/microsoft/MS-DOS
この中のv1.25のソースのフォルダに件のTRANS.COMのソースと思しきTRANS.ASMというファイルがあり、
https://github.com/microsoft/MS-DOS/blob/master/v1.25/source/TRANS.ASM
今回これをアセンブルして使用してみることとします。バイナリが配布されていればアセンブルの手間も要らなかったのですがそこはそれ、公開していただいているものをありがたく使わせてもらうこととしましょう。
また、86-DOS作者の現在の会社Paterson Technologyのwebページで86-DOSのマニュアル等公開されています。86-DOS User's Manualの中でTRANS.COMの使用方法の説明も確認できます。こちらも同様に参考になります。
TRANS.COM再アセンブル方針
先のTRANS.ASMの中身を見ると書式がMS-DOSでは見慣れたMASMのものとは違うことに気付きます。86-DOS User's ManualにASMというコマンドの使用方法が解説されており、初期のMS-DOSの開発にはこのアセンブラが使われていたようです。MS-DOS v1.25のソースディレクトリにこのアセンブラのソースと思われるASM.ASMというファイルがあり、これをアセンブルするとTRANS.ASMをアセンブルすることもできそうな感じではありますが、この記事の趣旨と違うので別のアセンブラ、今回はNasmでTRANS.ASMをアセンブルしTRANS.COMを生成してみることとします。
TRANS.COM再アセンブル手順
先ず、TRANS.ASMにバグらしい箇所があったのでそれを修正するパッチを用意します。
TRANS.ASM.patch1
--- TRANS.ASM
+++ TRANS.ASM
@@ -914,6 +914,7 @@ SHFT:
MOV AL,CH
CALL HEX
MOV AL,'H'
+ CLC
JMP PUTCH
OPTAB:
DW AOPS,BOPS,COPS,DOPS,EOPS
次いで、TRANS.COMは内部で当時の英語版のソフトに良くあったASCIIコードの文字列の最後をbit7をセットすることで表し、出力の際にはマスクをするということをやっており、日本語のコメントを通すのに問題となるのでそれを修正するパッチを用意します。
TRANS.ASM.patch2
--- TRANS.ASM
+++ TRANS.ASM
@@ -144,7 +144,7 @@ PUTCH:
XCHG AH,AL
PUSH AX
XCHG AH,AL
- AND AL,7FH
+; AND AL,7FH
MOV BX,[PUTPT]
MOV [BX],AL
INC BX
@@ -676,7 +676,9 @@ OUTSTR:
JNZ L0002
CALL NEWOP
L0002:
+ AND AL,7FH
CALL PUTCH
+ MOV AL,[BX]
INC BX
ADD AL,AL
JNC OUTSTR
あと、ASMの書式でNasmと互換性のないものについて解決する、互換マクロを用意します。
scpasm.inc
%macro MOVB 0
movsb
%endmacro
%macro LODB 0
lodsb
%endmacro
%macro SCAB 0
scasb
%endmacro
%macro RCR 1-*
%if %0 == 1
RCR %1, 1
%else
rcr %1, %2
%endif
%endmacro
%macro RCL 1-*
%if %0 == 1
RCL %1, 1
%else
rcl %1, %2
%endif
%endmacro
%macro UP 0
cld
%endmacro
%macro JP 1
jmp %1
%endmacro
%macro JMPS 1
jmp %1
%endmacro
%macro DM 1-*
%assign %%i 1
%rep %0
%ifstr %1
%assign %%j 1
%strlen %%l %1
%rep %%l
%substr %%c %1 %%j
%if %%i < %0 || %%j < %%l
db %%c
%else
db 80h | %%c
%endif
%assign %%j %%j + 1
%endrep
%else
%if %%i < %0
db %1
%else
db 80h | %1
%endif
%endif
%rotate 1
%assign %%i %%i + 1
%endrep
%endmacro
%macro DS 1
times %1 db 0
%endmacro
最後に、先のマクロで対応できない機能等についてTRANS.ASM全体に当てるパッチを用意します。
TRANS.ASM.patch3
--- TRANS.ASM
+++ TRANS.ASM
@@ -74,11 +74,11 @@ TRANLN:
CALL LOAD
MOV BX,OP1
CALL GETOP
- MOV B,[BX],0
+ MOV BYTE [BX],0
MOV BX,OP2
CALL GETOP
DOLIN:
- MOV B,[BX],0
+ MOV BYTE [BX],0
CALL FINDOP
ENLIN:
MOV SP,STACK
@@ -123,13 +123,13 @@ DELCHK:
CMP AL,';'
JZ DOLIN
CMP AL,' '
- JZ RET
+ JZ RET0
CMP AL,':'
- JZ RET
+ JZ RET0
CMP AL,','
- JZ RET
+ JZ RET0
CMP AL,9
- RET
+RET0: RET
HEX:
AND AL,0FH
ADD AL,90H
@@ -169,7 +169,7 @@ NOTAF:
POP CX
POP DX
POP BX
- RET
+RET1: RET
;
; Get character from source file.
;
@@ -224,9 +224,9 @@ LOADLP:
INC BX
CALL DELIM
JNZ LOADLP
- MOV B,[BX],0
+ MOV BYTE [BX],0
CMP AL,':'
- JNZ RET
+ JNZ RET1
MOV BX,OPCODE
CALL TRANS
JP ENLAB
@@ -248,7 +248,7 @@ OPCHAR:
LAHF
XCHG AX,BP
SAHF
- MOV B,[BX],'['
+ MOV BYTE [BX],'['
JP NEXCH
NOTLEF:
CMP AL,')'
@@ -260,11 +260,11 @@ NOTLEF:
LAHF
XCHG AX,BP
SAHF
- MOV B,[BX],']'
+ MOV BYTE [BX],']'
JP NEXCH
NOTRIT:
MOV [BX],AL
- CMP AL,''''
+ CMP AL,"'"
JZ EATQUO
CALL IDCHK
JNC GETID
@@ -276,7 +276,7 @@ IDRET:
JNZ OPCHAR
CMP AL,' '
JZ OPCHAR
- RET
+RET2: RET
EATQUO:
INC BX
CALL GETCH
@@ -285,20 +285,20 @@ EATQUO:
JZ L0000
CALL DELCHK
L0000:
- CMP AL,''''
+ CMP AL,"'"
JNZ EATQUO
JP NEXCH
IDCHK:
CMP AL,'0'
- JC RET
+ JC RET2
CMP AL,'9'+1
CMC
- JNC RET
+ JNC RET2
CMP AL,40H
- JC RET
+ JC RET2
AND AL,5FH
CMP AL,'A'
- JC RET
+ JC RET2
CMP AL,'Z'+1
CMC
RET
@@ -375,10 +375,10 @@ HAVRW:
PUSH BX
MOV AL,CL
MOV BX,IXSI
- CMP AL,RSI
+ CMP AL,RSI_-RBASE
JZ IXIY
MOV BX,IYDI
- CMP AL,RDI
+ CMP AL,RDI_-RBASE
JNZ NORW
IXIY:
LAHF
@@ -396,15 +396,15 @@ NOTENC:
SAHF
POP BX
DEC BX
- MOV B,[BX],'['
+ MOV BYTE [BX],'['
INC BX
- ADD AL,RIX-1
+ ADD AL,RIX-RBASE-1
MOV [BX],AL
INC BX
- MOV B,[BX],']'
+ MOV BYTE [BX],']'
INC BX
JP ENDRW
- RET
+RET3: RET
FINDOP:
MOV BX,OPCODE
MOV CX,5
@@ -417,13 +417,13 @@ FINDOP:
JNZ OPERR
MOV AL,4
SUB AL,CL
- JZ RET
+ JZ RET3
DEC AL
JZ OPERR
MOV CL,AL
DEC BX
DEC BX
- OR B,[BX],080H
+ OR BYTE [BX],080H
MOV AL,[OPCODE]
SUB AL,'A'
JC OPERR
@@ -462,7 +462,7 @@ LOOKLP:
JMP DX
NEXOP:
RCR SI
- TEST B,[BX],080H
+ TEST BYTE [BX],080H
RCL SI
LAHF
INC BX
@@ -518,19 +518,19 @@ TRANS:
INC BX
SAHF
OR AL,AL
- JZ RET
+ JZ RET4
CALL TRNTOK
JP TRANS
LCHECK:
MOV AL,[BX]
- CMP AL,RAL
- JNZ RET
+ CMP AL,RAL_-RBASE
+ JNZ RET4
MOV SI,DX
LODB
- CMP AL,RCX
- JZ RET
- CMP AL,RDX
- RET
+ CMP AL,RCX_-RBASE
+ JZ RET4
+ CMP AL,RDX_-RBASE
+RET4: RET
ONEOP:
CALL OUTSTR
@@ -545,7 +545,7 @@ TRAN1:
JP PTRANS
IN:
MOV AL,[OP1]
- CMP AL,RAL
+ CMP AL,RAL_-RBASE
XCHG DX,BX
MOV BX,OP2
JZ GETPORT
@@ -558,7 +558,7 @@ IN:
CALL ONEOP
MOV AL,','
CALL PUTCH
- MOV AL,RAL
+ MOV AL,RAL_-RBASE
CALL TRNTOK
IODONE:
MOV BX,RESTAX
@@ -567,7 +567,7 @@ OUT:
MOV AL,[OP2]
XCHG DX,BX
MOV BX,OP1
- CMP AL,RAL
+ CMP AL,RAL_-RBASE
JZ GETOUT
MOV BX,SAVEAX
CALL OUTSTR
@@ -597,23 +597,23 @@ GETPORT:
LAHF
DEC BX
SAHF
- MOV B,[BX],0
+ MOV BYTE [BX],0
POP BX
NOBRAK:
MOV AL,[BX]
- CMP AL,RGCL
+ CMP AL,RGCL-RBASE
JNZ FIXPOR
MOV BX,IO1
CALL OUTSTR
XCHG DX,BX
CALL OUTSTR
- MOV AL,RDX
+ MOV AL,RDX_-RBASE
CALL TRNTOK
MOV BX,IO2
JMP OUTSTR
GETOUT:
CALL GETPORT
- JNC RET
+ JNC RET5
MOV BX,BADIO
JMP OUTSTR
FIXPOR:
@@ -658,7 +658,7 @@ TRNTOK:
POP CX
POP BX
OR AL,AL
- JZ RET
+ JZ RET5
JMP PUTCH
PUSH:
MOV DX,PUSHAF
@@ -667,7 +667,7 @@ POP:
MOV DX,POPAF
AFCHK:
MOV AL,[OP1]
- CMP AL,RAX
+ CMP AL,RAX_-RBASE
JNZ ONEOPJ
XCHG DX,BX
OUTSTR:
@@ -682,7 +682,7 @@ L0002:
INC BX
ADD AL,AL
JNC OUTSTR
- RET
+RET5: RET
NEWOP:
MOV AL,13
CALL PUTCH
@@ -700,7 +700,7 @@ CPDR:
JP OUTSTR
ADD:
MOV AL,[OP1]
- CMP AL,RBX
+ CMP AL,RBX_-RBASE
JZ DAD
ARITH:
CALL OUTSTR
@@ -710,7 +710,7 @@ ARITH:
JMP TWOOPS
MOV AL,9
CALL PUTCH
- MOV AL,RAL
+ MOV AL,RAL_-RBASE
CALL TRNTOK
MOV AL,','
JMP TRAN1
@@ -718,7 +718,7 @@ ACCUM:
CALL OUTSTR
MOV AL,9
CALL PUTCH
- MOV AL,RAL
+ MOV AL,RAL_-RBASE
JMP TRNTOK
ONEOPJ: JMP ONEOP
DAD:
@@ -730,7 +730,7 @@ DAD:
INCDEC:
MOV AL,[OP1]
- CMP AL,RCX+1 ;16-bit?
+ CMP AL,RCX_-RBASE+1 ;16-bit?
JNC ONEOPJ
MOV BX,LAHF
CALL OUTSTR
@@ -763,18 +763,18 @@ OUTCON:
MOV AL,9
CALL PTRANS
MOV AL,CH
- CMP AL,ODDPAR
+ CMP AL,ODDPAR-RBASE
MOV BX,WARNPA
JZ OUTSTRJ
- CMP AL,EVEPAR
+ CMP AL,EVEPAR-RBASE
JZ OUTSTRJ
- RET
+RET6: RET
FIXCON:
MOV AL,[OP1]
- CMP AL,RGCL
- JNZ RET
- MOV AL,CY
- RET
+ CMP AL,RGCL-RBASE
+ JNZ RET6
+ MOV AL,CY-RBASE
+RET7: RET
RETURN:
MOV AL,[OP1]
OR AL,AL
@@ -811,21 +811,21 @@ L0003:
CALL OUTSTR
MOV BX,LABEL+4
NEXLAB:
- INC [BX]
+ INC WORD [BX]
MOV AL,[BX]
CMP AL,'9'+1
- JNZ RET
- MOV B,[BX],'0'
+ JNZ RET7
+ MOV BYTE [BX],'0'
LAHF
DEC BX
SAHF
JP NEXLAB
EX:
MOV AL,[OP1]
- CMP AL,RAX
+ CMP AL,RAX_-RBASE
JZ OUTSTRJ1
MOV AL,[OP1+1]
- CMP AL,STP
+ CMP AL,STP-RBASE
JZ XTHL
MOV BX,XCHG
CALL OUTSTR
@@ -841,9 +841,9 @@ PSEUDO:
CALL ONEOP
MOV AL,[OP2]
OR AL,AL
- JZ RET
+ JZ RET8
JMP TRNOP2
- RET
+RET8: RET
BITSET:
MOV CL,0
JP SETRES
@@ -871,30 +871,30 @@ L0005:
BYTCHK:
;Check if memory reference and add "B," for byte mode
- CMP B,[OP1],"[" ;Memory reference?
- JNZ RET
- CMP B,[OP1+1],RIX ;Referencing IX as a word?
- JZ RET
- CMP B,[OP1+1],RIY
- JZ RET
+ CMP BYTE [OP1],"[" ;Memory reference?
+ JNZ RET8
+ CMP BYTE [OP1+1],RIX-RBASE ;Referencing IX as a word?
+ JZ RET8
+ CMP BYTE [OP1+1],RIY-RBASE
+ JZ RET8
BFLAG:
CALL PUTCH
MOV AL,'B'
CALL PUTCH
MOV AL,','
- RET
+RET9: RET
GETBIT:
MOV AL,[OP1+1]
OR AL,AL
STC
- JNZ RET
+ JNZ RET9
MOV AL,[OP1]
SUB AL,'0'
- JC RET
+ JC RET9
CMP AL,8
CMC
- JC RET
+ JC RET9
MOV CH,AL
INC CH
XOR AL,AL
@@ -1009,7 +1009,7 @@ LOPS:
DM 'D'
DW LD,MOV
DM 'DIR'
- DW OUTSTR,UP
+ DW OUTSTR,UP_
DM 'DDR'
DW LDDR,DOWN
DB 0
@@ -1103,7 +1103,7 @@ PUSHAF: DB 'LAHF',0,'XCHG',9,'AH,AL',0,'
DM 'XCHG',9,'AH,AL'
POPAF: DM 'POP',9,'AX',0,'XCHG',9,'AH,AL',0,'SAHF'
DOWN: DM 'DOWN'
-UP: DB 'UP'
+UP_: DB 'UP'
BLMOVE: DB 0,'MOV',9,'SI,BX',0,'MOV',9,'DI,DX'
DB 0,'REP',0,'MOVB',0,'MOV',9,'DX,DI'
DM 0,'MOV',9,'BX,SI'
@@ -1192,25 +1192,26 @@ GETBUF: DS 128
PUTFCB: DS 33
DS 50
STACK: EQU $
- ORG 1 ;This is really just for equates without EQU
-RSI: DS 1
-RDI: DS 1
+ ;ORG 1 ;This is really just for equates without EQU
+RBASE: EQU $-1
+RSI_: DS 1
+RDI_: DS 1
ODDPAR: DS 1
EVEPAR: DS 1
DS 5 ;MINUS,PLUS,NOT ZERO,ZERO,NOT CARRY
CY: DS 1
-RAX: DS 1
+RAX_: DS 1
STP: DS 1
-RBX: DS 1
-RDX: DS 1
-RCX: DS 1
+RBX_: DS 1
+RDX_: DS 1
+RCX_: DS 1
RBL: DS 1
RBH: DS 1
RDL: DS 1
RDH: DS 1
RGCL: DS 1
RCH: DS 1
-RAL: DS 1
+RAL_: DS 1
RIX: DS 1
RIY: DS 1
\ No newline at end of file
以上を以下のように使用することで
$ patch < TRANS.ASM.patch1
patching file TRANS.ASM
$ patch < TRANS.ASM.patch2
patching file TRANS.ASM
$ patch < TRANS.ASM.patch3
patching file TRANS.ASM
$ nasm -fbin -p scpasm.inc TRANS.ASM -o TRANS.COM -l TRANS.LST
$ ls -l TRANS.COM
-rw-rw-r--+ 1 fujita なし 3685 Jan 1 00:00 TRANS.COM
$
Nasmを使用してTRANS.ASMをアセンブルしTRANS.COMを生成することができました。
TRANS.COM実行
今回テストに使用するプログラム
もう 5年ほど前になりますが『プロ生ちゃん #カレンダープログラミング プチコンテスト 2014』というのものがあり、そんときにウッカリ書いてしまったプログラムを再利用することとしました。
CP/MやMSX-DOSで動作させることを想定した万年カレンダープログラムです。
元のプログラムはインテルニモニックとザイログニモニックのちゃんぽんで記述していたのですが、今回の記事のためにザイログニモニックに統一して修正しています。
また、
PUTCRLF:LD A,CR
CALL PUTC
LD A,LF
DB 11H ; LD DE,203EH(2バイトスキップ)
PUTSPC: LD A,' '
PUTC: PUSH AF
2バイト先への分岐をするところでプログラムサイズ縮小のために分岐命令を使用せず、スキップしたい 2バイトを壊しても良いレジスタへの代入命令のオペランドとすることで 2バイトスキップするコーディングをしていた箇所があったのですが
PUTCRLF:LD A,CR
CALL PUTC
LD A,LF
JR PUTC
PUTSPC: LD A,' '
PUTC: PUSH AF
TRANS.COMで変換をするに当たり障害となりそうだったので普通の分岐命令に変更する修正を行っています。
CAL.MAC
BDOS EQU 0005H ; BDOS 番地
CONOUT EQU 2 ; コンソール出力
ARG1 EQU 005DH ; FCB+1
ARG2 EQU 006DH ; FCB2+1
CR EQU 0DH ; 復帰
LF EQU 0AH ; 改行
ASEG
ORG 100H
MAIN:
; DEに'年'取得
LD E,ARG1 ; コマンドプロンプトの第1引数
CALL GETNUM ; 数値を読み込み
PUSH DE ;
; (年+(年-1)/4-(年-1)/100+(年-1)/400) MOD 7
; →その年の最初の曜日をCに格納する
LD L,E ; HLに年
LD H,D ; DEに(年-1)
DEC DE ;
LD A,4 ; 4で割り
CALL DIV ;
ADD HL,DE ; HLに加える
LD A,25 ; '4で割った値'を25で割り
CALL DIV ;
OR A ; HLから引く
SBC HL,DE ;
LD A,4 ; ''4で割った値'を25で割った値'を4で割り
CALL DIV ;
ADD HL,DE ; HLに加える
EX DE,HL ; 7で割った剰余をCに代入
CALL DIV7 ;
LD C,A ;
POP DE ;
; 1月から入力された月までの月ごとの日数を求めBに代入する
LD H,1 ;
LOOP1: PUSH DE ;
LD B,31 ; 月の日数は基本31日
LD A,H
CP 2 ; 2月でないなら
JR NZ,SKIP1; 31日ある月(1月. 3月, 5月, 7月, 8月, 10月, 12月)判定へ
; 2月の日数判定
DEC B ; とりあえず2日減らす
DEC B ; (うるう年でなければあとで更に1日減らす)
LD A,E ; 4で割り切れないならうるう年でないので1日減らす
AND 03H ;
JR NZ,SKIP2;
LD A,100 ; 4で割り切れて
CALL DIV ; 100で割り切れないならうるう年なので判定終了
JR NZ,SKIP3;
LD A,E ; 4で割り切れて
AND 03H ; 100で割り切れて
JR Z,SKIP3 ; 400で割り切れるならうるう年なので判定終了
JR SKIP2 ; 4で割り切れて
; 100で割り切れて
; 400で割り切れないならうるう年でないので1日減らす
; 31日ある月(1月. 3月, 5月, 7月, 8月, 10月, 12月)か判定
SKIP1: ADD A,A ; 月を9倍しbit3が立っていれば31日ある月なので
ADD A,A ; 1日減らす処理をスキップする
ADD A,A ;
ADD A,H ;
AND 08H ;
JR NZ,SKIP3;
SKIP2: DEC B ; 1日減らす
; 先に求めたCに加えその次の月の最初の曜日を求める
SKIP3: LD A,C ; Cの値を7で割った余りを
CALL MOD7 ;
ADD A,B ; その月の日数を加え
LD C,A ; Cに格納する
; 入力された'月'まで繰り返し
LD E,ARG2 ; コマンドプロンプトの第2引数
CALL GETNUM ; 数値を読み込み
POP DE
INC H
CP H
JR NC,LOOP1
; 先にも求めた'その次の月の最初の曜日'から最後の月の日数を引き、
; その月の最初の曜日をCに代入する
LD A,C
SUB B
LD C,A
; カレンダーの最初の日曜日の日付(0未満だと先月)を求めHに代入
XOR A ; Hに 0-'その月の最初の曜日'+1 を代入
SUB C ;
LD H,A ;
LOOP2: INC H ;
LD A,H ; 1未満なら空白を出力
CP 1 ;
CALL M,PUTSPC; 空白を出力
JP M,SKIP6 ;
; 日付の10の位出力
LD D,'0'-1 ; Dに出力する数字の初期値を代入し
LOOP3: INC D ; 10を引けた数だけインクリメントする
SUB 10 ;
JR NC,LOOP3;
PUSH AF
LD A,D ; '0'だったらゼロサプレスの為に数字の代わりに空白を出力
CP '0' ;
JR NZ,SKIP4;
LD A,' ' ;
SKIP4: CALL PUTC ; 数字か空白を出力
POP AF ;
; 日付の1の位出力
ADD A,'0'+10; 数値→文字化(10引かれてるので+10)
SKIP6: CALL PUTC ; 空白か数字を出力
LD A,H ; 日付がその月の日数に達すれば改行して終了
CP B ;
JR Z,PUTCRLF; スタックに積まれてない状態でPUTCRLFにジャンプするので
; PUTCRLFの最後のRETでCCPに復帰する
LD DE,LOOP2; ループアドレスをスタックに積む
PUSH DE ;
ADD A,C ; (日付+'その月の最初の曜日')/7 を計算し
CALL MOD7 ; 剰余がなければ土曜日なので改行してループ
JR Z,PUTCRLF;
JR PUTSPC ; 土曜日以外なので空白を出力しループ
;---------------------------------------
; 7で除算
; 入力: A: 被除数
; 出力: DE: 商
; : A: 剰余
; : Z: 剰余なしでセット
;---------------------------------------
MOD7: LD E,A
LD D,0
;---------------------------------------
; 7で除算
; 入力: DE: 被除数
; 出力: DE: 商
; : A: 剰余
; : Z: 剰余なしでセット
;---------------------------------------
DIV7: LD A,7
;---------------------------------------
; 除算
; 入力: DE: 被除数
; : A: 除数
; 出力: DE: 商
; : A: 剰余
; : Z: 剰余なしでセット
; 備考: A: 除数に0を指定すると無限ループする
;---------------------------------------
DIV: PUSH HL
LD H,A ; 除数をHに退避
LD A,E ; 被除数下位をAに代入
LD E,H ; 除数をEに代入
LD HL,-1 ; '引けた回数'初期化
DIV1: INC HL ; '引けた回数'インクリメント
SUB E ; 被除数下位から除数を引いてみる
JR NC,DIV1 ; ボローなければ被除数上位からの借りはないので繰り返し
DEC D ; 被除数上位からボロー分を引く
JP P,DIV1 ; 被除数上位が負になるまで繰り返し
ADD A,E ; 剰余
EX DE,HL ; DEに'引けた回数'代入
POP HL
RET
;---------------------------------------
; 数値読み込み
; 入力: E: 文字列アドレス(上位は0固定)
; 出力: DE: 数値
; : A: 数値の下位バイト
;---------------------------------------
GETNUM: PUSH HL
PUSH BC
LD HL,0 ; 数値をクリア
LD D,H
GETNUM1:LD A,(DE) ; 文字列アドレスから1文字読み込み
INC DE ;
SUB '0' ; '0'未満なら文字列終了
JR C,GETNUM2
LD B,H ; 数値を10倍する
LD C,L ;
ADD HL,HL ; x2
ADD HL,HL ; x4
ADD HL,BC ; x5
ADD HL,HL ; x10
LD C,A ; 数値に文字列から読んだ値を加える
LD B,0 ;
ADD HL,BC ;
JR GETNUM1 ; 繰り返し
GETNUM2:EX DE,HL ; DEに求めた数値を代入
LD A,E ; Aに求めた数値の下位バイトを代入
POP BC
POP HL
RET
;---------------------------------------
; 改行出力
; 破壊: A: LFが代入される
; : DE
;---------------------------------------
PUTCRLF:LD A,CR
CALL PUTC
LD A,LF
JR PUTC
;---------------------------------------
; 空白出力
; 破壊: A: ' 'が代入される
; : DE
;---------------------------------------
PUTSPC: LD A,' '
;---------------------------------------
; 1文字出力
; 入力: A: 出力文字
; 破壊: DE
;---------------------------------------
PUTC: PUSH AF
PUSH HL
PUSH BC
LD C,CONOUT
LD E,A
CALL BDOS
POP BC
POP HL
POP AF
RET
END
変換手順
これをTRANS.COMを使用して8086のプログラムへ変換し、MS-DOS上で動作させてみます。
MS-DOS上で、先ほど生成したTRANS.COMに変換したいファイル名を与えて実行するだけで変換はすぐに終わります。
C:\HOME\FUJITA\TRANS>trans cal.mac
Z80 to 8086 Translator version 2.21
Translation complete
C:\HOME\FUJITA\TRANS>
この手順で、先ほどのザイログニモニックで書かれたプログラムCAL.MACから8086のニモニックで書かれたCAL.ASMが生成されます。
CAL.ASM
BDOS: EQU 0005H ; BDOS 番地
CONOUT: EQU 2 ; コンソール出力
ARG1: EQU 005DH ; FCB+1
ARG2: EQU 006DH ; FCB2+1
CR: EQU 0DH ; 復帰
LF: EQU 0AH ; 改行
ASEG ,
*** Opcode Error
ORG 100H
MAIN:
; DEに'年'取得
MOV DL,ARG1 ; コマンドプロンプトの第1引数
CALL GETNUM ; 数値を読み込み
PUSH DX ;
; (年+(年-1)/4-(年-1)/100+(年-1)/400) MOD 7
; →その年の最初の曜日をCに格納する
MOV BL,DL ; HLに年
MOV BH,DH ; DEに(年-1)
LAHF
DEC DX
SAHF ;
MOV AL,4 ; 4で割り
CALL DIV ;
LAHF
ADD BX,DX
RCR SI
SAHF
RCL SI ; HLに加える
MOV AL,25 ; '4で割った値'を25で割り
CALL DIV ;
OR AL,AL ; HLから引く
SBB BX,DX ;
MOV AL,4 ; ''4で割った値'を25で割った値'を4で割り
CALL DIV ;
LAHF
ADD BX,DX
RCR SI
SAHF
RCL SI ; HLに加える
XCHG DX,BX ; 7で割った剰余をCに代入
CALL DIV7 ;
MOV CL,AL ;
POP DX ;
; 1月から入力された月までの月ごとの日数を求めBに代入する
MOV BH,1 ;
LOOP1: PUSH DX ;
MOV CH,31 ; 月の日数は基本31日
MOV AL,BH
CMP AL,2 ; 2月でないなら
JNZ SKIP1 ; 31日ある月(1月. 3月, 5月, 7月, 8月, 10月, 12月)判定へ
; 2月の日数判定
DEC CH ; とりあえず2日減らす
DEC CH ; (うるう年でなければあとで更に1日減らす)
MOV AL,DL ; 4で割り切れないならうるう年でないので1日減らす
AND AL,03H ;
JNZ SKIP2 ;
MOV AL,100 ; 4で割り切れて
CALL DIV ; 100で割り切れないならうるう年なので判定終了
JNZ SKIP3 ;
MOV AL,DL ; 4で割り切れて
AND AL,03H ; 100で割り切れて
JZ SKIP3 ; 400で割り切れるならうるう年なので判定終了
JMPS SKIP2 ; 4で割り切れて
; 100で割り切れて
; 400で割り切れないならうるう年でないので1日減らす
; 31日ある月(1月. 3月, 5月, 7月, 8月, 10月, 12月)か判定
SKIP1: ADD AL,AL ; 月を9倍しbit3が立っていれば31日ある月なので
ADD AL,AL ; 1日減らす処理をスキップする
ADD AL,AL ;
ADD AL,BH ;
AND AL,08H ;
JNZ SKIP3 ;
SKIP2: DEC CH ; 1日減らす
; 先に求めたCに加えその次の月の最初の曜日を求める
SKIP3: MOV AL,CL ; Cの値を7で割った余りを
CALL MOD7 ;
ADD AL,CH ; その月の日数を加え
MOV CL,AL ; Cに格納する
; 入力された'月'まで繰り返し
MOV DL,ARG2 ; コマンドプロンプトの第2引数
CALL GETNUM ; 数値を読み込み
POP DX
INC BH
CMP AL,BH
JNC LOOP1
; 先にも求めた'その次の月の最初の曜日'から最後の月の日数を引き、
; その月の最初の曜日をCに代入する
MOV AL,CL
SUB AL,CH
MOV CL,AL
; カレンダーの最初の日曜日の日付(0未満だと先月)を求めHに代入
XOR AL,AL ; Hに 0-'その月の最初の曜日'+1 を代入
SUB AL,CL ;
MOV BH,AL ;
LOOP2: INC BH ;
MOV AL,BH ; 1未満なら空白を出力
CMP AL,1 ;
JNS L0000
CALL PUTSPC
L0000: ; 空白を出力
JS SKIP6 ;
; 日付の10の位出力
MOV DH,'0'-1 ; Dに出力する数字の初期値を代入し
LOOP3: INC DH ; 10を引けた数だけインクリメントする
SUB AL,10 ;
JNC LOOP3 ;
LAHF
XCHG AH,AL
PUSH AX
XCHG AH,AL
MOV AL,DH ; '0'だったらゼロサプレスの為に数字の代わりに空白を出力
CMP AL,'0' ;
JNZ SKIP4 ;
MOV AL,' ' ;
SKIP4: CALL PUTC ; 数字か空白を出力
POP AX
XCHG AH,AL
SAHF ;
; 日付の1の位出力
ADD AL,'0'+10 ; 数値→文字化(10引かれてるので+10)
SKIP6: CALL PUTC ; 空白か数字を出力
MOV AL,BH ; 日付がその月の日数に達すれば改行して終了
CMP AL,CH ;
JZ PUTCRLF ; スタックに積まれてない状態でPUTCRLFにジャンプするので
; PUTCRLFの最後のRETでCCPに復帰する
MOV DX,LOOP2 ; ループアドレスをスタックに積む
PUSH DX ;
ADD AL,CL ; (日付+'その月の最初の曜日')/7 を計算し
CALL MOD7 ; 剰余がなければ土曜日なので改行してループ
JZ PUTCRLF ;
JMPS PUTSPC ; 土曜日以外なので空白を出力しループ
;---------------------------------------
; 7で除算
; 入力: A: 被除数
; 出力: DE: 商
; : A: 剰余
; : Z: 剰余なしでセット
;---------------------------------------
MOD7: MOV DL,AL
MOV DH,0
;---------------------------------------
; 7で除算
; 入力: DE: 被除数
; 出力: DE: 商
; : A: 剰余
; : Z: 剰余なしでセット
;---------------------------------------
DIV7: MOV AL,7
;---------------------------------------
; 除算
; 入力: DE: 被除数
; : A: 除数
; 出力: DE: 商
; : A: 剰余
; : Z: 剰余なしでセット
; 備考: A: 除数に0を指定すると無限ループする
;---------------------------------------
DIV: PUSH BX
MOV BH,AL ; 除数をHに退避
MOV AL,DL ; 被除数下位をAに代入
MOV DL,BH ; 除数をEに代入
MOV BX,-1 ; '引けた回数'初期化
DIV1: LAHF
INC BX
SAHF ; '引けた回数'インクリメント
SUB AL,DL ; 被除数下位から除数を引いてみる
JNC DIV1 ; ボローなければ被除数上位からの借りはないので繰り返し
DEC DH ; 被除数上位からボロー分を引く
JNS DIV1 ; 被除数上位が負になるまで繰り返し
ADD AL,DL ; 剰余
XCHG DX,BX ; DEに'引けた回数'代入
POP BX
RET
;---------------------------------------
; 数値読み込み
; 入力: E: 文字列アドレス(上位は0固定)
; 出力: DE: 数値
; : A: 数値の下位バイト
;---------------------------------------
GETNUM: PUSH BX
PUSH CX
MOV BX,0 ; 数値をクリア
MOV DH,BH
GETNUM1: MOV SI,DX
LODB ; 文字列アドレスから1文字読み込み
LAHF
INC DX
SAHF ;
SUB AL,'0' ; '0'未満なら文字列終了
JC GETNUM2
MOV CH,BH ; 数値を10倍する
MOV CL,BL ;
LAHF
ADD BX,BX
RCR SI
SAHF
RCL SI ; x2
LAHF
ADD BX,BX
RCR SI
SAHF
RCL SI ; x4
LAHF
ADD BX,CX
RCR SI
SAHF
RCL SI ; x5
LAHF
ADD BX,BX
RCR SI
SAHF
RCL SI ; x10
MOV CL,AL ; 数値に文字列から読んだ値を加える
MOV CH,0 ;
LAHF
ADD BX,CX
RCR SI
SAHF
RCL SI ;
JMPS GETNUM1 ; 繰り返し
GETNUM2: XCHG DX,BX ; DEに求めた数値を代入
MOV AL,DL ; Aに求めた数値の下位バイトを代入
POP CX
POP BX
RET
;---------------------------------------
; 改行出力
; 破壊: A: LFが代入される
; : DE
;---------------------------------------
PUTCRLF: MOV AL,CR
CALL PUTC
MOV AL,LF
JMPS PUTC
;---------------------------------------
; 空白出力
; 破壊: A: ' 'が代入される
; : DE
;---------------------------------------
PUTSPC: MOV AL,' '
;---------------------------------------
; 1文字出力
; 入力: A: 出力文字
; 破壊: DE
;---------------------------------------
PUTC: LAHF
XCHG AH,AL
PUSH AX
XCHG AH,AL
PUSH BX
PUSH CX
MOV CL,CONOUT
MOV DL,AL
CALL BDOS
POP CX
POP BX
POP AX
XCHG AH,AL
SAHF
RET
END ,
*** Opcode Error
中で 2か所、TRANS.COMがサポートしていない疑似命令がエラーとなっていました。
ASEG ,
*** Opcode Error
END ,
*** Opcode Error
ここはテキストエディタで編集しコメントアウトしておきましょう。
アセンブルと実行
先のTRANS.ASM同様にNasmを使用してアセンブルしてみます。
$ nasm -fbin -p scpasm.inc CAL.ASM -o CAL.COM -l CAL.LST
$ ls -l CAL.COM
-rw-rw-r--+ 1 fujita なし 345 Jan 1 00:01 CAL.COM
$
正常にアセンブルできたようです。これをMS-DOS上で実行してみましょう。
C:\HOME\FUJITA\TRANS>cal 2019 12
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
C:\HOME\FUJITA\TRANS>cal 2020 1
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
C:\HOME\FUJITA\TRANS>
問題なさげな感じですね。
考察
サイズ効率は案外良い
今回テストに使用したプログラムはZ80のコードで224バイトのサイズがあったのですが、8086へ変換後のサイズは約1.5倍の345バイトとなりました。これは、8086用に最適化されたコードではないことを考慮すると案外効率が良いと思います。
試しに、Z80の文書化されている命令の全て(?)を用意し、
Z80ALL.MAC
nop ;nop
ld bc,i16 ;ld bc,i16
ld (bc),a ;ld (bc),a
inc bc ;inc bc
inc b ;inc b
dec b ;dec b
ld b,i8 ;ld b,i8
rlca ;rlca
ex af,af' ;ex af,af'
add hl,bc ;add hl,bc
ld a,(bc) ;ld a,(bc)
dec bc ;dec bc
inc c ;inc c
dec c ;dec c
ld c,i8 ;ld c,i8
rrca ;rrca
djnz addr ;djnz addr
ld de,i16 ;ld de,i16
ld (de),a ;ld (de),a
inc de ;inc de
inc d ;inc d
dec d ;dec d
ld d,i8 ;ld d,i8
rla ;rla
jr addr ;jr addr
add hl,de ;add hl,de
ld a,(de) ;ld a,(de)
dec de ;dec de
inc e ;inc e
dec e ;dec e
ld e,i8 ;ld e,i8
rra ;rra
jr nz,addr ;jr nz,addr
ld hl,i16 ;ld hl,i16
ld (addr),hl ;ld (addr),hl
inc hl ;inc hl
inc h ;inc h
dec h ;dec h
ld h,i8 ;ld h,i8
daa ;daa
jr z,addr ;jr z,addr
add hl,hl ;add hl,hl
ld hl,(addr) ;ld hl,(addr)
dec hl ;dec hl
inc l ;inc l
dec l ;dec l
ld l,i8 ;ld l,i8
cpl ;cpl
jr nc,addr ;jr nc,addr
ld sp,i16 ;ld sp,i16
ld (addr),a ;ld (addr),a
inc sp ;inc sp
inc (hl) ;inc (hl)
dec (hl) ;dec (hl)
ld (hl),i8 ;ld (hl),i8
scf ;scf
jr c,addr ;jr c,addr
add hl,sp ;add hl,sp
ld a,(addr) ;ld a,(addr)
dec sp ;dec sp
inc a ;inc a
dec a ;dec a
ld a,i8 ;ld a,i8
ccf ;ccf
ld b,b ;ld b,b
ld b,c ;ld b,c
ld b,d ;ld b,d
ld b,e ;ld b,e
ld b,h ;ld b,h
ld b,l ;ld b,l
ld b,(hl) ;ld b,(hl)
ld b,a ;ld b,a
ld c,b ;ld c,b
ld c,c ;ld c,c
ld c,d ;ld c,d
ld c,e ;ld c,e
ld c,h ;ld c,h
ld c,l ;ld c,l
ld c,(hl) ;ld c,(hl)
ld c,a ;ld c,a
ld d,b ;ld d,b
ld d,c ;ld d,c
ld d,d ;ld d,d
ld d,e ;ld d,e
ld d,h ;ld d,h
ld d,l ;ld d,l
ld d,(hl) ;ld d,(hl)
ld d,a ;ld d,a
ld e,b ;ld e,b
ld e,c ;ld e,c
ld e,d ;ld e,d
ld e,e ;ld e,e
ld e,h ;ld e,h
ld e,l ;ld e,l
ld e,(hl) ;ld e,(hl)
ld e,a ;ld e,a
ld h,b ;ld h,b
ld h,c ;ld h,c
ld h,d ;ld h,d
ld h,e ;ld h,e
ld h,h ;ld h,h
ld h,l ;ld h,l
ld h,(hl) ;ld h,(hl)
ld h,a ;ld h,a
ld l,b ;ld l,b
ld l,c ;ld l,c
ld l,d ;ld l,d
ld l,e ;ld l,e
ld l,h ;ld l,h
ld l,l ;ld l,l
ld l,(hl) ;ld l,(hl)
ld l,a ;ld l,a
ld (hl),b ;ld (hl),b
ld (hl),c ;ld (hl),c
ld (hl),d ;ld (hl),d
ld (hl),e ;ld (hl),e
ld (hl),h ;ld (hl),h
ld (hl),l ;ld (hl),l
halt ;halt
ld (hl),a ;ld (hl),a
ld a,b ;ld a,b
ld a,c ;ld a,c
ld a,d ;ld a,d
ld a,e ;ld a,e
ld a,h ;ld a,h
ld a,l ;ld a,l
ld a,(hl) ;ld a,(hl)
ld a,a ;ld a,a
add a,b ;add a,b
add a,c ;add a,c
add a,d ;add a,d
add a,e ;add a,e
add a,h ;add a,h
add a,l ;add a,l
add a,(hl) ;add a,(hl)
add a,a ;add a,a
adc a,b ;adc a,b
adc a,c ;adc a,c
adc a,d ;adc a,d
adc a,e ;adc a,e
adc a,h ;adc a,h
adc a,l ;adc a,l
adc a,(hl) ;adc a,(hl)
adc a,a ;adc a,a
sub b ;sub b
sub c ;sub c
sub d ;sub d
sub e ;sub e
sub h ;sub h
sub l ;sub l
sub (hl) ;sub (hl)
sub a ;sub a
sbc a,b ;sbc a,b
sbc a,c ;sbc a,c
sbc a,d ;sbc a,d
sbc a,e ;sbc a,e
sbc a,h ;sbc a,h
sbc a,l ;sbc a,l
sbc a,(hl) ;sbc a,(hl)
sbc a,a ;sbc a,a
and b ;and b
and c ;and c
and d ;and d
and e ;and e
and h ;and h
and l ;and l
and (hl) ;and (hl)
and a ;and a
xor b ;xor b
xor c ;xor c
xor d ;xor d
xor e ;xor e
xor h ;xor h
xor l ;xor l
xor (hl) ;xor (hl)
xor a ;xor a
or b ;or b
or c ;or c
or d ;or d
or e ;or e
or h ;or h
or l ;or l
or (hl) ;or (hl)
or a ;or a
cp b ;cp b
cp c ;cp c
cp d ;cp d
cp e ;cp e
cp h ;cp h
cp l ;cp l
cp (hl) ;cp (hl)
cp a ;cp a
ret nz ;ret nz
pop bc ;pop bc
jp nz,addr ;jp nz,addr
jp addr ;jp addr
call nz,addr ;call nz,addr
push bc ;push bc
add a,i8 ;add a,i8
rst 00h ;rst 00h
ret z ;ret z
ret ;ret
jp z,addr ;jp z,addr
call z,addr ;call z,addr
call addr ;call addr
adc a,i8 ;adc a,i8
rst 08h ;rst 08h
ret nc ;ret nc
pop de ;pop de
jp nc,addr ;jp nc,addr
out (port),a ;out (port),a
call nc,addr ;call nc,addr
push de ;push de
sub i8 ;sub i8
rst 10h ;rst 10h
ret c ;ret c
exx ;exx
jp c,addr ;jp c,addr
in a,(port) ;in a,(port)
call c,addr ;call c,addr
sbc a,i8 ;sbc a,i8
rst 18h ;rst 18h
ret po ;ret po
pop hl ;pop hl
jp po,addr ;jp po,addr
ex (sp),hl ;ex (sp),hl
call po,addr ;call po,addr
push hl ;push hl
and i8 ;and i8
rst 20h ;rst 20h
ret pe ;ret pe
jp (hl) ;jp (hl)
jp pe,addr ;jp pe,addr
ex de,hl ;ex de,hl
call pe,addr ;call pe,addr
xor i8 ;xor i8
rst 28h ;rst 28h
ret p ;ret p
pop af ;pop af
jp p,addr ;jp p,addr
di ;di
call p,addr ;call p,addr
push af ;push af
or i8 ;or i8
rst 30h ;rst 30h
ret m ;ret m
ld sp,hl ;ld sp,hl
jp m,addr ;jp m,addr
ei ;ei
call m,addr ;call m,addr
cp i8 ;cp i8
rst 38h ;rst 38h
in b,(c) ;in b,(c)
out (c),b ;out (c),b
sbc hl,bc ;sbc hl,bc
ld (addr),bc ;ld (addr),bc
neg ;neg
retn ;retn
im 0 ;im 0
ld i,a ;ld i,a
in c,(c) ;in c,(c)
out (c),c ;out (c),c
adc hl,bc ;adc hl,bc
ld bc,(addr) ;ld bc,(addr)
reti ;reti
ld r,a ;ld r,a
in d,(c) ;in d,(c)
out (c),d ;out (c),d
sbc hl,de ;sbc hl,de
ld (addr),de ;ld (addr),de
im 1 ;im 1
ld a,i ;ld a,i
in e,(c) ;in e,(c)
out (c),e ;out (c),e
adc hl,de ;adc hl,de
ld de,(addr) ;ld de,(addr)
im 2 ;im 2
ld a,r ;ld a,r
in h,(c) ;in h,(c)
out (c),h ;out (c),h
sbc hl,hl ;sbc hl,hl
rrd ;rrd
in l,(c) ;in l,(c)
out (c),l ;out (c),l
adc hl,hl ;adc hl,hl
rld ;rld
sbc hl,sp ;sbc hl,sp
ld (addr),sp ;ld (addr),sp
in a,(c) ;in a,(c)
out (c),a ;out (c),a
adc hl,sp ;adc hl,sp
ld sp,(addr) ;ld sp,(addr)
ldi ;ldi
cpi ;cpi
ini ;ini
outi ;outi
ldd ;ldd
cpd ;cpd
ind ;ind
outd ;outd
ldir ;ldir
cpir ;cpir
inir ;inir
otir ;otir
lddr ;lddr
cpdr ;cpdr
indr ;indr
otdr ;otdr
rlc b ;rlc b
rlc c ;rlc c
rlc d ;rlc d
rlc e ;rlc e
rlc h ;rlc h
rlc l ;rlc l
rlc (hl) ;rlc (hl)
rlc a ;rlc a
rrc b ;rrc b
rrc c ;rrc c
rrc d ;rrc d
rrc e ;rrc e
rrc h ;rrc h
rrc l ;rrc l
rrc (hl) ;rrc (hl)
rrc a ;rrc a
rl b ;rl b
rl c ;rl c
rl d ;rl d
rl e ;rl e
rl h ;rl h
rl l ;rl l
rl (hl) ;rl (hl)
rl a ;rl a
rr b ;rr b
rr c ;rr c
rr d ;rr d
rr e ;rr e
rr h ;rr h
rr l ;rr l
rr (hl) ;rr (hl)
rr a ;rr a
sla b ;sla b
sla c ;sla c
sla d ;sla d
sla e ;sla e
sla h ;sla h
sla l ;sla l
sla (hl) ;sla (hl)
sla a ;sla a
sra b ;sra b
sra c ;sra c
sra d ;sra d
sra e ;sra e
sra h ;sra h
sra l ;sra l
sra (hl) ;sra (hl)
sra a ;sra a
srl b ;srl b
srl c ;srl c
srl d ;srl d
srl e ;srl e
srl h ;srl h
srl l ;srl l
srl (hl) ;srl (hl)
srl a ;srl a
bit 0,b ;bit 0,b
bit 0,c ;bit 0,c
bit 0,d ;bit 0,d
bit 0,e ;bit 0,e
bit 0,h ;bit 0,h
bit 0,l ;bit 0,l
bit 0,(hl) ;bit 0,(hl)
bit 0,a ;bit 0,a
bit 1,b ;bit 1,b
bit 1,c ;bit 1,c
bit 1,d ;bit 1,d
bit 1,e ;bit 1,e
bit 1,h ;bit 1,h
bit 1,l ;bit 1,l
bit 1,(hl) ;bit 1,(hl)
bit 1,a ;bit 1,a
bit 2,b ;bit 2,b
bit 2,c ;bit 2,c
bit 2,d ;bit 2,d
bit 2,e ;bit 2,e
bit 2,h ;bit 2,h
bit 2,l ;bit 2,l
bit 2,(hl) ;bit 2,(hl)
bit 2,a ;bit 2,a
bit 3,b ;bit 3,b
bit 3,c ;bit 3,c
bit 3,d ;bit 3,d
bit 3,e ;bit 3,e
bit 3,h ;bit 3,h
bit 3,l ;bit 3,l
bit 3,(hl) ;bit 3,(hl)
bit 3,a ;bit 3,a
bit 4,b ;bit 4,b
bit 4,c ;bit 4,c
bit 4,d ;bit 4,d
bit 4,e ;bit 4,e
bit 4,h ;bit 4,h
bit 4,l ;bit 4,l
bit 4,(hl) ;bit 4,(hl)
bit 4,a ;bit 4,a
bit 5,b ;bit 5,b
bit 5,c ;bit 5,c
bit 5,d ;bit 5,d
bit 5,e ;bit 5,e
bit 5,h ;bit 5,h
bit 5,l ;bit 5,l
bit 5,(hl) ;bit 5,(hl)
bit 5,a ;bit 5,a
bit 6,b ;bit 6,b
bit 6,c ;bit 6,c
bit 6,d ;bit 6,d
bit 6,e ;bit 6,e
bit 6,h ;bit 6,h
bit 6,l ;bit 6,l
bit 6,(hl) ;bit 6,(hl)
bit 6,a ;bit 6,a
bit 7,b ;bit 7,b
bit 7,c ;bit 7,c
bit 7,d ;bit 7,d
bit 7,e ;bit 7,e
bit 7,h ;bit 7,h
bit 7,l ;bit 7,l
bit 7,(hl) ;bit 7,(hl)
bit 7,a ;bit 7,a
res 0,b ;res 0,b
res 0,c ;res 0,c
res 0,d ;res 0,d
res 0,e ;res 0,e
res 0,h ;res 0,h
res 0,l ;res 0,l
res 0,(hl) ;res 0,(hl)
res 0,a ;res 0,a
res 1,b ;res 1,b
res 1,c ;res 1,c
res 1,d ;res 1,d
res 1,e ;res 1,e
res 1,h ;res 1,h
res 1,l ;res 1,l
res 1,(hl) ;res 1,(hl)
res 1,a ;res 1,a
res 2,b ;res 2,b
res 2,c ;res 2,c
res 2,d ;res 2,d
res 2,e ;res 2,e
res 2,h ;res 2,h
res 2,l ;res 2,l
res 2,(hl) ;res 2,(hl)
res 2,a ;res 2,a
res 3,b ;res 3,b
res 3,c ;res 3,c
res 3,d ;res 3,d
res 3,e ;res 3,e
res 3,h ;res 3,h
res 3,l ;res 3,l
res 3,(hl) ;res 3,(hl)
res 3,a ;res 3,a
res 4,b ;res 4,b
res 4,c ;res 4,c
res 4,d ;res 4,d
res 4,e ;res 4,e
res 4,h ;res 4,h
res 4,l ;res 4,l
res 4,(hl) ;res 4,(hl)
res 4,a ;res 4,a
res 5,b ;res 5,b
res 5,c ;res 5,c
res 5,d ;res 5,d
res 5,e ;res 5,e
res 5,h ;res 5,h
res 5,l ;res 5,l
res 5,(hl) ;res 5,(hl)
res 5,a ;res 5,a
res 6,b ;res 6,b
res 6,c ;res 6,c
res 6,d ;res 6,d
res 6,e ;res 6,e
res 6,h ;res 6,h
res 6,l ;res 6,l
res 6,(hl) ;res 6,(hl)
res 6,a ;res 6,a
res 7,b ;res 7,b
res 7,c ;res 7,c
res 7,d ;res 7,d
res 7,e ;res 7,e
res 7,h ;res 7,h
res 7,l ;res 7,l
res 7,(hl) ;res 7,(hl)
res 7,a ;res 7,a
set 0,b ;set 0,b
set 0,c ;set 0,c
set 0,d ;set 0,d
set 0,e ;set 0,e
set 0,h ;set 0,h
set 0,l ;set 0,l
set 0,(hl) ;set 0,(hl)
set 0,a ;set 0,a
set 1,b ;set 1,b
set 1,c ;set 1,c
set 1,d ;set 1,d
set 1,e ;set 1,e
set 1,h ;set 1,h
set 1,l ;set 1,l
set 1,(hl) ;set 1,(hl)
set 1,a ;set 1,a
set 2,b ;set 2,b
set 2,c ;set 2,c
set 2,d ;set 2,d
set 2,e ;set 2,e
set 2,h ;set 2,h
set 2,l ;set 2,l
set 2,(hl) ;set 2,(hl)
set 2,a ;set 2,a
set 3,b ;set 3,b
set 3,c ;set 3,c
set 3,d ;set 3,d
set 3,e ;set 3,e
set 3,h ;set 3,h
set 3,l ;set 3,l
set 3,(hl) ;set 3,(hl)
set 3,a ;set 3,a
set 4,b ;set 4,b
set 4,c ;set 4,c
set 4,d ;set 4,d
set 4,e ;set 4,e
set 4,h ;set 4,h
set 4,l ;set 4,l
set 4,(hl) ;set 4,(hl)
set 4,a ;set 4,a
set 5,b ;set 5,b
set 5,c ;set 5,c
set 5,d ;set 5,d
set 5,e ;set 5,e
set 5,h ;set 5,h
set 5,l ;set 5,l
set 5,(hl) ;set 5,(hl)
set 5,a ;set 5,a
set 6,b ;set 6,b
set 6,c ;set 6,c
set 6,d ;set 6,d
set 6,e ;set 6,e
set 6,h ;set 6,h
set 6,l ;set 6,l
set 6,(hl) ;set 6,(hl)
set 6,a ;set 6,a
set 7,b ;set 7,b
set 7,c ;set 7,c
set 7,d ;set 7,d
set 7,e ;set 7,e
set 7,h ;set 7,h
set 7,l ;set 7,l
set 7,(hl) ;set 7,(hl)
set 7,a ;set 7,a
add ix,bc ;add ix,bc
add ix,de ;add ix,de
ld ix,i16 ;ld ix,i16
ld (addr),ix ;ld (addr),ix
inc ix ;inc ix
add ix,ix ;add ix,ix
ld ix,(addr) ;ld ix,(addr)
dec ix ;dec ix
inc (ix+off) ;inc (ix+off)
dec (ix+off) ;dec (ix+off)
ld (ix+off),i8 ;ld (ix+off),i8
add ix,sp ;add ix,sp
ld b,(ix+off) ;ld b,(ix+off)
ld c,(ix+off) ;ld c,(ix+off)
ld d,(ix+off) ;ld d,(ix+off)
ld e,(ix+off) ;ld e,(ix+off)
ld h,(ix+off) ;ld h,(ix+off)
ld l,(ix+off) ;ld l,(ix+off)
ld (ix+off),b ;ld (ix+off),b
ld (ix+off),c ;ld (ix+off),c
ld (ix+off),d ;ld (ix+off),d
ld (ix+off),e ;ld (ix+off),e
ld (ix+off),h ;ld (ix+off),h
ld (ix+off),l ;ld (ix+off),l
ld (ix+off),a ;ld (ix+off),a
ld a,(ix+off) ;ld a,(ix+off)
add a,(ix+off) ;add a,(ix+off)
adc a,(ix+off) ;adc a,(ix+off)
sub (ix+off) ;sub (ix+off)
sbc a,(ix+off) ;sbc a,(ix+off)
and (ix+off) ;and (ix+off)
xor (ix+off) ;xor (ix+off)
or (ix+off) ;or (ix+off)
cp (ix+off) ;cp (ix+off)
pop ix ;pop ix
ex (sp),ix ;ex (sp),ix
push ix ;push ix
jp (ix) ;jp (ix)
ld sp,ix ;ld sp,ix
rlc (ix+off) ;rlc (ix+off)
rrc (ix+off) ;rrc (ix+off)
rl (ix+off) ;rl (ix+off)
rr (ix+off) ;rr (ix+off)
sla (ix+off) ;sla (ix+off)
sra (ix+off) ;sra (ix+off)
srl (ix+off) ;srl (ix+off)
bit 0,(ix+off) ;bit 0,(ix+off)
bit 1,(ix+off) ;bit 1,(ix+off)
bit 2,(ix+off) ;bit 2,(ix+off)
bit 3,(ix+off) ;bit 3,(ix+off)
bit 4,(ix+off) ;bit 4,(ix+off)
bit 5,(ix+off) ;bit 5,(ix+off)
bit 6,(ix+off) ;bit 6,(ix+off)
bit 7,(ix+off) ;bit 7,(ix+off)
res 0,(ix+off) ;res 0,(ix+off)
res 1,(ix+off) ;res 1,(ix+off)
res 2,(ix+off) ;res 2,(ix+off)
res 3,(ix+off) ;res 3,(ix+off)
res 4,(ix+off) ;res 4,(ix+off)
res 5,(ix+off) ;res 5,(ix+off)
res 6,(ix+off) ;res 6,(ix+off)
res 7,(ix+off) ;res 7,(ix+off)
set 0,(ix+off) ;set 0,(ix+off)
set 1,(ix+off) ;set 1,(ix+off)
set 2,(ix+off) ;set 2,(ix+off)
set 3,(ix+off) ;set 3,(ix+off)
set 4,(ix+off) ;set 4,(ix+off)
set 5,(ix+off) ;set 5,(ix+off)
set 6,(ix+off) ;set 6,(ix+off)
set 7,(ix+off) ;set 7,(ix+off)
add iy,bc ;add iy,bc
add iy,de ;add iy,de
ld iy,i16 ;ld iy,i16
ld (addr),iy ;ld (addr),iy
inc iy ;inc iy
add iy,iy ;add iy,iy
ld iy,(addr) ;ld iy,(addr)
dec iy ;dec iy
inc (iy+off) ;inc (iy+off)
dec (iy+off) ;dec (iy+off)
ld (iy+off),i8 ;ld (iy+off),i8
add iy,sp ;add iy,sp
ld b,(iy+off) ;ld b,(iy+off)
ld c,(iy+off) ;ld c,(iy+off)
ld d,(iy+off) ;ld d,(iy+off)
ld e,(iy+off) ;ld e,(iy+off)
ld h,(iy+off) ;ld h,(iy+off)
ld l,(iy+off) ;ld l,(iy+off)
ld (iy+off),b ;ld (iy+off),b
ld (iy+off),c ;ld (iy+off),c
ld (iy+off),d ;ld (iy+off),d
ld (iy+off),e ;ld (iy+off),e
ld (iy+off),h ;ld (iy+off),h
ld (iy+off),l ;ld (iy+off),l
ld (iy+off),a ;ld (iy+off),a
ld a,(iy+off) ;ld a,(iy+off)
add a,(iy+off) ;add a,(iy+off)
adc a,(iy+off) ;adc a,(iy+off)
sub (iy+off) ;sub (iy+off)
sbc a,(iy+off) ;sbc a,(iy+off)
and (iy+off) ;and (iy+off)
xor (iy+off) ;xor (iy+off)
or (iy+off) ;or (iy+off)
cp (iy+off) ;cp (iy+off)
pop iy ;pop iy
ex (sp),iy ;ex (sp),iy
push iy ;push iy
jp (iy) ;jp (iy)
ld sp,iy ;ld sp,iy
rlc (iy+off) ;rlc (iy+off)
rrc (iy+off) ;rrc (iy+off)
rl (iy+off) ;rl (iy+off)
rr (iy+off) ;rr (iy+off)
sla (iy+off) ;sla (iy+off)
sra (iy+off) ;sra (iy+off)
srl (iy+off) ;srl (iy+off)
bit 0,(iy+off) ;bit 0,(iy+off)
bit 1,(iy+off) ;bit 1,(iy+off)
bit 2,(iy+off) ;bit 2,(iy+off)
bit 3,(iy+off) ;bit 3,(iy+off)
bit 4,(iy+off) ;bit 4,(iy+off)
bit 5,(iy+off) ;bit 5,(iy+off)
bit 6,(iy+off) ;bit 6,(iy+off)
bit 7,(iy+off) ;bit 7,(iy+off)
res 0,(iy+off) ;res 0,(iy+off)
res 1,(iy+off) ;res 1,(iy+off)
res 2,(iy+off) ;res 2,(iy+off)
res 3,(iy+off) ;res 3,(iy+off)
res 4,(iy+off) ;res 4,(iy+off)
res 5,(iy+off) ;res 5,(iy+off)
res 6,(iy+off) ;res 6,(iy+off)
res 7,(iy+off) ;res 7,(iy+off)
set 0,(iy+off) ;set 0,(iy+off)
set 1,(iy+off) ;set 1,(iy+off)
set 2,(iy+off) ;set 2,(iy+off)
set 3,(iy+off) ;set 3,(iy+off)
set 4,(iy+off) ;set 4,(iy+off)
set 5,(iy+off) ;set 5,(iy+off)
set 6,(iy+off) ;set 6,(iy+off)
set 7,(iy+off) ;set 7,(iy+off)
TRANS.COMで変換してみました。
Z80ALL.ASM
NOP ,
*** Opcode Error ;nop
MOV CX,I16 ;ld bc,i16
MOV DI,CX
STOB ;ld (bc),a
LAHF
INC CX
SAHF ;inc bc
INC CH ;inc b
DEC CH ;dec b
MOV CH,I8 ;ld b,i8
ROL AL ;rlca
LAHF
XCHG AX,BP
SAHF
LAHF
ADD BX,CX
RCR SI
SAHF
RCL SI ;add hl,bc
MOV SI,CX
LODB ;ld a,(bc)
LAHF
DEC CX
SAHF ;dec bc
INC CL ;inc c
DEC CL ;dec c
MOV CL,I8 ;ld c,i8
ROR AL ;rrca
DEC CH
; *** WARNING: DJNZ does not affect flags - DEC does.
JNZ ADDR ;djnz addr
MOV DX,I16 ;ld de,i16
MOV DI,DX
STOB ;ld (de),a
LAHF
INC DX
SAHF ;inc de
INC DH ;inc d
DEC DH ;dec d
MOV DH,I8 ;ld d,i8
RCL AL ;rla
JMPS ADDR ;jr addr
LAHF
ADD BX,DX
RCR SI
SAHF
RCL SI ;add hl,de
MOV SI,DX
LODB ;ld a,(de)
LAHF
DEC DX
SAHF ;dec de
INC DL ;inc e
DEC DL ;dec e
MOV DL,I8 ;ld e,i8
RCR AL ;rra
JNZ ADDR ;jr nz,addr
MOV BX,I16 ;ld hl,i16
MOV [ADDR],BX ;ld (addr),hl
LAHF
INC BX
SAHF ;inc hl
INC BH ;inc h
DEC BH ;dec h
MOV BH,I8 ;ld h,i8
DAA ;daa
JZ ADDR ;jr z,addr
LAHF
ADD BX,BX
RCR SI
SAHF
RCL SI ;add hl,hl
MOV BX,[ADDR] ;ld hl,(addr)
LAHF
DEC BX
SAHF ;dec hl
INC BL ;inc l
DEC BL ;dec l
MOV BL,I8 ;ld l,i8
NOT AL ;cpl
JNC ADDR ;jr nc,addr
MOV SP,I16 ;ld sp,i16
MOV [ADDR],AL ;ld (addr),a
LAHF
INC SP
SAHF ;inc sp
INC B,[BX] ;inc (hl)
DEC B,[BX] ;dec (hl)
MOV B,[BX],I8 ;ld (hl),i8
STC ;scf
JC ADDR ;jr c,addr
LAHF
ADD BX,SP
RCR SI
SAHF
RCL SI ;add hl,sp
MOV AL,[ADDR] ;ld a,(addr)
LAHF
DEC SP
SAHF ;dec sp
INC AL ;inc a
DEC AL ;dec a
MOV AL,I8 ;ld a,i8
CMC ;ccf
MOV CH,CH ;ld b,b
MOV CH,CL ;ld b,c
MOV CH,DH ;ld b,d
MOV CH,DL ;ld b,e
MOV CH,BH ;ld b,h
MOV CH,BL ;ld b,l
MOV CH,[BX] ;ld b,(hl)
MOV CH,AL ;ld b,a
MOV CL,CH ;ld c,b
MOV CL,CL ;ld c,c
MOV CL,DH ;ld c,d
MOV CL,DL ;ld c,e
MOV CL,BH ;ld c,h
MOV CL,BL ;ld c,l
MOV CL,[BX] ;ld c,(hl)
MOV CL,AL ;ld c,a
MOV DH,CH ;ld d,b
MOV DH,CL ;ld d,c
MOV DH,DH ;ld d,d
MOV DH,DL ;ld d,e
MOV DH,BH ;ld d,h
MOV DH,BL ;ld d,l
MOV DH,[BX] ;ld d,(hl)
MOV DH,AL ;ld d,a
MOV DL,CH ;ld e,b
MOV DL,CL ;ld e,c
MOV DL,DH ;ld e,d
MOV DL,DL ;ld e,e
MOV DL,BH ;ld e,h
MOV DL,BL ;ld e,l
MOV DL,[BX] ;ld e,(hl)
MOV DL,AL ;ld e,a
MOV BH,CH ;ld h,b
MOV BH,CL ;ld h,c
MOV BH,DH ;ld h,d
MOV BH,DL ;ld h,e
MOV BH,BH ;ld h,h
MOV BH,BL ;ld h,l
MOV BH,[BX] ;ld h,(hl)
MOV BH,AL ;ld h,a
MOV BL,CH ;ld l,b
MOV BL,CL ;ld l,c
MOV BL,DH ;ld l,d
MOV BL,DL ;ld l,e
MOV BL,BH ;ld l,h
MOV BL,BL ;ld l,l
MOV BL,[BX] ;ld l,(hl)
MOV BL,AL ;ld l,a
MOV [BX],CH ;ld (hl),b
MOV [BX],CL ;ld (hl),c
MOV [BX],DH ;ld (hl),d
MOV [BX],DL ;ld (hl),e
MOV [BX],BH ;ld (hl),h
MOV [BX],BL ;ld (hl),l
HLT ;halt
MOV [BX],AL ;ld (hl),a
MOV AL,CH ;ld a,b
MOV AL,CL ;ld a,c
MOV AL,DH ;ld a,d
MOV AL,DL ;ld a,e
MOV AL,BH ;ld a,h
MOV AL,BL ;ld a,l
MOV AL,[BX] ;ld a,(hl)
MOV AL,AL ;ld a,a
ADD AL,CH ;add a,b
ADD AL,CL ;add a,c
ADD AL,DH ;add a,d
ADD AL,DL ;add a,e
ADD AL,BH ;add a,h
ADD AL,BL ;add a,l
ADD AL,[BX] ;add a,(hl)
ADD AL,AL ;add a,a
ADC AL,CH ;adc a,b
ADC AL,CL ;adc a,c
ADC AL,DH ;adc a,d
ADC AL,DL ;adc a,e
ADC AL,BH ;adc a,h
ADC AL,BL ;adc a,l
ADC AL,[BX] ;adc a,(hl)
ADC AL,AL ;adc a,a
SUB AL,CH ;sub b
SUB AL,CL ;sub c
SUB AL,DH ;sub d
SUB AL,DL ;sub e
SUB AL,BH ;sub h
SUB AL,BL ;sub l
SUB AL,[BX] ;sub (hl)
SUB AL,AL ;sub a
SBB AL,CH ;sbc a,b
SBB AL,CL ;sbc a,c
SBB AL,DH ;sbc a,d
SBB AL,DL ;sbc a,e
SBB AL,BH ;sbc a,h
SBB AL,BL ;sbc a,l
SBB AL,[BX] ;sbc a,(hl)
SBB AL,AL ;sbc a,a
AND AL,CH ;and b
AND AL,CL ;and c
AND AL,DH ;and d
AND AL,DL ;and e
AND AL,BH ;and h
AND AL,BL ;and l
AND AL,[BX] ;and (hl)
AND AL,AL ;and a
XOR AL,CH ;xor b
XOR AL,CL ;xor c
XOR AL,DH ;xor d
XOR AL,DL ;xor e
XOR AL,BH ;xor h
XOR AL,BL ;xor l
XOR AL,[BX] ;xor (hl)
XOR AL,AL ;xor a
OR AL,CH ;or b
OR AL,CL ;or c
OR AL,DH ;or d
OR AL,DL ;or e
OR AL,BH ;or h
OR AL,BL ;or l
OR AL,[BX] ;or (hl)
OR AL,AL ;or a
CMP AL,CH ;cp b
CMP AL,CL ;cp c
CMP AL,DH ;cp d
CMP AL,DL ;cp e
CMP AL,BH ;cp h
CMP AL,BL ;cp l
CMP AL,[BX] ;cp (hl)
CMP AL,AL ;cp a
JNZ RET ;ret nz
POP CX ;pop bc
JNZ ADDR ;jp nz,addr
JMP ADDR ;jp addr
JZ L0000
CALL ADDR
L0000: ;call nz,addr
PUSH CX ;push bc
ADD AL,I8 ;add a,i8
CALL 00H ;rst 00h
JZ RET ;ret z
RET ;ret
JZ ADDR ;jp z,addr
JNZ L0001
CALL ADDR
L0001: ;call z,addr
CALL ADDR ;call addr
ADC AL,I8 ;adc a,i8
CALL 08H ;rst 08h
JNC RET ;ret nc
POP DX ;pop de
JNC ADDR ;jp nc,addr
OUTB PORT ;out (port),a
JC L0002
CALL ADDR
L0002: ;call nc,addr
PUSH DX ;push de
SUB AL,I8 ;sub i8
CALL 10H ;rst 10h
JC RET ;ret c
XCHG BX,[HL]
XCHG DX,[DE]
XCHG CX,[BC] ;exx
JC ADDR ;jp c,addr
INB PORT ;in a,(port)
JNC L0003
CALL ADDR
L0003: ;call c,addr
SBB AL,I8 ;sbc a,i8
CALL 18H ;rst 18h
JPO RET
; *** WARNING: Parity flag not always same as Z80. ;ret po
POP BX ;pop hl
JPO ADDR
; *** WARNING: Parity flag not always same as Z80. ;jp po,addr
POP SI
XCHG SI,BX
PUSH SI ;ex (sp),hl
JPE L0004
; *** WARNING: Parity flag not always same as Z80.
CALL ADDR
L0004: ;call po,addr
PUSH BX ;push hl
AND AL,I8 ;and i8
CALL 20H ;rst 20h
JPE RET
; *** WARNING: Parity flag not always same as Z80. ;ret pe
JMP BX ;jp (hl)
JPE ADDR
; *** WARNING: Parity flag not always same as Z80. ;jp pe,addr
XCHG DX,BX ;ex de,hl
JPO L0005
; *** WARNING: Parity flag not always same as Z80.
CALL ADDR
L0005: ;call pe,addr
XOR AL,I8 ;xor i8
CALL 28H ;rst 28h
JNS RET ;ret p
POP AX
XCHG AH,AL
SAHF ;pop af
JNS ADDR ;jp p,addr
DI ;di
JS L0006
CALL ADDR
L0006: ;call p,addr
LAHF
XCHG AH,AL
PUSH AX
XCHG AH,AL ;push af
OR AL,I8 ;or i8
CALL 30H ;rst 30h
JS RET ;ret m
MOV SP,BX ;ld sp,hl
JS ADDR ;jp m,addr
EI ;ei
JNS L0007
CALL ADDR
L0007: ;call m,addr
CMP AL,I8 ;cp i8
CALL 38H ;rst 38h
XCHG AX,SI
MOV DI,DX
MOV DL,CL
XOR DH,DH
INB DX
MOV DX,DI
MOV CH,AL
XCHG AX,SI ;in b,(c)
XCHG AX,SI
MOV AL,CH
MOV DI,DX
MOV DL,CL
XOR DH,DH
OUTB DX
MOV DX,DI
; *** WARNING: Flags not same as Z80.
XCHG AX,SI ;out (c),b
SBB BX,CX ;sbc hl,bc
MOV [ADDR],CX ;ld (addr),bc
NEG AL ;neg
IRET ;retn
IM 0 ,
*** Opcode Error ;im 0
MOV I,AL ;ld i,a
XCHG AX,SI
MOV DI,DX
MOV DL,CL
XOR DH,DH
INB DX
MOV DX,DI
MOV CL,AL
XCHG AX,SI ;in c,(c)
XCHG AX,SI
MOV AL,CL
MOV DI,DX
MOV DL,CL
XOR DH,DH
OUTB DX
MOV DX,DI
; *** WARNING: Flags not same as Z80.
XCHG AX,SI ;out (c),c
ADC BX,CX ;adc hl,bc
MOV CX,[ADDR] ;ld bc,(addr)
IRET ;reti
MOV R,AL ;ld r,a
XCHG AX,SI
MOV DI,DX
MOV DL,CL
XOR DH,DH
INB DX
MOV DX,DI
MOV DH,AL
XCHG AX,SI ;in d,(c)
XCHG AX,SI
MOV AL,DH
MOV DI,DX
MOV DL,CL
XOR DH,DH
OUTB DX
MOV DX,DI
; *** WARNING: Flags not same as Z80.
XCHG AX,SI ;out (c),d
SBB BX,DX ;sbc hl,de
MOV [ADDR],DX ;ld (addr),de
IM 1 ,
*** Opcode Error ;im 1
MOV AL,I ;ld a,i
XCHG AX,SI
MOV DI,DX
MOV DL,CL
XOR DH,DH
INB DX
MOV DX,DI
MOV DL,AL
XCHG AX,SI ;in e,(c)
XCHG AX,SI
MOV AL,DL
MOV DI,DX
MOV DL,CL
XOR DH,DH
OUTB DX
MOV DX,DI
; *** WARNING: Flags not same as Z80.
XCHG AX,SI ;out (c),e
ADC BX,DX ;adc hl,de
MOV DX,[ADDR] ;ld de,(addr)
IM 2 ,
*** Opcode Error ;im 2
MOV AL,R ;ld a,r
XCHG AX,SI
MOV DI,DX
MOV DL,CL
XOR DH,DH
INB DX
MOV DX,DI
MOV BH,AL
XCHG AX,SI ;in h,(c)
XCHG AX,SI
MOV AL,BH
MOV DI,DX
MOV DL,CL
XOR DH,DH
OUTB DX
MOV DX,DI
; *** WARNING: Flags not same as Z80.
XCHG AX,SI ;out (c),h
SBB BX,BX ;sbc hl,hl
RRD ,
*** Opcode Error ;rrd
XCHG AX,SI
MOV DI,DX
MOV DL,CL
XOR DH,DH
INB DX
MOV DX,DI
MOV BL,AL
XCHG AX,SI ;in l,(c)
XCHG AX,SI
MOV AL,BL
MOV DI,DX
MOV DL,CL
XOR DH,DH
OUTB DX
MOV DX,DI
; *** WARNING: Flags not same as Z80.
XCHG AX,SI ;out (c),l
ADC BX,BX ;adc hl,hl
RLD ,
*** Opcode Error ;rld
SBB BX,SP ;sbc hl,sp
MOV [ADDR],SP ;ld (addr),sp
MOV DI,DX
MOV DL,CL
XOR DH,DH
INB DX
MOV DX,DI ;in a,(c)
MOV DI,DX
MOV DL,CL
XOR DH,DH
OUTB DX
MOV DX,DI
; *** WARNING: Flags not same as Z80. ;out (c),a
ADC BX,SP ;adc hl,sp
MOV SP,[ADDR] ;ld sp,(addr)
LDI ,
*** Opcode Error ;ldi
CPI ,
*** Opcode Error ;cpi
INI ,
*** Opcode Error ;ini
OUTI ,
*** Opcode Error ;outi
LDD ,
*** Opcode Error ;ldd
CPD ,
*** Opcode Error ;cpd
IND ,
*** Opcode Error ;ind
OUTD ,
*** Opcode Error ;outd
UP
MOV SI,BX
MOV DI,DX
REP
MOVB
MOV DX,DI
MOV BX,SI ;ldir
UP
MOV DI,BX
REPNZ
SCAB
MOV BX,DI ;cpir
INIR ,
*** Opcode Error ;inir
OTIR ,
*** Opcode Error ;otir
DOWN
MOV SI,BX
MOV DI,DX
REP
MOVB
MOV DX,DI
MOV BX,SI ;lddr
DOWN
MOV DI,BX
REPNZ
SCAB
MOV BX,DI ;cpdr
INDR ,
*** Opcode Error ;indr
OTDR ,
*** Opcode Error ;otdr
ROL CH ;rlc b
ROL CL ;rlc c
ROL DH ;rlc d
ROL DL ;rlc e
ROL BH ;rlc h
ROL BL ;rlc l
ROL B,[BX] ;rlc (hl)
ROL AL ;rlc a
ROR CH ;rrc b
ROR CL ;rrc c
ROR DH ;rrc d
ROR DL ;rrc e
ROR BH ;rrc h
ROR BL ;rrc l
ROR B,[BX] ;rrc (hl)
ROR AL ;rrc a
RCL CH ;rl b
RCL CL ;rl c
RCL DH ;rl d
RCL DL ;rl e
RCL BH ;rl h
RCL BL ;rl l
RCL B,[BX] ;rl (hl)
RCL AL ;rl a
RCR CH ;rr b
RCR CL ;rr c
RCR DH ;rr d
RCR DL ;rr e
RCR BH ;rr h
RCR BL ;rr l
RCR B,[BX] ;rr (hl)
RCR AL ;rr a
SAL CH ;sla b
SAL CL ;sla c
SAL DH ;sla d
SAL DL ;sla e
SAL BH ;sla h
SAL BL ;sla l
SAL B,[BX] ;sla (hl)
SAL AL ;sla a
SAR CH ;sra b
SAR CL ;sra c
SAR DH ;sra d
SAR DL ;sra e
SAR BH ;sra h
SAR BL ;sra l
SAR B,[BX] ;sra (hl)
SAR AL ;sra a
SHR CH ;srl b
SHR CL ;srl c
SHR DH ;srl d
SHR DL ;srl e
SHR BH ;srl h
SHR BL ;srl l
SHR B,[BX] ;srl (hl)
SHR AL ;srl a
RCR AH
TEST CH ,001H
RCL AH ;bit 0,b
RCR AH
TEST CL ,001H
RCL AH ;bit 0,c
RCR AH
TEST DH ,001H
RCL AH ;bit 0,d
RCR AH
TEST DL ,001H
RCL AH ;bit 0,e
RCR AH
TEST BH ,001H
RCL AH ;bit 0,h
RCR AH
TEST BL ,001H
RCL AH ;bit 0,l
RCR AH
TEST B,[BX] ,001H
RCL AH ;bit 0,(hl)
RCR AH
TEST AL ,001H
RCL AH ;bit 0,a
RCR AH
TEST CH ,002H
RCL AH ;bit 1,b
RCR AH
TEST CL ,002H
RCL AH ;bit 1,c
RCR AH
TEST DH ,002H
RCL AH ;bit 1,d
RCR AH
TEST DL ,002H
RCL AH ;bit 1,e
RCR AH
TEST BH ,002H
RCL AH ;bit 1,h
RCR AH
TEST BL ,002H
RCL AH ;bit 1,l
RCR AH
TEST B,[BX] ,002H
RCL AH ;bit 1,(hl)
RCR AH
TEST AL ,002H
RCL AH ;bit 1,a
RCR AH
TEST CH ,004H
RCL AH ;bit 2,b
RCR AH
TEST CL ,004H
RCL AH ;bit 2,c
RCR AH
TEST DH ,004H
RCL AH ;bit 2,d
RCR AH
TEST DL ,004H
RCL AH ;bit 2,e
RCR AH
TEST BH ,004H
RCL AH ;bit 2,h
RCR AH
TEST BL ,004H
RCL AH ;bit 2,l
RCR AH
TEST B,[BX] ,004H
RCL AH ;bit 2,(hl)
RCR AH
TEST AL ,004H
RCL AH ;bit 2,a
RCR AH
TEST CH ,008H
RCL AH ;bit 3,b
RCR AH
TEST CL ,008H
RCL AH ;bit 3,c
RCR AH
TEST DH ,008H
RCL AH ;bit 3,d
RCR AH
TEST DL ,008H
RCL AH ;bit 3,e
RCR AH
TEST BH ,008H
RCL AH ;bit 3,h
RCR AH
TEST BL ,008H
RCL AH ;bit 3,l
RCR AH
TEST B,[BX] ,008H
RCL AH ;bit 3,(hl)
RCR AH
TEST AL ,008H
RCL AH ;bit 3,a
RCR AH
TEST CH ,010H
RCL AH ;bit 4,b
RCR AH
TEST CL ,010H
RCL AH ;bit 4,c
RCR AH
TEST DH ,010H
RCL AH ;bit 4,d
RCR AH
TEST DL ,010H
RCL AH ;bit 4,e
RCR AH
TEST BH ,010H
RCL AH ;bit 4,h
RCR AH
TEST BL ,010H
RCL AH ;bit 4,l
RCR AH
TEST B,[BX] ,010H
RCL AH ;bit 4,(hl)
RCR AH
TEST AL ,010H
RCL AH ;bit 4,a
RCR AH
TEST CH ,020H
RCL AH ;bit 5,b
RCR AH
TEST CL ,020H
RCL AH ;bit 5,c
RCR AH
TEST DH ,020H
RCL AH ;bit 5,d
RCR AH
TEST DL ,020H
RCL AH ;bit 5,e
RCR AH
TEST BH ,020H
RCL AH ;bit 5,h
RCR AH
TEST BL ,020H
RCL AH ;bit 5,l
RCR AH
TEST B,[BX] ,020H
RCL AH ;bit 5,(hl)
RCR AH
TEST AL ,020H
RCL AH ;bit 5,a
RCR AH
TEST CH ,040H
RCL AH ;bit 6,b
RCR AH
TEST CL ,040H
RCL AH ;bit 6,c
RCR AH
TEST DH ,040H
RCL AH ;bit 6,d
RCR AH
TEST DL ,040H
RCL AH ;bit 6,e
RCR AH
TEST BH ,040H
RCL AH ;bit 6,h
RCR AH
TEST BL ,040H
RCL AH ;bit 6,l
RCR AH
TEST B,[BX] ,040H
RCL AH ;bit 6,(hl)
RCR AH
TEST AL ,040H
RCL AH ;bit 6,a
RCR AH
TEST CH ,080H
RCL AH ;bit 7,b
RCR AH
TEST CL ,080H
RCL AH ;bit 7,c
RCR AH
TEST DH ,080H
RCL AH ;bit 7,d
RCR AH
TEST DL ,080H
RCL AH ;bit 7,e
RCR AH
TEST BH ,080H
RCL AH ;bit 7,h
RCR AH
TEST BL ,080H
RCL AH ;bit 7,l
RCR AH
TEST B,[BX] ,080H
RCL AH ;bit 7,(hl)
RCR AH
TEST AL ,080H
RCL AH ;bit 7,a
LAHF
AND CH ,0FEH
SAHF ;res 0,b
LAHF
AND CL ,0FEH
SAHF ;res 0,c
LAHF
AND DH ,0FEH
SAHF ;res 0,d
LAHF
AND DL ,0FEH
SAHF ;res 0,e
LAHF
AND BH ,0FEH
SAHF ;res 0,h
LAHF
AND BL ,0FEH
SAHF ;res 0,l
LAHF
AND B,[BX] ,0FEH
SAHF ;res 0,(hl)
LAHF
AND AL ,0FEH
SAHF ;res 0,a
LAHF
AND CH ,0FDH
SAHF ;res 1,b
LAHF
AND CL ,0FDH
SAHF ;res 1,c
LAHF
AND DH ,0FDH
SAHF ;res 1,d
LAHF
AND DL ,0FDH
SAHF ;res 1,e
LAHF
AND BH ,0FDH
SAHF ;res 1,h
LAHF
AND BL ,0FDH
SAHF ;res 1,l
LAHF
AND B,[BX] ,0FDH
SAHF ;res 1,(hl)
LAHF
AND AL ,0FDH
SAHF ;res 1,a
LAHF
AND CH ,0FBH
SAHF ;res 2,b
LAHF
AND CL ,0FBH
SAHF ;res 2,c
LAHF
AND DH ,0FBH
SAHF ;res 2,d
LAHF
AND DL ,0FBH
SAHF ;res 2,e
LAHF
AND BH ,0FBH
SAHF ;res 2,h
LAHF
AND BL ,0FBH
SAHF ;res 2,l
LAHF
AND B,[BX] ,0FBH
SAHF ;res 2,(hl)
LAHF
AND AL ,0FBH
SAHF ;res 2,a
LAHF
AND CH ,0F7H
SAHF ;res 3,b
LAHF
AND CL ,0F7H
SAHF ;res 3,c
LAHF
AND DH ,0F7H
SAHF ;res 3,d
LAHF
AND DL ,0F7H
SAHF ;res 3,e
LAHF
AND BH ,0F7H
SAHF ;res 3,h
LAHF
AND BL ,0F7H
SAHF ;res 3,l
LAHF
AND B,[BX] ,0F7H
SAHF ;res 3,(hl)
LAHF
AND AL ,0F7H
SAHF ;res 3,a
LAHF
AND CH ,0EFH
SAHF ;res 4,b
LAHF
AND CL ,0EFH
SAHF ;res 4,c
LAHF
AND DH ,0EFH
SAHF ;res 4,d
LAHF
AND DL ,0EFH
SAHF ;res 4,e
LAHF
AND BH ,0EFH
SAHF ;res 4,h
LAHF
AND BL ,0EFH
SAHF ;res 4,l
LAHF
AND B,[BX] ,0EFH
SAHF ;res 4,(hl)
LAHF
AND AL ,0EFH
SAHF ;res 4,a
LAHF
AND CH ,0DFH
SAHF ;res 5,b
LAHF
AND CL ,0DFH
SAHF ;res 5,c
LAHF
AND DH ,0DFH
SAHF ;res 5,d
LAHF
AND DL ,0DFH
SAHF ;res 5,e
LAHF
AND BH ,0DFH
SAHF ;res 5,h
LAHF
AND BL ,0DFH
SAHF ;res 5,l
LAHF
AND B,[BX] ,0DFH
SAHF ;res 5,(hl)
LAHF
AND AL ,0DFH
SAHF ;res 5,a
LAHF
AND CH ,0BFH
SAHF ;res 6,b
LAHF
AND CL ,0BFH
SAHF ;res 6,c
LAHF
AND DH ,0BFH
SAHF ;res 6,d
LAHF
AND DL ,0BFH
SAHF ;res 6,e
LAHF
AND BH ,0BFH
SAHF ;res 6,h
LAHF
AND BL ,0BFH
SAHF ;res 6,l
LAHF
AND B,[BX] ,0BFH
SAHF ;res 6,(hl)
LAHF
AND AL ,0BFH
SAHF ;res 6,a
LAHF
AND CH ,07FH
SAHF ;res 7,b
LAHF
AND CL ,07FH
SAHF ;res 7,c
LAHF
AND DH ,07FH
SAHF ;res 7,d
LAHF
AND DL ,07FH
SAHF ;res 7,e
LAHF
AND BH ,07FH
SAHF ;res 7,h
LAHF
AND BL ,07FH
SAHF ;res 7,l
LAHF
AND B,[BX] ,07FH
SAHF ;res 7,(hl)
LAHF
AND AL ,07FH
SAHF ;res 7,a
LAHF
OR CH ,001H
SAHF ;set 0,b
LAHF
OR CL ,001H
SAHF ;set 0,c
LAHF
OR DH ,001H
SAHF ;set 0,d
LAHF
OR DL ,001H
SAHF ;set 0,e
LAHF
OR BH ,001H
SAHF ;set 0,h
LAHF
OR BL ,001H
SAHF ;set 0,l
LAHF
OR B,[BX] ,001H
SAHF ;set 0,(hl)
LAHF
OR AL ,001H
SAHF ;set 0,a
LAHF
OR CH ,002H
SAHF ;set 1,b
LAHF
OR CL ,002H
SAHF ;set 1,c
LAHF
OR DH ,002H
SAHF ;set 1,d
LAHF
OR DL ,002H
SAHF ;set 1,e
LAHF
OR BH ,002H
SAHF ;set 1,h
LAHF
OR BL ,002H
SAHF ;set 1,l
LAHF
OR B,[BX] ,002H
SAHF ;set 1,(hl)
LAHF
OR AL ,002H
SAHF ;set 1,a
LAHF
OR CH ,004H
SAHF ;set 2,b
LAHF
OR CL ,004H
SAHF ;set 2,c
LAHF
OR DH ,004H
SAHF ;set 2,d
LAHF
OR DL ,004H
SAHF ;set 2,e
LAHF
OR BH ,004H
SAHF ;set 2,h
LAHF
OR BL ,004H
SAHF ;set 2,l
LAHF
OR B,[BX] ,004H
SAHF ;set 2,(hl)
LAHF
OR AL ,004H
SAHF ;set 2,a
LAHF
OR CH ,008H
SAHF ;set 3,b
LAHF
OR CL ,008H
SAHF ;set 3,c
LAHF
OR DH ,008H
SAHF ;set 3,d
LAHF
OR DL ,008H
SAHF ;set 3,e
LAHF
OR BH ,008H
SAHF ;set 3,h
LAHF
OR BL ,008H
SAHF ;set 3,l
LAHF
OR B,[BX] ,008H
SAHF ;set 3,(hl)
LAHF
OR AL ,008H
SAHF ;set 3,a
LAHF
OR CH ,010H
SAHF ;set 4,b
LAHF
OR CL ,010H
SAHF ;set 4,c
LAHF
OR DH ,010H
SAHF ;set 4,d
LAHF
OR DL ,010H
SAHF ;set 4,e
LAHF
OR BH ,010H
SAHF ;set 4,h
LAHF
OR BL ,010H
SAHF ;set 4,l
LAHF
OR B,[BX] ,010H
SAHF ;set 4,(hl)
LAHF
OR AL ,010H
SAHF ;set 4,a
LAHF
OR CH ,020H
SAHF ;set 5,b
LAHF
OR CL ,020H
SAHF ;set 5,c
LAHF
OR DH ,020H
SAHF ;set 5,d
LAHF
OR DL ,020H
SAHF ;set 5,e
LAHF
OR BH ,020H
SAHF ;set 5,h
LAHF
OR BL ,020H
SAHF ;set 5,l
LAHF
OR B,[BX] ,020H
SAHF ;set 5,(hl)
LAHF
OR AL ,020H
SAHF ;set 5,a
LAHF
OR CH ,040H
SAHF ;set 6,b
LAHF
OR CL ,040H
SAHF ;set 6,c
LAHF
OR DH ,040H
SAHF ;set 6,d
LAHF
OR DL ,040H
SAHF ;set 6,e
LAHF
OR BH ,040H
SAHF ;set 6,h
LAHF
OR BL ,040H
SAHF ;set 6,l
LAHF
OR B,[BX] ,040H
SAHF ;set 6,(hl)
LAHF
OR AL ,040H
SAHF ;set 6,a
LAHF
OR CH ,080H
SAHF ;set 7,b
LAHF
OR CL ,080H
SAHF ;set 7,c
LAHF
OR DH ,080H
SAHF ;set 7,d
LAHF
OR DL ,080H
SAHF ;set 7,e
LAHF
OR BH ,080H
SAHF ;set 7,h
LAHF
OR BL ,080H
SAHF ;set 7,l
LAHF
OR B,[BX] ,080H
SAHF ;set 7,(hl)
LAHF
OR AL ,080H
SAHF ;set 7,a
ADD [IX],CX ;add ix,bc
ADD [IX],DX ;add ix,de
MOV [IX],I16 ;ld ix,i16
MOV B,[ADDR],[IX] ;ld (addr),ix
INC [IX] ;inc ix
ADD [IX],[IX] ;add ix,ix
MOV [IX],[ADDR] ;ld ix,(addr)
DEC [IX] ;dec ix
MOV SI,[IX]
INC B,[SI+OFF] ;inc (ix+off)
MOV SI,[IX]
DEC B,[SI+OFF] ;dec (ix+off)
MOV SI,[IX]
MOV B,[SI+OFF],I8 ;ld (ix+off),i8
ADD [IX],SP ;add ix,sp
MOV SI,[IX]
MOV CH,[SI+OFF] ;ld b,(ix+off)
MOV SI,[IX]
MOV CL,[SI+OFF] ;ld c,(ix+off)
MOV SI,[IX]
MOV DH,[SI+OFF] ;ld d,(ix+off)
MOV SI,[IX]
MOV DL,[SI+OFF] ;ld e,(ix+off)
MOV SI,[IX]
MOV BH,[SI+OFF] ;ld h,(ix+off)
MOV SI,[IX]
MOV BL,[SI+OFF] ;ld l,(ix+off)
MOV SI,[IX]
MOV [SI+OFF],CH ;ld (ix+off),b
MOV SI,[IX]
MOV [SI+OFF],CL ;ld (ix+off),c
MOV SI,[IX]
MOV [SI+OFF],DH ;ld (ix+off),d
MOV SI,[IX]
MOV [SI+OFF],DL ;ld (ix+off),e
MOV SI,[IX]
MOV [SI+OFF],BH ;ld (ix+off),h
MOV SI,[IX]
MOV [SI+OFF],BL ;ld (ix+off),l
MOV SI,[IX]
MOV [SI+OFF],AL ;ld (ix+off),a
MOV SI,[IX]
MOV AL,[SI+OFF] ;ld a,(ix+off)
MOV SI,[IX]
ADD AL,[SI+OFF] ;add a,(ix+off)
MOV SI,[IX]
ADC AL,[SI+OFF] ;adc a,(ix+off)
MOV SI,[IX]
SUB AL,[SI+OFF] ;sub (ix+off)
MOV SI,[IX]
SBB AL,[SI+OFF] ;sbc a,(ix+off)
MOV SI,[IX]
AND AL,[SI+OFF] ;and (ix+off)
MOV SI,[IX]
XOR AL,[SI+OFF] ;xor (ix+off)
MOV SI,[IX]
OR AL,[SI+OFF] ;or (ix+off)
MOV SI,[IX]
CMP AL,[SI+OFF] ;cp (ix+off)
POP [IX] ;pop ix
POP SI
XCHG SI,[IX]
PUSH SI ;ex (sp),ix
PUSH [IX] ;push ix
MOV SI,[IX]
JMP SI ;jp (ix)
MOV SP,[IX] ;ld sp,ix
MOV SI,[IX]
ROL B,[SI+OFF] ;rlc (ix+off)
MOV SI,[IX]
ROR B,[SI+OFF] ;rrc (ix+off)
MOV SI,[IX]
RCL B,[SI+OFF] ;rl (ix+off)
MOV SI,[IX]
RCR B,[SI+OFF] ;rr (ix+off)
MOV SI,[IX]
SAL B,[SI+OFF] ;sla (ix+off)
MOV SI,[IX]
SAR B,[SI+OFF] ;sra (ix+off)
MOV SI,[IX]
SHR B,[SI+OFF] ;srl (ix+off)
MOV SI,[IX]
RCR AH
TEST B,[SI+OFF] ,001H
RCL AH ;bit 0,(ix+off)
MOV SI,[IX]
RCR AH
TEST B,[SI+OFF] ,002H
RCL AH ;bit 1,(ix+off)
MOV SI,[IX]
RCR AH
TEST B,[SI+OFF] ,004H
RCL AH ;bit 2,(ix+off)
MOV SI,[IX]
RCR AH
TEST B,[SI+OFF] ,008H
RCL AH ;bit 3,(ix+off)
MOV SI,[IX]
RCR AH
TEST B,[SI+OFF] ,010H
RCL AH ;bit 4,(ix+off)
MOV SI,[IX]
RCR AH
TEST B,[SI+OFF] ,020H
RCL AH ;bit 5,(ix+off)
MOV SI,[IX]
RCR AH
TEST B,[SI+OFF] ,040H
RCL AH ;bit 6,(ix+off)
MOV SI,[IX]
RCR AH
TEST B,[SI+OFF] ,080H
RCL AH ;bit 7,(ix+off)
MOV SI,[IX]
LAHF
AND B,[SI+OFF] ,0FEH
SAHF ;res 0,(ix+off)
MOV SI,[IX]
LAHF
AND B,[SI+OFF] ,0FDH
SAHF ;res 1,(ix+off)
MOV SI,[IX]
LAHF
AND B,[SI+OFF] ,0FBH
SAHF ;res 2,(ix+off)
MOV SI,[IX]
LAHF
AND B,[SI+OFF] ,0F7H
SAHF ;res 3,(ix+off)
MOV SI,[IX]
LAHF
AND B,[SI+OFF] ,0EFH
SAHF ;res 4,(ix+off)
MOV SI,[IX]
LAHF
AND B,[SI+OFF] ,0DFH
SAHF ;res 5,(ix+off)
MOV SI,[IX]
LAHF
AND B,[SI+OFF] ,0BFH
SAHF ;res 6,(ix+off)
MOV SI,[IX]
LAHF
AND B,[SI+OFF] ,07FH
SAHF ;res 7,(ix+off)
MOV SI,[IX]
LAHF
OR B,[SI+OFF] ,001H
SAHF ;set 0,(ix+off)
MOV SI,[IX]
LAHF
OR B,[SI+OFF] ,002H
SAHF ;set 1,(ix+off)
MOV SI,[IX]
LAHF
OR B,[SI+OFF] ,004H
SAHF ;set 2,(ix+off)
MOV SI,[IX]
LAHF
OR B,[SI+OFF] ,008H
SAHF ;set 3,(ix+off)
MOV SI,[IX]
LAHF
OR B,[SI+OFF] ,010H
SAHF ;set 4,(ix+off)
MOV SI,[IX]
LAHF
OR B,[SI+OFF] ,020H
SAHF ;set 5,(ix+off)
MOV SI,[IX]
LAHF
OR B,[SI+OFF] ,040H
SAHF ;set 6,(ix+off)
MOV SI,[IX]
LAHF
OR B,[SI+OFF] ,080H
SAHF ;set 7,(ix+off)
ADD [IY],CX ;add iy,bc
ADD [IY],DX ;add iy,de
MOV [IY],I16 ;ld iy,i16
MOV B,[ADDR],[IY] ;ld (addr),iy
INC [IY] ;inc iy
ADD [IY],[IY] ;add iy,iy
MOV [IY],[ADDR] ;ld iy,(addr)
DEC [IY] ;dec iy
MOV DI,[IY]
INC B,[DI+OFF] ;inc (iy+off)
MOV DI,[IY]
DEC B,[DI+OFF] ;dec (iy+off)
MOV DI,[IY]
MOV B,[DI+OFF],I8 ;ld (iy+off),i8
ADD [IY],SP ;add iy,sp
MOV DI,[IY]
MOV CH,[DI+OFF] ;ld b,(iy+off)
MOV DI,[IY]
MOV CL,[DI+OFF] ;ld c,(iy+off)
MOV DI,[IY]
MOV DH,[DI+OFF] ;ld d,(iy+off)
MOV DI,[IY]
MOV DL,[DI+OFF] ;ld e,(iy+off)
MOV DI,[IY]
MOV BH,[DI+OFF] ;ld h,(iy+off)
MOV DI,[IY]
MOV BL,[DI+OFF] ;ld l,(iy+off)
MOV DI,[IY]
MOV [DI+OFF],CH ;ld (iy+off),b
MOV DI,[IY]
MOV [DI+OFF],CL ;ld (iy+off),c
MOV DI,[IY]
MOV [DI+OFF],DH ;ld (iy+off),d
MOV DI,[IY]
MOV [DI+OFF],DL ;ld (iy+off),e
MOV DI,[IY]
MOV [DI+OFF],BH ;ld (iy+off),h
MOV DI,[IY]
MOV [DI+OFF],BL ;ld (iy+off),l
MOV DI,[IY]
MOV [DI+OFF],AL ;ld (iy+off),a
MOV DI,[IY]
MOV AL,[DI+OFF] ;ld a,(iy+off)
MOV DI,[IY]
ADD AL,[DI+OFF] ;add a,(iy+off)
MOV DI,[IY]
ADC AL,[DI+OFF] ;adc a,(iy+off)
MOV DI,[IY]
SUB AL,[DI+OFF] ;sub (iy+off)
MOV DI,[IY]
SBB AL,[DI+OFF] ;sbc a,(iy+off)
MOV DI,[IY]
AND AL,[DI+OFF] ;and (iy+off)
MOV DI,[IY]
XOR AL,[DI+OFF] ;xor (iy+off)
MOV DI,[IY]
OR AL,[DI+OFF] ;or (iy+off)
MOV DI,[IY]
CMP AL,[DI+OFF] ;cp (iy+off)
POP [IY] ;pop iy
POP SI
XCHG SI,[IY]
PUSH SI ;ex (sp),iy
PUSH [IY] ;push iy
MOV DI,[IY]
JMP DI ;jp (iy)
MOV SP,[IY] ;ld sp,iy
MOV DI,[IY]
ROL B,[DI+OFF] ;rlc (iy+off)
MOV DI,[IY]
ROR B,[DI+OFF] ;rrc (iy+off)
MOV DI,[IY]
RCL B,[DI+OFF] ;rl (iy+off)
MOV DI,[IY]
RCR B,[DI+OFF] ;rr (iy+off)
MOV DI,[IY]
SAL B,[DI+OFF] ;sla (iy+off)
MOV DI,[IY]
SAR B,[DI+OFF] ;sra (iy+off)
MOV DI,[IY]
SHR B,[DI+OFF] ;srl (iy+off)
MOV DI,[IY]
RCR AH
TEST B,[DI+OFF] ,001H
RCL AH ;bit 0,(iy+off)
MOV DI,[IY]
RCR AH
TEST B,[DI+OFF] ,002H
RCL AH ;bit 1,(iy+off)
MOV DI,[IY]
RCR AH
TEST B,[DI+OFF] ,004H
RCL AH ;bit 2,(iy+off)
MOV DI,[IY]
RCR AH
TEST B,[DI+OFF] ,008H
RCL AH ;bit 3,(iy+off)
MOV DI,[IY]
RCR AH
TEST B,[DI+OFF] ,010H
RCL AH ;bit 4,(iy+off)
MOV DI,[IY]
RCR AH
TEST B,[DI+OFF] ,020H
RCL AH ;bit 5,(iy+off)
MOV DI,[IY]
RCR AH
TEST B,[DI+OFF] ,040H
RCL AH ;bit 6,(iy+off)
MOV DI,[IY]
RCR AH
TEST B,[DI+OFF] ,080H
RCL AH ;bit 7,(iy+off)
MOV DI,[IY]
LAHF
AND B,[DI+OFF] ,0FEH
SAHF ;res 0,(iy+off)
MOV DI,[IY]
LAHF
AND B,[DI+OFF] ,0FDH
SAHF ;res 1,(iy+off)
MOV DI,[IY]
LAHF
AND B,[DI+OFF] ,0FBH
SAHF ;res 2,(iy+off)
MOV DI,[IY]
LAHF
AND B,[DI+OFF] ,0F7H
SAHF ;res 3,(iy+off)
MOV DI,[IY]
LAHF
AND B,[DI+OFF] ,0EFH
SAHF ;res 4,(iy+off)
MOV DI,[IY]
LAHF
AND B,[DI+OFF] ,0DFH
SAHF ;res 5,(iy+off)
MOV DI,[IY]
LAHF
AND B,[DI+OFF] ,0BFH
SAHF ;res 6,(iy+off)
MOV DI,[IY]
LAHF
AND B,[DI+OFF] ,07FH
SAHF ;res 7,(iy+off)
MOV DI,[IY]
LAHF
OR B,[DI+OFF] ,001H
SAHF ;set 0,(iy+off)
MOV DI,[IY]
LAHF
OR B,[DI+OFF] ,002H
SAHF ;set 1,(iy+off)
MOV DI,[IY]
LAHF
OR B,[DI+OFF] ,004H
SAHF ;set 2,(iy+off)
MOV DI,[IY]
LAHF
OR B,[DI+OFF] ,008H
SAHF ;set 3,(iy+off)
MOV DI,[IY]
LAHF
OR B,[DI+OFF] ,010H
SAHF ;set 4,(iy+off)
MOV DI,[IY]
LAHF
OR B,[DI+OFF] ,020H
SAHF ;set 5,(iy+off)
MOV DI,[IY]
LAHF
OR B,[DI+OFF] ,040H
SAHF ;set 6,(iy+off)
MOV DI,[IY]
LAHF
OR B,[DI+OFF] ,080H
SAHF ;set 7,(iy+off)
Z80命令の1語が、1~3語程度の8086の命令に割合多く変換されていることがわかります。これは、Z80も8086も祖を8080という共通のものに持ちアーキテクチャに共通している個所が多いことから得られたものでしょう。
変換できなかった命令
変換できなかった命令は
XXX ,
*** Opcode Error ;xxx
の形で変換されます。以下の命令が変換エラーとなっており、凡そ86-DOS User's Manualに書かれてある通りなのですが、
CPD
CPI
IM 0
IM 1
IM 2
IND
INDR
INI
INIR
LDD
LDI
NOP
OTDR
OTIR
OUTD
OUTI
RLD
RRD
NOPが変換されないのは意外な感じでした。
これらの命令が変換がされない理由は
- Z80の割り込み周り等8086の機能に変換不能
- 使用頻度が低い命令なので非対応
- プログラムが未完成
のいずれかと思われます。完全に自動に変換してくれることを期待すると痛い目を見るかもしれません。
互換性について
Z80のDJNZ命令はフラグに変化を与えませんが、TRANS.COMで変換した8086のプログラムは
DEC CH
; *** WARNING: DJNZ does not affect flags - DEC does.
JNZ ADDR ;djnz addr
とコメントにある通りフラグに変化を与えます。これは
LAHF
DEC CH
JZ L0000
SAHF
JMP ADDR
L0000: SAHF
等変換していればフラグの変化は避けられる程度のものなので手抜きのような気がします。
また、条件分岐命令はJP XX,ADDRもJR XX,ADDRも一律Jxx ADDRへ変換されますが、8086の条件分岐命令は分岐できる先の範囲が-126~+129に限られ、それを超える場合にはジャンプ命令を飛び越える
JNxx L0000
JMP ADDR
L0000:
コーディングが必要とされます。TRANS.COMを使用してZ80から8086へ変換を行ったプログラムがアセンブル時に条件分岐先が届かないエラーとなった場合、手作業で修正を行う必要が生じます。
あと、先にも述べた通りZ80も8086も8080に機能を追加したようなアーキテクチャとなっていますが、例えばオーバーフローの検出を、Z80は8080由来のパリティフラグにオーバーフローフラグの機能を追加させたのに対し、8086は独立にオーバーフローフラグを設けています。そのため、Z80のプログラムでパリティフラグを参照している場合にはオーバフローとパリティーのどちらを検出しているかは命令を遡って参照しないと判断する必要があるのですが、TRANS.COMでは、
JPO ADDR
; *** WARNING: Parity flag not always same as Z80. ;jp po,addr
JPE ADDR
; *** WARNING: Parity flag not always same as Z80. ;jp pe,addr
注意のコメントを出力するだけで済ませています。ある程度の手作業が介在することは前提とした設計となっているようです。
まとめ
以上を踏まえた上で、Z80のアセンブラで書かれたプログラムを8086用に書き換える作業が将来的に発生したとして(ないだろうけども)、TRANS.COMの使用はお勧めいたしません。
- ソースがアセンブラで書かれていて修正や変更にコストを要する
- 動作環境がMS-DOS
- 出力形式が86-DOS用アセンブラ
という点も現代的ではないと思われるので、参考にできる部分は参考にさせていただいた上で、LL言語かなんかで自前でコンバーターを作成するのが良いのではないかと思います。
おわりに
おわりです。