Jump to content
applekevin

How many of the 105 illegal opcodes are actually useful, or were ever used?

Recommended Posts

We already had opcode 0B on the list, the immediate AND + ROL combination, which sometimes does not generate a result.

 

now I'm not surprised that do not work as you expected. ANC #n ($0b) - check how it realy works: http://xxl.atari.pl/?p=824

Share this post


Link to post
Share on other sites

Can you show me a program or piece of code that fails because of INC $XXXX?

 

Which 65816 hack are you using?

 

"Working on an Atari" is not useful. Many, many programs only work on a 400/800, or with 128K of memory, or on an XL/XE system. The list is very large and does not apply only to illegal opcodes. Even things like "Load this with BASIC" or "This loads into $700 - use BEEPLOAD.COM" would be helpful.

 

furthermore 6502c (Sally) is NMOS so in read-modify-write codes do "false" write, 65816 in this case do "false" read - eg. in some cases use inc irqen do not work on 65816 but on atari work just fine. on 65816 in this case you need use about 4 commands.

 

 

 

 

 

 

"WARNING! this software works on Atari" - is this enought for you? :D

 

so if you replace part of atari with almost compatybile chips you got machine almost compatybile with atari ;-)

Share this post


Link to post
Share on other sites

I know I've seen a clever hack that use indexed reads to strobe 2 addresses on the 64 (strobe one and read the other). Don't know if anything like it exists on Atari. If anyone uses page wrap around effects on the 6502, those will break on the 65C02 and exact-cycle code may not work.

Share this post


Link to post
Share on other sites

Can you show me a program or piece of code that fails because of INC $XXXX?

 

yes. simple inc $d20e. try it.

main1.xex

  • Like 2

Share this post


Link to post
Share on other sites

What is MAIN1? I tried loading it from MyDOS and it just gives a couple of tones.

 

I did:

 

100 *=$600

110 INC $D20E

 

Assemble and G600.

 

Both a 6502 and 65816 appear to execute the same. It executes the INC and then sits there waiting for a RETURN key.

 

Bob

Share this post


Link to post
Share on other sites

What is MAIN1?

 

main1.xex is the program that dont work on 65816 just because inc $d20e

 

 

I tried loading it from MyDOS and it just gives a couple of tones.

 

better use init to load main1.xex.

Share this post


Link to post
Share on other sites

I noticed at least one person on the thread was confused... the 65C02 is NOT the same processor as the 6502C!! Don't get them confused! The 65C02 was a new version of the 6502 that got rid of all undocumented instructions, replacing them with all new instructions, like more push/pop opcodes, and bit instructions. The 65816 is based on the 65C02, not the 6502 or 6502C.

Share this post


Link to post
Share on other sites

I noticed at least one person on the thread was confused... the 65C02 is NOT the same processor as the 6502C!! Don't get them confused! The 65C02 was a new version of the 6502 that got rid of all undocumented instructions, replacing them with all new instructions, like more push/pop opcodes, and bit instructions. The 65816 is based on the 65C02, not the 6502 or 6502C.

 

Were there any major differences between the Atari 6502B and the 6502 used in the Apple ][?

Share this post


Link to post
Share on other sites

What is init?

 

What should I get on a 6502 Atari when I load main1?

 

Bob

 

 

 

main1.xex is the program that dont work on 65816 just because inc $d20e

 

 

 

 

better use init to load main1.xex.

Share this post


Link to post
Share on other sites

What is init?

 

What should I get on a 6502 Atari when I load main1?

 

Some music and a display of notes. It hangs in Altirra if you select a 65816 processor.

 

Q: Why INC $D20E anyway???

Edited by flashjazzcat

Share this post


Link to post
Share on other sites

Were there any major differences between the Atari 6502B and the 6502 used in the Apple ][?

 

Do you mean 6502C *or* 6502B? The Atari "Sally" chip had one additional WAIT pin that is pulled by Antic if it needs the bus for DMA or memory refresh. The original 6502 does not have that, instead a couple of gates manipulate the chip clock (IIRC) to do the same. What Atari did is to integrate this logic into the chip.

Share this post


Link to post
Share on other sites

It does not do much on a stock Atari or the 65816.

 

on atari it works (6-channel music player)

 

on 65816 do not work because regular INC $d20e

 

So, how do I load the thing?

 

http://atariage.com/...25#entry2813494

or if you haven't got 8-bit atari - use Altirra.

Edited by xxl

Share this post


Link to post
Share on other sites

I have 6502 Ataris and 65816 Ataris but I cannot load main1.xex from DOS on either - at least nothing useful results when I load it. I would like to see this fail on real hardware but you're not giving me anything I can test.

 

Bob

 

 

 

on atari it works (6-channel music player)

 

on 65816 do not work because regular INC $d20e

 

 

 

http://atariage.com/...25#entry2813494

or if you haven't got 8-bit atari - use Altirra.

Share this post


Link to post
Share on other sites

I also cannot get this to load on my NTSC 130XE. It hangs at the blue screen with cursor in home position.

Share this post


Link to post
Share on other sites

I have 6502 Ataris and 65816 Ataris but I cannot load main1.xex from DOS on either - at least nothing useful results when I load it. I would like to see this fail on real hardware but you're not giving me anything I can test.

 

main1.xex as I say do not load from dos... but :-) ok. try this program ( load from DOS ) do nor run on 65816 also ( INC $d20e )

 

