Ero partito con l'idea ambiziosa di creare l'insieme di Mandelbrot in Assembly 6502 per Commodore 64 usando un po' l'esperienza di questo
precedente post
In sintesi volevo un calcolo rapido utilizzando solo gli interi e la modalita' testo (un po' per riprendere Tequila Virus per DOS)
Alla fine ho barato....usando CC65, il crosscompilatore per 6502 e' possibile ottenere, oltre all'eseguibile. anche un listato Assembly....e tra gli esempi c'e' pure un calcolo di Mandelbrot che rispetto l'algoritmo che mi ero prefisso
Il tempo di esecuzione e' stato 1 minuto e 37 secondi
Versione in C
--------------------------------------------------------------------------------------------
include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#define SCREEN_X 40
#define SCREEN_Y 22
#define maxiterations 30
#define fpshift (10)
#define tofp(_x) ((_x)<<fpshift)
#define fromfp(_x) ((_x)>>fpshift)
#define fpabs(_x) (abs(_x))
#define mulfp(_a,_b) ((((signed long)_a)*(_b))>>fpshift)
#define divfp(_a,_b) ((((signed long)_a)<<fpshift)/(_b))
#pragma static-locals (1);
int main (void)
{
register unsigned char count;
register signed short r, r1, i;
register signed short xs, ys, xx, yy;
register signed short x, y;
register signed short x1,y1,x2,y2;
x1 = -2048;
y1 = -1024;
x2 = 1024;
y2 = 1024;
xs = 77;
ys = 93;
yy = y1;
for (y = 0; y < (SCREEN_Y); y++) {
yy += ys;
xx = x1;
for (x = 0; x < (SCREEN_X); x++) {
xx += xs;
/* Do iterations */
r = 0;
i = 0;
for (count = 0; (count < maxiterations) &&
(fpabs (r) < 2048) && (fpabs (i) < 2048);
++count) {
r1 = (mulfp (r, r) - mulfp (i, i)) + xx;
i = (((signed long) r * i) >> 9) + yy;
r = r1;
}
textcolor(count/2);
printf("O");
}
}
return EXIT_SUCCESS;
}
--------------------------------------------------------------------------------------------
Traduzione in Assembly
--------------------------------------------------------------------------------------------
;
; File generated by cc65 v 2.17 - Git N/A
;
.fopt compiler,"cc65 v 2.17 - Git N/A"
.setcpu "6502"
.smart on
.autoimport on
.case on
.debuginfo off
.importzp sp, sreg, regsave, regbank
.importzp tmp1, tmp2, tmp3, tmp4, ptr1, ptr2, ptr3, ptr4
.macpack longbranch
.forceimport __STARTUP__
.import _abs
.import _printf
.export _main
.segment "RODATA"
L0067:
.byte $25,$63,$00
; ---------------------------------------------------------------
; int __near__ main (void)
; ---------------------------------------------------------------
.segment "CODE"
.proc _main: near
.segment "BSS"
L0003:
.res 1,$00
L0004:
.res 2,$00
L0005:
.res 2,$00
L0006:
.res 2,$00
L0007:
.res 2,$00
L0008:
.res 2,$00
L0009:
.res 2,$00
L000A:
.res 2,$00
L000B:
.res 2,$00
L000C:
.res 2,$00
L000D:
.res 2,$00
L000E:
.res 2,$00
L000F:
.res 2,$00
L0010:
.res 2,$00
.segment "CODE"
;
; x1 = -2048;
;
ldx #$F8
lda #$00
sta L000D
stx L000D+1
;
; y1 = -1024;
;
ldx #$FC
lda #$00
sta L000E
stx L000E+1
;
; x2 = 1024;
;
ldx #$04
lda #$00
sta L000F
stx L000F+1
;
; y2 = 1024;
;
ldx #$04
lda #$00
sta L0010
stx L0010+1
;
; xs = 77;
;
ldx #$00
lda #$4D
sta L0007
stx L0007+1
;
; ys = 93;
;
ldx #$00
lda #$5D
sta L0008
stx L0008+1
;
; yy = y1;
;
lda L000E
ldx L000E+1
sta L000A
stx L000A+1
;
; for (y = 0; y < (SCREEN_Y); y++) {
;
ldx #$00
lda #$00
sta L000C
stx L000C+1
L001F: lda L000C
ldx L000C+1
cmp #$16
txa
sbc #$00
bvc L0027
eor #$80
L0027: asl a
lda #$00
ldx #$00
rol a
jne L0022
jmp L0020
;
; yy += ys;
;
L0022: lda L0008
ldx L0008+1
clc
adc L000A
sta L000A
txa
adc L000A+1
sta L000A+1
tax
lda L000A
;
; xx = x1;
;
lda L000D
ldx L000D+1
sta L0009
stx L0009+1
;
; for (x = 0; x < (SCREEN_X); x++) {
;
ldx #$00
lda #$00
sta L000B
stx L000B+1
L002D: lda L000B
ldx L000B+1
cmp #$28
txa
sbc #$00
bvc L0035
eor #$80
L0035: asl a
lda #$00
ldx #$00
rol a
jne L0030
jmp L0021
;
; xx += xs;
;
L0030: lda L0007
ldx L0007+1
clc
adc L0009
sta L0009
txa
adc L0009+1
sta L0009+1
tax
lda L0009
;
; r = 0;
;
ldx #$00
lda #$00
sta L0004
stx L0004+1
;
; i = 0;
;
ldx #$00
lda #$00
sta L0006
stx L0006+1
;
; for (count = 0; (count < maxiterations) &&
;
ldx #$00
lda #$00
sta L0003
L003D: ldx #$00
lda L0003
cmp #$1E
jsr boolult
jeq L0045
;
; (fpabs (r) < 2048) && (fpabs (i) < 2048);
;
lda L0004
ldx L0004+1
jsr _abs
cmp #$00
txa
sbc #$08
bvc L0049
eor #$80
L0049: asl a
lda #$00
ldx #$00
rol a
jeq L0045
lda L0006
ldx L0006+1
jsr _abs
cmp #$00
txa
sbc #$08
bvc L004D
eor #$80
L004D: asl a
lda #$00
ldx #$00
rol a
jne L0043
L0045: ldx #$00
lda #$00
jeq L004E
L0043: ldx #$00
lda #$01
L004E: jne L0040
jmp L003E
;
; r1 = (mulfp (r, r) - mulfp (i, i)) + xx;
;
L0040: lda L0004
ldx L0004+1
jsr axlong
jsr pusheax
lda L0004
ldx L0004+1
jsr axlong
jsr tosmuleax
txa
ldx sreg
ldy sreg+1
sty sreg
cpy #$80
ldy #$00
bcc L0058
dey
L0058: sty sreg+1
jsr asreax2
jsr pusheax
lda L0006
ldx L0006+1
jsr axlong
jsr pusheax
lda L0006
ldx L0006+1
jsr axlong
jsr tosmuleax
txa
ldx sreg
ldy sreg+1
sty sreg
cpy #$80
ldy #$00
bcc L005E
dey
L005E: sty sreg+1
jsr asreax2
jsr tossubeax
jsr pusheax
lda L0009
ldx L0009+1
jsr axlong
jsr tosaddeax
sta L0005
stx L0005+1
;
; i = (((signed long) r * i) >> 9) + yy;
;
lda L0004
ldx L0004+1
jsr axlong
jsr pusheax
lda L0006
ldx L0006+1
jsr axlong
jsr tosmuleax
txa
ldx sreg
ldy sreg+1
sty sreg
cpy #$80
ldy #$00
bcc L0063
dey
L0063: sty sreg+1
jsr asreax1
jsr pusheax
lda L000A
ldx L000A+1
jsr axlong
jsr tosaddeax
sta L0006
stx L0006+1
;
; r = r1;
;
lda L0005
ldx L0005+1
sta L0004
stx L0004+1
;
; ++count) {
;
ldx #$00
inc L0003
lda L0003
jmp L003D
;
; printf("%c",count+50);
;
L003E: lda #<(L0067)
ldx #>(L0067)
jsr pushax
ldx #$00
lda L0003
ldy #$32
jsr incaxy
jsr pushax
ldy #$04
jsr _printf
;
; for (x = 0; x < (SCREEN_X); x++) {
;
lda L000B
ldx L000B+1
sta regsave
stx regsave+1
jsr incax1
sta L000B
stx L000B+1
lda regsave
ldx regsave+1
jmp L002D
;
; for (y = 0; y < (SCREEN_Y); y++) {
;
L0021: lda L000C
ldx L000C+1
sta regsave
stx regsave+1
jsr incax1
sta L000C
stx L000C+1
lda regsave
ldx regsave+1
jmp L001F
;
; return EXIT_SUCCESS;
;
L0020: ldx #$00
lda #$00
jmp L0002
;
; }
;
L0002: rts
.endproc
--------------------------------------------------------------------------------------------