Why NES have too ugly arch?

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems. See the NESdev wiki for more information.

Moderator: Moderators

psycopathicteen
Posts: 3140
Joined: Wed May 19, 2010 6:12 pm

Re: Why NES have too ugly arch?

Post by psycopathicteen »

It was really nice how PAL and NTSC both have almost the exact same line frequency, and that PAL has a color carrier almost exactly 5/4 of NTSC.
psycopathicteen
Posts: 3140
Joined: Wed May 19, 2010 6:12 pm

Re: Why NES have too ugly arch?

Post by psycopathicteen »

I might as well say the 6502 instruction set is awkward. It should've gave both index registers the same addressing modes, and included "stx abs,y" and "sty abs,x". Have non-indexed indirect mode (though later revisions had it). Have add and sub without carry. Have register swap instructions. Being able to add or subtract index registers.
lidnariq
Posts: 11432
Joined: Sun Apr 13, 2008 11:12 am

Re: Why NES have too ugly arch?

Post by lidnariq »

psycopathicteen wrote:included "stx abs,y" and "sty abs,x"
The weirdest thing is that those two instructions are just barely not present... I have to assume it just didn't occur to the designing team.
User avatar
Myask
Posts: 965
Joined: Sat Jul 12, 2014 3:04 pm

Re: Why NES have too ugly arch?

Post by Myask »

Given how it ended up (with SHY abx/SHX aby), I expect it's more an error that the 6502 designers never got around to fixing, even in most descendants. Those instructions are on the 65ce02, though, five? designs later…albeit not at those opcodes.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Why NES have too ugly arch?

Post by tokumaru »

psycopathicteen wrote:Being able to add or subtract index registers.

Code: Select all

ByteTable:
	.db $00, $01, $02, $03, $04, (...) $fe, $ff

	adc ByteTable, x ;ADX
	adc ByteTable, y ;ADY
	sbc ByteTable, x ;SBX
	sbc ByteTable, y ;SBY
User avatar
Jarhmander
Formerly ~J-@D!~
Posts: 569
Joined: Sun Mar 12, 2006 12:36 am
Location: Rive nord de Montréal

Re: Why NES have too ugly arch?

Post by Jarhmander »

What tokumaru said is that by having an identity table, you can emulate certain instructions like doing arithmetic or bitwise operations with the index registers; it's in this thread.
((λ (x) (x x)) (λ (x) (x x)))
User avatar
Myask
Posts: 965
Joined: Sat Jul 12, 2014 3:04 pm

Re: Why NES have too ugly arch?

Post by Myask »

They're not the accumulator, though. The accumulator is for math. Index registers aren't.
This exchange seems relevant.
rainwarrior wrote:Nobody tell them about the PowerPC.
(And that thread you linked calls the ZP 256 extra registers.)
Oziphantom
Posts: 1565
Joined: Tue Feb 07, 2017 2:03 am

Re: Why NES have too ugly arch?

Post by Oziphantom »

The Dendy sounds like a fancy piece of engineering then.

Does the NES have a DRAM refresh circuit or does it force SRAM? Would have been nice if it had a DRAM circuit on-board board so you could put cheaper DRAMs in the carts instead of making us shill for SRAM each time.

The 6502 had one goal, to be $5. There was nothing else to compare it to so Chuck and Mensch weren't forced into adding feature X or Y to compete. Personally I think getting SEI and CLI backwards was their biggest misstep on the 6502. Also Non-Maskable .. :roll: sigh... For me Mensch nailed it with the 65816, it has all the goodies, although the 4510 might be a bit better in the end with its built in bank switching op code.

PHY/X PLX/Y would have really helped though.
TXY,TYX also would have been useful.
Not having LDA(zp) has been thorn in my side many a time.
LDA (zp,x) is a total waste and would have been better served as LDA (zp,x),y which would be pure gold.
JSR (XXXX) would save a lot of pain too.

Remember if you really need speed, S is a register too ;)
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Why NES have too ugly arch?

Post by tokumaru »

