#include "std.h"
#include "emul.h"
#include "vars.h"
#include "memory.h"
#include "dbglabls.h"
#include "z80asm.h"
#include "util.h"
char asmbuf[0x40];
#define _iw 9
#define _ib 10
#define _shrt 27
#define _ld 0x89
#define _zr16 0x8A
#define _zr8 0x8B
#define _cb 0x8C
#define _zjr 0x8D
#define _hl 0x8E
#define _zr81 0x8F
#define _zop 0x90
#define _zf 0x91
#define _zr16a 0x92
#define _zr8_ 0x9D
#define _zr81_ 0x9E
//=============================================================================
static unsigned char asm_tab_z80[] =
{
/*
#if 0
2,0xED,0xFF,0xFF,0xFF, // call unreal api
'u','a','p','i',0,
#endif
*/
// fix bug out (c),a => out (0C),a
//-------------------------------------------------------------------------
2, 0xED, 0x70, 0xFF, 0xFF, // in (c)
'i','n',' ','(','c',')',0,
//-------------------------------------------------------------------------
2, 0xED, 0x71, 0xFF, 0xFF, // out (c),0
'o','u','t',' ','(','c',')',',','0',0,
//-------------------------------------------------------------------------
2, 0xED, 0x40, 0xFF, 0xC7, // in r8,(c)
'i','n',' ',_zr8,',','(','c',')',0,
//-------------------------------------------------------------------------
2, 0xED, 0x41, 0xFF, 0xC7, // out (c),r8
'o','u','t',' ','(','c',')',',',_zr8,0,
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
1,0xCB,0xFF, // all cb-opcodes
_cb,0,
//-------------------------------------------------------------------------
1, 0x00, 0xFF, // nop
'n','o','p',0,
//-------------------------------------------------------------------------
1, 0x08, 0xFF, // ex af,af'
'e','x',' ','a','f',',','a','f','\'',0,
1, 0x08, 0xFF, // exa //[NS]
'e','x','a', 0 ,
//-------------------------------------------------------------------------
1,0x02, 0xFF, // ld (bc),a
_ld, '(','b','c',')',',','a',0,
//-------------------------------------------------------------------------
1,0x12, 0xFF, // ld (de),a
_ld, '(','d','e',')',',','a',0,
//-------------------------------------------------------------------------
1,0x0A, 0xFF, // ld a,(bc)
_ld, 'a',',','(','b','c',')',0,
//-------------------------------------------------------------------------
1,0x1A, 0xFF, // ld a,(de)
_ld, 'a',',','(','d','e',')',0,
//-------------------------------------------------------------------------
1,0x03,0xCF, // inc r16
'i','n','c',' ',_zr16,0,
//-------------------------------------------------------------------------
1,0x0B,0xCF, // dec r16
'd','e','c',' ',_zr16,0,
//-------------------------------------------------------------------------
1,0x04,0xC7, // inc r8
'i','n','c',' ', _zr8,0,
//-------------------------------------------------------------------------
1, 0x05, 0xC7, // dec r8
'd','e','c',' ', _zr8,0,
//-------------------------------------------------------------------------
1, 0x07, 0xFF, // rlca
'r','l','c','a',0,
//-------------------------------------------------------------------------
1, 0x17, 0xFF, // rla
'r','l','a',0,
//-------------------------------------------------------------------------
1, 0x27, 0xFF, // daa
'd','a','a',0,
//-------------------------------------------------------------------------
1, 0x37, 0xFF, // scf
's','c','f',0,
//-------------------------------------------------------------------------
1, 0x0F, 0xFF, // rrca
'r','r','c','a',0,
//-------------------------------------------------------------------------
1, 0x1F, 0xFF, // rra
'r','r','a',0,
//-------------------------------------------------------------------------
1, 0x2F, 0xFF, // cpl
'c','p','l',0,
//-------------------------------------------------------------------------
1, 0x3F, 0xFF, // ccf
'c','c','f',0,
//-------------------------------------------------------------------------
1, 0x00, 0xC7, // relative jumps
_zjr, _shrt, 0,
//-------------------------------------------------------------------------
1, 0x09, 0xCF, // add hl, r16
'a','d','d',' ',_hl,',',_zr16,0,
//-------------------------------------------------------------------------
1, 0x32, 0xFF, // ld (nnnn),a
_ld,'(',_iw,')',',','a',0,
//-------------------------------------------------------------------------
1, 0x3A, 0xFF, // ld a,(nnnn)
_ld,'a',',','(',_iw,')',0,
//-------------------------------------------------------------------------
1, 0x22, 0xFF, // ld (nnnn),hl
_ld,'(',_iw,')',',',_hl,0,
//-------------------------------------------------------------------------
1, 0x2A, 0xFF, // ld hl,(nnnn)
_ld,_hl,',','(',_iw,')',0,
//-------------------------------------------------------------------------
1, 0x76, 0xFF, // halt
'h','a','l','t',0,
//-------------------------------------------------------------------------
1, 0x40, 0xC0, // ld r8,r8
_ld, _zr8_, ',', _zr81_, 0,
//-------------------------------------------------------------------------
1, 0x80, 0xC0, // op r8
_zop/*, ' '*/, _zr81, 0,
//-------------------------------------------------------------------------
1, 0xC0, 0xC7, // ret cc
'r','e','t',' ',_zf,0,
//-------------------------------------------------------------------------
1, 0xC2, 0xC7, // jp cc, nnnn
'j','p',' ',_zf,',',_iw,0,
//-------------------------------------------------------------------------
1, 0xC4, 0xC7, // call cc, nnnn
'c','a','l','l',' ',_zf,',',_iw,0,
//-------------------------------------------------------------------------
1, 0xC6, 0xC7, // op immb
_zop/*, ' '*/, _ib, 0,
//-------------------------------------------------------------------------
1, 0xC1, 0xCF, // pop r16a
'p','o','p',' ',_zr16a,0,
//-------------------------------------------------------------------------
1, 0xC5, 0xCF, // push r16a
'p','u','s','h',' ',_zr16a,0,
//-------------------------------------------------------------------------
1, 0xC3, 0xFF, // jp nnnn
'j','p', ' ', _iw,0,
//-------------------------------------------------------------------------
1, 0xD3, 0xFF, // out (nn),a
'o','u','t',' ','(',_ib,')',',','a',0,
//-------------------------------------------------------------------------
1, 0xE3, 0xFF, // ex (sp),hl
'e','x',' ','(','s','p',')',',',_hl,0,
//-------------------------------------------------------------------------
1, 0xF3, 0xFF, // di
'd','i',0,
//-------------------------------------------------------------------------
1, 0xC9, 0xFF, // ret
'r','e','t',0,
//-------------------------------------------------------------------------
1, 0xD9, 0xFF, // exx
'e','x','x',0,
//-------------------------------------------------------------------------
1, 0xE9, 0xFF, // jp (hl)
'j','p',' ','(',_hl,')',0,
//-------------------------------------------------------------------------
1, 0xF9, 0xFF, // ld sp, hl
_ld, 's','p',',',_hl,0,
//-------------------------------------------------------------------------
1, 0xDB, 0xFF, // in a,(nn)
'i','n',' ','a',',','(',_ib,')',0,
//-------------------------------------------------------------------------
1, 0xEB, 0xFF, // ex de,hl - no 'ex de,ix' !
'e','x',' ','d','e',',','h','l',0,
1, 0xEB, 0xFF, // exd [NS]
'e','x','d', 0 ,
//-------------------------------------------------------------------------
1, 0xFB, 0xFF, // ei
'e','i',0,
//-------------------------------------------------------------------------
1, 0xCD, 0xFF, // call nnnn
'c','a','l','l',' ',_iw,0,
//-------------------------------------------------------------------------
1, 0xC7, 0xFF, // rst 0
'r','s','t',' ','0',0,
//-------------------------------------------------------------------------
1, 0xCF, 0xFF, // rst 8
'r','s','t',' ','8',0,
//-------------------------------------------------------------------------
1, 0xD7, 0xFF, // rst 10
'r','s','t',' ','1','0',0,
//-------------------------------------------------------------------------
1, 0xDF, 0xFF, // rst 18
'r','s','t',' ','1','8',0,
//-------------------------------------------------------------------------
1, 0xE7, 0xFF, // rst 20
'r','s','t',' ','2','0',0,
//-------------------------------------------------------------------------
1, 0xEF, 0xFF, // rst 28
'r','s','t',' ','2','8',0,
//-------------------------------------------------------------------------
1, 0xF7, 0xFF, // rst 30
'r','s','t',' ','3','0',0,
//-------------------------------------------------------------------------
1, 0xFF, 0xFF, // rst 38
'r','s','t',' ','3','8',0,
//-------------------------------------------------------------------------
/*
// ED opcodes
#if 0 // moved above
2, 0xED, 0x70, 0xFF, 0xFF, // in (c)
'i','n',' ','(','c',')',0,
2, 0xED, 0x71, 0xFF, 0xFF, // out (c),0
'o','u','t',' ','(','c',')',',','0',0,
2, 0xED, 0x40, 0xFF, 0xC7, // in r8,(c)
'i','n',' ',_zr8,',','(','c',')',0,
2, 0xED, 0x41, 0xFF, 0xC7, // out (c),r8
'o','u','t',' ','(','c',')',',',_zr8,0,
#endif
*/
//-------------------------------------------------------------------------
2, 0xED, 0x42, 0xFF, 0xCF, // sbc hl,r16
's','b','c',' ','h','l',',',_zr16,0,
//-------------------------------------------------------------------------
2, 0xED, 0x4A, 0xFF, 0xCF, // adc hl,r16
'a','d','c',' ','h','l',',',_zr16,0,
//-------------------------------------------------------------------------
2, 0xED, 0x43, 0xFF, 0xCF, // ld (nnnn), r16
_ld, '(',_iw,')',',',_zr16, 0,
//-------------------------------------------------------------------------
2, 0xED, 0x4B, 0xFF, 0xCF, // ld r16, (nnnn)
_ld, _zr16, ',', '(',_iw,')', 0,
//-------------------------------------------------------------------------
2, 0xED, 0x44, 0xFF, 0xC7, // neg
'n','e','g',0,
//-------------------------------------------------------------------------
2, 0xED, 0x45, 0xFF, 0xCF, // retn
'r','e','t','n',0,
//-------------------------------------------------------------------------
2, 0xED, 0x4D, 0xFF, 0xCF, // reti
'r','e','t','i',0,
//-------------------------------------------------------------------------
2, 0xED, 0x46, 0xFF, 0xDF, // im 0
'i','m',' ','0',0,
//-------------------------------------------------------------------------
2, 0xED, 0x56, 0xFF, 0xDF, // im 1
'i','m',' ','1',0,
//-------------------------------------------------------------------------
2, 0xED, 0x5E, 0xFF, 0xDF, // im 2
'i','m',' ','2',0,
//-------------------------------------------------------------------------
2, 0xED, 0x4E, 0xFF, 0xDF, // im 0/1
'i','m',' ','0','/','1',0,
//-------------------------------------------------------------------------
2, 0xED, 0x47, 0xFF, 0xFF, // ld i,a
_ld, 'i',',','a',0,
//-------------------------------------------------------------------------
2, 0xED, 0x57, 0xFF, 0xFF, // ld a,i
_ld, 'a',',','i',0,
//-------------------------------------------------------------------------
2, 0xED, 0x67, 0xFF, 0xFF, // rrd
'r','r','d',0,
//-------------------------------------------------------------------------
2, 0xED, 0x4F, 0xFF, 0xFF, // ld r,a
_ld, 'r',',','a',0,
//-------------------------------------------------------------------------
2, 0xED, 0x5F, 0xFF, 0xFF, // ld a,r
_ld, 'a',',','r',0,
//-------------------------------------------------------------------------
2, 0xED, 0x6F, 0xFF, 0xFF, // rld
'r','l','d',0,
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
2, 0xED, 0xA0, 0xFF, 0xFF, // ldi
'l','d','i',0,
//-------------------------------------------------------------------------
2, 0xED, 0xA1, 0xFF, 0xFF, // cpi
'c','p','i',0,
//-------------------------------------------------------------------------
2, 0xED, 0xA2, 0xFF, 0xFF, // ini
'i','n','i',0,
//-------------------------------------------------------------------------
2, 0xED, 0xA3, 0xFF, 0xFF, // outi
'o','u','t','i',0,
//-------------------------------------------------------------------------
2, 0xED, 0xA8, 0xFF, 0xFF, // ldd
'l','d','d',0,
//-------------------------------------------------------------------------
2, 0xED, 0xA9, 0xFF, 0xFF, // cpd
'c','p','d',0,
//-------------------------------------------------------------------------
2, 0xED, 0xAA, 0xFF, 0xFF, // ind
'i','n','d',0,
//-------------------------------------------------------------------------
2, 0xED, 0xAB, 0xFF, 0xFF, // outd
'o','u','t','d',0,
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
2, 0xED, 0xB0, 0xFF, 0xFF, // ldir
'l','d','i','r',0,
//-------------------------------------------------------------------------
2, 0xED, 0xB1, 0xFF, 0xFF, // cpir
'c','p','i','r',0,
//-------------------------------------------------------------------------
2, 0xED, 0xB2, 0xFF, 0xFF, // inir
'i','n','i','r',0,
//-------------------------------------------------------------------------
2, 0xED, 0xB3, 0xFF, 0xFF, // otir
'o','t','i','r',0,
//-------------------------------------------------------------------------
2, 0xED, 0xB8, 0xFF, 0xFF, // lddr
'l','d','d','r',0,
//-------------------------------------------------------------------------
2, 0xED, 0xB9, 0xFF, 0xFF, // cpdr
'c','p','d','r',0,
//-------------------------------------------------------------------------
2, 0xED, 0xBA, 0xFF, 0xFF, // indr
'i','n','d','r',0,
//-------------------------------------------------------------------------
2, 0xED, 0xBB, 0xFF, 0xFF, // otdr
'o','t','d','r',0,
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
2, 0xED, 0x00, 0xFF, 0x00, // all others 'ED'
'n','o','p','*',0,
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
// place immediates after all - 'ld a,b' is not 'ld a,0B'
1, 0x01, 0xCF, // ld r16,imm16
_ld, _zr16, ',', _iw, 0,
//-------------------------------------------------------------------------
1, 0x06, 0xC7, // ld r8, imm8
_ld, _zr8, ',', _ib, 0,
//-------------------------------------------------------------------------
0 // end
};
//=============================================================================
#define abs(x) ((x)>0 ? (x) : (-(x)))
//=============================================================================
// по 3
//static char z80r16_1[] = "bc\0de\0hl\0sp";
static char z80r16_1[] = "bc\0"
"de\0"
"hl\0"
"sp";
//static char z80r16_2[] = "bc\0de\0ix\0sp";
static char z80r16_2[] = "bc\0"
"de\0"
"ix\0"
"sp";
//static char z80r16_3[] = "bc\0de\0iy\0sp";
static char z80r16_3[] = "bc\0"
"de\0"
"iy\0"
"sp";
//=============================================================================
// по 5 остаток набираетсо \0
#define Z80R8_WIDTH 5
#define Z80R8_COUNT 16 //8 + 8 альтернативных (результат & 7)
//-----------------------------------------------------------------------------
//static char z80r8_1[] = "b\0\0\0\0c\0\0\0\0d\0\0\0\0e\0\0\0\0h\0\0\0\0l\0\0\0\0(hl)\0a";
static char z80r8_1[] = "b\0\0\0\0" //0
"c\0\0\0\0" //1
"d\0\0\0\0" //2
"e\0\0\0\0" //3
"h\0\0\0\0" //4
"l\0\0\0\0" //5
"(hl)\0" //6
"a\0\0\0\0" //7
"b\0\0\0\0" //0 ALT naming
"c\0\0\0\0" //1
"d\0\0\0\0" //2
"e\0\0\0\0" //3
"h\0\0\0\0" //4
"l\0\0\0\0" //5
"(hl)\0" //6
"a\0\0\0\0"; //7
//=============================================================================
//static char z80r8_2[] = "b\0\0\0\0c\0\0\0\0d\0\0\0\0e\0\0\0\0xh\0\0\0xl\0\0\0(1x)\0a";
// только буфер (будет перезаписан!!!)
static char z80r8_2[] = "b\0\0\0\0" //0
"c\0\0\0\0" //1
"d\0\0\0\0" //2
"e\0\0\0\0" //3
"ixh\0\0" //4
"ixl\0\0" //5
"(1x)\0" //6
"a\0\0\0\0" //7
"b\0\0\0\0" //0 ALT naming
"c\0\0\0\0" //1
"d\0\0\0\0" //2
"e\0\0\0\0" //3
"xh\0\0\0" //4
"xl\0\0\0" //5
"(1x)\0" //6
"a\0\0\0\0"; //7
//-----------------------------------------------------------------------------
// IXH IXL Style
const char z80r8_2_style_0[] = "b\0\0\0\0" //0
"c\0\0\0\0" //1
"d\0\0\0\0" //2
"e\0\0\0\0" //3
"ixh\0\0" //4 ixh main
"ixl\0\0" //5 ixl main
"(1x)\0" //6
"a\0\0\0\0" //7
"b\0\0\0\0" //0 ALT naming
"c\0\0\0\0" //1
"d\0\0\0\0" //2
"e\0\0\0\0" //3
"xh\0\0\0" //4 xh main
"xl\0\0\0" //5 xl main
"(1x)\0" //6
"a\0\0\0\0"; //7
//-----------------------------------------------------------------------------
// XH XL Style
const char z80r8_2_style_1[] = "b\0\0\0\0" //0
"c\0\0\0\0" //1
"d\0\0\0\0" //2
"e\0\0\0\0" //3
"xh\0\0\0" //4 xh main
"xl\0\0\0" //5 xl main
"(1x)\0" //6
"a\0\0\0\0" //7
"b\0\0\0\0" //0 ALT naming
"c\0\0\0\0" //1
"d\0\0\0\0" //2
"e\0\0\0\0" //3
"ixh\0\0" //4 ixh alt
"ixl\0\0" //5 ixl alt
"(1x)\0" //6
"a\0\0\0\0"; //7
//=============================================================================
//=============================================================================
//static char z80r8_3[] = "b\0\0\0\0c\0\0\0\0d\0\0\0\0e\0\0\0\0yh\0\0\0yl\0\0\0(1y)\0a";
static char z80r8_3[] = "b\0\0\0\0" //0
"c\0\0\0\0" //1
"d\0\0\0\0" //2
"e\0\0\0\0" //3
"iyh\0\0" //4
"iyl\0\0" //5
"(1y)\0" //6
"a\0\0\0\0" //7
"b\0\0\0\0" //0 ALT naming
"c\0\0\0\0" //1
"d\0\0\0\0" //2
"e\0\0\0\0" //3
"yh\0\0\0" //4
"yl\0\0\0" //5
"(1y)\0" //6
"a\0\0\0\0"; //7
//-----------------------------------------------------------------------------
// IYH IYL Style
const char z80r8_3_style_0[] = "b\0\0\0\0" //0
"c\0\0\0\0" //1
"d\0\0\0\0" //2
"e\0\0\0\0" //3
"iyh\0\0" //4 iyh main
"iyl\0\0" //5 iyl main
"(1y)\0" //6
"a\0\0\0\0" //7
"b\0\0\0\0" //0 ALT naming
"c\0\0\0\0" //1
"d\0\0\0\0" //2
"e\0\0\0\0" //3
"yh\0\0\0" //4 yh alt
"yl\0\0\0" //5 yl alt
"(1y)\0" //6
"a\0\0\0\0"; //7
//-----------------------------------------------------------------------------
// YH YL Style
const char z80r8_3_style_1[] = "b\0\0\0\0" //0 ALT naming
"c\0\0\0\0" //1
"d\0\0\0\0" //2
"e\0\0\0\0" //3
"yh\0\0\0" //4 yh main
"yl\0\0\0" //5 yl main
"(1y)\0" //6
"a\0\0\0\0" //7
"b\0\0\0\0" //0
"c\0\0\0\0" //1
"d\0\0\0\0" //2
"e\0\0\0\0" //3
"iyh\0\0" //4 iyh alt
"iyl\0\0" //5 iyl alt
"(1y)\0" //6
"a\0\0\0\0"; //7
//-----------------------------------------------------------------------------
//=============================================================================
// по 7
//static char cbtab[] = "rlc \0\0\0rrc \0\0\0rl \0\0\0\0rr \0\0\0\0sla \0\0\0sra \0\0\0sli \0\0\0srl \0\0\0"
// "bit 0,\0bit 1,\0bit 2,\0bit 3,\0bit 4,\0bit 5,\0bit 6,\0bit 7,\0"
// "res 0,\0res 1,\0res 2,\0res 3,\0res 4,\0res 5,\0res 6,\0res 7,\0"
// "set 0,\0set 1,\0set 2,\0set 3,\0set 4,\0set 5,\0set 6,\0set 7,\0";
static char cbtab[] = "rlc \0\0\0"
"rrc \0\0\0"
"rl \0\0\0\0"
"rr \0\0\0\0"
"sla \0\0\0"
"sra \0\0\0"
"sli \0\0\0"
"srl \0\0\0"
"bit 0,\0"
"bit 1,\0"
"bit 2,\0"
"bit 3,\0"
"bit 4,\0"
"bit 5,\0"
"bit 6,\0"
"bit 7,\0"
"res 0,\0"
"res 1,\0"
"res 2,\0"
"res 3,\0"
"res 4,\0"
"res 5,\0"
"res 6,\0"
"res 7,\0"
"set 0,\0"
"set 1,\0"
"set 2,\0"
"set 3,\0"
"set 4,\0"
"set 5,\0"
"set 6,\0"
"set 7,\0";
//=============================================================================
//static char zjr[] = "xxxxxx\0xxxxxx\0djnz \0\0jr \0\0\0\0jr nz,\0jr z,\0\0jr nc,\0jr c,\0";
static char zjr[] = "xxxxxx\0"
"xxxxxx\0"
"djnz \0\0"
"jr \0\0\0\0"
"jr nz,\0"
"jr z,\0\0"
"jr nc,\0"
"jr c,\0";
//=============================================================================
// по 8
#define ZOP_WIDTH 8
#define ZOP_COUNT 16 //8 + 8 альтернативных (результат & 7)
//-----------------------------------------------------------------------------
//char zop[] = "add\0adc\0sub\0sbc\0and\0xor\0or\0\0cp"; lvd OLD
//static char zop[] = "add a,\0\0adc a,\0\0sub \0\0\0\0sbc a,\0\0and \0\0\0\0xor \0\0\0\0or \0\0\0\0\0cp \0\0\0\0\0";
//-----------------------------------------------------------------------------
// буфер будет перезаписан! при входе в дебагер согласно конфигу
static char zop[] = "add a,\0\0" //0 add a,a
"adc a,\0\0" //1 adc a,a
"sub \0\0\0\0" //2 sub a
"sbc a,\0\0" //3 sbc a,a
"and \0\0\0\0" //4 and a
"xor \0\0\0\0" //5 xor a
"or \0\0\0\0\0" //6 or a
"cp \0\0\0\0\0" //7 cp a
"add \0\0\0\0" //0 add a ALT
"adc \0\0\0\0" //1 adc a
"sub a,\0\0" //2 sub a,a "sub \0\0\0\0"
"sbc \0\0\0\0" //3 sbc a
"and a,\0\0" //4 and a,a "and \0\0\0\0"
"xor a,\0\0" //5 xor a,a "xor \0\0\0\0"
"or a,\0\0\0" //6 or a,a "or \0\0\0\0\0"
"cp a,\0\0\0"; //7 cp a,a "cp \0\0\0\0\0"
//-----------------------------------------------------------------------------
// Full
const char zop_style_0[] = "add a,\0\0" //0 add a,a
"adc a,\0\0" //1 adc a,a
"sub a,\0\0" //2 sub a,a
"sbc a,\0\0" //3 sbc a,a
"and a,\0\0" //4 and a,a
"xor a,\0\0" //5 xor a,a
"or a,\0\0\0" //6 or a,a
"cp a,\0\0\0" //7 cp a,a
"add \0\0\0\0" //0 add a - ALT
"adc \0\0\0\0" //1 adc a
"sub \0\0\0\0" //2 sub a
"sbc \0\0\0\0" //3 sbc a
"and \0\0\0\0" //4 and a
"xor \0\0\0\0" //5 xor a
"or \0\0\0\0\0" //6 or a
"cp \0\0\0\0\0"; //7 cp a
//-----------------------------------------------------------------------------
// Short
const char zop_style_1[] = "add \0\0\0\0" //0 add a
"adc \0\0\0\0" //1 adc a
"sub \0\0\0\0" //2 sub a
"sbc \0\0\0\0" //3 sbc a
"and \0\0\0\0" //4 and a
"xor \0\0\0\0" //5 xor a
"or \0\0\0\0\0" //6 or a
"cp \0\0\0\0\0" //7 cp a
"add a,\0\0" //0 add a,a - ALT
"adc a,\0\0" //1 adc a,a
"sub a,\0\0" //2 sub a,a
"sbc a,\0\0" //3 sbc a,a
"and a,\0\0" //4 and a,a
"xor a,\0\0" //5 xor a,a
"or a,\0\0\0" //6 or a,a
"cp a,\0\0\0"; //7 cp a,a
//-----------------------------------------------------------------------------
// Classic
static char zop_style_2[] = "add a,\0\0" //0 add a,a
"adc a,\0\0" //1 adc a,a
"sub \0\0\0\0" //2 sub a
"sbc a,\0\0" //3 sbc a,a
"and \0\0\0\0" //4 and a
"xor \0\0\0\0" //5 xor a
"or \0\0\0\0\0" //6 or a
"cp \0\0\0\0\0" //7 cp a
"add \0\0\0\0" //0 add a ALT
"adc \0\0\0\0" //1 adc a
"sub a,\0\0" //2 sub a,a "sub \0\0\0\0"
"sbc \0\0\0\0" //3 sbc a
"and a,\0\0" //4 and a,a "and \0\0\0\0"
"xor a,\0\0" //5 xor a,a "xor \0\0\0\0"
"or a,\0\0\0" //6 or a,a "or \0\0\0\0\0"
"cp a,\0\0\0"; //7 cp a,a "cp \0\0\0\0\0"
//=============================================================================
//static char zf[] = "nz\0z\0\0nc\0c\0\0po\0pe\0p\0\0m";
static char zf[] = "nz\0"
"z\0\0"
"nc\0"
"c\0\0"
"po\0"
"pe\0"
"p\0\0"
"m";
//=============================================================================
//=============================================================================
void update_disasm_style()
{
//-------------------------------------------------------------------------
switch (conf.Disasm_A_Mnemonics_Style)
{
case 0: memcpy( zop, zop_style_0, sizeof(zop_style_0)); break; // Full form (xxx a,a)
case 1: memcpy( zop, zop_style_1, sizeof(zop_style_1)); break; // Short form (xxx a)
case 2: memcpy( zop, zop_style_2, sizeof(zop_style_2)); break; // Classic form
}
//-------------------------------------------------------------------------
switch (conf.Disasm_Index_H_L_Style)
{
//IXH IXL IYH IYL
case 0: memcpy( z80r8_2, z80r8_2_style_0, sizeof(z80r8_2_style_0));
memcpy( z80r8_3, z80r8_3_style_0, sizeof(z80r8_3_style_0)); break;
//XH XL YH YL
case 1: memcpy( z80r8_2, z80r8_2_style_1, sizeof(z80r8_2_style_1));
memcpy( z80r8_3, z80r8_3_style_1, sizeof(z80r8_3_style_1)); break;
}
//-------------------------------------------------------------------------
return;
}
//=============================================================================
static void disasm_address( char *line, unsigned addr, char labels)
{
char *label = nullptr;
// if (labels&&addr) label = mon_labels.find(am_r(addr)); //0.39.0
char *virtlabel = nullptr; //NEDOREPO
//-------------------------------------------------------------------------
if (labels && addr)
{
label = mon_labels.find( am_r( addr));
virtlabel = mon_labels.find( ((unsigned char *)NULL)+addr);
}
//-------------------------------------------------------------------------
if (virtlabel) // NEDOREPO
label = virtlabel;
//-------------------------------------------------------------------------
if (label)
{
//strcpy(line, label);
int i;
//---------------------------------------------------------------------
for (i = 0; (i < 20) && label[i]; i++)
line[i] = label[i];
//---------------------------------------------------------------------
line[i] = label[i];
} //Alone Coder 0.36.6
//-------------------------------------------------------------------------
else
{
sprintf( line, "%04X", addr & 0xFFFF);
}
//-------------------------------------------------------------------------
}
//=============================================================================
//=============================================================================
const unsigned char *disasm( const unsigned char *cmd, unsigned current, char labels)
{
const unsigned char *st = cmd;
unsigned char z80p;
char *z80r16;
char *z80r8;
z80r16 = z80r16_1;
z80r8 = z80r8_1;
z80p = 0;
//-------------------------------------------------------------------------
for ( ; ; )
{ // z80 prefixes
//---------------------------------------------------------------------
if (*cmd == 0xDD)
{
z80r16 = z80r16_2;
z80r8 = z80r8_2;
z80p = 0xDD;
}
//---------------------------------------------------------------------
else if (*cmd == 0xFD)
{
z80r16 = z80r16_3;
z80r8 = z80r8_3;
z80p = 0xFD;
}
//---------------------------------------------------------------------
else
{
break;
}
//---------------------------------------------------------------------
cmd++;
}
//-------------------------------------------------------------------------
for (unsigned char *ptr = asm_tab_z80; *ptr; )
{
// cmd - start of command, c1 - mod/rm, cm - current pointer
const unsigned char *rcmd = cmd;
//---------------------------------------------------------------------
if (*cmd == 0xED)
{
rcmd++;
z80r16 = z80r16_1;
z80r8 = z80r8_1;
z80p = 0;
}
//---------------------------------------------------------------------
const unsigned char *cm = rcmd + 1;
//---------------------------------------------------------------------
for (int j = 0; j < *ptr; j++) // match mask
if ((cmd[j] & ptr[j + *ptr + 1]) != ptr[j + 1])
goto nextcmd;
//---------------------------------------------------------------------
*asmbuf = 0;
unsigned char *pt;
//---------------------------------------------------------------------
for (pt = ptr + (2 * *ptr) + 1; *pt; pt++)
{ // scan all commands
char ln[/*32*/64];
const char *l1 = ln;
ln[0] = 0; //Alone Coder 0.36.6
//-----------------------------------------------------------------
switch (*pt)
{
//-------------------------------------------------------------
case _zr16: // in rcmd & 0x30
l1 = z80r16 + 3 * ((*rcmd >> 4) & 3);
break;
//-------------------------------------------------------------
case _zr16a: // in rcmd & 0x30
if (((*rcmd >> 4) & 3) == 3)
{
l1 = "af";
}
else
{
l1 = z80r16 + 3 * ((*rcmd >> 4) & 3);
}
break;
//-------------------------------------------------------------
case _hl: // hl/ix/iy
l1 = z80r16 + 3 * 2;
break;
//-------------------------------------------------------------
case _zjr: // relative jumps
l1 = zjr + 7 * ((*rcmd >> 3) & 7);
break;
//-------------------------------------------------------------
case _zop: // z80 operations at rcmd & 0x38
//l1 = zop + 4 * ((*rcmd >> 3) & 7); lvd OLD
//l1 = zop + 8 * ((*rcmd >> 3) & 7);
l1 = zop + ZOP_WIDTH * ((*rcmd >> 3) & 7);
break;
//-------------------------------------------------------------
case _zf: // z80 flags at rcmd & 0x38
l1 = zf + 3 * ((*rcmd >> 3) & 7);
break;
//-------------------------------------------------------------
case _cb: // all CB-opcodes
{
//---------------------------------------------------------
if (!z80p)
{
sprintf( ln,
"%s%s",
cbtab + (*cm >> 3) * 7,
z80r8_1 + (*cm & 7) * 5);
cm++;
}
//---------------------------------------------------------
else
{
//---------------------------------------------------------
if ((cm[1] & 7) != 6 && ((cm[1] & 0xC0) != 0x40)) // operand is reg,(ix+nn)
{
sprintf( ln,
"%s%s,(i%c%c%02X)",
cbtab + (cm[1] >> 3) * 7,
z80r8_1 + (cm[1] & 7) * 5,
z80p == 0xDD ? 'x' :
'y',
*(char*)cm >= 0 ? '+' :
'-',
abs(*(char*)cm)
);
}
//---------------------------------------------------------
else // only (ix+nn)
{
sprintf( ln,
"%s(i%c%c%02X)",
cbtab + (cm[1] >> 3) * 7,
z80p == 0xDD ? 'x' :
'y',
*(char*)cm >= 0 ? '+' :
'-',
abs(*(char*)cm)
);
}
//---------------------------------------------------------
cm += 2;
}
//---------------------------------------------------------
break;
}
//-------------------------------------------------------------
case _zr8: // in rcmd & 0x38
//---------------------------------------------------------
if (z80p && ((*rcmd & 0x38) == 0x30))
{
sprintf( ln,
"(i%c%c%02X)",
z80p == 0xDD ? 'x' :
'y',
*(char*)cm >= 0 ? '+' :
'-',
abs(*(char*)cm)
);
cm++;
}
//---------------------------------------------------------
else
{
l1 = z80r8 + 5 * ((*rcmd >> 3) & 7);
}
//---------------------------------------------------------
break;
//-------------------------------------------------------------
case _zr8_: // in rcmd & 0x38, in ld r8,r8
//---------------------------------------------------------
if (!z80p || (*rcmd & 7) == 6)
{
l1 = z80r8_1 + 5 * ((*rcmd >> 3) & 7);
break;
}
//---------------------------------------------------------
if ((*rcmd & 0x38) == 0x30)
{
sprintf( ln,
"(i%c%c%02X)",
z80p == 0xDD ? 'x' :
'y',
*(char*)cm >= 0 ? '+' :
'-',
abs(*(char*)cm)
);
cm++;
}
//---------------------------------------------------------
else
{
l1 = z80r8 + 5 * ((*rcmd >> 3) & 7);
}//--------------------------------------------------------
break;
//-------------------------------------------------------------
case _zr81: // in rcmd & 7
//---------------------------------------------------------
if (z80p && (*rcmd & 7) == 6)
{
sprintf( ln,
"(i%c%c%02X)",
z80p == 0xDD ? 'x' :
'y',
*(char*)cm >= 0 ? '+' :
'-',
abs(*(char*)cm)
);
cm++;
}
//---------------------------------------------------------
else
{
l1 = z80r8 + 5 * (*rcmd & 7);
}
//---------------------------------------------------------
break;
//-------------------------------------------------------------
case _zr81_: // in rcmd & 7, in ld r8,r8
//---------------------------------------------------------
if (!z80p || ((*rcmd & 0x38) == 0x30))
{
l1 = z80r8_1 + 5 * (*rcmd & 7);
break;
}
//---------------------------------------------------------
if ((*rcmd & 7) == 6)
{
sprintf( ln,
"(i%c%c%02X)",
z80p == 0xDD ? 'x' :
'y',
*(char*)cm >= 0 ? '+' :
'-',
abs(*(char*)cm)
);
cm++;
}
//---------------------------------------------------------
else
{
l1 = z80r8 + 5 * (*rcmd & 7);
}
//---------------------------------------------------------
break;
//-------------------------------------------------------------
case _ld:
l1 = "ld ";
break;
//-------------------------------------------------------------
case _shrt: // short jump
disasm_address( ln, unsigned( current + cm - st + *(signed char*) cm + 1), labels);
cm++;
break;
//-------------------------------------------------------------
case _ib: // immediate byte at cm
sprintf(ln, "%02X", *cm++);
break;
//-------------------------------------------------------------
case _iw: // immediate word at cm
disasm_address(ln, *(unsigned short*)cm, labels);
cm += 2;
break;
//-------------------------------------------------------------
default:
*(short*)ln = *pt;
//-------------------------------------------------------------
}
//-----------------------------------------------------------------
strcat(asmbuf, l1);
}
//---------------------------------------------------------------------
// make tabulation between instruction and operands
{
// if( !cpu.logena ) //LVD
{
char b1[0x40];
char *p = asmbuf;
char *q = b1;
//-------------------------------------------------------------
while (*p != ' ' && *p)
*q++ = *p++;
//-------------------------------------------------------------
*q++ = *p;
//-------------------------------------------------------------
if (*p)
{
//---------------------------------------------------------
if (conf.Disasm_Tabulation)
{
while (q < b1 + 5)
{
*q++ = ' '; // +5 - tab size=5, was 4
}
}
//---------------------------------------------------------
while(*++p)
*q++ = *p;
//---------------------------------------------------------
}
*q = 0;
strcpy(asmbuf, b1);
}
return max(cm, cmd + *ptr);
}
nextcmd:
ptr += (2 * *ptr) + 1;
//---------------------------------------------------------------------
while(*ptr++); // skip mask,code and instruction
//---------------------------------------------------------------------
}
strcpy(asmbuf, "???"); return cmd + 1;
}
//=============================================================================
//=============================================================================
static int getindex(unsigned char **ptr, char *table, unsigned width, int size)
{
// find max match - fdiv and fdivr must be found as fdivr
unsigned max = 0;
unsigned imax;
//-------------------------------------------------------------------------
for (unsigned i = 0; i < unsigned(size); i++)
{
size_t ln = strlen(table + i * width);
//---------------------------------------------------------------------
if (!strncmp((char*)*ptr, table + i * width, ln))
{
if (ln > max)
{
max = unsigned(ln);
imax = i;
}
}
//---------------------------------------------------------------------
}
if (max)
{
(*ptr) += strlen(table + imax*width);
return int(imax);
}
return -1;
}
//=============================================================================
//=============================================================================
static int scanhex(unsigned char **ptr)
{
int r = 0;
int s = 1;
//-------------------------------------------------------------------------
if (**ptr == '-')
{
(*ptr)++;
s = -1;
}
//-------------------------------------------------------------------------
if (**ptr == '+')
(*ptr)++;
//-------------------------------------------------------------------------
while (isdigit(**ptr) || (**ptr >= 'a' && **ptr <= 'f'))
{
r = 16 * r + hexdigit(**ptr);
(*ptr)++;
}
//-------------------------------------------------------------------------
return r*s;
}
//=============================================================================
static unsigned char cmdb[16];
unsigned char asmresult[24];
static unsigned char z80p;
static unsigned char a_command[0x40];
//=============================================================================
static int z80scanr8(unsigned char **ptr, unsigned char **cm)
{
// int in = getindex(ptr, z80r8_1, 5, 8);
int in = (getindex(ptr, z80r8_1, Z80R8_WIDTH, Z80R8_COUNT)) ; //+alt набор [NS]
if (in >= 0) in &= 0x07; //обрезка alt набора
//printf("in %d\n",in);
//-------------------------------------------------------------------------
if (in >= 0)
return in;
//-------------------------------------------------------------------------
char *r8 = z80r8_1;
//-------------------------------------------------------------------------
if (z80p == 0xDD)
r8 = z80r8_2;
//-------------------------------------------------------------------------
if (z80p == 0xFD)
r8 = z80r8_3;
//-------------------------------------------------------------------------
// in = getindex(ptr, r8, 5, 8);
in = (getindex(ptr, r8, Z80R8_WIDTH, Z80R8_COUNT)); //+alt набор [NS]
if (in >= 0) in &= 0x07; //обрезка alt набора
//printf("in %d\n",in);
//-------------------------------------------------------------------------
if (!z80p)
return in;
//-------------------------------------------------------------------------
// not (ix
if (*(unsigned short*)(*ptr) != WORD2('(','i'))
{
return in;
}
//-------------------------------------------------------------------------
(*ptr) += 3;
char c = char(*(*ptr - 1));
if (((z80p == 0xDD) && (c != 'x')) || ((z80p == 0xFD) && (c != 'y')))
{
return -1;
}
//-------------------------------------------------------------------------
int ofs = (**ptr == ')') ? 0 :
scanhex(ptr);
//-------------------------------------------------------------------------
if (ofs > 127 || ofs < -128)
return -1;
//-------------------------------------------------------------------------
if (*((*ptr)++) != ')')
return -1;
//-------------------------------------------------------------------------
*(signed char*)(*cm)++ = (signed char)ofs;
return 6;
}
//=============================================================================
//=============================================================================
static unsigned assemble(unsigned addr)
{
char *z80r16 = z80r16_1;
//-------------------------------------------------------------------------
if (z80p == 0xDD)
z80r16 = z80r16_2;
//-------------------------------------------------------------------------
if (z80p == 0xFD)
z80r16 = z80r16_3;
//-------------------------------------------------------------------------
for (unsigned char *p1 = asm_tab_z80; *p1; )
{
memset(cmdb, 0, sizeof(cmdb));
unsigned char *cc = a_command;
memcpy(cmdb, p1+1, *p1);
unsigned char *cmd = cmdb;
unsigned char *rcmd = cmd;
unsigned char *cm;
//---------------------------------------------------------------------
if (*cmd == 0xED)
{
rcmd++;
//-----------------------------------------------------------------
if (z80p)
goto nextcmd;
//-----------------------------------------------------------------
}
//---------------------------------------------------------------------
cm = rcmd+1;
int in;
unsigned char *ptr; //Alone Coder
//---------------------------------------------------------------------
for (ptr = p1+2 * *p1+1; *ptr; ptr++)
{
//-----------------------------------------------------------------
switch (*ptr)
{
//-------------------------------------------------------------
case _zr16: // in rcmd & 0x30
//---------------------------------------------------------
if ((in = getindex(&cc, z80r16, 3, 4)) < 0)
goto nextcmd;
//---------------------------------------------------------
*rcmd |= (in << 4);
break;
//-------------------------------------------------------------
case _zr16a: // in rcmd & 0x30
//---------------------------------------------------------
if (*(unsigned short*)cc == WORD2('a','f'))
{
cc += 2;
in = 3;
}
//---------------------------------------------------------
else
{
//-----------------------------------------------------
if ((in = getindex(&cc, z80r16, 3, 4)) < 0)
goto nextcmd;
//-----------------------------------------------------
}
//---------------------------------------------------------
*rcmd |= (in << 4);
break;
//-------------------------------------------------------------
case _zjr: // relative jumps
//---------------------------------------------------------
if ((in = getindex(&cc, zjr, 7, 8)) < 0)
goto nextcmd;
//---------------------------------------------------------
*rcmd |= (in << 3);
break;
//-------------------------------------------------------------
case _zop: // z80 ops
//---------------------------------------------------------
//if ((in = getindex(&cc, zop, 8, 8)) < 0)
if ((in = getindex(&cc, zop, ZOP_WIDTH, ZOP_COUNT)) < 0) // [NS]
goto nextcmd;
//---------------------------------------------------------
in &= 0x07; //обрезка alt вариантов [NS]
//---------------------------------------------------------
*rcmd |= (in << 3);
break;
//-------------------------------------------------------------
case _zf: // z80 flags
//---------------------------------------------------------
if ((in = getindex(&cc, zf, 3, 8)) < 0)
goto nextcmd;
//---------------------------------------------------------
*rcmd |= (in << 3);
break;
//-------------------------------------------------------------
case _hl: // hl/ix/iy
//---------------------------------------------------------
if ((in = getindex(&cc, z80r16, 3, 4)) != 2)
goto nextcmd;
//---------------------------------------------------------
break;
//-------------------------------------------------------------
case _cb: // all CB-opcodes
{
//---------------------------------------------------------
if ((in = getindex(&cc, cbtab, 7, 32)) < 0)
goto nextcmd;
//---------------------------------------------------------
int in1 = getindex(&cc, z80r8_1, 5, 8);
//---------------------------------------------------------
if (!z80p)
{
//-----------------------------------------------------
if (in1 < 0)
goto nextcmd;
//-----------------------------------------------------
}
//---------------------------------------------------------
else
{
//-----------------------------------------------------
if (in1 < 0)
{
in1 = z80scanr8(&cc, &cm);
//-------------------------------------------------
if (in1 < 0)
goto nextcmd;
//-------------------------------------------------
}
//-----------------------------------------------------
else
{
//-------------------------------------------------
if (*cc++ != ',' || z80scanr8(&cc, &cm) != 6)
goto nextcmd;
//-------------------------------------------------
}
//-----------------------------------------------------
}
//---------------------------------------------------------
*cm++ = u8(in*8+in1);
break;
}
//-------------------------------------------------------------
case _zr8: // r8 in *rcmd & 0x38
case _zr8_: // r8 in *rcmd & 0x38, in ld r8,r8
//---------------------------------------------------------
if ((in = z80scanr8(&cc, &cm)) < 0)
goto nextcmd;
//---------------------------------------------------------
*rcmd |= in << 3;
break;
//-------------------------------------------------------------
case _zr81: // r8 in *rcmd & 7
case _zr81_: // r8 in *rcmd & 7, in ld r8,r8
//---------------------------------------------------------
if ((in = z80scanr8(&cc, &cm)) < 0)
goto nextcmd;
//---------------------------------------------------------
*rcmd |= in;
break;
//-------------------------------------------------------------
case _ld:
//---------------------------------------------------------
if ((*(unsigned*)cc & 0xFFFFFF) != WORD4('l','d',' ',0))
goto nextcmd;
//---------------------------------------------------------
cc += 3;
break;
//-------------------------------------------------------------
case _shrt: // short jump
{
//---------------------------------------------------------
if (!ishex(char(*cc)))
goto nextcmd;
//---------------------------------------------------------
in = scanhex(&cc);
int x = i16( in - (int)addr + cmdb - cm - 1);
//---------------------------------------------------------
if (x > 0x7F || x < -0x80)
goto nextcmd;
//---------------------------------------------------------
*(char*)cm = char(x);
cm++;
break;
}
//-------------------------------------------------------------
case _ib: // immediate byte at cm
//---------------------------------------------------------
if ((*cc == '\'') && (cc[2] == '\''))
{
in = cc[1];
cc += 3;
goto imm;
}
//---------------------------------------------------------
if (!ishex(char(*cc)))
goto nextcmd;
//---------------------------------------------------------
in = scanhex(&cc);
//---------------------------------------------------------
if ((unsigned)in > 0xFF)
goto nextcmd;
//---------------------------------------------------------
imm:
*(char*)cm++ = (char)in;
break;
//---------------------------------------------------------
case _iw: // immediate word at cm
//---------------------------------------------------------
if (!ishex(char(*cc)))
goto nextcmd;
//---------------------------------------------------------
in = scanhex(&cc);
//---------------------------------------------------------
if ((unsigned)in > 0xFFFF)
goto nextcmd;
//---------------------------------------------------------
*(unsigned short*)cm = (unsigned short)in;
cm += 2;
break;
//-------------------------------------------------------------
default:
if (*ptr != *cc++)
goto nextcmd;
//-------------------------------------------------------------
} //switch (*ptr)
//-----------------------------------------------------------------
} //for (ptr = p1+2 * *p1+1; *ptr; ptr++)
//---------------------------------------------------------------------
if (!*cc)
return max(unsigned(cm-cmdb), unsigned(*p1));
//---------------------------------------------------------------------
nextcmd:
p1 += (2 * *p1) + 1;
//---------------------------------------------------------------------
while (*p1++);
//---------------------------------------------------------------------
}
//-------------------------------------------------------------------------
return 0;
}
//=============================================================================
//=============================================================================
unsigned assemble_cmd(unsigned char *cmd, unsigned addr)
{
unsigned char *res = a_command;
unsigned char bf[0x40];
strcpy((char*)bf, (char*)cmd);
//-------------------------------------------------------------------------
for (res = bf; *res; res++)
{ // don't allow to kill space befor (# - place 0x01
//---------------------------------------------------------------------
if (*(short*)res == WORD2( ' ', '(' ))
*(short*)res = WORD2( 1, '(' );
//---------------------------------------------------------------------
if (*(short*)res == WORD2( ' ', '#' ))
*(short*)res = WORD2( 1, '#' );
//---------------------------------------------------------------------
}
//-------------------------------------------------------------------------
res = a_command;
cmd = bf;
//-------------------------------------------------------------------------
while (*cmd == ' ')
cmd++;
//-------------------------------------------------------------------------
while (*cmd && *cmd != ' ')
*res++ = u8( tolower( *cmd++));
//-------------------------------------------------------------------------
while (*cmd)
{
//---------------------------------------------------------------------
while (*cmd == ' ' && (!isalnum(cmd[1]) || !isalnum(res[-1])))
cmd++;
//---------------------------------------------------------------------
*res++ = (cmd[-1] == '\'') ? *cmd :
u8(tolower(*cmd));
cmd++;
}
//-------------------------------------------------------------------------
if (res[-1] == ' ')
res[-1] = 0;
//-------------------------------------------------------------------------
*res = 0;
//-------------------------------------------------------------------------
// replace 0x01 to space again
for (res = a_command; *res; res++)
if (!(*res-1))
*res = ' ';
//-------------------------------------------------------------------------
unsigned r;
z80p = 0; if ((r = assemble( addr))) goto inspref1;
z80p = 0xDD; if ((r = assemble( addr))) goto inspref1;
z80p = 0xFD; if ((r = assemble( addr))) goto inspref1;
return 0;
//-------------------------------------------------------------------------
inspref1:
unsigned char *p = asmresult;
//-------------------------------------------------------------------------
if (z80p)
*p++ = z80p;
//-------------------------------------------------------------------------
for (unsigned i=0; i < r; i++)
*p++ = cmdb[i];
//-------------------------------------------------------------------------
return r + (z80p ? 1 :
0 );
}
//=============================================================================