Jump to content
IGNORED

Illegal Op codes


Wrathchild

Recommended Posts

Sheddy is currently making a Space Harrier program for the 130XE that uses some illegals, I think. And I posted a text file that lists them and their compatability between the C64 and Atari hardware. I dunno about differences between Atari platforms, though (I would guess that the older the chip is, the better...right?).

 

http://wwwstud.ira.uka.de/~s_tomczy/opcodes.html

C64 on top, Atari on the bottom

 

That page lists the ones that are known to work, as well as short descriptions of how they may be useful and what the savings (if any) would be.

Link to comment
Share on other sites

There are only a few illegal opcode that are really useful:

  • NOP: there are different NOPs with different addressing modes and lengths, useful for wasting cycles and for hiding the next instruction

[*]LAX: especially useful when used as LAX (),y instead of LDA(),y/TAX

[*]DCP, ISB: also sometimes useful in very special cases

  • IIRC I never have used any of the many other illegal opcodes.
Link to comment
Share on other sites

AXA and TAS might also be kinda (since the argument is used as both an address and one of the AND values) useful, since they perform double-AND instructions without altering the registers :!: Not bad for 5 or 6 cycles.

Have you noticed any of those that don't work on different Atari computer models?

Link to comment
Share on other sites

I read somewhere that the early 400/800 models had the 6502B chip which doesn't support these extra instructions. Atari had the 6502C made coz it allowed them to leave out some extra support chips; something to do with WSYNC I think...pulling down the HALT line on the chip???

All the models after that definitely have the 6502C.

Only problem arises is when people have replaced the processor with some super 16 bit CPU upgrade which has 6502 instructions...they don't have the 6502C instructions...

 

I've only used the LAX (),y instruction. Like Thomas says, saves doing a TAX. Very handy in a time critical sprite routine for masking.

EG

 

lax (data),y

ora (screen),y

and mask_table,x

sta (screen),y

 

Frankly I've never had the ingenuity to figure out a use for the others - luckily we don't have to work to exact cycle counts on 8-bit Atari computers - some of the extra instructions seem pretty bizarre, and I guess they are mostly just obscure side effects rather than any deliberately designed instructions, although maybe you can do something like Nukey mentions...not sure quite how for most things though...some of the demo coders might know different though.

:)

Link to comment
Share on other sites

Yep...I think that some articles point out that it is in regards to how the bits of the instruction's binary assignment are arranged that gives the undocumented instructions their effects (eight of this, eight of that, etc.), leading many to be too highly specialized to be of any real use at all. There was a really good chart that shows that...but I can't seem to find it at the moment :P

 

Side topic:

Wouldn't it have been great that if the argument of FF or 00 in a branching instruction would have allowed you to jump a full page reverse and forward? I suppose that would probably tax the processor a bit, though.

Link to comment
Share on other sites

Its probably irrational on my part, but I am very reluctant to use illegal opcodes.   I guess I worry about running into an incompatability with some version of the microprocessor.  

Don't worry to much. :)

 

:idea: Yes, there are some (very weird, e.g. with BCD arithmetic involved) opcodes that have been reported to behave different, but all my documentations and tests show that way the most of them work 100% identical on any 650x CPU (incl. TAX, NOP, DCP, ISB).

Link to comment
Share on other sites

Side topic:

Wouldn't it have been great that if the argument of FF or 00 in a branching instruction would have allowed you to jump a full page reverse and forward?  I suppose that would probably tax the processor a bit, though.

 

That would be nice - so turning it into a 3 byte instruction for just this special case? Certainly hard for the proc if the instruction is variable length - I'm not a hardware person, but I think that would make the decoding hardware a lot more complicated.

 

I'd have liked a whole range of conditional jumps, something like jeq $nnnn, jcc $nnnn etc.

 

Mind you, given the chance to change the 6502 instruction set....there's just so much that would be nice to add, change or get rid of!

:)

Link to comment
Share on other sites

No, I meant using FF or 00 as the argument. As they are, FF jumps in the middle of the instruction, and 00 jumps to the next instruction. What I meant was if $1FE3: BEQ 00 would jump to address $20E3 (changing the high byte of the program counter instead of the low byte)...but I liked your conditional jumps better :)

