base:8x_scale_charset_scrolling_message
no way to compare when less than two revisions
Differences
This shows you the differences between two versions of the page.
— | base:8x_scale_charset_scrolling_message [2015-04-17 04:30] (current) – created - external edit 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ===== 8x scale charset scroller ===== | ||
+ | This source code shows you a simple way of displaying the classic | ||
+ | oldskool scroller of an expanded 1x1 charset to 8x8 characters on | ||
+ | the screen. | ||
+ | don't decide to include your own. | ||
+ | |||
+ | People can of course alter the code to different constraints of | ||
+ | their liking, but this is just the simple 8x8 approach. | ||
+ | may not be the most optimised either, as this is just to help new | ||
+ | coders to understand the routine. | ||
+ | |||
+ | coder: | ||
+ | |||
+ | The source code is in KickAssembler format, so make sure you know | ||
+ | how to use the assembler before trying out the code. | ||
+ | |||
+ | |||
+ | |||
+ | < | ||
+ | / | ||
+ | KickAssember variables used in routine. | ||
+ | ---------------------------------------*/ | ||
+ | .var scroll=$02 | ||
+ | | ||
+ | .var chardata=$04 | ||
+ | | ||
+ | .var regstates=$06 | ||
+ | | ||
+ | .var chr_himem=$d0 | ||
+ | .var scrmem=$07e8-[$28*8] | ||
+ | |||
+ | |||
+ | .pc=$0801 " | ||
+ | : | ||
+ | |||
+ | |||
+ | / | ||
+ | Beginning of program. | ||
+ | ---------------------*/ | ||
+ | .pc=$0810 " | ||
+ | | ||
+ | sei // Halt any interrupts. | ||
+ | |||
+ | / | ||
+ | Set the scrolltext start address values | ||
+ | to the reserved zeropage addresses. | ||
+ | ---------------------------------------*/ | ||
+ | lda #> | ||
+ | sta scroll+1 | ||
+ | lda #< | ||
+ | sta scroll | ||
+ | | ||
+ | / | ||
+ | Set up irq. | ||
+ | -----------*/ | ||
+ | lda #$01 // Set raster compare irq flag and | ||
+ | sta $d01a // interrupt request register to 1. | ||
+ | sta $d019 // | ||
+ | lda #$7f // Set CIA interrupt control register. | ||
+ | sta $dc0d // | ||
+ | lda #$35 // Set memory configuration to | ||
+ | sta $01 // full RAM with I/O. | ||
+ | lda #< | ||
+ | ldy #<nmi | ||
+ | sta $fffe | ||
+ | sty $fffa | ||
+ | lda #>irq | ||
+ | ldy #>nmi | ||
+ | sta $ffff | ||
+ | sty $fffb | ||
+ | lda #$f8 // Set raster line required in irq. | ||
+ | sta $d012 // | ||
+ | lda #$1b // Set to view to text mode and | ||
+ | sta $d011 // clear the MSB of raster line. | ||
+ | lda #$03 // Set bank | ||
+ | sta $dd00 // | ||
+ | lda #$08 // Set X scroll position | ||
+ | sta $d016 // | ||
+ | lda #$14 // Set screenmem and charset base | ||
+ | sta $d018 // | ||
+ | lda $dc0d // Latch CIA irq control register. | ||
+ | | ||
+ | cli // Clear interrupt flag. | ||
+ | bvc * // loop here. | ||
+ | |||
+ | / | ||
+ | Beginning of the irq routine. | ||
+ | -----------------------------*/ | ||
+ | irq: | ||
+ | sta regstates | ||
+ | stx regstates+1 | ||
+ | sty regstates+2 | ||
+ | |||
+ | / | ||
+ | Check if requested raster line has reached. | ||
+ | -------------------------------------------*/ | ||
+ | lda $d012 | ||
+ | !:cmp $d012 // Z=? | ||
+ | bne !- // if Z=0, take branch | ||
+ | |||
+ | / | ||
+ | This is optional if you want to use the ROM charset. | ||
+ | ----------------------------------------------------*/ | ||
+ | lda $01 // Save original $01 state | ||
+ | sta original_01+1 | ||
+ | lda #$32 // Set memory configuration to | ||
+ | sta $01 // character ROM access. | ||
+ | |||
+ | / | ||
+ | Scroll 8 lines of screen memory by one char to the left. | ||
+ | This isn't the foremost way performance wise, but it | ||
+ | does the job at least. | ||
+ | --------------------------------------------------------*/ | ||
+ | ldx #$00 // X=0 | ||
+ | !:lda scrmem+$1,x | ||
+ | sta scrmem+$0,x | ||
+ | lda scrmem+$29, | ||
+ | sta scrmem+$28, | ||
+ | lda scrmem+$51, | ||
+ | sta scrmem+$50, | ||
+ | lda scrmem+$79, | ||
+ | sta scrmem+$78, | ||
+ | lda scrmem+$a1, | ||
+ | sta scrmem+$a0, | ||
+ | lda scrmem+$c9, | ||
+ | sta scrmem+$c8, | ||
+ | lda scrmem+$f1, | ||
+ | sta scrmem+$f0, | ||
+ | lda scrmem+$119, | ||
+ | sta scrmem+$118, | ||
+ | inx // X++ | ||
+ | cpx #$27 // Z=? | ||
+ | bne !- // if Z=0, take branch | ||
+ | |||
+ | / | ||
+ | The 8x scale font scroll routine starts here. | ||
+ | ---------------------------------------------*/ | ||
+ | dec print_pos+1 | ||
+ | ldx #$07 // X=7 | ||
+ | print_pos: | ||
+ | ldy #$00 // N=? | ||
+ | bpl print_char | ||
+ | iny // Y++ | ||
+ | sty chardata+1 | ||
+ | stx print_pos+1 | ||
+ | |||
+ | lda (scroll), | ||
+ | bne !+ // ? Z=0 * | ||
+ | lda #> | ||
+ | sta scroll+1 | ||
+ | lda #< | ||
+ | sta scroll | ||
+ | lda (scroll), | ||
+ | |||
+ | / | ||
+ | This following chunk of code is not necessary to include, | ||
+ | but it allows spaces on the scroller to be slightly shorter | ||
+ | when viewed on the screen, making the text more readable. | ||
+ | ------------------------------------------------------------*/ | ||
+ | !:cmp #$20 // * Z=0, check if char is a space, Z=? | ||
+ | bne !+ // ? Z=0 ** | ||
+ | dec print_pos+1 | ||
+ | dec print_pos+1 | ||
+ | dec print_pos+1 | ||
+ | |||
+ | / | ||
+ | Do left bit shifting to get the start address of the | ||
+ | | ||
+ | two reserved zeropage address to allow char pixel reading. | ||
+ | ------------------------------------------------------------*/ | ||
+ | // A = 11111111 | ||
+ | !:asl // A = 11111110, C=msb | ||
+ | rol chardata+1 | ||
+ | asl // A = 11111100, C=msb | ||
+ | rol chardata+1 | ||
+ | asl // A = 11111000, C=msb | ||
+ | rol chardata+1 | ||
+ | sta chardata | ||
+ | lda chardata+1 | ||
+ | ora # | ||
+ | sta chardata+1 | ||
+ | inc scroll | ||
+ | bne !+ // | ||
+ | inc scroll+1 | ||
+ | !:lda (chardata), | ||
+ | sta charbuff, | ||
+ | iny // and store into an 8 byte buffer. | ||
+ | dex // | ||
+ | bpl !- // | ||
+ | ldx #$07 // X=7 | ||
+ | |||
+ | / | ||
+ | Branch here is a character is still to be printed. | ||
+ | --------------------------------------------------*/ | ||
+ | print_char: | ||
+ | ldy #$27 // First, set the start address of screen | ||
+ | lda #< | ||
+ | sta chardata | ||
+ | lda #> | ||
+ | sta chardata+1 | ||
+ | |||
+ | / | ||
+ | This is a loop routine to print each row of the | ||
+ | current character column pixel to the screen. | ||
+ | -----------------------------------------------*/ | ||
+ | print_char_loop: | ||
+ | lda #$40 // Set your display character here. | ||
+ | asl charbuff, | ||
+ | ror // Invery display character via the C flag. | ||
+ | sta (chardata), | ||
+ | lda chardata | ||
+ | adc #$28 // screen memory. | ||
+ | sta chardata | ||
+ | lda chardata+1 | ||
+ | adc #$00 // | ||
+ | sta chardata+1 | ||
+ | dex // How many rows left?, X-- N=? | ||
+ | bpl print_char_loop | ||
+ | |||
+ | / | ||
+ | End of scroller routine. | ||
+ | ------------------------*/ | ||
+ | original_01: | ||
+ | lda #$00 // Retrieve the original memory configuration | ||
+ | sta $01 // state before the scroll routine was executed. | ||
+ | | ||
+ | / | ||
+ | End of interrupt routine. | ||
+ | -------------------------*/ | ||
+ | lda #$01 // Reset interrupt request register to 1. Spare me | ||
+ | sta $d019 // the critisim on how to REALLY do this. ;D | ||
+ | lda $dc0d // Latch CIA irq control register. | ||
+ | ldy regstates+2 | ||
+ | ldx regstates+1 | ||
+ | lda regstates | ||
+ | nmi: | ||
+ | rti // Return from interrupt | ||
+ | |||
+ | |||
+ | / | ||
+ | Character buffer data here. | ||
+ | ---------------------------*/ | ||
+ | .pc=* " | ||
+ | charbuff: | ||
+ | .byte $00, | ||
+ | |||
+ | |||
+ | / | ||
+ | Scrolltext data here. | ||
+ | ---------------------*/ | ||
+ | .pc=$0c00 " | ||
+ | scrolltext: | ||
+ | .text "hi there! | ||
+ | .text "a selectable character to write to screen memory. | ||
+ | .text " | ||
+ | .text "coded by conrad/ | ||
+ | </ | ||
+ | |||
+ | This is what the result will look like on a c-64: | ||
+ | |||
+ | {{base: |
base/8x_scale_charset_scrolling_message.txt · Last modified: 2015-04-17 04:30 by 127.0.0.1