Category : Assembly Language Source Code
Archive   : 68XASM.ZIP
Filename : CODE1.C

 
Output of file : CODE1.C contained in archive : 68XASM.ZIP

/***************************** 68000 SIMULATOR ****************************

File Name: CODE1.C
Version: 1.0

The instructions implemented in this file are the MOVE instructions:

MOVE, MOVEP, MOVEA, MOVE_FR_SR, MOVE_TO_CCR, MOVE_TO_SR, MOVEM,
MOVE_USP, MOVEQ


***************************************************************************/



#include
#include "extern.h" /* contains global "extern" declarations */


/* the following two arrays specify the execution times of the MOVE
instruction, for byte/word operands and for long operands */

int move_bw_times [12][9] = {
4, 4, 8, 8, 8, 12, 14, 12, 16 ,
4, 4, 8, 8, 8, 12, 14, 12, 16 ,
8, 8, 12, 12, 12, 16, 18, 16, 20 ,
8, 8, 12, 12, 12, 16, 18, 16, 20 ,
10, 10, 14, 14, 14, 18, 20, 18, 22 ,
12, 12, 16, 16, 16, 20, 22, 20, 24 ,
14, 14, 18, 18, 18, 22, 24, 22, 26 ,
12, 12, 16, 16, 16, 20, 22, 20, 24 ,
16, 16, 20, 20, 20, 24, 26, 24, 28 ,
12, 12, 16, 16, 16, 20, 22, 20, 24 ,
14, 14, 18, 18, 18, 22, 24, 22, 26 ,
8, 8, 12, 12, 12, 16, 18, 16, 20 };


int move_l_times [12][9] = {
4, 4, 12, 12, 12, 16, 18, 16, 20 ,
4, 4, 12, 12, 12, 16, 18, 16, 20 ,
12, 12, 20, 20, 20, 24, 26, 24, 28 ,
12, 12, 20, 20, 20, 24, 26, 24, 28 ,
14, 14, 22, 22, 22, 26, 28, 26, 30 ,
16, 16, 24, 24, 24, 28, 30, 28, 32 ,
18, 18, 26, 26, 26, 30, 32, 30, 34 ,
16, 16, 24, 24, 24, 28, 30, 28, 32 ,
20, 20, 28, 28, 28, 32, 34, 32, 36 ,
16, 16, 24, 24, 24, 28, 30, 28, 32 ,
18, 18, 26, 26, 26, 30, 32, 30, 34 ,
12, 12, 20, 20, 20, 24, 26, 24, 28 };


/* the following two arrays specify the instruction execution times
for the MOVEM instruction for memory-to-reg and reg-to-memory cases */

int movem_t_r_times[11] = {
0, 0, 12, 12, 0, 16, 18, 16, 20, 16, 18 };

int mover_t_m_times[11] = {
0, 0, 8, 0, 8, 12, 14, 12, 16, 0, 0 };



int MOVE()
{
long size; /* 'size' holds the instruction size */
int src, dst; /* 'src' and 'dst' hold the addressing mode codes */
/* for instruction execution time computation */

/* MOVE has a different format for size field than all other instructions */
/* so we can't use the 'decode_size' function */
switch ( (inst >> 12) & 0x03)
{
case 0x01 : size = BYTE; /* bit pattern '01' */
break;
case 0x03 : size = WORD; /* bit pattern '10' */
break;
case 0x02 : size = LONG; /* bit pattern '11' */
break;
default : return (BAD_INST); /* bad size field */
break;
}

/* the following gets the effective addresses for the source and destination
operands */
if ( (eff_addr (size, ALL_ADDR, FALSE)) ||
(eff_addr (size, DATA_ALT_ADDR, FALSE)) )
return (BAD_INST); /* if bad address format then return */
/* the code for 'bad instruction' */

dest = EV2; /* set 'dest' for use in 'cc_update' */

put (EA2, EV1, size); /* perform the move to '*EA2' */
value_of (EA2, &EV2, size); /* set 'EV2' for use in 'cc_update' */

src = eff_addr_code(inst,0); /* get the addressing mode codes */
dst = eff_addr_code(inst,6);

if (size == LONG) /* use the codes in instruction time computation */
inc_cyc (move_l_times [src] [dst]);
else
inc_cyc (move_bw_times [src] [dst]);

/* now update the condition codes */
cc_update (N_A, GEN, GEN, ZER, ZER, EV1, dest, EV2, size, 0);

/* return the value for 'success' */
return SUCCESS;

}



int MOVEP()
{
int address, Dx, disp, count, direction, reg;
long temp, size;

mem_request (&PC, (long) WORD, &temp);
from_2s_comp (temp, (long) WORD, &temp);

address = A[a_reg(inst&0x07)] + (temp & WORD);

direction = inst & 0x80;

if (inst & 0x40)
{
size = LONG;
count = 4;
}
else
{
size = WORD;
count = 2;
}

reg = (inst >> 9) & 0x07;
Dx = D[reg] & size;

for (;count > 0; count--)
{
disp = 8 * (count - 1);
if (direction)
mem_put ( (long)((Dx >> disp) & BYTE) , address, (long) BYTE);
else
{
mem_req (address, (long) BYTE, &temp);
switch (count) {
case 4 : D[reg] = (D[reg] & 0x00ffffff) | (temp * 0x1000000);
break;
case 3 : D[reg] = (D[reg] & 0xff00ffff) | (temp * 0x10000);
break;
case 2 : D[reg] = (D[reg] & 0xffff00ff) | (temp * 0x100);
break;
case 1 : D[reg] = (D[reg] & 0xffffff00) | (temp);
break;
}
}
address += 2;
}


inc_cyc ( (size == LONG) ? 24 : 16);

return SUCCESS;

}