and video how to load this using DOS:

 

or YT if there is any problem with opening .zip ;-)

 

goldrunner.xex

test.zip

Edited by xxl

Share this post


Link to post
Share on other sites

None of my systems will run this. Does it have to be PAL? The 130XE and 800XL (6502) fail the same. A 1200XL fails worse in either 6502 or 65816.

 

What is the expected result from executing an INC $D20E? Perhaps I can just write a little m/l routine to test this?

 

Bob

Share this post


Link to post
Share on other sites
What is the expected result from executing an INC $D20E? Perhaps I can just write a little m/l routine to test this?

 

yes, you can :-)

 

    org $2000
   
start   sei
    lda #$00
    sta IRQEN
    sta NMIEN
    sta DMACTL
    lda #$FE
    sta PORTB
    lda <my_irq
    sta $FFFE
    lda >my_irq
    sta $FFFF
   
    lda #0
    sta AUDCTL
    lda #3
    sta SKCTL	   ; reset
    lda #%00000001
    sta AUDCTL	  ;ZEGAR 15KHZ
    lda #77		 ;PODZIAL 312/4 - 1 = 77 (PAL)
    sta AUDF4
    lda #$00
    sta AUDC4
    sta STIMER	  ;WPIS WARTOSCI
    lda #%00000100  ;tylko timer4
    sta IRQEN
    cli
stop    jmp stop	   


my_irq  pha
    lda #$0f
    sta wsync
    sta colbak

    inc IRQEN ; do not work on CMOS

    lda #$00
    sta wsync
    sta colbak
    pla
    rti

run start

Share this post


Link to post
Share on other sites

Can anyone explain why the code above fails on the 65816?

 

XXL explained it above, but I don't quite get what he means here:

furthermore 6502c (Sally) is NMOS so in read-modify-write codes do "false" write, 65816 in this case do "false" read - eg. in some cases use inc irqen do not work on 65816 but on atari work just fine. on 65816 in this case you need use about 4 commands.

 

I guess something to do with the dual nature of IRQEN, that it's a different register reading or writing, and the code above is an "optimization" based on the behaviour of the 6502 and somehow the 65816 behaves differently?

Share this post


Link to post
Share on other sites

Do you mean 6502C *or* 6502B? The Atari "Sally" chip had one additional WAIT pin that is pulled by Antic if it needs the bus for DMA or memory refresh. The original 6502 does not have that, instead a couple of gates manipulate the chip clock (IIRC) to do the same. What Atari did is to integrate this logic into the chip.

 

That is indeed the case. The original 6502 series didn't have a HALT line, but you could hold the clock line low indefinitely. In the 400 and 800, the ANTIC asserts /HALT, which goes to a flip-flop to latch the signal. The inverted out from the flip-flop is asserted, which turns off the buffers between the 6502 and the bus (taking the 6502 off the bus), and driving the clock line low (through a NOR gate).

Share this post


Link to post
Share on other sites

In general, Altirra's 65816 emulation is not tested as well at the cycle-exact level than its 6502 emulation. I'm improving it over time but I wouldn't rely on it just yet as an indicator of 6502/65816 incompatibilities.

 