Oziphantom wrote:The Dendy sounds like a fancy piece of engineering then.
Yes, I'm still impressed that pirates did a better job of adapting the Famicom architecture to PAL than Nintendo themselves.
Personally I think getting SEI and CLI backwards was their biggest misstep on the 6502.
What do you mean backwards? Do you think the mnemonics would better match their function if they were switched? The CPU only understands opcodes, not mnemonics, so if this bothers you so much you can always create your own assembler (or modify someone else's) with these two switched. I mean, look at the source code for the NES version of Magic Floor... It's written in 80XX syntax! You can write source code anyway you want, as long as the resulting binary is comprised of valid 6502 opcodes. Unintuitive mnemonics are NOT hardware design flaws by any stretch of the imagination.
PHY/X PLX/Y would have really helped though.
Would them? Maybe it's my style of coding, but I hardly ever use the stack to back up values. Even in the NMI handler, where I need to backup all 3 registers, I use 3 ZP locations I have reserved exclusively for this purpose, instead of using the stack.
TXY,TYX also would have been useful.
ByteTable to the rescue:

Code: Select all

ByteTable:
	.db $00, $01, $02, $03, $04, (...) $fe, $ff

	ldy ByteTable, x ;TXY
	ldx ByteTable, y ;TYX
Not having LDA(zp) has been thorn in my side many a time.
That I actually miss sometimes, but I often end up finding a way to make Y useful instead of having to load it with 0.
LDA (zp,x) is a total waste
I don't know, LDA (ZP, X) can be useful for accessing collections of streams, such as the different channels of a song.
and would have been better served as LDA (zp,x),y which would be pure gold.
But then you'd be using all your registers for reading, meaning you could have trouble indexing the destination if not reusing Y or an auto-increment register such as $2007. Not to mention that this would be a pretty slow instruction.
JSR (XXXX) would save a lot of pain too.
Working with the attribute tables in an 8-way scroller is a pain. Changing the palette mid-frame is a pain. Doing raster effects without IRQs is a pain. Animating patterns in such a short vblank time is a pain. JSR'ing to a JMP (XXXX) is definitely not a pain.
Remember if you really need speed, S is a register too ;)
Specially on the Atari 2600, which doesn't have any interrupts, so S can safely be used to load data faster in display kernels.
User avatar
za909
Posts: 249
Joined: Fri Jan 24, 2014 9:05 am
Location: Mijn hart woont al in Nederland

Re: Why NES have too ugly arch?

Post by za909 »

As far as instruction sets go, sometimes I look at the Z80 set with quite some envy. It may be slow as all hell but it sure has some clever instructions that I could really use in NES programs. For example the bit tests that can test a single bit in a register or in RAM. With the 6502 you can only check the top two bits with relative ease (and even the available addressing modes of BIT leave a lot to be desired) while the rest require you to load from the address and then AND to discard the bits you aren't interested in testing, or LSR to carry if you want to test bit 0.

I could say the same about the individual bit-setting and clearing instructions. No need to load from RAM and then use AND/ORA, and then storing the result. The Z80 even has those DMA-type instructions to work with a large chunk of data (moving it, finding a certain value in a table, etc.)
Oziphantom
Posts: 1565
Joined: Tue Feb 07, 2017 2:03 am

Re: Why NES have too ugly arch?

Post by Oziphantom »

