Why does the 6502 have the BIT instruction?





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{
margin-bottom:0;
}








31















The 6502 has a bit instruction which




  • copies two of the bits into the N and V flags,

  • pretends to and the byte with the accumulator, but discards the result and only affects Z.


I'm having a hard time picturing a use for this. And curiously, it's missing any indexed or indirect addressing modes, and so can only be used absolutely or in the zero page.



(Incidentally, it's convenient also for skipping two bytes in the instruction stream in cases where you don't care what happens to the flags, but I don't imagine that's the use MOS had in mind). What kinds of things was it meant for?










share|improve this question



























  • The nature of this question is similar to that of Why does the Z80 include the RLD and RRD instructions?

    – Wilson
    May 25 at 16:00






  • 1





    Looking at the ProDOS 8 source code, BIT is used to check for a flag in bits 6 or 7, check if a number in memory is negative (again, bit 7), to read i/o memory (without destroying registers). It's also used twice as a clever hack to set the V flag (since there's a CLV instruction but no SEV instruction), and once used to hide other instructions.

    – Kelvin Sherlock
    May 25 at 17:16






  • 4





    You are mistaken, the AND affects the Z flag, not the C flag.

    – Janka
    May 25 at 18:28






  • 1





    @fadden Is it an undocumented instruction? What is the opcode?

    – berendi
    May 27 at 15:26






  • 2





    @berendi BIT imm is not a 6502 but a 65C02 instruction.Opcode is $89.

    – Raffzahn
    May 27 at 17:17


















31















The 6502 has a bit instruction which




  • copies two of the bits into the N and V flags,

  • pretends to and the byte with the accumulator, but discards the result and only affects Z.


I'm having a hard time picturing a use for this. And curiously, it's missing any indexed or indirect addressing modes, and so can only be used absolutely or in the zero page.



(Incidentally, it's convenient also for skipping two bytes in the instruction stream in cases where you don't care what happens to the flags, but I don't imagine that's the use MOS had in mind). What kinds of things was it meant for?










share|improve this question



























  • The nature of this question is similar to that of Why does the Z80 include the RLD and RRD instructions?

    – Wilson
    May 25 at 16:00






  • 1





    Looking at the ProDOS 8 source code, BIT is used to check for a flag in bits 6 or 7, check if a number in memory is negative (again, bit 7), to read i/o memory (without destroying registers). It's also used twice as a clever hack to set the V flag (since there's a CLV instruction but no SEV instruction), and once used to hide other instructions.

    – Kelvin Sherlock
    May 25 at 17:16






  • 4





    You are mistaken, the AND affects the Z flag, not the C flag.

    – Janka
    May 25 at 18:28






  • 1





    @fadden Is it an undocumented instruction? What is the opcode?

    – berendi
    May 27 at 15:26






  • 2





    @berendi BIT imm is not a 6502 but a 65C02 instruction.Opcode is $89.

    – Raffzahn
    May 27 at 17:17














31












31








31


2






The 6502 has a bit instruction which




  • copies two of the bits into the N and V flags,

  • pretends to and the byte with the accumulator, but discards the result and only affects Z.


I'm having a hard time picturing a use for this. And curiously, it's missing any indexed or indirect addressing modes, and so can only be used absolutely or in the zero page.



(Incidentally, it's convenient also for skipping two bytes in the instruction stream in cases where you don't care what happens to the flags, but I don't imagine that's the use MOS had in mind). What kinds of things was it meant for?










share|improve this question
















The 6502 has a bit instruction which




  • copies two of the bits into the N and V flags,

  • pretends to and the byte with the accumulator, but discards the result and only affects Z.


I'm having a hard time picturing a use for this. And curiously, it's missing any indexed or indirect addressing modes, and so can only be used absolutely or in the zero page.



(Incidentally, it's convenient also for skipping two bytes in the instruction stream in cases where you don't care what happens to the flags, but I don't imagine that's the use MOS had in mind). What kinds of things was it meant for?







6502 instruction-set






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited May 26 at 20:40









fadden

3,6291 gold badge15 silver badges52 bronze badges




3,6291 gold badge15 silver badges52 bronze badges










asked May 25 at 15:59









WilsonWilson

14.7k7 gold badges68 silver badges161 bronze badges




14.7k7 gold badges68 silver badges161 bronze badges
















  • The nature of this question is similar to that of Why does the Z80 include the RLD and RRD instructions?

    – Wilson
    May 25 at 16:00






  • 1





    Looking at the ProDOS 8 source code, BIT is used to check for a flag in bits 6 or 7, check if a number in memory is negative (again, bit 7), to read i/o memory (without destroying registers). It's also used twice as a clever hack to set the V flag (since there's a CLV instruction but no SEV instruction), and once used to hide other instructions.

    – Kelvin Sherlock
    May 25 at 17:16






  • 4





    You are mistaken, the AND affects the Z flag, not the C flag.

    – Janka
    May 25 at 18:28






  • 1





    @fadden Is it an undocumented instruction? What is the opcode?

    – berendi
    May 27 at 15:26






  • 2





    @berendi BIT imm is not a 6502 but a 65C02 instruction.Opcode is $89.

    – Raffzahn
    May 27 at 17:17



















  • The nature of this question is similar to that of Why does the Z80 include the RLD and RRD instructions?

    – Wilson
    May 25 at 16:00






  • 1





    Looking at the ProDOS 8 source code, BIT is used to check for a flag in bits 6 or 7, check if a number in memory is negative (again, bit 7), to read i/o memory (without destroying registers). It's also used twice as a clever hack to set the V flag (since there's a CLV instruction but no SEV instruction), and once used to hide other instructions.

    – Kelvin Sherlock
    May 25 at 17:16






  • 4





    You are mistaken, the AND affects the Z flag, not the C flag.

    – Janka
    May 25 at 18:28






  • 1





    @fadden Is it an undocumented instruction? What is the opcode?

    – berendi
    May 27 at 15:26






  • 2





    @berendi BIT imm is not a 6502 but a 65C02 instruction.Opcode is $89.

    – Raffzahn
    May 27 at 17:17

















The nature of this question is similar to that of Why does the Z80 include the RLD and RRD instructions?

– Wilson
May 25 at 16:00





The nature of this question is similar to that of Why does the Z80 include the RLD and RRD instructions?

– Wilson
May 25 at 16:00




1




1





Looking at the ProDOS 8 source code, BIT is used to check for a flag in bits 6 or 7, check if a number in memory is negative (again, bit 7), to read i/o memory (without destroying registers). It's also used twice as a clever hack to set the V flag (since there's a CLV instruction but no SEV instruction), and once used to hide other instructions.

– Kelvin Sherlock
May 25 at 17:16





Looking at the ProDOS 8 source code, BIT is used to check for a flag in bits 6 or 7, check if a number in memory is negative (again, bit 7), to read i/o memory (without destroying registers). It's also used twice as a clever hack to set the V flag (since there's a CLV instruction but no SEV instruction), and once used to hide other instructions.

– Kelvin Sherlock
May 25 at 17:16




4




4





You are mistaken, the AND affects the Z flag, not the C flag.

– Janka
May 25 at 18:28





You are mistaken, the AND affects the Z flag, not the C flag.

– Janka
May 25 at 18:28




1




1





@fadden Is it an undocumented instruction? What is the opcode?

– berendi
May 27 at 15:26





@fadden Is it an undocumented instruction? What is the opcode?

– berendi
May 27 at 15:26




2




2





@berendi BIT imm is not a 6502 but a 65C02 instruction.Opcode is $89.

– Raffzahn
May 27 at 17:17





@berendi BIT imm is not a 6502 but a 65C02 instruction.Opcode is $89.

– Raffzahn
May 27 at 17:17










5 Answers
5






active

oldest

votes


















40
















Early MOS documentation (KIM-1 Programming Manual, Synertek SY6500/MCS6500 Microcomputer Programming manual, etc) states:




The BIT instruction actually combines two instructions from
the PDP-11 and MC6800, that of TST (Test Memory) and (BIT Test).



...



