]> Shamusworld >> Repos - rmac/blobdiff - mach.c
Actually implement ^^FILESIZE this time :)
[rmac] / mach.c
diff --git a/mach.c b/mach.c
index b4b410666f38f77444b16b2322cf107afdbce2f6..6d5bcf38a8652daa7a5fd7cf96655feca9d4a8d5 100644 (file)
--- a/mach.c
+++ b/mach.c
@@ -1,7 +1,7 @@
 //
 // RMAC - Reboot's Macro Assembler for all Atari computers
 // MACH.C - Code Generation
-// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends
+// Copyright (C) 199x Landon Dyer, 2011-2020 Reboot and Friends
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
@@ -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);
@@ -60,7 +60,7 @@ int m_cas2(WORD inst, WORD siz);
 int m_chk2(WORD inst, WORD siz);
 int m_cmp2(WORD inst, WORD siz);
 int m_bkpt(WORD inst, WORD siz);
-int m_cpbr(WORD inst, WORD siz);
+int m_cpbcc(WORD inst, WORD siz);
 int m_cpdbr(WORD inst, WORD siz);
 int m_muls(WORD inst, WORD siz);
 int m_move16a(WORD inst, WORD siz);
@@ -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);
@@ -89,6 +92,7 @@ int m_ploadw(WORD inst, WORD siz);
 
 // FPU
 int m_fabs(WORD inst, WORD siz);
+int m_fbcc(WORD inst, WORD siz);
 int m_facos(WORD inst, WORD siz);
 int m_fadd(WORD inst, WORD siz);
 int m_fasin(WORD inst, WORD siz);
@@ -606,7 +610,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 +1049,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 +1185,42 @@ 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,12 +1543,10 @@ int m_chk2(WORD inst, WORD siz)
 
 
 //
-// cpbcc(68020, 68030)
+// cpbcc(68020, 68030, 68040 (FBcc), 68060 (FBcc)), pbcc (68851)
 //
-int m_cpbr(WORD inst, WORD siz)
+int m_fpbr(WORD inst, WORD siz)
 {
-       if ((activecpu & (CPU_68020 | CPU_68030)) == 0)
-               return error(unsupport);
 
        if (a0exattr & DEFINED)
        {
@@ -1541,7 +1566,7 @@ int m_cpbr(WORD inst, WORD siz)
                                return OK;
                        }
                }
-        else // SIZW/SIZN
+               else // SIZW/SIZN
                {
                        if ((v + 0x8000) >= 0x10000)
                                return error(range_error);
@@ -1575,6 +1600,38 @@ int m_cpbr(WORD inst, WORD siz)
 }
 
 
+//
+// cpbcc(68020, 68030, 68040 (FBcc), 68060 (FBcc))
+//
+int m_cpbcc(WORD inst, WORD siz)
+{
+       if (!(activecpu & (CPU_68020 | CPU_68030)))
+               return error(unsupport);
+
+       return m_fpbr(inst, siz);
+}
+
+
+//
+// fbcc(6808X, 68040, 68060)
+//
+int m_fbcc(WORD inst, WORD siz)
+{
+       CHECKNOFPU;
+       return m_fpbr(inst, siz);
+}
+
+
+//
+// pbcc(68851 but let's assume 68020 only)
+//
+int m_pbcc(WORD inst, WORD siz)
+{
+       CHECKNO20;
+       return m_fpbr(inst, siz);
+}
+
+
 //
 // cpdbcc(68020, 68030)
 //
@@ -1612,6 +1669,7 @@ int m_cpdbr(WORD inst, WORD siz)
        }
 
        return OK;
+
 }
 
 
@@ -1632,7 +1690,7 @@ int m_muls(WORD inst, WORD siz)
 
        if (flg & 16)
        {
-               // OR-in register number 
+               // OR-in register number
                if (flg & 8)
                        inst |= reg_9[a1reg];           // ea1reg in bits 9..11
                else
@@ -1661,7 +1719,7 @@ int m_muls(WORD inst, WORD siz)
 
                 D_word(inst);
 
-               // Generate ea0 if requested 
+               // Generate ea0 if requested
                if (flg & 2)
                        ea0gen(siz);
 
@@ -1729,7 +1787,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 +1796,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 +1981,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 +2044,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)
 {
@@ -2081,16 +2139,6 @@ int m_moves(WORD inst, WORD siz)
 }
 
 
-//
-// PBcc (MC68851)
-//
-int m_pbcc(WORD inst, WORD siz)
-{
-       CHECKNO20;
-       return error("Not implemented yet.");
-}
-
-
 //
 // pflusha (68030, 68040)
 //
@@ -2141,7 +2189,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 +2231,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 +2305,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 +2455,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 +2477,7 @@ int m_pmove(WORD inst, WORD siz)
        }
        else if (am1 == CREG)
        {
-       inst |= am0 | a0reg;
+               inst |= am0 | a0reg;
                D_word(inst);
        }
 
@@ -2471,7 +2531,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;
@@ -2872,7 +2932,7 @@ int m_fintrz(WORD inst, WORD siz)
 
        if (activefpu == FPU_68040)
                warn("Instruction is emulated in 68040");
-       
+
        return gen_fpu(inst, siz, B8(00000011), FPU_NOWARN);
 }
 
@@ -2908,14 +2968,12 @@ int m_flogn(WORD inst, WORD siz)
 
 
 //
-// flognp1 (68040FPSP, 68060FPSP)
+// flognp1 (6888X, 68040FPSP, 68060FPSP)
 //
 int m_flognp1(WORD inst, WORD siz)
 {
-       if (activefpu & (FPU_68040 | FPU_68060))
-               return gen_fpu(inst, siz, B8(00000110), FPU_FPSP);
-
-       return error("Unsupported in current FPU");
+       CHECKNOFPU;
+       return gen_fpu(inst, siz, B8(00000110), FPU_FPSP);
 }
 
 
@@ -3379,7 +3437,7 @@ int m_fsmul(WORD inst, WORD siz)
 {
        if (activefpu & (FPU_68040 | FPU_68060))
                return gen_fpu(inst, siz, B8(01100011), FPU_NOWARN);
-       
+
        return error("Unsupported in current FPU");
 }
 
@@ -3408,7 +3466,7 @@ int m_fneg(WORD inst, WORD siz)
                a1reg = a0reg;
                return gen_fpu(inst, siz, B8(00011010), FPU_NOWARN);
        }
-       
+
        return gen_fpu(inst, siz, B8(00011010), FPU_NOWARN);
 }
 
@@ -3425,7 +3483,7 @@ int m_fsneg(WORD inst, WORD siz)
                        a1reg = a0reg;
                        return gen_fpu(inst, siz, B8(01011010), FPU_NOWARN);
                }
-               
+
                return gen_fpu(inst, siz, B8(01011010), FPU_NOWARN);
        }
 
@@ -3587,7 +3645,7 @@ int m_fsfsqrt(WORD inst, WORD siz)
 {
        if (activefpu & (FPU_68040 | FPU_68060))
                return gen_fpu(inst, siz, B8(01000001), FPU_NOWARN);
-       
+
        return error("Unsupported in current FPU");
 }
 
@@ -3728,3 +3786,45 @@ 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;
+}
+