teamtempest wrote:
Quote:
BLT - Branch Less Than (C=0 or Z=1)
BGT - Branch Greater Than (C=1 and Z=0)
Signed or unsigned comparison? As things stand now signed comparisons are always a tricky thing on the 6502. You have to use that mysterious V-flag if you want to do signed. It's difficult enough to grasp what's going on that a lot of people stay away from it. Perhaps explicitly signed comparison, subtraction and addition instruction branch instrctions would be helpful as well.
Unsigned. I had noticed that I had sequences of Branches to do just that, branch on greater (where BCS is basically greater or equal) or branch on less or equal (where BCC is basically branch on less).
Forgive my ignorance, but isn't signed the same as unsigned, as long as V is NOT set?
Quote:
Quote:
SWP - swap upper and lower nibble
This would be extremely handy. This might be the best addition of them all.
As has been asked in another post in this thread, yes, that exchanges the two nibbles in a single byte. Due to the extended nature of my 65k, of course there are SWP.W to exchange the bytes in a word, SWP.L to exchange the WORDs in a LONG, and SWP.Q to exchange the LONGs in a QUAD (64 bit).
Quote:
Quote:
INV - two's complement
I dunno. It's easy enough already to do "EOR #$FF". I don't know that I want to do this often enough to make it worthwhile as a separate instruction. Is there some address mode other than accumulator where this is useful?
"EOR #$FF" is the one's complement, not the two's complement. I made this to easily do a reverse substraction as mentioned in another post here. But in fact, replacing
Code:
EOR #$FF
SEC
ADC value
with
Code:
INV A
CLC
ADC value
does not help much - I should probably investigate the reverse substract as well (in addition to ADD and SUB that don't use the carry)
Quote:
Quote:
BCN - bit count, compute number of 1-bits
This would take a (very) short routine to duplicate, and the answer would come in log(N) time. Or a big lookup table and constant time. Is there enough need to make it a separate instruction? I can see that it would be handy if you wanted to do parity checks, but beyond that I'm stumped. If parity is all it's good for, why not just a parity status flag?
Parity flag is a good point. I currently just don't have a status register bit left... My 65k can have up to 64 bit values - the routine would still be very short, but log(64) is still getting larger, so I thought it in order to do this.
Quote:
Quote:
PSH - push all registers (in a 6502 that would be AC, XR, YR, more in a 65002)
PLL - pull all registers (in a 6502 that would be AC, XR, YR, more in a 65002)
So the other day I was thinking "What if each register had its own dedicated on-chip stack space?" Ie, N registers, N stacks And then I thought "What would that possibly be good for?" And then I thought "Interrupts!". I was thinking the processor would do it automatically upon recognizing an interrupt, so an ISR could start out trashing any register it wanted. RTI would restore them all. If each stack was 8- or 16-deep, you could even deal with re-entrant interrupts. The stacks would not be user-accessible, just places to stash register values during interrupts.
But an instruction to do it would be just as useful. The idea of multiple dedicated stacks would of course be to minimize response time to an interrupt. I don't think these would be as useful for calling subroutines, mainly because of the difficulty of returning results in registers (if the callee did PSH at the start then PLL at the end would trash anything you put in them...unless maybe the caller did PSH? Then after the callee returns, save any results passed in registers before the caller does PLL...might work. Okay, I like it)
a per-register stack is a neat idea, but what do you do if it overflows?
I though doing these opcodes to make model/family-independent interrupt routines. A later 650x0 could have more registers, and this PLL/PSH would simply be extended to pull/push them from/onto the stack.
This would not necessarily be used for calling subroutines - here I would use the registers for parameters and return values anyway, and selectively save those on the stack that are needed.
Quote:
Quote:
FIL - fill a memory area with a byte value
Again a short subroutine. Is the speed advantage (one or two cycles per byte?) worth it?
I don't intend to make it as inefficient as the 65816 one. I was more thinking of one cycle per byte (or even less with a wider memory interface).
Quote:
Quote:
ADS - add value to stack pointer
SBS - substract value from stack pointer
Fun. I like these, although playing with stack pointer is not for novices.
No, but those can be used for handling pointers to parameters on the stack.
Quote:
Quote:
MVN/MVP - move a memory area (see 65816)
I never liked this instruction much. Kind of ugly. The coolest answer to this in the 6502 world I ever saw were the Commodore RAM expanders. That REC chip could do transfers and fills at a byte per clock cycle, and swap two bytes in two clock cycles.
I wonder how that would work, swap two bytes in two clock cycles. I can only see this with two memory banks read in parallel and written back in parallel.
Anyway, the plan is to have two cycles per byte maximum (maybe less with wider memory interfaces)
Quote:
Quote:
HBS - determine bit number of highest bit that is set (like log2)
HBC - determine bit number of highest bit that is clear
BSW - bit swap - exchange bit 7 with bit 0, bit 6 with bit 1, etc
How is the result returned, BTW? What if no bit is set? If bits are numbered 7..0 then zero is not an answer to that. I guess I'm having trouble seeing how useful they'd be, ie., what problem do they solve?
Admittedly HBS/HBC are "imagined", but could possibly come in handy to shorten an integer multiply/division routine.
BSW I would find useful for computing the swapped addresses in a fast fourier transform (although then it would probably better be used on an index register).
Those would either be read memory -> do operation -> store in AC, or AC -> operation -> AC. Don't think a R/M/W would be useful here though.
If no bit is set/cleared on HBS/HBC respectively, the carry bit could be set for example. Haven't thought about that yet I have to admit.
André