From cb23bca33af7378247a4c5bd71100b6c5e57bd97 Mon Sep 17 00:00:00 2001 From: Peter Schorn Date: Sat, 23 May 2020 19:06:21 +0200 Subject: [PATCH] AltairZ80: Update m68kasm.y.txt --- AltairZ80/m68kasm.y.txt | 1332 +++++++++++++++++++-------------------- 1 file changed, 666 insertions(+), 666 deletions(-) diff --git a/AltairZ80/m68kasm.y.txt b/AltairZ80/m68kasm.y.txt index 61047a15..570553b0 100644 --- a/AltairZ80/m68kasm.y.txt +++ b/AltairZ80/m68kasm.y.txt @@ -1,666 +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 -#include - -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 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 bcdop bcdarg dualop immop qop immop2 shftarg monop btop -%type mdop dbop jop arop -%type direct -%type brop -%type dualarg shftop -%type dreg areg -%type ea0 ea1 ea2 ea3 ea4 ea5 ea6 ea70 ea72 ea73 ea74 eama eaa eaall eada eadas easr ead eac eacad eacai -%type szwl szbwl szmv szm szs -%type 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 +#include + +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 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 bcdop bcdarg dualop immop qop immop2 shftarg monop btop +%type mdop dbop jop arop +%type direct +%type brop +%type dualarg shftop +%type dreg areg +%type ea0 ea1 ea2 ea3 ea4 ea5 ea6 ea70 ea72 ea73 ea74 eama eaa eaall eada eadas easr ead eac eacad eacai +%type szwl szbwl szmv szm szs +%type 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