;file: coldet.s ;collision detect ;sister file: cdvars.s (collision detect variables) ; ; precision version ; call with movs in x and y regs ; rts carry set if collision ; coldet: pushx pushy ; ; calc useful params ; lda movy,x ;xd = movy,x sta xd lda movht,x ;xu = (movht,x * 16) + xd asl asl asl asl clc adc xd sta xu lda movy,y ;yd = movy,y sta yd lda movht,y ;yu = (movht,y * 16) + yx asl asl asl asl clc adc yd sta yu lda movx,x ;xl = movx,x clc adc #($100 - SCWP)/2 sta xl lda movx,y ;yl = movx,y clc adc #($100 - SCWP)/2 sta yl lda movw,x ;xr = xl + (movw,x << 2) asl asl clc adc xl sta xr lda movw,y ;yr = yl + (movw,y << 2) asl asl clc adc yl sta yr ; ; find lesser of xu,yu store as lesserup ; lda xu cmp yu bcc .yuOVERxu ;xuOVERyu: lda yu jmp .break1 .yuOVERxu: lda xu .break1: sta lesserup ; ; switch on greater of (xd,yd) ; lda xd cmp yd bcc .ydOVERxd ; ; set high addresses and height of overlap ; ;xdOVERyd: lda movfrh,x ;xah = movfrh,x sta xah lda movfrh,y ;yah = movfrh,y + (xd - yd) clc adc xd sec sbc yd sta yah lda xd ;cdheight = xd - lesser(xu,yu) (2's comp) sec sbc lesserup sta cdheight jmp .break2 .ydOVERxd: lda movfrh,y ;yah = movfrh,y sta yah lda movfrh,x ;xah = movfrh,x + (yd - xd) clc adc yd sec sbc xd sta xah lda yd ;cdheight = yd - lesser(xu,yu) (2's comp) sec sbc lesserup sta cdheight .break2: ; ; 2`s comp of height and its carry are ready here ; if carry set, then no overlap, ret false ; bcc .lineoverlap jmp .exitfalse .lineoverlap: ; ; find lesser of xr,yr store as lesserright ; lda xr cmp yr bcc .yrOVERxr ;xrOVERyr: lda yr jmp .break3 .yrOVERxr: lda xr .break3: sta lesserright ; ; switch on greater of (xl,yl) ; lda xl cmp yl bcc .yprimary ; ; set low addresses and width of overlap ; ;xprimary: lda xah ;pah = xah sta pah lda yah ;sah = yah sta sah lda movfrl,x ;pal = movfrl,x sta pal lda xl ;pshift = (xl - yl) & %11 sec sbc yl sta i ;save this intermediate calc (xl - yl) and #%11 sta pshift eor #%11 ;sshift = ~pshift + 1 & %11 clc adc #1 sta sshift lda i ;sal = ((xl - yl) >> 2) + movfrl,y lsr lsr clc adc movfrl,y sta sal lda xl ;cdwidth = xl - lesser(xr,yr) (2's comp) sec sbc lesserright sta cdwidth jmp .break4 .yprimary: lda yah ;pah = yah sta pah lda xah ;sah = xah sta sah lda movfrl,y ;pal = movfrl,y sta pal lda yl ;pshift = (yl - xl) & %11 sec sbc xl sta i ;save this intermediate calc (yl - xl) and #%11 sta pshift eor #%11 ;sshift = ~pshift + 1 & %11 clc adc #1 sta sshift lda i ;sal = ((yl - xl) >> 2) + movfrl,x lsr lsr clc adc movfrl,x sta sal lda yl ;cdwidth = yl - lesser(yr,xr) (2's comp) sec sbc lesserright sta cdwidth .break4: ; ; 2`s comp of width and its carry are ready here ; carry set, then no overlap, rts false ; bcc .pixoverlap jmp .exitfalse .pixoverlap: ; ; x and y regs now used for new purposes ; ldy #0 ; ; save vars that will be clobbered in inner loop but needed again lda pal sta palsav lda sal sta salsav .lineloop: lda (sal),y ;get first secondary byte beq .skipc1 .if 0 jsr convbits .endif tax ;convert 2bits per pixel to 1 lda COLTAB,x .skipc1: inc sal ;point to next byte sta sbyte lda cdwidth ;init remaining width sta rwidth .pixloop: lda (pal),y ;get primary byte beq .skipc2 .if 0 jsr convbits ;convert 2bits per pixel to 1 .endif tax lda COLTAB,x .skipc2: inc pal ;point to next byte sta pbyte ldx pshift ;shift primary byte beq .donepshift .pshiftloop: lsr dex bne .pshiftloop .donepshift: and sbyte ;AND shifted primary with secondary bytes bne .exittrue lda rwidth ;update remaining width, exit inner if zero clc adc sshift sta rwidth beq .breakinner ; ; Get secondary byte, inc pointer, shift, AND with primary byte ; lda (sal),y beq .skipc3 .if 0 jsr convbits .endif tax ;convert 2 bits per pixel to 1 lda COLTAB,x .skipc3: inc sal sta sbyte ldx sshift ;shift secondary byte beq .donesshift .sshiftloop: lsr dex bne .sshiftloop .donesshift: and pbyte ;AND shifted secondary with primary bne .exittrue lda rwidth ;update remaining width, exit inner if zero clc adc pshift sta rwidth beq .breakinner jmp .pixloop .breakinner: ; ; if no remaining height, exit false ; inc cdheight beq .exitfalse ; ; restore clobbered vars, check next line ; lda palsav sta pal lda salsav sta sal inc pah ;inc address highs inc sah jmp .lineloop .exittrue: popy popx sec rts .exitfalse: popy popx clc rts ; ; convert bits ; compresses one byte of 2 bits per pixel to one bit per pixel ; input and output in accumulator ; clobbers x reg, i .if 0 convbits: tax lda COLTAB,x rts tax lda #0 sta i txa and #%11 beq .skip1 lda #1 sta i .skip1: txa and #%1100 beq .skip2 lda #%10 ora i sta i .skip2: txa and #%110000 beq .skip3 lda #%100 ora i sta i .skip3: txa and #%11000000 beq .skip4 lda #%1000 ora i sta i .skip4: lda i .endif rts ; ; set score to an absolute number, in A reg (octal readout) ; .if 0 setscore: sta i pushx pushy lda #0 sta score sta score+1 sta score+2 lda i asl asl asl asl and #%01110000 jsr incsc lda i asl and #%01110000 ora #1 jsr incsc lda i lsr lsr and #%01110000 ora #2 jsr incsc popy popx lda i rts .endif