/* m11mch.c */ /* * (C) Copyright 1989 * All Rights Reserved * * Alan R. Baldwin * 721 Berkeley St. * Kent, Ohio 44240 */ #include #include #include "asm.h" #include "6811.h" struct sdp sdp[] = { NULL }; /* * Process a machine op. */ VOID machine(mp) struct mne *mp; { register op, t1, t2; struct expr e1, e2, e3; struct area *espa; char id[NCPS]; int reg, cpg, type, v1; reg = 0; cpg = 0; op = mp->m_valu; type = mp->m_type; switch (type) { case S_SDP: espa = NULL; if (more()) { getid(id, -1); espa = alookup(id); if ( espa == NULL) { err('u'); } } if (espa) { sdp->s_area = espa; } else { sdp->s_area = dot->s_area; } lmode = SLIST; break; case S_INH2: outab(PAGE2); case S_INH: outab(op); break; case S_PUL: v1 = admode(abdxy); if (v1 == S_A) { outab(op); break; } if (v1 == S_B) { outab(op+1); break; } if (v1 == S_X) { outab(op+6); break; } if (v1 == S_Y) { outab(PAGE2); outab(op+6); break; } aerr(); break; case S_BRA: expr(&e1, 0); v1 = e1.e_addr - dot->s_addr - 2; if ((v1 < -128) || (v1 > 127)) aerr(); if (e1.e_base.e_ap != dot->s_area) rerr(); outab(op); outab(v1); break; case S_TYP1: t1 = addr(&e1); if (t1 == S_A) { outab(op|A); break; } if (t1 == S_B) { outab(op|B); break; } if (t1 == S_D) { if (op == 0x44) { outab(0x04); break; } if (op == 0x48) { outab(0x05); break; } aerr(); break; } if (t1 == S_INDX || t1 == S_INDY) { if (t1 == S_INDY) outab(PAGE2); outab(op|X); outrb(&e1, 0); break; } if (t1 == S_DIR || t1 == S_EXT) { outab(op|0x30); outrw(&e1, 0); break; } aerr(); break; case S_TYP2: if (!(reg = admode(abdxy))) aerr(); case S_TYP3: if (!reg) { reg = op & 0x40; } else if (reg == S_A) { reg = 0x00; } else if (reg == S_B) { reg = 0x40; } else if (reg == S_D) { if (op == 0x80) { op = 0x83; } else if (op == 0x8B) { op = 0xC3; } else { aerr(); } reg = 0x00; } else { aerr(); reg = 0x00; } t1 = addr(&e1); if (t1 == S_IMMED) { if ((op|0x40) == 0xC7) aerr(); if (op == 0x83 || op == 0xC3) { outab(op|reg); outrw(&e1, 0); } else { outab(op|reg); outrb(&e1, 0); } break; } if (t1 == S_DIR) { outab(op|reg|0x10); outrb(&e1, 0); break; } if (t1 == S_INDX || t1 == S_INDY) { if (t1 == S_INDY) outab(PAGE2); outab(op|reg|0x20); outrb(&e1, 0); break; } if (t1 == S_EXT) { outab(op|reg|0x30); outrw(&e1, 0); break; } aerr(); break; case S_TYP4: t1 = addr(&e1); if (t1 == S_IMMED) { if (op&0x0D == 0x0D) aerr(); outab(op); outrw(&e1, 0); break; } if (t1 == S_DIR) { outab(op|0x10); outrb(&e1, 0); break; } if (t1 == S_INDX || t1 == S_INDY) { if (t1 == S_INDY) outab(PAGE2); outab(op|0x20); outrb(&e1, 0); break; } if (t1 == S_EXT) { outab(op|0x30); outrw(&e1, 0); break; } aerr(); break; case S_TYP5: t1 = addr(&e1); if (t1 == S_INDX || t1 == S_INDY) { if (t1 == S_INDY) outab(PAGE2); outab(op); outrb(&e1, 0); break; } if (t1 == S_EXT) { outab(op|0x10); outrw(&e1, 0); break; } aerr(); break; case S_PG3: cpg += (PAGE3-PAGE2); case S_PG2: cpg += PAGE2; case S_TYP6: t1 = addr(&e1); if (t1 == S_IMMED) { if (op == 0xCF) aerr(); if (cpg) outab(cpg); outab(op); outrw(&e1, 0); break; } if (t1 == S_DIR) { if (cpg) outab(cpg); outab(op|0x10); outrb(&e1, 0); break; } if (t1 == S_INDX) { if (cpg) outab(PAGE3); outab(op|0x20); outrb(&e1, 0); break; } if (t1 == S_INDY) { if (cpg == PAGE2) { outab(PAGE2); } else { outab(PAGE4); } outab(op|0x20); outrb(&e1, 0); break; } if (t1 == S_EXT) { if (cpg) outab(cpg); outab(op|0x30); outrw(&e1, 0); break; } aerr(); break; case S_BTB: case S_STCLR: v1 = 0; t1 = addr(&e1); if (t1 == S_DIR) { ; } else if (t1 == S_INDX || t1 == S_INDY) { if (type == S_BTB) { op += 0x0C; } else { op += 0x08; } } else { aerr(); } comma(); t2 = addr(&e2); if (t2 != S_IMMED) aerr(); if (type == S_BTB) { comma(); expr(&e3, 0); v1 = e3.e_addr - dot->s_addr - 4; if (t1 == S_INDY) --v1; if ((v1 < -128) || (v1 > 127)) aerr(); if (e3.e_base.e_ap != dot->s_area) rerr(); } if (t1 == S_INDY) outab(PAGE2); outab(op); outrb(&e1, 0); outrb(&e2, 0); if (type == S_BTB) outab(v1); break; default: err('o'); } } /* * The next character must be a * comma. */ VOID comma() { if (getnb() != ',') qerr(); } /* * Machine dependent initialization */ VOID minit() { sdp->s_area = dot->s_area; }