1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-06-03 07:29:37 +00:00
kickc/src/test/ref/bitmap-circle-standalone.asm
jespergravgaard ce28c50d34 updated tests
2023-05-19 11:06:44 +02:00

436 lines
7.2 KiB
NASM

// Plots a circle on a bitmap using Bresenham's Circle algorithm
// Coded by Richard-William Loerakker
// Original Source https://bcaorganizer.blogspot.com/p/c-program-for_21.html?fbclid=IwAR0iL8pYcCqhCPa6LmtQ9qej-YonYVepY2cBegYRIWO0l8RPeOnTVniMAac
// Commodore 64 PRG executable file
.file [name="bitmap-circle-standalone.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segment Basic
:BasicUpstart(main)
.const VICII_BMM = $20
.const VICII_DEN = $10
.const VICII_RSEL = 8
.const BLUE = 6
.label SCREEN = $400
.label BITMAP = $2000
.label D011 = $d011
.label VICII_MEMORY = $d018
.label BORDER_COLOR = $d020
.segment Code
main: {
// fill(BITMAP,40*25*8,0)
ldx #0
lda #<$28*$19*8
sta.z fill.size
lda #>$28*$19*8
sta.z fill.size+1
lda #<BITMAP
sta.z fill.addr
lda #>BITMAP
sta.z fill.addr+1
jsr fill
// fill(SCREEN,40*25,$16)
ldx #$16
lda #<$28*$19
sta.z fill.size
lda #>$28*$19
sta.z fill.size+1
lda #<SCREEN
sta.z fill.addr
lda #>SCREEN
sta.z fill.addr+1
jsr fill
// *BORDER_COLOR = BLUE
lda #BLUE
sta BORDER_COLOR
// *D011 = VICII_BMM|VICII_DEN|VICII_RSEL|3
lda #VICII_BMM|VICII_DEN|VICII_RSEL|3
sta D011
// *VICII_MEMORY = (byte)((((word)SCREEN&$3fff)/$40)|(((word)BITMAP&$3fff)/$400))
lda #(SCREEN&$3fff)/$40|(BITMAP&$3fff)/$400
sta VICII_MEMORY
// circle(100,100,50)
jsr circle
__b1:
jmp __b1
}
// Fill some memory with a value
// void fill(char *start, __zp($e) int size, __register(X) char val)
fill: {
.label end = $e
.label addr = $c
.label size = $e
// byte* end = start + size
clc
lda.z end
adc.z addr
sta.z end
lda.z end+1
adc.z addr+1
sta.z end+1
__b1:
// for(byte* addr = start; addr!=end; addr++)
lda.z addr+1
cmp.z end+1
bne __b2
lda.z addr
cmp.z end
bne __b2
// }
rts
__b2:
// *addr = val
txa
ldy #0
sta (addr),y
// for(byte* addr = start; addr!=end; addr++)
inc.z addr
bne !+
inc.z addr+1
!:
jmp __b1
}
// void circle(int xc, int yc, int r)
circle: {
.const xc = $64
.const yc = $64
.const r = $32
.label __5 = 8
.label __6 = 8
.label __7 = $a
.label __9 = 6
.label __10 = $a
.label p = $a
.label y = $c
.label x1 = $e
lda #<3-(r<<1)
sta.z p
lda #>3-(r<<1)
sta.z p+1
lda #<r
sta.z y
lda #>r
sta.z y+1
lda #<0
sta.z x1
sta.z x1+1
__b1:
// for(int x = 0; x <= y; x ++)
lda.z y
cmp.z x1
lda.z y+1
sbc.z x1+1
bvc !+
eor #$80
!:
bpl __b2
// }
rts
__b2:
// if(p < 0)
lda.z p+1
bpl !__b3+
jmp __b3
!__b3:
// y=y-1
sec
lda.z y
sbc #1
sta.z y
bcs !+
dec.z y+1
!:
// x-y
lda.z x1
sec
sbc.z y
sta.z __5
lda.z x1+1
sbc.z y+1
sta.z __5+1
// (x-y) << 2
asl.z __6
rol.z __6+1
asl.z __6
rol.z __6+1
// p + ((x-y) << 2)
clc
lda.z __7
adc.z __6
sta.z __7
lda.z __7+1
adc.z __6+1
sta.z __7+1
// p = p + ((x-y) << 2) + 10
lda.z p
clc
adc #<$a
sta.z p
lda.z p+1
adc #>$a
sta.z p+1
__b4:
// plot(xc+x,yc-y)
clc
lda.z x1
adc #<xc
sta.z plot.x
lda.z x1+1
adc #>xc
sta.z plot.x+1
lda #<yc
sec
sbc.z y
sta.z plot.y
lda #>yc
sbc.z y+1
sta.z plot.y+1
jsr plot
// plot(xc-x,yc-y)
lda #<xc
sec
sbc.z x1
sta.z plot.x
lda #>xc
sbc.z x1+1
sta.z plot.x+1
lda #<yc
sec
sbc.z y
sta.z plot.y
lda #>yc
sbc.z y+1
sta.z plot.y+1
jsr plot
// plot(xc+x,yc+y)
clc
lda.z x1
adc #<xc
sta.z plot.x
lda.z x1+1
adc #>xc
sta.z plot.x+1
clc
lda.z y
adc #<yc
sta.z plot.y
lda.z y+1
adc #>yc
sta.z plot.y+1
jsr plot
// plot(xc-x,yc+y)
lda #<xc
sec
sbc.z x1
sta.z plot.x
lda #>xc
sbc.z x1+1
sta.z plot.x+1
clc
lda.z y
adc #<yc
sta.z plot.y
lda.z y+1
adc #>yc
sta.z plot.y+1
jsr plot
// plot(xc+y,yc-x)
clc
lda.z y
adc #<xc
sta.z plot.x
lda.z y+1
adc #>xc
sta.z plot.x+1
lda #<yc
sec
sbc.z x1
sta.z plot.y
lda #>yc
sbc.z x1+1
sta.z plot.y+1
jsr plot
// plot(xc-y,yc-x)
lda #<xc
sec
sbc.z y
sta.z plot.x
lda #>xc
sbc.z y+1
sta.z plot.x+1
lda #<yc
sec
sbc.z x1
sta.z plot.y
lda #>yc
sbc.z x1+1
sta.z plot.y+1
jsr plot
// plot(xc+y,yc+x)
clc
lda.z y
adc #<xc
sta.z plot.x
lda.z y+1
adc #>xc
sta.z plot.x+1
clc
lda.z x1
adc #<yc
sta.z plot.y
lda.z x1+1
adc #>yc
sta.z plot.y+1
jsr plot
// plot(xc-y,yc+x)
lda #<xc
sec
sbc.z y
sta.z plot.x
lda #>xc
sbc.z y+1
sta.z plot.x+1
clc
lda.z x1
adc #<yc
sta.z plot.y
lda.z x1+1
adc #>yc
sta.z plot.y+1
jsr plot
// for(int x = 0; x <= y; x ++)
inc.z x1
bne !+
inc.z x1+1
!:
jmp __b1
__b3:
// x << 2
lda.z x1
asl
sta.z __9
lda.z x1+1
rol
sta.z __9+1
asl.z __9
rol.z __9+1
// p + (x << 2)
clc
lda.z __10
adc.z __9
sta.z __10
lda.z __10+1
adc.z __9+1
sta.z __10+1
// p = p + (x << 2) + 6
lda.z p
clc
adc #<6
sta.z p
lda.z p+1
adc #>6
sta.z p+1
jmp __b4
}
// void plot(__zp(8) int x, __zp(6) int y)
plot: {
.label __0 = 4
.label __2 = 6
.label __3 = 2
.label x = 8
.label y = 6
.label location = 4
.label __7 = 2
.label __8 = 2
// x & $fff8
lda.z x
and #<$fff8
sta.z __0
lda.z x+1
and #>$fff8
sta.z __0+1
// location += x & $fff8
lda #<BITMAP
clc
adc.z location
sta.z location
lda #>BITMAP
adc.z location+1
sta.z location+1
// (char)y & 7
lda.z y
and #7
// location += (char)y & 7
clc
adc.z location
sta.z location
bcc !+
inc.z location+1
!:
// y >> 3
lda.z __2+1
cmp #$80
ror.z __2+1
ror.z __2
lda.z __2+1
cmp #$80
ror.z __2+1
ror.z __2
lda.z __2+1
cmp #$80
ror.z __2+1
ror.z __2
// (y >> 3) * 320
lda.z __2
asl
sta.z __7
lda.z __2+1
rol
sta.z __7+1
asl.z __7
rol.z __7+1
clc
lda.z __8
adc.z __2
sta.z __8
lda.z __8+1
adc.z __2+1
sta.z __8+1
lda.z __3+1
sta.z $ff
lda.z __3
sta.z __3+1
lda #0
sta.z __3
lsr.z $ff
ror.z __3+1
ror.z __3
lsr.z $ff
ror.z __3+1
ror.z __3
// location += ((y >> 3) * 320)
clc
lda.z location
adc.z __3
sta.z location
lda.z location+1
adc.z __3+1
sta.z location+1
// x & 7
lda #7
and.z x
// (*location) | bitmask[x & 7]
tay
lda bitmask,y
ldy #0
ora (location),y
// (*location) = (*location) | bitmask[x & 7]
sta (location),y
// }
rts
}
.segment Data
bitmask: .byte $80, $40, $20, $10, 8, 4, 2, 1