2023-01-07 01:18:13 +00:00
|
|
|
; Our zero-page vars
|
2023-01-22 03:17:30 +00:00
|
|
|
sx = $80 ; i16: screen pixel x
|
|
|
|
sy = $82 ; i16: screen pixel y
|
2023-01-22 19:17:51 +00:00
|
|
|
ox = $84 ; fixed4.12: center point x
|
|
|
|
oy = $86 ; fixed4.12: center point y
|
2023-01-22 22:34:30 +00:00
|
|
|
cx = $88 ; fixed4.12: c_x
|
|
|
|
cy = $8a ; fixed4.12: c_y
|
|
|
|
zx = $8c ; fixed4.12: z_x
|
|
|
|
zy = $8e ; fixed4.12: z_y
|
2023-01-22 19:17:51 +00:00
|
|
|
|
2023-01-22 22:34:30 +00:00
|
|
|
zx_2 = $90 ; fixed4.12: z_x^2
|
|
|
|
zy_2 = $92 ; fixed4.12: z_y^2
|
|
|
|
zx_zy = $94 ; fixed4.12: z_x * z_y
|
|
|
|
dist = $96 ; fixed4.12: z_x^2 + z_y^2
|
2023-01-22 03:17:30 +00:00
|
|
|
|
2023-02-05 22:26:58 +00:00
|
|
|
iter = $a0 ; u8: iteration count
|
2023-01-30 02:50:04 +00:00
|
|
|
|
2023-02-05 22:26:58 +00:00
|
|
|
zoom = $a1 ; u8: zoom shift level
|
|
|
|
count_frames = $a2 ; u8
|
|
|
|
count_pixels = $a3 ; u8
|
|
|
|
total_ms = $a4 ; float48
|
|
|
|
total_pixels = $aa ; float48
|
|
|
|
|
|
|
|
temp = $b0 ; u16
|
2023-02-11 20:24:48 +00:00
|
|
|
temp2 = $b2 ; u16
|
|
|
|
pixel_ptr = $b4 ; u16
|
|
|
|
pixel_color = $b6 ; u8
|
|
|
|
pixel_mask = $b7 ; u8
|
|
|
|
pixel_shift = $b8 ; u8
|
|
|
|
pixel_offset = $b9 ; u8
|
2023-01-07 01:18:13 +00:00
|
|
|
|
2023-01-22 17:09:12 +00:00
|
|
|
|
2022-12-29 05:08:16 +00:00
|
|
|
; FP registers in zero page
|
2023-02-05 22:26:58 +00:00
|
|
|
FR0 = $d4 ; float48
|
|
|
|
FRE = $da
|
|
|
|
FR1 = $e0 ; float48
|
|
|
|
FR2 = $e6 ; float48
|
|
|
|
CIX = $f2 ; u8 - index into INBUFF
|
|
|
|
INBUFF = $f3 ; u16 - pointer to ascii
|
|
|
|
FLPTR = $fc ; u16 - pointer to user buffer float48
|
|
|
|
|
|
|
|
LBUFF = $0580 ; result buffer for FASC routine
|
|
|
|
|
|
|
|
; FP ROM routine vectors
|
|
|
|
FASC = $D8E6 ; FLOATING POINT TO ASCII (output in INBUFF, last char has high bit set)
|
|
|
|
IFP = $D9AA ; INTEGER TO FLOATING POINT CONVERSION (FR0:u16 -> FR0:float48)
|
|
|
|
FADD = $DA66 ; ADDITION (FR0 += FR1)
|
|
|
|
FSUB = $DA60 ; SUBTRACTION (FR0 -= FR1)
|
|
|
|
FMUL = $DADB ; MULTIPLICATION (FR0 *= FR1)
|
|
|
|
FDIV = $DB28 ; DIVISION (FR0 /= FR1)
|
|
|
|
ZF1 = $DA46 ; CLEAR ZERO PAGE FLOATING POINT NUMBER (XX)
|
|
|
|
FLD0R = $DD89 ; LOAD FR0 WITH FLOATING POINT NUMBER (YYXX)
|
|
|
|
FLD1R = $DD98 ; LOAD FR1 WITH FLOATING POINT NUMBER (YYXX)
|
|
|
|
FST0R = $DDA7 ; STORE FR0 IN USER BUFFER (YYXX)
|
|
|
|
FMOVE = $DDB6 ; MOVE FR0 TO FR1
|
2022-12-29 05:08:16 +00:00
|
|
|
|
2023-01-22 03:17:30 +00:00
|
|
|
; High data
|
2023-01-22 15:36:08 +00:00
|
|
|
framebuffer_top = $8000
|
|
|
|
textbuffer = $8f00
|
2023-01-22 03:17:30 +00:00
|
|
|
framebuffer_bottom = $9000
|
2023-01-22 15:36:08 +00:00
|
|
|
display_list = $9f00
|
|
|
|
framebuffer_end = $a000
|
2023-01-22 03:17:30 +00:00
|
|
|
|
|
|
|
height = 184
|
|
|
|
half_height = height >> 1
|
|
|
|
width = 160
|
2023-01-22 16:20:59 +00:00
|
|
|
half_width = width >> 1
|
|
|
|
stride = width >> 2
|
2023-01-22 03:17:30 +00:00
|
|
|
|
|
|
|
DMACTL = $D400
|
|
|
|
DLISTL = $D402
|
|
|
|
DLISTH = $D403
|
|
|
|
|
2023-01-22 13:54:50 +00:00
|
|
|
; OS shadow registers
|
|
|
|
SDLSTL = $230
|
|
|
|
SDLSTH = $231
|
|
|
|
|
2023-01-30 02:50:04 +00:00
|
|
|
; interrupt stuff
|
|
|
|
XITVBV = $E462
|
|
|
|
SETVBV = $E45C
|
|
|
|
|
2023-02-05 22:26:58 +00:00
|
|
|
.struct float48
|
|
|
|
exponent .byte
|
|
|
|
mantissa .byte 6
|
|
|
|
.endstruct
|
|
|
|
|
2023-02-11 20:24:48 +00:00
|
|
|
.import mul_lobyte256
|
|
|
|
.import mul_hibyte256
|
|
|
|
.import mul_hibyte512
|
|
|
|
|
2023-01-22 03:17:30 +00:00
|
|
|
.data
|
|
|
|
|
2023-01-22 14:12:40 +00:00
|
|
|
strings:
|
|
|
|
str_self:
|
2023-01-22 14:35:41 +00:00
|
|
|
.byte "MANDEL-6502"
|
|
|
|
str_self_end:
|
2023-01-22 14:12:40 +00:00
|
|
|
str_speed:
|
2023-01-22 14:35:41 +00:00
|
|
|
.byte "ms/px"
|
|
|
|
str_speed_end:
|
|
|
|
str_run:
|
2023-01-22 15:23:46 +00:00
|
|
|
.byte " RUN"
|
2023-01-22 14:35:41 +00:00
|
|
|
str_run_end:
|
2023-01-22 14:12:40 +00:00
|
|
|
str_done:
|
2023-01-22 14:35:41 +00:00
|
|
|
.byte "DONE"
|
|
|
|
str_done_end:
|
|
|
|
|
|
|
|
str_self_len = str_self_end - str_self
|
|
|
|
str_speed_len = str_speed_end - str_speed
|
|
|
|
str_run_len = str_run_end - str_run
|
|
|
|
str_done_len = str_done_end - str_done
|
|
|
|
|
2023-02-05 22:26:58 +00:00
|
|
|
speed_start = str_self_len + 2
|
|
|
|
speed_len = 14 + str_speed_len
|
|
|
|
|
|
|
|
|
2023-01-22 14:35:41 +00:00
|
|
|
char_map:
|
|
|
|
; Map ATASCII string values to framebuffer font entries
|
|
|
|
; Sighhhhh
|
|
|
|
.repeat 32, i
|
|
|
|
.byte i + 64
|
|
|
|
.endrepeat
|
|
|
|
.repeat 64, i
|
|
|
|
.byte i
|
|
|
|
.endrepeat
|
|
|
|
.repeat 32, i
|
|
|
|
.byte 96 + i
|
|
|
|
.endrepeat
|
2023-01-22 14:12:40 +00:00
|
|
|
|
2023-01-22 03:17:30 +00:00
|
|
|
aspect:
|
|
|
|
; aspect ratio!
|
|
|
|
; pixels at 320w are 5:6 (narrow)
|
|
|
|
; pixels at 160w are 5:3 (wide)
|
|
|
|
;
|
|
|
|
; cy = (sy << (8 - zoom)) * (96 / 128 = 3 / 4)
|
|
|
|
; cx = (sx << (8 - zoom)) * ((3 / 4) * (5 / 3) = 5 / 4)
|
|
|
|
;
|
|
|
|
; so vertical range -92 .. 91.9 is -2.15625 .. 2.15624
|
|
|
|
; &horizontal range -80 .. 79.9 is -3.125 .. 3.124
|
|
|
|
;
|
|
|
|
; 184h is the equiv of 220.8h at square pixels
|
|
|
|
; 320 / 220.8 = 1.45 display aspect ratio
|
2023-02-05 22:26:58 +00:00
|
|
|
aspect_x: ; fixed4.16 5/4
|
2023-01-22 19:17:51 +00:00
|
|
|
.word 5 << (12 - 2)
|
2023-01-22 03:17:30 +00:00
|
|
|
|
2023-02-05 22:26:58 +00:00
|
|
|
aspect_y: ; fixed4.16 3/4
|
2023-01-22 19:17:51 +00:00
|
|
|
.word 3 << (12 - 2)
|
2023-01-22 03:17:30 +00:00
|
|
|
|
2023-02-05 22:26:58 +00:00
|
|
|
ms_per_frame: ; float48 16.66666667
|
|
|
|
.byte 64 ; exponent/sign
|
|
|
|
.byte $16 ; BCD digits
|
|
|
|
.byte $66
|
|
|
|
.byte $66
|
|
|
|
.byte $66
|
|
|
|
.byte $67
|
2023-01-22 03:17:30 +00:00
|
|
|
|
2023-01-22 15:36:08 +00:00
|
|
|
display_list_start:
|
2023-01-22 17:09:12 +00:00
|
|
|
; 24 lines overscan
|
|
|
|
.repeat 3
|
2023-01-22 03:17:30 +00:00
|
|
|
.byte $70 ; 8 blank lines
|
|
|
|
.endrep
|
|
|
|
|
2023-01-22 13:54:50 +00:00
|
|
|
; 8 scan lines, 1 row of 40-column text
|
|
|
|
.byte $42
|
|
|
|
.addr textbuffer
|
|
|
|
|
2023-01-22 03:17:30 +00:00
|
|
|
; 184 lines graphics
|
|
|
|
; ANTIC mode e (160px 2bpp, 1 scan line per line)
|
|
|
|
.byte $4e
|
|
|
|
.addr framebuffer_top
|
|
|
|
.repeat half_height - 1
|
|
|
|
.byte $0e
|
|
|
|
.endrep
|
|
|
|
.byte $4e
|
|
|
|
.addr framebuffer_bottom
|
|
|
|
.repeat half_height - 1
|
|
|
|
.byte $0e
|
|
|
|
.endrep
|
|
|
|
|
|
|
|
.byte $41 ; jump and blank
|
|
|
|
.addr display_list
|
2023-01-22 15:36:08 +00:00
|
|
|
display_list_end:
|
|
|
|
display_list_len = display_list_end - display_list_start
|
2023-01-22 03:17:30 +00:00
|
|
|
|
2023-01-22 16:20:59 +00:00
|
|
|
color_map:
|
|
|
|
.byte 0
|
|
|
|
.repeat 85
|
|
|
|
.byte 1
|
|
|
|
.byte 2
|
|
|
|
.byte 3
|
|
|
|
.endrepeat
|
|
|
|
|
2022-12-29 05:08:16 +00:00
|
|
|
.code
|
|
|
|
|
|
|
|
.export start
|
|
|
|
|
2023-01-07 01:18:13 +00:00
|
|
|
; 2 + 9 * byte cycles
|
|
|
|
.macro add bytes, dest, arg1, arg2
|
|
|
|
clc ; 2 cyc
|
|
|
|
.repeat bytes, byte ; 9 * byte cycles
|
|
|
|
lda arg1 + byte
|
|
|
|
adc arg2 + byte
|
|
|
|
sta dest + byte
|
|
|
|
.endrepeat
|
|
|
|
.endmacro
|
|
|
|
|
|
|
|
.macro add16 dest, arg1, arg2
|
|
|
|
add 2, dest, arg1, arg2
|
|
|
|
.endmacro
|
|
|
|
|
|
|
|
.macro add32 dest, arg1, arg2
|
2023-01-22 18:42:37 +00:00
|
|
|
add 4, dest, arg2, dest
|
2023-01-07 01:18:13 +00:00
|
|
|
.endmacro
|
|
|
|
|
2023-02-11 20:24:48 +00:00
|
|
|
.macro add_carry dest
|
|
|
|
lda dest
|
|
|
|
adc #0
|
|
|
|
sta dest
|
|
|
|
.endmacro
|
|
|
|
|
2023-01-07 01:18:13 +00:00
|
|
|
; 2 + 9 * byte cycles
|
|
|
|
.macro sub bytes, dest, arg1, arg2
|
|
|
|
sec ; 2 cyc
|
|
|
|
.repeat bytes, byte ; 9 * byte cycles
|
|
|
|
lda arg1 + byte
|
|
|
|
sbc arg2 + byte
|
|
|
|
sta dest + byte
|
|
|
|
.endrepeat
|
|
|
|
.endmacro
|
|
|
|
|
|
|
|
.macro sub16 dest, arg1, arg2
|
|
|
|
sub 2, dest, arg1, arg2
|
|
|
|
.endmacro
|
|
|
|
|
|
|
|
.macro sub32 dest, arg1, arg2
|
|
|
|
sub 4, dest, arg1, arg2
|
|
|
|
.endmacro
|
|
|
|
|
|
|
|
.macro shl bytes, arg
|
|
|
|
asl arg
|
2023-01-22 17:09:12 +00:00
|
|
|
.repeat bytes-1, i
|
|
|
|
rol arg + 1 + i
|
2023-01-07 01:18:13 +00:00
|
|
|
.endrepeat
|
|
|
|
.endmacro
|
|
|
|
|
|
|
|
.macro shl16 arg
|
|
|
|
shl 2, arg
|
|
|
|
.endmacro
|
|
|
|
|
|
|
|
.macro shl24 arg
|
|
|
|
shl 3, arg
|
|
|
|
.endmacro
|
|
|
|
|
|
|
|
.macro shl32 arg
|
|
|
|
shl 4, arg
|
|
|
|
.endmacro
|
|
|
|
|
|
|
|
; 6 * bytes cycles
|
|
|
|
.macro copy bytes, dest, arg
|
|
|
|
.repeat bytes, byte ; 6 * bytes cycles
|
|
|
|
lda arg + byte ; 3 cyc
|
|
|
|
sta dest + byte ; 3 cyc
|
|
|
|
.endrepeat
|
|
|
|
.endmacro
|
|
|
|
|
|
|
|
.macro copy16 dest, arg
|
|
|
|
copy 2, dest, arg
|
|
|
|
.endmacro
|
|
|
|
|
|
|
|
.macro copy32 dest, arg
|
|
|
|
copy 4, dest, arg
|
|
|
|
.endmacro
|
|
|
|
|
2023-01-30 02:50:04 +00:00
|
|
|
.macro copyfloat dest, arg
|
|
|
|
copy 6, dest, arg
|
|
|
|
.endmacro
|
|
|
|
|
2022-12-30 08:43:44 +00:00
|
|
|
; 2 + 8 * byte cycles
|
|
|
|
.macro neg bytes, arg
|
|
|
|
sec ; 2 cyc
|
|
|
|
.repeat bytes, byte ; 8 * byte cycles
|
|
|
|
lda #00 ; 2 cyc
|
|
|
|
sbc arg + byte ; 3 cyc
|
|
|
|
sta arg + byte ; 3 cyc
|
|
|
|
.endrepeat
|
|
|
|
.endmacro
|
|
|
|
|
|
|
|
; 18 cycles
|
|
|
|
.macro neg16 arg
|
|
|
|
neg 2, arg
|
|
|
|
.endmacro
|
|
|
|
|
|
|
|
; 34 cycles
|
|
|
|
.macro neg32 arg
|
|
|
|
neg 4, arg
|
|
|
|
.endmacro
|
|
|
|
|
2022-12-31 02:25:43 +00:00
|
|
|
; inner loop for imul16
|
2023-01-05 04:21:51 +00:00
|
|
|
; bitnum < 8: 25 or 41 cycles
|
|
|
|
; bitnum >= 8: 30 or 46 cycles
|
2022-12-30 04:18:21 +00:00
|
|
|
.macro bitmul16 arg1, arg2, result, bitnum
|
2023-01-05 03:52:56 +00:00
|
|
|
.local zero
|
2023-01-05 04:12:34 +00:00
|
|
|
.local one
|
|
|
|
.local next
|
2022-12-29 11:37:51 +00:00
|
|
|
|
2022-12-30 08:43:44 +00:00
|
|
|
; does 16-bit adds
|
2023-01-05 05:09:45 +00:00
|
|
|
; arg1 and arg2 are treated as unsigned
|
|
|
|
; negative signed inputs must be flipped first
|
2022-12-30 08:43:44 +00:00
|
|
|
|
2023-01-05 04:12:34 +00:00
|
|
|
; 7 cycles up to the branch
|
2022-12-30 04:18:21 +00:00
|
|
|
|
|
|
|
; check if arg1 has 0 or 1 bit in this place
|
2022-12-31 01:33:18 +00:00
|
|
|
; 5 cycles either way
|
2022-12-30 04:18:21 +00:00
|
|
|
.if bitnum < 8
|
2022-12-31 01:33:18 +00:00
|
|
|
lda arg1 ; 3 cyc
|
2023-01-22 20:02:15 +00:00
|
|
|
and #(1 << (bitnum)) ; 2 cyc
|
2022-12-30 04:18:21 +00:00
|
|
|
.else
|
2022-12-31 01:33:18 +00:00
|
|
|
lda arg1 + 1 ; 3 cyc
|
2023-01-22 20:02:15 +00:00
|
|
|
and #(1 << ((bitnum) - 8)) ; 2 cyc
|
2022-12-30 04:18:21 +00:00
|
|
|
.endif
|
2023-01-05 04:12:34 +00:00
|
|
|
bne one ; 2 cyc
|
|
|
|
|
2023-01-05 04:21:51 +00:00
|
|
|
zero: ; 18 cyc, 23 cyc
|
2023-01-05 04:12:34 +00:00
|
|
|
lsr result + 3 ; 5 cyc
|
|
|
|
jmp next ; 3 cyc
|
2022-12-29 11:37:51 +00:00
|
|
|
|
2023-01-05 04:21:51 +00:00
|
|
|
one: ; 32 cyc, 37 cyc
|
2022-12-29 11:37:51 +00:00
|
|
|
; 16-bit add on the top bits
|
2023-01-05 04:12:34 +00:00
|
|
|
clc ; 2 cyc
|
2022-12-31 02:21:31 +00:00
|
|
|
lda result + 2 ; 3 cyc
|
|
|
|
adc arg2 ; 3 cyc
|
|
|
|
sta result + 2 ; 3 cyc
|
|
|
|
lda result + 3 ; 3 cyc
|
|
|
|
adc arg2 + 1 ; 3 cyc
|
2023-01-05 05:09:45 +00:00
|
|
|
ror a ; 2 cyc - get a jump on the shift
|
2022-12-31 02:21:31 +00:00
|
|
|
sta result + 3 ; 3 cyc
|
2023-01-05 04:33:42 +00:00
|
|
|
next:
|
2022-12-31 01:33:18 +00:00
|
|
|
ror result + 2 ; 5 cyc
|
|
|
|
ror result + 1 ; 5 cyc
|
2022-12-30 04:18:21 +00:00
|
|
|
.if bitnum >= 8
|
2023-01-05 04:21:51 +00:00
|
|
|
; we can save 5 cycles * 8 bits = 40 cycles total by skipping this byte
|
|
|
|
; when it's all uninitialized data
|
2022-12-31 01:33:18 +00:00
|
|
|
ror result ; 5 cyc
|
2022-12-30 04:18:21 +00:00
|
|
|
.endif
|
2023-01-05 04:21:51 +00:00
|
|
|
|
2022-12-29 05:08:16 +00:00
|
|
|
.endmacro
|
|
|
|
|
2022-12-31 01:33:18 +00:00
|
|
|
; 5 to 25 cycles
|
2022-12-30 08:43:44 +00:00
|
|
|
.macro check_sign arg
|
|
|
|
; Check sign bit and flip argument to postive,
|
2023-02-11 20:24:48 +00:00
|
|
|
; keeping a count of sign bits in the Y register.
|
2022-12-30 08:43:44 +00:00
|
|
|
.local positive
|
2022-12-31 01:33:18 +00:00
|
|
|
lda arg + 1 ; 3 cyc
|
|
|
|
bpl positive ; 2 cyc
|
|
|
|
neg16 arg ; 18 cyc
|
2023-02-11 20:24:48 +00:00
|
|
|
iny ; 2 cyc
|
2022-12-30 08:43:44 +00:00
|
|
|
positive:
|
|
|
|
.endmacro
|
2022-12-29 05:08:16 +00:00
|
|
|
|
2023-01-07 01:18:13 +00:00
|
|
|
; 518 - 828 cyc
|
|
|
|
.macro imul16 dest, arg1, arg2
|
|
|
|
copy16 FR0, arg1 ; 12 cyc
|
|
|
|
copy16 FR1, arg2 ; 12 cyc
|
2023-01-22 03:17:30 +00:00
|
|
|
jsr imul16_func ; 470-780 cyc
|
2023-01-07 01:18:13 +00:00
|
|
|
copy32 dest, FR2 ; 24 cyc
|
|
|
|
.endmacro
|
|
|
|
|
2023-01-22 19:17:51 +00:00
|
|
|
.macro shift_round_16 arg, shift
|
|
|
|
.repeat shift
|
|
|
|
shl32 arg
|
|
|
|
.endrepeat
|
|
|
|
round16 arg
|
|
|
|
.endmacro
|
|
|
|
|
|
|
|
.macro imul16_round dest, arg1, arg2, shift
|
2023-01-22 03:17:30 +00:00
|
|
|
copy16 FR0, arg1 ; 12 cyc
|
|
|
|
copy16 FR1, arg2 ; 12 cyc
|
|
|
|
jsr imul16_func ; 470-780 cyc
|
2023-01-22 19:17:51 +00:00
|
|
|
shift_round_16 FR2, shift
|
2023-01-22 03:17:30 +00:00
|
|
|
copy16 dest, FR2 + 2 ; 12 cyc
|
|
|
|
.endmacro
|
|
|
|
|
2023-01-05 04:37:16 +00:00
|
|
|
; min 470 cycles
|
|
|
|
; max 780 cycles
|
2023-02-11 20:24:48 +00:00
|
|
|
.proc imul16_func_orig
|
2022-12-30 08:43:44 +00:00
|
|
|
arg1 = FR0 ; 16-bit arg (clobbered)
|
|
|
|
arg2 = FR1 ; 16-bit arg (clobbered)
|
|
|
|
result = FR2 ; 32-bit result
|
|
|
|
|
2023-02-11 20:24:48 +00:00
|
|
|
ldy #0 ; 2 cyc
|
|
|
|
; counts the number of sign bits in Y
|
2022-12-31 01:33:18 +00:00
|
|
|
check_sign arg1 ; 5 to 25 cyc
|
|
|
|
check_sign arg2 ; 5 to 25 cyc
|
2022-12-30 08:43:44 +00:00
|
|
|
|
2022-12-30 04:18:21 +00:00
|
|
|
; zero out the 32-bit temp's top 16 bits
|
2022-12-31 01:33:18 +00:00
|
|
|
lda #0 ; 2 cyc
|
|
|
|
sta result + 2 ; 3 cyc
|
|
|
|
sta result + 3 ; 3 cyc
|
2022-12-29 11:37:51 +00:00
|
|
|
; the bottom two bytes will get cleared by the shifts
|
2022-12-29 05:08:16 +00:00
|
|
|
|
2022-12-30 08:43:44 +00:00
|
|
|
; unrolled loop for maximum speed, at the cost
|
|
|
|
; of a larger routine
|
2023-01-05 04:37:16 +00:00
|
|
|
; 440 to 696 cycles
|
2022-12-29 05:08:16 +00:00
|
|
|
.repeat 16, bitnum
|
2023-01-05 04:37:16 +00:00
|
|
|
; bitnum < 8: 25 or 41 cycles
|
|
|
|
; bitnum >= 8: 30 or 46 cycles
|
2022-12-30 08:43:44 +00:00
|
|
|
bitmul16 arg1, arg2, result, bitnum
|
2022-12-29 05:08:16 +00:00
|
|
|
.endrepeat
|
2022-12-30 04:18:21 +00:00
|
|
|
|
2022-12-30 08:43:44 +00:00
|
|
|
; In case of mixed input signs, return a negative result.
|
2023-02-11 20:24:48 +00:00
|
|
|
cpy #1 ; 2 cyc
|
|
|
|
bne positive_result ; 2 cyc
|
|
|
|
neg32 result ; 34 cyc
|
|
|
|
positive_result:
|
|
|
|
|
|
|
|
rts ; 6 cyc
|
|
|
|
.endproc
|
|
|
|
|
|
|
|
; Adapted from https://everything2.com/title/Fast+6502+multiplication
|
|
|
|
.macro imul8 dest, arg1, arg2
|
|
|
|
.local under256
|
|
|
|
.local next
|
|
|
|
.local small_product
|
|
|
|
.scope
|
|
|
|
mul_factor_a = arg1
|
|
|
|
mul_factor_x = arg2
|
|
|
|
mul_product_lo = dest
|
|
|
|
mul_product_hi = dest + 1
|
|
|
|
|
|
|
|
lda mul_factor_a ; setup: 6 cycles
|
|
|
|
;ldx mul_factor_x
|
|
|
|
|
|
|
|
clc ; (a + x)^2/2: 23 cycles
|
|
|
|
adc mul_factor_x
|
|
|
|
tax
|
|
|
|
bcc under256
|
|
|
|
lda mul_hibyte512,x
|
|
|
|
bcs next
|
|
|
|
under256:
|
|
|
|
lda mul_hibyte256,x
|
|
|
|
sec
|
|
|
|
next:
|
|
|
|
sta mul_product_hi
|
|
|
|
lda mul_lobyte256,x
|
|
|
|
|
|
|
|
ldx mul_factor_a ; - a^2/2: 20 cycles
|
|
|
|
sbc mul_lobyte256,x
|
|
|
|
sta mul_product_lo
|
|
|
|
lda mul_product_hi
|
|
|
|
sbc mul_hibyte256,x
|
|
|
|
sta mul_product_hi
|
|
|
|
|
|
|
|
ldx mul_factor_x ; + x & a & 1: 22 cycles
|
|
|
|
txa ; (this is a kludge to correct a
|
|
|
|
and mul_factor_a ; roundoff error that makes odd * odd too low)
|
|
|
|
and #1
|
|
|
|
|
|
|
|
clc
|
|
|
|
adc mul_product_lo
|
|
|
|
bcc small_product
|
|
|
|
inc mul_product_hi
|
|
|
|
small_product:
|
|
|
|
sec ; - x^2/2: 25 cycles
|
|
|
|
sbc mul_lobyte256,x
|
|
|
|
lda mul_product_hi
|
|
|
|
sbc mul_hibyte256,x
|
|
|
|
sta mul_product_hi
|
|
|
|
.endscope
|
|
|
|
.endmacro
|
|
|
|
|
|
|
|
.proc imul16_func
|
|
|
|
arg1 = FR0 ; 16-bit arg (clobbered)
|
|
|
|
arg2 = FR1 ; 16-bit arg (clobbered)
|
|
|
|
result = FR2 ; 32-bit result
|
|
|
|
inter = temp2
|
|
|
|
|
|
|
|
ldy #0 ; 2 cyc
|
|
|
|
; counts the number of sign bits in Y
|
|
|
|
check_sign arg1 ; 5 to 25 cyc
|
|
|
|
check_sign arg2 ; 5 to 25 cyc
|
|
|
|
|
|
|
|
lda #0
|
|
|
|
sta result + 0
|
|
|
|
sta result + 1
|
|
|
|
sta result + 2
|
|
|
|
sta result + 3
|
|
|
|
|
|
|
|
imul8 inter, arg1, arg2
|
|
|
|
add16 result, result, inter
|
|
|
|
|
|
|
|
imul8 inter, arg1 + 1, arg2
|
|
|
|
add16 result + 1, result + 1, inter
|
|
|
|
|
|
|
|
imul8 inter, arg1, arg2 + 1
|
|
|
|
add16 result + 1, result + 1, inter
|
|
|
|
add_carry result + 3
|
|
|
|
|
|
|
|
imul8 inter, arg1 + 1, arg2 + 1
|
|
|
|
add16 result + 2, result + 2, inter
|
|
|
|
|
|
|
|
; In case of mixed input signs, return a negative result.
|
|
|
|
cpy #1 ; 2 cyc
|
2022-12-31 01:33:18 +00:00
|
|
|
bne positive_result ; 2 cyc
|
|
|
|
neg32 result ; 34 cyc
|
2022-12-30 08:43:44 +00:00
|
|
|
positive_result:
|
|
|
|
|
2022-12-31 01:33:18 +00:00
|
|
|
rts ; 6 cyc
|
2022-12-29 05:08:16 +00:00
|
|
|
.endproc
|
|
|
|
|
2023-01-07 01:18:13 +00:00
|
|
|
.macro round16 arg
|
2023-01-05 17:06:07 +00:00
|
|
|
; Round top 16 bits of 32-bit fixed-point number in-place
|
2023-01-29 00:31:55 +00:00
|
|
|
.local increment
|
|
|
|
.local high_half
|
|
|
|
.local check_sign
|
2023-01-05 17:06:07 +00:00
|
|
|
.local next
|
|
|
|
|
2023-01-29 00:31:55 +00:00
|
|
|
; low word > $8000: round up
|
|
|
|
; = $8000: round up if positive
|
|
|
|
; round down if negative
|
|
|
|
; < $8000: round down
|
2023-01-28 22:34:52 +00:00
|
|
|
|
2023-01-29 00:31:55 +00:00
|
|
|
lda arg + 1
|
|
|
|
cmp #$80
|
|
|
|
beq high_half
|
|
|
|
bpl increment
|
|
|
|
bmi next
|
2023-01-05 17:06:07 +00:00
|
|
|
|
2023-01-29 00:31:55 +00:00
|
|
|
high_half:
|
|
|
|
lda arg
|
|
|
|
beq check_sign
|
|
|
|
bpl increment
|
|
|
|
bmi next
|
2023-01-05 17:06:07 +00:00
|
|
|
|
2023-01-29 00:31:55 +00:00
|
|
|
check_sign:
|
|
|
|
lda arg + 3
|
|
|
|
bmi next
|
2023-01-28 20:07:42 +00:00
|
|
|
|
2023-01-29 00:31:55 +00:00
|
|
|
increment: ; 5-10 cyc
|
2023-01-05 17:06:07 +00:00
|
|
|
inc arg + 2 ; 5 cyc
|
2023-01-22 20:57:52 +00:00
|
|
|
bne next ; 2 cyc
|
2023-01-05 17:06:07 +00:00
|
|
|
inc arg + 3 ; 5 cyc
|
|
|
|
|
|
|
|
next:
|
|
|
|
|
|
|
|
.endmacro
|
|
|
|
|
2023-01-07 01:18:13 +00:00
|
|
|
.proc mandelbrot
|
|
|
|
; input:
|
|
|
|
; cx: position scaled to 4.12 fixed point - -8..+7.9
|
|
|
|
; cy: position scaled to 4.12
|
|
|
|
;
|
|
|
|
; output:
|
|
|
|
; iter: iteration count at escape or 0
|
2023-01-05 19:32:15 +00:00
|
|
|
|
2022-12-29 05:08:16 +00:00
|
|
|
; zx = 0
|
|
|
|
; zy = 0
|
|
|
|
; zx_2 = 0
|
2022-12-30 08:55:48 +00:00
|
|
|
; zy_2 = 0
|
|
|
|
; zx_zy = 0
|
2023-01-07 01:18:13 +00:00
|
|
|
; dist = 0
|
|
|
|
; iter = 0
|
|
|
|
lda #00
|
2023-01-22 17:34:42 +00:00
|
|
|
ldx #(iter - zx + 1)
|
2023-01-07 01:18:13 +00:00
|
|
|
initloop:
|
2023-01-22 17:34:42 +00:00
|
|
|
sta zx - 1,x
|
2023-01-07 01:18:13 +00:00
|
|
|
dex
|
|
|
|
bne initloop
|
2022-12-29 05:08:16 +00:00
|
|
|
|
|
|
|
loop:
|
2023-01-22 18:42:37 +00:00
|
|
|
; iter++ & max-iters break
|
|
|
|
inc iter
|
|
|
|
bne keep_going
|
2023-01-07 01:18:13 +00:00
|
|
|
rts
|
|
|
|
keep_going:
|
2022-12-29 05:08:16 +00:00
|
|
|
|
2023-01-22 21:56:19 +00:00
|
|
|
.macro quick_exit arg, max
|
2023-01-28 20:07:42 +00:00
|
|
|
.local positive
|
|
|
|
.local negative
|
|
|
|
.local nope_out
|
|
|
|
.local first_equal
|
|
|
|
.local all_done
|
|
|
|
|
|
|
|
; check sign bit
|
2023-01-22 20:02:15 +00:00
|
|
|
lda arg + 1
|
2023-01-28 20:07:42 +00:00
|
|
|
bmi negative
|
|
|
|
|
|
|
|
positive:
|
2023-01-22 21:56:19 +00:00
|
|
|
cmp #((max) << 4)
|
2023-01-28 20:07:42 +00:00
|
|
|
bmi all_done ; 'less than'
|
2023-01-22 20:02:15 +00:00
|
|
|
rts
|
2023-01-28 20:07:42 +00:00
|
|
|
|
|
|
|
negative:
|
2023-01-22 21:56:19 +00:00
|
|
|
cmp #(256 - ((max) << 4))
|
2023-01-28 20:07:42 +00:00
|
|
|
beq first_equal ; 'equal' on first byte
|
|
|
|
bpl all_done ; 'greater than'
|
|
|
|
|
|
|
|
nope_out:
|
2023-01-22 20:47:24 +00:00
|
|
|
rts
|
2023-01-28 20:07:42 +00:00
|
|
|
|
|
|
|
first_equal:
|
|
|
|
lda arg
|
|
|
|
beq nope_out ; 2nd byte 0 shows it's really 'equal'
|
|
|
|
|
|
|
|
all_done:
|
2023-01-22 20:02:15 +00:00
|
|
|
.endmacro
|
|
|
|
|
2023-01-05 19:32:15 +00:00
|
|
|
; 4.12: (-8 .. +7.9)
|
2023-01-22 18:42:37 +00:00
|
|
|
; zx = zx_2 - zy_2 + cx
|
2023-01-22 20:02:15 +00:00
|
|
|
sub16 zx, zx_2, zy_2
|
2023-01-07 01:18:13 +00:00
|
|
|
add16 zx, zx, cx
|
2023-01-22 21:56:19 +00:00
|
|
|
quick_exit zx, 2
|
2023-01-07 01:18:13 +00:00
|
|
|
|
2023-01-22 18:42:37 +00:00
|
|
|
; zy = zx_zy + zx_zy + cy
|
2023-01-22 20:02:15 +00:00
|
|
|
add16 zy, zx_zy, zx_zy
|
2023-01-07 01:18:13 +00:00
|
|
|
add16 zy, zy, cy
|
2023-01-22 21:56:19 +00:00
|
|
|
quick_exit zy, 2
|
2022-12-29 05:08:16 +00:00
|
|
|
|
2023-01-22 18:42:37 +00:00
|
|
|
; zx_2 = zx * zx
|
2023-01-22 20:02:15 +00:00
|
|
|
imul16_round zx_2, zx, zx, 4
|
2023-01-07 01:18:13 +00:00
|
|
|
|
2023-01-22 18:42:37 +00:00
|
|
|
; zy_2 = zy * zy
|
2023-01-22 20:02:15 +00:00
|
|
|
imul16_round zy_2, zy, zy, 4
|
2023-01-07 01:18:13 +00:00
|
|
|
|
2023-01-22 18:42:37 +00:00
|
|
|
; zx_zy = zx * zy
|
2023-01-22 20:02:15 +00:00
|
|
|
imul16_round zx_zy, zx, zy, 4
|
2023-01-07 01:18:13 +00:00
|
|
|
|
2023-01-22 18:42:37 +00:00
|
|
|
; dist = zx_2 + zy_2
|
2023-01-22 20:02:15 +00:00
|
|
|
add16 dist, zx_2, zy_2
|
2023-01-22 21:56:19 +00:00
|
|
|
quick_exit dist, 4
|
2022-12-30 08:55:48 +00:00
|
|
|
|
|
|
|
; if may be in the lake, look for looping output with a small buffer
|
|
|
|
; as an optimization vs running to max iters
|
2023-01-22 18:42:37 +00:00
|
|
|
jmp loop
|
2022-12-30 08:55:48 +00:00
|
|
|
|
2023-01-22 20:02:15 +00:00
|
|
|
peace_out:
|
|
|
|
rts
|
|
|
|
|
2022-12-29 05:08:16 +00:00
|
|
|
.endproc
|
2022-12-30 04:32:58 +00:00
|
|
|
|
2023-01-22 03:17:30 +00:00
|
|
|
.macro zoom_factor dest, src, zoom, aspect
|
|
|
|
.local cont
|
|
|
|
.local enough
|
|
|
|
|
|
|
|
; cx = (sx << (8 - zoom))
|
|
|
|
copy16 dest, src
|
|
|
|
ldx zoom
|
|
|
|
cont:
|
|
|
|
cpx #8
|
|
|
|
beq enough
|
|
|
|
shl16 dest
|
|
|
|
inx
|
|
|
|
jmp cont
|
|
|
|
enough:
|
|
|
|
|
|
|
|
; cy = cy * (3 / 4)
|
|
|
|
; cx = cx * (5 / 4)
|
2023-01-22 19:17:51 +00:00
|
|
|
imul16_round dest, dest, aspect, 4
|
2023-01-22 03:17:30 +00:00
|
|
|
.endmacro
|
|
|
|
|
|
|
|
.proc pset
|
|
|
|
; screen coords in signed sx,sy
|
|
|
|
; iter holds the target to use
|
|
|
|
; @todo implement
|
2023-01-22 16:20:59 +00:00
|
|
|
|
|
|
|
; iter -> color
|
|
|
|
ldx iter
|
|
|
|
lda color_map,x
|
|
|
|
sta pixel_color
|
|
|
|
lda #(255 - 3)
|
|
|
|
sta pixel_mask
|
|
|
|
|
|
|
|
; sy -> line base address in temp
|
|
|
|
lda sy
|
|
|
|
bpl positive
|
|
|
|
|
|
|
|
negative:
|
|
|
|
; temp1 = top half
|
|
|
|
lda #.lobyte(framebuffer_top + stride * half_height)
|
|
|
|
sta pixel_ptr
|
|
|
|
lda #.hibyte(framebuffer_top + stride * half_height)
|
|
|
|
sta pixel_ptr + 1
|
|
|
|
jmp point
|
|
|
|
|
|
|
|
positive:
|
|
|
|
|
|
|
|
lda #.lobyte(framebuffer_bottom)
|
|
|
|
sta pixel_ptr
|
|
|
|
lda #.hibyte(framebuffer_bottom)
|
|
|
|
sta pixel_ptr + 1
|
|
|
|
|
|
|
|
point:
|
|
|
|
|
|
|
|
; pixel_ptr += sy * stride
|
|
|
|
; temp * 40
|
|
|
|
; = temp * 32 + temp * 8
|
|
|
|
; = (temp << 5) + (temp << 3)
|
2023-01-22 17:09:12 +00:00
|
|
|
copy16 temp, sy
|
2023-01-22 16:20:59 +00:00
|
|
|
shl16 temp
|
|
|
|
shl16 temp
|
|
|
|
shl16 temp
|
2023-01-22 16:34:06 +00:00
|
|
|
add16 pixel_ptr, pixel_ptr, temp
|
2023-01-22 16:20:59 +00:00
|
|
|
shl16 temp
|
|
|
|
shl16 temp
|
2023-01-22 16:34:06 +00:00
|
|
|
add16 pixel_ptr, pixel_ptr, temp
|
2023-01-22 16:20:59 +00:00
|
|
|
|
|
|
|
; Ok so temp1 points to the start of the line, which is 40 bytes.
|
|
|
|
; Get the byte and bit offsets
|
|
|
|
lda sx
|
|
|
|
clc
|
|
|
|
adc #half_width
|
|
|
|
sta temp
|
|
|
|
|
|
|
|
; pixel_shift = temp & 3
|
|
|
|
; pixel_color <<= pixel_shift (shifting in zeros)
|
|
|
|
; pixel_mask <<= pixel_shift (shifting in ones)
|
|
|
|
and #3
|
|
|
|
sta pixel_shift
|
2023-01-22 17:37:37 +00:00
|
|
|
lda #3
|
|
|
|
sec
|
|
|
|
sbc pixel_shift
|
2023-01-22 16:20:59 +00:00
|
|
|
tax
|
|
|
|
shift_loop:
|
|
|
|
beq shift_done
|
|
|
|
asl pixel_color
|
2023-01-22 17:09:12 +00:00
|
|
|
asl pixel_color
|
|
|
|
sec
|
|
|
|
rol pixel_mask
|
2023-01-22 16:20:59 +00:00
|
|
|
sec
|
|
|
|
rol pixel_mask
|
|
|
|
dex
|
|
|
|
jmp shift_loop
|
|
|
|
shift_done:
|
|
|
|
|
|
|
|
; pixel_offset = temp >> 2
|
|
|
|
lda temp
|
|
|
|
lsr a
|
|
|
|
lsr a
|
|
|
|
sta pixel_offset
|
|
|
|
tay
|
|
|
|
|
|
|
|
; read, mask, or, write
|
2023-01-22 17:09:12 +00:00
|
|
|
lda (pixel_ptr),y
|
2023-01-22 16:20:59 +00:00
|
|
|
and pixel_mask
|
|
|
|
ora pixel_color
|
2023-01-22 17:09:12 +00:00
|
|
|
sta (pixel_ptr),y
|
2023-01-22 16:20:59 +00:00
|
|
|
|
2023-01-22 03:17:30 +00:00
|
|
|
rts
|
|
|
|
.endproc
|
|
|
|
|
2023-01-22 14:35:41 +00:00
|
|
|
.macro draw_text col, len, cstr
|
2023-01-22 14:12:40 +00:00
|
|
|
; clobbers A, X
|
|
|
|
.local loop
|
|
|
|
.local done
|
|
|
|
ldx #0
|
|
|
|
loop:
|
2023-01-22 14:35:41 +00:00
|
|
|
cpx #len
|
2023-01-22 14:12:40 +00:00
|
|
|
beq done
|
2023-01-22 14:35:41 +00:00
|
|
|
ldy cstr,x
|
|
|
|
lda char_map,y
|
2023-01-22 14:12:40 +00:00
|
|
|
sta textbuffer + col,x
|
|
|
|
inx
|
|
|
|
jmp loop
|
|
|
|
done:
|
|
|
|
.endmacro
|
|
|
|
|
2023-02-05 22:26:58 +00:00
|
|
|
.proc vblank_handler
|
|
|
|
inc count_frames
|
2023-01-30 02:50:04 +00:00
|
|
|
jmp XITVBV
|
|
|
|
.endproc
|
|
|
|
|
|
|
|
.proc update_speed
|
|
|
|
; convert frames (u16) to fp
|
|
|
|
; add to frames_total
|
|
|
|
; convert pixels (u16) to fp
|
|
|
|
; add to pixels_total
|
|
|
|
; (frames_total * 16.66666667) / pixels_total
|
|
|
|
; convert to ATASCII
|
|
|
|
; draw text
|
|
|
|
.endproc
|
|
|
|
|
2022-12-30 04:32:58 +00:00
|
|
|
.proc start
|
2022-12-30 08:43:44 +00:00
|
|
|
|
2023-01-22 03:17:30 +00:00
|
|
|
; ox = 0; oy = 0; zoom = 0
|
2023-02-05 22:26:58 +00:00
|
|
|
; count_frames = 0; count_pixels = 0
|
2023-01-22 03:17:30 +00:00
|
|
|
lda #0
|
|
|
|
sta ox
|
|
|
|
sta ox + 1
|
|
|
|
sta oy
|
|
|
|
sta oy + 1
|
2023-02-05 22:26:58 +00:00
|
|
|
sta count_frames
|
|
|
|
sta count_pixels
|
|
|
|
|
|
|
|
; total_ms = 0.0; total_pixels = 0.0
|
|
|
|
ldx #total_ms
|
|
|
|
jsr ZF1
|
|
|
|
ldx #total_pixels
|
|
|
|
jsr ZF1
|
2023-01-22 20:02:15 +00:00
|
|
|
|
|
|
|
; zoom = 2x
|
|
|
|
lda #1
|
2023-01-22 03:17:30 +00:00
|
|
|
sta zoom
|
2022-12-30 04:32:58 +00:00
|
|
|
|
2023-01-22 03:17:30 +00:00
|
|
|
; Disable display DMA
|
2023-01-22 20:02:15 +00:00
|
|
|
lda #0
|
2023-01-22 03:17:30 +00:00
|
|
|
sta DMACTL
|
2023-01-07 01:18:13 +00:00
|
|
|
|
2023-01-22 03:17:30 +00:00
|
|
|
; zero the range from framebuffer_top to framebuffer_end
|
|
|
|
lda #.lobyte(framebuffer_top)
|
2023-01-07 01:18:13 +00:00
|
|
|
sta temp
|
2023-01-22 03:17:30 +00:00
|
|
|
lda #.hibyte(framebuffer_top)
|
|
|
|
sta temp + 1
|
|
|
|
|
|
|
|
zero_page_loop:
|
|
|
|
lda #0
|
|
|
|
ldy #0
|
|
|
|
zero_byte_loop:
|
|
|
|
sta (temp),y
|
|
|
|
iny
|
|
|
|
bne zero_byte_loop
|
|
|
|
|
|
|
|
inc temp + 1
|
|
|
|
lda temp + 1
|
|
|
|
cmp #.hibyte(framebuffer_end)
|
|
|
|
bne zero_page_loop
|
|
|
|
|
2023-01-22 15:36:08 +00:00
|
|
|
; Copy the display list into properly aligned memory
|
|
|
|
; Can't cross 1024-byte boundaries :D
|
|
|
|
ldx #0
|
|
|
|
copy_byte_loop:
|
|
|
|
lda display_list_start,x
|
|
|
|
sta display_list,x
|
|
|
|
inx
|
|
|
|
cpx #display_list_len
|
|
|
|
bne copy_byte_loop
|
|
|
|
|
|
|
|
; Set up the display list
|
|
|
|
lda #.lobyte(display_list)
|
|
|
|
sta DLISTL ; actual register
|
|
|
|
sta SDLSTL ; shadow register the OS will copy in
|
|
|
|
lda #.hibyte(display_list)
|
|
|
|
sta DLISTH ; actual register
|
|
|
|
sta SDLSTH ; shadow register the OS will copy in
|
|
|
|
|
2023-01-22 15:23:46 +00:00
|
|
|
; Status bar
|
2023-01-22 14:35:41 +00:00
|
|
|
draw_text 0, str_self_len, str_self
|
|
|
|
draw_text 40 - str_run_len, str_run_len, str_run
|
2023-01-22 14:12:40 +00:00
|
|
|
|
2023-01-22 03:17:30 +00:00
|
|
|
; Re-enable display DMA
|
|
|
|
lda #$22
|
|
|
|
sta DMACTL
|
|
|
|
|
2023-01-30 02:50:04 +00:00
|
|
|
; install the vblank handler
|
|
|
|
lda #7 ; deferred
|
|
|
|
ldx #.hibyte(vblank_handler)
|
|
|
|
ldy #.lobyte(vblank_handler)
|
|
|
|
jsr SETVBV
|
|
|
|
|
2023-01-22 03:17:30 +00:00
|
|
|
main_loop:
|
|
|
|
; sy = -92 .. 91
|
|
|
|
lda #(256-half_height)
|
|
|
|
sta sy
|
|
|
|
lda #(256-1)
|
|
|
|
sta sy + 1
|
|
|
|
|
|
|
|
loop_sy:
|
|
|
|
; sx = -80 .. 79
|
|
|
|
lda #(256-half_width)
|
|
|
|
sta sx
|
|
|
|
lda #(256-1)
|
|
|
|
sta sx + 1
|
|
|
|
|
|
|
|
loop_sx:
|
|
|
|
zoom_factor cx, sx, zoom, aspect_x
|
|
|
|
zoom_factor cy, sy, zoom, aspect_y
|
2023-01-22 17:13:19 +00:00
|
|
|
jsr mandelbrot
|
2023-01-22 03:17:30 +00:00
|
|
|
jsr pset
|
|
|
|
|
2023-02-05 23:14:24 +00:00
|
|
|
|
2023-02-05 22:26:58 +00:00
|
|
|
; check if we should update the counters
|
|
|
|
;
|
|
|
|
; count_pixels >= width? update!
|
|
|
|
inc count_pixels
|
|
|
|
lda count_pixels
|
|
|
|
cmp #width
|
2023-02-05 23:14:24 +00:00
|
|
|
bmi update_status
|
2023-02-05 22:26:58 +00:00
|
|
|
|
|
|
|
; count_frames >= 120? update!
|
|
|
|
lda count_frames
|
|
|
|
cmp #120 ; >= 2 seconds
|
|
|
|
bmi skip_status
|
|
|
|
|
|
|
|
update_status:
|
|
|
|
; FR0 = (float)count_pixels & clear count_pixels
|
|
|
|
lda count_pixels
|
|
|
|
sta FR0
|
|
|
|
lda #0
|
|
|
|
sta FR0 + 1
|
|
|
|
sta count_pixels
|
|
|
|
jsr IFP
|
|
|
|
|
|
|
|
; FR1 = total_pixels
|
|
|
|
ldx #.lobyte(total_pixels)
|
|
|
|
ldy #.hibyte(total_pixels)
|
|
|
|
jsr FLD1R
|
|
|
|
|
|
|
|
; FR0 += FR1
|
|
|
|
jsr FADD
|
|
|
|
|
|
|
|
; total_pixels = FR0
|
|
|
|
ldx #.lobyte(total_pixels)
|
|
|
|
ldy #.hibyte(total_pixels)
|
|
|
|
jsr FST0R
|
|
|
|
|
|
|
|
|
|
|
|
; FR0 = (float)count_frames & clear count_frames
|
|
|
|
; warning: this should really disable interrupts @TODO
|
|
|
|
lda count_frames
|
|
|
|
sta FR0
|
|
|
|
lda #0
|
|
|
|
sta FR0 + 1
|
|
|
|
sta count_frames
|
|
|
|
jsr IFP
|
|
|
|
|
|
|
|
; FR0 *= ms_per_frame
|
|
|
|
ldx #.lobyte(ms_per_frame)
|
|
|
|
ldy #.hibyte(ms_per_frame)
|
2023-02-05 23:14:24 +00:00
|
|
|
jsr FLD1R
|
2023-02-05 22:26:58 +00:00
|
|
|
jsr FMUL
|
|
|
|
|
2023-02-05 23:14:24 +00:00
|
|
|
; FR0 += total_ms
|
2023-02-05 22:26:58 +00:00
|
|
|
ldx #total_ms
|
|
|
|
ldy #0
|
|
|
|
jsr FLD1R
|
|
|
|
jsr FADD
|
|
|
|
|
|
|
|
; total_ms = FR0
|
|
|
|
ldx #total_ms
|
|
|
|
ldy #0
|
|
|
|
jsr FST0R
|
|
|
|
|
2023-02-05 23:14:24 +00:00
|
|
|
; FR0 /= total_pixels
|
2023-02-05 22:26:58 +00:00
|
|
|
ldx #total_pixels
|
|
|
|
ldy #0
|
|
|
|
jsr FLD1R
|
|
|
|
jsr FDIV
|
|
|
|
|
|
|
|
; convert to ASCII in INBUFF
|
|
|
|
jsr FASC
|
|
|
|
|
|
|
|
; find the last byte
|
|
|
|
ldy #0
|
|
|
|
number_loop:
|
|
|
|
lda (INBUFF),y
|
|
|
|
bmi lastchar
|
|
|
|
|
|
|
|
tax
|
|
|
|
lda char_map,x
|
|
|
|
sta textbuffer + speed_start,y
|
|
|
|
|
|
|
|
iny
|
|
|
|
bpl number_loop
|
|
|
|
lastchar:
|
|
|
|
; Y is last char
|
|
|
|
; trim that high bit
|
|
|
|
and #$7f
|
|
|
|
tax
|
|
|
|
lda char_map,x
|
|
|
|
sta textbuffer + speed_start,y
|
|
|
|
|
|
|
|
; Fill out any remaining spaces
|
|
|
|
lda #0
|
|
|
|
space_loop:
|
|
|
|
iny
|
|
|
|
sta textbuffer + speed_start,y
|
|
|
|
cpy #(20)
|
|
|
|
bmi space_loop
|
|
|
|
|
|
|
|
skip_status:
|
|
|
|
|
2023-01-22 03:17:30 +00:00
|
|
|
clc
|
2023-01-22 17:09:12 +00:00
|
|
|
lda sx
|
2023-01-22 03:17:30 +00:00
|
|
|
adc #1
|
|
|
|
sta sx
|
|
|
|
lda sx + 1
|
|
|
|
adc #0
|
|
|
|
sta sx + 1
|
2023-01-22 16:34:06 +00:00
|
|
|
|
|
|
|
lda sx
|
|
|
|
cmp #half_width
|
|
|
|
beq loop_sx_done
|
2023-01-22 03:17:30 +00:00
|
|
|
jmp loop_sx
|
|
|
|
|
|
|
|
loop_sx_done:
|
|
|
|
|
|
|
|
clc
|
2023-01-22 17:09:12 +00:00
|
|
|
lda sy
|
2023-01-22 03:17:30 +00:00
|
|
|
adc #1
|
|
|
|
sta sy
|
|
|
|
lda sy + 1
|
|
|
|
adc #0
|
|
|
|
sta sy + 1
|
2023-01-22 16:34:06 +00:00
|
|
|
|
|
|
|
lda sy
|
|
|
|
cmp #half_height
|
|
|
|
beq loop_sy_done
|
2023-01-22 03:17:30 +00:00
|
|
|
jmp loop_sy
|
|
|
|
|
|
|
|
loop_sy_done:
|
2023-01-07 01:18:13 +00:00
|
|
|
|
2023-01-22 14:35:41 +00:00
|
|
|
draw_text 40 - str_done_len, str_done_len, str_done
|
2023-01-22 14:12:40 +00:00
|
|
|
|
2023-01-05 04:12:34 +00:00
|
|
|
loop:
|
2023-01-22 03:17:30 +00:00
|
|
|
; finished
|
|
|
|
jmp loop
|
2022-12-30 04:32:58 +00:00
|
|
|
.endproc
|