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
|
|
|
|
|
2023-02-12 19:37:52 +00:00
|
|
|
z_buffer_active = $b0 ; boolean: 1 if we triggered the lake, 0 if not
|
|
|
|
z_buffer_start = $b1 ; u8: index into z_buffer
|
|
|
|
z_buffer_end = $b2 ; u8: index into z_buffer
|
|
|
|
temp = $b4 ; u16
|
|
|
|
|
|
|
|
pixel_ptr = $b6 ; u16
|
|
|
|
pixel_color = $b8 ; u8
|
|
|
|
pixel_mask = $b9 ; u8
|
|
|
|
pixel_shift = $ba ; u8
|
|
|
|
pixel_offset = $bb ; u8
|
2024-02-04 22:25:15 +00:00
|
|
|
fill_level = $bc ; u8
|
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
|
|
|
|
|
2023-03-05 23:45:44 +00:00
|
|
|
CH1 = $02f2 ; previous character read from keyboard
|
|
|
|
CH = $02fc ; current character read from keyboard
|
|
|
|
|
2023-02-05 22:26:58 +00:00
|
|
|
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-03-05 23:45:44 +00:00
|
|
|
WSYNC = $D40A
|
2023-01-22 03:17:30 +00:00
|
|
|
|
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
|
2023-03-05 23:45:44 +00:00
|
|
|
SYSVBV = $E45F
|
2023-01-30 02:50:04 +00:00
|
|
|
XITVBV = $E462
|
|
|
|
SETVBV = $E45C
|
|
|
|
|
2023-03-12 04:45:32 +00:00
|
|
|
; Keycodes!
|
|
|
|
KEY_PLUS = $06
|
|
|
|
KEY_MINUS = $0e
|
|
|
|
KEY_UP = $8e
|
|
|
|
KEY_DOWN = $8f
|
|
|
|
KEY_LEFT = $86
|
|
|
|
KEY_RIGHT = $87
|
2023-03-05 23:45:44 +00:00
|
|
|
|
2023-02-05 22:26:58 +00:00
|
|
|
.struct float48
|
|
|
|
exponent .byte
|
|
|
|
mantissa .byte 6
|
|
|
|
.endstruct
|
|
|
|
|
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-03-05 21:48:39 +00:00
|
|
|
.byte " ms/px"
|
2023-01-22 14:35:41 +00:00
|
|
|
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-03-05 21:56:50 +00:00
|
|
|
speed_precision = 6
|
2023-01-22 14:35:41 +00:00
|
|
|
|
2023-03-05 21:56:50 +00:00
|
|
|
speed_start = 40 - str_done_len - str_speed_len - speed_precision - 1
|
2023-02-05 22:26:58 +00:00
|
|
|
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-03-05 23:45:44 +00:00
|
|
|
hex_chars:
|
|
|
|
.byte "0123456789abcdef"
|
|
|
|
|
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
|
|
|
|
|
2023-02-12 19:37:52 +00:00
|
|
|
z_buffer_len = 16
|
|
|
|
z_buffer_mask = z_buffer_len - 1
|
|
|
|
z_buffer:
|
|
|
|
; the last N zx/zy values
|
|
|
|
.repeat z_buffer_len
|
|
|
|
.word 0
|
|
|
|
.word 0
|
|
|
|
.endrepeat
|
|
|
|
|
2022-12-29 05:08:16 +00:00
|
|
|
.export start
|
|
|
|
|
2024-02-04 22:25:15 +00:00
|
|
|
max_fill_level = 6
|
|
|
|
fill_masks:
|
|
|
|
.byte %00011111
|
|
|
|
.byte %00001111
|
|
|
|
.byte %00000111
|
|
|
|
.byte %00000011
|
|
|
|
.byte %00000001
|
|
|
|
.byte %00000000
|
|
|
|
|
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
|
|
|
|
|
|
|
|
; 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,
|
|
|
|
; keeping a count of sign bits in the X register.
|
|
|
|
.local positive
|
2022-12-31 01:33:18 +00:00
|
|
|
lda arg + 1 ; 3 cyc
|
|
|
|
bpl positive ; 2 cyc
|
|
|
|
neg16 arg ; 18 cyc
|
|
|
|
inx ; 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-01-07 01:18:13 +00:00
|
|
|
.proc imul16_func
|
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
|
|
|
|
|
2022-12-31 01:33:18 +00:00
|
|
|
ldx #0 ; 2 cyc
|
2022-12-30 08:43:44 +00:00
|
|
|
; counts the number of sign bits in X
|
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.
|
2022-12-31 01:33:18 +00:00
|
|
|
cpx #1 ; 2 cyc
|
|
|
|
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
|
2023-02-12 19:37:52 +00:00
|
|
|
sta z_buffer_start
|
2023-03-06 00:54:40 +00:00
|
|
|
sta z_buffer_end
|
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-02-12 19:37:52 +00:00
|
|
|
jmp exit_path
|
2023-01-07 01:18:13 +00:00
|
|
|
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-02-12 19:37:52 +00:00
|
|
|
jmp exit_path
|
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-02-12 19:37:52 +00:00
|
|
|
jmp exit_path
|
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-02-12 19:37:52 +00:00
|
|
|
lda z_buffer_active
|
|
|
|
beq skip_z_buffer
|
|
|
|
|
|
|
|
ldx z_buffer_start
|
|
|
|
cpx z_buffer_end
|
|
|
|
beq z_nothing_to_read
|
|
|
|
|
|
|
|
z_buffer_loop:
|
|
|
|
.macro z_compare arg
|
|
|
|
.local compare_no_match
|
|
|
|
lda z_buffer,x
|
|
|
|
inx
|
|
|
|
cmp arg
|
|
|
|
bne compare_no_match
|
|
|
|
iny
|
|
|
|
compare_no_match:
|
|
|
|
.endmacro
|
|
|
|
.macro z_advance
|
|
|
|
.local skip_reset_x
|
|
|
|
cpx #(z_buffer_len * 4)
|
|
|
|
bmi skip_reset_x
|
|
|
|
ldx #0
|
|
|
|
skip_reset_x:
|
|
|
|
.endmacro
|
|
|
|
.macro z_store arg
|
|
|
|
lda arg
|
|
|
|
sta z_buffer,x
|
|
|
|
inx
|
|
|
|
.endmacro
|
|
|
|
|
|
|
|
; Compare the previously stored z values
|
|
|
|
ldy #0
|
|
|
|
z_compare zx
|
|
|
|
z_compare zx + 1
|
|
|
|
z_compare zy
|
|
|
|
z_compare zy + 1
|
|
|
|
|
|
|
|
cpy #4
|
|
|
|
bne z_no_matches
|
|
|
|
jmp z_exit
|
|
|
|
|
|
|
|
z_no_matches:
|
|
|
|
z_advance
|
|
|
|
|
|
|
|
cpx z_buffer_end
|
|
|
|
bne z_buffer_loop
|
|
|
|
|
|
|
|
z_nothing_to_read:
|
|
|
|
|
|
|
|
; Store and expand
|
|
|
|
z_store zx
|
|
|
|
z_store zx + 1
|
|
|
|
z_store zy
|
|
|
|
z_store zy + 1
|
|
|
|
z_advance
|
|
|
|
stx z_buffer_end
|
|
|
|
|
|
|
|
; Increment the start roller if necessary (limit size)
|
|
|
|
lda iter
|
|
|
|
cmp #(z_buffer_len * 4)
|
|
|
|
bmi skip_inc_start
|
|
|
|
lda z_buffer_start
|
|
|
|
clc
|
|
|
|
adc #4
|
|
|
|
tax
|
|
|
|
z_advance
|
|
|
|
stx z_buffer_start
|
|
|
|
skip_inc_start:
|
|
|
|
|
|
|
|
skip_z_buffer:
|
|
|
|
|
2023-01-22 18:42:37 +00:00
|
|
|
jmp loop
|
2022-12-30 08:55:48 +00:00
|
|
|
|
2023-02-12 19:37:52 +00:00
|
|
|
z_exit:
|
|
|
|
lda #0
|
|
|
|
sta iter
|
|
|
|
|
|
|
|
exit_path:
|
|
|
|
ldx #0
|
|
|
|
lda iter
|
|
|
|
bne next
|
|
|
|
inx
|
|
|
|
next:
|
|
|
|
stx z_buffer_active
|
2023-01-22 20:02:15 +00:00
|
|
|
rts
|
|
|
|
|
2022-12-29 05:08:16 +00:00
|
|
|
.endproc
|
2022-12-30 04:32:58 +00:00
|
|
|
|
2023-03-12 04:45:32 +00:00
|
|
|
.macro scale_zoom dest
|
|
|
|
; clobbers X, flags
|
2023-01-22 03:17:30 +00:00
|
|
|
.local cont
|
|
|
|
.local enough
|
|
|
|
|
|
|
|
; cx = (sx << (8 - zoom))
|
|
|
|
ldx zoom
|
|
|
|
cont:
|
|
|
|
cpx #8
|
|
|
|
beq enough
|
|
|
|
shl16 dest
|
|
|
|
inx
|
|
|
|
jmp cont
|
|
|
|
enough:
|
2023-03-12 04:45:32 +00:00
|
|
|
.endmacro
|
|
|
|
|
|
|
|
.macro zoom_factor dest, src, zoom, aspect
|
|
|
|
; clobbers A, X, flags, etc
|
|
|
|
copy16 dest, src
|
|
|
|
scale_zoom dest
|
2023-01-22 03:17:30 +00:00
|
|
|
|
|
|
|
; 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-03-05 21:48:39 +00:00
|
|
|
.macro draw_text_indirect col, len, strptr
|
|
|
|
; clobbers A, X
|
|
|
|
.local loop
|
|
|
|
.local done
|
|
|
|
ldx #0
|
|
|
|
loop:
|
|
|
|
cpx #len
|
|
|
|
beq done
|
|
|
|
txa
|
|
|
|
tay
|
|
|
|
lda (strptr),y
|
|
|
|
tay
|
|
|
|
lda char_map,y
|
|
|
|
sta textbuffer + col,x
|
|
|
|
inx
|
|
|
|
jmp loop
|
|
|
|
done:
|
|
|
|
.endmacro
|
|
|
|
|
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
|
|
|
|
|
2023-03-12 04:45:32 +00:00
|
|
|
.proc keycheck
|
|
|
|
; clobbers all
|
|
|
|
; returns 255 in A if state change or 0 if no change
|
|
|
|
|
|
|
|
; check keyboard buffer
|
|
|
|
lda CH
|
|
|
|
cmp #$ff
|
|
|
|
beq skip_char
|
|
|
|
|
|
|
|
; Clear the keyboard buffer and re-enable interrupts
|
|
|
|
ldx #$ff
|
|
|
|
stx CH
|
|
|
|
|
|
|
|
tay
|
|
|
|
|
|
|
|
lda zoom
|
|
|
|
cpy #KEY_PLUS
|
|
|
|
beq plus
|
|
|
|
cpy #KEY_MINUS
|
|
|
|
beq minus
|
|
|
|
|
|
|
|
; temp = $0010 << (8 - zoom)
|
|
|
|
lda #$10
|
|
|
|
sta temp
|
|
|
|
lda #$00
|
|
|
|
sta temp + 1
|
|
|
|
scale_zoom temp
|
|
|
|
|
|
|
|
cpy #KEY_UP
|
|
|
|
beq up
|
|
|
|
cpy #KEY_DOWN
|
|
|
|
beq down
|
|
|
|
cpy #KEY_LEFT
|
|
|
|
beq left
|
|
|
|
cpy #KEY_RIGHT
|
|
|
|
beq right
|
|
|
|
|
|
|
|
skip_char:
|
|
|
|
lda #0
|
|
|
|
rts
|
|
|
|
|
|
|
|
plus:
|
|
|
|
cmp #8
|
|
|
|
bpl skip_char
|
|
|
|
inc zoom
|
|
|
|
jmp done
|
|
|
|
minus:
|
|
|
|
cmp #1
|
|
|
|
bmi skip_char
|
|
|
|
dec zoom
|
|
|
|
jmp done
|
|
|
|
up:
|
|
|
|
sub16 oy, oy, temp
|
|
|
|
jmp done
|
|
|
|
down:
|
|
|
|
add16 oy, oy, temp
|
|
|
|
jmp done
|
|
|
|
left:
|
|
|
|
sub16 ox, ox, temp
|
|
|
|
jmp done
|
|
|
|
right:
|
|
|
|
add16 ox, ox, temp
|
|
|
|
done:
|
|
|
|
lda #255
|
|
|
|
rts
|
|
|
|
|
|
|
|
.endproc
|
|
|
|
|
2024-02-25 23:15:23 +00:00
|
|
|
.proc clear_screen
|
|
|
|
; zero the range from framebuffer_top to display_list
|
|
|
|
lda #.lobyte(framebuffer_top)
|
|
|
|
sta temp
|
|
|
|
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(display_list)
|
|
|
|
bne zero_page_loop
|
|
|
|
|
|
|
|
rts
|
|
|
|
.endproc
|
|
|
|
|
|
|
|
.proc status_bar
|
|
|
|
; Status bar
|
|
|
|
draw_text 0, str_self_len, str_self
|
|
|
|
draw_text 40 - str_run_len, str_run_len, str_run
|
|
|
|
|
|
|
|
rts
|
|
|
|
.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
|
|
|
|
2024-02-25 23:15:23 +00:00
|
|
|
jsr clear_screen
|
2023-01-22 03:17:30 +00:00
|
|
|
|
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 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:
|
2024-02-25 23:15:23 +00:00
|
|
|
jsr clear_screen
|
|
|
|
jsr status_bar
|
|
|
|
|
2024-02-04 22:25:15 +00:00
|
|
|
lda #0
|
|
|
|
sta fill_level
|
|
|
|
|
|
|
|
fill_loop:
|
|
|
|
|
2023-01-22 03:17:30 +00:00
|
|
|
; 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:
|
2024-02-04 22:25:15 +00:00
|
|
|
; check the fill mask
|
|
|
|
ldy #0
|
|
|
|
|
|
|
|
loop_skip_level:
|
|
|
|
cpy fill_level
|
|
|
|
beq current_level
|
|
|
|
|
|
|
|
lda fill_masks,y
|
|
|
|
and sx
|
|
|
|
bne not_skipped_mask1
|
|
|
|
|
|
|
|
lda fill_masks,y
|
|
|
|
and sy
|
|
|
|
beq skipped_mask
|
|
|
|
|
|
|
|
not_skipped_mask1:
|
|
|
|
iny
|
|
|
|
jmp loop_skip_level
|
|
|
|
|
|
|
|
current_level:
|
|
|
|
lda fill_masks,y
|
|
|
|
and sx
|
|
|
|
bne skipped_mask
|
|
|
|
|
|
|
|
lda fill_masks,y
|
|
|
|
and sy
|
|
|
|
beq not_skipped_mask
|
|
|
|
|
|
|
|
skipped_mask:
|
|
|
|
jmp skipped
|
|
|
|
|
|
|
|
not_skipped_mask:
|
|
|
|
|
|
|
|
; run the fractal!
|
2023-01-22 03:17:30 +00:00
|
|
|
zoom_factor cx, sx, zoom, aspect_x
|
2023-03-12 04:45:32 +00:00
|
|
|
add16 cx, cx, ox
|
2023-01-22 03:17:30 +00:00
|
|
|
zoom_factor cy, sy, zoom, aspect_y
|
2023-03-12 04:45:32 +00:00
|
|
|
add16 cy, cy, oy
|
2023-01-22 17:13:19 +00:00
|
|
|
jsr mandelbrot
|
2023-01-22 03:17:30 +00:00
|
|
|
jsr pset
|
|
|
|
|
2023-03-12 04:45:32 +00:00
|
|
|
jsr keycheck
|
|
|
|
beq no_key
|
2023-03-12 05:15:08 +00:00
|
|
|
; @fixme clear the pixel stats
|
2024-02-25 23:15:23 +00:00
|
|
|
jmp main_loop
|
2023-02-05 23:14:24 +00:00
|
|
|
|
2023-03-12 04:45:32 +00:00
|
|
|
no_key:
|
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
|
2024-02-04 22:25:15 +00:00
|
|
|
bmi skipped
|
2023-02-05 22:26:58 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
|
2023-03-05 21:48:39 +00:00
|
|
|
; print the first 6 digits
|
2023-03-05 21:56:50 +00:00
|
|
|
draw_text_indirect speed_start, speed_precision, INBUFF
|
|
|
|
draw_text speed_start + speed_precision, str_speed_len, str_speed
|
2023-02-05 22:26:58 +00:00
|
|
|
|
2024-02-04 22:25:15 +00:00
|
|
|
skipped:
|
2023-02-05 22:26:58 +00:00
|
|
|
|
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
|
|
|
|
2024-02-04 22:25:15 +00:00
|
|
|
fill_loop_done:
|
|
|
|
inc fill_level
|
|
|
|
lda fill_level
|
|
|
|
cmp #max_fill_level
|
|
|
|
beq loop
|
|
|
|
jmp fill_loop
|
|
|
|
|
2023-01-05 04:12:34 +00:00
|
|
|
loop:
|
2023-01-22 03:17:30 +00:00
|
|
|
; finished
|
2023-03-12 04:45:32 +00:00
|
|
|
jsr keycheck
|
|
|
|
beq loop
|
|
|
|
jmp main_loop
|
|
|
|
|
2022-12-30 04:32:58 +00:00
|
|
|
.endproc
|