int MOVEA()
{
long size;
int src;

if (inst & 0x1000)
size = WORD;
else
size = LONG;

src = eff_addr_code(inst,0);
if (size == WORD)
inc_cyc (move_bw_times[src][2]);
else
inc_cyc (move_l_times[src][2]);

if (eff_addr(size, ALL_ADDR, FALSE))
return (BAD_INST);

if (size == WORD)
sign_extend ((int)EV1, (long) WORD, &EV1);

A[a_reg((inst >> 9) & 0x07)] = EV1;

return SUCCESS;

}



int MOVE_FR_SR()
{

if (eff_addr ((long) WORD, DATA_ALT_ADDR, TRUE))
return (BAD_INST);

put (EA1, (long) SR, (long) WORD);

inc_cyc ((inst & 0x0030) ? 8 : 6);

return SUCCESS;

}



int MOVE_TO_CCR()
{

if (eff_addr ((long) WORD, DATA_ADDR, TRUE))
return (BAD_INST);

put (&SR, EV1, (long) BYTE);

inc_cyc (12);

return SUCCESS;

}



int MOVE_TO_SR()
{

if (! (SR & sbit))
return (NO_PRIVILEGE);

if (eff_addr ((long) WORD, DATA_ADDR, TRUE))
return (BAD_INST);

put (&SR, EV1, (long) WORD);

inc_cyc (12);

return SUCCESS;

}



int MOVEM()
{
int direction, addr_modes_mask, counter, addr_mode;
int displacement, address, total_displacement;
long size, mask_list, temp;

mem_request (&PC, (long) WORD, &mask_list);

if (inst & 0x0040)
size = LONG;
else
size = WORD;

if (direction = (inst & 0x0400))
addr_modes_mask = CONTROL_ADDR | bit_4;
else
addr_modes_mask = CONT_ALT_ADDR | bit_5;

if (eff_addr (size, addr_modes_mask, FALSE))
return (BAD_INST); /* bad effective address */

address = (long) ( (long)EA1 - (long)&memory[0]);
total_displacement = address;

if ((inst & 0x0038) != 0x20)
{
if (size == WORD)
displacement = 2;
else
displacement = 4;
}
else
{
if (size == WORD)
displacement = -2;
else
displacement = -4;
}

addr_mode = eff_addr_code (inst,0);

if (direction)
inc_cyc (movem_t_r_times[addr_mode]); /* memory to registers */
else
inc_cyc (mover_t_m_times[addr_mode]); /* registers to memory */

for (counter = 0; counter < 16; counter++)
if (mask_list & (1 << counter))
{
if (size == LONG)
inc_cyc (8);
else
inc_cyc (4);
if (direction)
{
if (size == WORD) /* if size is WORD then sign-extend */
{
mem_req (address, (long) WORD, &temp);
sign_extend ((int) temp, LONG, &temp);
}
if (counter < 8)
D[counter] = temp;
else
A[a_reg(counter - 8)] = temp;
}
else
{
if ((inst & 0x38) == 0x20)
{
if (counter < 8)
mem_put (A[a_reg(7 - counter)], address, size);
else
mem_put (D[15 - counter], address, size);
}
else
{
if (counter < 8)
mem_put (D[counter], address, size);
else
mem_put (A[a_reg(counter - 8)], address, size);
}
}
address += displacement;
}
address -= displacement;
total_displacement = address - total_displacement;

/* if pre-decrement or post-increment modes then change the value */
/* of the address register appropriately */
if ( ((inst & 0x38) == 0x20) || ( (inst & 0x38) == 0x18) )
A[a_reg(inst & 0x7)] += total_displacement;

return SUCCESS;

}



int MOVE_USP()
{
int reg;

if (!(SR & sbit))
return (NO_PRIVILEGE); /* supervisor state not on */

reg = inst & 0x7;
if (reg == 7)
reg = 8;

if (inst & 0x8)
A[reg] = A[7];
else
A[7] = A[reg];

inc_cyc (4);

return SUCCESS;

}



int MOVEQ()
{
int reg;

reg = (inst >> 9) & 0x7;
source = inst & 0xff;
dest = D[reg];

/* the data register is sign extended to a longword */
sign_extend ((int)source, (long) BYTE, &D[reg]);
sign_extend ((int)D[reg], (long) WORD, &D[reg]);

cc_update (N_A, GEN, GEN, ZER, ZER, source, dest, D[reg], LONG, 0);
inc_cyc (4);
return SUCCESS;

}



  3 Responses to “Category : Assembly Language Source Code
Archive   : 68XASM.ZIP
Filename : CODE1.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/