Link to comment
Share on other sites

No, I meant using FF or 00 as the argument.  As they are, FF jumps in the middle of the instruction, and 00 jumps to the next instruction.  What I meant was if $1FE3: BEQ 00 would jump to address $20E3 (changing the high byte of the program counter instead of the low byte).

 

That is genius, I wonder why they didn't do that. :?

 

* Gives Nukey the silent programmer award * :D

Link to comment
Share on other sites

oh,

that's what I thought you meant to start with for a split second!...but, no he couldn't have meant that...of course, on reflection, yes, that could have been very handy indeed :D

 

definitely an award of some sort required... 6502 hack award???!

Link to comment
Share on other sites

Mind you, given the chance to change the 6502 instruction set....there's just so much that would be nice to add, change or get rid of!

 

I've worked with a Mitsubishi 37450 in the past (swimming pool controller). These use a 6502 core but have all those instructions you wish the A8 had ;) e.g.

 

INC/DEC the 'A' register :)

BBS/BBC - branch if bit set or clear 8)

MUL - 8*8 -> 16 bit multiply :love:

DIV - 16/8 -> 16 bit divide

BRA - relative jmp (2 bytes)

LDM - Load ZP location with immediate value (3 bytes)

RRF - Rotate ZP location's content by 4 bits (e.g. low/hi swap)

COM - 1's complement a ZP location

TST - test a ZP location = 0

 

These would certainly make for more compact programs!

 

Also, when you see threads based on 'if they were to make a new A8...' then for me this is a candidate processor for it! I think you can even get them now with on-board USB support.

 

(scans of pages dropped in place of this link)

http://www.infomicom.maec.co.jp/usb/753dsume.htm

 

Anyway, thanks for the responses to the thread!

 

Take care,

 

Mark

Link to comment
Share on other sites

Yeah, would have loved some of those instructions!

Lots of embedded controllers and the like use cores based on 6502 or 68000 and even better now. Also tend to run much faster. Seems kind of weird that the swimming pool controller or the washing machine can dump on our old home computers from a great height, computing-power-wise

:)

Link to comment
Share on other sites

Most of the embedded stuff I do now is PIC (Microchip) 16c7x based. These don't even have index registers, just an 8-bit work (W) register!

However, on-board Serial/SPI and I2C help make things fun.

 

I'm looking into making a board which will use a PIC to interface with a 16Meg SD card via SPI and hope to pump results to the XL via the SIO port. That would make a nice little hard-disk ;)

Link to comment
Share on other sites

what about

 

inc a/dec a

mul/div

bra

mov.b #,adr (4 bytes instead of 5... mov val adrl adrh)

swap a (low nibble with hi nibble of a byte)

lda () without ,y

lda (),x

lda (,y)

clr a

clr x

clr y

clr axy

clr adr (moves #0 to adr)

 

and all XASM ones...

 

like post and pre increment

 

lda (),y+

etc...

 

hve

Link to comment
Share on other sites

I wonder why everybody wants BRA.

 

Normally you can always find a flag you can rely on, it makes programming just al little more challenging. ;)

 

But two separate branch opcodes for each flag would be nice, one jumping up to 256 bytes back and one jumping up to 256 bytes forward. They could both have still the same name and the assmebler would take care to select the right one.

Link to comment
Share on other sites

Yes, but then the challenge of keeping the carry in a constant state would have been gone! ;)

Nice when it can be done, but often the carry state is unknown / could be either.

 

What's wrong with EOR #$FF, ADC #1 ? :)

 

Don't you mean EOR #$FF, SEC, ADC #0 ? :D

Link to comment
Share on other sites

Don't you mean EOR #$FF, SEC, ADC #0 ?  :D

Yes and no, I meant EOR #$FF, ADC #1 :) (without SEC/CLC)

 

Like in:

SEC

LDA v1

SBC v2

BCS .skip

EOR #$ff

ADC #1

.skip:

 

And this would be even better (because the carry is always set then afterwards).

SBC #0

EOR #$FF

 

I love optimizing! :D

Link to comment
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.
Note: Your post will require moderator approval before it will be visible.

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...