1
0

backlog of changes from the uconsole

This commit is contained in:
dtb
2025-03-07 05:36:27 -07:00
parent 55bb27a1de
commit 9846c7ad27
50 changed files with 1207 additions and 726 deletions

View File

@@ -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);
}