Abscissa Posted August 27, 2005 Share Posted August 27, 2005 (edited) Pardon if this is a stupid question... I've come across a strange thing (I'm using the Z26 emulator, if it makes any difference). At first, I had my VBlank loop look like this: ldx #37 VBlankLoop sta WSYNC dex bne VBlankLoop (It's a slighly modified form of what was in one of Andrew Davie's tutorials.) I was using the X register, and needed X to be 0 later on anyway, so I just looped by decrementing from 37 to 0. But then, I wanted to switch it to use A. So I changed it to this, but this now makes the screen go blank: lda #37 VBlankLoop sta WSYNC adc #$FF; Decrement, by adding the two's complement of 1 bne VBlankLoop (This was before I remembered there was a subtract instruction ) But then it worked again when I changed it to this: lda #37 VBlankLoop sta WSYNC adc #$FE; Decrement, by adding the one's complement of 1 (aka the two's complement of 2) bne VBlankLoop Which seems to tell me one of three things: 1. I've run into a strange bug in either Z26 or the 6502/6507 (doubtful) 2. The 6502 (or at least the 6507 variant) uses one's compliment arithmetic instead of two's complement (which I would find very surprising, since I didn't think one's complement was ever used in something this common) 3. I screwed up something somewhere else (entirely plausable ) But this other variant I made seems to make #1 or #2 more likely than #3: lda #37 VBlankLoop sta WSYNC sbc #1; Decrement, by subtracting 1 bne VBlankLoop That code does work, unlike adding $FF. So what do the experts think? Am I nuts for not realizing that the Atari 2600 is a one's complement machine, or have I probably just screwed up something else? (Or is there some other thing going on?) EDIT: I guess this board doesn't like bold within a code block. Edited August 27, 2005 by Abscissa Quote Link to comment Share on other sites More sharing options...
CPUWIZ Posted August 27, 2005 Share Posted August 27, 2005 Just took a quick glance and I don't see you setting or clearing the carry flag anywhere, which leads me to believe that when this code is run, the carry flag could be random. Quote Link to comment Share on other sites More sharing options...
Abscissa Posted August 27, 2005 Author Share Posted August 27, 2005 (edited) Just took a quick glance and I don't see you setting or clearing the carry flag anywhere, which leads me to believe that when this code is run, the carry flag could be random. 919770[/snapback] Took me a minute to realize why you said the carry flag instead of the zero flag . But, that's a good call, I'll try that. EDIT: Aha! That's it! I tried clearing the carry flag before each "adc #$FF", and it worked: lda #37 VBlankLoop sta WSYNC clc adc #$FF; Add two's complement of 1 bne VBlankLoop Obviously, I'll still use the subtract instruction instead. But thanks, thought I was going nuts for a minute Edited August 27, 2005 by Abscissa Quote Link to comment Share on other sites More sharing options...
CPUWIZ Posted August 27, 2005 Share Posted August 27, 2005 The reason why I said that, is the fact that adc and sbc add/subtract the immediate value and the carry from the accumulator. E.G. A = A + (immediate + carry) or A = A - (immediate + carry) Quote Link to comment Share on other sites More sharing options...
Abscissa Posted August 27, 2005 Author Share Posted August 27, 2005 The reason why I said that, is the fact that adc and sbc add/subtract the immediate value and the carry from the accumulator. E.G. A = A + (immediate + carry) or A = A - (immediate + carry) 919778[/snapback] Right, yea. Although I guess that means that even though I'm going to use the SBC instead of ADC, I should still clear the flag before starting the loop, right? (I realize I won't need it in the loop, since the loop itself won't be causing a carry.) Quote Link to comment Share on other sites More sharing options...
CPUWIZ Posted August 27, 2005 Share Posted August 27, 2005 Take a look at this... Arithmetic Instructions ======================= ADC - ADd to accumulator with Carry SBC - SuBtract from accumulator with Carry The 6502 has two arithmetic modes, binary and decimal. Both addition and subtraction implement the carry flag to track carries and borrows thereby making multibyte arithmetic simple. Note that in the case of subtraction it is necessary to SET the carry flag as it is the opposite of the carry that is subtracted. Addition should follow this form: CLC ADC ... . . ADC ... . . . Clear the carry flag, and perform all the additions. The carry between additions will be handled in the carry flag. Add from low byte to high byte. Symbolically, the net effect of an ADC instruction is: A + M + C --> A Subtraction follows the same format: SEC SBC ... . . SBC ... . . . In this case set the carry flag first and then do the subtractions. Symbolically, A - M - ~C --> A , where ~C is the opposite of C Ex.1 ---- A 16-bit addition routine. $20,$21 + $22,$23 = $24,$25 CLC clear the carry LDA $20 get the low byte of the first number ADC $22 add to it the low byte of the second STA $24 store in the low byte of the result LDA $21 get the high byte of the first number ADC $23 add to it the high byte of the second, plus carry STA $25 store in high byte of the result ... on exit the carry will be set if the result could not be contained in 16-bit number. Ex.2 ---- A 16-bit subtraction routine. $20,$21 - $22,$23 = $24,$25 SEC clear the carry LDA $20 get the low byte of the first number SBC $22 add to it the low byte of the second STA $24 store in the low byte of the result LDA $21 get the high byte of the first number SBC $23 add to it the high byte of the second, plus carry STA $25 store in high byte of the result ... on exit the carry will be set if the result produced a borrow Aside from the carry flag, arithmetic instructions also affect the N, Z, and V flags as follows: Z = 1 if result was zero, 0 otherwise N = 1 if bit 7 of the result is 1, 0 otherwise V = 1 if bit 7 of the accumulator was changed, a sign change Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.