GARTHWILSON wrote:
Quote:
1.) Get rid of the indirect-X addressing mode --- it was a waste of chip-space --- nobody ever used it for anything.
Actually, (ZP,X) is used
constantly in Forth. This is discussed in the topic "
(zp,X), high-level languages, and processor design."
Indirect-X is only used in C@ and C! --- it is not used in @ and ! --- in C@ and C! it has minimal value (a very few clocks faster) compared to using indirect-Y like @ and ! use.
I think indirect-X was a waste of chip-space --- it is only useful for a table of pointers to 8-bit data, but typically your pointers are to multi-byte structs.
GARTHWILSON wrote:
Quote:
3.) Fix the return-address so it is a valid address (on the 6502 it is off by one, which is a bug not a feature). Also, provide LDS and STS instructions for loading and saving the S register to zero-page --- and fix the S register so that it is a valid address (when saved to zero-page as a low-byte, given 1 as the high-byte, you get a valid zero-page pointer).
I don't think it was a bug, nor was it touted as a feature AFAIK; but I suspect it was done the way it was because interrupts worked differently from subroutines, and it took less silicon real estate the way they did it. But yeah, it would be nice if JSR left the address of the first byte of the following instruction, instead of the last byte of its own operand. For LDS and STS, TSX and TXS do the job, although involving X. It would be nice to keep X out of it; but having several LDS and STS addressing modes would have taken up valuable op-code table space that was later needed for the 65816.
Maybe "bug" wasn't the correct word --- a bug is inadvertant --- the weird return-stack in the 6502 was a convenience to the hardware designers, and they hoped that the software guys wouldn't notice, but we did.
I'm only suggesting here that LDS and STS work with zero-page direct addressing --- the only purpose is to support having zero-page pointers into the return-stack --- this is an addition of only two opcodes, which would have been reasonable in the 1970s (especially after the many indirect-X opcodes have been removed).
GARTHWILSON wrote:
Quote:
4.) Support 128KB (64KB for code and 64KB for data) by having a 17-bit address bus and switching the high bit back and forth as needed during instruction execution (get rid of that set-overflow pin that was never used) --- memory will become less expensive in the 1980s, and people will want bigger programs that work with more data.
I've never used the SO\ pin, but a few hardware devices like the C64's disc drive did, to get faster input. Jeff makes use of it for ultra fast I/O at
http://wilsonminesco.com/6502primer/potpourri.html#Jeff, using 65c02 illegal op codes to accomplish bit output
and input
simultaneously, in a single cycle (twice as fast as the normal 6502 minimum instruction time), for following it immediately with BVC or BVS.
Well, I think everybody in the 1980s wanted 128KB of memory --- everybody hated bank-switching --- this one isn't very controversial...
GARTHWILSON wrote:
Quote:
Note that the #3 bug-fixes above open a lot of doors. LDS and STS would have allowed a local-frame pointer in zero-page (pointing into the return-stack) allowing both Forth or C to have local variables, which would have made reentrant code possible, which would have made a multi-tasking OS realistic. We could have also had efficient direct-threaded-code in Forth (every colon word starts with a JSR to DOCOLON, and the DOCOLON pulls the return address from the S stack and stores it in IP which is a zero-page pointer).
I tell how to do local variables and environment on the '02 in the
Local variables & environments section of the stacks treatise, and how to do recursion on the '02 in the
Recursion section. Jonathan Halliday is working on a GUI with preemptive multitasking on a 6502 8-bit Atari. He's not finished, but he has very impressive stuff working which he demonstrates in videos. See
http://wilsonminesco.com/stacks/potpourri.html#Gek .
I know that it is possible to just use a zero-page pointer as the local-frame pointer, and have your locals stack distinct from the return-stack --- most likely this is what you are suggesting (I didn't read your thread) --- I also know, however, that having locals on the return-stack is fast because PHA can be used for pushing the parameters in preparation for calling the sub-function in C (or at the entrance to the sub-function in Forth).
GARTHWILSON wrote:
Bruce Clark (a forum member here) shows how to do a single-instruction, 6-cycle NEXT in DTC Forth on the 65816 at
viewtopic.php?t=586 , and how to do a two-instruction NEXT in ITC Forth on the 65816 at
viewtopic.php?t=584 .
The '816 opens up a lot of avenues where the '02 was either clumsy or incapable. It adds stack-relative addressing modes plus a 16-bit stack pointer, so local variables work a lot better and recursion won't risk running you out of stack space. You can also set its direct page (like zero page, but it can be moved around) to overlap the top of the stack, affording DP addressing modes in the stack space. It gives 16MB address space, and is much more suited to multitasking, multithreading, relocatable code, and lots of other things. The price difference is minimal. I find the '816 to be actually
easier to program, in situations where you're constantly dealing with 16-bit quantities.
I agree that the 65c816 is much better than the 65c02 --- but in this thread I'm saying what I would suggest given a time-machine to the early 1970s --- the 65c816 was not feasible then; any different version of the 6502 would have to be pretty close to the actual 6502 to be feasible.
I actually think the 6502 was a huge step up from the MC6800 and i8080 that came out one year previously --- I'm just saying that it wasn't perfect --- it could have been better at little or no cost, and this would have changed the course of history.