Jump to content
IGNORED

Illegal opcodes?


Recommended Posts

I just found this page on illegal opcodes for the 6502, some sound very useful. I am already a fan of the Three cycle nop, but How would I go about to executing some of these other illegals. For example, If I wanted to do SRE (Shift right then EOR with accumulator) Would I acutally type 'SRE' or would I type .byte $47?

 

here is the page:

 

http://members.chello.nl/taf.offenga/illopc31.txt

Link to comment
Share on other sites

I just found this page on illegal opcodes for the 6502, some sound very useful. I am already a fan of the Three cycle nop, but How would I go about to executing some of these other illegals. For example, If I wanted to do SRE (Shift right then EOR with accumulator) Would I acutally type 'SRE' or would I type .byte $47?

 

here is the page:

 

http://members.chello.nl/taf.offenga/illopc31.txt

You can type the mnemonics as you say, but don't use the above source, as Dasm seems to take the mnemonics from this source instead:

 

http://www.viceteam.org/plain/64doc.txt

Link to comment
Share on other sites

Dasm supports illegals (i.e. undocumented opcodes). But Distella doesn't (so I use my own edited version of it that doesn't generate those huge files...and that generates the same 3-letter menomics that Dasm uses).

 

 

Here's a list of differences between them. When using undocumented opcodes in an assembly file, you can use the names listed in the examples. Dasm should interpret them correctly. When in doubt, you can use .byte followed by the opcode value and argument.

 

;Dasm/Distella undocumented opcode differences
;Dasm-compatable examples given for each (always using $EA as an argument).



;AAC (ANC) [ANC]
;~~~~~~~~~~~~~~~
;AND byte with accumulator. If result is negative then carry is
;set. Status flags: N,Z,C
;Dasm uses ANC, which assembles to the opcode $0B
;Distella uses .byte $xx;.ANC...and causes the argument to be interpreted as code
;Addressing  |Mnemonics  |Opc|Sz | n
;------------|-----------|---|---|---
;Immediate   |AAC #arg   |$0B| 2 | 2
   ANC	#$EA				   ;2

;duplicates...
;Immediate   |AAC #arg   |$2B| 2 | 2
   .byte $2B,$EA				 ;2



;AAX (SAX) [AXS]
;~~~~~~~~~~~~~~~
;AND X register with accumulator and store result in memory.
;Status flags: N,Z
;Dasm uses SAX
;Distella uses .byte $xx;.SAX...and causes the argument to be interpreted as code
;Addressing  |Mnemonics  |Opc|Sz | n
;------------|-----------|---|---|---
;Zero Page   |AAX arg	|$87| 2 | 3
   SAX	$EA					;3
;Zero Page,Y |AAX arg,Y  |$97| 2 | 4
   SAX	$EA,Y				  ;4
;(Indirect,X)|AAX (arg,X)|$83| 2 | 6
   SAX	($EA,X)				;6
;Absolute	|AAX arg	|$8F| 3 | 4
   SAX	$EAEA				  ;4


;ARR (ARR) [ARR]
;~~~~~~~~~~~~~~~
;AND byte with accumulator, then rotate one bit right in accu-
;mulator and check bit 5 and 6:
;If both bits are 1: set C, clear V.
;If both bits are 0: clear C and V.
;If only bit 5 is 1: set V, clear C.
;If only bit 6 is 1: set C and V.
;Status flags: N,V,Z,C
;Dasm uses ARR
;Distella uses .byte $6B;.ARR...and causes the argument to be interpreted as code
;Addressing  |Mnemonics  |Opc|Sz | n
;------------|-----------|---|---|---
;Immediate   |ARR #arg   |$6B| 2 | 2
   ARR	#$EA				   ;2


;ASR (ASR) [ALR]
;~~~~~~~~~~~~~~~
;AND byte with accumulator, then shift right one bit in accumu-
;lator. Status flags: N,Z,C
;Dasm uses ASR
;Distella uses .byte $4B;.ASR...and causes the argument to be interpreted as code
;Addressing  |Mnemonics  |Opc|Sz | n
;------------|-----------|---|---|---
;Immediate   |ASR #arg   |$4B| 2 | 2
   ASR	#$EA				   ;2


