User Tools

Site Tools


base:256_bytes_tune_player
no way to compare when less than two revisions

Differences

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


base:256_bytes_tune_player [2015-04-17 04:30] (current) – created - external edit 127.0.0.1
Line 1: Line 1:
 +====== 256 bytes tune+player by FTC/HT ======
 +Sorry, don't remember what assembler I used to assemble this. Might have been Dreamass by Doc Bacardi/The Dreams.
  
 +This tune+player was coded as a compo entry for the Tiny SID #1 competition. The aim was to make a quite long tune rather than something short with fancy instruments.
 +
 +NOTE: Freshness79 wrote a post on CSDb where he said: "You can cut 2 more bytes by using $032c to "automagically" run your code. This routine gets called at the end of the load process to close all channels ($F32F). It doesn't need to be followed by particular sequences of bytes."
 +
 +<code>
 +; Title:  "NewKidOnTheBlock"
 +; Chip:   6581 C64 used when composing.
 +; Author: Frantic/Hack'n'Trade
 +
 +;---------------------------------
 +; CONSTANTS
 +;
 +DEBUG = 0
 +NUMBEROFVOICES = 3 ;Using all three Voices
 +S = $10 ;Song "speed"
 +
 +;---------------------------------
 +; ZERO PAGE ADDRESSES
 +;
 +
 +TICKCOUNTERS = $02 ;Use zp for tickcounters.. TICKCOUNTERS+0, TICKCOUNTERS+7,
 + ;TICKCOUNTERS+14 will be used.
 +DATAPOS = $03 ;Use zp for SONGPOSITIONS... 0, 7, 14.. 
 +FILTERHI = $23
 +
 +;---------------------------------
 +; CODE
 +;
 + * = $326
 +
 +        .word start ;Four byte init code. Shamelessly ripped from Alihs entry, who ripped it from Steven 
 +        .word $f6ed ;Judd... :) Since Alih "ripped" this I guess I could just as well use it too.???
 +        ;I hope that won't break any competition rules. Ninjas method, used in xxxlarge was
 +        ;nice too, but still some bytes larger even if one includes the extra code here
 +        ;needed for raster sync.. 
 +
 +start: sei
 +
 + ldy #$02 ;Set it to $02 so the first incorrectly timed 
 + ;iteration won't affect anything
 + sty FILTERHI ;Init filtersweep to make it a bit more deterministic.
 +
 + ;Init counters and sonpositions
 + lda #(NUMBEROFVOICES-1)*7 ;Voice indeX
 +@initlp: tax
 + sta DATAPOS,x ;Init datapos+0 to 0, datapos+7 to 7 and datapos+14 to 14.
 + sty TICKCOUNTERS,x ;y can be anything.. doesn't matter, but now I happen to 
 + ;init the filter so set it to $01 too
 + sec
 + sbc #7
 + bpl @initlp
 +
 +;--
 +; Main player loop
 +@outerloop:
 +@wrast: cpx $d012 ;After the loop, x is a negative number, thus well above $3e 
 + ;(or whatever the critical raster value is again..)
 + bne @wrast ;First iteration won't be correct though, but since the
 + ;counters are set to 2 initially it doesn't matter.
 +
 + #if DEBUG
 + lda #1
 + sta $d020
 + sta $d021
 + #endif
 +
 + jsr $b5ff ;hijack some BASIC ROM shit to do the filter sweep
 + ;b5ff looks like this:
 + ; inc $23
 + ; ldx $23
 + ; ldy #$00
 + ; rts
 + stx $d416 ;filter hi
 +
 + ldx #(NUMBEROFVOICES-1)*7 ;Voice indeX
 + ;Right here is a good place for Voice specific code, if there is any reason for that.
 +@innerloop:
 + dec TICKCOUNTERS,x
 + bne @loopend
 +
 + ;Time for new sound settings, turn gate and oscillator off..
 + lda #8
 + sta $d404,x
 +
 + ;Turn on global volume to make sure we'll hear anything at all.
 + ;Reason for having this code *inside* the loop: 
 + ;  To make sure the player won't run too fast and get executed
 + ;  twice on the same rasterline.
 + lda #$5f ;Hi-pass + Lo-pass filter on.
 + sta $d418
 + lda #$a2 ;Filter used on middle (melody) voice.
 + sta $d417
 +
 + ;Parse data sequence data
 + ldy DATAPOS,x
 + @newseq:
 + iny
 + lda @musicdata-1,y ;Get databyte
 + bne @nonewseq
 + lda @musicdata-0,y ;Get jumpval if it's jumptime
 + tay ;..and use new one instead
 + bpl @newseq ;This means data may not be larger than $80 bytes
 + @nonewseq:
 + sty DATAPOS,x
 + pha
 + and #$0f ;Note value
 + tay
 + lda @freqhi,y
 + sta $d401,x ;Freq hi
 + lda @freqlo,y
 + sta $d400,x ;Freq lo
 + pla
 + lsr
 + lsr
 + lsr
 + lsr
 + tay
 + lda adtab,y
 + sta $d405,x
 + lda durtab,y
 + sta TICKCOUNTERS,x
 + lda ctrltab,y
 + sta $d404,x
 +
 +@loopend:
 + txa
 + .byte $cb,7 ;axs #7 / sbx #7 / whatever..
 + bpl @innerloop
 +
 + #if DEBUG
 + dec $d020
 + dec $d021
 + jmp @outerloop
 + #endif
 +
 + bmi @outerloop
 +
 +
 +;---------------------------------
 +; "Instruments"
 +;
 +; Using AD only to save space. (SR is set to 00 as default)
 +;
 +; A pattern is S*8 ticks long, so using "instrument" 5 we
 +; can represent a whole empty pattern by just one byte in
 +; the sequence data. At the same time, this format allows
 +; for changes to the waveform every tick, which means we
 +; can also make drums and such things. But, not in this 
 +; tune. Perhaps in the next one..
 +;
 +;        00   01   02   03   04   05   06
 +@adtab: .byte $1c, $1b, $cd, $2b, $1a, $00, $ad
 +@ctrltab: .byte $11, $11, $21, $21, $21, $00, $21
 +@durtab: .byte S*1, S*3, S*6, S*2, S*1, S*8, S*8
 +
 +;---------------------------------
 +; Sequence data
 +;
 +; Voc0 starts at 0
 +; Voc1 starts at 7
 +; Voc2 starts at 14
 +;
 +; Note and duration stored in one byte and the byte following a $00 (JP)
 +; byte is interpreted as the destination of a jump to another place in 
 +; the data.
 +
 +@musicdata:
 +@Voc0start:
 + .byte $00 | G4
 + .byte $00 | Az4
 + .byte $00 | C5
 + .byte $00 | D5
 + .byte $00 | Dz5
 + .byte JP
 + .byte <(@Voc0komp-@musicdata)
 +@Voc1start:
 + .byte $20 | D5
 + .byte $30 | Dz5
 +
 + .byte $20 | D5
 + .byte $40 | A4
 + .byte $40 | Az4
 +
 + .byte JP
 + .byte <(@Voc1melody-@musicdata)
 +@Voc2start:
 + ;-
 + .byte $50 | 0
 + .byte $50 | 0
 + .byte $50 | 0
 + .byte $50 | 0
 +
 + ;-
 + .byte $50 | 0
 +@Voc2loop:
 + .byte $50 | 0
 + .byte $50 | 0
 + .byte $20 | C5
 + .byte $40 | Dz4
 + .byte $40 | F4
 +
 + ;-
 + .byte $50 | 0
 + .byte $60 | D5
 + .byte $20 | Dz5
 + .byte $30 | Az4
 + .byte $20 | A4
 + .byte $30 | F4
 +
 + ;-
 + .byte $60 | G4
 + .byte $50 | 0
 + .byte $50 | 0
 + .byte $60 | C5
 +
 + ;-
 + .byte $50 | 0
 + .byte $60 | D5
 + .byte $60 | Dz5
 + .byte $60 | F5
 +
 + ;-
 + .byte $60 | G5
 + .byte JP
 + .byte <(@Voc2loop-@musicdata)
 +@Voc0komp:
 + .byte $10 | G5
 +
 + .byte $00 | D4
 + .byte $00 | Fz4
 + .byte $00 | A4
 + .byte $00 | Az4
 + .byte $00 | C5
 + .byte $10 | D5
 +
 + .byte $00 | Dz4
 + .byte $00 | F4
 + .byte $00 | G4
 + .byte $00 | Az4
 + .byte $00 | C5
 + .byte $10 | Dz5
 +
 + .byte $00 | F4
 + .byte $00 | A4
 + .byte $00 | C5
 + .byte $00 | D5
 + .byte $00 | Dz5
 + .byte $10 | F5
 +
 + .byte JP
 + .byte <(@Voc0start-@musicdata)
 +
 +@Voc1melody:
 + .byte $20 | C5
 + .byte $30 | Az4
 +
 + .byte $20 | A4
 + .byte $30 | F4
 +
 + ;-
 + .byte $60 | G4
 +
 + .byte $50 | 0
 +
 + .byte $20 | F4
 + .byte $30 | Dz4
 +
 + .byte $20 | F4
 + .byte $30 | Dz4
 +
 + ;-
 + .byte $20 | D4
 + .byte $30 | Dz4
 +
 + .byte $20 | D4
 + .byte $30 | Fz4
 +
 + .byte $20 | G4
 + .byte $30 | Dz4
 +
 + .byte $00 | C4
 + .byte $00 | Dz4
 + .byte $00 | F4
 + .byte $00 | G4
 + .byte $00 | A4
 + .byte $00 | C5
 + .byte $00 | G5
 + .byte $00 | F5
 +
 + .byte JP
 + .byte <(@Voc1start-@musicdata)
 +
 +;---------------------------------
 +;Note freq data
 +;
 +; Only using needed notes.
 +
 + JP =  0
 + C4 =  1
 + D4 =  2
 + Dz4 =  3
 + ;E4 =  2;Not used
 + F4 =  4
 + Fz4 =  5
 + G4 =  6
 + ;Gz4 =  6;Not used
 + A4 =  7
 + Az4 =  8
 + ;B4 =  8;Not used
 + C5 =  9
 + ;Cz5 =  9;Not used
 + D5 = 10
 + Dz5 = 11
 + ;E5 = 11;Not used
 + F5 = 12
 + ;Fz5 = 13;Not used
 + G5 = 13
 + ;Gz5 ;Not used
 + ;A5 ;Not used
 + ;Az5 = 14;Not used
 +
 +@freqlo = *-1 ;-1 to exclude the corresponding first byte (in @freqhi) used as a "wrap flag"
 + .byte $77
 + .byte $61,$e1
 + .byte $f7,$8f,$30
 + .byte $8f,$4e
 + .byte $ef
 + .byte $c3,$c3
 + .byte $ef
 + .byte $60
 +
 +@freqhi:
 + .byte $00 ;WRAP
 + .byte $07
 + .byte $08,$08
 + .byte $09,$0a,$0b
 + .byte $0c,$0d
 + .byte $0e
 + .byte $10,$11
 + .byte $13
 + .byte $16
 +
 +
 +</code>
base/256_bytes_tune_player.txt · Last modified: 2015-04-17 04:30 by 127.0.0.1