BIT $hhll
Mnemonic: | BIT $hhll | ||||||
2. Schreibweise: | {{{2. Schreibweise}}} | ||||||
Opcode: | $2C | ||||||
Operator(en): | $ll $hh | ||||||
Byte count: | 3 | ||||||
Command type: | Arithmetic- and logic command | ||||||
Address mode: | absolute | ||||||
register flags: | |||||||
Negative Flag | |||||||
Overflow Flag | |||||||
Zero Flag | |||||||
Cycles: | 4 | ||||||
The assembler command BIT $hhll performs a bitwise AND with the content of the memory location $hhll.
The result unlike the command AND $hhll is not written into the Accumulator, only the flags (Zero Flag, Negative Flag and Overflow Flag) are modified.
This command is optimal for checking single bits. (see Example 1)
Another possible application is to skip commands. (see Example 2)
The command BIT $hhll is processed in two steps.
Step 1: Bits 7 and 6 are of memory location $hhll are checked and the Negative Flag as well as the Overflow Flag are modified accordingly.
Step 2: A bitwise AND operation between the accumulator and the content of memory location $hhll is performed, only modifying the Zero Flag.
Due to this two step processing all three flags can be modified at once. It's even possible that all three flags are set at the same time. This cannot happen with the assembler command AND $hhll since the Negative Flag and the Zero Flag cannot be set at the same time; a number can only be zero or negative.
Function flow
Explanation of the mnemonic shortcut
BIT | BIT test |
Test Bits |
Example 1
Checking for single set bits.
; This program is a simple joystick check routine for control port 2. ; Joystick up/down = border color +/- ; Joystick left/right = background color +/- ; Fire button = end ; Start with SYS 49152 *=$c000 ; start address of the program start lda $02 cmp $dc00 beq start ; loop until the joystick register changes. lda $dc00 ; store new value in memory location 2. sta $02 lda #%00000001 ; mask joystick up movement bit $dc00 ; bitwise AND with address 56320 bne cont1 ; no movement up -> do not increase border color inc $d020 ; border color + 1 cont1 lda #%00000010 ; mask joystick down movement bit $dc00 ; bitwise AND with address 56320 bne cont2 ; no movement down -> do not decrease border color dec $d020 ; border color- 1 cont2 lda #%00000100 ; mask joystick left movement bit $dc00 ; bitwise AND with address 56320 bne cont3 ; no movement left -> do not increase background color inc $d021 ; background color + 1 cont3 lda #%00001000 ; mask joystick right movement bit $dc00 ; bitwise AND with address 56320 bne cont4 ; no movement right -> do not decrease background color dec $d021 ; background color - 1 cont4 lda #%00010000 ; mask joystick button push bit $dc00 ; bitwise AND with address 56320 bne start ; button not pressed -> enter loop again rts ; back to basic
.c000 a5 02 lda $02 .c002 cd 00 dc cmp $dc00 .c005 f0 f9 beq $c000 .c007 ad 00 dc lda $dc00 .c00a 85 02 sta $02 .c00c a9 01 lda #$01 .c00e 2c 00 dc bit $dc00 .c011 d0 03 bne $c016 .c013 ee 20 d0 inc $d020 .c016 a9 02 lda #$02 .c018 2c 00 dc bit $dc00 .c01b d0 03 bne $c020 .c01d ce 20 d0 dec $d020 .c020 a9 04 lda #$04 .c022 2c 00 dc bit $dc00 .c025 d0 03 bne $c02a .c027 ee 21 d0 inc $d021 .c02a a9 08 lda #$08 .c02c 2c 00 dc bit $dc00 .c02f d0 03 bne $c034 .c031 ce 21 d0 dec $d021 .c034 a9 10 lda #$10 .c036 2c 00 dc bit $dc00 .c039 d0 c5 bne $c000 .c03b 60 rts
Comparison of the 1. example program with Basic
100 A=0 110 IF A=PEEK(56320) THEN 110 120 A=PEEK(56320) 200 O=A AND 1 210 IF O>0 THEN 300 220 POKE 53280, (PEEK(53280)+1) AND 255 300 O=A AND 2 310 IF O>0 THEN 400 320 POKE 53280, (PEEK(53280)-1) AND 255 400 O=A AND 4 410 IF O>0 THEN 500 420 POKE 53281, (PEEK(53281)+1) AND 255 500 O=A AND 8 510 IF O>0 THEN 600 520 POKE 53281, (PEEK(53281)-1) AND 255 600 O=A AND 16 610 IF O>0 THEN 110
Example 2
Proper misuse of BIT: Low memory skipping of following commands of two bytes length. The actual functionality of the command is not used, it is treated as a three byte NOP. The illegal opcode $0c might be used for this as well (which is a NOP $hhll and does not modify flags), most common is BIT though.
; This program shows the skipping of commands by using the BIT command. ; Instead of $2Cs there might also be a JMP Out or BNE Out, both do need more memory though. ; After starting with SYS 49152 the screen is cleared and the string !***! is printed. *=$c000 ; start address of the program BSOUT = $ffd2 start jsr Clrscr ; clear screen jsr Rufzeichen ; print ! jsr Stern ; print * jsr Stern ; print * jsr Stern ; print * jsr Rufzeichen ; print ! rts ; return to Basic ; ----- sub program ----- Stern lda #'*' ; print star (command flow: lda #'*' bit $21a9 bit $93a9 jsr $ffd2 rts) .byte $2c ; opcode for BIT $hhll Rufzeichen lda #'!' ; print exclamation mark (command flow: lda #'!' bit $93a9 jsr $ffd2 rts) .byte $2c ; opcode for BIT $hhll Clrscr lda #147 ; clear screen Out jsr BSOUT ; print char on screen rts ; return
.c000 20 19 c0 jsr $c019 .c003 20 16 c0 jsr $c016 .c006 20 13 c0 jsr $c013 .c009 20 13 c0 jsr $c013 .c00c 20 13 c0 jsr $c013 .c00f 20 16 c0 jsr $c016 .c012 60 rts .c013 a9 2a lda #$2a >c015 2c .byte $2c .c016 a9 21 lda #$21 >c018 2c .byte $2c .c019 a9 93 lda #$93 .c01b 20 d2 ff jsr $ffd2 .c01e 60 rts
The CPU performs the following commands:
; ...after a jsr $c013: .c013 a9 2a lda #$2a .c015 2c a9 21 bit $21a9 ; BIT "hidden" a9 21 = lda #$21 .c018 2c a9 93 bit $93a9 ; BIT "hidden" a9 93 = lda #$93 .c01b 20 d2 ff jsr $ffd2 .c01e 60 rts ; ...after a jsr $c016: .c016 a9 21 lda #$21 .c018 2c a9 93 bit $93a9 ; BIT "hidden" a9 93 = lda #$93 .c01b 20 d2 ff jsr $ffd2 .c01e 60 rts