;ATX (LXA) [OAL]
;~~~~~~~~~~~~~~~
;AND byte with accumulator, then transfer accumulator to X
;register. Status flags: N,Z
;Dasm uses LXA
;Distella uses .byte $AB;.LXA...and causes the argument to be interpreted as code
;Addressing  |Mnemonics  |Opc|Sz | n
;------------|-----------|---|---|---
;Immediate   |ATX #arg   |$AB| 2 | 2
   LXA	#$EA				   ;2


;AXA (SHA) [AXA]
;~~~~~~~~~~~~~~~
;AND X register with accumulator then AND result with 7 and
;store in memory. Status flags: -
;Dasm uses SHA
;Distella uses .byte $xx;.SHA...and causes the argument to be interpreted as code
;Addressing  |Mnemonics  |Opc|Sz | n
;------------|-----------|---|---|---
;Absolute,Y  |AXA arg,Y  |$9F| 3 | 5
   SHA	$EAEA,Y				;5
;(Indirect),Y|AXA arg	|$93| 2 | 6
   SHA	($EA),Y				;6


;AXS (SBX) [SAX]
;~~~~~~~~~~~~~~~
;AND X register with accumulator and store result in X regis-
;ter, then subtract byte from X register (without borrow).
;Status flags: N,Z,C
;Dasm uses SBX
;Distella uses .byte $CB;.SBX...and causes the argument to be interpreted as code
;Addressing  |Mnemonics  |Opc|Sz | n
;------------|-----------|---|---|---
;Immediate   |AXS #arg   |$CB| 2 | 2
   SBX	#$EA				   ;2


;DCP (DCP) [DCM]
;~~~~~~~~~~~~~~~
;Subtract 1 from memory (without borrow).
;Status flags: C
;Dasm uses DCP
;Distella uses .byte $xx;.DCP...and causes the argument to be interpreted as code
;Addressing  |Mnemonics  |Opc|Sz | n
;------------|-----------|---|---|---
;Zero Page   |DCP arg	|$C7| 2 | 5
   DCP	$EA					;5
;Zero Page,X |DCP arg,X  |$D7| 2 | 6
   DCP	$EA,X				  ;6
;Absolute	|DCP arg	|$CF| 3 | 6
   DCP	$EAEA				  ;6
;Absolute,X  |DCP arg,X  |$DF| 3 | 7
   DCP	$EAEA,X				;7
;Absolute,Y  |DCP arg,Y  |$DB| 3 | 7
   DCP	$EAEA,Y				;7
;(Indirect,X)|DCP (arg,X)|$C3| 2 | 8
   DCP	($EA,X)				;8
;(Indirect),Y|DCP (arg),Y|$D3| 2 | 8
   DCP	($EA),Y				;8



;DOP (NOP) [SKB]
;~~~~~~~~~~~~~~~
;No operation (double NOP). The argument has no significance.
;Status flags: -
;Dasm uses NOP
;Distella uses .byte $xx;.NOO...and causes the argument to be interpreted as code
;NOTE: Distella's is actually named NOOP, which will cause wraparound error in the disassembly
;Addressing  |Mnemonics  |Opc|Sz | n
;------------|-----------|---|---|---
;Zero Page   |DOP arg	|$04| 2 | 3
   NOP	$EA					;3
;Zero Page,X |DOP arg,X  |$14| 2 | 4
   NOP	$EA,X				  ;4
;Immediate   |DOP #arg   |$80| 2 | 2
   NOP	#$EA				   ;2

;duplicates...
;Immediate   |DOP #arg   |$82| 2 | 2
   .byte $82,$EA				 ;2
;Immediate   |DOP #arg   |$89| 2 | 2
   .byte $89,$EA				 ;2
;Immediate   |DOP #arg   |$C2| 2 | 2
   .byte $C2,$EA				 ;2
;Immediate   |DOP #arg   |$E2| 2 | 2
   .byte $E2,$EA				 ;2
;Zero Page   |DOP arg	|$44| 2 | 3
   .byte $44,$EA				 ;3
;Zero Page   |DOP arg	|$64| 2 | 3
   .byte $64,$EA				 ;3
;Zero Page,X |DOP arg,X  |$34| 2 | 4
   .byte $34,$EA				 ;4
