incrementing only the lower 4 bits of a byte
LAX word
INX
AND #$F0
STA temp
TXA
AND #$0F
ORA temp
STA word
; or maybe
inc word
lax word
and #$0f
bne no
txa
sbx #$10
stx word
no:
; unsigned divide by 3
sta temp
lsr
lsr
clc
adc temp
ror
lsr
clc
adc temp
ror
lsr
clc
adc temp
ror
lsr
clc
adc temp
ror
lsr
It checks wether a point is within a rectangle (software collision detection!):
LDA rect.right
SBC point.x
BMI NoHit
SBC rect.width
BPL NoHit
LDA rect.top
SBC point.y
BMI NoHit
SBC rect.height
BPL NoHit
;BANG!
NoHit
Here's the software collision routine I worked up for Go Fish!
A little different - I use it to check if two boxes overlap. Call it once for X values, then call it again with Y values.
CheckBoundaries
lda rect1.leftortop
cmp rect2.leftortop
bmi Check2
cmp rect2.rightorbottom
bmi InsideBoundingBox
Check2
lda rect2.leftortop
cmp rect1.leftortop
bmi NotInsideBoundingBox
cmp rect1.rightorbottom
bpl NotInsideBoundingBox
InsideBoundingBox
sec
rts
NotInsideBoundingBox
clc
rts
What this does is set a number of random bits in a memory location. X is defined before calling this routine. Actually, it's not "killer" yet - I think this can be improved for cycles as well as space... but I'm at a loss for ideas... Anyone?
EDIT: oops, "bits" should be zero page, not immediate.
makemines
lda bits
sta TEMPVAR
loop JSR randomize; returns random value in accumulator
AND #7
TAY
LDA maskbit,y
ORA minefield-1,x; x is defined outside this routine
STA minefield-1,x
dec TEMPVAR
BPL loop
rts
maskbit
.byte %00000001
.byte %00000010
.byte %00000100
.byte %00001000
.byte %00010000
.byte %00100000
.byte %01000000
.byte %10000000
multiply
; x and a contain multiplicands, result in a
stx temp1
sta temp2
lda #0
rept
lsr temp2
bcc skip
clc
adc temp1
;bcs done might save cycles?
skip
;beq done might save cycles?
asl temp1
bne rept
done
divide
; x=numerator a=denominator, result in x
lsr
beq end;div by 0 = bad, div by 1=no calc needed, so bail out
rol;restore a
sta temp1
txa
ldx #$ff
sec
loop
sbc temp1
inx
bcs loop
end; result in x
Nothing particularly fancy, the code simply makes use of the fact that the NMOS 6502 does not set the zero flag bit when doing decimal adds or subtracts and the CMOS 6502 does. The result of this is that Zb is set only if the code is run on a CMOS 6502.
check if 65c02
SED ; set decimal mode
CLC ; clear carry for add
LDA #$99 ; actually 99 decimal in this case
ADC #$01 ; +1 gives 00 and sets Zb on 65C02
CLD ; exit decimal mode
LAX Index,y
AND #%00000111
STA AddressHi
LDA #%11111000
SAX AddressLo
LAX Index,y \ AND #%00000111
STA AddressHi \ LDA #%11111000
SAX AddressLo