AltairZ80: Added symbolic assembler for M68K CPU including bison/yacc source.
This commit is contained in:
parent
345b87034a
commit
02fc4b0e3c
6 changed files with 4460 additions and 11 deletions
|
@ -76,6 +76,7 @@ extern DEVICE wdi2_dev;
|
|||
extern DEVICE scp300f_dev;
|
||||
|
||||
extern long disasm (unsigned char *data, char *output, int segsize, long offset);
|
||||
extern t_stat parse_sym_m68k(char* c, t_addr a, UNIT* u, t_value* val, int32 sw);
|
||||
|
||||
void prepareMemoryAccessMessage(const t_addr loc);
|
||||
void prepareInstructionMessage(const t_addr loc, const uint32 op);
|
||||
|
@ -788,7 +789,6 @@ static int32 parse_X80(const char *cptr, const int32 addr, uint32 *val, const ch
|
|||
*/
|
||||
t_stat parse_sym(CONST char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32 sw) {
|
||||
static t_bool symbolicInputNotImplementedMessage8086 = FALSE;
|
||||
static t_bool symbolicInputNotImplementedMessageM68K = FALSE;
|
||||
if ((sw & (SWMASK('M'))) && (chiptype == CHIP_TYPE_8086)) {
|
||||
if (!symbolicInputNotImplementedMessage8086) {
|
||||
sim_printf("Symbolic input is not supported for the 8086.\n");
|
||||
|
@ -796,13 +796,6 @@ t_stat parse_sym(CONST char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32
|
|||
}
|
||||
return SCPE_NOFNC;
|
||||
}
|
||||
if ((sw & (SWMASK('M'))) && (chiptype == CHIP_TYPE_M68K)) {
|
||||
if (!symbolicInputNotImplementedMessageM68K) {
|
||||
sim_printf("Symbolic input is not supported for the M68K.\n");
|
||||
symbolicInputNotImplementedMessageM68K = TRUE;
|
||||
}
|
||||
return SCPE_NOFNC;
|
||||
}
|
||||
while (isspace(*cptr))
|
||||
cptr++; /* absorb spaces */
|
||||
if ((sw & (SWMASK('A') | SWMASK('C'))) || ((*cptr == '\'') && cptr++)) { /* ASCII char? */
|
||||
|
@ -811,7 +804,8 @@ t_stat parse_sym(CONST char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32
|
|||
val[0] = (uint32) cptr[0];
|
||||
return SCPE_OK;
|
||||
}
|
||||
return parse_X80(cptr, addr, val, chiptype == CHIP_TYPE_Z80 ? MnemonicsZ80 : Mnemonics8080);
|
||||
return (chiptype == CHIP_TYPE_M68K ? parse_sym_m68k((char *)cptr, addr, uptr, val, sw) :
|
||||
parse_X80(cptr, addr, val, chiptype == CHIP_TYPE_Z80 ? MnemonicsZ80 : Mnemonics8080));
|
||||
}
|
||||
|
||||
/* Set Memory Base Address routine */
|
||||
|
|
3785
AltairZ80/m68kasm.c
Normal file
3785
AltairZ80/m68kasm.c
Normal file
File diff suppressed because it is too large
Load diff
666
AltairZ80/m68kasm.y.txt
Normal file
666
AltairZ80/m68kasm.y.txt
Normal file
|
@ -0,0 +1,666 @@
|
|||
%{
|
||||
/* m68k_parse.c: line assembler for generic m68k_cpu
|
||||
|
||||
Copyright (c) 2009-2010, Holger Veit
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
HOLGER VEIT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of Holger Veit et al shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Holger Veit et al.
|
||||
|
||||
04-Oct-09 HV Initial version
|
||||
20-Sep-14 PS Adapted for AltairZ80
|
||||
|
||||
use "bison m68kasm.y -o m68kasm.c" to create m68kasm.c
|
||||
*/
|
||||
|
||||
#include "sim_defs.h"
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
struct _ea {
|
||||
int ea;
|
||||
int cnt;
|
||||
t_value arg[10];
|
||||
};
|
||||
struct _rea {
|
||||
int reg;
|
||||
struct _ea ea;
|
||||
};
|
||||
struct _mask {
|
||||
int x;
|
||||
int d;
|
||||
};
|
||||
struct _brop {
|
||||
int opc;
|
||||
int len;
|
||||
};
|
||||
|
||||
static int oplen;
|
||||
const static int movemx[] = { 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
|
||||
0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080 };
|
||||
const static int movemd[] = { 0x0080, 0x0040, 0x0020, 0x0010, 0x0008, 0x0004, 0x0002, 0x0001,
|
||||
0x8000, 0x4000, 0x2000, 0x1000, 0x0800, 0x0400, 0x0200, 0x0100 };
|
||||
static int yyrc;
|
||||
static int yyerrc;
|
||||
static int yylex(void);
|
||||
static int _genop(t_value arg);
|
||||
static int _genea(struct _ea arg);
|
||||
static int _genbr(t_value arg,t_value,int);
|
||||
static void yyerror(char* s);
|
||||
|
||||
#define YYDEBUG 1
|
||||
%}
|
||||
|
||||
%union {
|
||||
int rc;
|
||||
int reg;
|
||||
int wl;
|
||||
int opc;
|
||||
struct _ea ea;
|
||||
t_value num;
|
||||
struct _rea rea;
|
||||
struct _mask mask;
|
||||
struct _brop brop;
|
||||
}
|
||||
|
||||
%token A0 A1 A2 A3 A4 A5 A6 A7 D0 D1 D2 D3 D4 D5 D6 D7
|
||||
%token CCR SR USP PC
|
||||
%token <num> NUMBER
|
||||
%token ABCD ADD ADDA ADDI ADDQ ADDX AND ANDI OR ORI SBCD SUB SUBA SUBI SUBQ SUBX
|
||||
%token ASL ASR LSL LSR ROL ROR ROXL ROXR
|
||||
%token BCC BCS BEQ BGE BGT BHI BLE BLS BLT BMI BNE BPL BVC BVS BSR BRA
|
||||
%token BCLR BSET BCHG BTST CHK CMP CMPA CMPI CMPM EOR EORI EXG EXT
|
||||
%token DIVU DIVS MULU MULS
|
||||
%token DBCC DBCS DBEQ DBF DBGE DBGT DBHI DBLE DBLS DBLT DBMI DBNE DBPL DBT DBVC DBVS
|
||||
%token SCC SCS SEQ SF SGE SGT SHI SLE SLS SLT SMI SNE SPL ST SVC SVS
|
||||
%token ILLEGAL NOP RESET RTE RTR RTS TRAPV
|
||||
%token JMP JSR LEA LINK MOVE MOVEA MOVEM MOVEP MOVEQ
|
||||
%token CLR NEG NEGX NBCD NOT PEA STOP TAS SWAP TRAP TST UNLK
|
||||
|
||||
%token PREDEC POSTINC BSIZE WSIZE LSIZE SSIZE
|
||||
|
||||
%start stmt
|
||||
%type <opc> bcdop bcdarg dualop immop qop immop2 shftarg monop btop
|
||||
%type <opc> mdop dbop jop arop
|
||||
%type <opc> direct
|
||||
%type <brop> brop
|
||||
%type <rea> dualarg shftop
|
||||
%type <reg> dreg areg
|
||||
%type <ea> ea0 ea1 ea2 ea3 ea4 ea5 ea6 ea70 ea72 ea73 ea74 eama eaa eaall eada eadas easr ead eac eacad eacai
|
||||
%type <wl> szwl szbwl szmv szm szs
|
||||
%type <mask> regs reglist
|
||||
|
||||
%%
|
||||
stmt:
|
||||
bcdop bcdarg { _genop($1 | $2); yyrc = -1; }
|
||||
| dualop dualarg { _genop($1 | $2.reg | $2.ea.ea); yyrc = _genea($2.ea) -1; }
|
||||
| immop '#' NUMBER ',' eada { _genop($1 | $5.ea); if (oplen==0) { _genop($3 & 0xff); yyrc = _genea($5) - 3; }
|
||||
else if (oplen==1) { _genop($3); yyrc = _genea($5) - 3; } else { _genop($3>>16); _genop($3 & 0xffff); yyrc = _genea($5)-5; } }
|
||||
| qop '#' NUMBER ',' eaa { _genop($1 | (($3&7)<<9) | $5.ea); yyrc = _genea($5) - 1; }
|
||||
| immop2 '#' NUMBER ',' eadas { _genop($1 | $5.ea); if (oplen==0) { _genop($3 & 0xff); yyrc = _genea($5) - 3; }
|
||||
else if (oplen==1) { _genop($3); yyrc = _genea($5) - 3; } else { _genop($3>>16); _genop($3 & 0xffff); yyrc = _genea($5)-5; } }
|
||||
| shftop { _genop($1.reg); if (($1.reg&0xc0)==0xc0) yyrc = _genea($1.ea) - 1; else { yyrc = -1; } }
|
||||
| brop NUMBER { yyrc = _genbr($1.opc,$2,$1.len); }
|
||||
| btop dreg ',' eada { _genop($1 | ($2<<9) | 0x100 | $4.ea); yyrc = _genea($4) - 1; }
|
||||
| btop '#' NUMBER ',' eada { _genop($1 | 0x0800 | $5.ea); _genop($3); yyrc = _genea($5) - 3; }
|
||||
| CHK ead ',' dreg { _genop(0x4180 | ($4<<9) | $2.ea); yyrc = _genea($2) - 1; }
|
||||
| monop eada { _genop($1 | $2.ea); yyrc = _genea($2) - 1; }
|
||||
| CMP szbwl eaall ',' dreg { _genop(0xb000 | ($2<<6) | ($5<<9) | $3.ea); yyrc = _genea($3) - 1; }
|
||||
| mdop ead ',' dreg { _genop($1 | ($4<<9) | $2.ea); yyrc = _genea($2) - 1; }
|
||||
| CMPA szwl eaall ',' areg { _genop(0xb0c0 | ($2<<8) | ($5<<9) | $3.ea); yyrc = _genea($3) - 1; }
|
||||
| CMPM szbwl ea3 ',' ea3 { _genop(0xb108 | ($5.ea<<9) | ($2<<6) | $3.ea); yyrc = -1; }
|
||||
| dbop dreg ',' NUMBER { yyrc = _genbr($1 | $2, $4, 1); }
|
||||
| EOR szbwl dreg ',' eada { _genop(0xb000 | ($2 << 6) | 0x100 | $5.ea); yyrc = _genea($5) - 1; }
|
||||
| EXG dreg ',' dreg { _genop(0xc140 | ($2<<9) | $4); yyrc = -1; }
|
||||
| EXG areg ',' areg { _genop(0xc148 | ($2<<9) | $4); yyrc = -1; }
|
||||
| EXG areg ',' dreg { _genop(0xc188 | ($4<<9) | $2); yyrc = -1; }
|
||||
| EXG dreg ',' areg { _genop(0xc188 | ($2<<9) | $4); yyrc = -1; }
|
||||
| EXT szwl dreg { _genop(0x4840 | ($2<<6) | $3); yyrc = -1; }
|
||||
| direct { _genop($1); yyrc = -1; }
|
||||
| jop eac { _genop($1 | $2.ea); yyrc = _genea($2) -1; }
|
||||
| LEA eac ',' areg { _genop(0x41c0 | $2.ea); yyrc = _genea($2) - 1; }
|
||||
| LINK areg ',' '#' NUMBER { _genop(0x4e50 | $2); _genop($5); yyrc = -3; }
|
||||
| MOVE szmv eaall ',' eadas { if ($5.ea==074) { _genop(0x44c0 | ($5.cnt==1?0x0200:0x0000) | $3.ea); yyrc = _genea($3) - 1; }
|
||||
else { int tmp = (($5.ea&070)>>3)|(($5.ea&7)<<3); _genop(0x0000 | ($2<<12) | (tmp<<6) | $3.ea);
|
||||
yyrc = _genea($3) - 1; yyrc += _genea($5); } }
|
||||
| MOVE SR ',' eada { _genop(0x40c0 | $4.ea); yyrc = _genea($4) - 1; }
|
||||
| MOVE USP ',' areg { _genop(0x4e68 | $4); yyrc = -1; }
|
||||
| MOVE areg ',' USP { _genop(0x4e60 | $2); yyrc = -1; }
|
||||
| MOVEA szm eada ',' areg { _genop(0x0040 | ($2<<12) | ($5<<9) | $3.ea); yyrc = _genea($3) - 1; }
|
||||
| MOVEM szwl reglist ',' eacad { _genop(0x4880 | ($2<<6) | $5.ea); _genop(($5.ea&070)==040 ? $3.d : $3.x); yyrc = _genea($5) - 3; }
|
||||
| MOVEM szwl eacai ',' reglist { _genop(0x4c80 | ($2<<6) | $3.ea); _genop($5.x); yyrc = _genea($3) - 3; }
|
||||
| MOVEP szwl dreg ',' ea5 { _genop(0x0108 | ($3<<9) | ($2<<6) | ($5.ea & 7)); yyrc = _genea($5) - 1; }
|
||||
| MOVEP szwl ea5 ',' dreg { _genop(0x0188 | ($5<<9) | ($2<<6) | ($3.ea & 7)); yyrc = _genea($3) - 1; }
|
||||
| MOVEQ '#' NUMBER ',' dreg { _genop(0x7000 | ($5<<9) | ($3&0xff)); yyrc = -1; }
|
||||
| STOP '#' NUMBER { _genop(0x4e72); yyrc = _genop($3&0xffff) - 1; }
|
||||
| arop szwl eaall ',' areg { _genop($1 | ($5<<9) | ($2<<8) | $3.ea); yyrc = _genea($3) - 1; }
|
||||
| SWAP dreg { _genop(0x4840 | $2); yyrc = -1; }
|
||||
| TRAP '#' NUMBER { _genop(0x4e40 | ($3 & 0x0f)); yyrc = -1; }
|
||||
| UNLK areg { _genop(0x4e58 | $2); yyrc = -1; }
|
||||
;
|
||||
|
||||
arop:
|
||||
ADDA { $$ = 0xd0c0; }
|
||||
| SUBA { $$ = 0x90c0; };
|
||||
|
||||
bcdop:
|
||||
ABCD { $$ = 0xc100; }
|
||||
| ADDX szbwl { $$ = 0xd100 | ($2<<6); }
|
||||
| SBCD { $$ = 0x8100; }
|
||||
| SUBX szbwl { $$ = 0x9100 | ($2<<6); }
|
||||
;
|
||||
|
||||
dualop:
|
||||
ADD szbwl { $$ = 0xd000 | ($2<<6); }
|
||||
| AND szbwl { $$ = 0xc000 | ($2<<6); }
|
||||
| OR szbwl { $$ = 0x8000 | ($2<<6); }
|
||||
| SUB szbwl { $$ = 0x9000 | ($2<<6); }
|
||||
;
|
||||
|
||||
immop:
|
||||
ADDI szbwl { $$ = 0x0600 | ($2<<6); }
|
||||
| CMPI szbwl { $$ = 0x0c00 | ($2<<6); }
|
||||
| SUBI szbwl { $$ = 0x0400 | ($2<<6); }
|
||||
;
|
||||
|
||||
immop2:
|
||||
ANDI szbwl { $$ = 0x0200 | ($2<<6); }
|
||||
| EORI szbwl { $$ = 0x0a00 | ($2<<6); }
|
||||
| ORI szbwl { $$ = 0x0000 | ($2<<6); }
|
||||
;
|
||||
|
||||
qop:
|
||||
ADDQ szbwl { $$ = 0x5000 | ($2<<6); }
|
||||
| SUBQ szbwl { $$ = 0x5100 | ($2<<6); }
|
||||
;
|
||||
|
||||
shftop:
|
||||
ASL eama { $$.reg = 0xe1c0 | $2.ea; $$.ea = $2; }
|
||||
| ASL szbwl shftarg { $$.reg = 0xe100 | ($2<<6) | $3; }
|
||||
| ASR eama { $$.reg = 0xe0c0 | $2.ea; $$.ea = $2; }
|
||||
| ASR szbwl shftarg { $$.reg = 0xe000 | ($2<<6) | $3; }
|
||||
| LSL eama { $$.reg = 0xe3c0 | $2.ea; $$.ea = $2; }
|
||||
| LSL szbwl shftarg { $$.reg = 0xe108 | ($2<<6) | $3; }
|
||||
| LSR eama { $$.reg = 0xe2c0 | $2.ea; $$.ea = $2; }
|
||||
| LSR szbwl shftarg { $$.reg = 0xe008 | ($2<<6) | $3; }
|
||||
| ROL eama { $$.reg = 0xe7c0 | $2.ea; $$.ea = $2; }
|
||||
| ROL szbwl shftarg { $$.reg = 0xe118 | ($2<<6) | $3; }
|
||||
| ROR eama { $$.reg = 0xe6c0 | $2.ea; $$.ea = $2; }
|
||||
| ROR szbwl shftarg { $$.reg = 0xe018 | ($2<<6) | $3; }
|
||||
| ROXL eama { $$.reg = 0xe5c0 | $2.ea; $$.ea = $2; }
|
||||
| ROXL szbwl shftarg { $$.reg = 0xe100 | ($2<<6) | $3; }
|
||||
| ROXR eama { $$.reg = 0xe4c0 | $2.ea; $$.ea = $2; }
|
||||
| ROXR szbwl shftarg { $$.reg = 0xe000 | ($2<<6) | $3; }
|
||||
;
|
||||
|
||||
brop:
|
||||
BCC { $$.opc = 0x6400; $$.len = 1; }
|
||||
| BCS { $$.opc = 0x6500; $$.len = 1; }
|
||||
| BEQ { $$.opc = 0x6700; $$.len = 1; }
|
||||
| BGE { $$.opc = 0x6c00; $$.len = 1; }
|
||||
| BGT { $$.opc = 0x6e00; $$.len = 1; }
|
||||
| BHI { $$.opc = 0x6200; $$.len = 1; }
|
||||
| BLE { $$.opc = 0x6f00; $$.len = 1; }
|
||||
| BLS { $$.opc = 0x6300; $$.len = 1; }
|
||||
| BLT { $$.opc = 0x6d00; $$.len = 1; }
|
||||
| BMI { $$.opc = 0x6b00; $$.len = 1; }
|
||||
| BNE { $$.opc = 0x6600; $$.len = 1; }
|
||||
| BPL { $$.opc = 0x6a00; $$.len = 1; }
|
||||
| BVC { $$.opc = 0x6800; $$.len = 1; }
|
||||
| BVS { $$.opc = 0x6900; $$.len = 1; }
|
||||
| BSR { $$.opc = 0x6100; $$.len = 1; }
|
||||
| BRA { $$.opc = 0x6000; $$.len = 1; }
|
||||
| BCC szs { $$.opc = 0x6400; $$.len = 0; }
|
||||
| BCS szs { $$.opc = 0x6500; $$.len = 0; }
|
||||
| BEQ szs { $$.opc = 0x6700; $$.len = 0; }
|
||||
| BGE szs { $$.opc = 0x6c00; $$.len = 0; }
|
||||
| BGT szs { $$.opc = 0x6e00; $$.len = 0; }
|
||||
| BHI szs { $$.opc = 0x6200; $$.len = 0; }
|
||||
| BLE szs { $$.opc = 0x6f00; $$.len = 0; }
|
||||
| BLS szs { $$.opc = 0x6300; $$.len = 0; }
|
||||
| BLT szs { $$.opc = 0x6d00; $$.len = 0; }
|
||||
| BMI szs { $$.opc = 0x6b00; $$.len = 0; }
|
||||
| BNE szs { $$.opc = 0x6600; $$.len = 0; }
|
||||
| BPL szs { $$.opc = 0x6a00; $$.len = 0; }
|
||||
| BVC szs { $$.opc = 0x6800; $$.len = 0; }
|
||||
| BVS szs { $$.opc = 0x6900; $$.len = 0; }
|
||||
| BSR szs { $$.opc = 0x6100; $$.len = 0; }
|
||||
| BRA szs { $$.opc = 0x6000; $$.len = 0; }
|
||||
;
|
||||
|
||||
btop:
|
||||
BCHG { $$ = 0x0040; }
|
||||
| BCLR { $$ = 0x0080; }
|
||||
| BSET { $$ = 0x00c0; }
|
||||
| BTST { $$ = 0x0000; }
|
||||
;
|
||||
|
||||
monop:
|
||||
CLR szbwl { $$ = 0x4200 | ($2<<6); }
|
||||
| NBCD { $$ = 0x4800; }
|
||||
| NEG szbwl { $$ = 0x4400 | ($2<<6); }
|
||||
| NEGX szbwl { $$ = 0x4000 | ($2<<6); }
|
||||
| NOT szbwl { $$ = 0x4600 | ($2<<6); }
|
||||
| SCC { $$ = 0x54c0; }
|
||||
| SCS { $$ = 0x55c0; }
|
||||
| SEQ { $$ = 0x57c0; }
|
||||
| SF { $$ = 0x51c0; }
|
||||
| SGE { $$ = 0x5cc0; }
|
||||
| SGT { $$ = 0x5ec0; }
|
||||
| SHI { $$ = 0x52c0; }
|
||||
| SLE { $$ = 0x5fc0; }
|
||||
| SLS { $$ = 0x53c0; }
|
||||
| SLT { $$ = 0x5dc0; }
|
||||
| SMI { $$ = 0x5bc0; }
|
||||
| SNE { $$ = 0x56c0; }
|
||||
| SPL { $$ = 0x5ac0; }
|
||||
| ST { $$ = 0x50c0; }
|
||||
| SVC { $$ = 0x58c0; }
|
||||
| SVS { $$ = 0x59c0; }
|
||||
| TAS { $$ = 0x4ac0; }
|
||||
| TST szbwl { $$ = 0x4a00 | ($2<<6); }
|
||||
;
|
||||
|
||||
mdop:
|
||||
DIVS { $$ = 0x81c0; }
|
||||
| DIVU { $$ = 0x80c0; }
|
||||
| MULS { $$ = 0xc1c0; }
|
||||
| MULU { $$ = 0xc0c0; }
|
||||
;
|
||||
|
||||
dbop:
|
||||
DBCC { $$ = 0x54c8; }
|
||||
| DBCS { $$ = 0x55c8; }
|
||||
| DBEQ { $$ = 0x57c8; }
|
||||
| DBGE { $$ = 0x5cc8; }
|
||||
| DBGT { $$ = 0x5ec8; }
|
||||
| DBHI { $$ = 0x52c8; }
|
||||
| DBLE { $$ = 0x5fc8; }
|
||||
| DBLS { $$ = 0x53c8; }
|
||||
| DBLT { $$ = 0x5dc8; }
|
||||
| DBMI { $$ = 0x5bc8; }
|
||||
| DBNE { $$ = 0x56c8; }
|
||||
| DBPL { $$ = 0x5ac8; }
|
||||
| DBVC { $$ = 0x58c8; }
|
||||
| DBVS { $$ = 0x59c8; }
|
||||
| DBF { $$ = 0x51c8; }
|
||||
| DBT { $$ = 0x50c8; }
|
||||
;
|
||||
|
||||
direct:
|
||||
ILLEGAL { $$ = 0x4afc; }
|
||||
| NOP { $$ = 0x4e71; }
|
||||
| RESET { $$ = 0x4e70; }
|
||||
| RTE { $$ = 0x4e73; }
|
||||
| RTR { $$ = 0x4e77; }
|
||||
| RTS { $$ = 0x4e75; }
|
||||
| TRAPV { $$ = 0x4e76; }
|
||||
;
|
||||
|
||||
jop:
|
||||
JMP { $$ = 0x4ec0; }
|
||||
| JSR { $$ = 0x4e80; }
|
||||
| PEA { $$ = 0x4840; };
|
||||
|
||||
shftarg:
|
||||
dreg ',' dreg { $$ = ($1<<9) | 0x20 | $3; }
|
||||
| '#' NUMBER ',' dreg { $$ = (($2 & 7)<<9) | $4; };
|
||||
|
||||
bcdarg:
|
||||
ea0 ',' ea0 { $$ = (($1.ea & 7) << 9) | ($3.ea & 7); }
|
||||
| ea4 ',' ea4 { $$ = (($1.ea & 7) << 9) | 0x0008 | ($3.ea & 7); };
|
||||
|
||||
dualarg:
|
||||
dreg ',' eaa { if (($3.ea & 070)==0) { /* dx,dy must be swapped */
|
||||
$$.reg = ($3.ea & 7)<<9; $3.ea = $1 & 7; $$.ea = $3; }
|
||||
else { $$.reg = ($1<<9) | 0x100; $$.ea = $3; } }
|
||||
| eama ',' dreg { $$.reg = ($3<<9); $$.ea = $1; };
|
||||
|
||||
areg:
|
||||
A0 { $$=0; }
|
||||
| A1 { $$=1; }
|
||||
| A2 { $$=2; }
|
||||
| A3 { $$=3; }
|
||||
| A4 { $$=4; }
|
||||
| A5 { $$=5; }
|
||||
| A6 { $$=6; }
|
||||
| A7 { $$=7; };
|
||||
|
||||
dreg:
|
||||
D0 { $$=0; }
|
||||
| D1 { $$=1; }
|
||||
| D2 { $$=2; }
|
||||
| D3 { $$=3; }
|
||||
| D4 { $$=4; }
|
||||
| D5 { $$=5; }
|
||||
| D6 { $$=6; }
|
||||
| D7 { $$=7; };
|
||||
|
||||
szs:
|
||||
SSIZE { $$ = 1; oplen = 0; }
|
||||
|
||||
szwl:
|
||||
WSIZE { $$ = 0; oplen = 1; }
|
||||
| LSIZE { $$ = 1; oplen = 2; };
|
||||
|
||||
szbwl:
|
||||
BSIZE { $$ = 0; oplen = 0; }
|
||||
| WSIZE { $$ = 1; oplen = 1; }
|
||||
| LSIZE { $$ = 2; oplen = 2; };
|
||||
|
||||
szmv:
|
||||
BSIZE { $$ = 1; oplen = 0; }
|
||||
| WSIZE { $$ = 3; oplen = 1; }
|
||||
| LSIZE { $$ = 2; oplen = 2; };
|
||||
|
||||
szm:
|
||||
WSIZE { $$ = 3; oplen = 1; }
|
||||
| LSIZE { $$ = 2; oplen = 2; };
|
||||
|
||||
reglist:
|
||||
regs { $$ = $1; }
|
||||
| regs '/' reglist { $$.x = $1.x | $3.x; $$.d = $1.d | $3.d; };
|
||||
|
||||
regs:
|
||||
areg { $$.x = movemx[$1]; $$.d = movemd[$1]; }
|
||||
| dreg { $$.x = movemx[$1+8]; $$.d = movemd[$1+8]; }
|
||||
| areg '-' areg { int i,l=$1,h=$3; if (l>h) { l=$3; h=$1; } $$.x = $$.d = 0;
|
||||
for (i=l; i<=h; i++) { $$.d |= movemx[i]; $$.d |= movemd[i]; } }
|
||||
| dreg '-' dreg { int i,l=$1,h=$3; if (l>h) { l=$3; h=$1; } $$.x = $$.d = 0;
|
||||
for (i=l; i<=h; i++) { $$.x |= movemx[i+8]; $$.d |= movemd[i+8]; } }
|
||||
;
|
||||
|
||||
eama: ea1 | ea2 | ea3 | ea4 | ea5 | ea6 | ea70 | ea72 | ea73 | ea74;
|
||||
eaa: ea0 | ea1 | ea2 | ea3 | ea4 | ea5 | ea6 | ea70;
|
||||
ead: ea0 | ea2 | ea3 | ea4 | ea5 | ea6 | ea70 | ea72 | ea73 | ea74;
|
||||
eaall: ea0 | eama;
|
||||
eada: ea0 | ea2 | ea3 | ea4 | ea5 | ea6 | ea70;
|
||||
eadas: eada | easr;
|
||||
eac: ea2 | ea5 | ea6 | ea70 | ea72 | ea73;
|
||||
eacai: ea2 | ea3 | ea5 | ea6 | ea70;
|
||||
eacad: ea2 | ea4 | ea5 | ea6 | ea70;
|
||||
|
||||
ea0:
|
||||
dreg { $$.ea = $1; $$.cnt = 0; };
|
||||
ea1:
|
||||
areg { $$.ea = 010 | $1; $$.cnt = 0; };
|
||||
ea2:
|
||||
'(' areg ')' { $$.ea = 020 | $2; $$.cnt = 0; };
|
||||
ea3:
|
||||
'(' areg POSTINC { $$.ea = 030 | $2; $$.cnt = 0; };
|
||||
ea4:
|
||||
PREDEC areg ')' { $$.ea = 040 | $2; $$.cnt = 0; };
|
||||
ea5:
|
||||
'(' NUMBER ',' areg ')' { $$.ea = 050 | $4; $$.cnt = 1; $$.arg[0] = $2; };
|
||||
ea6:
|
||||
'(' NUMBER ',' areg ',' dreg szwl ')'
|
||||
{ $$.ea = 060 | $4; $$.cnt = 1; $$.arg[0] = 0x8000 | ($6<<12) | ($7<<11) | ($2 & 0xff); }
|
||||
| '(' NUMBER ',' areg ',' areg szwl ')'
|
||||
{ $$.ea = 060 | $4; $$.cnt = 1; $$.arg[0] = ($6<<12) | ($7<<11) | ($2 & 0xff); };
|
||||
ea70:
|
||||
'(' NUMBER ')' szwl { if ($4==0) { $$.ea = 070; $$.cnt = 1; $$.arg[0] = $2; }
|
||||
else { $$.ea = 071; $$.cnt = 2; $$.arg[0] = $2 >> 16; $$.arg[1] = $2 & 0xffff; } }
|
||||
| '(' NUMBER ')' { int tmp = ($2>>15) & 0x1ffff; if (tmp==0 || tmp==0x1ffff) { $$.ea = 070; $$.cnt = 1; $$.arg[0] = $2; }
|
||||
else { $$.ea = 070; $$.cnt = 2; $$.arg[0] = $2 >> 16; $$.arg[1] = $2 & 0xffff; } };
|
||||
ea72:
|
||||
'(' NUMBER ',' PC ')' { $$.ea = 072; $$.cnt = 1; $$.arg[0] = $2; }
|
||||
| NUMBER { $$.ea = 072; $$.cnt = 1; $$.arg[0] = $1; };
|
||||
ea73:
|
||||
'(' NUMBER ',' PC ',' dreg szwl ')'
|
||||
{ $$.ea = 073; $$.cnt = 1; $$.arg[0] = 0x8000 | ($6<<12) | ($7<<11) | ($2 & 0xff); }
|
||||
| '(' NUMBER ',' PC ',' areg szwl ')'
|
||||
{ $$.ea = 073; $$.cnt = 1; $$.arg[0] = ($6<<12) | ($7<<11) | ($2 & 0xff); };
|
||||
ea74:
|
||||
'#' NUMBER { $$.ea = 074; if (oplen==0) { $$.cnt = 1; $$.arg[0] = $2 & 0xff; }
|
||||
else if (oplen==1) { $$.cnt = 1; $$.arg[0] = $2 & 0xffff; }
|
||||
else { $$.cnt = 2; $$.arg[0] = $2 >> 16; $$.arg[1] = $2 & 0xffff; } };
|
||||
easr:
|
||||
CCR { $$.ea = 074; $$.cnt = 0; }
|
||||
| SR { $$.ea = 074; $$.cnt = 1; };
|
||||
%%
|
||||
|
||||
static void yyerror(char* s)
|
||||
{
|
||||
/* do not emit anything, but set error flag */
|
||||
yyerrc = 1;
|
||||
}
|
||||
|
||||
struct _optable {
|
||||
char* mnem;
|
||||
int token;
|
||||
};
|
||||
|
||||
static struct _optable ops[] = {
|
||||
{ "abcd", ABCD }, { "add", ADD }, { "adda", ADDA }, { "addi", ADDI },
|
||||
{ "addq", ADDQ }, { "addx", ADDX }, { "and", AND }, { "andi", ANDI },
|
||||
{ "asl", ASL }, { "asr", ASR }, { "bcc", BCC }, { "bcs", BCS },
|
||||
{ "beq", BEQ }, { "bge", BGE }, { "bgt", BGT }, { "bhi", BHI },
|
||||
{ "ble", BLE }, { "bls", BLS }, { "blt", BLT }, { "bmi", BMI },
|
||||
{ "bne", BNE }, { "bpl", BPL }, { "bvc", BVC }, { "bvs", BVS },
|
||||
{ "bchg", BCHG }, { "bclr", BCLR }, { "bra", BRA }, { "bset", BSET },
|
||||
{ "bsr", BSR }, { "btst", BTST }, { "chk", CHK }, { "clr", CLR },
|
||||
{ "cmp", CMP }, { "cmpa", CMPA }, { "cmpi", CMPI }, { "cmpm", CMPM },
|
||||
{ "dbcc", DBCC }, { "dbcs", DBCS }, { "dbeq", DBEQ }, { "dbf", DBF },
|
||||
{ "dbge", DBGE }, { "dbgt", DBGT }, { "dbhi", DBHI }, { "dble", DBLE },
|
||||
{ "dbls", DBLS }, { "dblt", DBLT }, { "dbmi", DBMI }, { "dbne", DBNE },
|
||||
{ "dbpl", DBPL }, { "dbt", DBT }, { "dbvc", DBVC }, { "dbvs", DBVS },
|
||||
{ "divs", DIVS }, { "divu", DIVU }, { "eor", EOR }, { "eori", EORI },
|
||||
{ "exg", EXG }, { "ext", EXT }, { "illegal",ILLEGAL }, { "jmp", JMP },
|
||||
{ "jsr", JSR }, { "lea", LEA }, { "link", LINK }, { "lsl", LSL },
|
||||
{ "lsr", LSR }, { "move", MOVE }, { "movea", MOVEA }, { "movem", MOVEM },
|
||||
{ "movep", MOVEP }, { "moveq", MOVEQ }, { "muls", MULS }, { "mulu", MULU },
|
||||
{ "nbcd", NBCD }, { "neg", NEG }, { "negx", NEGX }, { "nop", NOP },
|
||||
{ "not", NOT }, { "or", OR }, { "ori", ORI }, { "pea", PEA },
|
||||
{ "reset", RESET }, { "rol", ROL }, { "ror", ROR }, { "roxl", ROXL },
|
||||
{ "roxr", ROXR }, { "rte", RTE }, { "rtr", RTR },
|
||||
{ "rts", RTS }, { "scc", SCC }, { "scs", SCS }, { "seq", SEQ },
|
||||
{ "sf", SF }, { "sge", SGE }, { "sgt", SGT }, { "shi", SHI },
|
||||
{ "sle", SLE }, { "sls", SLS }, { "slt", SLT }, { "smi", SMI },
|
||||
{ "sne", SNE }, { "spl", SPL }, { "st", ST }, { "svc", SVC },
|
||||
{ "svs", SVS }, { "stop", STOP }, { "sub", SUB }, { "suba", SUBA },
|
||||
{ "subi", SUBI }, { "subq", SUBQ }, { "subx", SUBX }, { "swap", SWAP },
|
||||
{ "tas", TAS }, { "trap", TRAP }, { "trapv", TRAPV }, { "tst", TST },
|
||||
{ "unlk", UNLK }, { "a0", A0 }, { "a1", A1 }, { "a2", A2 },
|
||||
{ "a3", A3 }, { "a4", A4 }, { "a5", A5 }, { "a6", A6 },
|
||||
{ "a7", A7 }, { "d0", D0 }, { "d1", D1 }, { "d2", D2 },
|
||||
{ "d3", D3 }, { "d4", D4 }, { "d5", D5 }, { "d6", D6 },
|
||||
{ "d7", D7 }, { "ccr", CCR }, { "sr", SR }, { "usp", USP },
|
||||
{ "pc", PC },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
typedef struct _ophash {
|
||||
struct _ophash* next;
|
||||
struct _optable* op;
|
||||
} OPHASH;
|
||||
#define OPHASHSIZE 97
|
||||
|
||||
static OPHASH **ophash = 0;
|
||||
|
||||
static int getophash(const char* s)
|
||||
{
|
||||
int h = 0;
|
||||
while (*s++) h += (int)*s;
|
||||
return h % OPHASHSIZE;
|
||||
}
|
||||
|
||||
static int oplookup(const char* s)
|
||||
{
|
||||
int idx = getophash(s);
|
||||
OPHASH* oph = ophash[idx];
|
||||
if (oph) {
|
||||
if (oph->next) {
|
||||
while (oph) {
|
||||
if (!strcmp(s,oph->op->mnem)) return oph->op->token;
|
||||
oph = oph->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return oph->op->token;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void init_ophash()
|
||||
{
|
||||
struct _optable* op = ops;
|
||||
OPHASH* oph;
|
||||
ophash = (OPHASH**)calloc(sizeof(OPHASH*),OPHASHSIZE);
|
||||
while (op->mnem) {
|
||||
int idx = getophash(op->mnem);
|
||||
oph = (OPHASH*)malloc(sizeof(OPHASH));
|
||||
oph->next = ophash[idx];
|
||||
oph->op = op;
|
||||
ophash[idx] = oph;
|
||||
op++;
|
||||
}
|
||||
}
|
||||
|
||||
static char* yystream;
|
||||
|
||||
static int yylex()
|
||||
{
|
||||
char ident[30];
|
||||
char *p = ident;
|
||||
char c = yystream[0];
|
||||
|
||||
while (c != 0 && (c=='\t' || c==' ')) {
|
||||
c = *++yystream;
|
||||
}
|
||||
if (c==0) return EOF;
|
||||
|
||||
if (isalpha(c)) {
|
||||
while (isalnum(c) && (p-ident)<28) {
|
||||
*p++ = tolower(c); c = *++yystream;
|
||||
}
|
||||
*p = 0;
|
||||
if (p>ident) { return oplookup(ident); }
|
||||
return EOF;
|
||||
} else if (isdigit(c)) {
|
||||
*p++ = c;
|
||||
if (yystream[1]=='x' || yystream[1]=='X') { *p++ = 'x'; yystream++; }
|
||||
c = *++yystream;
|
||||
while ((isdigit(c) || isxdigit(c)) && (p-ident)<28) {
|
||||
*p++ = c; c = *++yystream;
|
||||
}
|
||||
*p = 0;
|
||||
yylval.num = strtol(ident,0,0);
|
||||
return NUMBER;
|
||||
} else if (c=='$') {
|
||||
if (isdigit(yystream[1]) || isxdigit(yystream[1])) {
|
||||
c = *++yystream;
|
||||
while ((isdigit(c) || isxdigit(c)) && (p-ident)<28) {
|
||||
*p++ = c; c = *++yystream;
|
||||
}
|
||||
*p = 0;
|
||||
yylval.num = strtol(ident,0,16);
|
||||
return NUMBER;
|
||||
} else return '$';
|
||||
} else if (c == '-' && yystream[1] == '(') {
|
||||
yystream += 2; return PREDEC;
|
||||
} else if (c == ')' && yystream[1] == '+') {
|
||||
yystream += 2; return POSTINC;
|
||||
} else if (c == '.') {
|
||||
switch (yystream[1]) {
|
||||
case 'b': yystream += 2; return BSIZE;
|
||||
case 'w': yystream += 2; return WSIZE;
|
||||
case 'l': yystream += 2; return LSIZE;
|
||||
case 's': yystream += 2; return SSIZE;
|
||||
default: yystream++; return '.';
|
||||
}
|
||||
} else {
|
||||
++yystream; return c;
|
||||
}
|
||||
}
|
||||
|
||||
static t_value *yyvalptr;
|
||||
static t_addr yyaddr;
|
||||
|
||||
t_stat parse_sym_m68k(char* c, t_addr a, UNIT* u, t_value* val, int32 sw)
|
||||
{
|
||||
char ch;
|
||||
|
||||
if (!ophash) init_ophash();
|
||||
|
||||
yyvalptr = val;
|
||||
yyaddr = a;
|
||||
|
||||
yystream = c;
|
||||
yyerrc = 0;
|
||||
|
||||
ch = *yystream;
|
||||
while (ch != 0 && (ch=='\t' || ch==' ')) {
|
||||
ch = *++yystream;
|
||||
}
|
||||
if (ch == 0) return 0;
|
||||
|
||||
if (sw & SWMASK('Y')) yydebug = 1 - yydebug;
|
||||
if ((sw & SWMASK('A')) || ch=='\'') {
|
||||
if ((ch = yystream[1])) {
|
||||
val[0] = (uint32)ch;
|
||||
return SCPE_OK;
|
||||
} else return SCPE_ARG;
|
||||
}
|
||||
if ((sw & SWMASK('C')) || ch=='"') {
|
||||
if ((ch = yystream[1])) {
|
||||
val[0] = ((uint32)ch << 8) | (uint32)yystream[1];
|
||||
return SCPE_OK;
|
||||
} else return SCPE_ARG;
|
||||
}
|
||||
|
||||
yyparse();
|
||||
// sim_printf("rc=%d\n",yyrc);
|
||||
if (yyerrc) return SCPE_ARG;
|
||||
return yyrc;
|
||||
}
|
||||
|
||||
static int _genop(t_value arg)
|
||||
{
|
||||
// sim_printf("_genop(%x)@%x\n",arg,(int)yyvalptr);
|
||||
*yyvalptr = (arg >> 8) & 0xff;
|
||||
yyvalptr++;
|
||||
*yyvalptr = arg & 0xff;
|
||||
yyvalptr++;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int _genea(struct _ea arg)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<arg.cnt; i++) _genop(arg.arg[i]);
|
||||
return -(arg.cnt*2)-1;
|
||||
}
|
||||
|
||||
static int _genbr(t_value arg,t_addr tgt,int len)
|
||||
{
|
||||
t_addr a = tgt - yyaddr -2;
|
||||
if (len==1) {
|
||||
_genop(arg);
|
||||
_genop(a & 0xffff);
|
||||
a &= 0xffff8000;
|
||||
if (a != 0x00000000 && a != 0xffff8000) return SCPE_ARG;
|
||||
return -3;
|
||||
} else {
|
||||
_genop(arg | (a&0xff));
|
||||
a &= 0xffffff80;
|
||||
if (a != 0x00000000 && a != 0xffffff80) return SCPE_ARG;
|
||||
return -1;
|
||||
}
|
||||
}
|
|
@ -259,6 +259,10 @@
|
|||
RelativePath="..\AltairZ80\m68kdasm.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\AltairZ80\m68kasm.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\AltairZ80\m68kopac.c"
|
||||
>
|
||||
|
|
|
@ -366,7 +366,7 @@ ALTAIRZ80_SOURCE2 = $(ALTAIRZ80_DIR)S100_DISK1A.C,$(ALTAIRZ80_DIR)S100_DISK2.C,\
|
|||
$(ALTAIRZ80_DIR)WD179X.C,$(ALTAIRZ80_DIR)S100_DISK3.C,\
|
||||
$(ALTAIRZ80_DIR)S100_ADCS6.C,$(ALTAIRZ80_DIR)S100_HDC1001.C,\
|
||||
$(ALTAIRZ80_DIR)S100_IF3.C,$(ALTAIRZ80_DIR)ALTAIRZ80_MHDSK.C,\
|
||||
$(ALTAIRZ80_DIR)S100_TARBELL.C,\
|
||||
$(ALTAIRZ80_DIR)S100_TARBELL.C,$(ALTAIRZ80_DIR)M68KASM.C,\
|
||||
$(ALTAIRZ80_DIR)M68KCPU.C,$(ALTAIRZ80_DIR)M68KDASM.C,\
|
||||
$(ALTAIRZ80_DIR)M68KOPAC.C,$(ALTAIRZ80_DIR)M68KOPDM.C,\
|
||||
$(ALTAIRZ80_DIR)M68KOPNZ.C,$(ALTAIRZ80_DIR)M68KOPS.C,$(ALTAIRZ80_DIR)M68KSIM.C
|
||||
|
|
2
makefile
2
makefile
|
@ -1650,7 +1650,7 @@ ALTAIRZ80 = ${ALTAIRZ80D}/altairz80_cpu.c ${ALTAIRZ80D}/altairz80_cpu_nommu.c \
|
|||
${ALTAIRZ80D}/s100_tarbell.c \
|
||||
${ALTAIRZ80D}/wd179x.c ${ALTAIRZ80D}/s100_hdc1001.c \
|
||||
${ALTAIRZ80D}/s100_if3.c ${ALTAIRZ80D}/s100_adcs6.c \
|
||||
${ALTAIRZ80D}/m68kcpu.c ${ALTAIRZ80D}/m68kdasm.c \
|
||||
${ALTAIRZ80D}/m68kcpu.c ${ALTAIRZ80D}/m68kdasm.c ${ALTAIRZ80D}/m68kasm.c \
|
||||
${ALTAIRZ80D}/m68kopac.c ${ALTAIRZ80D}/m68kopdm.c \
|
||||
${ALTAIRZ80D}/m68kopnz.c ${ALTAIRZ80D}/m68kops.c ${ALTAIRZ80D}/m68ksim.c
|
||||
ALTAIRZ80_OPT = -I ${ALTAIRZ80D} -DUSE_SIM_IMD
|
||||
|
|
Loading…
Add table
Reference in a new issue