BIT $hhll

From C64-Wiki
Jump to navigationJump to search
Disambiguation The title of this article is ambiguous. Bit (Disambiguation).


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

Assembler command 2c.gif

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

Links