===== 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. 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 8x8 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 #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 #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:8x8scroll.png|}}