In addition to the nondestructive feature of the BIT which
allows us to isolate an individual bit by use of the branch equal or
branch no equal test, two modifications to the PDP-11 version of that
instruction have been made in the MCS650X microprocessor. These are
to allow a test of bit 7 and bit 6 of the field examined with the BIT
test. This feature is particularly useful in serving polled interrupts
and particularly in dealing with the MCS6520 (Peripheral Interface
Device). This device has an interrupt sense bit in bit 6 and bit 7
of the status words. It is a standard of the M6800 bus that whenever
possible, bit 7 reflects the interrupt status of an I/O device. This
means that under normal circumstances, an analysis of the N flag
after a load or BIT instruction should indicate the status of the
bit 7 on the I/O device being sampled. To facilitate this test using
the BIT instruction, bit 7 from the memory being tested is set
into the N flag irrespective of the value in the accumulator.
This is different from the bit instruction in the M6800 which
requires that bit 7 also be set on the accumulator to set N. The
advantage to the user is that if he decides to test bit 7 in the
memory, it is done directly by sampling the N bit with a BIT
followed by branch minus or branch plus instruction. This means that
I/O sampling can be accomplished at any time during the operation
of instructions irrespective of the value preloaded in the accumulator.



Another feature of the BIT test is the setting of bit 6 into
the V flag. As indicated previously, the V flag is normally reserved
for overflow into the sign position during an add and subtract instruction.
In other words, the V flag is not disturbed by normal
instructions. When the BIT instruction is used, it is assumed that
the user is trying to examine the memory that he is testing with the
BIT instruction. In order to receive maximum value from a BIT
instruction, bit 6 from the memory being tested is set into the V flag.
In the case of a normal memory operation, this just means that the
user should organize his memory such that both of his flags to be
tested are in either bit 6 or bit 7, in which case an appropriate
mask does not have to be loaded into the accumulator prior to
implementing the BIT instruction. In the case of the MCS6520, the BIT
instruction can be used for sampling interrupt, irrespective of the
mask. This allows the programmer to totally interrogate both bit 6 and
bit 7 of the MCS6520 without disturbing the accumulator. In the case
of the concurrent interrupts, i.e., bit 6 and bit 7 both on, the fact
that the V flag is automatically set by the BIT instruction allows
the user to postpone testing for the "6th bit on" until after he has
totally handled the interrupt "for bit 7 on" unless he performs an
arithmetic operation subsequent to the BIT operation.







