Advertisement
felixnardella

Flip Screen

Feb 12th, 2025
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
6502 TASM/64TASS 7.91 KB | Source Code | 0 0
  1. ; Flip Screen - v.2.0 (02/2025)
  2. ; Code by kimono (f. nardella)
  3. ; A program that flips both the character set and screen memory vertically and horizontally
  4. ; Compile with 64tass cross-assembler:
  5. ; 64tass -c -a --cbm-prg flip-screen.asm -o flipscreen.prg
  6.  
  7. ; BASIC starter - creates a SYS command that jumps to our code
  8.  *   = $0801          ; Start of BASIC memory
  9.      .word (+), 2025  ; Pointer to next BASIC line and line number
  10.      .null $9e, format("%d", start)  ; SYS token and start address
  11.  + .word 0           ; End of BASIC program
  12.  
  13. ; Memory location constants
  14. CHAR_MEM = $3000     ; New character set location (12288 decimal)
  15. INIT_SCREEN = $0400  ; Start of screen memory (1024 decimal)
  16. END_SCREEN = $07e7   ; End of screen memory (2023 decimal)
  17. BUFFER = $C800       ; Temporary buffer for screen data
  18. CHARSET_ROM = $D000  ; Location of character ROM (53248 decimal)
  19. VIC_CR = $D018       ; VIC-II control register for character set location
  20. MEM_CONFIG = $01     ; CPU memory configuration register
  21.  
  22.     * = $1000        ; Program code starts at $1000
  23.  
  24. start:
  25.     ; Initialize by disabling interrupts and switching character ROM to RAM
  26.     sei               ; Disable interrupts to prevent timing issues
  27.     lda MEM_CONFIG    ; Load current memory configuration
  28.     and #$FB          ; Clear bit 2 to enable RAM under ROM
  29.     sta MEM_CONFIG    ; Store new configuration
  30.  
  31. ; Copy character ROM to RAM in 6 blocks of 256 bytes each
  32. ; Each block is copied and each character is flipped horizontally using the lookup table
  33. copy_loop:           ; First 256 bytes
  34.     lda CHARSET_ROM, x
  35.     jsr flip_bits    ; Flip each byte horizontally
  36.     sta CHAR_MEM, x
  37.     inx
  38.     bne copy_loop    ; Continue until X wraps around (256 times)
  39.  
  40. copy_loop2:          ; Second 256 bytes
  41.     lda CHARSET_ROM + $FF, x
  42.     jsr flip_bits
  43.     sta CHAR_MEM + $FF, x
  44.     inx
  45.     bne copy_loop2
  46.  
  47. copy_loop3:          ; Third 256 bytes
  48.     lda CHARSET_ROM + 2 * $FF, x
  49.     jsr flip_bits
  50.     sta CHAR_MEM + 2 * $FF, x
  51.     inx
  52.     bne copy_loop3
  53.  
  54. copy_loop4:          ; Fourth 256 bytes
  55.     lda CHARSET_ROM + 3 * $FF, x
  56.     jsr flip_bits
  57.     sta CHAR_MEM + 3 * $FF, x
  58.     inx
  59.     bne copy_loop4
  60.  
  61. copy_loop5:          ; Fifth 256 bytes
  62.     lda CHARSET_ROM + 4 * $FF, x
  63.     jsr flip_bits
  64.     sta CHAR_MEM + 4 * $FF, x
  65.     inx
  66.     bne copy_loop5
  67.  
  68. copy_loop6:          ; Sixth 256 bytes
  69.     lda CHARSET_ROM + 5 * $FF, x
  70.     jsr flip_bits
  71.     sta CHAR_MEM + 5 * $FF, x
  72.     inx
  73.     bne copy_loop6
  74.  
  75. ; Copy flipped character set to buffer for vertical flipping
  76.     ldx #<CHAR_MEM    ; Set up source pointer low byte
  77.     stx $FA
  78.     ldx #>CHAR_MEM    ; Set up source pointer high byte
  79.     stx $FB
  80.     ldx #<BUFFER      ; Set up destination pointer low byte
  81.     stx $FC
  82.     ldx #>BUFFER      ; Set up destination pointer high byte
  83.     stx $FD
  84.     ldy #0
  85.  
  86. ciclo:               ; Copy loop for character set
  87.     lda ($FA), y     ; Load byte from source
  88.     sta ($FC), y     ; Store byte in buffer
  89.     iny
  90.     bne ciclo        ; Continue for 256 bytes
  91.     inc $FB          ; Increment high bytes of pointers
  92.     inc $FD
  93.     ldx $FB
  94.     cpx #$35         ; Check if we've copied all characters
  95.     bne ciclo
  96.  
  97. ; Prepare to flip characters vertically
  98.     ldx #<CHAR_MEM   ; Reset pointers for vertical flip
  99.     stx $FA
  100.     ldx #>CHAR_MEM
  101.     stx $FB
  102.     ldx #<BUFFER
  103.     stx $FC
  104.     ldx #>BUFFER
  105.     stx $FD
  106.  
  107. ; Flip each character vertically (7 bytes per character)
  108. flip_all_chars_loop:
  109.     ldx #6           ; Start from bottom row (6)
  110.     ldy #0           ; Start reading from top row (0)
  111.  
  112. C1:
  113.     lda ($FC), y     ; Read byte from buffer
  114.     sta $02          ; Store temporarily
  115.     tya              ; Save Y
  116.     pha            
  117.     txa              ; Use X as new Y for inverted write
  118.     tay            
  119.     lda $02          ; Get stored byte
  120.     sta ($FA), y     ; Write to new position
  121.     pla              ; Restore Y
  122.     tay            
  123.     iny              ; Next source byte
  124.     dex              ; Previous destination position
  125.     cpy #7           ; Check if we've done all 7 rows
  126.     bne C1
  127.  
  128.     ; Move to next character in buffer
  129.     clc
  130.     lda $FC
  131.     adc #8           ; Each character is 8 bytes
  132.     sta $FC
  133.     bcc skip1
  134.     inc $FD
  135. skip1:
  136.  
  137.     ; Move to next character in destination
  138.     clc
  139.     lda $FA
  140.     adc #8
  141.     sta $FA
  142.     bcc skip2
  143.     inc $FB
  144. skip2:
  145.  
  146.     ; Check if we've processed all characters
  147.     lda $FB
  148.     cmp #$35         ; End of character set
  149.     bne flip_all_chars_loop
  150.  
  151. ; Copy screen memory to buffer for flipping
  152.     ldx #<INIT_SCREEN
  153.     stx $FA
  154.     ldx #>INIT_SCREEN
  155.     stx $FB
  156.     ldx #<BUFFER
  157.     stx $FC
  158.     ldx #>BUFFER
  159.     stx $FD
  160.     ldy #0
  161.  
  162. ciclo1:              ; Copy screen memory to buffer
  163.     lda ($FA), y
  164.     sta ($FC), y
  165.     iny
  166.     bne ciclo1
  167.     inc $FB
  168.     inc $FD
  169.     ldx $FB
  170.     cpx #8           ; Check if we've copied all screen memory
  171.     bne ciclo1
  172.  
  173. ; Flip screen memory vertically in four 256-byte blocks
  174. flip_screen_loop:    ; First block
  175.     lda BUFFER, x    ; Read from start of buffer
  176.     sta END_SCREEN - $FF, y  ; Write to end of screen
  177.     inx
  178.     dey
  179.     bne flip_screen_loop
  180.  
  181. flip_screen_loop2:   ; Second block
  182.     lda BUFFER + $FF, x
  183.     sta END_SCREEN - 2 * $FF, y
  184.     inx
  185.     dey
  186.     bne flip_screen_loop2
  187.  
  188. flip_screen_loop3:   ; Third block
  189.     lda BUFFER + 2 * $FF, x
  190.     sta END_SCREEN - 3 * $FF, y
  191.     inx
  192.     dey
  193.     bne flip_screen_loop3
  194.  
  195. flip_screen_loop4:   ; Fourth block
  196.     lda BUFFER + 3 * $FF, x
  197.     sta END_SCREEN - 4 * $FF, y
  198.     inx
  199.     dey
  200.     bne flip_screen_loop4
  201.  
  202. ; Cleanup and finish
  203.     lda MEM_CONFIG   ; Restore ROM configuration
  204.     ora #$04         ; Set bit 2 to enable ROM
  205.     sta MEM_CONFIG
  206.     cli              ; Re-enable interrupts
  207.  
  208. ; Point VIC-II to new character set
  209.     lda VIC_CR
  210.     and #$F0         ; Clear lower nibble
  211.     ora #$0C         ; Set to point to $3000
  212.     sta VIC_CR
  213.  
  214.     rts              ; Return from subroutine
  215.  
  216. ; Subroutine to flip bits in a byte horizontally
  217. flip_bits:
  218.     tay              ; Use byte as index into lookup table
  219.     lda bit_flip_table, y  ; Get flipped byte from table
  220.     rts
  221.  
  222.  
  223. ; Lookup table for bit flipping
  224. ; Each byte in the table contains the bit-reversed pattern of its index
  225. ; For example: Input 0000 0001 ($01) returns 1000 0000 ($80)
  226. bit_flip_table:
  227.     .byte $00, $80, $40, $C0, $20, $A0, $60, $E0
  228.     .byte $10, $90, $50, $D0, $30, $B0, $70, $F0
  229.     .byte $08, $88, $48, $C8, $28, $A8, $68, $E8
  230.     .byte $18, $98, $58, $D8, $38, $B8, $78, $F8
  231.     .byte $04, $84, $44, $C4, $24, $A4, $64, $E4
  232.     .byte $14, $94, $54, $D4, $34, $B4, $74, $F4
  233.     .byte $0C, $8C, $4C, $CC, $2C, $AC, $6C, $EC
  234.     .byte $1C, $9C, $5C, $DC, $3C, $BC, $7C, $FC
  235.     .byte $02, $82, $42, $C2, $22, $A2, $62, $E2
  236.     .byte $12, $92, $52, $D2, $32, $B2, $72, $F2
  237.     .byte $0A, $8A, $4A, $CA, $2A, $AA, $6A, $EA
  238.     .byte $1A, $9A, $5A, $DA, $3A, $BA, $7A, $FA
  239.     .byte $06, $86, $46, $C6, $26, $A6, $66, $E6
  240.     .byte $16, $96, $56, $D6, $36, $B6, $76, $F6
  241.     .byte $0E, $8E, $4E, $CE, $2E, $AE, $6E, $EE
  242.     .byte $1E, $9E, $5E, $DE, $3E, $BE, $7E, $FE
  243.     .byte $01, $81, $41, $C1, $21, $A1, $61, $E1
  244.     .byte $11, $91, $51, $D1, $31, $B1, $71, $F1
  245.     .byte $09, $89, $49, $C9, $29, $A9, $69, $E9
  246.     .byte $19, $99, $59, $D9, $39, $B9, $79, $F9
  247.     .byte $05, $85, $45, $C5, $25, $A5, $65, $E5
  248.     .byte $15, $95, $55, $D5, $35, $B5, $75, $F5
  249.     .byte $0D, $8D, $4D, $CD, $2D, $AD, $6D, $ED
  250.     .byte $1D, $9D, $5D, $DD, $3D, $BD, $7D, $FD
  251.     .byte $03, $83, $43, $C3, $23, $A3, $63, $E3
  252.     .byte $13, $93, $53, $D3, $33, $B3, $73, $F3
  253.     .byte $0B, $8B, $4B, $CB, $2B, $AB, $6B, $EB
  254.     .byte $1B, $9B, $5B, $DB, $3B, $BB, $7B, $FB
  255.     .byte $07, $87, $47, $C7, $27, $A7, $67, $E7
  256.     .byte $17, $97, $57, $D7, $37, $B7, $77, $F7
  257.     .byte $0F, $8F, $4F, $CF, $2F, $AF, $6F, $EF
  258.     .byte $1F, $9F, $5F, $DF, $3F, $BF, $7F, $FF
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement