c65gm/examples/shift_demo/shift_demo.c65

411 lines
No EOL
9.7 KiB
Text

//-----------------------------------------------------------
// Shift Operations Demo
// Practical examples of << and >> operators
// Shows real-world uses for bit manipulation
//-----------------------------------------------------------
#INCLUDE <c64start.c65>
#INCLUDE <c64defs.c65>
#PRAGMA _P_REMOVE_UNUSED 1
#INCLUDE <cbmiolib.c65>
#PRAGMA _P_USE_CBM_STRINGS 1
GOTO start
// Variables for demos
BYTE demo_value
BYTE demo_result
BYTE demo_shift
WORD demo_word
WORD demo_word_result
//-----------------------------------------------------------
// Wait for key press
//-----------------------------------------------------------
FUNC wait_key
BYTE key
// Wait for no key
WHILE 1
key = PEEK $c5
IF key = 64
BREAK
ENDIF
WEND
// Wait for key press
WHILE 1
key = PEEK $c5
IF key != 64
BREAK
ENDIF
WEND
// Reset key buffer
POKE $c6 WITH 0
FEND
//-----------------------------------------------------------
// Clear screen
//-----------------------------------------------------------
FUNC clear_screen
lib_cbmio_cls()
lib_cbmio_home()
FEND
//-----------------------------------------------------------
// Print binary representation of byte
//-----------------------------------------------------------
FUNC print_binary({BYTE val})
BYTE i = 7
BYTE mask
BYTE bit
lib_cbmio_print(" %")
WHILE i < 8 // Will break when i wraps around to 255
mask = 1 << i
bit = val & mask
IF bit != 0
lib_cbmio_print("1")
ELSE
lib_cbmio_print("0")
ENDIF
// Add space every 4 bits for readability
IF i = 4
lib_cbmio_print(" ")
ENDIF
// Decrement i, break if we go below 0
IF i = 0
BREAK
ENDIF
i = i - 1
WEND
FEND
//-----------------------------------------------------------
// Demo 1: Basic shift operations
//-----------------------------------------------------------
FUNC demo_basic_shifts
lib_cbmio_printlf("basic shift operations")
lib_cbmio_printlf("======================")
lib_cbmio_printlf("")
// Constant left shift
demo_value = $03 // Binary: 00000011
demo_result = demo_value << 2
lib_cbmio_print("$03 << 2 = $")
lib_cbmio_hexoutb(demo_result)
print_binary(demo_result)
lib_cbmio_printlf(" (3 * 4 = 12)")
lib_cbmio_printlf("")
// Constant right shift
demo_value = $30 // Binary: 00110000
demo_result = demo_value >> 3
lib_cbmio_print("$30 >> 3 = $")
lib_cbmio_hexoutb(demo_result)
print_binary(demo_result)
lib_cbmio_printlf(" (48 / 8 = 6)")
lib_cbmio_printlf("")
// Variable shift amount
demo_value = $80 // Binary: 10000000
demo_shift = 3
demo_result = demo_value >> demo_shift
lib_cbmio_print("$80 >> ")
lib_cbmio_hexoutb(demo_shift)
lib_cbmio_print(" = $")
lib_cbmio_hexoutb(demo_result)
print_binary(demo_result)
lib_cbmio_printlf("")
lib_cbmio_printlf("")
wait_key()
FEND
//-----------------------------------------------------------
// Demo 2: Bit manipulation
//-----------------------------------------------------------
FUNC demo_bit_manipulation
lib_cbmio_printlf("bit manipulation")
lib_cbmio_printlf("================")
lib_cbmio_printlf("")
// Extract color components from C64 color byte
// C64 color: bits 7-4 = background, bits 3-0 = foreground
BYTE color = $3E // Background: 3, Foreground: E
BYTE background
BYTE foreground
background = color >> 4
foreground = color & $0F
lib_cbmio_print("color byte: $")
lib_cbmio_hexoutb(color)
print_binary(color)
lib_cbmio_printlf("")
lib_cbmio_print("background: $")
lib_cbmio_hexoutb(background)
lib_cbmio_printlf(" (>> 4)")
lib_cbmio_print("foreground: $")
lib_cbmio_hexoutb(foreground)
lib_cbmio_printlf(" (& $0f)")
lib_cbmio_printlf("")
// Create bit masks
lib_cbmio_printlf("bit masks:")
BYTE mask
mask = 1 << 0
lib_cbmio_print("1 << 0 = $")
lib_cbmio_hexoutb(mask)
lib_cbmio_print(" (bit 0)")
lib_cbmio_printlf("")
mask = 1 << 7
lib_cbmio_print("1 << 7 = $")
lib_cbmio_hexoutb(mask)
lib_cbmio_print(" (bit 7)")
lib_cbmio_printlf("")
mask = 1 | 2 // Bits 0 and 1
lib_cbmio_print("bits 0+1 = $")
lib_cbmio_hexoutb(mask)
print_binary(mask)
lib_cbmio_printlf("")
lib_cbmio_printlf("")
wait_key()
FEND
//-----------------------------------------------------------
// Demo 3: Multiplication and division
//-----------------------------------------------------------
FUNC demo_multiply_divide
lib_cbmio_printlf("fast multiply/divide")
lib_cbmio_printlf("====================")
lib_cbmio_printlf("")
// Multiplication by powers of 2
BYTE value = 7
lib_cbmio_print("7 * 2 = ")
demo_result = value << 1
lib_cbmio_hexoutb(demo_result)
lib_cbmio_printlf(" (7 << 1)")
lib_cbmio_print("7 * 4 = ")
demo_result = value << 2
lib_cbmio_hexoutb(demo_result)
lib_cbmio_printlf(" (7 << 2)")
lib_cbmio_print("7 * 8 = ")
demo_result = value << 3
lib_cbmio_hexoutb(demo_result)
lib_cbmio_printlf(" (7 << 3)")
lib_cbmio_printlf("")
// Division by powers of 2
value = 100
lib_cbmio_print("100 / 2 = ")
demo_result = value >> 1
lib_cbmio_hexoutb(demo_result)
lib_cbmio_printlf(" (100 >> 1)")
lib_cbmio_print("100 / 4 = ")
demo_result = value >> 2
lib_cbmio_hexoutb(demo_result)
lib_cbmio_printlf(" (100 >> 2)")
lib_cbmio_print("100 / 8 = ")
demo_result = value >> 3
lib_cbmio_hexoutb(demo_result)
lib_cbmio_printlf(" (100 >> 3)")
lib_cbmio_printlf("")
// Variable shift for scaling
value = 5
demo_shift = 3 // Multiply by 8
lib_cbmio_print("5 * 8 = ")
demo_result = value << demo_shift
lib_cbmio_hexoutb(demo_result)
lib_cbmio_print(" (5 << ")
lib_cbmio_hexoutb(demo_shift)
lib_cbmio_printlf(")")
lib_cbmio_printlf("")
wait_key()
FEND
//-----------------------------------------------------------
// Demo 4: Word operations
//-----------------------------------------------------------
FUNC demo_word_operations
lib_cbmio_printlf("16-bit word operations")
lib_cbmio_printlf("======================")
lib_cbmio_printlf("")
// Word left shift (multiply by 2)
demo_word = $1234
demo_word_result = demo_word << 1
lib_cbmio_print("$1234 << 1 = $")
lib_cbmio_hexoutw(demo_word_result)
lib_cbmio_printlf(" ($1234 * 2 = $2468)")
lib_cbmio_printlf("")
// Word right shift (divide by 2)
demo_word = $ABCD
demo_word_result = demo_word >> 1
lib_cbmio_print("$abcd >> 1 = $")
lib_cbmio_hexoutw(demo_word_result)
lib_cbmio_printlf(" ($abcd / 2 = $55e6)")
lib_cbmio_printlf("")
// Shift between bytes
demo_word = $00FF
demo_word_result = demo_word << 8
lib_cbmio_print("$00ff << 8 = $")
lib_cbmio_hexoutw(demo_word_result)
lib_cbmio_printlf(" (low->high byte)")
demo_word = $FF00
demo_word_result = demo_word >> 8
lib_cbmio_print("$ff00 >> 8 = $")
lib_cbmio_hexoutw(demo_word_result)
lib_cbmio_printlf(" (high->low byte)")
lib_cbmio_printlf("")
// Byte to word conversion with shift
BYTE small = $81
WORD large
large = small << 2 // Zero-extends byte to word, then shifts
lib_cbmio_print("byte $81 << 2 = word $")
lib_cbmio_hexoutw(large)
lib_cbmio_printlf(" (zero-extended)")
lib_cbmio_printlf("")
wait_key()
FEND
//-----------------------------------------------------------
// Demo 5: Practical C64 example
//-----------------------------------------------------------
FUNC demo_c64_example
lib_cbmio_printlf("c64 practical example")
lib_cbmio_printlf("=====================")
lib_cbmio_printlf("")
// Simulate reading joystick port 2
// Bits: 0=up, 1=down, 2=left, 3=right, 4=fire
BYTE joystick = $17 // Binary: 00010111 (up, down, right, fire)
lib_cbmio_print("joystick port: $")
lib_cbmio_hexoutb(joystick)
print_binary(joystick)
lib_cbmio_printlf("")
lib_cbmio_printlf("")
// Check individual buttons using shifts
lib_cbmio_printlf("checking buttons:")
lib_cbmio_printlf("")
// Fire button (bit 4)
BYTE fire_mask
BYTE fire_check
fire_mask = 1 << 4
fire_check = joystick & fire_mask
IF fire_check = 0
lib_cbmio_printlf("fire: pressed")
ELSE
lib_cbmio_printlf("fire: not pressed")
ENDIF
// Up button (bit 0)
BYTE up_mask
BYTE up_check
up_mask = 1 << 0
up_check = joystick & up_mask
IF up_check = 0
lib_cbmio_printlf("up: pressed")
ELSE
lib_cbmio_printlf("up: not pressed")
ENDIF
// Right button (bit 3)
BYTE right_mask
BYTE right_check
right_mask = 1 << 3
right_check = joystick & right_mask
IF right_check = 0
lib_cbmio_printlf("right: pressed")
ELSE
lib_cbmio_printlf("right: not pressed")
ENDIF
lib_cbmio_printlf("")
// Extract direction bits to nibble
BYTE direction
direction = joystick & $0F // Mask off fire button
lib_cbmio_print("direction bits: $")
lib_cbmio_hexoutb(direction)
print_binary(direction)
lib_cbmio_printlf("")
lib_cbmio_printlf("")
wait_key()
FEND
//-----------------------------------------------------------
// Main program
//-----------------------------------------------------------
LABEL start
clear_screen()
lib_cbmio_printlf("shift operators demo")
lib_cbmio_printlf("====================")
lib_cbmio_printlf("")
lib_cbmio_printlf("press any key...")
lib_cbmio_printlf("")
wait_key()
demo_basic_shifts()
clear_screen()
demo_bit_manipulation()
clear_screen()
demo_multiply_divide()
clear_screen()
demo_word_operations()
clear_screen()
demo_c64_example()
clear_screen()
lib_cbmio_printlf("demo complete!")
lib_cbmio_printlf("")
lib_cbmio_printlf("shift operators:")
lib_cbmio_printlf(" << left shift (multiply)")
lib_cbmio_printlf(" >> right shift (divide)")
lib_cbmio_printlf("")
lib_cbmio_printlf("works with bytes and words")
lib_cbmio_printlf("")
// Infinite loop
LABEL loop
GOTO loop