357 lines
8.2 KiB
C
357 lines
8.2 KiB
C
/* pdkmch.c */
|
|
|
|
/*
|
|
* Copyright (C) 1998-2011 Alan R. Baldwin
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*
|
|
* Alan R. Baldwin
|
|
* 721 Berkeley St.
|
|
* Kent, Ohio 44240
|
|
*
|
|
* This Assember Ported by
|
|
* John L. Hartman (JLH)
|
|
* jhartman at compuserve dot com
|
|
* noice at noicedebugger dot com
|
|
*
|
|
*/
|
|
|
|
#include "asxxxx.h"
|
|
#include "pdk.h"
|
|
|
|
static VOID outpdkaw(struct inst inst, struct expr e) {
|
|
outaw(inst.op | (e.e_addr & inst.mask));
|
|
}
|
|
|
|
static VOID outpdkrm(struct inst inst, struct expr e) {
|
|
/* Don't generate relocatable data if everything is constant. */
|
|
if (is_abs(&e)) {
|
|
outpdkaw(inst, e);
|
|
} else {
|
|
outrwp(&e, inst.op, inst.mask, /*jump=*/0);
|
|
}
|
|
}
|
|
|
|
static VOID outpdka(struct inst inst) {
|
|
struct expr e;
|
|
clrexpr(&e);
|
|
outpdkaw(inst, e);
|
|
}
|
|
|
|
VOID emov(struct inst def,
|
|
struct inst ioa,
|
|
struct inst aio,
|
|
struct inst ma,
|
|
struct inst am) {
|
|
struct expr e, e1;
|
|
clrexpr(&e);
|
|
clrexpr(&e1);
|
|
|
|
int t = addr(&e);
|
|
comma(1);
|
|
int t1 = addr(&e1);
|
|
|
|
if (t == S_IO && t1 == S_A) {
|
|
outpdkaw(ioa, e);
|
|
} else
|
|
if (t == S_A && t1 == S_IO) {
|
|
outpdkaw(aio, e1);
|
|
} else
|
|
if (t == S_M && t1 == S_A) {
|
|
outpdkrm(ma, e);
|
|
} else
|
|
if (t == S_A && t1 == S_M) {
|
|
outpdkrm(am, e1);
|
|
} else
|
|
if (t == S_A && t1 == S_K) {
|
|
outpdkrm(def, e1);
|
|
} else
|
|
aerr();
|
|
}
|
|
|
|
VOID eidxm(struct inst am, struct inst ma) {
|
|
struct expr e, e1;
|
|
clrexpr(&e);
|
|
clrexpr(&e1);
|
|
|
|
int t = addr(&e);
|
|
comma(1);
|
|
int t1 = addr(&e1);
|
|
|
|
if (t == S_A && t1 == S_M) {
|
|
outpdkrm(am, e1);
|
|
} else
|
|
if (t == S_M && t1 == S_A) {
|
|
outpdkrm(ma, e);
|
|
} else
|
|
aerr();
|
|
}
|
|
|
|
VOID earith(struct inst def,
|
|
struct inst ma,
|
|
struct inst am) {
|
|
struct expr e, e1;
|
|
clrexpr(&e);
|
|
clrexpr(&e1);
|
|
|
|
int t = addr(&e);
|
|
comma(1);
|
|
int t1 = addr(&e1);
|
|
|
|
if (t == S_M && t1 == S_A) {
|
|
outpdkrm(ma, e);
|
|
} else
|
|
if (t == S_A && t1 == S_M) {
|
|
outpdkrm(am, e1);
|
|
} else
|
|
if (t == S_A && t1 == S_K) {
|
|
outpdkrm(def, e1);
|
|
} else
|
|
aerr();
|
|
}
|
|
|
|
VOID earithc(struct inst ma,
|
|
struct inst am,
|
|
struct inst m,
|
|
struct inst a) {
|
|
struct expr e;
|
|
clrexpr(&e);
|
|
int t = more() ? addr(&e) : S_A;
|
|
|
|
if (comma(0)) {
|
|
struct expr e1;
|
|
clrexpr(&e1);
|
|
int t1 = addr(&e1);
|
|
if (t == S_M && t1 == S_A) {
|
|
outpdkrm(ma, e);
|
|
} else
|
|
if (t == S_A && t1 == S_M) {
|
|
outpdkrm(am, e1);
|
|
} else
|
|
aerr();
|
|
} else
|
|
if (t == S_M) {
|
|
outpdkrm(m, e);
|
|
} else
|
|
if (t == S_A) {
|
|
outpdka(a);
|
|
} else
|
|
aerr();
|
|
}
|
|
|
|
VOID eshift(struct inst a,
|
|
struct inst m) {
|
|
struct expr e;
|
|
clrexpr(&e);
|
|
int t = more() ? addr(&e) : S_A;
|
|
|
|
if (t == S_A) {
|
|
outpdka(a);
|
|
} else
|
|
if (t == S_M) {
|
|
outpdkrm(m, e);
|
|
} else
|
|
aerr();
|
|
}
|
|
|
|
VOID ebit(struct inst def,
|
|
struct inst ma,
|
|
struct inst am,
|
|
struct inst *ioa) {
|
|
struct expr e, e1;
|
|
clrexpr(&e);
|
|
clrexpr(&e1);
|
|
|
|
int t = addr(&e), t1 = 0;
|
|
|
|
if (!more()) {
|
|
if (t == S_K) {
|
|
t = S_A;
|
|
t1 = S_K;
|
|
e1 = e;
|
|
} else if (t == S_IO) {
|
|
t1 = S_A;
|
|
} else
|
|
aerr();
|
|
} else {
|
|
comma(1);
|
|
t1 = addr(&e1);
|
|
}
|
|
|
|
if (t == S_M && t1 == S_A) {
|
|
outpdkrm(ma, e);
|
|
} else
|
|
if (t == S_A && t1 == S_M) {
|
|
outpdkrm(am, e1);
|
|
} else
|
|
if (t == S_A && t1 == S_K) {
|
|
outpdkrm(def, e1);
|
|
} else
|
|
if (t == S_IO && t1 == S_A && ioa) {
|
|
outpdkaw(*ioa, e);
|
|
} else
|
|
aerr();
|
|
}
|
|
|
|
VOID enot(struct inst def, struct inst m) {
|
|
struct expr e;
|
|
clrexpr(&e);
|
|
int t = more() ? addr(&e) : S_A;
|
|
|
|
if (t == S_M) {
|
|
outpdkrm(m, e);
|
|
} else if (t == S_A) {
|
|
outpdka(def);
|
|
} else
|
|
aerr();
|
|
}
|
|
|
|
VOID ebitn(struct inst io, struct inst m, int offset) {
|
|
struct expr e, e1;
|
|
clrexpr(&e);
|
|
clrexpr(&e1);
|
|
|
|
int t = addr(&e);
|
|
comma(1);
|
|
if (pdkbit(&e1) != S_K)
|
|
aerr();
|
|
|
|
const a_uint bitn = (e1.e_addr & 0x7) << offset;
|
|
if (t == S_IO) {
|
|
io.op |= bitn;
|
|
outpdkaw(io, e);
|
|
} else
|
|
if (t == S_M) {
|
|
m.op |= bitn;
|
|
outpdkrm(m, e);
|
|
} else
|
|
aerr();
|
|
}
|
|
|
|
VOID eskip(struct inst def, struct inst m) {
|
|
struct expr e;
|
|
clrexpr(&e);
|
|
int t = addr(&e);
|
|
if (t == S_A) {
|
|
comma(1);
|
|
t = addr(&e);
|
|
}
|
|
|
|
if (t == S_M) {
|
|
outpdkrm(m, e);
|
|
} else
|
|
if (t == S_K) {
|
|
outpdkrm(def, e);
|
|
} else
|
|
aerr();
|
|
}
|
|
|
|
VOID ezsn(struct inst def, struct inst m) {
|
|
/* IZSN and DZSN insts have the same params as NOT. */
|
|
enot(def, m);
|
|
}
|
|
|
|
VOID eret(struct inst def, struct inst k) {
|
|
if (more()) {
|
|
struct expr e;
|
|
clrexpr(&e);
|
|
if (addr(&e) != S_K)
|
|
aerr();
|
|
outpdkrm(k, e);
|
|
} else
|
|
outpdka(def);
|
|
}
|
|
|
|
VOID eone(struct inst m) {
|
|
struct expr e;
|
|
clrexpr(&e);
|
|
if (addr(&e) != S_M)
|
|
aerr();
|
|
|
|
outpdkrm(m, e);
|
|
}
|
|
|
|
VOID exch(struct inst m) {
|
|
struct expr e;
|
|
clrexpr(&e);
|
|
|
|
int t = addr(&e);
|
|
if (t == S_A) {
|
|
comma(1);
|
|
t = addr(&e);
|
|
}
|
|
|
|
if (t != S_M)
|
|
aerr();
|
|
outpdkrm(m, e);
|
|
}
|
|
|
|
VOID epupo(struct inst def) {
|
|
if (more() && (def.op & 0x2000)) {
|
|
int t = getnb();
|
|
if (t != 'a')
|
|
aerr();
|
|
if (!more() || ((t = getnb()) != 'f'))
|
|
aerr();
|
|
def.op &= 0x1FFF;
|
|
}
|
|
outpdka(def);
|
|
}
|
|
|
|
VOID eopta(struct inst def) {
|
|
if (more()) {
|
|
struct expr e;
|
|
clrexpr(&e);
|
|
if (addr(&e) != S_A)
|
|
aerr();
|
|
}
|
|
outpdka(def);
|
|
}
|
|
|
|
VOID eswapc(struct inst iok, int offset) {
|
|
struct expr e, e1;
|
|
clrexpr(&e);
|
|
clrexpr(&e1);
|
|
|
|
int t = addr(&e);
|
|
comma(1);
|
|
int t1 = pdkbit(&e1);
|
|
|
|
if (t != S_IO || t1 != S_K)
|
|
aerr();
|
|
|
|
iok.op |= (e1.e_addr & 0x7) << offset;
|
|
outpdkaw(iok, e);
|
|
}
|
|
|
|
VOID espec(struct inst am, struct inst ma) {
|
|
struct expr e, e1;
|
|
clrexpr(&e);
|
|
clrexpr(&e1);
|
|
|
|
int t = addr(&e);
|
|
comma(1);
|
|
int t1 = addr(&e1);
|
|
|
|
if (t == S_A && t1 == S_M) {
|
|
outpdkrm(am, e1);
|
|
} else
|
|
if (t == S_M && t1 == S_A) {
|
|
outpdkrm(ma, e);
|
|
} else
|
|
aerr();
|
|
}
|
|
|