; compile with MADS icl "includes.m65" ROWCRS equ $54 ;Row of cursor, 1 byte ;COLCRS equ $55 ;Column of cursor, 2 bytes OLDROW equ $5a OLDCOL equ $5b color equ $2fb ;Color for graphics operations ;drawpoint equ $f1ca ;f1d8 (if oldrow/col not needed) drawpoint equ $f1d8 drawline equ $f9af drawline_raw equ $f9c2 openmode equ $ef9c putchar equ $f1a4 org $2000 start ;############### init stuff mva #0 AUDCTL ; init POKEY mva #3 SKCTL lda #8 ; open gr.8 via illegal OS B opcode jsr openmode ldy #vbi lda #$07 jsr SETVBV ;####################### main loop fx ; do some funky fx stuff here ldx vbipos+1 ; "jump table" cpx #4 ;************ could be optimized by using another initial vbipos value and leveraging bmi,bpl,beq bcc part1 beq part2 bcs part4 part1 ; draw pseudo moire pattern stx COLOR2 ; x ranges from 0 to 3, so almost black (saves the lda #0 stuff) inc COLCRS bne weiter inc ROWCRS weiter lda $b0 adc ROWCRS sta $b0 lda $b1 adc COLCRS sta $b1 eor $b0 sta color jsr drawpoint bvc fx part2 ; scroll up upper and lower half of the screen ; lda SAVMSC+1 ; switch between the two banks (upper and lower half) and scroll each ; eor #$10 ; sta SAVMSC+1 jsr $f7f7 ; illegal OS B vector to scroll part of the screen up (within the 4k bank) jmp fx part4 lda #0 ; open GR.0 with black background jsr openmode part4start jsr $f9a6 ; illegal OS B vector to save SAVMSC in ADRESS ldx #24 stx ay part4y ldy #39 sty ax ; just use *any* constant value as init part4x txa adc vbipos ; inc x factor part4adc adc ax ; ora gives fullscreen scrolling black/white, eor gives fullscreen scrolling stripes, adc gives scrolling curve pattern sta ax part4eor sta ay ; eor with y factor and #128 ; use only inverse bit ora textdata,y ; or with SquoQuo text sta (ADRESS),y ; and save to screen dey ; next bpl part4x clc ; increase address by either 40 or 41 (see vbi) => chess board or diagonal board lda ADRESS part4adder adc #40 ; 40 gives standard chess board, other values give diagonally teared chessboards sta ADRESS bcc noinc inc ADRESS+1 noinc lda vbipos ; inc y factor adc ay sta ay dex ; next row bne part4y stx COLOR2 ; x is 0 now, so use this as the background color beq part4start ; repeat endlessly (bpl before fails, so bmi must jump) ax equ $a0 ay equ $a1 ;################### VBI mainly driving the audio vbi ; VBI is locate on page start, so we can use static init values for multiple initializations inc vbipos ; increase 16 bit counter (RTCLOK wouldn't do because of the unstable starting value) bne vbi_start inc vbipos+1 ; lda part4adder+1 ; eor #1 ; sta part4adder+1 ; inc part4adder+1 ; increase zoomer line offset to generate different patterns lda part4adc ; change the zoom-interference commands to change the patterns eor #$20 ; switch between adc and eor (curves vs scrolling stripes) sta part4adc cmp #$45 beq vbi_start ; only switch the other commands every second run lda part4eor eor #$c0 ; switch between eor and sta (replace for illegal DOP) sta part4eor bpl vbi_start ; only switch the last command every fouth run lda part4x eor #$12 ; switch between txa and tya (as pseudo constant init) sta part4x vbi_start ;#### audio part lda vbipos+1 ; easy pattern selection, only 4 variants are possible (valid values: 0,2,4,6) and #6 ; a bit pattern testing each channel separately would be better, but uses more memory tax audioloop ldy audioamp,x ; preload current amplitude lda vbipos and audiomask,x bne audiodec ; if trigger fires... ldy vbipos ; new frequency is only set if trigger fires lda audioramp+1,x ; get the rom page used for this channel sta audioromreader+1 lda (audioromreader),y ; grab some random ROM part ora #7 ; failsafe to avoid to high notes sta AUDF1,x ; and use as "note" ldy #25 ; set the amplitude to 25 (will be decremented afterwards anyway) audiodec tya ; get the current amplitude sbc audioramp,x ; falloff bpl audiodec_valid lda #0 ; clip to 0 audiodec_valid sta audioamp,x ; store amplitude ora audiomask+1,x ; or the sound mask sta AUDC1,x ; and fill the audc register dex ; next one (skip 2 since we're using this as an index to the AUDC1-4 registers dex bpl audioloop vbi_end .ifdef edit ;**************** keycode for adjusting the sound patterns lda KEY cmp #255 beq vbi_finish cmp keyold beq vbi_finish cmp #$8e bne key_not_up inc audioramp+1 key_not_up cmp #$8f bne vbi_finish dec audioramp+1 jmp vbi_finish keyold dta 255 vbi_finish sta keyold lda #255 sta KEY ;************* end of keycode .endif jmp RETURN vbipos equ $80 ; dword, should be 0 initially, will be 16bit frame counter audioamp equ $82 ; 8 bytes of zero initially audioromreader equ $8a audiomask dta $07,$80 ; each line corresponds to one audio channel dta $07,$80 ; first byte is the and mask for triggering dta $24,$a0 ; second byte is the ORed audio control (use lower 4 bits for constantly playing sound) dta $0f,$60 audioramp ; since value starts at 25 (due to size optimized routine, see above) falloff values below 3 lead to audibly delayed sounds dta $10,$30 ; each line corresponds to one audio channel dta $05,$f0 ; first byte is the falloff value (i.e. 0=constant, 1=longest tone, $10=click) dta $0e,$f0 ; second byte is the memory page used for frequencies dta $02,$e8 ;audiobit dta $00,$00,$01,$01,$02,$02,$04,$04 ;26 60 08 ee ;07 82 0a e8 relaxed nice rhythm ;26 a0 03 fb ;24 a0 03 f0 chords ;07 80 10 30 closed hihat ;0f 60 01 e8 bassline textdata dta d'SquoQuo' run start