Skip to content

Commit

Permalink
fixed div bug
Browse files Browse the repository at this point in the history
added chaosnet support
  • Loading branch information
lisper committed Oct 21, 2004
1 parent 6b4ab9d commit 3b19edb
Show file tree
Hide file tree
Showing 6 changed files with 161 additions and 259 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# $Id$
#

USIM_SRC = main.c decode.c ucode.c disk.c iob.c syms.c config.c sdl.c
USIM_SRC = main.c decode.c ucode.c disk.c iob.c chaos.c syms.c config.c sdl.c
USIM_HDR = ucode.h config.h

USIM_LIBS = -lSDL -lpthread
Expand Down
12 changes: 6 additions & 6 deletions README
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
CADR simulator
10/19/04
10/21/04
Brad Parker
[email protected]

Expand Down Expand Up @@ -61,18 +61,18 @@ There are some hacks for noticing unibus access but no xbus/unibus
mapping support. The two machine lash-up/debug interface is not (yet)
supported. I want to add this, however.

I believe the divide code is still broken and needs to be fixed. I
put in a hack which aborts the last step and now it seems ok, but I
think something is wrong with my emulation of the h/w.
I finally fixed the divide code. Naturally the Q shift and the ALU
shift (with a bit conditional on the Q sign) happen at the same time
in the hardware (but not in the C code :-).

There's a long delay when booting, even though the world is running
and system-x works fine. I need to track this down - possibly waiting
for a time packet?
for a time packet? The system is available right away, however, try
"F2-p".

What needs to be done?
----------------------

- fix the divide code
- cleanup keyboard emulation
- cleanup mouse emulation
- cleanup chaosnet emulation
Expand Down
112 changes: 90 additions & 22 deletions div.c
Original file line number Diff line number Diff line change
@@ -1,82 +1,150 @@
/*
;;; DIVIDE SUBROUTINE
; DIVIDEND IN M-1, DIVISOR IN M-2
; QUOTIENT IN Q-R, REMAINDER IN M-1, CLOBBERS A-TEM1
DIV (JUMP-GREATER-OR-EQUAL-XCT-NEXT M-1 A-ZERO DIV1)
((A-TEM1 Q-R) M-1) ;Q GETS MAGNITUDE OF DIVIDEND, A-TEM1 SAVES ORIGINAL
((Q-R) SUB M-ZERO A-TEM1)
DIV1 ((M-1) DIVIDE-FIRST-STEP M-ZERO A-2)
DIV1A (CALL-IF-BIT-SET (BYTE-FIELD 1 0) Q-R TRAP) ;DIVIDE OVERFLOW
(REPEAT 31. ((M-1) DIVIDE-STEP M-1 A-2))
((M-1) DIVIDE-LAST-STEP M-1 A-2)
(JUMP-LESS-OR-EQUAL-XCT-NEXT M-ZERO A-TEM1 DIV2) ;JUMP IF POSITIVE DIVIDEND
((M-1) DIVIDE-REMAINDER-CORRECTION-STEP M-1 A-2) ;M-1 GETS MAGNITUDE OF REMAINDER
((M-1) SUB M-ZERO A-1) ;NEGATIVE DIVIDEND => NEGATIVE REMAINDER
DIV2 ((A-TEM1) XOR M-2 A-TEM1) ;IF SIGNS OF DIVIDEND AND DIVISOR ARE DIFFERENT,
(POPJ-LESS-OR-EQUAL M-ZERO A-TEM1)
(POPJ-AFTER-NEXT
(A-TEM1) Q-R)
((Q-R) SUB M-ZERO A-TEM1) ;THEN QUOTIENT IS NEGATIVE
*/

/*
* unsigned divide simulation; based on CADR h/w & microcode
*/

int show = 1;

void ud(unsigned int dividend,
unsigned int divisor,
unsigned int *pquotient,
unsigned int *premainder )
{
int q, m, a, alu;
unsigned int q, m, a, alu, old_q;
int i;
int do_sub, do_add;
int negq, nega;

q = dividend;
a = divisor;
m = 0;
negq = 0;
nega = 0;

printf("(/ 0x%x (%o) 0x%x (%o) ); ", q, q, a, a);

if ((int)q < 0) {
q = -(int)q;
negq = 1;
}

if ((int)a < 0) {
nega = 1;
}

if (show) printf("\n");

alu = m - a;

old_q = q;
q <<= 1;
if ((alu & 0x80000000) == 0)
q |= 1;
m = (alu << 1) | ((q & 0x80000000) ? 1 : 0);
// m = (alu << 1) | ((q & 0x80000000) ? 1 : 0);
m = (alu << 1) | ((old_q & 0x80000000) ? 1 : 0);

for (i = 0; i < 32; i++) {

do_sub = q & 1;
if (0)
printf("loop %d, m %08x alu %08x, q %08x, do_sub %d\n",
i, m, alu, q, do_sub);

if (show)
printf("loop %d, m %08x (%o) alu %08x (%o), q %08x (%o), do_sub %d\n",
i, m, m, alu, alu, q, q, do_sub);

if (do_sub) {
alu = m - a;
} else {
alu = m + a;
}

old_q = q;
q <<= 1;
if ((alu & 0x80000000) == 0)
q |= 1;

if (i < 31)
m = (alu << 1) | ((q & 0x80000000) ? 1 : 0);
// m = (alu << 1) | ((q & 0x80000000) ? 1 : 0);
m = (alu << 1) | ((old_q & 0x80000000) ? 1 : 0);
else
m = alu;
}

do_sub = q & 1;
if (0)
printf("remainder; alu %08x, q %08x, do_sub %d\n", alu, q, do_sub);

if (nega)
do_sub = !do_sub;

if (show)
printf("remainder; m %08x, alu %08x, q %08x, do_sub %d\n", m, alu, q, do_sub);

if (do_sub) {
// alu = alu;
alu = m;
/* setm */
printf("setm; ");
} else {
// alu = alu + a;
alu = m + a;
}

// alu >>= 1;
// q >>= 1;
if (negq ^ nega) {
printf("diff; ");
q = -(int)q;
}

printf("done; alu %08x, q %08x (%d,%o)\n", alu, q, q, q);
printf("done; alu %08x (%o), q %08x (%o) (%d,%d)\n", alu, alu, q, q, alu, q);
}


main()
{
unsigned int q, r;

// unsigned_divide(0, 3, &q, &r);
// unsigned_divide(4, 2, &q, &r);
// ud(4, 2, &q, &r);
show = 0;
ud(4, 2, &q, &r);
#if 1
ud(10, 3, &q, &r);

ud(8, 2, &q, &r);
// ud(10, 5, &q, &r);
// ud(10, 3, &q, &r);
ud(100, 3, &q, &r);
// ud(021, 0503, &q, &r);
// ud(0136, 021, &q, &r);

ud(10, 5, &q, &r);

// ud(100, 3, &q, &r);

// ud(0503, 021, &q, &r);
ud(06434, 0503, &q, &r);
ud(0136, 021, &q, &r);

ud(0142, 021, &q, &r);

ud(0x7fffffff, 02, &q, &r);
ud(-1, 2, &q, &r);

ud(-6, 2, &q, &r);
// show=1;
ud(-6, -2, &q, &r);
ud(6, 2, &q, &r);
#endif

#if 0
int i;
Expand Down
Loading

0 comments on commit 3b19edb

Please sign in to comment.