home *** CD-ROM | disk | FTP | other *** search
/ 8bitfiles.net/archives / archives.tar / archives / genie-commodore-file-library / Information / HACKING6B.SFX / hacking6b
Encoding:
Text File  |  1993-09-17  |  28.8 KB  |  695 lines

  1. _Garbage appearing_
  2.  
  3. When we open the top and bottom borders, some graphics may appear. Even
  4. though VIC has already completed the graphics data fetches for the screen
  5. area, it will still fetch data for every character position in top and bottom
  6. borders. This will not do any harm though, because it does not generate any
  7. bad lines and happens during video fetch cycles [see Missing Cycles article].
  8. VIC reads the data from the last address in the current video bank, which is
  9. normally $3fff and displays this over and over again.
  10.  
  11. If we change the data in this address in the border area, the change will be
  12. visible right away. And if you synchronize the routine to the beam position,
  13. you can have a different value on each line. If there is nothing else to do
  14. in the border, you can get seven different values on each scan line.
  15.  
  16. The bad thing about this graphics is that it is impossible to change its
  17. color - it is always black. It is of course possible to use inverted graphics
  18. and change the background color. And if you have different data on each line,
  19. you can as easily have different color(s) on each line too.
  20.  
  21. If you don't use $3fff for any effects, it is a good idea to set it to zero,
  22. but remember to check that you do not store anything important in that
  23. address. In one demo I just cleared $3fff and it was right in the middle of
  24. another packed demopart. It took some time to find out what was wrong with
  25. the other part.
  26.  
  27.  
  28. _Horizontal scrolling_
  29.  
  30. This new graphics data also obeys the horizontal scroll register ($D016), so
  31. you can do limited tech-tech effects in the border too. You can also use
  32. sprites and open the sideborders. You can see an example of the tech-tech
  33. effect in the first example program. Multicolor mode select has no effect
  34. on this data. You can read more about tech-tech effects in a future article.
  35.  
  36.  
  37. _Example routine_
  38.  
  39. The example program will show how to open the top and bottom borders and how
  40. to use the $3fff-graphics. It is fairly well commented, so just check it for
  41. details. The program uses a sprite to do the synchronization [see Missing
  42. Cycles article] and reads a part of the character ROM to the display data
  43. buffer. To be honest, I might add that this is almost the same routine than
  44. the one in the Missing Cycles article. I have included both PAL and NTSC
  45. versions of the executables.
  46.  
  47. --------------------------------------------------------------------------
  48. The example program - $3fff-graphics
  49.  
  50. IMAGE0= $CE00   ; First graphics piece to show
  51. IMAGE1= $CF00   ; Second piece
  52. TECH=   $CD00   ; x-shift
  53. RASTER= $FA     ; Rasterline for the interrupt
  54. DUMMY=  $CFFF   ; Dummy-address for timing (refer to missing_cycles-article)
  55.  
  56. *= $C000
  57.         SEI             ; Disable interrupts
  58.         LDA #$7F        ; Disable timer interrupts (CIA)
  59.         STA $DC0D
  60.         LDA #$01        ; Enable raster interrupts (VIC)
  61.         STA $D01A
  62.         STA $D015       ; Enable the timing sprite
  63.         LDA #<IRQ
  64.         STA $0314       ; Interrupt vector to our routine
  65.         LDA #>IRQ
  66.         STA $0315
  67.         LDA #RASTER     ; Set the raster compare (9th bit will be set
  68.         STA $D012       ;  inside the raster routine)
  69.         LDA #RASTER-20  ; Sprite is situated 20 lines before the interrupt
  70.         STA $D001
  71.  
  72.         LDX #111
  73.         LDY #0
  74.         STY $D017       ; Disable y-expand
  75.         LDA #$32
  76.         STA $01         ; Select Character ROM
  77. LOOP0   LDA $D000,X
  78.         STA IMAGE0,Y    ; Copy a part of the charset to be the graphics
  79.         STA IMAGE0+112,Y
  80.         LDA $D800,X
  81.         STA IMAGE1,Y
  82.         STA IMAGE1+112,Y
  83.         INY             ; Until we copied enough
  84.         DEX
  85.         BPL LOOP0
  86.         LDA #$37        ; Char ROM out of the address space
  87.         STA $01
  88.  
  89.         LDY #15
  90. LOOP1   LDA XPOS,Y      ; Take a half of a sinus and mirror it to make
  91.         STA TECH,Y      ;  a whole cycle and then copy it as many times
  92.         STA TECH+32,Y   ;   as necassary
  93.         LDA #24
  94.         SEC
  95.         SBC XPOS,Y
  96.         STA TECH+16,Y
  97.         STA TECH+48,Y
  98.         DEY
  99.         BPL LOOP1
  100.         LDY #64
  101. LOOP2   LDA TECH,Y
  102.         STA TECH+64,Y
  103.         STA TECH+128,Y
  104.         DEY
  105.         BPL LOOP2
  106.         CLI             ; Enable interrupts
  107.         RTS             ; Return to basic (?)
  108.  
  109.  
  110. IRQ     LDA #$13        ; Open the bottom border (top border will open too)
  111.         STA $D011
  112.         NOP
  113.         LDY #111        ; Reduce for NTSC ?
  114.         INC DUMMY       ; Do the timing with a sprite
  115.         BIT $EA         ; Wait a bit (add a NOP for NTSC)
  116.  
  117. LOOP3   LDA TECH,Y      ; Do the x-shift
  118.         STA $D016
  119. FIRST   LDX IMAGE0,Y    ; Load the graphics to registers
  120. SECOND  LDA IMAGE1,Y
  121.         STA $3FFF       ; Alternate the graphics
  122.         STX $3FFF
  123.         STA $3FFF
  124.         STX $3FFF
  125.         STA $3FFF
  126.         STX $3FFF
  127.         STA $3FFF
  128.         STX $3FFF
  129.         STA $3FFF
  130.         STX $3FFF
  131.         LDA #0          ; Throw away 2 cycles (add a NOP for NTSC)
  132.         DEY
  133.         BPL LOOP3
  134.  
  135.         STA $3FFF       ; Clear the graphics
  136.         LDA #8
  137.         STA $D016       ; x-scroll to normal
  138.         LDA #$1B
  139.         STA $D011       ; Normal screen (be ready to open the border again)
  140.         LDA #111
  141.         DEC FIRST+1     ; Move the graphics by changing the low byte of the
  142.         BPL OVER        ;  load instruction
  143.         STA FIRST+1
  144. OVER    SEC
  145.         SBC FIRST+1
  146.         STA SECOND+1    ; Another graphics goes to opposite direction
  147.         LDA LOOP3+1     ; Move the x-shift also
  148.         SEC
  149.         SBC #2
  150.         AND #31         ; Sinus cycle is 32 bytes
  151.         STA LOOP3+1
  152.  
  153.         LDA #1
  154.         STA $D019       ; Acknowledge the raster interrupt
  155.         JMP $EA31       ; jump to the normal irq-handler
  156.  
  157. XPOS    BYT $C,$C,$D,$E,$E,$F,$F,$F,$F,$F,$F,$F,$E,$E,$D,$C
  158.         BYT $C,$B,$A,$9,$9,$8,$8,$8,$8,$8,$8,$8,$9,$9,$A,$B
  159.                         ; half of the sinus
  160.  
  161. --------------------------------------------------------------------------
  162. Basic loader for the $3fff-program (PAL)
  163.  
  164. 1 S=49152
  165. 2 DEFFNH(C)=C-48+7*(C>64)
  166. 3 CH=0:READA$,A:PRINTA$:IFA$="END"THENPRINT"<clear>":SYS49152:END
  167. 4 FORF=0TO31:Q=FNH(ASC(MID$(A$,F*2+1)))*16+FNH(ASC(MID$(A$,F*2+2)))
  168. 5 CH=CH+Q:POKES,Q:S=S+1:NEXT:IFCH=ATHEN3
  169. 6 PRINT"CHECKSUM ERROR":END
  170. 100 DATA 78A97F8D0DDCA9018D1AD08D15D0A9718D1403A9C08D1503A9FA8D12D0A9E68D,4003
  171. 101 DATA 01D0A26FA0008C17D0A9328501BD00D09900CE9970CEBD00D89900CF9970CFC8,4030
  172. 102 DATA CA10EAA9378501A00FB9DCC09900CD9920CDA91838F9DCC09910CD9930CD8810,4172
  173. 103 DATA E8A040B900CD9940CD9980CD8810F45860A9138D11D0EAA06FEEFFCF24EAB906,4554
  174. 104 DATA CD8D16D0BE53CEB91CCF8DFF3F8EFF3F8DFF3F8EFF3F8DFF3F8EFF3F8DFF3F8E,4833
  175. 105 DATA FF3F8DFF3F8EFF3FA9008810D18DFF3FA9088D16D0A91B8D11D0A96FCE85C010,4163
  176. 106 DATA 038D85C038ED85C08D88C0AD7FC018E901291F8D7FC0EE19D04C31EA0C0C0D0E,3719
  177. 107 DATA 0E0F0F0F0F0F0F0F0E0E0D0C0C0B0A09090808080808080809090A0B00000000,318
  178. 200 DATA END,0
  179.  
  180. --------------------------------------------------------------------------
  181. An uuencoded C64 executable $3fff-program (PAL)
  182.  
  183. begin 644 xFFF.64
  184. M`0@-"`$`4[(T.3$U,@`F"`(`EJ5(*$,ILD.K-#BJ-ZPH0[$V-"D`40@#`$-(?
  185. MLC`ZAT$D+$$ZF4$D.HM!)+(B14Y$(J>9(I,B.IXT.3$U,CJ``(@(!`"!1K(P/
  186. MI#,Q.E&RI4@HQBC**$$D+$:L,JHQ*2DIK#$VJJ5(*,8HRBA!)"Q&K#*J,BDI:
  187. M*0"I"`4`0TBR0TBJ43J74RQ1.E.R4ZHQ.H(ZBT-(LD&G,P#!"`8`F2)#2$5#F
  188. M2U-532!%4E)/4B(Z@``."60`@R`W.$$Y-T8X1#!$1$-!.3`Q.$0Q040P.$0QK
  189. M-40P03DW,3A$,30P,T$Y0S`X1#$U,#-!.49!.$0Q,D0P03E%-CA$+"`T,#`S9
  190. M`%L)90"#(#`Q1#!!,C9&03`P,#A#,3=$,$$Y,S(X-3`Q0D0P,$0P.3DP,$-%Y
  191. M.3DW,$-%0D0P,$0X.3DP,$-&.3DW,$-&0S@L(#0P,S``J`EF`(,@0T$Q,$5!S
  192. M03DS-S@U,#%!,#!&0CE$0T,P.3DP,$-$.3DR,$-$03DQ.#,X1CE$0T,P.3DQL
  193. M,$-$.3DS,$-$.#@Q,"P@-#$W,@#U"6<`@R!%.$$P-#!".3`P0T0Y.30P0T0Y0
  194. M.3@P0T0X.#$P1C0U.#8P03DQ,SA$,3%$,$5!03`V1D5%1D9#1C(T14%".3`V5
  195. M+"`T-34T`$(*:`"#($-$.$0Q-D0P0D4U,T-%0CDQ0T-&.$1&1C-&.$5&1C-&%
  196. M.$1&1C-&.$5&1C-&.$1&1C-&.$5&1C-&.$1&1C-&.$4L(#0X,S,`CPII`(,@'
  197. M1D8S1CA$1D8S1CA%1D8S1D$Y,#`X.#$P1#$X1$9&,T9!.3`X.$0Q-D0P03DQ-
  198. M0CA$,3%$,$$Y-D9#13@U0S`Q,"P@-#$V,P#<"FH`@R`P,SA$.#5#,#,X140X+
  199. M-4,P.$0X.$,P040W1D,P,3A%.3`Q,CDQ1CA$-T9#,$5%,3E$,#1#,S%%03!#.
  200. M,$,P1#!%+"`S-S$Y`"@+:P"#(#!%,$8P1C!&,$8P1C!&,$8P13!%,$0P0S!#P
  201. M,$(P03`Y,#DP.#`X,#@P.#`X,#@P.#`Y,#DP03!",#`P,#`P,#`L(#,Q.``T>
  202. -"\@`@R!%3D0L,````#@P1
  203. ``
  204. end
  205. size 823
  206. --------------------------------------------------------------------------
  207. An uuencoded C64 executable $3fff-program (NTSC)
  208.  
  209. begin 644 xfff-ntsc.64
  210. M`0@-"`$`4[(T.3$U,@`F"`(`EJ5(*$,ILD.K-#BJ-ZPH0[$V-"D`40@#`$-(?
  211. MLC`ZAT$D+$$ZF4$D.HM!)+(B14Y$(J>9(I,B.IXT.3$U,CJ``(@(!`"!1K(P/
  212. MI#,Q.E&RI4@HQBC**$$D+$:L,JHQ*2DIK#$VJJ5(*,8HRBA!)"Q&K#*J,BDI:
  213. M*0"I"`4`0TBR0TBJ43J74RQ1.E.R4ZHQ.H(ZBT-(LD&G,P#!"`8`F2)#2$5#F
  214. M2U-532!%4E)/4B(Z@`#'"%H`@``4"60`@R`W.$$Y-T8X1#!$1$-!.3`Q.$0QX
  215. M040P.$0Q-40P03DW,3A$,30P,T$Y0S`X1#$U,#-!.49!.$0Q,D0P03E%-CA$H
  216. M+"`T,#`S`&$)90"#(#`Q1#!!,C9&03`P,#A#,3=$,$$Y,S(X-3`Q0D0P,$0PX
  217. M.3DP,$-%.3DW,$-%0D0P,$0X.3DP,$-&.3DW,$-&0S@L(#0P,S``K@EF`(,@H
  218. M0T$Q,$5!03DS-S@U,#%!,#!&0CE$14,P.3DP,$-$.3DR,$-$03DQ.#,X1CE$`
  219. M14,P.3DQ,$-$.3DS,$-$.#@Q,"P@-#$W-@#["6<`@R!%.$$P-#!".3`P0T0Y8
  220. M.30P0T0Y.3@P0T0X.#$P1C0U.#8P03DQ,SA$,3%$,$5!03`V1D5%1D9#1C(T+
  221. M14%%04(Y+"`T-S@R`$@*:`"#(#`P0T0X1#$V1#!"13`P0T5".3`P0T8X1$9&>
  222. M,T8X149&,T8X1$9&,T8X149&,T8X1$9&,T8X149&,T8X1$9&,T8L(#0U.#``?
  223. ME0II`(,@.$5&1C-&.$1&1C-&.$5&1C-&14%!.3`P.#@Q,$0P.$1&1C-&03DP`
  224. M.#A$,39$,$$Y,4(X1#$Q1#!!.39&0T4X-BP@-#,S,0#B"FH`@R!#,#$P,#,XY
  225. M1#@V0S`S.$5$.#9#,#A$.#E#,$%$.#!#,#$X13DP,3(Y,48X1#@P0S!%13$YO
  226. M1#`T0S,Q14$P0S!#+"`S.3`U`"X+:P"#(#!$,$4P13!&,$8P1C!&,$8P1C!&W
  227. M,$4P13!$,$,P0S!",$$P.3`Y,#@P.#`X,#@P.#`X,#@P.3`Y,$$P0D$R,#`L%
  228. 4(#4P-P`["VP`@R!%3D0L+3$````PB
  229. ``
  230. end
  231. size 830
  232.  
  233. ==============================================================================
  234. 64 Documentation
  235. by Jarkko Sonninen, Jouko Valta, John West, and Marko M"akel"a
  236.    (sonninen@lut.fi, jopi@stekt.oulu.fi, john@ucc.gu.uwa.edu.au,
  237.     msmakela@hylk.helsinki.fi)
  238.  
  239. [Ed's Note: I'm leaving this file as is because of its intention to
  240. serve as a reference guide, and not necessarily to be presented in
  241. article format. The detail and clarity with which the authors have
  242. presented the material is wonderful!!]
  243.  
  244. #
  245. # $Id: 64doc,v 1.3 93/06/21 13:37:18 jopi Exp $
  246. #
  247. # This file is part of Commodore 64 emulator
  248. #      and Program Development System.
  249. #
  250. # See README for copyright notice
  251. #
  252. # This file contains documentation for 6502/6510/8502 instruction set.
  253. #
  254. # Written by 
  255. #   Jarkko Sonninen (sonninen@lut.fi)
  256. #   Jouko Valta     (jopi@stekt.oulu.fi)
  257. #   John West       (john@ucc.gu.uwa.edu.au)
  258. #   Marko M"akel"a  (msmakela@hylk.helsinki.fi)
  259. #
  260. # $Log: 64doc,v $
  261. # Revision 1.3  93/06/21  13:37:18  jopi
  262. #  X64 version 0.2 PL 0
  263. # Revision 1.2  93/06/21  13:07:15  jopi
  264. # *** empty log message ***
  265. #
  266. #
  267.  
  268.                 6510 Instructions by Addressing Modes
  269.  
  270.         ++++++++ Positive ++++++++++    -------- Negative ----------
  271.         00      20      40      60      80      a0      c0      e0      mode
  272.  
  273. +00     BRK     JSR     RTI     RTS     NOP*    LDY     CPY     CPX  Impl/immed
  274. +01     ORA     AND     EOR     ADC     STA     LDA     CMP     SBC  (indir,x)
  275. +02      t       t       t       t      NOP*t   LDX     NOP*t   NOP*t  ? /immed
  276. +03     SLO*    RLA*    SRE*    RRA*    SAX*    LAX*    DCP*    ISB* (indir,x)
  277. +04     NOP*    BIT     NOP*    NOP*    STY     LDY     CPY     CPX  Zeropage
  278. +05     ORA     AND     EOR     ADC     STA     LDA     CMP     SBC     -"-
  279. +06     ASL     ROL     LSR     ROR     STX     LDX     DEC     INC     -"-
  280. +07     SLO*    RLA*    SRE*    RRA*    SAX*    LAX*    DCP*    ISB*    -"-
  281.  
  282. +08     PHP     PLP     PHA     PLA     DEY     TAY     INY     INX  Implied
  283. +09     ORA     AND     EOR     ADC     NOP*    LDA     CMP     SBC  Immediate
  284. +0a     ASL     ROL     LSR     ROR     TXA     TAX     DEX     NOP  Accu/impl
  285. +0b     ANC**   ANC**   ASR**   AR
  286.  Cancel 
  287.  
  288. /duck/mailserv/hacking> 
  289.  Interrupt 
  290.  
  291. /duck/mailserv/hacking> 
  292.  
  293.                 6510 Instructions by Addressing Modes
  294.  
  295.         ++++++++ Positive ++++++++++    -------- Negative ----------
  296.         00      20      40      60      80      a0      c0      e0      mode
  297.  
  298. +00     BRK     JSR     RTI     RTS     NOP*    LDY     CPY     CPX  Impl/immed
  299. +01     ORA     AND     EOR     ADC     STA     LDA     CMP     SBC  (indir,x)
  300. +02      t       t       t       t      NOP*t   LDX     NOP*t   NOP*t  ? /immed
  301. +03     SLO*    RLA*    SRE*    RRA*    SAX*    LAX*    DCP*    ISB* (indir,x)
  302. +04     NOP*    BIT     NOP*    NOP*    STY     LDY     CPY     CPX  Zeropage
  303. +05     ORA     AND     EOR     ADC     STA     LDA     CMP     SBC     -"-
  304. +06     ASL     ROL     LSR     ROR     STX     LDX     DEC     INC     -"-
  305. +07     SLO*    RLA*    SRE*    RRA*    SAX*    LAX*    DCP*    ISB*    -"-
  306.  
  307. +08     PHP     PLP     PHA     PLA     DEY     TAY     INY     INX  Implied
  308. +09     ORA     AND     EOR     ADC     NOP*    LDA     CMP     SBC  Immediate
  309. +0a     ASL     ROL     LSR     ROR     TXA     TAX     DEX     NOP  Accu/impl
  310. +0b     ANC**   ANC**   ASR**   ARR**   ANE**   LXA**   SBX**   SBC* Immediate
  311. +0c     NOP*    BIT     JMP     JMP     STY     LDY     CPY     CPX  Absolute
  312. +0d     ORA     AND     EOR     ADC     STA     LDA     CMP     SBC     -"-
  313. +0e     ASL     ROL     LSR     ROR     STX     LDX     DEC     INC     -"-
  314. +0f     SLO*    RLA*    SRE*    RRA*    SAX*    LAX*    DCP*    ISB*    -"-
  315.  
  316. +10     BPL     BMI     BVC     BVS     BCC     BCS     BNE     BEQ  Relative
  317. +11     ORA     AND     EOR     ADC     STA     LDA     CMP     SBC  (indir),y
  318. +12      t       t       t       t       t       t       t       t      ?
  319. +13     SLO*    RLA*    SRE*    RRA*    SHA**   LAX*    DCP*    ISB* (indir),y
  320. +14     NOP*    NOP*    NOP*    NOP*    STY     LDY     NOP*    NOP* Zeropage,x
  321. +15     ORA     AND     EOR     ADC     STA     LDA     CMP     SBC     -"-
  322. +16     ASL     ROL     LSR     ROR     STX y)  LDX y)  DEC     INC     -"-
  323. +17     SLO*    RLA*    SRE*    RRA*    SAX* y) LAX* y) DCP     ISB     -"-
  324.  
  325. +18     CLC     SEC     CLI     SEI     TYA     CLV     CLD     SED  Implied
  326. +19     ORA     AND     EOR     ADC     STA     LDA     CMP     SBC  Absolute,y
  327. +1a     NOP*    NOP*    NOP*    NOP*    TXS     TSX     NOP*    NOP* Implied
  328. +1b     SLO*    RLA*    SRE*    RRA*    SHS**   LAS**   DCP*    ISB* Absolute,y
  329. +1c     NOP*    NOP*    NOP*    NOP*    SHY**   LDY     NOP*    NOP* Absolute,x
  330. +1d     ORA     AND     EOR     ADC     STA     LDA     CMP     SBC     -"-
  331. +1e     ASL     ROL     LSR     ROR     SHX**y) LDX y)  DEC     INC     -"-
  332. +1f     SLO*    RLA*    SRE*    RRA*    SHA**y) LAX* y) DCP     ISB     -"-
  333.  
  334.         Legend:
  335.  
  336.         t       Jams the machine
  337.         *t      Jams very rarely
  338.         *       Undocumented command
  339.         **      Unusual operation
  340.         y)      indexed using IY instead of IX
  341.  
  342.  
  343.  
  344.                 6510/8502 Undocumented Commands
  345.  
  346.          -- A brief explanation about what may happen while
  347.                 using don't care states.
  348.  
  349.  
  350.         ANE $8B         AC = (AC | #$EE) & IX & #byte
  351.                         same as
  352.                         AC = ((AC & #$11 & IX) | ( #$EE & IX)) & #byte
  353.  
  354.                         In real 6510/8502 the internal parameter #$11 may
  355.                         occasionally be #$10, #$01 or even #$00. This occurs
  356.                         probably when the VIC halts the processor right between
  357.                         the two clock cycles of this instruction.
  358.  
  359.         LXA $AB         C=Lehti:   AC = IX = ANE
  360.                         Alternate: AC = IX = (AC & #byte)
  361.  
  362.                         TXA and TAX have to be responsible for these.
  363.  
  364.  
  365.         SHA $93,$9F     Store (AC & IX & (ADDR_HI + 1))
  366.         SHX $9E         Store (IX & (ADDR_HI + 1))
  367.         SHY $9C         Store (IY & (ADDR_HI + 1))
  368.         SHS $9B         SHA and TXS, where X is replaced by (AC & IX).
  369.  
  370.                         Note: The value to be stored is copied also
  371.                         to ADDR_HI if page boundary is crossed.
  372.  
  373.  
  374.         SBX $CB         Carry and Decimal flags are ignored but set in 
  375.                         substraction. This is due to the CMP command,
  376.                         which is executed instead of the real SBC.
  377.  
  378.  
  379.  Many undocumented commands do not use AND between registers, the CPU just
  380.  throws the bytes to a bus simultaneously and lets the open-collector drivers
  381.  perform the AND. I.e. the command called 'SAX', which is in the STORE section
  382.  (opcodes $A0...$BF), stores the result of (AC & IX) by this way.
  383.  
  384.  More fortunate is its opposite, 'LAX' which just loads a byte simultaeously
  385.  into both AC and IX.
  386.  
  387.  
  388.         $CB  SBX   IX <- (AC & IX) - Immediate
  389.  
  390.  The 'SBX' ($CB) may seem to be very complex operation, even though it is
  391.  combination of subtraction of accumulator and parameter, as in the 'CMP'
  392.  instruction, and the command 'DEX'. As a result, both AC and IX are connected
  393.  to ALU but only the subtraction takes place. Since the comparison logic was
  394.  used, the result of subtraction should be normally ignored, but the 'DEX' now
  395.  happily stores to IX the value of (AC & IX) - Immediate.
  396.  That is why this instruction does not have any decimal mode, and it does not
  397.  affect the V flag. Also Carry flag is ignored in the subtraction but set
  398.  according to the result.
  399.  
  400.  Proof:
  401.  
  402. begin 644 vsbx
  403. M`0@9$,D'GL(H-#,IJC(U-JS"*#0T*:HR-@```*D`H#V1*Z`_D2N@09$KJ0>%
  404. M^QBE^VEZJ+$KH#F1*ZD`2"BI`*(`RP`(:-B@.5$K*4#P`E@`H#VQ*SAI`)$K
  405. JD-Z@/[$K:0"1*Y#4J2X@TO\XH$&Q*VD`D2N0Q,;[$+188/_^]_:_OK>V
  406. `
  407. end
  408.  
  409.  and
  410.  
  411. begin 644 sbx
  412. M`0@9$,D'GL(H-#,IJC(U-JS"*#0T*:HR-@```'BI`*!-D2N@3Y$KH%&1*ZD#
  413. MA?L8I?M*2)`#J1@LJ3B@29$K:$J0`ZGX+*G8R)$K&/BXJ?2B8\L)AOP(:(7]
  414. MV#B@3;$KH$\Q*Z!1\2L(1?SP`0!H1?TIM]#XH$VQ*SAI`)$KD,N@3[$K:0"1
  415. 9*Y#!J2X@TO\XH%&Q*VD`D2N0L<;[$))88-#X
  416. `
  417. end
  418.  
  419.  These test programs show if your machine is compatible with ours
  420.  regarding the opcode $CB. The first test, vsbx, shows that SBX does
  421.  not affect the V flag. The latter one, sbx, shows the rest of our
  422.  theory. The vsbx test tests 33554432 SBX combinations (16777216
  423.  different AC, IX and Immediate combinations, and two different V flag
  424.  states), and the sbx test doubles that amount (16777216*4 D and C flag
  425.  combinations). Both tests have run successfully on a C64 and a Vic20.
  426.  They ought to run on C16, +4 and the PET series as well. The tests
  427.  stop with BRK, if the opcode $CB does not work expectedly. Successful
  428.  operation ends in RTS. As the tests are very slow, they print dots on
  429.  the screen while running so that you know that the machine has
  430.  not jammed. On computers running at 1 MHz, the first test prints
  431.  approximately one dot every four seconds and a total of 2048 dots,
  432.  whereas the second one prints half that amount, one dot every seven seconds.
  433.  
  434.  If the tests fail on your machine, please let us know your processor's part
  435.  number and revision. If possible, save the executable (after it has stopped
  436.  with BRK) under another name and send it to us so that we know at which stage
  437.  the program stopped.
  438.  
  439.  The following program is a Commodore 64 executable that Marko M"akela
  440.  developed when trying to find out how the V flag is affected by SBX.
  441.  (It was believed that the SBX affects the flag in a weird way, and this
  442.  program shows how SBX sets the flag differently from SBC.)
  443.  You may find the subroutine at $C150 useful when researching other 
  444.  undocumented instructions' flags. Run the program in a machine language
  445.  monitor, as it makes use of the BRK instruction. The result tables will be
  446.  written on pages $C2 and $C3.
  447.  
  448. begin 644 sbx-c100
  449. M`,%XH`",#L&,$,&,$L&XJ8*B@LL7AOL(:(7\N#BM#L$M$,'M$L$(Q?OP`B@`
  450. M:$7\\`,@4,'N#L'0U.X0P=#/SB#0[A+!T,<``````````````)BJ\!>M#L$M
  451. L$,'=_\'0":T2P=W_PM`!8,K0Z:T.P2T0P9D`PID`!*T2P9D`PYD`!<C0Y``M
  452. `
  453. end
  454.  
  455.  
  456.  Other undocumented instructions usually cause two preceding opcodes being
  457.  executed. However 'NOP' seems to completely disappear from 'SBC' code $EB.
  458.  
  459.  The most difficult to comprehend are the rest of the instructions located on
  460.  the '$0B' line.
  461.  
  462.  All the instructions located at the positive (left) side of this line should
  463.  rotate either memory or the accumulator, but the addressing mode turns out
  464.  to be immediate!
  465.  No problem. Just read the operand, let it be ANDed with the accumulator
  466.  and finally use accumulator addressing mode for the instructions above them.
  467.  
  468.  The rest two instructions on the same line, called 'ANE' and 'LXA' ($8B and
  469.  $AB respectively) often give quite unpredictable results.
  470.  However, the most usual operation is to store ((A | #$ee) & X & #$nn) to
  471.  accumulator. Note that this does not work reliably in a real 64!
  472.  On 8502 opcode $8B uses values 8C,CC, EE, and occasionally 0C and 8E for the
  473.  OR instead of EE,EF,FE and FF used by 6510. With 8502 running at 2 MHz #$EE is
  474.  always used.
  475.  Opcode $AB does not cause this OR taking place on 8502 while 6510 always 
  476.  performs it.  Note that this behaviour depends on chip revision.
  477.  
  478.  Let's take a closer look at $8B (6510).
  479.  
  480.         AC <- IX & D & (AC | VAL)
  481.  
  482.         where VAL comes from this table:
  483.  
  484.        IX high  D high  D low   VAL
  485.         even     even    ---    $EE (1)
  486.         even     odd     ---    $EE
  487.         odd      even    ---    $EE
  488.         odd      odd      0     $EE
  489.         odd      odd     not 0  $FE (2)
  490.  
  491.  (1) If the bottom 2 bits of AC are both 1, then the LSB of the result may
  492.     be 0. The values of IX and D are different every time I run the test.
  493.     This appears to be very rare.
  494.  (2) VAL is $FE most of the time. Sometimes it is $EE - it seems to be random,
  495.     not related to any of the data. This is much more common than (1).
  496.  
  497.   In decimal mode, VAL is usually $FE.
  498.  
  499.  
  500.  Two different functions has been discovered for LAX, opcode $AB. One is
  501.  AC = IX = ANE (see above) and the other, encountered with 6510 and 8502,
  502.  is less complicated AC = IX = (AC & #byte). However, according to what is
  503.  reported, the version altering only the lowest bits of each nybble seems to
  504.  be more common.
  505.  
  506.  What happens, is that $AB loads a value into both AC and IX, ANDing
  507.  the low bit of each nybble with the corresponding bit of the old AC. However,
  508.  there are exceptions. Sometimes the low bit is cleared even when AC contains
  509.  a '1', and sometimes other bits are cleared. The exceptions seem random (they
  510.  change every time I run the test). Oops - that was in decimal mode. Much
  511.  the same with D=0.
  512.  
  513.  What causes the randomness?  Probably it is that it is marginal logic levels -
  514.  when too much wired-anding goes on, some of the signals get very close to
  515.  the threshold. Perhaps we're seeing some of them step over it. The low bit
  516.  of each nybble is special, since it has to cope with carry differently
  517.  (remember decimal mode). We never see a '0' turn into a '1'.
  518.  
  519.  Since these instructions are unpredictable, they should not be used.
  520.  
  521.  
  522.  There is still very strange instruction left, the one named SHA/X/Y, which is
  523.  the only one with only indexed addressing modes. Actually, the commands 'SHA',
  524.  'SHX' and 'SHY' are generated by the indexing algorithm.
  525.  
  526.  While using indexed addressing, effective address for page boundary crossing
  527.  is calculated as soon as possible so it does not slow down operation.
  528.  As a result, in the case of SHA/X/Y, the address and data are prosessed at the
  529.  same time making AND between the to take place. Thus, the value to be stored
  530.  by SAX, for example, is in fact (AC & IX & (ADDR_HI + 1)).
  531.  On page boundary crossing the same value is copied also to high byte of the
  532.  effective address.
  533.  
  534.  
  535.  
  536.   Register selection for load and store
  537.  
  538.    bit1 bit0    AC IX IY
  539.     0   0             x
  540.     0   1          x
  541.     1   0       x
  542.     1   1       x  x
  543.  
  544.  So, AC and IX are selected by bits 1 and 0 respectively, while ~(bit1 | bit0)
  545.  enables IY.
  546.  
  547.  Indexing is determined by bit4, even in relative addressing mode, which
  548.  is one kind of indexing.
  549.  
  550.  Lines containing opcodes xxx000x1 (01 and 03) are treated as absolute after
  551.  the effective address has been loaded into CPU.
  552.  
  553.  Zeropage,y and Absolute,y (codes 10x1 x11x) are distinquished by bit5.
  554.  
  555.  
  556.                  Decimal mode in NMOS 6500 series
  557.  
  558.    Most sources claim that the NMOS 6500 series sets the N, V and Z flags
  559.  unpredictably. Of course, this is not true. While testing how the flags are
  560.  set, I also wanted to see what happens if you use illegal BCD values.
  561.  
  562.    ADC works in Decimal mode in a quite complicated way. It is amazing how it
  563.  can do that all in a single cycle. Here's a pseudo code version of the
  564.  instruction:
  565.  
  566.         AC      accumulator
  567.         AL      low nybble of accumulator
  568.         AH      high nybble of accumulator
  569.  
  570.         C       Carry flag
  571.         Z       Zero flag
  572.         V       oVerflow flag
  573.         N       Negative flag
  574.  
  575.         s       value to be added to accumulator
  576.  
  577.         AL = (AC & 15) + (s & 15) + C;          ! Calculate the lower nybble.
  578.  
  579.         if (AL > 9)                             ! BCD fixup
  580.           AL += 6;                              ! for lower nybble
  581.  
  582.         AH = (A >> 4) + (s >> 4) + (AL > 15);   ! Calculate the upper nybble.
  583.  
  584.         Z = (AC + s + C != 0);                  ! Zero flag is set just
  585.                                                 ! like in Binary mode.
  586.  
  587.         ! Negative and Overflow flags are set with the same logic than in
  588.         ! Binary mode, but after fixing the lower nybble.
  589.  
  590.         N = (AH & 8 != 0);
  591.         V = ((AH & 8) ^ (A >> 4)) && (!(A ^ s) & 128);
  592.  
  593.         if (AH > 9)                             ! BCD fixup
  594.           AH += 6;                              ! for upper nybble
  595.  
  596.         
  597.  
  598.         ! Carry is the only flag set after fixing the result.
  599.  
  600.         C = (AH > 15);
  601.         AC = ((AH << 4) | (AL & 15)) & 255;
  602.  
  603.  
  604.    The C flag is set as the quiche eaters expect, but the N and V flags 
  605.  are set after fixing the lower nybble but before fixing the upper one.
  606.  They use the same logic than binary mode ADC. The Z flag is set before
  607.  any BCD fixup, so the D flag does not have any influence on it.
  608.  
  609.  Proof: The following test program tests all 131072 ADC combinations in
  610.         Decimal mode, and aborts with BRK if anything breaks this theory.
  611.         If everything goes well, it ends in RTS.
  612.  
  613. begin 600 dadc
  614. M 0@9",D'GL(H-#,IJC(U-JS"*#0T*:HR-@   'BI&*  A/N$_$B@+)$KH(V1
  615. M*Q@(I?PI#X7]I?LI#V7]R0J0 FD%J"D/A?VE^RGP9?PI\ C $) ":0^JL @H
  616. ML ?)H) &""@X:5\X!?V%_0AH*3W@ ! ""8"HBD7[$ JE^T7\, 28"4"H**7[
  617. M9?S0!)@) J@8N/BE^V7\V A%_= G:(3]1?W0(.;[T(?F_-"#:$D8\ )88*D=
  618. 0&&4KA?NI &4LA?RI.&S[  A%
  619.  
  620. end
  621.  
  622.    All programs in this chapter have been successfully tested on a Vic20
  623.  and a Commodore 64. They should run on C16, +4 and on the PET series as
  624.  well. If not, please report the problem to Marko M"akel"a. Each test in
  625.  this chapter should run in less than a minute at 1 MHz.
  626.  
  627.    SBC is much easier. Just like CMP, its flags are not affected by
  628.  the D flag.
  629.  
  630.  Proof:
  631.  
  632. begin 600 dsbc-cmp-flags
  633. M 0@9",D'GL(H-#,IJC(U-JS"*#0T*:HR-@   'B@ (3[A/RB XH8:66HL2N@
  634. M09$KH$R1*XII::BQ*Z!%D2N@4)$K^#BXI?OE_-@(:(7].+BE^^7\"&A%_? !
  635. 5 .;[T./F_-#?RA"_8!@X&#CEY<7%
  636.  
  637. end
  638.  
  639.  
  640.    The only difference in SBC's operation in decimal mode from binary mode
  641.  is the result-fixup:
  642.  
  643.         AC      accumulator
  644.         AL      low nybble of accumulator
  645.         AH      high nybble of accumulator
  646.  
  647.         C       Carry flag
  648.         Z       Zero flag
  649.         V       oVerflow flag
  650.         N       Negative flag
  651.  
  652.         s       value to be added to accumulator
  653.  
  654.         AL = (AC & 15) - (s & 15) - !C;         ! Calculate the lower nybble.
  655.  
  656.         if (AL & 16)                            ! BCD fixup
  657.           AL -= 6;                              ! for lower nybble
  658.  
  659.         AH = (AC >> 4) - (s >> 4) - (AL > 15);  ! Calculate the upper nybble.
  660.  
  661.         if (AH & 16)                            ! BCD fixup
  662.           AH -= 6;                              ! for upper nybble
  663.  
  664.         ! Flags are set just like in Binary mode.
  665.  
  666.         C = (AC - s - !C > 255);
  667.         Z = (AC - s - !C != 0);
  668.         V = ((AC - s - !C) ^ s) && ((AC ^ s) & 128);
  669.         N = ((AC - s - !C) & 128);
  670.  
  671.         AC = ((AH << 4) | (AL & 15)) & 255;
  672.  
  673.  
  674.    Again Z flag is set before any BCD fixup. The N and V flags are set
  675.  at any time before fixing the high nybble. The C flag may be set in any
  676.  phase.
  677.  
  678.    Decimal subtraction is easier than decimal addition, as you have to
  679.  make the BCD fixup only when a nybble flows over. In decimal addition,
  680.  you had to verify if the nybble was greater than 9. The processor has
  681.  an internal "half carry" flag for the lower nybble, and it uses it to
  682.  trigger the BCD fixup. When calculating with legal BCD values, the
  683.  lower nybble cannot flow over again when fixing it. So the processor
  684.  does not handle overflows while performing the fixup. Similarly, the
  685.  BCD fixup occurs in the high nybble only if the value flows over,
  686.  i.e. when the C flag will be cleared.
  687.  
  688.    Because SBC's flags are not affected by the Decimal mode flag, you
  689.  could guess that CMP uses the SBC logic, only setting the C flag
  690.  first. But the SBX instruction shows that CMP also temporarily clears
  691.  the D flag, although it is totally unnecessary.
  692.  
  693.