INC IRQEN is used as a fast way to acknowledge a POKEY IRQ for interrupt-driven digitized playback. It relies on the NMOS 6502 doing read-write-write on a read/modify/write operation, versus the 65C02 and 65C816 which do read-read-write. This is documented behavior on both sides and is a known incompatibility between the CPUs. On an '816, it should fail to acknowledge the IRQ and jam the CPU in an interrupt loop. I don't know of an alternative way to ACK a POKEY IRQ on a 65C02 or a 65816 that is as fast as a read/modify/write instruction on the 6502.

 

There are other known and officially documented incompatibilties between the 6502 and the 65C02/65816, including absolute indexed read/modify/write cycle counts, decimal mode cycle counts, decimal flag state on interrupt, absolute indexed wrapping, and RDY during write cycles (affects INC WSYNC). As far as I know, the illegal opcodes were never officially acknowledged. However, they've been extensively studied and commercial software has been shipped that uses them to an advantage, so there's no point in pretending they're useless or all unstable. You can definitely argue that it's bad practice to use them, but the illegal opcodes are a reality and anything that doesn't at least attempt to support them just isn't a 6502.

  • Like 3

Share this post


Link to post
Share on other sites

One other incompatibilities to add to your list was posted by John Harris. I ran the demo and it does bug the screen output. The 65816 and 65C02 fixes this of course. Just my op but I think having this fixed is probably about as important as leaving bugs in! ;)

 

*****Start of John's post****

Ok, here it is. The demonstration of the interrupt problem in the 6502.

Oddly, it doesn't even have to use an IRQ, as the software BRK in this

example shows. Results are the same, no matter which IRQ and NMI we are

talking about. Anything can get skipped.

Note, that this is far from the most extensive tests I did for proof. It

is in fact the simplest test I could reduce it to, and was the one I used

to try convincing other people, (i.e. ones with resources to help me figure

out what the heck was going on), that the problem was not my imagination,

or poor programming.

LDA #<DLI

STA $200

LDA #>DLI

STA $201

LDA #<BRKLP

STA $206

LDA #>BRKLP

STA $207

LDA $230

STA $80

LDA $231

STA $81

LDY #8

LDA #$82

STA ($80),Y ; Put in a couple DLI's

LDY #$17

STA ($80),Y

LDA #$80

STA $D40E

BRK ; We should now jump through ($206) -> BRKLP

;

BRKLP LDA $D20A ; These first 5 lines are just to get a random

AND #3 ;element into the timing. Without them, it is

SEC ;possible to run a fixed loop that always

DELAY SBC #1 ;misses the critical point of timing.

BPL DELAY

PLA ; Pull all the stuff that the IRQ pushed

PLP

PLA

PLA

BRK ; This should be an infinite loop to BRKLP

;

INY ; This line is never executed.

LDA $2C8 ; But it occasionally gets here, and I change the

CLC ;border color.

ADC #8

STA $2C8

STA $D01A

BRK ; Back to the loop

;

DLI PHA

LDA $D40B ; Use the line counter to get two different colors

STA $D018 ; I didn't use WSYNC to eliminate it as a variable

PLA

RTI

Ok, the DLI's put two new blocks of color on the screen. What you'll see

if you run this code, is these blocks will flicker, as well as the border

color. This is because both BRK's and NMI's are being skipped. The Y

register never changes, which means the program gets to the $2C8 color

change without going through the INY. This address is equal to the address

of the BRK, +2, which is the address that gets pushed onto the stack when

the BRK is executed. I'm about to show how it gets to that address.

There's 12 years worth of data to describe about my testing this phenomena.

Here's the highlights:

At the peak of discovery, I disabled the OS ROM, and put the BRKLP and DLI

pointers directly into $FFFA and $FFFE. Eliminate more variables. I also

slowed the BRK loop way down, and put counters, both frame and VCOUNT into

both the BRK and DLI interrupts. I also put some checks into the DLI to

see what the stack looked like. Now this is really neat. At the point of

the error, the stack from the DLI contained only one return address, and

this was the address of the BRK +2! Also, the B status bit was set in the

pushed status register! Now, the BRK +2 address is never executed in the

normal loop of code, and thus BRK+2 should never be pushed as the result of