;Zero Page,X |DOP arg,X  |$54| 2 | 4
   .byte $54,$EA				 ;4
;Zero Page,X |DOP arg,X  |$74| 2 | 4
   .byte $74,$EA				 ;4
;Zero Page,X |DOP arg,X  |$D4| 2 | 4
   .byte $D4,$EA				 ;4
;Zero Page,X |DOP arg,X  |$F4| 2 | 4
   .byte $F4,$EA				 ;4


;ISC (ISB) [INS]
;~~~~~~~~~~~~~~~
;Increase memory by one, then subtract memory from accumulator
;(with borrow). Status flags: N,V,Z,C
;Dasm uses ISB
;Distella uses .byte $xx;.ISB...and causes the argument to be interpreted as code
;Addressing  |Mnemonics  |Opc|Sz | n
;------------|-----------|---|---|---
;Zero Page   |ISC arg	|$E7| 2 | 5
   ISB	$EA					;5
;Zero Page,X |ISC arg,X  |$F7| 2 | 6
   ISB	$EA,X				  ;6
;Absolute	|ISC arg	|$EF| 3 | 6
   ISB	$EAEA				  ;6
;Absolute,X  |ISC arg,X  |$FF| 3 | 7
   ISB	$EAEA,X				;7
;Absolute,Y  |ISC arg,Y  |$FB| 3 | 7
   ISB	$EAEA,Y				;7
;(Indirect,X)|ISC (arg,X)|$E3| 2 | 8
   ISB	($EA,X)				;8
;(Indirect),Y|ISC (arg),Y|$F3| 2 | 8
   ISB	($EA),Y				;8


;KIL (JAM) [HLT]
;~~~~~~~~~~~~~~~
;Stop program counter (processor lock up).
;Status flags: -
;Dasm uses .byte $xx
;Distella uses .byte $xx;.JAM
;Addressing  |Mnemonics  |Opc|Sz | n
;------------|-----------|---|---|---
;Implied	 |KIL		|$02| 1 | -
   .byte $02					 ;0
;Implied	 |KIL		|$12| 1 | -
   .byte $12					 ;0
;Implied	 |KIL		|$22| 1 | -
   .byte $22					 ;0
;Implied	 |KIL		|$32| 1 | -
   .byte $32					 ;0
;Implied	 |KIL		|$42| 1 | -
   .byte $42					 ;0
;Implied	 |KIL		|$52| 1 | -
   .byte $52					 ;0
;Implied	 |KIL		|$62| 1 | -
   .byte $62					 ;0
;Implied	 |KIL		|$72| 1 | -
   .byte $72					 ;0
;Implied	 |KIL		|$92| 1 | -
   .byte $92					 ;0
;Implied	 |KIL		|$B2| 1 | -
   .byte $B2					 ;0
;Implied	 |KIL		|$D2| 1 | -
   .byte $D2					 ;0
;Implied	 |KIL		|$F2| 1 | -
   .byte $F2					 ;0


;LAR (LAE) [LAS]
;~~~~~~~~~~~~~~~
;AND memory with stack pointer, transfer result to accumulator,
;X register and stack pointer.
;Status flags: N,Z
;Dasm uses LAS
;Distella uses .byte $BB;.LAS...and causes the argument to be interpreted as code
;Addressing  |Mnemonics  |Opc|Sz | n
;------------|-----------|---|---|---
;Absolute,Y  |LAR arg,Y  |$BB| 3 | 4 *
   LAS	$EAEA,Y				;4*


;LAX (LAX) [LAX]
;~~~~~~~~~~~~~~~
;Load accumulator and X register with memory.
;Status flags: N,Z
;Dasm uses LAX
;Distella uses .byte $xx;.LAX...and causes the argument to be interpreted as code
;Addressing  |Mnemonics  |Opc|Sz | n
;------------|-----------|---|---|---
;Zero Page   |LAX arg	|$A7| 2 | 3
   LAX	$EA					;3
;Zero Page,Y |LAX arg,Y  |$B7| 2 | 4
   LAX	$EA,Y				  ;4
;Absolute	|LAX arg	|$AF| 3 | 4
   LAX	$EAEA				  ;4
;Absolute,Y  |LAX arg,Y  |$BF| 3 | 4 *
   LAX	$EAEA,Y				;4*