tokumaru wrote:
Oziphantom wrote:The Dendy sounds like a fancy piece of engineering then.
Yes, I'm still impressed that pirates did a better job of adapting the Famicom architecture to PAL than Nintendo themselves.
Personally I think getting SEI and CLI backwards was their biggest misstep on the 6502.
What do you mean backwards? Do you think the mnemonics would better match their function if they were switched? The CPU only understands opcodes, not mnemonics, so if this bothers you so much you can always create your own assembler (or modify someone else's) with these two switched. I mean, look at the source code for the NES version of Magic Floor... It's written in 80XX syntax! You can write source code anyway you want, as long as the resulting binary is comprised of valid 6502 opcodes. Unintuitive mnemonics are NOT hardware design flaws by any stretch of the imagination.
Sure I could easily make my own standard but the standard set down by Chuck and Bill is the standard we all know and use. SEI Set Enable Interrupt - actually disables Interrupts. Not a 6502 design flaw, nothing wrong with the die, but still Chuck and Bill's misstep ;)
tokumaru wrote:
PHY/X PLX/Y would have really helped though.
Would them? Maybe it's my style of coding, but I hardly ever use the stack to back up values. Even in the NMI handler, where I need to backup all 3 registers, I use 3 ZP locations I have reserved exclusively for this purpose, instead of using the stack.
If you have a single NMI source and 100% guarantee you won't renter, then sure use the ZP, its faster. But if you have 4 IRQ sources and an NMI source or might re-enter, use the stack or you are could get lots of pain, the adding 1 opcode to this unrelated function causes the whole screen to become a mess kind of pain. Or make 5x3 store areas if you have the RAM to spare.If you want to make lite threads or "peel off" threading on a 6502 the stack helps. Also when you just need to preserve a register somewhere to recall it 3 lines down or so, having the option to use the Stack over the ZP, which might then get trashed by some other function or maybe in an interrupt if its a shared "general ZP store" would be nice sometimes. Rather than a STX Somewhere, LDX somewhere else, it adds a dependency to your code or lib that could be mitigated with a Stack operation. You could even use a PHY PLX to get around not having a TYX for example for when you have to do the I need what is in X to now be in Y but I really want to preserve A docey-do. I would also be handy for parameter passing, that you use in the function but don't need it now. For example something like

Code: Select all

myFunc
STY ZPY
STX ZPX
LDY #4
STA (ptr),y
JSR functionThatModifiesA ; I hope this doesn't trash ZPY or ZPX one day
LDX ZPX
ADC Table,x
LDX ZPY
AND Table,y
LDY #4
STA (ptr),y
RTS
Could become

Code: Select all

myFunc
PHY
PHX
LDY #4
STA (ptr),y
JSR functionThatModifiesA ; can do whatever it wants with things
PLX
ADC Table,x
PLY
AND Table,y
LDY #4
STA (ptr),y
RTS
tokumaru wrote:
TXY,TYX also would have been useful.
ByteTable to the rescue:

Code: Select all

ByteTable:
	.db $00, $01, $02, $03, $04, (...) $fe, $ff

	ldy ByteTable, x ;TXY
	ldx ByteTable, y ;TYX
Yeah byte tables are nice things to have around.
tokumaru wrote:
Not having LDA(zp) has been thorn in my side many a time.
That I actually miss sometimes, but I often end up finding a way to make Y useful instead of having to load it with 0.
LDA (zp,x) is a total waste
I don't know, LDA (ZP, X) can be useful for accessing collections of streams, such as the different channels of a song.
and would have been better served as LDA (zp,x),y which would be pure gold.
But then you'd be using all your registers for reading, meaning you could have trouble indexing the destination if not reusing Y or an auto-increment register such as $2007. Not to mention that this would be a pretty slow instruction.
If X is your entity number, and Y is the field you want in the entity then ZP can hold an entity pointer table of which you can easily index into. Gives you the ability to easily make 2 dimensional arrays. It would add 1 clock to the cycle which is a lot faster than doing it the long way at the moment.
tokumaru wrote:
JSR (XXXX) would save a lot of pain too.
Working with the attribute tables in an 8-way scroller is a pain. Changing the palette mid-frame is a pain. Doing raster effects without IRQs is a pain. Animating patterns in such a short vblank time is a pain. JSR'ing to a JMP (XXXX) is definitely not a pain.
Doing a push with the address -1 on the stack then doing a jump is cumbersome, and I come from a machine where I can actually just change the JSR params ;) Still it would be nice if I didn't have to. Also those other things are NES problems not a 6502 problem.
tokumaru wrote:
Remember if you really need speed, S is a register too ;)
Specially on the Atari 2600, which doesn't have any interrupts, so S can safely be used to load data faster in display kernels.
Revenant
Posts: 462
Joined: Sat Apr 25, 2015 1:47 pm
Location: FL

Re: Why NES have too ugly arch?

Post by Revenant »

Oziphantom wrote:SEI Set Enable Interrupt - actually disables Interrupts.
The word "enable" isn't what the E stands for. "SE" and "CL" are just short for "set" and "clear"; SED is the only one of those that's actually intended to enable anything.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Why NES have too ugly arch?

Post by tokumaru »

For me these were always SEt I, CLear I, SEt D, CLear D, with I and D being the "IRQ inhibit" and "Decimal mode" flags. Pretty straightforward if you ask me.
Revenant
Posts: 462
Joined: Sat Apr 25, 2015 1:47 pm
Location: FL

Re: Why NES have too ugly arch?

Post by Revenant »

In fact, the actual 6502 datasheet from 1976 (page 5) refers to SEI as "Set Interrupt Disable", as well.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Why NES have too ugly arch?

Post by tokumaru »

That works too, if you call the I flag "interrupt disable".
Post Reply