an NMI. The data logs showed a gap in the counters for the BRK loop, and

that gap corresponded exactly to the DLI that logged the odd stack frame.

That, plus the fact that the B status was set leads me to believe that the

two interrupts somehow got 'fused' into one. The 6502 is processing the

BRK internally, but before it jumps through $FFFE, an NMI comes along and

somehow revectors the jump to $FFFA without pushing new stuff on the stack.

The Zaks 6502 book mentions some vague stuff about setting the I flag as

part of an IRQ so the processor isn't interrupted while it is manipulating

internal registers. But that doesn't stop an NMI. What happens then? It

also talks about accepting the interrupt as soon as the current instruction

is completed. But what if that instruction is another interrupt? I don't

know what the actual conflict is caused by. But I think I've shown that it

occurs.

All responses to this will be most appreciated. This problem has cost me

months of debugging time over several different projects trying to find

bugs that didn't exist. It has been an obsession, and I'm eager to talk

more about it.

John Harris

  • Like 1

Share this post


Link to post
Share on other sites

The 65816 only does a Read/Read/Write when it is not in Emulate mode. I confirmed R/W/W on real hardware with E=1. This is documented in the WDC spec sheets.

 

This is not to say that INC $D20E should work - I don't know that, but it probably isn't because of R/R/W behavior.

 

Yes, lots of commercial s/w has been shipped that proved to be incompatible with later hardware. Didn't we learn a lesson?

 

Thank you for your input. I spend a lot of time trying to trace failures that work on a 6502 and fail on my 65816s. It is mostly a hardware problem, but some are as you describe - indexing, Ready and such. If they turn out to be illegal opcodes, I will have a tough time finding them since some may be legal even under emulation.

 

Bob

 

 

 

In general, Altirra's 65816 emulation is not tested as well at the cycle-exact level than its 6502 emulation. I'm improving it over time but I wouldn't rely on it just yet as an indicator of 6502/65816 incompatibilities.

 

INC IRQEN is used as a fast way to acknowledge a POKEY IRQ for interrupt-driven digitized playback. It relies on the NMOS 6502 doing read-write-write on a read/modify/write operation, versus the 65C02 and 65C816 which do read-read-write. This is documented behavior on both sides and is a known incompatibility between the CPUs. On an '816, it should fail to acknowledge the IRQ and jam the CPU in an interrupt loop. I don't know of an alternative way to ACK a POKEY IRQ on a 65C02 or a 65816 that is as fast as a read/modify/write instruction on the 6502.

 

There are other known and officially documented incompatibilties between the 6502 and the 65C02/65816, including absolute indexed read/modify/write cycle counts, decimal mode cycle counts, decimal flag state on interrupt, absolute indexed wrapping, and RDY during write cycles (affects INC WSYNC). As far as I know, the illegal opcodes were never officially acknowledged. However, they've been extensively studied and commercial software has been shipped that uses them to an advantage, so there's no point in pretending they're useless or all unstable. You can definitely argue that it's bad practice to use them, but the illegal opcodes are a reality and anything that doesn't at least attempt to support them just isn't a 6502.

Share this post


Link to post
Share on other sites

I typed in your routine - it runs exactly the same on a 65816 as a 6502. At both 1.79mhz and 14.32mhz (65816).

 

Bob

 

 

 

yes, you can :-)

 

 org $2000

start sei
 lda #$00
 sta IRQEN
 sta NMIEN
 sta DMACTL
 lda #$FE
 sta PORTB
 lda <my_irq
 sta $FFFE
 lda >my_irq
 sta $FFFF

 lda #0
 sta AUDCTL
 lda #3
 sta SKCTL	 ; reset
 lda #%00000001
 sta AUDCTL	 ;ZEGAR 15KHZ
 lda #77		 ;PODZIAL 312/4 - 1 = 77 (PAL)
 sta AUDF4
 lda #$00
 sta AUDC4
 sta STIMER	 ;WPIS WARTOSCI
 lda #%00000100 ;tylko timer4
 sta IRQEN
 cli
stop jmp stop	


my_irq pha
 lda #$0f
 sta wsync
 sta colbak

 inc IRQEN ; do not work on CMOS

 lda #$00
 sta wsync
 sta colbak
 pla
 rti

run start

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...