base:8x_scale_charset_scrolling_message
8x scale charset scroller
This source code shows you a simple way of displaying the classic oldskool scroller of an expanded 1×1 charset to 8×8 characters on the screen. This version includes reading the ROM charset if you 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 8×8 approach. The code may not be the most optimised either, as this is just to help new coders to understand the routine.
coder: conrad/onslaught/samar
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 /* 2 Zeropage addresses to store the scrolltext current read address. */ .var chardata=$04 /* 2 Zeropage addresses to store character data for bit shifting. */ .var regstates=$06 /* 3 Zeropage addresses to store register states during irq. */ .var chr_himem=$d0 // Hi-byte start address of charset .var scrmem=$07e8-[$28*8] // Screen location of scroller .pc=$0801 "BASIC" :BasicUpstart($0810) // Include basic start. /*--------------------- Beginning of program. ---------------------*/ .pc=$0810 "ROUTINE" sei // Halt any interrupts. /*--------------------------------------- Set the scrolltext start address values to the reserved zeropage addresses. ---------------------------------------*/ lda #>scrolltext sta scroll+1 lda #<scrolltext 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 #<irq // Set irq and nmi vector locations. 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 // Save A register state stx regstates+1 // Save X register state sty regstates+2 // Save Y register state /*------------------------------------------- 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,x sta scrmem+$28,x lda scrmem+$51,x sta scrmem+$50,x lda scrmem+$79,x sta scrmem+$78,x lda scrmem+$a1,x sta scrmem+$a0,x lda scrmem+$c9,x sta scrmem+$c8,x lda scrmem+$f1,x sta scrmem+$f0,x lda scrmem+$119,x sta scrmem+$118,x inx // X++ cpx #$27 // Z=? bne !- // if Z=0, take branch /*--------------------------------------------- The 8x scale font scroll routine starts here. ---------------------------------------------*/ dec print_pos+1 // print_pos-- ldx #$07 // X=7 print_pos: ldy #$00 // N=? bpl print_char // ? N=0 * iny // Y++ sty chardata+1 // chardata=Y (0) stx print_pos+1 // print_pos=X (7) lda (scroll),y // read scrolltext char, Z=? bne !+ // ? Z=0 * lda #>scrolltext // Restore the start address of the sta scroll+1 // scrolltext to the zeropage addresses. lda #<scrolltext // sta scroll // lda (scroll),y // read scrolltext again /*------------------------------------------------------------ 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 character read from the scrolltext, puttin the address into two reserved zeropage address to allow char pixel reading. ------------------------------------------------------------*/ // A = 11111111 !:asl // A = 11111110, C=msb rol chardata+1 // chardata+1 = 0000000? <- C asl // A = 11111100, C=msb rol chardata+1 // chardata+1 = 000000C? <- C asl // A = 11111000, C=msb rol chardata+1 // chardata+1 = 00000CC? <- C sta chardata // chardata = A lda chardata+1 // Add the the hi-byte charset base ora #chr_himem // address to chardata+1 sta chardata+1 // inc scroll // Increase scrolltext read pointers. bne !+ // inc scroll+1 // !:lda (chardata),y // Now begin a loop of reading pixel data sta charbuff,x // from the gathered char memory location 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: // * N=0 ldy #$27 // First, set the start address of screen lda #<scrmem // memory to be written to. sta chardata // lda #>scrmem // 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,x // Bit shift character buffer left once, C=? ror // Invery display character via the C flag. sta (chardata),y // Store display character to screen memory. lda chardata // Set memory pointer to the next row of 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 // if N=0, take branch. /*------------------------ 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 // Y=original state ldx regstates+1 // X=original state lda regstates // A=original state nmi: rti // Return from interrupt /*--------------------------- Character buffer data here. ---------------------------*/ .pc=* "CHARACTER BUFFER DATA" virtual charbuff: .byte $00,$00,$00,$00,$00,$00,$00,$00 /*--------------------- Scrolltext data here. ---------------------*/ .pc=$0c00 "SCROLL TEXT" scrolltext: .text "hi there! this is a test scrolltext for the tutorial routine on how to write a simple 8x scale font scroller, using " .text "a selectable character to write to screen memory. the source of this routine can be found at http://codebase64.org/" .text " ...feel free to do modifications or possible optimisations if you plan to use a routine as such as this one! " .text "coded by conrad/onslaught/samar, 2nd january 2008. wrap... @"
This is what the result will look like on a c-64:
base/8x_scale_charset_scrolling_message.txt · Last modified: 2015-04-17 04:30 by 127.0.0.1