;(Indirect,X)|LAX (arg,X)|$A3| 2 | 6
   LAX	($EA,X)				;6
;(Indirect),Y|LAX (arg),Y|$B3| 2 | 5 *
   LAX	($EA),Y				;5*


;NOP (NOP) [NOP]
;~~~~~~~~~~~~~~~
;No operation
;Status flags: -
;NOTE: Duplicates of the NOP (implied) opcode
;Dasm uses .byte $xx
;Distella uses .byte $xx;.NOO
;NOTE: Distella's is actually named NOOP, which will cause wraparound error in the disassembly
;Addressing  |Mnemonics  |Opc|Sz | n
;------------|-----------|---|---|---
;Implied	 |NOP		|$1A| 1 | 2
   .byte $1A					 ;2
;Implied	 |NOP		|$3A| 1 | 2
   .byte $3A					 ;2
;Implied	 |NOP		|$5A| 1 | 2
   .byte $5A					 ;2
;Implied	 |NOP		|$7A| 1 | 2
   .byte $7A					 ;2
;Implied	 |NOP		|$DA| 1 | 2
   .byte $DA					 ;2
;Implied	 |NOP		|$FA| 1 | 2
   .byte $FA					 ;2


;RLA (RLA) [RLA]
;~~~~~~~~~~~~~~~
;Rotate one bit left in memory, then AND accumulator with
;memory. Status flags: N,Z,C
;Dasm uses RLA
;Distella uses .byte $xx;.RLA...and causes the argument to be interpreted as code
;Addressing  |Mnemonics  |Opc|Sz | n
;------------|-----------|---|---|---
;Zero Page   |RLA arg	|$27| 2 | 5
   RLA	$EA					;5
;Zero Page,X |RLA arg,X  |$37| 2 | 6
   RLA	$EA,X				  ;6
;Absolute	|RLA arg	|$2F| 3 | 6
   RLA	$EAEA				  ;6
;Absolute,X  |RLA arg,X  |$3F| 3 | 7
   RLA	$EAEA,X				;7
;Absolute,Y  |RLA arg,Y  |$3B| 3 | 7
   RLA	$EAEA,Y				;7
;(Indirect,X)|RLA (arg,X)|$23| 2 | 8
   RLA	($EA,X)				;8
;(Indirect),Y|RLA (arg),Y|$33| 2 | 8
   RLA	($EA),Y				;8


;RRA (RRA) [RRA]
;~~~~~~~~~~~~~~~
;Rotate one bit right in memory, then add memory to accumulator
;(with carry).
;Status flags: N,V,Z,C
;Dasm uses RRA
;Distella uses .byte $xx;.RRA...and causes the argument to be interpreted as code
;Addressing  |Mnemonics  |Opc|Sz | n
;------------|-----------|---|---|---
;Zero Page   |RRA arg	|$67| 2 | 5
   RRA	$EA					;5
;Zero Page,X |RRA arg,X  |$77| 2 | 6
   RRA	$EA,X				  ;6
;Absolute	|RRA arg	|$6F| 3 | 6
   RRA	$EAEA				  ;6
;Absolute,X  |RRA arg,X  |$7F| 3 | 7
   RRA	$EAEA,X				;7
;Absolute,Y  |RRA arg,Y  |$7B| 3 | 7
   RRA	$EAEA,Y				;7
;(Indirect,X)|RRA (arg,X)|$63| 2 | 8
   RRA	($EA,X)				;8
;(Indirect),Y|RRA (arg),Y|$73| 2 | 8
   RRA	($EA),Y				;8


