upd7725 overflow (attn: byuu)
Moderator: Moderators
Forum rules
- For making cartridges of your Super NES games, see Reproduction.
Re: upd7725 overflow (attn: byuu)
So, the real way to rule all of this out for good ...
Lord Nightmare has a pile of uPD7720 chips unflashed. If we:
1) write a uPD7720 assembler,
2) write a test program in uPD7720 syntax to evaluate all input/output combinations of flags,
3) write an emulator for the 7720 (MAME's could work but it's an insane hack) to debug the test program,
Then Lord Nightmare could try to flash the program onto one of his chips. I'm not sure if he's capable of then putting it into a circuit design and sending / receiving values from the chip, but it's possible we can find someone else capable of doing so that would be up for the task.
Barring this, we're never really going to know for sure, with 100% confidence, how all of this works.
There's still the open question of how exactly S1 is modified on other ALU operations. Manual just says indeterminate, but there are several valid possibilities.
If someone is willing to do the other parts ... I'll volunteer to do part 1 and write a uPD7720 assembler. But you might not like the syntax I come up with ... and I'll be quite saddened if I do the work for nothing >_<
...
Also, here are the relevant sections from the manuals I have:
Lord Nightmare has a pile of uPD7720 chips unflashed. If we:
1) write a uPD7720 assembler,
2) write a test program in uPD7720 syntax to evaluate all input/output combinations of flags,
3) write an emulator for the 7720 (MAME's could work but it's an insane hack) to debug the test program,
Then Lord Nightmare could try to flash the program onto one of his chips. I'm not sure if he's capable of then putting it into a circuit design and sending / receiving values from the chip, but it's possible we can find someone else capable of doing so that would be up for the task.
Barring this, we're never really going to know for sure, with 100% confidence, how all of this works.
There's still the open question of how exactly S1 is modified on other ALU operations. Manual just says indeterminate, but there are several valid possibilities.
If someone is willing to do the other parts ... I'll volunteer to do part 1 and write a uPD7720 assembler. But you might not like the syntax I come up with ... and I'll be quite saddened if I do the work for nothing >_<
...
Also, here are the relevant sections from the manuals I have:
Re: upd7725 overflow (attn: byuu)
The manual is clear that the chip can distinguish between two overflows in the same direction (OV1 flag remains set) and two overflows in opposite directions (OV1 flag becomes clear). It has to be able to do so in order to produce the correct overflow state after three operations, as advertised. Your implementation doesn't do that.nocash wrote:PS. I think my implemention might have opposite S1 values (ie. 0=positive vs 1=positive), this works as long as SGN opcode is processing S1 accordingly.
Re: upd7725 overflow (attn: byuu)
Ah, yes, got it you are right. Two overflows in same direction won't work with my code.
Hmmm, web.archive is somehow overloading my PC (no chance to download the pdf files), but it does seem to have more/different files than datasheetarchive. Thanks for posting the relevant pages!
Hmmm, web.archive is somehow overloading my PC (no chance to download the pdf files), but it does seem to have more/different files than datasheetarchive. Thanks for posting the relevant pages!
Re: upd7725 overflow (attn: byuu)
Just noticed the question about multiply overflow in byuu's forum thread. 0x8000 * 0x8000 -> int31 is considered an "overflow" because the sign of the result is wrong. Multiplying two negative numbers should produce a positive result, but int31(0x40000000) is negative.
-
- Posts: 131
- Joined: Wed Apr 05, 2006 10:12 am
- Location: PA, USA
- Contact:
Re: upd7725 overflow (attn: byuu)
I'm trying to figure out in what circumstances the " if (!flag.ov1) flag.s1 = flag.s0;" should run.
In byuu's code in higan, it runs on OP opcodes, before ov1 is recalculated(which I believe is correct), it is updated on any add/sub/adc/sbb/inc/dec opcode(which I believe is correct), it is left alone on a nop(which I believe is correct), and not on an or/and/xor/cmp/shr1/shl1/shl2/shl4/xchg(which I'm not sure about). It also isn't updated on an RT/JMP opcode, nor on an LD opcode. (also not sure about these, guessing that it shouldn't be touched on RT/JMP, unsure about LD)
In MAME, I made it run for all OP alu types except for NOP(where it is left alone), and ov1 is only updated during add/sub/adc/sbb/inc/dec opcodes (ov1 is updated after ov0 is), and is explicitly cleared(along with ov0) on or/and/xor/cmp/shr1/shl1/shl2/shl4/xchg opcodes.
I'm not 100% sure which way is correct, given that branches can happen based on s1 and ov1 status.
LN
In byuu's code in higan, it runs on OP opcodes, before ov1 is recalculated(which I believe is correct), it is updated on any add/sub/adc/sbb/inc/dec opcode(which I believe is correct), it is left alone on a nop(which I believe is correct), and not on an or/and/xor/cmp/shr1/shl1/shl2/shl4/xchg(which I'm not sure about). It also isn't updated on an RT/JMP opcode, nor on an LD opcode. (also not sure about these, guessing that it shouldn't be touched on RT/JMP, unsure about LD)
In MAME, I made it run for all OP alu types except for NOP(where it is left alone), and ov1 is only updated during add/sub/adc/sbb/inc/dec opcodes (ov1 is updated after ov0 is), and is explicitly cleared(along with ov0) on or/and/xor/cmp/shr1/shl1/shl2/shl4/xchg opcodes.
I'm not 100% sure which way is correct, given that branches can happen based on s1 and ov1 status.
LN
"When life gives you zombies... *CHA-CHIK!* ...you make zombie-ade!"
Re: upd7725 overflow (attn: byuu)
You're guessing no matter what you do with the other ALU ops.
I'm willing to match your behavior, but I worry that people might see it in the future and think that's definitely how it works, when in truth we have no idea. Needs a clear source code comment that we're guessing, even if it is the most logical conclusion to us.
I'm willing to match your behavior, but I worry that people might see it in the future and think that's definitely how it works, when in truth we have no idea. Needs a clear source code comment that we're guessing, even if it is the most logical conclusion to us.
Re: upd7725 overflow (attn: byuu)
Well, I wrote a program that should allow you to test any sequence of ALU operations you want, if someone wants to figure out how to assemble, burn and test it (don't forget the screwy bit order the '7720 needs for its program ROM) The command protocol is heavily based on the DSP-1, including the need to input a dummy operand for no-operand commands. It doesn't use serial I/O, DMA, or anything else fancy. It also doesn't use the data ROM at all.
Protocol:
Wait for RQM to go high, write 8 bit opcode/carry selector:
Wait for RQM to go high, write 16-bit right-side operand (LSB first). You have to do this even for unary opcodes like the shifts (the operand value is ignored).
Wait for RQM to go high, read 16-bit result (value in accumulator A after executing opcode).
Wait for RQM to go high, read 8-bit flags as follows:
Accumulator A and its flags (should be) preserved between operations, i.e. you should be able to do a sequence of additions/subtractions and look at the flags after each step.
Someone should eyeball my code before using up rare chips, especially the rats' nest of branches that is the command decoding (also based on the DSP1 code--and there really isn't any better way to do it as far as I can tell)
Protocol:
Wait for RQM to go high, write 8 bit opcode/carry selector:
Code: Select all
000CPPPP
000 = must be zero
C = incoming carry B flag
PPPP = opcode (same order as native instruction encoding--0001 is OR, etc.)
Wait for RQM to go high, read 16-bit result (value in accumulator A after executing opcode).
Wait for RQM to go high, read 8-bit flags as follows:
Code: Select all
11SsczVv
11 = always 1
S = SA1
s = SA0
c = CA
z = ZA
V = OVA1
v = OVA0
Code: Select all
: ld 0400,sr ; 8-bit
: ld 00c0,dr
; === main loop ===
loop : ld 00e0,b
: jrqm * ; wait for (8-bit) read or write (read flags or write opcode)
: mov dr,tr | and dr,b ; get opcode and carry-in
: jnzb loop
; === decode opcode ===
: ld 0000,sr ; 16-bit
: or tr,b
: jrqm * ; wait for (16-bit) write (operand)
: mov drnf,tr | shr1 b ; get operand
: jcb opxxx1
opxxx0 : shr1 b
: jcb opxx10
opxx00 : shr1 b
: jcb opx100
opx000 : shr1 b
: jncb afterop ; 0000 = nop
: jcb op1000
opx100 : shr1 b
: jncb op0100
: jcb op1100
opxx10 : shr1 b
: jcb opx110
opx010 : shr1 b
: jncb op0010
: jcb op1010
opx110 : shr1 b
: jncb op0110
: jcb op1110
opxxx1 : shr1 b
: jcb opxx11
opxx01 : shr1 b
: jcb opx101
opx001 : shr1 b
: jncb op0001
: jcb op1001
opx101 : shr1 b
: jncb op0101
: jcb op1101
opxx11 : shr1 b
: jcb opx111
opx011 : shr1 b
: jncb op0011
: jcb op1011
opx111 : shr1 b
: jncb op0111
: jcb op1111
; === execute opcode ===
op0001 : shr1 b
: or tr,a
: jmp afterop
op0010 : shr1 b
: and tr,a
: jmp afterop
op0011 : shr1 b
: xor tr,a
: jmp afterop
op0100 : shr1 b
: sub tr,a
: jmp afterop
op0101 : shr1 b
: add tr,a
: jmp afterop
op0110 : shr1 b
: sbb tr,a
: jmp afterop
op0111 : shr1 b
: adc tr,a
: jmp afterop
op1000 : shr1 b
: dec a
: jmp afterop
op1001 : shr1 b
: inc a
: jmp afterop
op1010 : shr1 b
: cmp a
: jmp afterop
op1011 : shr1 b
: shr1 a
: jmp afterop
op1100 : shr1 b
: shl1 a
: jmp afterop
op1101 : shr1 b
: shl2 a
: jmp afterop
op1110 : shr1 b
: shl4 a
: jmp afterop
op1111 : shr1 b
: xchg a
; === output result and flags ===
afterop: mov a,dr ; send result
: ld 00c0,b
: jnsa1 nosa1
: ld 0020,tr
: or tr,b
nosa1 : jnsa0 nosa0
: ld 0010,tr
: or tr,b
nosa0 : jnca noca
: ld 0008,tr
: or tr,b
noca : jnza noza
: ld 0004,tr
: or tr,b
noza : jnova1 noova1
: ld 0002,tr
: or tr,b
noova1 : jnova0 noova0
: ld 0001,tr
: or tr,b
noova0 : jrqm * ; wait for (16-bit) read (result)
: ld 0400,sr ; 8-bit
: mov b,dr ; send flags
: jmp loop ; back to the top
The docs say that S1 is "indeterminate" after any ALU operation other than addition/subtraction or NOP. LD and JMP instructions definitely shouldn't affect any flags at all (there's no accumulator/flag select field in those instructions, and somewhere one of the docs explicitly clarifies that loading a value into one of the accumulators via MOV or LD doesn't update its sign or zero flags)I'm trying to figure out in what circumstances the " if (!flag.ov1) flag.s1 = flag.s0;" should run.
Re: upd7725 overflow (attn: byuu)
Any test program should be debugged thoroughly with an emulator before being burned.
These chips are exceedingly rare.
These chips are exceedingly rare.
-
- Posts: 131
- Joined: Wed Apr 05, 2006 10:12 am
- Location: PA, USA
- Contact:
Re: upd7725 overflow (attn: byuu)
The 10 blank upd77P20s I have have windows; if I run out, I can always uv-erase them and try again, I think they're good for 100+ prog/erase cycles at least.
What I don't have (and I wish I did) are blank upd77P25D chips with windows; those are significantly rarer.
EDIT: There is actually someone selling pulled upd77P25D chips, from china, on ebay. Whether these are 'real' or remarked something else, I don't know. They're about $5 each + $6shipping even for more than one, and there's 50+ available. I ordered two of them, since for $16 its worth a shot at them being real.
LN
What I don't have (and I wish I did) are blank upd77P25D chips with windows; those are significantly rarer.
EDIT: There is actually someone selling pulled upd77P25D chips, from china, on ebay. Whether these are 'real' or remarked something else, I don't know. They're about $5 each + $6shipping even for more than one, and there's 50+ available. I ordered two of them, since for $16 its worth a shot at them being real.
LN
"When life gives you zombies... *CHA-CHIK!* ...you make zombie-ade!"
Re: upd7725 overflow (attn: byuu)
The 7720 and 7725 appear to be pin-compatible, except that the EPROM versions of both require power on pin 1. I wonder if you could put a programmed 7720 onto a suitable SNES cartridge for software testing, rather than have to use an Arduino or something.