backlog of changes from the uconsole
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
* nybbles 4--|4--|4--|4--|4--|4--|
|
||||
* bits 111111111111111111111111 */
|
||||
|
||||
#include <complex.h>
|
||||
#if __STDC_VERSION__ >= 199901L
|
||||
/* C99 type definitions */
|
||||
# include <stdint.h>
|
||||
@@ -42,6 +43,7 @@ struct Intel4004_State {
|
||||
Nybble acc; /* Accumulator */
|
||||
Nybble reg[16]; /* R0 through RF */
|
||||
Word pc[4]; /* PC0 through PC3 */
|
||||
Word *cc; /* Current PC */
|
||||
Byte *rom;
|
||||
Byte *ram;
|
||||
};
|
||||
@@ -117,11 +119,38 @@ enum Intel4004_Instruction {
|
||||
/* INVALID 0xFF 0b 1111 1111 */
|
||||
};
|
||||
|
||||
#define INTEL4004_THIS_OP (state->rom[*state->cc])
|
||||
#define INTEL4004_NEXT_OP (state->rom[*state->cc + 1])
|
||||
#define INTEL4004_INC_OP do{ ++*state->cc; }while(0)
|
||||
#define INTEL4004_INC2_OP do{ *state->cc += 2; }while(0)
|
||||
|
||||
/* <http://e4004.szyc.org/>-style naming */
|
||||
#define INTEL4004_PL (*state->cc & 0x00F)
|
||||
#define INTEL4004_PM ((*state->cc & 0x0F0) >> 4)
|
||||
#define INTEL4004_PH ((*state->cc & 0xF00) >> 8)
|
||||
|
||||
/* Also see the Intel MCS-4 Assembly Language Programming Manual (1973). */
|
||||
|
||||
/* From the datasheet. */
|
||||
void Intel4004_RESET(struct Intel4004_State *state){
|
||||
Nybble i;
|
||||
|
||||
state->carry = 0;
|
||||
state->test = 0;
|
||||
state->acc = 0;
|
||||
for(i = 0; i <= (sizeof state->reg) / (sizeof *state->reg); ++i)
|
||||
state->reg[i] = 0;
|
||||
for(i = 0; i <= (sizeof state->pc) / (sizeof *state->pc); ++i)
|
||||
state->pc[i] = 0;
|
||||
state->cc = &state->pc[0];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Does nothing. */
|
||||
void Intel4004_NOP(struct Intel4004_State *state){ /* 0b 0000 0000 */
|
||||
|
||||
++*state->pc;
|
||||
|
||||
INTEL4004_INC_OP;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -141,16 +170,16 @@ void Intel4004_NOP(struct Intel4004_State *state){ /* 0b 0000 0000 */
|
||||
* If *state->pc & 0x08, a one test flag satisfies the condition. */
|
||||
void Intel4004_JCN(struct Intel4004_State *state){ /* 0b 0001 CCCC */
|
||||
|
||||
*state->pc =
|
||||
!INTEL4004_JCN_COND_ISINVERT(state->rom[*state->pc])
|
||||
&& ( (INTEL4004_JCN_COND_ISACCZERO(state->rom[*state->pc])
|
||||
*state->cc =
|
||||
!INTEL4004_JCN_COND_ISINVERT(INTEL4004_THIS_OP)
|
||||
&& ( (INTEL4004_JCN_COND_ISACCZERO(INTEL4004_THIS_OP)
|
||||
&& state->acc == 0)
|
||||
|| (INTEL4004_JCN_COND_ISCARRYON(state->rom[*state->pc])
|
||||
|| (INTEL4004_JCN_COND_ISCARRYON(INTEL4004_THIS_OP)
|
||||
&& state->carry == 1)
|
||||
|| (INTEL4004_JCN_COND_ISTESTON(state->rom[*state->pc])
|
||||
|| (INTEL4004_JCN_COND_ISTESTON(INTEL4004_THIS_OP)
|
||||
&& state->test == 1))
|
||||
? state->rom[*state->pc + 1]
|
||||
: *state->pc + 2;
|
||||
? state->rom[*state->cc + 1]
|
||||
: *state->cc + 2;
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -166,14 +195,13 @@ void Intel4004_JCN(struct Intel4004_State *state){ /* 0b 0001 CCCC */
|
||||
/* Fetches an immediate byte from ROM. */
|
||||
void Intel4004_FIM(struct Intel4004_State *state){ /* 0b 0010 RRR0 */
|
||||
|
||||
state->reg[INTEL4004_REGPAIR(state->rom[*state->pc])]
|
||||
= HIGH_NYBBLE(state->rom[*state->pc + 1]);
|
||||
state->reg[INTEL4004_REGPAIR(INTEL4004_THIS_OP)]
|
||||
= HIGH_NYBBLE(INTEL4004_NEXT_OP);
|
||||
|
||||
state->reg[INTEL4004_REGPAIR(state->rom[*state->pc]) + 1]
|
||||
= LOW_NYBBLE(state->rom[*state->pc + 1]);
|
||||
|
||||
*state->pc += 2;
|
||||
state->reg[INTEL4004_REGPAIR(INTEL4004_THIS_OP) + 1]
|
||||
= LOW_NYBBLE(INTEL4004_NEXT_OP);
|
||||
|
||||
INTEL4004_INC2_OP;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -182,3 +210,37 @@ void Intel4004_SRC(struct Intel4004_State *state){ /* 0b 0010 RRR1 */
|
||||
|
||||
void Intel4004_FIN(struct Intel4004_State *state){ /* 0b 0011 RRR0 */
|
||||
}
|
||||
|
||||
/* Loads the immediate value in the low nybble of the opcode into the
|
||||
* accumulator. */
|
||||
void Intel4004_LDM(struct Intel4004_State *state){ /* 0b 1101 DDDD */
|
||||
|
||||
state->acc = LOW_NYBBLE(INTEL4004_THIS_OP);
|
||||
|
||||
INTEL4004_INC_OP;
|
||||
return;
|
||||
}
|
||||
|
||||
void Intel4004_BBL(struct Intel4004_State *state){ /* 0b 1100 DDDD */
|
||||
/* <http://e4004.szyc.org/> lists 0b 1100 RRRR, most likely as a typo. I found
|
||||
* 0b 1100 DDDD on the Intel 4004 datasheet. */
|
||||
|
||||
return Intel4004_LDM(state);
|
||||
}
|
||||
|
||||
/* Clears the carry bit. */
|
||||
void Intel4004_CLC(struct Intel4004_State *state){ /* 0b 1111 0001 */
|
||||
|
||||
state->carry = 0;
|
||||
|
||||
INTEL4004_INC_OP;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Clears both the accumulator and the carry bit. */
|
||||
void Intel4004_CLB(struct Intel4004_State *state){ /* 0b 1111 0000 */
|
||||
|
||||
state->acc = 0;
|
||||
|
||||
return Intel4004_CLC(state);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user