;SBC (SBC) [SBC]
;~~~~~~~~~~~~~~~
;The same as the legal opcode $E9 (SBC #byte)
;Status flags: N,V,Z,C
;Dasm uses .byte $EB
;Distella uses .byte $EB;.USB...and causes the argument to be interpreted as code
;Addressing  |Mnemonics  |Opc|Sz | n
;------------|-----------|---|---|---
;Immediate   |SBC #byte  |$EB| 2 | 2
   .byte $EB,$EA				  ;2


;SLO (SLO) [ASO]
;~~~~~~~~~~~~~~~
;Shift left one bit in memory, then OR accumulator with memory.
;Status flags: N,Z,C
;Dasm uses SLO
;Distella uses .byte $xx;.SLO...and causes the argument to be interpreted as code
;Addressing  |Mnemonics  |Opc|Sz | n
;------------|-----------|---|---|---
;Zero Page   |SLO arg	|$07| 2 | 5
   SLO	$EA					;5
;Zero Page,X |SLO arg,X  |$17| 2 | 6
   SLO	$EA,X				  ;6
;Absolute	|SLO arg	|$0F| 3 | 6
   SLO	$EAEA				  ;6
;Absolute,X  |SLO arg,X  |$1F| 3 | 7
   SLO	$EAEA,X				;7
;Absolute,Y  |SLO arg,Y  |$1B| 3 | 7
   SLO	$EAEA,Y				;7
;(Indirect,X)|SLO (arg,X)|$03| 2 | 8
   SLO	($EA,X)				;8
;(Indirect),Y|SLO (arg),Y|$13| 2 | 8
   SLO	($EA),Y				;8


;SRE (SRE) [LSE]
;~~~~~~~~~~~~~~~
;Shift right one bit in memory, then EOR accumulator with
;memory. Status flags: N,Z,C
;Dasm uses SRE
;Distella uses .byte $xx;.SRE...and causes the argument to be interpreted as code
;Addressing  |Mnemonics  |Opc|Sz | n
;------------|-----------|---|---|---
;Zero Page   |SRE arg	|$47| 2 | 5
   SRE	$EA					;5
;Zero Page,X |SRE arg,X  |$57| 2 | 6
   SRE	$EA,X				  ;6
;Absolute	|SRE arg	|$4F| 3 | 6
   SRE	$EAEA				  ;6
;Absolute,X  |SRE arg,X  |$5F| 3 | 7
   SRE	$EAEA,X				;7
;Absolute,Y  |SRE arg,Y  |$5B| 3 | 7
   SRE	$EAEA,Y				;7
;(Indirect,X)|SRE (arg,X)|$43| 2 | 8
   SRE	($EA,X)				;8
;(Indirect),Y|SRE (arg),Y|$53| 2 | 8
   SRE	($EA),Y				;8


;SXA (SHX) [XAS]
;~~~~~~~~~~~~~~~
;AND X register with the high byte of the target address of the
;argument + 1. Store the result in memory.
;M = X AND HIGH(arg) + 1
;Status flags: -
;Dasm uses SHX
;Distella uses .byte $9E;.SHX...and causes the argument to be interpreted as code
;Addressing  |Mnemonics  |Opc|Sz | n
;------------|-----------|---|---|---
;Absolute,Y  |SXA arg,Y  |$9E| 3 | 5
   SHX	$EAEA,Y				;5


;SYA (SHY) [SAY]
;~~~~~~~~~~~~~~~
;AND Y register with the high byte of the target address of the
;argument + 1. Store the result in memory.
;M = Y AND HIGH(arg) + 1
;Status flags: -
;Dasm uses SHY
;Distella uses .byte $9C;.SHY...and causes the argument to be interpreted as code
;Addressing  |Mnemonics  |Opc|Sz | n
;------------|-----------|---|---|---
;Absolute,X  |SYA arg,X  |$9C| 3 | 5
   SHY	$EAEA,X				;5


;TOP (NOP) [SKW]
;~~~~~~~~~~~~~~~
;No operation (tripple NOP). The argument has no significance.
;Status flags: -
;Dasm uses NOP
;Distella uses .byte $xx;.NOO...and causes the argument to be interpreted as code
;NOTE: Distella's is actually named NOOP, which will cause wraparound error in the disassembly
;Addressing  |Mnemonics  |Opc|Sz | n
;------------|-----------|---|---|---
;Absolute	|TOP arg	|$0C| 3 | 4
   NOP	$EAEA				  ;4*
;Absolute,X  |TOP arg,X  |$1C| 3 | 4 *
   NOP	$EAEA,X				;4*

;duplicates...
;Absolute,X  |TOP arg,X  |$3C| 3 | 4 *
   .byte $3C,$EA				 ;4*
;Absolute,X  |TOP arg,X  |$5C| 3 | 4 *
   .byte $5C,$EA				 ;4*
;Absolute,X  |TOP arg,X  |$7C| 3 | 4 *
   .byte $7C,$EA				 ;4*
;Absolute,X  |TOP arg,X  |$DC| 3 | 4 *
   .byte $DC,$EA				 ;4*
;Absolute,X  |TOP arg,X  |$FC| 3 | 4 *
   .byte $FC,$EA				 ;4*


;XAA (ANE) [XAA]
;~~~~~~~~~~~~~~~
;Exact operation unknown. Read the referenced documents for
;more information and observations.
;Dasm uses ANE
;Distella uses .byte $xx;.ANE...and causes the argument to be interpreted as code
;Addressing  |Mnemonics  |Opc|Sz | n
;------------|-----------|---|---|---
;Immediate   |XAA #arg   |$8B| 2 | 2
   ANE	#$EA				   ;2


;XAS (SHS) [TAS]
;~~~~~~~~~~~~~~~
;AND X register with accumulator and store result in stack
;pointer, then AND stack pointer with the high byte of the
;target address of the argument + 1. Store result in memory.
;S = X AND A, M = S AND HIGH(arg) + 1
;Status flags: -
;Dasm uses SHS
;Distella uses .byte $9B;.SHS...and causes the argument to be interpreted as code
;Addressing  |Mnemonics  |Opc|Sz | n
;------------|-----------|---|---|---
;Absolute,Y  |XAS arg,Y  |$9B| 3 | 5
   SHS	$EAEA,Y				;5

Link to comment
Share on other sites

They should be.

 

BTW here's a "use at your own risk" hack of Distella v2.10 that I use all the time. 4+letter menomics have been banished to kill that wraparound error...and it assumes that a .cfg file exists (or it automatically translates everything). Useful to me. Dunno about anyone else.

 

 

/waits for people to complain

D3.zip

Link to comment
Share on other sites

Have you ever tried DIS6502? I think it's intended for disassembling Atari 400/800/XL/XE programs, but it's easy to create a file that uses the Atari 2600's TIA and RIOT locations instead of all the Atari 800's locations. One of the nice things about DIS6502 is that you can do interactive disassembly-- e.g., you can flag a group of addresses as data so DIS6502 won't try to disassemble them. Also, DIS6502 can recognize "illegal" opcodes. :)

 

Michael

Link to comment
Share on other sites

Have you ever tried DIS6502? I think it's intended for disassembling Atari 400/800/XL/XE programs, but it's easy to create a file that uses the Atari 2600's TIA and RIOT locations instead of all the Atari 800's locations. One of the nice things about DIS6502 is that you can do interactive disassembly-- e.g., you can flag a group of addresses as data so DIS6502 won't try to disassemble them. Also, DIS6502 can recognize "illegal" opcodes. :)

 

Michael

I have used DIS6502 for all of my 8 bit computer to 5200 conversions and can recommend it. Only complaint I have (unless it has been fixed) is you could not tag data as being low byte or high byte of a word unless it is part of an instruction which is useful if you have tables that are built that way. Maybe the latest version allows that. IIRC, I also don't think it is always good at prompting you to save changes. It does let you view data in graphics mode though which it nice.

 

--Ken

Link to comment
Share on other sites

BTW here's a "use at your own risk" hack of Distella v2.10 that I use all the time. 4+letter menomics have been banished to kill that wraparound error...and it assumes that a .cfg file exists (or it automatically translates everything). Useful to me. Dunno about anyone else.

Have you run across commercial games that have used undocumented opcodes? I haven't found any yet but I'm curious if any used them.

Link to comment
Share on other sites

FWIW, there was a Distella 3.0 released, that had some of the justification issues solved.

It added 7800 support, but did not add illegal opcode support.

 

It was released back in 2003:

http://www.atariage.com/forums/index.php?showtopic=24981

But, the hosted site no longer has it.

 

I had some info posted about it in a link to one of my ancient websites:

http://pages.cs.wisc.edu/~harvey/7800/distella.html

I kept the distella.zip posted at the hosted site, so that link is lost.

 

I did dig up a copy from my computer, and am adding it to this post.

Anyone want to be the new host?

Maybe we can fuse in Nukey's changes, and make a Distella 4.0?

 

distella30.zip

 

-John

Link to comment
Share on other sites

Anyone want to be the new host?

Maybe we can fuse in Nukey's changes, and make a Distella 4.0?

I don't have the capacity to host or maintain Distella, but what about SourceForge or something? As far as changes, aside from supporting "illegal" opcodes, another thing that would be cool is if a switch could be added to specify the bankswitch method, so Distella could disassemble bankswitched ROMs. By the way, what language is Distella written in?

 

Michael

Link to comment
Share on other sites

Straight-up C.

I was afraid you were going to say that! ;) I do have Visual C++ 6.0, but I'm not a C or C++ programmer-- I got it just to dabble, and I never really did much dabbling after I got it. Are there any free C compilers that would be perfectly suited to compiling Distella?

 

