User Tools

Site Tools


base:8x_scale_charset_scrolling_message

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

base:8x_scale_charset_scrolling_message [2015-04-17 04:30]
base:8x_scale_charset_scrolling_message [2015-04-17 04:30] (current)
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.  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.
 +
 +
 +
 +<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),       // 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),       // 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),     // Now begin a loop of reading pixel data
 +  sta charbuff,       // 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,       // Bit shift character buffer left once, C=?
 +  ror                   // Invery display character via the C flag.
 +  sta (chardata),     // 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...          @"
 +</code>
 +
 +This is what the result will look like on a c-64:
 +
 +{{base:8x8scroll.png|}}
base/8x_scale_charset_scrolling_message.txt ยท Last modified: 2015-04-17 04:30 (external edit)