share|improve this answer

































    29

















    I'm having a hard time picturing a use for this [BIT]




    It's mainly an I/O issue.



    The 6502 is in many ways designed especially for control/embedded applications and BIT is a part of this. 6500 specific IO-devices are designed to report any service conditions on bit 7 (and 6). For example the 6522 will set bit 7 of the Interrupt Flag Register when an interrupt condition has been reported. So a 6522 can be polled in a system without interrupts without eating up many instructions. Even an active wait in polling would be just two instructions. As long as it's about bit 6 and 7 BIT operates non destructive - unlike a sequence of LDA/AND - so no registers need to be saved, only flags changed, enabling the insertion of frequent checks.



    Same reason why the Apple II's keyboard port puts the key-pressed flag into bit 7. so a quick BIT can be used to check if a key has been pressed. And only the flags are affected.



    As a side-effect BIT is versatile for fast test of flags/semaphores. Bit 6/7 of a flag byte can be tested right away. Likewise (counting) semaphores/locks. In addition bit can be used to test for a numbers sign, again without touching anything but the flags.




    And curiously, it's missing any indexed or indirect addressing modes, and so can only be used absolutely or in the zero page.




    Not a concern for I/O, as these addresses are usually in fixed locations, especially when thinking embedded systems.





    Bottom Line: BIT is an instruction meant to speed up I/O handling.





    The design side reasoning is to have an instruction to enable branching on as many bits as possible with minimal impact. Of the four testable bits (N/V/Z/C) one, carry, is as well usable as user flag (SEC/CLC), so keeping that function leaves 3. Using the AND function already implemented sets N and Z, so BIT just needs to suppress copying the result of AND back to A and copying Bit 6 into V.



    Sounds like minimal effort to add a quite handy instruction.






    share|improve this answer



































      22
















      A good example would be reading from the floppy drive on the C64. The incoming clock and data signals of the serial bus are (perhaps not accidentally) wired to bits 6 and 7 of port A on CIA#2, appearing at $DD00.



      BIT $DD00


      samples both inputs and stores them in the N and V flags. Jumping back conditionally with



      BVC $-3


      waits while the clock is low, as data must be sampled on the rising clock edge. When it falls through the BVC, the N flag contains the data bit. It can be transferred to the C flag this way



      BMI $+4
      CLC
      BIT $38


      just to showcase the secondary use of the BIT instruction, skipping the SEC (opcode $38), where BMI is jumping to.



      Now the data bit is in the carry flag, without altering any of the three data registers. It can be shifted into the accumulator, which would hold the data byte being assembled. Meanwhile X can count the number of bits received, and Y can serve as offset when storing the received data with STA (zp),Y






      share|improve this answer




























      • That BMI, CLC, BIT$38 snippet is indeed a part of many I/O routines.

        – Janka
        May 26 at 0:02











      • Sampling both inputs at a time can be handy. An even cuter exploitation of BIT can be found on the Atari 2600's video chip. It has 15 sprite-collision input flags and 6 controller input flags, but rather than e.g. using two 8-bit registers for the sprite flags and one for the inputs, it puts the collision flags on bits 6-7 of eight addresses, and the controller inputs on bit 7 of six more. What makes this especially cute is that the chip only includes drive circuitry for the top two bits of the data bus; since code won't care what's on the bottom six bits, there's no need to drive them.

        – supercat
        May 28 at 15:06



















      13
















      Simply it gives the developer the ability to set status flags without actually moving any memory or destroying any registers. With a register starved system like the 6502, and the fact that (pretty much) all data movement is through the registers, there can certainly be use cases where this capability can come in handy.






      share|improve this answer

































        0
















        I spent a lot of time in the 80s going through 6502 ROMs for home computers. I can honestly tell you what the BIT instruction is used for most of the time in practice.



        Mostly it's not used for any calculation of interest. It's used as a filler instruction to allow multiple entry points to a routine, each with different common parameter values. I don't think I ever saw it used for the intended purpose. (Maybe once or twice.)



        So for example if you had a routine which prints an ASCII character, you might commonly want to print space, or carriage return or things like '?' on the Commodore machines etc. and to save space in the ROM they just used the BIT instruction to isolate LDA instructions, or other loads. For example:



        label_print_CR:
        LDA #$0D - carriage return
        .byte $2C (BIT instruction op code)
        label_print_space:
        LDA #$20 - space
        .byte $2C
        label_print_question_mark:
        LDA #$3F - '?'
        label_print_character:
        main code to print character in A


        That would assemble to be:



        A9 0D 2C A9 20 2C A9 3F etc..


        If you disassemble it you get:



        LDA #$0D
        BIT $20A9
        BIT $3FA9
        etc


        so the BIT is doing nothing, but it's giving you these cunning specific extra entry points to the routine for printing.



        Here's the entry points for the Commodore PET V4.0 BASIC (I don't have the code unfortunately.)



        bb1d    strout  Output String
        bb3a outspc Output Format Character
        bb41 -Print '<cursor right>'
        bb44 -Print '?'
        bb46 - Output Character in A


        You can clearly see the entry points are just 2-3 bytes apart for 41, 44, 46 so there's no way they're using branches or jumps to load and jump into the general routine.



        This application of the BIT instruction is just totally ubiquitous across 6502 machines of that era. I used it in my own code all the time. As you can tell from the disassembly it can be rather confusing as to what they're doing.



        This is from the 1976 Microsoft 6502 BASIC listing which you can check out here https://www.pagetable.com/docs/M6502.MAC.txt



        DEFINE  SKIP1,  <XWD ^O1000,^O044>  ;BIT ZERO PAGE TRICK.
        DEFINE SKIP2, <XWD ^O1000,^O054> ;BIT ABS TRICK.


        Note these values are in octal so that's $24 and $2c for the two byte and three byte BIT instructions.



        Here's an example:



        PARCHK: JSR CHKOPN      ;ONLY POSSIBILITY LEFT IS
        JSR FRMEVL ;A FORMULA IN PARENTHESIS.
        ;RECURSIVELY EVALUATE THE FORMULA.
        CHKCLS: LDAI 41 ;CHECK FOR A RIGHT PARENTHESE
        SKIP2
        CHKOPN: LDAI 40
        SKIP2
        CHKCOM: LDAI 44
        ;
        ; "SYNCHK" LOOKS AT THE CURRENT CHARACTER TO MAKE SURE IT
        ; IS THE SPECIFIC THING LOADED INTO ACCA JUST BEFORE THE CALL TO
        ; "SYNCHK". IF NOT, IT CALLS THE "SYNTAX ERROR" ROUTINE.
        ; OTHERWISE IT GOBBLES THE NEXT CHAR AND RETURNS,
        ;
        ; [A]=NEW CHAR AND TXTPTR IS ADVANCED BY "CHRGET".
        ;
        SYNCHR: LDYI 0
        CMPDY TXTPTR ;CHARACTERS EQUAL?
        BNE SNERR
        CHRGO5: JMP CHRGET





        share|improve this answer























        • 1





          From the OP: "(Incidentally, it's convenient also for skipping two bytes in the instruction stream in cases where you don't care what happens to the flags, but I don't imagine that's the use MOS had in mind). What kinds of things was it meant for?)"

          – Wilson
          May 28 at 10:50















        Your Answer








        StackExchange.ready(function() {
        var channelOptions = {
        tags: "".split(" "),
        id: "648"
        };
        initTagRenderer("".split(" "), "".split(" "), channelOptions);

        StackExchange.using("externalEditor", function() {
        // Have to fire editor after snippets, if snippets enabled
        if (StackExchange.settings.snippets.snippetsEnabled) {
        StackExchange.using("snippets", function() {
        createEditor();
        });
        }
        else {
        createEditor();
        }
        });

        function createEditor() {
        StackExchange.prepareEditor({
        heartbeatType: 'answer',
        autoActivateHeartbeat: false,
        convertImagesToLinks: false,
        noModals: true,
        showLowRepImageUploadWarning: true,
        reputationToPostImages: null,
        bindNavPrevention: true,
        postfix: "",
        imageUploader: {
        brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
        contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/4.0/"u003ecc by-sa 4.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
        allowUrls: true
        },
        noCode: true, onDemand: true,
        discardSelector: ".discard-answer"
        ,immediatelyShowMarkdownHelp:true
        });


        }
        });















        draft saved

        draft discarded
















        StackExchange.ready(
        function () {
        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fretrocomputing.stackexchange.com%2fquestions%2f11108%2fwhy-does-the-6502-have-the-bit-instruction%23new-answer', 'question_page');
        }
        );

        Post as a guest















        Required, but never shown

























        5 Answers
        5






        active

        oldest

        votes








        5 Answers
        5






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes









        40
















        Early MOS documentation (KIM-1 Programming Manual, Synertek SY6500/MCS6500 Microcomputer Programming manual, etc) states:




        The BIT instruction actually combines two instructions from
        the PDP-11 and MC6800, that of TST (Test Memory) and (BIT Test).



        ...



        In addition to the nondestructive feature of the BIT which
        allows us to isolate an individual bit by use of the branch equal or
        branch no equal test, two modifications to the PDP-11 version of that
        instruction have been made in the MCS650X microprocessor. These are
        to allow a test of bit 7 and bit 6 of the field examined with the BIT
        test. This feature is particularly useful in serving polled interrupts
        and particularly in dealing with the MCS6520 (Peripheral Interface
        Device). This device has an interrupt sense bit in bit 6 and bit 7
        of the status words. It is a standard of the M6800 bus that whenever
        possible, bit 7 reflects the interrupt status of an I/O device. This
        means that under normal circumstances, an analysis of the N flag
        after a load or BIT instruction should indicate the status of the
        bit 7 on the I/O device being sampled. To facilitate this test using
        the BIT instruction, bit 7 from the memory being tested is set
        into the N flag irrespective of the value in the accumulator.
        This is different from the bit instruction in the M6800 which
        requires that bit 7 also be set on the accumulator to set N. The
        advantage to the user is that if he decides to test bit 7 in the
        memory, it is done directly by sampling the N bit with a BIT
        followed by branch minus or branch plus instruction. This means that
        I/O sampling can be accomplished at any time during the operation
        of instructions irrespective of the value preloaded in the accumulator.



        Another feature of the BIT test is the setting of bit 6 into
        the V flag. As indicated previously, the V flag is normally reserved
        for overflow into the sign position during an add and subtract instruction.
        In other words, the V flag is not disturbed by normal
        instructions. When the BIT instruction is used, it is assumed that
        the user is trying to examine the memory that he is testing with the
        BIT instruction. In order to receive maximum value from a BIT
        instruction, bit 6 from the memory being tested is set into the V flag.
        In the case of a normal memory operation, this just means that the
        user should organize his memory such that both of his flags to be
        tested are in either bit 6 or bit 7, in which case an appropriate
        mask does not have to be loaded into the accumulator prior to
        implementing the BIT instruction. In the case of the MCS6520, the BIT
        instruction can be used for sampling interrupt, irrespective of the
        mask. This allows the programmer to totally interrogate both bit 6 and
        bit 7 of the MCS6520 without disturbing the accumulator. In the case
        of the concurrent interrupts, i.e., bit 6 and bit 7 both on, the fact
        that the V flag is automatically set by the BIT instruction allows
        the user to postpone testing for the "6th bit on" until after he has
        totally handled the interrupt "for bit 7 on" unless he performs an
        arithmetic operation subsequent to the BIT operation.







        share|improve this answer






























          40
















          Early MOS documentation (KIM-1 Programming Manual, Synertek SY6500/MCS6500 Microcomputer Programming manual, etc) states:




          The BIT instruction actually combines two instructions from
          the PDP-11 and MC6800, that of TST (Test Memory) and (BIT Test).



          ...



          In addition to the nondestructive feature of the BIT which
          allows us to isolate an individual bit by use of the branch equal or
          branch no equal test, two modifications to the PDP-11 version of that
          instruction have been made in the MCS650X microprocessor. These are
          to allow a test of bit 7 and bit 6 of the field examined with the BIT
          test. This feature is particularly useful in serving polled interrupts
          and particularly in dealing with the MCS6520 (Peripheral Interface
          Device). This device has an interrupt sense bit in bit 6 and bit 7
          of the status words. It is a standard of the M6800 bus that whenever
          possible, bit 7 reflects the interrupt status of an I/O device. This
          means that under normal circumstances, an analysis of the N flag
          after a load or BIT instruction should indicate the status of the
          bit 7 on the I/O device being sampled. To facilitate this test using
          the BIT instruction, bit 7 from the memory being tested is set
          into the N flag irrespective of the value in the accumulator.
          This is different from the bit instruction in the M6800 which
          requires that bit 7 also be set on the accumulator to set N. The
          advantage to the user is that if he decides to test bit 7 in the
          memory, it is done directly by sampling the N bit with a BIT
          followed by branch minus or branch plus instruction. This means that
          I/O sampling can be accomplished at any time during the operation
          of instructions irrespective of the value preloaded in the accumulator.



          Another feature of the BIT test is the setting of bit 6 into
          the V flag. As indicated previously, the V flag is normally reserved
          for overflow into the sign position during an add and subtract instruction.
          In other words, the V flag is not disturbed by normal
          instructions. When the BIT instruction is used, it is assumed that
          the user is trying to examine the memory that he is testing with the
          BIT instruction. In order to receive maximum value from a BIT
          instruction, bit 6 from the memory being tested is set into the V flag.
          In the case of a normal memory operation, this just means that the
          user should organize his memory such that both of his flags to be
          tested are in either bit 6 or bit 7, in which case an appropriate
          mask does not have to be loaded into the accumulator prior to
          implementing the BIT instruction. In the case of the MCS6520, the BIT
          instruction can be used for sampling interrupt, irrespective of the
          mask. This allows the programmer to totally interrogate both bit 6 and
          bit 7 of the MCS6520 without disturbing the accumulator. In the case
          of the concurrent interrupts, i.e., bit 6 and bit 7 both on, the fact
          that the V flag is automatically set by the BIT instruction allows
          the user to postpone testing for the "6th bit on" until after he has
          totally handled the interrupt "for bit 7 on" unless he performs an
          arithmetic operation subsequent to the BIT operation.







          share|improve this answer




























            40














            40










            40









            Early MOS documentation (KIM-1 Programming Manual, Synertek SY6500/MCS6500 Microcomputer Programming manual, etc) states:




            The BIT instruction actually combines two instructions from
            the PDP-11 and MC6800, that of TST (Test Memory) and (BIT Test).



            ...



            In addition to the nondestructive feature of the BIT which
            allows us to isolate an individual bit by use of the branch equal or
            branch no equal test, two modifications to the PDP-11 version of that
            instruction have been made in the MCS650X microprocessor. These are
            to allow a test of bit 7 and bit 6 of the field examined with the BIT
            test. This feature is particularly useful in serving polled interrupts
            and particularly in dealing with the MCS6520 (Peripheral Interface
            Device). This device has an interrupt sense bit in bit 6 and bit 7
            of the status words. It is a standard of the M6800 bus that whenever
            possible, bit 7 reflects the interrupt status of an I/O device. This
            means that under normal circumstances, an analysis of the N flag
            after a load or BIT instruction should indicate the status of the
            bit 7 on the I/O device being sampled. To facilitate this test using
            the BIT instruction, bit 7 from the memory being tested is set
            into the N flag irrespective of the value in the accumulator.
            This is different from the bit instruction in the M6800 which
            requires that bit 7 also be set on the accumulator to set N. The
            advantage to the user is that if he decides to test bit 7 in the
            memory, it is done directly by sampling the N bit with a BIT
            followed by branch minus or branch plus instruction. This means that
            I/O sampling can be accomplished at any time during the operation
            of instructions irrespective of the value preloaded in the accumulator.



            Another feature of the BIT test is the setting of bit 6 into
            the V flag. As indicated previously, the V flag is normally reserved
            for overflow into the sign position during an add and subtract instruction.
            In other words, the V flag is not disturbed by normal
            instructions. When the BIT instruction is used, it is assumed that
            the user is trying to examine the memory that he is testing with the
            BIT instruction. In order to receive maximum value from a BIT
            instruction, bit 6 from the memory being tested is set into the V flag.
            In the case of a normal memory operation, this just means that the
            user should organize his memory such that both of his flags to be
            tested are in either bit 6 or bit 7, in which case an appropriate
            mask does not have to be loaded into the accumulator prior to
            implementing the BIT instruction. In the case of the MCS6520, the BIT
            instruction can be used for sampling interrupt, irrespective of the
            mask. This allows the programmer to totally interrogate both bit 6 and
            bit 7 of the MCS6520 without disturbing the accumulator. In the case
            of the concurrent interrupts, i.e., bit 6 and bit 7 both on, the fact
            that the V flag is automatically set by the BIT instruction allows
            the user to postpone testing for the "6th bit on" until after he has
            totally handled the interrupt "for bit 7 on" unless he performs an
            arithmetic operation subsequent to the BIT operation.







            share|improve this answer













            Early MOS documentation (KIM-1 Programming Manual, Synertek SY6500/MCS6500 Microcomputer Programming manual, etc) states:




            The BIT instruction actually combines two instructions from
            the PDP-11 and MC6800, that of TST (Test Memory) and (BIT Test).



            ...



            In addition to the nondestructive feature of the BIT which
            allows us to isolate an individual bit by use of the branch equal or
            branch no equal test, two modifications to the PDP-11 version of that
            instruction have been made in the MCS650X microprocessor. These are
            to allow a test of bit 7 and bit 6 of the field examined with the BIT
            test. This feature is particularly useful in serving polled interrupts
            and particularly in dealing with the MCS6520 (Peripheral Interface
            Device). This device has an interrupt sense bit in bit 6 and bit 7
            of the status words. It is a standard of the M6800 bus that whenever
            possible, bit 7 reflects the interrupt status of an I/O device. This
            means that under normal circumstances, an analysis of the N flag
            after a load or BIT instruction should indicate the status of the
            bit 7 on the I/O device being sampled. To facilitate this test using
            the BIT instruction, bit 7 from the memory being tested is set
            into the N flag irrespective of the value in the accumulator.
            This is different from the bit instruction in the M6800 which
            requires that bit 7 also be set on the accumulator to set N. The
            advantage to the user is that if he decides to test bit 7 in the
            memory, it is done directly by sampling the N bit with a BIT
            followed by branch minus or branch plus instruction. This means that
            I/O sampling can be accomplished at any time during the operation
            of instructions irrespective of the value preloaded in the accumulator.



            Another feature of the BIT test is the setting of bit 6 into
            the V flag. As indicated previously, the V flag is normally reserved
            for overflow into the sign position during an add and subtract instruction.
            In other words, the V flag is not disturbed by normal
            instructions. When the BIT instruction is used, it is assumed that
            the user is trying to examine the memory that he is testing with the
            BIT instruction. In order to receive maximum value from a BIT
            instruction, bit 6 from the memory being tested is set into the V flag.
            In the case of a normal memory operation, this just means that the
            user should organize his memory such that both of his flags to be
            tested are in either bit 6 or bit 7, in which case an appropriate
            mask does not have to be loaded into the accumulator prior to
            implementing the BIT instruction. In the case of the MCS6520, the BIT
            instruction can be used for sampling interrupt, irrespective of the
            mask. This allows the programmer to totally interrogate both bit 6 and
            bit 7 of the MCS6520 without disturbing the accumulator. In the case
            of the concurrent interrupts, i.e., bit 6 and bit 7 both on, the fact
            that the V flag is automatically set by the BIT instruction allows
            the user to postpone testing for the "6th bit on" until after he has
            totally handled the interrupt "for bit 7 on" unless he performs an
            arithmetic operation subsequent to the BIT operation.








            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered May 25 at 17:42









            Kelvin SherlockKelvin Sherlock

            9585 silver badges10 bronze badges




            9585 silver badges10 bronze badges




























                29

















                I'm having a hard time picturing a use for this [BIT]




                It's mainly an I/O issue.



                The 6502 is in many ways designed especially for control/embedded applications and BIT is a part of this. 6500 specific IO-devices are designed to report any service conditions on bit 7 (and 6). For example the 6522 will set bit 7 of the Interrupt Flag Register when an interrupt condition has been reported. So a 6522 can be polled in a system without interrupts without eating up many instructions. Even an active wait in polling would be just two instructions. As long as it's about bit 6 and 7 BIT operates non destructive - unlike a sequence of LDA/AND - so no registers need to be saved, only flags changed, enabling the insertion of frequent checks.



                Same reason why the Apple II's keyboard port puts the key-pressed flag into bit 7. so a quick BIT can be used to check if a key has been pressed. And only the flags are affected.



                As a side-effect BIT is versatile for fast test of flags/semaphores. Bit 6/7 of a flag byte can be tested right away. Likewise (counting) semaphores/locks. In addition bit can be used to test for a numbers sign, again without touching anything but the flags.




                And curiously, it's missing any indexed or indirect addressing modes, and so can only be used absolutely or in the zero page.




                Not a concern for I/O, as these addresses are usually in fixed locations, especially when thinking embedded systems.





                Bottom Line: BIT is an instruction meant to speed up I/O handling.





                The design side reasoning is to have an instruction to enable branching on as many bits as possible with minimal impact. Of the four testable bits (N/V/Z/C) one, carry, is as well usable as user flag (SEC/CLC), so keeping that function leaves 3. Using the AND function already implemented sets N and Z, so BIT just needs to suppress copying the result of AND back to A and copying Bit 6 into V.



                Sounds like minimal effort to add a quite handy instruction.






                share|improve this answer
































                  29

















                  I'm having a hard time picturing a use for this [BIT]




                  It's mainly an I/O issue.



                  The 6502 is in many ways designed especially for control/embedded applications and BIT is a part of this. 6500 specific IO-devices are designed to report any service conditions on bit 7 (and 6). For example the 6522 will set bit 7 of the Interrupt Flag Register when an interrupt condition has been reported. So a 6522 can be polled in a system without interrupts without eating up many instructions. Even an active wait in polling would be just two instructions. As long as it's about bit 6 and 7 BIT operates non destructive - unlike a sequence of LDA/AND - so no registers need to be saved, only flags changed, enabling the insertion of frequent checks.



                  Same reason why the Apple II's keyboard port puts the key-pressed flag into bit 7. so a quick BIT can be used to check if a key has been pressed. And only the flags are affected.



                  As a side-effect BIT is versatile for fast test of flags/semaphores. Bit 6/7 of a flag byte can be tested right away. Likewise (counting) semaphores/locks. In addition bit can be used to test for a numbers sign, again without touching anything but the flags.




                  And curiously, it's missing any indexed or indirect addressing modes, and so can only be used absolutely or in the zero page.




                  Not a concern for I/O, as these addresses are usually in fixed locations, especially when thinking embedded systems.





                  Bottom Line: BIT is an instruction meant to speed up I/O handling.





                  The design side reasoning is to have an instruction to enable branching on as many bits as possible with minimal impact. Of the four testable bits (N/V/Z/C) one, carry, is as well usable as user flag (SEC/CLC), so keeping that function leaves 3. Using the AND function already implemented sets N and Z, so BIT just needs to suppress copying the result of AND back to A and copying Bit 6 into V.



                  Sounds like minimal effort to add a quite handy instruction.






                  share|improve this answer






























                    29














                    29










                    29










                    I'm having a hard time picturing a use for this [BIT]




                    It's mainly an I/O issue.



                    The 6502 is in many ways designed especially for control/embedded applications and BIT is a part of this. 6500 specific IO-devices are designed to report any service conditions on bit 7 (and 6). For example the 6522 will set bit 7 of the Interrupt Flag Register when an interrupt condition has been reported. So a 6522 can be polled in a system without interrupts without eating up many instructions. Even an active wait in polling would be just two instructions. As long as it's about bit 6 and 7 BIT operates non destructive - unlike a sequence of LDA/AND - so no registers need to be saved, only flags changed, enabling the insertion of frequent checks.



                    Same reason why the Apple II's keyboard port puts the key-pressed flag into bit 7. so a quick BIT can be used to check if a key has been pressed. And only the flags are affected.



                    As a side-effect BIT is versatile for fast test of flags/semaphores. Bit 6/7 of a flag byte can be tested right away. Likewise (counting) semaphores/locks. In addition bit can be used to test for a numbers sign, again without touching anything but the flags.




                    And curiously, it's missing any indexed or indirect addressing modes, and so can only be used absolutely or in the zero page.




                    Not a concern for I/O, as these addresses are usually in fixed locations, especially when thinking embedded systems.





                    Bottom Line: BIT is an instruction meant to speed up I/O handling.





                    The design side reasoning is to have an instruction to enable branching on as many bits as possible with minimal impact. Of the four testable bits (N/V/Z/C) one, carry, is as well usable as user flag (SEC/CLC), so keeping that function leaves 3. Using the AND function already implemented sets N and Z, so BIT just needs to suppress copying the result of AND back to A and copying Bit 6 into V.



                    Sounds like minimal effort to add a quite handy instruction.






                    share|improve this answer
















                    I'm having a hard time picturing a use for this [BIT]




                    It's mainly an I/O issue.



                    The 6502 is in many ways designed especially for control/embedded applications and BIT is a part of this. 6500 specific IO-devices are designed to report any service conditions on bit 7 (and 6). For example the 6522 will set bit 7 of the Interrupt Flag Register when an interrupt condition has been reported. So a 6522 can be polled in a system without interrupts without eating up many instructions. Even an active wait in polling would be just two instructions. As long as it's about bit 6 and 7 BIT operates non destructive - unlike a sequence of LDA/AND - so no registers need to be saved, only flags changed, enabling the insertion of frequent checks.



                    Same reason why the Apple II's keyboard port puts the key-pressed flag into bit 7. so a quick BIT can be used to check if a key has been pressed. And only the flags are affected.



                    As a side-effect BIT is versatile for fast test of flags/semaphores. Bit 6/7 of a flag byte can be tested right away. Likewise (counting) semaphores/locks. In addition bit can be used to test for a numbers sign, again without touching anything but the flags.




                    And curiously, it's missing any indexed or indirect addressing modes, and so can only be used absolutely or in the zero page.




                    Not a concern for I/O, as these addresses are usually in fixed locations, especially when thinking embedded systems.





                    Bottom Line: BIT is an instruction meant to speed up I/O handling.





                    The design side reasoning is to have an instruction to enable branching on as many bits as possible with minimal impact. Of the four testable bits (N/V/Z/C) one, carry, is as well usable as user flag (SEC/CLC), so keeping that function leaves 3. Using the AND function already implemented sets N and Z, so BIT just needs to suppress copying the result of AND back to A and copying Bit 6 into V.



                    Sounds like minimal effort to add a quite handy instruction.







                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited May 26 at 18:42

























                    answered May 25 at 23:42









                    RaffzahnRaffzahn

                    71.1k7 gold badges177 silver badges297 bronze badges




                    71.1k7 gold badges177 silver badges297 bronze badges


























                        22
















                        A good example would be reading from the floppy drive on the C64. The incoming clock and data signals of the serial bus are (perhaps not accidentally) wired to bits 6 and 7 of port A on CIA#2, appearing at $DD00.



                        BIT $DD00


                        samples both inputs and stores them in the N and V flags. Jumping back conditionally with



                        BVC $-3


                        waits while the clock is low, as data must be sampled on the rising clock edge. When it falls through the BVC, the N flag contains the data bit. It can be transferred to the C flag this way



                        BMI $+4
                        CLC
                        BIT $38


                        just to showcase the secondary use of the BIT instruction, skipping the SEC (opcode $38), where BMI is jumping to.



                        Now the data bit is in the carry flag, without altering any of the three data registers. It can be shifted into the accumulator, which would hold the data byte being assembled. Meanwhile X can count the number of bits received, and Y can serve as offset when storing the received data with STA (zp),Y






                        share|improve this answer




























                        • That BMI, CLC, BIT$38 snippet is indeed a part of many I/O routines.

                          – Janka
                          May 26 at 0:02











                        • Sampling both inputs at a time can be handy. An even cuter exploitation of BIT can be found on the Atari 2600's video chip. It has 15 sprite-collision input flags and 6 controller input flags, but rather than e.g. using two 8-bit registers for the sprite flags and one for the inputs, it puts the collision flags on bits 6-7 of eight addresses, and the controller inputs on bit 7 of six more. What makes this especially cute is that the chip only includes drive circuitry for the top two bits of the data bus; since code won't care what's on the bottom six bits, there's no need to drive them.

                          – supercat
                          May 28 at 15:06
















                        22
















                        A good example would be reading from the floppy drive on the C64. The incoming clock and data signals of the serial bus are (perhaps not accidentally) wired to bits 6 and 7 of port A on CIA#2, appearing at $DD00.



                        BIT $DD00


                        samples both inputs and stores them in the N and V flags. Jumping back conditionally with



                        BVC $-3


                        waits while the clock is low, as data must be sampled on the rising clock edge. When it falls through the BVC, the N flag contains the data bit. It can be transferred to the C flag this way



                        BMI $+4
                        CLC
                        BIT $38


                        just to showcase the secondary use of the BIT instruction, skipping the SEC (opcode $38), where BMI is jumping to.



                        Now the data bit is in the carry flag, without altering any of the three data registers. It can be shifted into the accumulator, which would hold the data byte being assembled. Meanwhile X can count the number of bits received, and Y can serve as offset when storing the received data with STA (zp),Y






                        share|improve this answer




























                        • That BMI, CLC, BIT$38 snippet is indeed a part of many I/O routines.

                          – Janka
                          May 26 at 0:02











                        • Sampling both inputs at a time can be handy. An even cuter exploitation of BIT can be found on the Atari 2600's video chip. It has 15 sprite-collision input flags and 6 controller input flags, but rather than e.g. using two 8-bit registers for the sprite flags and one for the inputs, it puts the collision flags on bits 6-7 of eight addresses, and the controller inputs on bit 7 of six more. What makes this especially cute is that the chip only includes drive circuitry for the top two bits of the data bus; since code won't care what's on the bottom six bits, there's no need to drive them.

                          – supercat
                          May 28 at 15:06














                        22














                        22










                        22









                        A good example would be reading from the floppy drive on the C64. The incoming clock and data signals of the serial bus are (perhaps not accidentally) wired to bits 6 and 7 of port A on CIA#2, appearing at $DD00.



                        BIT $DD00


                        samples both inputs and stores them in the N and V flags. Jumping back conditionally with



                        BVC $-3


                        waits while the clock is low, as data must be sampled on the rising clock edge. When it falls through the BVC, the N flag contains the data bit. It can be transferred to the C flag this way



                        BMI $+4
                        CLC
                        BIT $38


                        just to showcase the secondary use of the BIT instruction, skipping the SEC (opcode $38), where BMI is jumping to.



                        Now the data bit is in the carry flag, without altering any of the three data registers. It can be shifted into the accumulator, which would hold the data byte being assembled. Meanwhile X can count the number of bits received, and Y can serve as offset when storing the received data with STA (zp),Y






                        share|improve this answer















                        A good example would be reading from the floppy drive on the C64. The incoming clock and data signals of the serial bus are (perhaps not accidentally) wired to bits 6 and 7 of port A on CIA#2, appearing at $DD00.



                        BIT $DD00


                        samples both inputs and stores them in the N and V flags. Jumping back conditionally with



                        BVC $-3


                        waits while the clock is low, as data must be sampled on the rising clock edge. When it falls through the BVC, the N flag contains the data bit. It can be transferred to the C flag this way



                        BMI $+4
                        CLC
                        BIT $38


                        just to showcase the secondary use of the BIT instruction, skipping the SEC (opcode $38), where BMI is jumping to.



                        Now the data bit is in the carry flag, without altering any of the three data registers. It can be shifted into the accumulator, which would hold the data byte being assembled. Meanwhile X can count the number of bits received, and Y can serve as offset when storing the received data with STA (zp),Y







                        share|improve this answer














                        share|improve this answer



                        share|improve this answer








                        edited May 26 at 4:23

























                        answered May 25 at 20:55









                        berendiberendi

                        2,1591 gold badge7 silver badges18 bronze badges




                        2,1591 gold badge7 silver badges18 bronze badges
















                        • That BMI, CLC, BIT$38 snippet is indeed a part of many I/O routines.

                          – Janka
                          May 26 at 0:02











                        • Sampling both inputs at a time can be handy. An even cuter exploitation of BIT can be found on the Atari 2600's video chip. It has 15 sprite-collision input flags and 6 controller input flags, but rather than e.g. using two 8-bit registers for the sprite flags and one for the inputs, it puts the collision flags on bits 6-7 of eight addresses, and the controller inputs on bit 7 of six more. What makes this especially cute is that the chip only includes drive circuitry for the top two bits of the data bus; since code won't care what's on the bottom six bits, there's no need to drive them.

                          – supercat
                          May 28 at 15:06



















                        • That BMI, CLC, BIT$38 snippet is indeed a part of many I/O routines.

                          – Janka
                          May 26 at 0:02











                        • Sampling both inputs at a time can be handy. An even cuter exploitation of BIT can be found on the Atari 2600's video chip. It has 15 sprite-collision input flags and 6 controller input flags, but rather than e.g. using two 8-bit registers for the sprite flags and one for the inputs, it puts the collision flags on bits 6-7 of eight addresses, and the controller inputs on bit 7 of six more. What makes this especially cute is that the chip only includes drive circuitry for the top two bits of the data bus; since code won't care what's on the bottom six bits, there's no need to drive them.

                          – supercat
                          May 28 at 15:06

















                        That BMI, CLC, BIT$38 snippet is indeed a part of many I/O routines.

                        – Janka
                        May 26 at 0:02





                        That BMI, CLC, BIT$38 snippet is indeed a part of many I/O routines.

                        – Janka
                        May 26 at 0:02













                        Sampling both inputs at a time can be handy. An even cuter exploitation of BIT can be found on the Atari 2600's video chip. It has 15 sprite-collision input flags and 6 controller input flags, but rather than e.g. using two 8-bit registers for the sprite flags and one for the inputs, it puts the collision flags on bits 6-7 of eight addresses, and the controller inputs on bit 7 of six more. What makes this especially cute is that the chip only includes drive circuitry for the top two bits of the data bus; since code won't care what's on the bottom six bits, there's no need to drive them.

                        – supercat
                        May 28 at 15:06





                        Sampling both inputs at a time can be handy. An even cuter exploitation of BIT can be found on the Atari 2600's video chip. It has 15 sprite-collision input flags and 6 controller input flags, but rather than e.g. using two 8-bit registers for the sprite flags and one for the inputs, it puts the collision flags on bits 6-7 of eight addresses, and the controller inputs on bit 7 of six more. What makes this especially cute is that the chip only includes drive circuitry for the top two bits of the data bus; since code won't care what's on the bottom six bits, there's no need to drive them.

                        – supercat
                        May 28 at 15:06











                        13
















                        Simply it gives the developer the ability to set status flags without actually moving any memory or destroying any registers. With a register starved system like the 6502, and the fact that (pretty much) all data movement is through the registers, there can certainly be use cases where this capability can come in handy.






                        share|improve this answer






























                          13
















                          Simply it gives the developer the ability to set status flags without actually moving any memory or destroying any registers. With a register starved system like the 6502, and the fact that (pretty much) all data movement is through the registers, there can certainly be use cases where this capability can come in handy.






                          share|improve this answer




























                            13














                            13










                            13









                            Simply it gives the developer the ability to set status flags without actually moving any memory or destroying any registers. With a register starved system like the 6502, and the fact that (pretty much) all data movement is through the registers, there can certainly be use cases where this capability can come in handy.






                            share|improve this answer













                            Simply it gives the developer the ability to set status flags without actually moving any memory or destroying any registers. With a register starved system like the 6502, and the fact that (pretty much) all data movement is through the registers, there can certainly be use cases where this capability can come in handy.







                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered May 25 at 17:22









                            Will HartungWill Hartung

                            5,06612 silver badges26 bronze badges




                            5,06612 silver badges26 bronze badges


























                                0
















                                I spent a lot of time in the 80s going through 6502 ROMs for home computers. I can honestly tell you what the BIT instruction is used for most of the time in practice.



                                Mostly it's not used for any calculation of interest. It's used as a filler instruction to allow multiple entry points to a routine, each with different common parameter values. I don't think I ever saw it used for the intended purpose. (Maybe once or twice.)



                                So for example if you had a routine which prints an ASCII character, you might commonly want to print space, or carriage return or things like '?' on the Commodore machines etc. and to save space in the ROM they just used the BIT instruction to isolate LDA instructions, or other loads. For example:



                                label_print_CR:
                                LDA #$0D - carriage return
                                .byte $2C (BIT instruction op code)
                                label_print_space:
                                LDA #$20 - space
                                .byte $2C
                                label_print_question_mark:
                                LDA #$3F - '?'
                                label_print_character:
                                main code to print character in A


                                That would assemble to be:



                                A9 0D 2C A9 20 2C A9 3F etc..


                                If you disassemble it you get:



                                LDA #$0D
                                BIT $20A9
                                BIT $3FA9
                                etc


                                so the BIT is doing nothing, but it's giving you these cunning specific extra entry points to the routine for printing.



                                Here's the entry points for the Commodore PET V4.0 BASIC (I don't have the code unfortunately.)



                                bb1d    strout  Output String
                                bb3a outspc Output Format Character
                                bb41 -Print '<cursor right>'
                                bb44 -Print '?'
                                bb46 - Output Character in A


                                You can clearly see the entry points are just 2-3 bytes apart for 41, 44, 46 so there's no way they're using branches or jumps to load and jump into the general routine.



                                This application of the BIT instruction is just totally ubiquitous across 6502 machines of that era. I used it in my own code all the time. As you can tell from the disassembly it can be rather confusing as to what they're doing.



                                This is from the 1976 Microsoft 6502 BASIC listing which you can check out here https://www.pagetable.com/docs/M6502.MAC.txt



                                DEFINE  SKIP1,  <XWD ^O1000,^O044>  ;BIT ZERO PAGE TRICK.
                                DEFINE SKIP2, <XWD ^O1000,^O054> ;BIT ABS TRICK.


                                Note these values are in octal so that's $24 and $2c for the two byte and three byte BIT instructions.



                                Here's an example:



                                PARCHK: JSR CHKOPN      ;ONLY POSSIBILITY LEFT IS
                                JSR FRMEVL ;A FORMULA IN PARENTHESIS.
                                ;RECURSIVELY EVALUATE THE FORMULA.
                                CHKCLS: LDAI 41 ;CHECK FOR A RIGHT PARENTHESE
                                SKIP2
                                CHKOPN: LDAI 40
                                SKIP2
                                CHKCOM: LDAI 44
                                ;
                                ; "SYNCHK" LOOKS AT THE CURRENT CHARACTER TO MAKE SURE IT
                                ; IS THE SPECIFIC THING LOADED INTO ACCA JUST BEFORE THE CALL TO
                                ; "SYNCHK". IF NOT, IT CALLS THE "SYNTAX ERROR" ROUTINE.
                                ; OTHERWISE IT GOBBLES THE NEXT CHAR AND RETURNS,
                                ;
                                ; [A]=NEW CHAR AND TXTPTR IS ADVANCED BY "CHRGET".
                                ;
                                SYNCHR: LDYI 0
                                CMPDY TXTPTR ;CHARACTERS EQUAL?
                                BNE SNERR
                                CHRGO5: JMP CHRGET





                                share|improve this answer























                                • 1





                                  From the OP: "(Incidentally, it's convenient also for skipping two bytes in the instruction stream in cases where you don't care what happens to the flags, but I don't imagine that's the use MOS had in mind). What kinds of things was it meant for?)"

                                  – Wilson
                                  May 28 at 10:50


















                                0
















                                I spent a lot of time in the 80s going through 6502 ROMs for home computers. I can honestly tell you what the BIT instruction is used for most of the time in practice.



                                Mostly it's not used for any calculation of interest. It's used as a filler instruction to allow multiple entry points to a routine, each with different common parameter values. I don't think I ever saw it used for the intended purpose. (Maybe once or twice.)



                                So for example if you had a routine which prints an ASCII character, you might commonly want to print space, or carriage return or things like '?' on the Commodore machines etc. and to save space in the ROM they just used the BIT instruction to isolate LDA instructions, or other loads. For example:



                                label_print_CR:
                                LDA #$0D - carriage return
                                .byte $2C (BIT instruction op code)
                                label_print_space:
                                LDA #$20 - space
                                .byte $2C
                                label_print_question_mark:
                                LDA #$3F - '?'
                                label_print_character:
                                main code to print character in A


                                That would assemble to be:



                                A9 0D 2C A9 20 2C A9 3F etc..


                                If you disassemble it you get:



                                LDA #$0D
                                BIT $20A9
                                BIT $3FA9
                                etc


                                so the BIT is doing nothing, but it's giving you these cunning specific extra entry points to the routine for printing.



                                Here's the entry points for the Commodore PET V4.0 BASIC (I don't have the code unfortunately.)



                                bb1d    strout  Output String
                                bb3a outspc Output Format Character
                                bb41 -Print '<cursor right>'
                                bb44 -Print '?'
                                bb46 - Output Character in A


                                You can clearly see the entry points are just 2-3 bytes apart for 41, 44, 46 so there's no way they're using branches or jumps to load and jump into the general routine.



                                This application of the BIT instruction is just totally ubiquitous across 6502 machines of that era. I used it in my own code all the time. As you can tell from the disassembly it can be rather confusing as to what they're doing.



                                This is from the 1976 Microsoft 6502 BASIC listing which you can check out here https://www.pagetable.com/docs/M6502.MAC.txt



                                DEFINE  SKIP1,  <XWD ^O1000,^O044>  ;BIT ZERO PAGE TRICK.
                                DEFINE SKIP2, <XWD ^O1000,^O054> ;BIT ABS TRICK.


                                Note these values are in octal so that's $24 and $2c for the two byte and three byte BIT instructions.



                                Here's an example:



                                PARCHK: JSR CHKOPN      ;ONLY POSSIBILITY LEFT IS
                                JSR FRMEVL ;A FORMULA IN PARENTHESIS.
                                ;RECURSIVELY EVALUATE THE FORMULA.
                                CHKCLS: LDAI 41 ;CHECK FOR A RIGHT PARENTHESE
                                SKIP2
                                CHKOPN: LDAI 40
                                SKIP2
                                CHKCOM: LDAI 44
                                ;
                                ; "SYNCHK" LOOKS AT THE CURRENT CHARACTER TO MAKE SURE IT
                                ; IS THE SPECIFIC THING LOADED INTO ACCA JUST BEFORE THE CALL TO
                                ; "SYNCHK". IF NOT, IT CALLS THE "SYNTAX ERROR" ROUTINE.
                                ; OTHERWISE IT GOBBLES THE NEXT CHAR AND RETURNS,
                                ;
                                ; [A]=NEW CHAR AND TXTPTR IS ADVANCED BY "CHRGET".
                                ;
                                SYNCHR: LDYI 0
                                CMPDY TXTPTR ;CHARACTERS EQUAL?
                                BNE SNERR
                                CHRGO5: JMP CHRGET





                                share|improve this answer























                                • 1





                                  From the OP: "(Incidentally, it's convenient also for skipping two bytes in the instruction stream in cases where you don't care what happens to the flags, but I don't imagine that's the use MOS had in mind). What kinds of things was it meant for?)"

                                  – Wilson
                                  May 28 at 10:50
















                                0














                                0










                                0









                                I spent a lot of time in the 80s going through 6502 ROMs for home computers. I can honestly tell you what the BIT instruction is used for most of the time in practice.



                                Mostly it's not used for any calculation of interest. It's used as a filler instruction to allow multiple entry points to a routine, each with different common parameter values. I don't think I ever saw it used for the intended purpose. (Maybe once or twice.)



                                So for example if you had a routine which prints an ASCII character, you might commonly want to print space, or carriage return or things like '?' on the Commodore machines etc. and to save space in the ROM they just used the BIT instruction to isolate LDA instructions, or other loads. For example:



                                label_print_CR:
                                LDA #$0D - carriage return
                                .byte $2C (BIT instruction op code)
                                label_print_space:
                                LDA #$20 - space
                                .byte $2C
                                label_print_question_mark:
                                LDA #$3F - '?'
                                label_print_character:
                                main code to print character in A


                                That would assemble to be:



                                A9 0D 2C A9 20 2C A9 3F etc..


                                If you disassemble it you get:



                                LDA #$0D
                                BIT $20A9
                                BIT $3FA9
                                etc


                                so the BIT is doing nothing, but it's giving you these cunning specific extra entry points to the routine for printing.



                                Here's the entry points for the Commodore PET V4.0 BASIC (I don't have the code unfortunately.)



                                bb1d    strout  Output String
                                bb3a outspc Output Format Character
                                bb41 -Print '<cursor right>'
                                bb44 -Print '?'
                                bb46 - Output Character in A


                                You can clearly see the entry points are just 2-3 bytes apart for 41, 44, 46 so there's no way they're using branches or jumps to load and jump into the general routine.



                                This application of the BIT instruction is just totally ubiquitous across 6502 machines of that era. I used it in my own code all the time. As you can tell from the disassembly it can be rather confusing as to what they're doing.



                                This is from the 1976 Microsoft 6502 BASIC listing which you can check out here https://www.pagetable.com/docs/M6502.MAC.txt



                                DEFINE  SKIP1,  <XWD ^O1000,^O044>  ;BIT ZERO PAGE TRICK.
                                DEFINE SKIP2, <XWD ^O1000,^O054> ;BIT ABS TRICK.


                                Note these values are in octal so that's $24 and $2c for the two byte and three byte BIT instructions.



                                Here's an example:



                                PARCHK: JSR CHKOPN      ;ONLY POSSIBILITY LEFT IS
                                JSR FRMEVL ;A FORMULA IN PARENTHESIS.
                                ;RECURSIVELY EVALUATE THE FORMULA.
                                CHKCLS: LDAI 41 ;CHECK FOR A RIGHT PARENTHESE
                                SKIP2
                                CHKOPN: LDAI 40
                                SKIP2
                                CHKCOM: LDAI 44
                                ;
                                ; "SYNCHK" LOOKS AT THE CURRENT CHARACTER TO MAKE SURE IT
                                ; IS THE SPECIFIC THING LOADED INTO ACCA JUST BEFORE THE CALL TO
                                ; "SYNCHK". IF NOT, IT CALLS THE "SYNTAX ERROR" ROUTINE.
                                ; OTHERWISE IT GOBBLES THE NEXT CHAR AND RETURNS,
                                ;
                                ; [A]=NEW CHAR AND TXTPTR IS ADVANCED BY "CHRGET".
                                ;
                                SYNCHR: LDYI 0
                                CMPDY TXTPTR ;CHARACTERS EQUAL?
                                BNE SNERR
                                CHRGO5: JMP CHRGET





                                share|improve this answer















                                I spent a lot of time in the 80s going through 6502 ROMs for home computers. I can honestly tell you what the BIT instruction is used for most of the time in practice.



                                Mostly it's not used for any calculation of interest. It's used as a filler instruction to allow multiple entry points to a routine, each with different common parameter values. I don't think I ever saw it used for the intended purpose. (Maybe once or twice.)



                                So for example if you had a routine which prints an ASCII character, you might commonly want to print space, or carriage return or things like '?' on the Commodore machines etc. and to save space in the ROM they just used the BIT instruction to isolate LDA instructions, or other loads. For example:



                                label_print_CR:
                                LDA #$0D - carriage return
                                .byte $2C (BIT instruction op code)
                                label_print_space:
                                LDA #$20 - space
                                .byte $2C
                                label_print_question_mark:
                                LDA #$3F - '?'
                                label_print_character:
                                main code to print character in A


                                That would assemble to be:



                                A9 0D 2C A9 20 2C A9 3F etc..


                                If you disassemble it you get:



                                LDA #$0D
                                BIT $20A9
                                BIT $3FA9
                                etc


                                so the BIT is doing nothing, but it's giving you these cunning specific extra entry points to the routine for printing.



                                Here's the entry points for the Commodore PET V4.0 BASIC (I don't have the code unfortunately.)



                                bb1d    strout  Output String
                                bb3a outspc Output Format Character
                                bb41 -Print '<cursor right>'
                                bb44 -Print '?'
                                bb46 - Output Character in A


                                You can clearly see the entry points are just 2-3 bytes apart for 41, 44, 46 so there's no way they're using branches or jumps to load and jump into the general routine.



                                This application of the BIT instruction is just totally ubiquitous across 6502 machines of that era. I used it in my own code all the time. As you can tell from the disassembly it can be rather confusing as to what they're doing.



                                This is from the 1976 Microsoft 6502 BASIC listing which you can check out here https://www.pagetable.com/docs/M6502.MAC.txt



                                DEFINE  SKIP1,  <XWD ^O1000,^O044>  ;BIT ZERO PAGE TRICK.
                                DEFINE SKIP2, <XWD ^O1000,^O054> ;BIT ABS TRICK.


                                Note these values are in octal so that's $24 and $2c for the two byte and three byte BIT instructions.



                                Here's an example:



                                PARCHK: JSR CHKOPN      ;ONLY POSSIBILITY LEFT IS
                                JSR FRMEVL ;A FORMULA IN PARENTHESIS.
                                ;RECURSIVELY EVALUATE THE FORMULA.
                                CHKCLS: LDAI 41 ;CHECK FOR A RIGHT PARENTHESE
                                SKIP2
                                CHKOPN: LDAI 40
                                SKIP2
                                CHKCOM: LDAI 44
                                ;
                                ; "SYNCHK" LOOKS AT THE CURRENT CHARACTER TO MAKE SURE IT
                                ; IS THE SPECIFIC THING LOADED INTO ACCA JUST BEFORE THE CALL TO
                                ; "SYNCHK". IF NOT, IT CALLS THE "SYNTAX ERROR" ROUTINE.
                                ; OTHERWISE IT GOBBLES THE NEXT CHAR AND RETURNS,
                                ;
                                ; [A]=NEW CHAR AND TXTPTR IS ADVANCED BY "CHRGET".
                                ;
                                SYNCHR: LDYI 0
                                CMPDY TXTPTR ;CHARACTERS EQUAL?
                                BNE SNERR
                                CHRGO5: JMP CHRGET






                                share|improve this answer














                                share|improve this answer



                                share|improve this answer








                                edited May 28 at 8:19

























                                answered May 28 at 7:44









                                RobotbugsRobotbugs

                                1594 bronze badges




                                1594 bronze badges











                                • 1





                                  From the OP: "(Incidentally, it's convenient also for skipping two bytes in the instruction stream in cases where you don't care what happens to the flags, but I don't imagine that's the use MOS had in mind). What kinds of things was it meant for?)"

                                  – Wilson
                                  May 28 at 10:50
















                                • 1





                                  From the OP: "(Incidentally, it's convenient also for skipping two bytes in the instruction stream in cases where you don't care what happens to the flags, but I don't imagine that's the use MOS had in mind). What kinds of things was it meant for?)"

                                  – Wilson
                                  May 28 at 10:50










                                1




                                1





                                From the OP: "(Incidentally, it's convenient also for skipping two bytes in the instruction stream in cases where you don't care what happens to the flags, but I don't imagine that's the use MOS had in mind). What kinds of things was it meant for?)"

                                – Wilson
                                May 28 at 10:50







                                From the OP: "(Incidentally, it's convenient also for skipping two bytes in the instruction stream in cases where you don't care what happens to the flags, but I don't imagine that's the use MOS had in mind). What kinds of things was it meant for?)"

                                – Wilson
                                May 28 at 10:50





















                                draft saved

                                draft discarded



















































                                Thanks for contributing an answer to Retrocomputing Stack Exchange!


                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid



                                • Asking for help, clarification, or responding to other answers.

                                • Making statements based on opinion; back them up with references or personal experience.


                                To learn more, see our tips on writing great answers.




                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function () {
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fretrocomputing.stackexchange.com%2fquestions%2f11108%2fwhy-does-the-6502-have-the-bit-instruction%23new-answer', 'question_page');
                                }
                                );

                                Post as a guest















                                Required, but never shown





















































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown

































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown







                                Popular posts from this blog

                                He _____ here since 1970 . Answer needed [closed]What does “since he was so high” mean?Meaning of “catch birds for”?How do I ensure “since” takes the meaning I want?“Who cares here” meaningWhat does “right round toward” mean?the time tense (had now been detected)What does the phrase “ring around the roses” mean here?Correct usage of “visited upon”Meaning of “foiled rail sabotage bid”It was the third time I had gone to Rome or It is the third time I had been to Rome

                                Bunad

                                Færeyskur hestur Heimild | Tengill | Tilvísanir | LeiðsagnarvalRossið - síða um færeyska hrossið á færeyskuGott ár hjá færeyska hestinum