Michael

Link to comment
Share on other sites

If I remember right (this is 5 years ago), I compiled with Borland Turbo C.

I *think* it was abandonware at the time, easy to install, and easy to work with.

Of course, that's all on a hard drive on a disconnected computer at the moment.

Let me know if you want/need me to look it up to see what version it is.

 

I'm sure people on these forums may have better recommendations or be able to point you to a place to get Turbo C on the web.

 

-John

Link to comment
Share on other sites

Straight-up C.

I was afraid you were going to say that! ;) I do have Visual C++ 6.0, but I'm not a C or C++ programmer-- I got it just to dabble, and I never really did much dabbling after I got it. Are there any free C compilers that would be perfectly suited to compiling Distella?

 

Michael

DJGPP would be a good choice. It's what I use for bB.

Link to comment
Share on other sites

Have you run across commercial games that have used undocumented opcodes? I haven't found any yet but I'm curious if any used them.

 

I don't believe that there are any. Programs at that time (regardless of platform) avoided the use of them like the plague...probably because any future revisions of the chip might have not supported them...or had the same effect as their predecessor. I think it's safe to say that the chip's design is final by now ;)

 

The closest I've seen is the use of the BIT opcode to skip ahead a byte or two...but that really isn't the same thing (just using an existing instruction in an "undocumented" way).

