dos33fsprogs/interlace_demo/pt3_lib_sample_ornament.s
2019-09-14 23:22:05 -04:00

168 lines
4.0 KiB
ArmAsm

;========================================================================
; EVERYTHING IS CYCLE COUNTED
;========================================================================
;===========================
; Load Ornament 0/Sample 1
;===========================
; these only called by init so in theory are not cycle critical
load_ornament0_sample1:
lda #0 ; 2
jsr load_ornament ; 6
load_sample1:
lda #1 ; 2
; fall through
;===========================
;===========================
; Load Sample
;===========================
;===========================
; cycles: 72 (NOTE SAMPLES MUST NOT CROSS PAGE BOUNDARY)
;===========================
;===========================
; sample in A
; which note offset in X
; Sample table pointers are 16-bits little endian
; There are 32 of these pointers starting at $6a:$69
; Our sample starts at address (A*2)+that pointer
; We point SAMPLE_H:SAMPLE_L to this
; then we load the length/data values
; and then leave SAMPLE_H:SAMPLE_L pointing to begnning of
; the sample data
load_sample:
sty PT3_TEMP ; 3
;pt3->ornament_patterns[i]=
; (pt3->data[0x6a+(i*2)]<<8)|pt3->data[0x69+(i*2)];
asl ; A*2 ; 2
tay ; 2
; Set the initial sample pointer
; a->sample_pointer=pt3->sample_patterns[a->sample];
lda PT3_LOC+PT3_SAMPLE_LOC_L,Y ; 4+
sta SAMPLE_L ; 3
lda PT3_LOC+PT3_SAMPLE_LOC_L+1,Y ; 4+
; assume pt3 file is at page boundary
adc #>PT3_LOC ; 2
sta SAMPLE_H ; 3
; Set the loop value
; a->sample_loop=pt3->data[a->sample_pointer];
ldy #0 ; 2
lda (SAMPLE_L),Y ; 5+
sta note_a+NOTE_SAMPLE_LOOP,X ; 4
; Set the length value
; a->sample_length=pt3->data[a->sample_pointer];
iny ; 2
lda (SAMPLE_L),Y ; 5+
sta note_a+NOTE_SAMPLE_LENGTH,X ; 4
; Set pointer to beginning of samples
lda SAMPLE_L ; 3
adc #$2 ; 2
sta note_a+NOTE_SAMPLE_POINTER_L,X ; 4
lda SAMPLE_H ; 3
adc #$0 ; 2
sta note_a+NOTE_SAMPLE_POINTER_H,X ; 4
ldy PT3_TEMP ; 3
rts ; 6
;============
; 72
;===========================
; Load Ornament
;===========================
;===========================
; cycles: 78 (NOTE SAMPLES MUST NOT CROSS PAGE BOUNDARY)
;===========================
;===========================
; ornament value in A
; note offset in X
; Ornament table pointers are 16-bits little endian
; There are 16 of these pointers starting at $aa:$a9
; Our ornament starts at address (A*2)+that pointer
; We point ORNAMENT_H:ORNAMENT_L to this
; then we load the length/data values
; and then leave ORNAMENT_H:ORNAMENT_L pointing to begnning of
; the ornament data
; Optimization:
; Loop and length only used once, can be located negative
; from the pointer, but 6502 doesn't make addressing like that
; easy. Can't self modify as channels A/B/C have own copies
; of the var.
load_ornament:
sty PT3_TEMP ; save Y value ; 3
;pt3->ornament_patterns[i]=
; (pt3->data[0xaa+(i*2)]<<8)|pt3->data[0xa9+(i*2)];
asl ; A*2 ; 2
tay ; 2
; a->ornament_pointer=pt3->ornament_patterns[a->ornament];
lda PT3_LOC+PT3_ORNAMENT_LOC_L,Y ; 4+
sta ORNAMENT_L ; 3
lda PT3_LOC+PT3_ORNAMENT_LOC_L+1,Y ; 4+
; we're assuming PT3 is loaded to a page boundary
adc #>PT3_LOC ; 2
sta ORNAMENT_H ; 3
lda #0 ; 2
sta note_a+NOTE_ORNAMENT_POSITION,X ; 4
tay ; 2
; Set the loop value
; a->ornament_loop=pt3->data[a->ornament_pointer];
lda (ORNAMENT_L),Y ; 5+
sta note_a+NOTE_ORNAMENT_LOOP,X ; 4
; Set the length value
; a->ornament_length=pt3->data[a->ornament_pointer];
iny ; 2
lda (ORNAMENT_L),Y ; 5+
sta note_a+NOTE_ORNAMENT_LENGTH,X ; 4
; Set the pointer to the value past the length
lda ORNAMENT_L ; 3
adc #$2 ; 2
sta note_a+NOTE_ORNAMENT_POINTER_L,X ; 4
lda ORNAMENT_H ; 3
adc #$0 ; 2
sta note_a+NOTE_ORNAMENT_POINTER_H,X ; 4
ldy PT3_TEMP ; restore Y value ; 3
rts ; 6
;============
; 78