rilo

Char cycler effect for the C64

Jun 28th, 2019
1,237
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2. Example of a char cycler effect for the Commodore 64
  3. Coded by Scan/Desire
  4. Compile using Kick Assembler
  5. Made with the help of consulting http://lodev.org/cgtutor/plasma.html
  6. Pseudo-random number generator from http://codebase64.org/doku.php?id=base:small_fast_8-bit_prng
  7. For the full effect, see the "C64, Hear 64" demo from Desire: https://www.youtube.com/watch?v=ftEYcJDlFjg#t=6m55s
  8.  */
  9. .const w=40
  10. .const h=25
  11. .const multicolor=true
  12.  
  13. basic:
  14. :BasicUpstart2(start)
  15.  
  16. .pc = * "Entrypoint"
  17. start: 
  18.                 // Initialize stuff
  19.                 jsr $ff81
  20.                 jsr $ff84
  21.                 jsr $ff8a
  22.  
  23.                 jsr generatecharset // trashes memory area where speedcode will be generated later
  24.                 jsr generatespeedcode
  25.  
  26.                 sei
  27.                 // Initialize colors and screen data
  28.                 .if (multicolor) {
  29.                     lda #CYAN
  30.                 } else {
  31.                     lda #BLUE
  32.                 }
  33.                 sta $d021
  34.                 lda #BLUE
  35.                 sta $d023
  36.                 lda #LIGHT_BLUE
  37.                 sta $d022
  38.                 ldx #$00
  39.                 stx $d020
  40. !:              lda screendata,x
  41.                 sta $0400,x
  42.                 lda screendata+$100,x
  43.                 sta $0500,x
  44.                 lda screendata+$200,x
  45.                 sta $0600,x
  46.                 lda screendata+$300,x
  47.                 sta $0700,x
  48.                 .if (multicolor) {
  49.                     lda #BLACK | %00001000
  50.                 } else {
  51.                     lda #BLACK
  52.                 }
  53.                 sta $d800,x
  54.                 sta $d900,x
  55.                 sta $da00,x
  56.                 sta $db00,x
  57.                 inx
  58.                 bne !-
  59.  
  60.                 lda $d018           // set character bank ($2000)
  61.                 and #%11110000
  62.                 ora #%00001000
  63.                 sta $d018
  64.  
  65.                 lda $d016           // enable multicolor charset
  66.                 ora #%00010000
  67.                 sta $d016
  68.  
  69.                 // Wait for rasterline 255
  70. frame:          lda #$ff
  71. !:              cmp $d012
  72.                 bne !-
  73.  
  74.                 // Increase all screen values by 1
  75.                 jsr incall
  76.                 jmp frame
  77.  
  78.  
  79. .memblock "Speedcode generator"
  80. .const dstlo = $20
  81. .const dsthi = dstlo+1             
  82. // This generates a lot of INC $xxxx opcodes, for every position on the screen
  83. generatespeedcode:
  84.                 lda #<incall
  85.                 sta dstlo
  86.                 lda #>incall
  87.                 sta dsthi
  88.                 lda #$00
  89.                 sta scrlo
  90.                 lda #$04
  91.                 sta scrhi
  92.  
  93. nextopcode:     ldy #$00
  94.                 lda #INC_ABS
  95.                 sta (dstlo),y
  96.                 iny
  97.                 lda scrlo
  98.                 sta (dstlo),y
  99.                 iny
  100.                 lda scrhi
  101.                 sta (dstlo),y
  102.                 lda dstlo
  103.                 clc
  104.                 adc #$3
  105.                 bcc !+
  106.                 inc dsthi
  107. !:              sta dstlo
  108.                 inc scrlo
  109.                 bne !+
  110.                 inc scrhi
  111. !:              lda scrhi
  112.                 cmp #$07
  113.                 bne nextopcode
  114.                 lda scrlo
  115.                 cmp #$e8
  116.                 bne nextopcode     
  117.                 ldy #$00
  118.                 lda #RTS
  119.                 sta (dstlo),y
  120.                 rts
  121.  
  122. scrlo:          .byte 0
  123. scrhi:          .byte 0
  124.  
  125. .memblock "Characterset generator"
  126. .const chrsrclo = $20
  127. .const chrsrchi = chrsrclo+1
  128. .const chrdstlo = chrsrchi+1
  129. .const chrdsthi = chrdstlo+1
  130.  
  131. /*
  132.   This routine creates the gradient character set. first another subroutine is called which will create chars
  133.   from being completely empty to completely full. Then this copies (and inverts) the gradient to complete the whole charset, so
  134.   this reads as empty->full->empty->full->repeat.
  135. */
  136. generatecharset:   
  137.                 jsr generate64chars
  138.                 ldx #$00
  139. !:              lda $2000,x
  140.                 sta $2400,x
  141.                 eor #$ff
  142.                 sta $2200,x
  143.                 sta $2600,x
  144.                 lda $2100,x
  145.                 sta $2500,x
  146.                 eor #$ff
  147.                 sta $2300,x
  148.                 sta $2700,x
  149.                 dex
  150.                 bne !-
  151.                 rts
  152.  
  153. generate64chars:
  154.                 // this generates an array 0-63, randomly ordered but always starts with 0
  155.                 jsr generateintarray
  156.                 // this will generate a unique random sequence of the numbers
  157.                 ldx #63
  158. !:              jsr getrangednum
  159.                 beq !-
  160.                 sta randomarray,x
  161.                 dex
  162.                 bne !-
  163.                 // blank out 1st character
  164.                 ldy #$07
  165.                 lda #$00
  166. !:              sta $2000,y
  167.                 dey
  168.                 bpl !-
  169.  
  170.                 // initialize pointers
  171.                 lda #$00
  172.                 sta chrsrclo
  173.                 lda #$20
  174.                 sta chrsrchi
  175.                 sta chrdsthi
  176.                 lda #$08
  177.                 sta chrdstlo
  178.  
  179. nextchar:       ldx arraycount
  180.                 cpx #64
  181.                 bne !+
  182.                 rts
  183.  
  184. // This will take a number from the random ordered array and sets a corresponding pixel in the 8x8 char matrix
  185. !:              lda randomarray,x
  186.                 pha
  187.                 and #%00000111
  188.                 sta chrrow
  189.                 pla
  190.                 lsr
  191.                 lsr
  192.                 lsr
  193.                 tay
  194.                 lda #$00
  195.                 sec
  196. !:              rol
  197.                 dey
  198.                 bpl !-
  199.                 sta ormask
  200.                 ldy chrrow
  201.                 lda (chrsrclo),y
  202.                 ora ormask
  203.                 sta (chrsrclo),y
  204.                
  205.                 // copy current character to next
  206.                 ldy #$07
  207. !:              lda (chrsrclo),y
  208.                 sta (chrdstlo),y
  209.                 dey
  210.                 bpl !-
  211.  
  212.                 // move current pointer to next char
  213.                 lda chrdstlo
  214.                 sta chrsrclo
  215.                 lda chrdsthi
  216.                 sta chrsrchi
  217.                 lda chrdstlo
  218.                 clc
  219.                 adc #$08
  220.                 sta chrdstlo
  221.                 bcc !+
  222.                 inc chrdsthi
  223. !:              inc arraycount
  224.                 jmp nextchar
  225.  
  226. arraycount:     .byte 0
  227. chrrow:         .byte 0
  228. ormask:         .byte 0
  229.  
  230. // Generates an array of integers of 0-63
  231. generateintarray:
  232.                 ldx #63
  233. !:              txa
  234.                 sta intarray,x
  235.                 dex
  236.                 bpl !-
  237.                 rts
  238.  
  239. // Picks a random number from the list of integers which is not already been used
  240. getrangednum:
  241. alreadyused:    jsr getrndnum
  242.                 and #$3f
  243.                 tay
  244.                 lda intarray,y
  245.                 bmi alreadyused
  246.                 eor #%10000000
  247.                 sta intarray,y  // mark as used
  248.                 and #%01111111
  249.                 rts
  250.  
  251. // Codebase stuff ;)
  252. getrndnum:      lda seed
  253.                 beq doEor
  254.                 asl
  255.                 bcc noEor
  256. doEor:          eor #$1d
  257. noEor:          sta seed
  258.                 rts    
  259.  
  260. seed:           .byte 0            
  261.  
  262. //
  263. .function charcyclegen(x,y,w,h) {
  264.         // This creates a complex charcycle pattern
  265.         .return (40 * sin(sqrt(pow(x - w / 2, 2) + pow(y - h / 2, 2)) / 2)) + 4 * sin((x + y)) + (62 * cos((x + y) / 5));
  266.  
  267.         // This creates a simple circle (removing the negation will reverse the movement direction)
  268.         .return -(pow(x - w / 2, 2) + pow(y - h / 2, 2)) / 2;
  269.  
  270.         // This creates a checkerboard-like effect
  271.         .return (x ^ y) * 2;
  272. }
  273.  
  274. .memblock "Screen data"
  275. screendata:
  276. .for (var y = 0; y < h; y++) {
  277.     .for (var x = 0; x < w; x++) {
  278.         .byte charcyclegen(x,y,w,h)
  279.     }
  280. }
  281.  
  282. .pc = * "Speedcode"
  283. incall:
  284. intarray:
  285. .label randomarray = *+64
Add Comment
Please, Sign In to add comment