Link to comment
Share on other sites

As far as changes, aside from supporting "illegal" opcodes, another thing that would be cool is if a switch could be added to specify the bankswitch method, so Distella could disassemble bankswitched ROMs.

 

This was discussed in the past. The general opinion was that if somebody already understands what bankswitching does, disassembly of programs that use it is just as easy as regular non-BS programs (i.e. if Distella could automatically do it for you, you still shouldn't be moving things around in the resulting disassembly unless you already know it's safe to do so). Creation of .cfg files is no big deal...it takes just a few minutes unless the program is -really- conveluted.

 

Score: more trouble than it's worth. Seperating code from data is just the first (easy) step.

Link to comment
Share on other sites

Score: more trouble than it's worth. Seperating code from data is just the first (easy) step.

 

One thing that would help with DiStella would be the ability to specify a list of known entry points, and having DiStella automatically classify as code any memory that is reachable via those entry points.

Link to comment
Share on other sites

DJGPP would be a good choice. It's what I use for bB.

Okay, I'll check it out. The thing is, one of the reasons I never got very far at dabbling with Visual C++ 6.0 was because I had gotten it purely to tinker with the source of a freeware astrology program, to see if I could make any modifications to it-- and I couldn't even figure out how to compile the sucker, because I had no clue how to set everything up (i.e., all the directories, resource files, makefile, etc., for the project), plus the project had originally been set up to be compiled using some other C or C+ or C++ package, rather than Visual C++ 6.0, so some of the operating system resource files (?) that it was looking for had been replaced by other files in Visual C++ 6.0. Years later a C++ programmer went through the source, did a lot of cleanup work, organized the files and directories, and made the changes necessary to compile it with Visual C++ 6.0-- and when I downloaded the source code from *his* site, I was finally able to compile it! Hooray! :party:

 

Being a professional programmer, I know how important it can be to have everything set up "just so" when you compile a project. You need all the right files (and right versions of the files) in all the right directories, use all the right command switches, have the batch file or make file or whatchamacallit file in the right place with the right contents, etc. If one little thing is out of whack, you either get a compile error, or maybe it acts like it compiles correctly but the compiled program refuses to behave correctly when you execute it. So I'm always a little leery of poking around with C source for a project that is someone else's baby, especially since I'm *not* a C programmer (although I can muddle my way around in it).

 

