1
0
mirror of https://github.com/DoctorWkt/unix-jun72.git synced 2026-02-02 06:51:49 +00:00
Files
DoctorWkt.unix-jun72/tools/apout/ea.c
2008-05-06 23:25:22 +00:00

589 lines
10 KiB
C

/* ea.c - Calculate, load, and store using the proper effective address as
* specified by the current instruction. Also push and pop stack operations.
*
* $Revision: 2.17 $
* $Date: 1999/09/17 05:11:10 $
*/
#include "defines.h"
void
load_ea(void)
{
u_int16_t indirect;
switch (DST_MODE) {
case 0:
illegal();
return;
case 1:
dstword = regs[DST_REG];
return;
case 2:
dstword = regs[DST_REG]; /* this is wrong for 11/34 */
regs[DST_REG] += 2;
return;
case 3:
indirect = regs[DST_REG]; /* this is wrong for 11/34 */
regs[DST_REG] += 2;
lli_word(indirect, dstword);
return;
case 4:
regs[DST_REG] -= 2;
dstword = regs[DST_REG];
return;
case 5:
regs[DST_REG] -= 2;
indirect = regs[DST_REG];
lli_word(indirect, dstword);
return;
case 6:
lli_word(regs[PC], indirect);
regs[PC] += 2;
dstword = regs[DST_REG] + indirect;
return;
case 7:
lli_word(regs[PC], indirect);
regs[PC] += 2;
indirect = regs[DST_REG] + indirect;
ll_word(indirect, dstword);
return;
}
illegal();
}
INLINE void
pop(void)
{
ll_word(regs[SP], dstword);
regs[SP] += 2;
}
INLINE void
push(void)
{
regs[SP] -= 2;
sl_word(regs[SP], srcword);
}
void
loadb_dst(void)
{
u_int16_t addr, indirect;
switch (DST_MODE) {
case 0:
dstbyte = (u_int8_t)(regs[DST_REG] & 0377);
return;
case 1:
addr = regs[DST_REG];
ea_addr = addr;
if (DST_REG == PC) {
lli_byte(addr, dstbyte)
} else {
ll_byte(addr, dstbyte);
}
return;
case 2:
addr = regs[DST_REG];
ea_addr = addr;
if (DST_REG == PC) {
lli_byte(addr, dstbyte)
} else {
ll_byte(addr, dstbyte);
}
if (DST_REG >= 6)
regs[DST_REG] += 2;
else
regs[DST_REG] += 1;
return;
case 3:
indirect = regs[DST_REG];
if (DST_REG == PC) {
lli_word(indirect, addr)
} else {
ll_word(indirect, addr);
}
ea_addr = addr;
ll_byte(addr, dstbyte);
regs[DST_REG] += 2;
return;
case 4:
if (DST_REG >= 6)
regs[DST_REG] -= 2;
else
regs[DST_REG] -= 1;
addr = regs[DST_REG];
ea_addr = addr;
ll_byte(addr, dstbyte);
return;
case 5:
regs[DST_REG] -= 2;
indirect = regs[DST_REG];
ll_word(indirect, addr);
ea_addr = addr;
ll_byte(addr, dstbyte);
return;
case 6:
lli_word(regs[PC], indirect);
regs[PC] += 2;
addr = regs[DST_REG] + indirect;
ea_addr = addr;
ll_byte(addr, dstbyte);
return;
case 7:
lli_word(regs[PC], indirect);
regs[PC] += 2;
indirect = regs[DST_REG] + indirect;
ll_word(indirect, addr);
ea_addr = addr;
ll_byte(addr, dstbyte);
return;
}
illegal();
}
void
loadb_src(void)
{
u_int16_t addr, indirect;
switch (SRC_MODE) {
case 0:
srcbyte = (u_int8_t)(regs[SRC_REG] & 0377);
return;
case 1:
addr = regs[SRC_REG];
if (SRC_REG == PC) {
lli_byte(addr, srcbyte);
} else {
ll_byte(addr, srcbyte);
}
return;
case 2:
addr = regs[SRC_REG];
if (SRC_REG == PC) {
lli_byte(addr, srcbyte);
} else {
ll_byte(addr, srcbyte);
}
if (SRC_REG >= 6)
regs[SRC_REG] += 2;
else
regs[SRC_REG] += 1;
return;
case 3:
indirect = regs[SRC_REG];
if (SRC_REG == PC) {
lli_word(indirect, addr)
} else {
ll_word(indirect, addr);
}
ll_byte(addr, srcbyte);
regs[SRC_REG] += 2;
return;
case 4:
if (SRC_REG >= 6)
regs[SRC_REG] -= 2;
else
regs[SRC_REG] -= 1;
addr = regs[SRC_REG];
ll_byte(addr, srcbyte);
return;
case 5:
regs[SRC_REG] -= 2;
indirect = regs[SRC_REG];
ll_word(indirect, addr);
ll_byte(addr, srcbyte);
return;
case 6:
lli_word(regs[PC], indirect);
regs[PC] += 2;
addr = regs[SRC_REG] + indirect;
ll_byte(addr, srcbyte);
return;
case 7:
lli_word(regs[PC], indirect);
regs[PC] += 2;
indirect = regs[SRC_REG] + indirect;
ll_word(indirect, addr);
ll_byte(addr, srcbyte);
return;
}
illegal();
}
void
storeb_dst(void)
{
u_int16_t addr, indirect;
switch (DST_MODE) {
case 0:
regs[DST_REG]&= 0xff00;
regs[DST_REG]|= srcbyte;
return;
case 1:
addr = regs[DST_REG];
sl_byte(addr, srcbyte);
return;
case 2:
addr = regs[DST_REG];
sl_byte(addr, srcbyte);
if (DST_REG >= 6)
regs[DST_REG] += 2;
else
regs[DST_REG] += 1;
return;
case 3:
indirect = regs[DST_REG];
ll_word(indirect, addr);
sl_byte(addr, srcbyte);
regs[DST_REG] += 2;
return;
case 4:
if (DST_REG >= 6) /* xyz */
regs[DST_REG] -= 2;
else
regs[DST_REG] -= 1;
addr = regs[DST_REG];
sl_byte(addr, srcbyte);
return;
case 5:
regs[DST_REG] -= 2;
indirect = regs[DST_REG];
ll_word(indirect, addr);
sl_byte(addr, srcbyte);
return;
case 6:
lli_word(regs[PC], indirect);
regs[PC] += 2;
addr = regs[DST_REG] + indirect;
sl_byte(addr, srcbyte);
return;
case 7:
lli_word(regs[PC], indirect);
regs[PC] += 2;
indirect = regs[DST_REG] + indirect;
ll_word(indirect, addr);
sl_byte(addr, srcbyte);
return;
}
illegal();
}
INLINE void
storeb_dst_2(void)
{
if (DST_MODE == 0) {
regs[DST_REG]&= 0xff00;
regs[DST_REG]|= dstbyte;
return;
}
sl_byte(ea_addr, dstbyte);
}
void
loadp_dst(void)
{
u_int16_t addr, indirect;
switch (DST_MODE) {
case 0:
srcword = regs[DST_REG];
return;
case 1:
addr = regs[DST_REG];
ll_word(addr, srcword);
return;
case 2:
addr = regs[DST_REG];
ll_word(addr, srcword);
regs[DST_REG] += 2;
return;
case 3:
indirect = regs[DST_REG];
ll_word(indirect, addr);
ll_word(addr, srcword);
regs[DST_REG] += 2;
return;
case 4:
regs[DST_REG] -= 2;
addr = regs[DST_REG];
ll_word(addr, srcword);
return;
case 5:
regs[DST_REG] -= 2;
indirect = regs[DST_REG];
ll_word(indirect, addr);
ll_word(addr, srcword);
return;
case 6:
lli_word(regs[PC], indirect);
regs[PC] += 2;
addr = regs[DST_REG] + indirect;
if (DST_REG == PC)
lli_word(addr, srcword)
else
ll_word(addr, srcword);
return;
case 7:
not_impl();
}
illegal();
}
void
storep_dst(void)
{
u_int16_t addr, indirect;
switch (DST_MODE) {
case 0:
regs[DST_REG] = dstword;
return;
case 1:
addr = regs[DST_REG];
sl_word(addr, dstword);
return;
case 2:
addr = regs[DST_REG];
sl_word(addr, dstword);
regs[DST_REG] += 2;
return;
case 3:
indirect = regs[DST_REG];
ll_word(indirect, addr);
sl_word(addr, dstword);
regs[DST_REG] += 2;
return;
case 4:
regs[DST_REG] -= 2;
addr = regs[DST_REG];
sl_word(addr, dstword);
return;
case 5:
regs[DST_REG] -= 2;
indirect = regs[DST_REG];
ll_word(indirect, addr);
sl_word(addr, dstword);
return;
case 6:
lli_word(regs[PC], indirect);
regs[PC] += 2;
addr = regs[DST_REG] + indirect;
sl_word(addr, dstword);
return;
case 7:
not_impl();
}
illegal();
}
void
load_src(void)
{
u_int16_t addr, indirect;
switch (SRC_MODE) {
case 0:
srcword = regs[SRC_REG];
return;
case 1:
addr = regs[SRC_REG];
if (SRC_REG == PC) {
lli_word(addr, srcword)
} else {
ll_word(addr, srcword);
}
return;
case 2:
addr = regs[SRC_REG];
if (SRC_REG == PC) {
lli_word(addr, srcword)
} else {
ll_word(addr, srcword);
}
regs[SRC_REG] += 2;
return;
case 3:
indirect = regs[SRC_REG];
if (SRC_REG == PC) {
lli_word(indirect, addr)
} else {
ll_word(indirect, addr);
}
regs[SRC_REG] += 2; /* is this right ? */
ll_word(addr, srcword);
return;
case 4:
regs[SRC_REG] -= 2;
addr = regs[SRC_REG];
ll_word(addr, srcword);
return;
case 5:
regs[SRC_REG] -= 2;
indirect = regs[SRC_REG];
ll_word(indirect, addr);
ll_word(addr, srcword);
return;
case 6:
lli_word(regs[PC], indirect);
regs[PC] += 2;
addr = regs[SRC_REG] + indirect;
ll_word(addr, srcword);
return;
case 7:
lli_word(regs[PC], indirect);
regs[PC] += 2;
indirect = regs[SRC_REG] + indirect;
ll_word(indirect, addr);
ll_word(addr, srcword);
return;
}
illegal();
}
void
store_dst(void)
{
u_int16_t addr, indirect;
switch (DST_MODE) {
case 0:
regs[DST_REG] = dstword;
return;
case 1:
addr = regs[DST_REG];
sl_word(addr, dstword);
return;
case 2:
addr = regs[DST_REG];
sl_word(addr, dstword);
regs[DST_REG] += 2;
return;
case 3:
indirect = regs[DST_REG];
ll_word(indirect, addr);
regs[DST_REG] += 2; /* is this right ? */
sl_word(addr, dstword);
return;
case 4:
regs[DST_REG] -= 2;
addr = regs[DST_REG];
sl_word(addr, dstword);
return;
case 5:
regs[DST_REG] -= 2;
indirect = regs[DST_REG];
ll_word(indirect, addr);
sl_word(addr, dstword);
return;
case 6:
lli_word(regs[PC], indirect);
regs[PC] += 2;
addr = regs[DST_REG] + indirect;
sl_word(addr, dstword);
return;
case 7:
lli_word(regs[PC], indirect);
regs[PC] += 2;
indirect = regs[DST_REG] + indirect;
ll_word(indirect, addr);
sl_word(addr, dstword);
return;
}
illegal();
}
void
load_dst(void)
{
u_int16_t addr, indirect;
switch (DST_MODE) {
case 0:
dstword = regs[DST_REG];
return;
case 1:
addr = regs[DST_REG];
ea_addr = addr;
if (DST_REG == PC) {
lli_word(addr, dstword)
} else {
ll_word(addr, dstword);
}
return;
case 2:
addr = regs[DST_REG];
ea_addr = addr;
if (DST_REG == PC) {
lli_word(addr, dstword)
} else {
ll_word(addr, dstword);
}
regs[DST_REG] += 2;
return;
case 3:
indirect = regs[DST_REG];
if (DST_REG == PC) {
lli_word(indirect, addr)
} else {
ll_word(indirect, addr);
}
ea_addr = addr;
ll_word(addr, dstword);
regs[DST_REG] += 2;
return;
case 4:
regs[DST_REG] -= 2;
addr = regs[DST_REG];
ea_addr = addr;
ll_word(addr, dstword);
return;
case 5:
regs[DST_REG] -= 2;
indirect = regs[DST_REG];
ll_word(indirect, addr);
ea_addr = addr;
ll_word(addr, dstword);
return;
case 6:
lli_word(regs[PC], indirect);
regs[PC] += 2;
addr = regs[DST_REG] + indirect;
ea_addr = addr;
ll_word(addr, dstword);
return;
case 7:
lli_word(regs[PC], indirect);
regs[PC] += 2;
indirect = regs[DST_REG] + indirect;
ll_word(indirect, addr);
ea_addr = addr;
ll_word(addr, dstword);
return;
}
illegal();
}
INLINE void
store_dst_2(void)
{
if (DST_MODE == 0) {
regs[DST_REG] = dstword;
return;
}
sl_word(ea_addr, dstword);
}