A2 03 B5 FB 95 26 CA 10 F9 88 D0 01 60 A5 26 85 61 A5 27 85 62 A5 FB 85 63 A5
FC 85 64 A9 20 85 6F D0 36 18 A5 6D 65 65 85 28 A5 6E 65 66 85 29 A5 4B 85 26
A5 4C 85 27 50 CF 38 A5 6D E5 65 85 4B A5 6E E5 66 85 4C A5 28 85 61 A5 29 85
62 A5 FB 85 63 A5 FC 85 64 06 6F A9 00 85 65 85 66 A2 10 46 62 66 61 90 0D A5
63 18 65 65 85 65 A5 64 65 66 85 66 06 63 26 64 CA 10 E6 A9 FF 24 6F 70 B9 30
02 F0 9E A5 65 85 6D A5 66 85 6E 24 6F 30 14 A5 28 85 61 A5 29 85 62 A5 FD 85
63 A5 FE 85 64 06 6F D0 B4 A5 26 85 61 A5 27 85 62 A5 FD 85 63 A5 FE 85 64 06
6F B0 A0
- উন্নত "স্প্যাগেটি" কাঠামো সহ -12 বাইট
- -২ বাইটগুলি রেজিস্টার পরিবর্তন করে এক্সপেন্ডেন্টটি পাস করার জন্য, তাই আমরা প্রাথমিক কপির লুপে জেরোপেজ অ্যাড্রেসিং মোডটি ব্যবহার করতে পারি
এটি অবস্থান-স্বতন্ত্র কোড, কেবল এটিকে র্যামের কোথাও রেখে এটিকে কল করুন jsr
নির্দেশের ।
রুটিনটি (জটিল) বেসটিকে দুটি 16 বিট স্বাক্ষরিত পূর্ণসংখ্যার হিসাবে (2 এর পরিপূরক, ছোট-এন্ডিয়ান) $fb/$fc
(বাস্তব) এবং$fd/$fe
(কাল্পনিক) হিসাবে এবং নিখরচায়কের স্বাক্ষরযুক্ত 8 বিট পূর্ণসংখ্যার হিসাবে প্রকাশককে গ্রহণ করে Y
।
ফলাফল ফিরে আসে $26/$27
(বাস্তব) এবং$28/$29
(কাল্পনিক) এ ।
ব্যাখ্যা
এমনকি 6502 সিপিইউতে এটি এখনও একটি আকর্ষণীয় চ্যালেঞ্জ কারণ এখানে এমনকি গুণনের কোনও নির্দেশ নেই। পদ্ধতির সোজা এগিয়ে রয়েছে, একটি জটিল গুণ প্রয়োগ করে এবং প্রায়শই প্রয়োজন হিসাবে এটি কার্যকর করে exp গল্ফিং সাবরুটাইনগুলি এড়িয়ে পরিবর্তে একটি "ব্রাঞ্চ স্প্যাগেটি" তৈরি করে করা হয়, তাই একাধিকবার প্রয়োজন এমন একটি সহজ 16 বিট গুণনের কোডটি সর্বনিম্ন সম্ভব ওভারহেড দিয়ে পুনরায় ব্যবহার করা হয়। এখানে মন্তব্য বিচ্ছিন্ন:
.cexp:
A2 03 LDX #$03 ; copy argument ...
.copyloop:
B5 FB LDA $FB,X
95 26 STA $26,X
CA DEX
10 F9 BPL .copyloop ; ... to result
.exploop:
88 DEY ; decrement exponent
D0 01 BNE .mult ; zero reached -> done
60 RTS
.mult: ; multiply (complex) result by argument
A5 26 LDA $26 ; prepare to multiply real components
85 61 STA $61 ; (a*c)
A5 27 LDA $27
85 62 STA $62
A5 FB LDA $FB
85 63 STA $63
A5 FC LDA $FC
85 64 STA $64
A9 20 LDA #$20 ; marker for where to continue
85 6F STA $6F
D0 36 BNE .mult16 ; branch to 16bit multiplication
.mult5:
18 CLC ; calculate sum (a*d) + (b*c)
A5 6D LDA $6D
65 65 ADC $65
85 28 STA $28 ; and store to imaginary component of result
A5 6E LDA $6E
65 66 ADC $66
85 29 STA $29
A5 4B LDA $4B ; load temporary result (a*c) - (b*d)
85 26 STA $26 ; and store to real component of result
A5 4C LDA $4C
85 27 STA $27
50 CF BVC .exploop ; next exponentiation step
.mult3:
38 SEC ; calculate difference (a*c) - (b*d)
A5 6D LDA $6D
E5 65 SBC $65
85 4B STA $4B ; and store to temporary location
A5 6E LDA $6E
E5 66 SBC $66
85 4C STA $4C
A5 28 LDA $28 ; prepare to multiply real component of result
85 61 STA $61 ; with imaginary component of argument
A5 29 LDA $29 ; (a*d)
85 62 STA $62
A5 FB LDA $FB
85 63 STA $63
A5 FC LDA $FC
85 64 STA $64
06 6F ASL $6F ; advance "continue marker"
.mult16:
A9 00 LDA #$00 ; initialize 16bit multiplication
85 65 STA $65 ; result with 0
85 66 STA $66
A2 10 LDX #$10 ; bit counter (16)
.m16_loop:
46 62 LSR $62 ; shift arg1 right
66 61 ROR $61
90 0D BCC .m16_noadd ; no carry -> nothing to add
A5 63 LDA $63 ; add arg2 ...
18 CLC
65 65 ADC $65
85 65 STA $65
A5 64 LDA $64
65 66 ADC $66
85 66 STA $66 ; ... to result
.m16_noadd:
06 63 ASL $63 ; shift arg2 left
26 64 ROL $64
CA DEX ; decrement number of bits to go
10 E6 BPL .m16_loop
A9 FF LDA #$FF ; check marker for where to continue
24 6F BIT $6F
70 B9 BVS .mult3
30 02 BMI .saveres ; have to save result to temp in 2 cases
F0 9E BEQ .mult5
.saveres:
A5 65 LDA $65 ; save result to temporary
85 6D STA $6D
A5 66 LDA $66
85 6E STA $6E
24 6F BIT $6F ; check "continue marker" again
30 14 BMI .mult4
.mult2:
A5 28 LDA $28 ; prepare to multiply imaginary components
85 61 STA $61 ; (b*d)
A5 29 LDA $29
85 62 STA $62
A5 FD LDA $FD
85 63 STA $63
A5 FE LDA $FE
85 64 STA $64
06 6F ASL $6F ; advance "continue marker"
D0 B4 BNE .mult16 ; branch to 16bit multiplication
.mult4:
A5 26 LDA $26 ; prepare to multiply imaginary component of
85 61 STA $61 ; result with real component of argument
A5 27 LDA $27 ; (b*c)
85 62 STA $62
A5 FD LDA $FD
85 63 STA $63
A5 FE LDA $FE
85 64 STA $64
06 6F ASL $6F ; advance "continue marker"
B0 A0 BCS .mult16 ; branch to 16bit multiplication
প্রোগ্রামটি ব্যবহার করে উদাহরণস্বরূপ (সি 64, সিএএনএক্স- সিন্ট্যাক্সে সমাবেশের উত্স ):
.import cexp
CEXP_A = $fb
CEXP_AL = $fb
CEXP_AH = $fc
CEXP_B = $fd
CEXP_BL = $fd
CEXP_BH = $fe
CEXP_RA = $26
CEXP_RAL = $26
CEXP_RAH = $27
CEXP_RB = $28
CEXP_RBL = $28
CEXP_RBH = $29
.segment "LDADDR"
.word $c000
.segment "MAIN"
jsr $aefd ; consume comma
jsr $ad8a ; evaluate number
jsr $b1aa ; convert to 16bit int
sty CEXP_AL ; store as first argument
sta CEXP_AH
jsr $aefd ; ...
jsr $ad8a
jsr $b1aa
sty CEXP_BL ; store as second argument
sta CEXP_BH
jsr $b79b ; read 8bit unsigned into X
txa ; and transfer
tay ; to Y
jsr cexp ; call our function
lda CEXP_RAH ; read result (real part)
ldy CEXP_RAL
jsr numout ; output
ldx CEXP_RBH ; read result (imaginary part)
bmi noplus
lda #'+' ; output a `+` if it's not negative
jsr $ffd2
noplus: txa
ldy CEXP_RBL
jsr numout ; output (imaginary part)
lda #'i'
jsr $ffd2 ; output `i`
lda #$0d ; and newline
jmp $ffd2
numout:
jsr $b391 ; convert to floating point
jsr $bddd ; format floating point as string
ldy #$01
numout_loop: lda $ff,y ; output loop
bne numout_print ; until 0 terminator found
rts
numout_print: cmp #' ' ; skip space characters in output
beq numout_next
jsr $ffd2
numout_next: iny
bne numout_loop
ব্যবহার: sys49152,[a],[b],[c]
যেমন, sys49152,5,2,2
(আউটপুট 21+20i
:)