Michael

Link to comment
Share on other sites

The closest I've seen is the use of the BIT opcode to skip ahead a byte or two...but that really isn't the same thing (just using an existing instruction in an "undocumented" way).

Actually, that was a pretty well-known and oft-used technique, and it was documented in articles and books about 6502 programming-- even if it wasn't actually an "intended use" for the BIT instruction.

 

Michael

Link to comment
Share on other sites

Score: more trouble than it's worth. Seperating code from data is just the first (easy) step.

 

One thing that would help with DiStella would be the ability to specify a list of known entry points, and having DiStella automatically classify as code any memory that is reachable via those entry points.

I disagree about the worth thing. It isn't just a matter of whether or not a knowledgeable person can do it themselves if they understand the way a particular bankswitch method behaves. It's also the issue of having to split up files that are larger than 4K-- and not just split them into two or more 4K chunks, but split them into chunks that are the right size and number (e.g., four 2K chunks instead of two 4K chunks). And as supercat pointed out, it's also the issue of entry points, plus bankswitching hotspots, etc. But yeah, I can see where this could be a real pain to maintain, because once upon a time there were just a few well-known bankswitching methods; but these days it seems like you can't even get through another year without people like supercat inventing at least one new bankswitching scheme. :D

 

Anyway, it would be really nice if we could disassemble a bankswitched ROM without having to split it up into separate 4K (or 2K) files first, correctly disassemble each of those files separately (as far as the ORG or RORG addresses, etc.), and then try to work out the address references correctly. Sure, it would be a chore to add them all to Distella; but if we start with the simplest classic methods first-- which should be the easiest to add-- then we could slowly but steadily add the rest.

 

Michael

Link to comment
Share on other sites

The latter is what I meant by the use of the word "undocumented" (hence, the quotes). Undocumented = unintended.

 

One thing that would help with DiStella would be the ability to specify a list of known entry points, and having DiStella automatically classify as code any memory that is reachable via those entry points.

 

I agree...but bankswitch hotspot accesses that use an index register to hit a specific bank could throw a monkey in the wrench. The same could be said of unconditional branching that exists above a data table. The user is still required to look through the code at least once after an automatic test disassembly.

Link to comment
Share on other sites

I agree...but bankswitch hotspot accesses that use an index register to hit a specific bank could throw a monkey in the wrench.

 

Anyone disassembling such code would have to recognize every bank that could be triggered via such a hotspot, and add an explicit entry point for each one. In some cases, one might also have to explicitly mark that the instruction following a particular branch, call, or memory-access instruction is not reachable. Nonetheless, being able to mark that an instruction is reachable and have the disassembler automatically mark all reachable parts of the memory image as code would be nicer than having to explicitly go in and add each different region.

Link to comment
Share on other sites

I think it's safe to say that the chip's design is final by now ;)

 

Almost, but not quite - the CPU in the FB2 is a prime example, and I believe the 2600 Jr has some issues with illegal opcodes too...?

 

It's not about chip design at all, really. Illegal opcodes arose from holes in the instruction set on the chip, and happen to work purely by chance thanks to the internal layout of the processor. Any implementation of a 6502 is NOT guaranteed to support any undefined opcodes, and certainly not in any consistent manner.

Link to comment
Share on other sites

I don't remember hearing that the FB2 had any issues with illegal opcodes; all its incompatibility issues were with its TIA revision, I thought.

 

And AFAIK the 2600 Jr is the same situation - the 6507 in it is functionally identical; all its issues are with its TIA.

Link to comment
Share on other sites

I don't remember hearing that the FB2 had any issues with illegal opcodes; all its incompatibility issues were with its TIA revision, I thought.

 

And AFAIK the 2600 Jr is the same situation - the 6507 in it is functionally identical; all its issues are with its TIA.

 

There are some TIA differences in the FB2 (e.g. Cosmic Ark starfield won't work), but there are also some unsupported opcodes that batari found: http://www.atariage.com/forums/index.php?s...st&p=954273

ARR and SBX (at least) don't work, and possibly more.

 

For the 2600 Jr you're probably right about it being just TIA differences, though.

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