From: ggn Date: Tue, 23 Jan 2018 12:07:23 +0000 (+0200) Subject: Various small fixes including: X-Git-Tag: v2.1.0~87 X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=rmac;a=commitdiff_plain;h=0951a3e28907fbaf89a10c5201b71d8080ffe5a8;ds=sidebyside Various small fixes including: - Corner case in ([bd,An/PC],Xn,od) addressing mode where bd is suppressed - 68060 specific instructions (68ktab, mach.c) - PMMU instruction fixes (68ktab, mach.c) - FMOVEM fixes (amode.c) - Switching CPU state fixes (direct.c) - Bitfield instruction fixes (mach.c) - pflush fixes (68ktab, mach.c) - Various warnings silenced (mark.c, riscasm.c) - Formatting ;) --- diff --git a/68ktab b/68ktab index 71c5f36..7f54cef 100644 --- a/68ktab +++ b/68ktab @@ -580,6 +580,8 @@ lea NL C_CTRL M_AREG %0100rrr111eR1000 m_lea link NWL M_AREG M_IMMED %0100111001010rrr m_link +lpstop NW M_IMMED M_AM_NONE %1111100000000000 m_lpstop + lsl NBWL M_DREG M_DREG %1110rrr1ss101rrr m_shr + - NBWL M_IMMED M_DREG %1110ccc1ss001rrr m_shi + - NBWL C_ALTMEM M_AM_NONE %1110001111eee000 m_ea + @@ -675,12 +677,14 @@ pdbcc NWL M_DREG C_LABEL %1111000001001ccc m_cpdbr pflush ! M_AM_NONE M_AM_NONE %1111000000eeeeee m_pflush pflushn ! M_AM_NONE M_AM_NONE %1111010100000111 m_pflush -pflushan N M_AM_NONE M_AM_NONE %1111010100010000 m_self +pflushan N M_AM_NONE M_AM_NONE %1111010100010000 m_pflushan pflusha N M_AM_NONE M_AM_NONE %1111000000000000 m_pflusha pflushr N C_ALL030 M_AM_NONE %1111000000eeeeee m_pflushr ploadr N M_FC C_PMOVE %1111000000eeeeee m_ploadr -ploadw N M_FC C_PMOVE %1111000000eeeeee m_ploadw +ploadw N M_FC C_PMOVE %1111000000eeeeee m_ploadw + +plpa N M_AIND M_AM_NONE %1111010110001rrr m_plpa pmove NWLD M_MRN C_PMOVE %1111000000eeeeee m_pmove + - NWLD C_PMOVE M_MRN %1111000000eeeeee m_pmove diff --git a/amode.c b/amode.c index fb10055..175fe73 100644 --- a/amode.c +++ b/amode.c @@ -324,8 +324,8 @@ int fpu_reglist_left(WORD * a_rmask) int fpu_reglist_right(WORD * a_rmask) { static WORD msktab_plus[] = { - 0x0001, 0x0002, 0x0004, 0x0008, - 0x0010, 0x0020, 0x0040, 0x0080 + 0x0080, 0x0040, 0x0020, 0x0010, + 0x0008, 0x0004, 0x0002, 0x0001 }; WORD rmask = 0; diff --git a/direct.c b/direct.c index 7447553..e507bc5 100644 --- a/direct.c +++ b/direct.c @@ -35,7 +35,6 @@ int largestAlign[3] = { 2, 2, 2 }; // Largest alignment value seen per section // Function prototypes int d_unimpl(void); int d_68000(void); -int d_68000(void); int d_68020(void); int d_68030(void); int d_68040(void); @@ -1536,29 +1535,29 @@ int d_68060(void) { d_68000(); activecpu = CPU_68060; - activefpu = FPU_68040; + activefpu = FPU_68060; return 0; } // -// .68881 - Back to 68000 TEXT segment and select 68881 FPU +// .68881 - Back to 680x0 TEXT segment and select 68881 FPU // int d_68881(void) { - d_68000(); + //d_68000(); activefpu = FPU_68881; return 0; } // -// .68882 - Back to 68000 TEXT segment and select 68882 FPU +// .68882 - Back to 680x0 TEXT segment and select 68882 FPU // int d_68882(void) { - d_68000(); - activefpu = FPU_68881; + //d_68000(); + activefpu = FPU_68882; return 0; } diff --git a/expr.c b/expr.c index b86111b..82bb5c6 100644 --- a/expr.c +++ b/expr.c @@ -1,4 +1,4 @@ - +// // RMAC - Reboot's Macro Assembler for all Atari computers // EXPR.C - Expression Analyzer // Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends diff --git a/mach.c b/mach.c index b4b4106..64061dc 100644 --- a/mach.c +++ b/mach.c @@ -24,7 +24,7 @@ int movep = 0; // Global flag to indicate we're generating a movep instruction // Function prototypes -int m_unimp(WORD, WORD), m_badmode(WORD, WORD), m_bad6mode(WORD, WORD), m_bad6inst(WORD, WORD); +int m_unimp(WORD, WORD), m_badmode(WORD, WORD); int m_self(WORD, WORD); int m_abcd(WORD, WORD); int m_reg(WORD, WORD); @@ -73,12 +73,15 @@ int m_cinv(WORD inst, WORD siz); int m_cprest(WORD inst, WORD siz); int m_movec(WORD inst, WORD siz); int m_moves(WORD inst, WORD siz); +int m_lpstop(WORD inst, WORD siz); +int m_plpa(WORD inst, WORD siz); // PMMU int m_pbcc(WORD inst, WORD siz); int m_pflusha(WORD inst, WORD siz); int m_pflush(WORD inst, WORD siz); int m_pflushr(WORD inst, WORD siz); +int m_pflushan(WORD inst, WORD siz); int m_pload(WORD inst, WORD siz, WORD extension); int m_pmove(WORD inst, WORD siz); int m_pmovefd(WORD inst, WORD siz); @@ -606,7 +609,7 @@ int m_dbra(WORD inst, WORD siz) if ((a1exattr & TDB) != cursect) return error(rel_error); - uint32_t v = a1exval - sloc; + uint32_t v = (uint32_t)a1exval - sloc; if (v + 0x8000 > 0x10000) return error(range_error); @@ -1045,7 +1048,7 @@ immed1: rmask = 0; for(i=0x8000; i; i>>=1, w>>=1) - rmask = (WORD)((rmask << 1) | w & 1); + rmask = (WORD)((rmask << 1) | (w & 1)); } } else @@ -1181,19 +1184,38 @@ int m_bfop(WORD inst, WORD siz) else bfparam1 = bfval1 << 12; - D_word((inst | am0 | a0reg | am1 | a1reg)); + //D_word((inst | am0 | a0reg | am1 | a1reg)); + if (inst == B16(11101111, 11000000)) + // bfins special case + D_word((inst | am1 | a1reg)); + else + D_word((inst | am0 | a0reg)); + ea0gen(siz); // Generate EA // Second instruction word - Dest register (if exists), Do, Offset, Dw, Width - inst = bfparam1 | bfparam2; + if (inst == B16(11101111, 11000000)) + { + // bfins special case + inst = bfparam1 | bfparam2; - if (am1 == DREG) - inst |= a1reg << 0; + if (am1 == DREG) + inst |= a0reg << 12; - if (am0 == DREG) - inst |= a0reg << 12; + D_word(inst); + } + else + { + inst = bfparam1 | bfparam2; - D_word(inst); + if (am1 == DREG) + inst |= a0reg << 0; + + if (am0 == DREG) + inst |= a1reg << 12; + + D_word(inst); + } return OK; } @@ -1516,11 +1538,12 @@ int m_chk2(WORD inst, WORD siz) // -// cpbcc(68020, 68030) +// cpbcc(68020, 68030, 68040 (FBcc), 68060 (FBcc)) +// TODO: Better checks for different instructions? // int m_cpbr(WORD inst, WORD siz) { - if ((activecpu & (CPU_68020 | CPU_68030)) == 0) + if ((activecpu & (CPU_68020 | CPU_68030)) && (!activefpu == 0)) return error(unsupport); if (a0exattr & DEFINED) @@ -1541,7 +1564,7 @@ int m_cpbr(WORD inst, WORD siz) return OK; } } - else // SIZW/SIZN + else // SIZW/SIZN { if ((v + 0x8000) >= 0x10000) return error(range_error); @@ -1612,6 +1635,7 @@ int m_cpdbr(WORD inst, WORD siz) } return OK; + } @@ -1729,7 +1753,7 @@ int m_move16b(WORD inst, WORD siz) return error("Wasn't this suppose to call m_move16a???"); else { - //move16 (ax)+,(xxx).L + // move16 (ax)+,(xxx).L inst |= 0 << 3; v = (int)a1exval; } @@ -1738,20 +1762,20 @@ int m_move16b(WORD inst, WORD siz) { if (am1 == AIND) { - //move16 (xxx).L,(ax)+ + // move16 (xxx).L,(ax)+ inst |= 1 << 3; v = (int)a0exval; } - else //APOSTINC + else // APOSTINC { - //move16 (xxx).L,(ax) + // move16 (xxx).L,(ax) inst |= 3 << 3; v = (int)a0exval; } } else if (am0 == AIND) { - //move16 (ax),(xxx).L + // move16 (ax),(xxx).L inst |= 2 << 3; v = (int)a1exval; } @@ -1923,7 +1947,7 @@ int m_trapcc(WORD inst, WORD siz) // -// cinvl/p/a (68040) +// cinvl/p/a (68040/68060) // int m_cinv(WORD inst, WORD siz) { @@ -1986,7 +2010,7 @@ int m_frestore(WORD inst, WORD siz) // -// movec (68010, 68020, 68030, 68040, CPU32) +// movec (68010, 68020, 68030, 68040, 68060, CPU32) // int m_movec(WORD inst, WORD siz) { @@ -2141,7 +2165,7 @@ int m_pflush(WORD inst, WORD siz) if ((a0exattr & DEFINED) == 0) return error("function code immediate should be defined"); - if (a0exval > 7 && a0exval < 0) + if (a0exval > 7) return error("function code out of range (0-7)"); fc = (uint16_t)a0exval; @@ -2183,7 +2207,7 @@ int m_pflush(WORD inst, WORD siz) if ((a0exattr & DEFINED) == 0) return error("mask immediate value should be defined"); - if (a0exval > 7 && a0exval < 0) + if (a0exval > 7) return error("function code out of range (0-7)"); mask = (uint16_t)a0exval << 5; @@ -2257,6 +2281,18 @@ int m_pflush(WORD inst, WORD siz) } +// +// pflushan (68040, 68060) +// +int m_pflushan(WORD inst, WORD siz) +{ + if (activecpu == CPU_68040 || activecpu == CPU_68060) + D_word(inst); + + return OK; +} + + // // pflushr (68851) // @@ -2395,7 +2431,7 @@ int m_pmove(WORD inst, WORD siz) // The instruction is a quad-word (8 byte) operation // for the CPU root pointer and the supervisor root pointer. - // It is a long - word operation for the translation control register + // It is a long-word operation for the translation control register // and the transparent translation registers(TT0 and TT1). // It is a word operation for the MMU status register. @@ -2417,7 +2453,7 @@ int m_pmove(WORD inst, WORD siz) } else if (am1 == CREG) { - inst |= am0 | a0reg; + inst |= am0 | a0reg; D_word(inst); } @@ -2471,7 +2507,7 @@ int m_pmovefd(WORD inst, WORD siz) // int m_ptrapcc(WORD inst, WORD siz) { - CHECKNO20; + CHECKNO20; // We stash the 5 condition bits inside the opcode in 68ktab (bits 0-4), // so we need to extract them first and fill in the clobbered bits. WORD opcode = inst & 0x1F; @@ -3728,3 +3764,43 @@ int m_ftwotox(WORD inst, WORD siz) return gen_fpu(inst, siz, B8(00010001), FPU_FPSP); } + +///////////////////////////////// +// // +// 68060 specific instructions // +// // +///////////////////////////////// + + +// +// lpstop (68060) +// +int m_lpstop(WORD inst, WORD siz) +{ + CHECKNO60; + D_word(B16(00000001, 11000000)); + + if (a0exattr&DEFINED) + D_word(a0exval); + else + { + AddFixup(FU_WORD, sloc, a0expr); + D_word(0); + } + + return OK; +} + + +// +// plpa (68060) +// +int m_plpa(WORD inst, WORD siz) +{ + CHECKNO60; + inst |= a0reg; // Install register + D_word(inst); + + return OK; +} + diff --git a/mark.c b/mark.c index 7378c8a..2a089c3 100644 --- a/mark.c +++ b/mark.c @@ -221,7 +221,7 @@ uint32_t MarkImage(register uint8_t * mp, uint32_t siz, uint32_t tsize, int okfl w |= symbol->senv << 3; *wp++ = w >> 8; - *wp = w; + *wp = (uint8_t)w; } } else diff --git a/parmode.h b/parmode.h index dd9c77a..0c5d66d 100644 --- a/parmode.h +++ b/parmode.h @@ -197,7 +197,9 @@ // It might be (Dn[.wl][*scale],od) // Maybe this is wrong and we have to write some code here // instead of reusing that path... - AnEXTEN |= EXT_BDSIZE0; // Base displacement null - suppressed + AnEXTEN |= EXT_FULLWORD; // Definitely using full extension format, so set bit 8 + AnEXTEN |= EXT_BS; // Base displacement null - suppressed + AnEXTEN |= AnIXREG << 12; goto CHECKODn; } else @@ -370,7 +372,7 @@ } else if ((*tok >= KW_A0) && (*tok <= KW_A7)) { // ([bd,An,... - AnREG = (6 << 3) | *tok & 7; + AnREG = (6 << 3) | (*tok & 7); tok++; } else if ((*tok >= KW_D0) && (*tok <= KW_D7)) @@ -603,7 +605,7 @@ if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK) goto badmode; - if (CHECK_OPTS(OPT_BASE_DISP) && (AnEXVAL == 0)) + if (CHECK_OPTS(OPT_BASE_DISP) && (AnEXATTR & DEFINED) && (AnEXVAL == 0)) { // od=0 so optimise it out AMn = MEMPOST; // let's say it's ([bd,An],Xn,od) with od=0 then @@ -616,7 +618,26 @@ if (*tok == DOTL) { // expr.L - AnEXTEN |= EXT_IISPOSL; // Long outer displacement + if (!(AnEXTEN & EXT_BS)) + AnEXTEN |= EXT_IISPOSL; // Long outer displacement + else + { + // bd is suppressed, so sticking the od size in bd + AnEXTEN |= EXT_BDSIZEL; + // And of course the expression has to be copied to + // AnBEXPR instead of AnEXPR. Yay. :-/ + int i = 0; + + do + { + AnBEXPR[i] = AnEXPR[i]; + i++; + } + while (AnEXPR[i] != 'E'); + + AnBEXPR[i] = 'E'; + } + AMn = MEMPOST; tok++; @@ -726,9 +747,9 @@ IS_SUPPRESSEDn: } else if (*tok == ',') { - *tok++; // ([bd,An,Xn.size*scale],od) + tok++; // ([bd,An,Xn.size*scale],od) - //Check for Xn + // Check for Xn if ((*tok >= KW_A0) && (*tok <= KW_A7)) { AnEXTEN |= ((*tok & 7) << 12); @@ -744,8 +765,8 @@ IS_SUPPRESSEDn: // Check for size { - // ([bd,An/PC],Xn.W/L...) - switch ((int)*tok) + // ([bd,An/PC],Xn.W/L...) + switch ((int)*tok) { // Index reg size: | .W | .L case DOTW: @@ -764,8 +785,8 @@ IS_SUPPRESSEDn: } // Check for scale - if (*tok == '*') // ([bd,An/PC],Xn*...) - { // scale: *1, *2, *4, *8 + if (*tok == '*') // ([bd,An/PC],Xn*...) + { // scale: *1, *2, *4, *8 tok++; if (*tok == SYMBOL) diff --git a/riscasm.c b/riscasm.c index 533eca7..f9aa055 100644 --- a/riscasm.c +++ b/riscasm.c @@ -193,7 +193,7 @@ int GetRegister(WORD rattr) } // If we got a register in range (0-31), return it - if ((eval >= 0) && (eval <= 31)) + if (eval <= 31) return (int)eval; // Otherwise, it's out of range & we flag an error @@ -751,7 +751,7 @@ int GenerateRISCCode(int state) ccsym = lookup(string[tok[1]], LABEL, 0); if (ccsym && (ccsym->sattre & EQUATEDCC) && !(ccsym->sattre & UNDEF_CC)) - val = ccsym->svalue; + val = (int)ccsym->svalue; else return error("unknown condition code"); } diff --git a/symbol.c b/symbol.c index b66216b..c24720f 100644 --- a/symbol.c +++ b/symbol.c @@ -309,7 +309,6 @@ uint32_t sy_assign_ELF(uint8_t * buf, uint8_t *(* construct)()) // and export all global-referenced labels. Not sure if this is // required but it's here nonetheless - //for(sy=sdecl; sy!=NULL; sy=sy->sorder) for(SYM * sy=sdecl; sy!=NULL; sy=sy->sdecl) { if ((sy->stype == LABEL)