Category : Assembly Language Source Code
Archive   : CUG292.ZIP
Filename : M09ADR.C

 
Output of file : M09ADR.C contained in archive : CUG292.ZIP

/* M09ADR:C */

/*
* (C) Copyright 1989,1990
* All Rights Reserved
*
* Alan R. Baldwin
* 721 Berkeley St.
* Kent, Ohio 44240
*/

#include
#include
#include "asm.h"
#include "m6809.h"

int index;

int
addr(esp)
register struct expr *esp;
{
register c;

index = 0;
if ((c = getnb()) == '#') {
expr(esp, 0);
esp->e_mode = S_IMMED;
} else
if (c == '[') {
index = 0x90;
addr1(esp);
if (getnb() != ']') {
aerr();
}
} else {
unget(c);
addr1(esp);
}
return (esp->e_mode);
}

int
addr1(esp)
register struct expr *esp;
{
register c;

if (admode(abd)) {
comma();
if (!admode(xyus))
aerr();
esp->e_mode = S_IND;
esp->e_flag = 0;
esp->e_addr = 0;
esp->e_base.e_ap = NULL;
} else
if ((c = getnb()) == ',') {
if (admode(xyus)) {
index |= 0x04;
} else
if (admode(auto2)) {
;
} else
if (!(index & 0x10) && admode(auto1)) {
;
} else {
aerr();
}
esp->e_mode = S_IND;
esp->e_flag = 0;
esp->e_addr = 0;
esp->e_base.e_ap = NULL;
} else
if (c == '*') {
expr(esp, 0);
esp->e_mode = S_DIR;
if ((c = getnb()) == ',') {
if (admode(xyus)) {
esp->e_mode = S_OFST;
} else
if (admode(pcr)) {
esp->e_mode = S_PCR;
} else
if (admode(pc)) {
esp->e_mode = S_PC;
} else {
aerr();
}
} else {
unget(c);
}
} else {
unget(c);
expr(esp, 0);
if ((c = getnb()) == ',') {
if (admode(xyus)) {
esp->e_mode = S_OFST;
} else
if (admode(pcr)) {
esp->e_mode = S_PCR;
} else
if (admode(pc)) {
esp->e_mode = S_PC;
} else {
aerr();
}
} else {
unget(c);
esp->e_mode = S_EXT;
}
}
return (esp->e_mode);
}


/*
* Enter admode() to search a specific addressing mode table
* for a match. Return the addressing value on a match or
* zero for no match.
*/
int
admode(sp)
register struct adsym *sp;
{
register char *ptr;
register int i, v;
unget(getnb());
i = 0;
while ( *(ptr = (char *) &sp[i]) ) {
if (srch(ptr)) {
v = sp[i].a_val;
index |= (v | 0x80);
return(v);
}
i++;
}
return(0);
}

/*
* srch --- does string match ?
*/
int
srch(str)
register char *str;
{
register char *ptr;
ptr = ip;

#if CASE_SENSITIVE
while (*ptr && *str) {
if (*ptr != *str)
break;
ptr++;
str++;
}
if (*ptr == *str) {
ip = ptr;
return(1);
}
#else
while (*ptr && *str) {
if (ccase[*ptr] != ccase[*str])
break;
ptr++;
str++;
}
if (ccase[*ptr] == ccase[*str]) {
ip = ptr;
return(1);
}
#endif

if (!*str)
if (any(*ptr," \t\n,];")) {
ip = ptr;
return(1);
}
return(0);
}

/*
* any --- does str contain c?
*/
int
any(c,str)
char c, *str;
{
while (*str)
if(*str++ == c)
return(1);
return(0);
}

struct adsym abd[] = { /* a, b, or d indexed offset */
"a", 0x06,
"b", 0x05,
"d", 0x0B,
"", 0x00
};

struct adsym xyus[] = { /* x, y, u, or s index register */
"x", 0x100,
"y", 0x120,
"u", 0x140,
"s", 0x160,
"", 0x000
};

struct adsym auto1[] = { /* auto increment/decrement by 1 */
"x+", 0x100,
"-x", 0x102,
"y+", 0x120,
"-y", 0x122,
"u+", 0x140,
"-u", 0x142,
"s+", 0x160,
"-s", 0x162,
"", 0x000
};

struct adsym auto2[] = { /* auto increment/decrement by 2 */
"x++", 0x101,
"--x", 0x103,
"y++", 0x121,
"--y", 0x123,
"u++", 0x141,
"--u", 0x143,
"s++", 0x161,
"--s", 0x163,
"", 0x000
};

struct adsym pc[] = { /* pc */
"pc", 0x0C,
"", 0x00
};

struct adsym pcr[] = { /* pc relative */
"pcr", 0x0C,
"", 0x00
};

struct adsym regs[] = { /* exg, tfr register coding */
"d", 0x100,
"x", 0x101,
"y", 0x102,
"u", 0x103,
"s", 0x104,
"pc", 0x105,
"a", 0x108,
"b", 0x109,
"cc", 0x10A,
"dp", 0x10B,
"", 0x000
};

struct adsym stks[] = { /* push/pull on system stack */
"cc", 0x01,
"a", 0x02,
"b", 0x04,
"d", 0x06,
"dp", 0x08,
"x", 0x10,
"y", 0x20,
"u", 0x40,
"pc", 0x80,
"", 0x00
};

struct adsym stku[] = { /* push/pull on user stack */
"cc", 0x01,
"a", 0x02,
"b", 0x04,
"d", 0x06,
"dp", 0x08,
"x", 0x10,
"y", 0x20,
"s", 0x40,
"pc", 0x80,
"", 0x00
};