Advertisement
verz

Mattoni.asm

Jul 29th, 2019
1,384
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ;---------------------------------
  2.  
  3. ;   Mattoni v1.0
  4. ;      search for Euler Bricks with sides in the range 0..3000.
  5.  
  6. ;      the search is brute force: two nested loops of A and B try to verify
  7. ;       if C is integer when   C^ = A^2 + B^2
  8. ;       to speed up things, precomputes all squares in the range 0..3000;
  9. ;       compiles a list of all the TPs with short sides in the range 0..3000;
  10. ;       search the list of TPs for set of TPs forming an Euler Brick.
  11. ;       While printing the list, checks if a Brick is Primitive and prints it
  12. ;       otherwise no
  13.  
  14. ;---------------------------------
  15.  
  16.  
  17.  
  18. ;---------------------------------
  19. ; Basic Loader
  20. ; 10 SYS2061
  21.  
  22. *=$0801
  23.  
  24.         BYTE    $0B, $08, $0A, $00, $9E, $32, $30, $36, $31, $00, $00, $00
  25.  
  26. ;---------------------------------
  27.  
  28.  
  29.                 jmp Main
  30.  
  31.  
  32. ;---------------------------------Global Variables & definitions
  33.  
  34.  
  35.  
  36. _QU = 3000
  37. _QUI= _QU-1
  38. _timer = $A0     ;bytes 3
  39. _timSQR bytes 3
  40. _timTP bytes 3
  41. _timBR bytes 3
  42. _irqvec bytes 2
  43.  
  44. _CnvStr byte 0,0,0,0,0,0,0,0
  45. ScrBase = $0400
  46. ScrRow = $9b
  47.  
  48. _ArrTP = $2000
  49. _ArrSq = $7600
  50. _ArrBr = $c000
  51.  
  52. _pnt1 = $3
  53. _pnt2 = $5
  54. _bcd = $63
  55. _lobyte = $c8
  56. _mibyte = $c9
  57. _hibyte = $ca
  58.  
  59. _regY = $2a
  60.  
  61. _cnt1 = $a3
  62. _cnt2 = $a5
  63. _sqcnt1 = $a7
  64. _sqcnt2 = $aa
  65. _lpKvalA = $57
  66. _lpKvalB = $59
  67. _lpKvalC = $5b
  68. _pntBR = $5d                
  69. _pntSQ = $fb
  70. _pntTP = $fd
  71.  
  72. _square  = $57     ; 4 bytes: $5b-$5e; input value
  73. _sqrt    = $5F     ; 2 bytes: $5f-$60; result
  74. _remainder = _M+2  ; 2 bytes: $5d-$5e; is in fact the high bytes of _M
  75. _T       = $5B     ; 4 bytes: $57-$5a; could be 2 bytes: T+0 is always 0
  76. _M       = $57     ; 4 bytes: $5b-$5e, over the input _square
  77.  
  78. dividend = $57
  79. divisor  = $5a
  80. remainder = $5d
  81. pztemp    = $60
  82.  
  83. multiplier    = $61
  84. multiplicand  = $63
  85. product       = $57
  86.  
  87. bricks byte 0
  88.  
  89.  
  90. ;********************************************
  91. ;
  92. ;       CalcTP
  93. ;
  94. ;  descr: Cerca le TP con un doppio loop innestato (I,J); applicando Pitagora
  95. ;       verifica se il terzo lato è un numero intero: in quel caso è una TP
  96. ;       non calcola i quadrati, ma li recupera da quelli precalcolati
  97. ;       Il loop più interno (J) parte da I+1: non è necessario eseguire sia
  98. ;       IxJ che JxI; peraltro così ottengo una lista di TP ordinata secondo
  99. ;       il primo cateto (quello minore), e poi crescente anche per il secondo
  100. ;       cateto
  101. ;
  102.  
  103. CalcTP
  104.         lda #0
  105.         sta _cnt1
  106.         sta _cnt1+1
  107.  
  108.         lda #<_ArrSq
  109.         sta _sqcnt1
  110.         lda #>_ArrSq
  111.         sta _sqcnt1+1
  112.  
  113.         lda #<_ArrTP    ; <-- point to destination TP
  114.         sta _pntTP
  115.         lda #>_ArrTP
  116.         sta _pntTP+1
  117.  
  118. _lpI    inc _cnt1       ; cnt1 += 1; cnt2=cnt1
  119.         bne _incI
  120.         inc _cnt1+1
  121. _incI   lda _cnt1
  122.         sta _cnt2
  123.         lda _cnt1+1
  124.         sta _cnt2+1
  125.         clc
  126.         lda #3          ; puntatore ai quadrati: si muove di 3 in 3
  127.         adc _sqcnt1
  128.         sta _pntSQ
  129.         sta _sqcnt1
  130.         lda #0
  131.         adc _sqcnt1+1
  132.         sta _pntSQ+1
  133.         sta _sqcnt1+1
  134.  
  135.         ldy #0
  136.         lda (_pntSQ),y
  137.         sta _sqcnt2     ; load I^2
  138.         iny
  139.         lda (_pntSQ),y
  140.         sta _sqcnt2+1
  141.         iny
  142.         lda (_pntSQ),y
  143.         sta _sqcnt2+2
  144. _lpJ            inc _cnt2       ; loop J: increments "J"
  145.                 bne _incJ
  146.                 inc _cnt2+1
  147. _incJ           clc
  148.                 lda #3          ; increments pointer
  149.                 adc _pntSQ
  150.                 sta _pntSQ
  151.                 bcc _noinc
  152.                 inc _pntSQ+1
  153.                 clc
  154. _noinc          ldy #0
  155.                 sty _square+3   ; 24bit: squareHI=0
  156.                 lda (_pntSQ),y  ; J^2 + I^2
  157.                 adc _sqcnt2
  158.                 sta _square
  159.                 iny
  160.                 lda (_pntSQ),y
  161.                 adc _sqcnt2+1
  162.                 sta _square+1
  163.                 iny
  164.                 lda (_pntSQ),y
  165.                 adc _sqcnt2+2
  166.                 sta _square+2
  167.  
  168.                 jsr sqrt32
  169.  
  170.                 lda _remainder    ; verifica se il resto è 0 (cioè la radice è intera)
  171.                 ora _remainder+1
  172.                 bne _nxtTP
  173.                                 ; è una TP; salviamola
  174.                 ldy #0
  175.                 lda _cnt1
  176.                 sta (_pntTP),y
  177.                 iny
  178.                 lda _cnt1+1
  179.                 sta (_pntTP),y
  180.                 iny
  181.                 lda _cnt2
  182.                 sta (_pntTP),y
  183.                 iny
  184.                 lda _cnt2+1
  185.                 sta (_pntTP),y
  186.  
  187.                 clc             ; muove il puntatore in avanti per la prox TP
  188.                 lda #4
  189.                 adc _pntTP
  190.                 sta _pntTP
  191.                 bcc _nxtTP
  192.                 inc _pntTP+1
  193. _nxtTP
  194.                 lda _cnt2       ; verifica che il loop J non sia giunto alla fine
  195.                 cmp #<_QU
  196.                 lda _cnt2+1
  197.                 sbc #>_QU
  198.                 bcc _lpJ        
  199.         jsr PrintNum
  200.         lda _cnt1       ; verifica che il loop I non sia giunto alla fine
  201.         cmp #<_QUI
  202.         lda _cnt1+1
  203.         sbc #>_QUI
  204.         bcs _endctp
  205.         jmp _lpI
  206. _endctp
  207.         rts
  208.  
  209.  
  210.  
  211. align 64
  212. ;********************************************
  213. ;*    sqrt32
  214. ;*
  215. ;*   computes Sqrt of a 32bit number
  216. ;*
  217. ;*      input:  _square, the 4-byte source number
  218. ;*      output: _sqrt, 16bit value
  219. ;*              _remainder, 16bit value
  220. ;*
  221. ;* implements:
  222. ;*
  223. ;        R= 0
  224. ;        M= N
  225. ;        D= 2^(p-1)
  226. ;        for n= 1 to p
  227. ;        {
  228. ;            T= (R+R+D) ASL (p-1)
  229. ;            if (T <= M) then M=M-T: R=R+D
  230. ;            M= M ASL 1
  231. ;            D= D LSR 1
  232. ;        }
  233. ;   p: number of bits of the result
  234. ;
  235.  
  236. ;_tosq16
  237. ;        jmp sqrt16
  238.  
  239. sqrt32
  240. ;        lda _square+2
  241. ;        ora _square+3
  242. ;        beq _tosq16
  243.  
  244.         lda #0
  245.         sta _sqrt       ; R=0
  246.         sta _sqrt+1
  247.         sta _M+4        ; aka T+0
  248.         ;sta _T+1       ; T+1 is zero until last iteration; T+0 is always 0
  249.  
  250.         ldy #6         ; 7 iterations (6-->0)
  251. _loop6  
  252. ;        lda _sqrt  ; (2*R+D) LSR 1; actually: R+(D LSR 1)
  253. ;;        ora stablo,y  ;   [Dlo=0 during this iterations]
  254. ;        sta _T+2       ;   [sqrt+0 =0 during this iterations]
  255.         lda _sqrt+1    ; would be stabhi,y but changed the counter
  256.         ora stablo,y
  257.         sta _T+3
  258. ;;;;        bcs skip06          ;;;useless in this project
  259.        
  260.         lda _M+3
  261.         cmp _T+3
  262.         bcc skip16       ; T <= M    (branch if T>M)
  263. ;        bne skip06
  264. ;        lda _M+2
  265. ;        sbc _sqrt       ; T+2 = _sqrt =0 during this iterations
  266. ;        bcc skip16
  267. skip06   ;sec
  268. ;        lda _M+2        ; M=M-T
  269. ;;        sbc _T+2
  270. ;        sbc _sqrt      ; T+2=sqrt+0  =0 during this iterations
  271. ;        sta _M+2
  272.         lda _M+3
  273.         sbc _T+3
  274.         sta _M+3
  275. ;        lda _sqrt      ; R=R+D   ; stablo+1,y is zero during this iterations
  276. ;        ora stablo+1,y
  277. ;        sta _sqrt
  278.         lda _sqrt+1
  279.         ora stablo+1,y    ; would be stabhi,y but changed the counter
  280.         sta _sqrt+1
  281. skip16
  282.         asl _M          ; M=M*2
  283.         rol _M+1
  284.         rol _M+2
  285.         rol _M+3
  286.         dey             ; implicit: D=D/2, by the move of .Y
  287.         bpl _loop6
  288.  
  289.                         ; 8th iteration
  290. _loop8  
  291. ;        lda #$80  ; (2*R+D) LSR 1; actually: R+(D LSR 1)
  292. ;        ora _sqrt       ; _sqrt = 0
  293. ;        sta _T+2
  294. ;        lda _sqrt+1          ; stabhi,y = 0 during this iterations
  295. ;        sta _T+3
  296. ;;;;        bcs skip08          ;;;useless in this project
  297.        
  298.         lda _M+3
  299.         cmp _sqrt+1     ; T+3=_sqrt+1
  300.         bcc skip18      ; T <= M    (branch if T>M)
  301.         bne skip08
  302.         lda _M+2
  303.         sbc #$80        ; T+2=$80
  304.         bcc skip18
  305. skip08   ;sec
  306.         lda _M+2        ; M=M-T
  307.         sbc #$80        ; T+2=$80
  308.         sta _M+2
  309.         lda _M+3
  310.         sbc _sqrt+1     ; T+3=_sqrt+1
  311.         sta _M+3
  312. ;        lda _sqrt      ; R=R+D
  313. ;        ora stablo+1,y         ; stablo+1,y =0 during this iteration
  314. ;        sta _sqrt
  315. ;        lda _sqrt+1
  316. ;        ora #1
  317. ;        sta _sqrt+1
  318.         inc _sqrt+1
  319. skip18
  320.         asl _M          ; M=M*2
  321.         rol _M+1
  322.         rol _M+2
  323.         rol _M+3
  324.  
  325.         ldy #6         ; 7 iterations (6-->0)
  326. _loop9  
  327.         lda stablo,y  ; (2*R+D) LSR 1; actually: R+(D LSR 1)
  328.         ora _sqrt
  329.         sta _T+2
  330. ;        lda _sqrt+1     ; stabhi,y = 0 during this iterations
  331. ;        sta _T+3
  332. ;;;;        bcs skip09          ;;;useless in this project
  333.        
  334.         lda _M+3
  335.         cmp _sqrt+1     ; T+3=_sqrt+1
  336.         bcc skip19      ; T <= M    (branch if T>M)
  337.         bne skip09
  338.         lda _M+2
  339.         sbc _T+2
  340.         bcc skip19
  341. skip09   ;sec
  342.         lda _M+2        ; M=M-T
  343.         sbc _T+2
  344.         sta _M+2
  345.         lda _M+3
  346.         sbc _sqrt+1     ; T+3=_sqrt+1
  347.         sta _M+3
  348.         lda _sqrt       ; R=R+D
  349.         ora stablo+1,y
  350.         sta _sqrt
  351. ;        lda _sqrt+1
  352. ;        adc #0          ; stabhi+1,y =0 during this iterations
  353. ;        sta _sqrt+1
  354. ;        lda _M          ; _M+0=0 during this iterations
  355. ;        lda _M+1
  356. ;        ora _M+2
  357. ;        ora _M+3
  358. ;        beq _sqrend     ; if M=0 then exit
  359. skip19
  360. ;        asl _M          ; M=M*2
  361. ;        rol _M+1        ; _M+0 =0 during this iterations
  362.         asl _M+1
  363.         rol _M+2
  364.         rol _M+3
  365.         dey             ; implicit: D=D/2, by the move of .Y
  366.         bpl _loop9
  367.  
  368. _lastiter               ; code for last iteration
  369.         ; during last iteration D=1, so (2*R+D) LSR 1 makes D the MSB of T+1
  370. ;;;;        bcs skp0          ;;;useless in this project
  371.  
  372.         lda _M+3
  373.         cmp _sqrt+1    ; T+3 = _sqrt+1
  374.         bcc skp1       ; T <= M    branch if T>M
  375.         bne skp0
  376.         lda _M+2
  377.         cmp _sqrt      ; T+2 = _sqrt
  378.         bcc skp1
  379.         bne skp0
  380.         lda _M+1
  381.         cmp #$80        ; T+1 = $80
  382.         bcc skp1
  383. skp0    ;sec
  384.         lda _M+1
  385.         sbc #$80        ; T+1 = $80
  386.         sta _M+1
  387.         lda _M+2        ; M=M-T
  388.         sbc _sqrt
  389.         sta _M+2
  390.         lda _M+3
  391.         sbc _sqrt+1
  392.         sta _M+3
  393.         inc _sqrt      ; R=R+D with D=1
  394. skp1    ;asl _M          ; M=M*2
  395.         asl _M+1
  396.         rol _M+2
  397.         rol _M+3
  398.         rol _M+4
  399. _sqrend rts
  400.  
  401. ;stabhi byte 0,0,0,0,0,0,0,0
  402. stablo BYTE $01,$02,$04,$08,$10,$20,$40,$80
  403. ;       byte 0,0,0,0,0,0,0,0
  404.  
  405.  
  406.  
  407. ;;********************************************
  408. ;MyTimer
  409. ;        inc _timer
  410. ;        bne _go2irq
  411. ;        inc _timer+1
  412. ;        bne _go2irq
  413. ;        inc _timer+2
  414. ;_go2irq
  415. ;        jmp (_irqvec)
  416.  
  417.  
  418. ;********************************************
  419. ;
  420. ;       Main
  421. ;
  422. ; descr: richiama i quattro blocchi di elaborazione:
  423. ;                - Calcolo dei Quadrati
  424. ;                - Calcolo delle TP
  425. ;                - Ricerca dei mattoni
  426. ;                - Stampa della lista dei mattoni
  427. ;
  428.  
  429. Main
  430.         lda #0
  431.         sta _timer
  432.         sta _timer+1
  433.         sta _timer+2
  434.  
  435. ;        sei
  436. ;        lda $314        
  437. ;        sta _irqvec
  438. ;        lda $315
  439. ;        sta _irqvec+1
  440.  
  441. ;        lda #<MyTimer
  442. ;        sta $314
  443. ;        lda #>MyTimer
  444. ;        sta $315
  445. ;        cli
  446.  
  447.         lda #$20
  448.         jsr ClearScreen
  449.        
  450.         ldx #3
  451.         ldy #3
  452.         jsr SetCurs
  453.         lda #<_qdr
  454.         ldx #>_qdr
  455.         jsr PrintAt
  456.         lda #<_QU
  457.         sta _lobyte
  458.         lda #>_QU
  459.         sta _hibyte
  460.         jsr _ItoA
  461.         lda #<_CnvStr
  462.         ldx #>_CnvStr
  463.         jsr ChainPrint
  464.                 jsr CalcQuad      ; calcola la tabella dei quadrati (24bit)
  465.         lda _timer+2
  466.         sta _timSQR
  467.         lda _timer+1
  468.         sta _timSQR+1
  469.         lda _timer+0
  470.         sta _timSQR+2
  471.         ldx #10
  472.         ldy #4
  473.         jsr SetCurs
  474.         jsr PrintTime
  475.  
  476.  
  477.         ldx #3
  478.         ldy #6
  479.         jsr SetCurs
  480.         lda #<_ctp
  481.         ldx #>_ctp
  482.         jsr PrintAt
  483.                 jsr CalcTP        ; calcola le terne pitagoriche (2x 16bit)
  484.         lda _timer+1
  485.         sta _timTP
  486.         lda _timer+1
  487.         sta _timTP+1
  488.         lda _timer+0
  489.         sta _timTP+2
  490.         ldx #10
  491.         stx $d3
  492.         ldy #7
  493.         sty $d6
  494.         jsr SetCurs
  495.         jsr PrintTime
  496.  
  497.  
  498.         ldx #3
  499.         ldy #9
  500.         jsr SetCurs
  501.         lda #<_brk
  502.         ldx #>_brk
  503.         jsr PrintAt
  504.                 jsr SearchBricks  ; cerca i mattoni nelle terne e produce lista (3x 16bit)
  505.         lda _timer+2
  506.         sta _timBR
  507.         lda _timer+1
  508.         sta _timBR+1
  509.         lda _timer+0
  510.         sta _timBR+2
  511.         ldx #10
  512.         ldy #10
  513.         jsr SetCurs
  514.         jsr PrintTime
  515.  
  516. ;        sei
  517. ;        lda _irqvec
  518. ;        sta $314
  519. ;        lda _irqvec+1
  520. ;        sta $315
  521. ;        cli
  522.  
  523.                 jsr PrintBricks   ; Stampa la lista dei mattoni
  524.  
  525.         rts
  526.  
  527. _qdr byte 'calcolo dei quadrati:', 0
  528. _ctp byte 'calcolo delle terne: ', 0
  529. _brk byte 'ricerca dei mattoni:     0', 0
  530. _tot byte '  tempo totale:   ', 0
  531. _sec byte ' sec',0
  532.  
  533.  
  534.  
  535.  
  536.  
  537. ;********************************************
  538. ;
  539. ;       SearchBricks
  540. ;
  541. ; descr: ricerca i mattoni all'interno della lista delle TP
  542. ;       La lista delle TP è costituita da coppie ordinate (A,B), dove B>A e
  543. ;       l'elemento successivo della lista è tale che An+1 >= An e Bn+1 > Bn:
  544. ;       la lista è ordinata.
  545. ;       Sono tre loop innestati: nel più esterno scorro la lista
  546. ;       elemento per elemento: cerco in avanti (secondo loop) un'altra TP
  547. ;       che abbia lo stesso primo termine; ho quindi un termine B1 proveniente
  548. ;       dalla prima TP e un termine B2 proveniente dalla seconda; B1 < B2.
  549. ;       Cerco in avanti (terzo loop) una TP con B1 al primo termine e B2 al
  550. ;       secondo. Se la trovo, questo è un mattone
  551.  
  552. align 64
  553. _toNextI
  554.         jmp _nextI
  555. SearchBricks
  556.         ldx #0
  557.         stx bricks
  558.  
  559.         lda #<_ArrBr    ; puntatore alla lista dei mattoni trovati
  560.         sta _pntBR
  561.         lda #>_ArrBr
  562.         sta _pntBR+1
  563.  
  564.         lda #<_ArrTP    ; puntatore alla lista delle TP
  565.         sta _cnt1
  566.         sta _cnt2
  567.         lda #>_ArrTP
  568.         sta _cnt1+1
  569.         sta _cnt2+1
  570.  
  571.         ; I loop
  572. _reI    ldy #0          ; for i=0 to _pntTP-1
  573.         lda (_cnt1),y
  574.         sta _lpKvalA
  575.         iny
  576.         lda (_cnt1),y
  577.         sta _lpKvalA+1
  578.  
  579.                 ; J loop
  580. _reJ            lda _cnt2        ; for j=i+1 to _pntTP-1
  581.                 clc
  582.                 adc #4
  583.                 sta _cnt2
  584.                 bcc _noJHiInc
  585.                 inc _cnt2+1
  586.  
  587. _noJHiInc       lda _pntTP+1     ; verifica se siamo oltre la fine
  588.                 cmp _cnt2+1
  589.                 bcc _nextI     ; J > fine
  590.                 bne _tryJ
  591.                 lda _pntTP
  592.                 cmp _cnt2
  593.                 bcc _nextI     ; J > fine
  594.  
  595. _tryJ           ldy #0          ; .Y=0
  596.                 lda _lpKvalA
  597.                 cmp (_cnt2),y   ; gli elementi successivi con primo termine uguale
  598.                 bne _nextI      ; saranno vicini: se il termine è diverso => loop esterno
  599.                 iny             ; .Y=1
  600.                 lda _lpKvalA+1
  601.                 cmp (_cnt2),y
  602.                 bne _nextI
  603.  
  604.                         ; K loop                ; for k=j+1 to _pntTP-1
  605.                         iny             ; .Y=2
  606.                         lda (_cnt1),y
  607.                         sta _lpKvalB
  608.                         lda (_cnt2),y
  609.                         sta _lpKvalC
  610.                         iny             ; .Y=3
  611.                         lda (_cnt1),y
  612.                         sta _lpKvalB+1
  613.                         lda (_cnt2),y
  614.                         sta _lpKvalC+1
  615.  
  616.                         lda _cnt2
  617.                         clc
  618.                         adc #4
  619.                         sta _sqcnt1
  620.                         lda _cnt2+1
  621.                         adc #0
  622.                         sta _sqcnt1+1
  623.  
  624. _reK                    ldy #1          ; .Y=1
  625.                         lda _lpKvalB+1
  626.                         cmp (_sqcnt1),y
  627.                         bcc _reJ          ;se mHI(k1)>mHI(i2)  => prox J
  628.                         bne _nextK        ;se mHI(k1)!=mHI(i2) => m(k1)<m(i2) => prox K
  629.                         dey             ; .Y=0
  630.                         lda _lpKvalB
  631.                         cmp (_sqcnt1),y
  632.                         bcc _reJ          ;se mLO(k1)>mLO(i2)  => prox J
  633.                         bne _nextK        ;se mLO(k1)!=mLO(i2) => m(k1)<m(i2) => prox K
  634.                        
  635.                         ; m(k1)=m(i2); vediamo se m(k2)=m(j2)
  636.                         ldy #3          ; .Y=3
  637.                         lda _lpKvalC+1
  638.                         cmp (_sqcnt1),y
  639.                         bcc _reJ          ;se mHI(k2)>mHI(j2)  => prox J
  640.                         bne _nextK        ;se mHI(k2)!=mHI(j2) => m(k2)<m(j2) => prox K
  641.                         dey             ; .Y=2
  642.                         lda _lpKvalC
  643.                         cmp (_sqcnt1),y
  644.                         bcc _reJ          ;se mLO(k2)>mLO(j2)  => prox J
  645.                         ;bne _nextK        ;se mLO(k2)!=mLO(j2) => m(k2)<m(j2) => prox K
  646.                         beq _found
  647.                         ;jmp _found
  648.  
  649. _nextK                  clc             ; punta alla prox TP
  650.                         lda _sqcnt1
  651.                         adc #4
  652.                         sta _sqcnt1
  653.                         bcc _noKHiInc
  654.                         inc _sqcnt1+1
  655.  
  656. _noKHiInc               lda _pntTP+1    ; verifica che non siamo alla fine
  657.                         cmp _sqcnt1+1
  658.                         bcc _nextJ     ; K > fine
  659.                         bne _reK
  660.                         lda _pntTP
  661.                         cmp _sqcnt1
  662.                         bcc _nextJ     ; K > fine
  663.                         bne _reK
  664.                         ;jmp _reK
  665.  
  666. _nextJ          jmp _reJ
  667.  
  668. _nextI  clc
  669.         lda _cnt1       ; si sposta alla prox TP
  670.         adc #4
  671.         sta _cnt1
  672.         sta _cnt2
  673.         lda _cnt1+1
  674.         adc #0
  675.         sta _cnt1+1
  676.         sta _cnt2+1
  677.  
  678.         lda _pntTP+1    ; verifica che non siamo alla fine
  679.         cmp _cnt1+1
  680.         bcc _endloop
  681.         bne _toreI
  682.         lda _pntTP
  683.         cmp _cnt1
  684.         bcc _endloop
  685.         beq _endloop
  686. _toreI  jmp _reI
  687. _endloop
  688.         ldx bricks
  689.         stx _lobyte
  690.         ldx #0
  691.         stx _hibyte
  692.         jsr _ItoA
  693.         ldx #24
  694.         ldy #9
  695.         jsr SetCurs
  696.         lda #<_CnvStr
  697.         ldx #>_CnvStr
  698.         jmp PrintAt
  699.  
  700. _found                  ; trovato! m(k1)=m(i2) e m(k2)=m(j2)
  701.                         inc bricks      ; aumenta il contatore
  702.                         ldx bricks
  703.                         stx _lobyte     ; stampa il numero di mattoni trovati
  704.                         ldx #0
  705.                         stx _hibyte
  706.                         ldx #24
  707.                         ldy #9
  708.                         jsr SetCurs
  709.                         jsr _ItoA
  710.                         lda #<_CnvStr
  711.                         ldx #>_CnvStr
  712.                         jsr PrintAt
  713.  
  714.                         ldy #0          ; salva i 3 valori e la loro somma
  715.                         lda _lpKvalA
  716.                         sta (_pntBR),y
  717.                         iny             ; .Y=1
  718.                         lda _lpKvalA+1
  719.                         sta (_pntBR),y
  720.                         iny             ; .Y=2
  721.                         lda _lpKvalB
  722.                         sta (_pntBR),y
  723.                         iny             ; .Y=3
  724.                         lda _lpKvalB+1
  725.                         sta (_pntBR),y
  726.                         iny             ; .Y=4
  727.                         clc
  728.                         lda _lpKvalC
  729.                         sta (_pntBR),y
  730.                         adc _lpKvalA               ; Alo + Clo
  731.                         sta _lpKvalC
  732.                         iny             ; .Y=5
  733.                         lda _lpKvalC+1
  734.                         sta (_pntBR),y
  735.                         adc _lpKvalA+1             ; Ahi + Chi
  736.                         sta _lpKvalC+1
  737.                         iny             ; .Y=6
  738.                         clc
  739.                         lda _lpKvalC
  740.                         adc _lpKvalB               ; Alo + Blo + Clo
  741.                         sta (_pntBR),y
  742.                         iny             ; .Y=7
  743.                         lda _lpKvalC+1
  744.                         adc _lpKvalB+1             ; Ahi + Bhi + Chi
  745.                         sta (_pntBR),y
  746.                         clc
  747.                         lda #8
  748.                         adc _pntBR
  749.                         sta _pntBR
  750.                         bcc _tonextJ
  751.                         inc _pntBR+1
  752. _tonextJ                jmp _reJ
  753.                         ;jmp _aftfound
  754.  
  755.  
  756. ;********************************************
  757. ;
  758. ;       CalcQuad
  759. ;
  760. ; descr: calcola i quadrati dei numeri 0-3000, e li mette in una lista
  761. ;       vengono salvati solo 3 bytes (24 bit) perché sufficienti
  762. ;
  763.  
  764. CalcQuad
  765.         lda #>_ArrSq
  766.         sta _pntSQ+1
  767.         lda #<_ArrSq+3
  768.         sta _pntSQ
  769.  
  770.         ldx #0
  771.         stx _cnt1
  772.         stx _cnt1+1
  773.  
  774. _lp     inc _cnt1       ; cnt1 += 1
  775.         bne _next
  776.         inc _cnt1+1
  777.  
  778. _next   lda _cnt1       ; prepara la moltiplicazione del numero per sé stesso
  779.         sta multiplier
  780.         sta multiplicand
  781.         lda _cnt1+1
  782.         sta multiplier+1
  783.         sta multiplicand+1
  784.        
  785.         jsr mult16      ; richiama la moltiplicazione
  786.        
  787.         ldy #0          ; salva il prodotto nella lista (solo 3 byte)
  788.         lda product
  789.         sta (_pntSQ),y
  790.         iny
  791.         lda product+1
  792.         sta (_pntSQ),y
  793.         iny
  794.         lda product+2
  795.         sta (_pntSQ),y
  796.  
  797.         clc
  798.         lda #3          ; sposta il puntatore
  799.         adc _pntSQ
  800.         sta _pntSQ
  801.         bcc _prx
  802.         inc _pntSQ+1
  803.  
  804. _prx    lda _cnt1       ; verifica che non sia alla fine
  805.         cmp #<_QU
  806.         lda _cnt1+1
  807.         sbc #>_QU
  808.         bcc _lp
  809.         rts
  810.  
  811.  
  812. ;********************************************
  813. PrintNum
  814.         ldy #6
  815.         ldx #24
  816.         jsr SetCurs
  817.  
  818.         lda _cnt1
  819.         sta _lobyte
  820.         lda _cnt1+1    
  821.         sta _hibyte
  822.         jsr _ItoA
  823.         lda #<_CnvStr
  824.         ldx #>_CnvStr
  825.         jmp PrintAt
  826.  
  827.  
  828.  
  829. ;********************************************
  830. WaitForSpace            ;thanx to Phaze101
  831.         lda     #$7f    ;%01111111 - only row 7 KB matrix
  832.         sta     $dc00
  833.         lda     $dc01
  834.         and     #$10    ;mask %00010000
  835.         bne     WaitForSpace
  836.         rts
  837.  
  838. _waitkey byte 'premere spazio per la lista',0
  839.  
  840.  
  841.  
  842. ;********************************************
  843. ;
  844. ;       PrintBricks
  845. ;
  846. ; descr: stampa la lista dei mattoni trovati. Stampa solo i mattoni primitivi.
  847. ;       E' hackerata un po' brutalmente in maniera da saltare i mattoni
  848. ;       non primitivi, come richiesto dal challenge
  849. ;
  850.  
  851. PrintBricks
  852.         ldy #20
  853.         ldx #8
  854.         jsr SetCurs
  855.         lda #<_waitkey
  856.         ldx #>_waitkey
  857.         jsr PrintAt
  858.  
  859.         jsr WaitForSpace  
  860.         lda #$20
  861.         jsr ClearScreen
  862.  
  863.         lda #<_ArrBr
  864.         sta _cnt1
  865.         lda #>_ArrBr
  866.         sta _cnt1+1
  867.  
  868.         lda bricks
  869.         lsr
  870.         sta _cnt2+1
  871.         lda #0
  872.         sta _cnt2
  873.  
  874.  
  875.         sta _regY
  876.  
  877.         lda #10
  878.         sta _cnt2+1
  879.  
  880. _loop1clmn        
  881.                 jsr CheckIfP
  882.                 lda _PoD
  883.                 bne _1np
  884.  
  885.                 ldy _cnt2
  886.                 iny
  887.                 iny
  888.                 ldx #2
  889.                 jsr SetCurs
  890.                 ldy #0
  891.                 lda (_cnt1),y
  892.                 sta _lobyte
  893.                 iny
  894.                 lda (_cnt1),y
  895.                 sta _hibyte
  896.                 iny
  897.                 sty _regY
  898.                 jsr _ItoA       ; conversion
  899.                 ldx #>_CnvStr
  900.                 lda #<_CnvStr
  901.                 jsr PrintAt     ; print
  902.        
  903.                 ldy _regY
  904.                 lda (_cnt1),y
  905.                 sta _lobyte
  906.                 iny
  907.                 lda (_cnt1),y
  908.                 sta _hibyte
  909.                 iny
  910.                 sty _regY
  911.                 jsr _ItoA       ; conversion
  912.                 ldx #>_CnvStr
  913.                 lda #<_CnvStr
  914.                 jsr ChainPrint     ; print
  915.  
  916.                 ldy _regY
  917.                 lda (_cnt1),y
  918.                 sta _lobyte
  919.                 iny
  920.                 lda (_cnt1),y
  921.                 sta _hibyte
  922.                 iny
  923.                 sty _regY
  924.                 jsr _ItoA       ; conversion
  925.                 ldx #>_CnvStr
  926.                 lda #<_CnvStr
  927.                 jsr ChainPrint     ; print
  928.  
  929.                 ldx #>_BrPR
  930.                 lda #<_BrPR
  931.                 jsr ChainPrint              
  932.        
  933. _1np            clc
  934.                 lda #8
  935.                 adc _cnt1
  936.                 sta _cnt1
  937.                 lda _cnt1+1
  938.                 adc #0
  939.                 sta _cnt1+1
  940.                 lda _PoD
  941.                 bne _loop1clmn
  942.  
  943.                 ldx _cnt2
  944.                 inx
  945.                 stx _cnt2
  946.                 cpx _cnt2+1
  947.                 bne _loop1clmn
  948.                
  949.                 jmp _ep
  950.  
  951.                 sec
  952.                 lda bricks
  953.                 sbc _cnt2+1
  954.                 sta _cnt2+1
  955.                 lda #0
  956.                 sta _cnt2
  957.  
  958. _loop2clmn
  959.                 jsr CheckIfP
  960.                 ldy _cnt2
  961.                 iny
  962.                 iny
  963.                 ldx #22
  964.                 jsr SetCurs
  965.                 ldy #0
  966.                 lda (_cnt1),y
  967.                 sta _lobyte
  968.                 iny
  969.                 lda (_cnt1),y
  970.                 sta _hibyte
  971.                 iny
  972.                 sty _regY
  973.                 jsr _ItoA       ; conversion
  974.                 ldx #>_CnvStr
  975.                 lda #<_CnvStr
  976.                 jsr PrintAt     ; print
  977.                
  978.                 ldy _regY
  979.                 lda (_cnt1),y
  980.                 sta _lobyte
  981.                 iny
  982.                 lda (_cnt1),y
  983.                 sta _hibyte
  984.                 iny
  985.                 sty _regY
  986.                 jsr _ItoA       ; conversion
  987.                 ldx #>_CnvStr
  988.                 lda #<_CnvStr
  989.                 jsr ChainPrint     ; print
  990.  
  991.                 ldy _regY
  992.                 lda (_cnt1),y
  993.                 sta _lobyte
  994.                 iny
  995.                 lda (_cnt1),y
  996.                 sta _hibyte
  997.                 iny
  998.                 sty _regY
  999.                 jsr _ItoA       ; conversion
  1000.                 ldx #>_CnvStr
  1001.                 lda #<_CnvStr
  1002.                 jsr ChainPrint     ; print
  1003.  
  1004.                 lda _PoD
  1005.                 bne _2np
  1006.                 ldx #>_BrPR
  1007.                 lda #<_BrPR
  1008.                 jsr ChainPrint              
  1009.  
  1010. _2np            clc
  1011.                 lda #8
  1012.                 adc _cnt1
  1013.                 sta _cnt1
  1014.                 lda _cnt1+1
  1015.                 adc #0
  1016.                 sta _cnt1+1
  1017.  
  1018.                 ldx _cnt2
  1019.                 inx
  1020.                 stx _cnt2
  1021.                 cpx _cnt2+1
  1022.                 bne _loop2clmn
  1023.  
  1024. _ep     ldx #3
  1025.         ldy #23
  1026.         jsr SetCurs
  1027.         lda #<_elab
  1028.         ldx #>_elab
  1029.         jsr PrintAt
  1030.         ldx #26
  1031.         ldy #23
  1032.         jsr SetCurs
  1033.  
  1034.  
  1035.         lda _timBR
  1036.         sta _timer+2
  1037.         lda _timBR+1
  1038.         sta _timer+1
  1039.         lda _timBR+2
  1040.         sta _timer
  1041.         jsr PrintTime
  1042.  
  1043.         jsr WaitForSpace            
  1044.  
  1045.         rts
  1046. _BrPR byte ' p',0
  1047. _BrDR byte ' d',0
  1048. _elab byte 'Tempo di elaborazione: ',0
  1049.  
  1050.  
  1051.  
  1052. ;********************************************
  1053. ;
  1054. ;       CheckIFP
  1055. ;
  1056. ; descr: controlla se il mattone corrente è primitivo: cerca all'indietro
  1057. ;       nella lista dei mattoni, dividendo la somma dei termini per la somma
  1058. ;       dei termini dei mattoni precedenti: se il resto della divisione è 0
  1059. ;       allora il mattone non è primitivo
  1060. ;
  1061. _PoD   byte 0
  1062. CheckIfP
  1063.         lda #0  
  1064.         sta _PoD
  1065.         lda _cnt1
  1066.         sta _sqcnt1
  1067.         lda _cnt1+1
  1068.         sta _sqcnt1+1
  1069.  
  1070. _lpSrchDer
  1071.         sec
  1072.         lda _sqcnt1
  1073.         sbc #8
  1074.         sta _sqcnt1
  1075.         lda _sqcnt1+1
  1076.         sbc #0
  1077.         sta _sqcnt1+1
  1078.         cmp #>_ArrBr
  1079.         bcc _endsearch
  1080.         bne _dotest
  1081.         lda _sqcnt1
  1082.         cmp #<_ArrBr
  1083.         bcc _endsearch
  1084. _dotest ldy #6
  1085.         lda (_cnt1),y
  1086.         sta dividend
  1087.         lda (_sqcnt1),y
  1088.         sta divisor
  1089.         iny
  1090.         lda (_cnt1),y
  1091.         sta dividend+1
  1092.         lda (_sqcnt1),y
  1093.         sta divisor+1
  1094.         lda #0
  1095.         sta dividend+2
  1096.         jsr div24
  1097.         lda remainder
  1098.         ora remainder+1
  1099.         bne _lpSrchDer
  1100.  
  1101.         dec _PoD
  1102. _endsearch
  1103.         rts
  1104.  
  1105.  
  1106.  
  1107. ;--------------------------------------
  1108. ; Call with
  1109. ; .X = value of horizontal pos
  1110. ; .Y = value of vertical pos
  1111. ;
  1112. ; thanx to Phaze101
  1113. ;--------------------------------------
  1114.  
  1115. SetCurs
  1116.         lda #0
  1117.         sta _pnt1
  1118.         sta _pnt1+1
  1119.         cpy #0                 ;first line: no need to add rows
  1120.         beq AddColumn-1
  1121.  
  1122.         clc
  1123. CalcRow
  1124.         tya             ;2                max(Y)=25
  1125.         asl             ;2   A= Y x 2
  1126.         asl             ;2   A= Y x 4
  1127.         sty _pnt1-1     ;3      
  1128.         adc _pnt1-1     ;3   A= Y x 5
  1129.         asl             ;2   A= Y x 10 (still contained in one byte)
  1130.         asl             ;2   A= Y x 20 (now needs two bytes)
  1131.         rol _pnt1+1     ;5    flows on high byte
  1132.         asl             ;2   A= Y x 40
  1133.         rol _pnt1+1     ;5    flows on high byte
  1134.         sta _pnt1       ;3   stores on low byte
  1135.  
  1136. AddColumn
  1137.         clc
  1138.         txa    
  1139.         adc     _pnt1
  1140.         sta     _pnt1
  1141.         bcc AddScrBase
  1142.         inc     _pnt1+1
  1143.  
  1144.         clc                     ;Add position to base address
  1145. AddScrBase
  1146.         ;lda     _pnt1
  1147.         adc     #<ScrBase
  1148.         sta     _pnt2
  1149.         lda     #>ScrBase
  1150.         adc     _pnt1+1
  1151.         sta     _pnt2+1
  1152.  
  1153.         rts
  1154.  
  1155. ;-------------------------------
  1156. ; Converts a 16bit number in BCD
  1157. ;-------------------------------
  1158. _ItoA
  1159. ;        lda #0
  1160. ;        sta _CnvStr
  1161. ;        sta _CnvStr+1
  1162. ;        sta _CnvStr+2
  1163. ;        sta _CnvStr+3
  1164. ;        sta _CnvStr+4
  1165. ;        sta _CnvStr+5
  1166.  
  1167.  
  1168. BINBCD16        SED             ; Switch to decimal mode
  1169.                 LDA #0          ; Ensure the result is clear
  1170.                 STA _bcd+0
  1171.                 STA _bcd+1
  1172.                 STA _bcd+2
  1173.                 LDX #16         ; The number of source bits
  1174. CNVBIT          ASL _lobyte     ; Shift out one bit
  1175.                 ROL _hibyte
  1176.                 LDA _bcd+0      ; And add into result
  1177.                 ADC _bcd+0
  1178.                 STA _bcd+0
  1179.                 LDA _bcd+1      ; propagating any carry
  1180.                 ADC _bcd+1
  1181.                 STA _bcd+1
  1182.                 LDA _bcd+2      ; ... thru whole result
  1183.                 ADC _bcd+2
  1184.                 STA _bcd+2
  1185.                 DEX             ; And repeat for next bit
  1186.                 BNE CNVBIT
  1187.                 CLD             ; Back to binary
  1188.                
  1189.                 ;rts             ; All Done.
  1190.  
  1191.  
  1192. ;-------------------------------
  1193. ; Converts a 16bit unsigned number into string
  1194. ;-------------------------------
  1195. ;_ItoA
  1196.         ;jsr BinBcd16
  1197.         ;lda _bcd+2
  1198.         and #$0f
  1199.         ora #$30
  1200.         sta _CnvStr+0
  1201.  
  1202.         lda _bcd+1
  1203.         and #$0f
  1204.         ora #$30
  1205.         sta _CnvStr+2
  1206.         lda _bcd+1
  1207.         lsr
  1208.         lsr
  1209.         lsr
  1210.         lsr
  1211.         ora #$30
  1212.         sta _CnvStr+1
  1213.  
  1214.         lda _bcd+0
  1215.         and #$0f
  1216.         ora #$30
  1217.         sta _CnvStr+4
  1218.         lda _bcd+0
  1219.         lsr
  1220.         lsr
  1221.         lsr
  1222.         lsr
  1223.         ora #$30
  1224.         sta _CnvStr+3
  1225.         lda #0  
  1226.         sta _CnvStr+5
  1227. ;        rts                    ; uncomment to avoid stripping leading 0s
  1228.  
  1229.         ldx #0                  ;remove 0s at beginning
  1230.         stx _CnvStr+6
  1231. _rem0   lda _CnvStr,x
  1232.         cmp #$30
  1233.         bne _rts
  1234.         lda #$20                ;put a space instead
  1235.         sta _CnvStr,x
  1236.         inx
  1237.         cpx #$5
  1238.         bne _rem0
  1239.  
  1240. _rts    rts
  1241.  
  1242.  
  1243.  
  1244. ;--------------------------------------
  1245. ; PrintAt, ChainPrint
  1246. ; Call with
  1247. ; .A = low  byte of the string
  1248. ; .X = high byte of the string
  1249. ;
  1250. ; thanx to Phaze101
  1251. ;--------------------------------------
  1252. PrintAt
  1253.         ldy #$0
  1254.         sta _pnt1
  1255.         stx _pnt1+1
  1256.         jmp _ln
  1257. _PrtLoop
  1258.         sta (_pnt2),y          
  1259.         iny
  1260. _ln     lda (_pnt1),y
  1261.         bne _PrtLoop
  1262.  
  1263.         sty _PAdisp
  1264.         rts
  1265.  
  1266. _PAdisp   byte 0
  1267.  
  1268. ChainPrint
  1269.         sta _pnt1
  1270.         stx _pnt1+1
  1271.         lda _PAdisp
  1272.         ldy #0
  1273.         clc
  1274.         adc _pnt2
  1275.         sta _pnt2
  1276.         bcc _ln
  1277.         inc _pnt2+1
  1278.         bcs _ln
  1279.  
  1280.  
  1281.  
  1282. ;--------------------------------------
  1283. ; Call with
  1284. ; .A = value of the character to use to fill the screen
  1285. ;
  1286. ; thanx to Phaze101
  1287. ;--------------------------------------
  1288. ClearScreen    ldx #+124 ; init index
  1289. ClrLoop        sta ScrBase,x
  1290.                sta ScrBase+125,x
  1291.                sta ScrBase+250,x
  1292.                sta ScrBase+375,x
  1293.                sta ScrBase+500,x
  1294.                sta ScrBase+625,x
  1295.                sta ScrBase+750,x
  1296.                sta ScrBase+875,x
  1297.                dex
  1298.                bpl ClrLoop
  1299.                rts
  1300.  
  1301.  
  1302.  
  1303.  
  1304. ;********************************************
  1305. mult16
  1306.         lda     #$00
  1307.         sta     product+2       ; clear upper bits of product
  1308.         sta     product+3
  1309.         ldx     #$10            ; set binary count to 16
  1310. sh_r    lsr     multiplier+1    ; divide multiplier by 2
  1311.         ror     multiplier
  1312.         bcc     rot_r
  1313.         clc
  1314.         lda     product+2       ; get upper half of product and add multiplicand
  1315.         adc     multiplicand
  1316.         sta     product+2
  1317.         lda     product+3
  1318.         adc     multiplicand+1
  1319. rot_r   ror                     ; rotate partial product
  1320.         sta     product+3
  1321.         ror     product+2
  1322.         ror     product+1
  1323.         ror     product
  1324.         dex
  1325.         bne     sh_r
  1326.         rts
  1327.  
  1328.  
  1329.  
  1330. ;********************************************
  1331. PrintTime
  1332.         lda _timer+2
  1333.         sta dividend
  1334.         lda _timer+1
  1335.         sta dividend+1
  1336.         lda _timer+0
  1337.         sta dividend+2
  1338.         lda #60
  1339.         sta divisor
  1340.         lda #0
  1341.         sta divisor+1
  1342.         sta divisor+2
  1343.         jsr div24
  1344.         lda dividend
  1345.         sta _lobyte
  1346.         lda dividend+1
  1347.         sta _hibyte
  1348. ;        lda dividend+2
  1349. ;        sta _hibyte
  1350.         jsr _ItoA
  1351.         lda #<_CnvStr
  1352.         ldx #>_CnvStr
  1353.         jsr PrintAt
  1354.         lda #<_sec
  1355.         ldx #>_sec
  1356.         jmp ChainPrint
  1357.  
  1358.  
  1359. align 63
  1360. ;********************************************
  1361. div24   lda #0          ;preset remainder to 0
  1362.         sta remainder
  1363.         sta remainder+1
  1364.         sta remainder+2
  1365.         ldx #24         ;repeat for each bit: ...
  1366.  
  1367. divloop asl dividend    ;dividend lb & hb*2, msb -> Carry
  1368.         rol dividend+1  
  1369.         rol dividend+2
  1370.         rol remainder   ;remainder lb & hb * 2 + msb from carry
  1371.         rol remainder+1
  1372.         rol remainder+2
  1373.         lda remainder
  1374.         sec
  1375.         sbc divisor     ;substract divisor to see if it fits in
  1376.         tay             ;lb result -> Y, for we may need it later
  1377.         lda remainder+1
  1378.         sbc divisor+1
  1379.         sta pztemp
  1380.         lda remainder+2
  1381.         sbc divisor+2
  1382.         bcc skip        ;if carry=0 then divisor didn't fit in yet
  1383.  
  1384.         sta remainder+2 ;else save substraction result as new remainder,
  1385.         lda pztemp
  1386.         sta remainder+1
  1387.         sty remainder  
  1388.         inc dividend    ;and INCrement result cause divisor fit in 1 times
  1389.  
  1390. skip    dex
  1391.         bne divloop    
  1392.         rts
  1393.  
  1394.  
  1395.  
  1396.  
  1397.  
  1398. ;********************************************
  1399. ;*    sqrt16
  1400. ;*
  1401. ;*   computes Sqrt of a 16bit number
  1402. ;*
  1403. ;*      input:  square, the 2-byte source number
  1404. ;*      output: sqrt, 8bit value
  1405. ;*              remnd, 8bit value
  1406. ;*
  1407.  
  1408. sqrt16
  1409.         lda #0
  1410.         ;sta _sqrt      ; R=0
  1411.         sta _sqrt+1
  1412.         sta _M+2
  1413.         ;sta T          ; (T+0) is zero until last iteration
  1414.         tax
  1415.  
  1416.         ldy #6          ; 7 iterations (6-->0) + last iteration
  1417. loopsq16
  1418.         txa             ; _sqrt
  1419.         ora stablo,y    ; (2*R+D) LSR 1; actually: R+(D LSR 1)
  1420.         sta _T+1
  1421.  
  1422.         lda _M+1
  1423.  
  1424.         bcs skip016
  1425.  
  1426.         cmp _T+1
  1427.         bcc skip116
  1428. skip016   ;sec
  1429.         sbc _T+1         ; M=M-T
  1430.         sta _M+1
  1431.         txa              ; R=R+D
  1432.         ora stablo+1,y
  1433.         tax
  1434. skip116
  1435.         asl _M           ; M=M*2
  1436.         rol _M+1
  1437.         dey              ; implicit: D=D/2, by the decrement of .Y
  1438.         bpl loopsq16
  1439. lastiter16               ; code for last iteration
  1440.         ; during last iteration D=1, so [(2*R+D) LSR 1] makes D the MSB of T+1
  1441.         stx _sqrt
  1442.         bcs skp016
  1443.         lda _M+1
  1444.         cmp _sqrt        ; (T+1) = sqrtLO
  1445.         bcc skp116
  1446.         bne skp016
  1447.         lda _M
  1448.         cmp #$80         ; value of (T+0) during last iteration
  1449.         bcc skp116
  1450. skp016    ;sec
  1451.         lda _M
  1452.         sbc #$80         ; (T+0) during last iteration
  1453.         sta _M
  1454.         lda _M+1         ; M=M-T
  1455.         sbc _sqrt        ; (T+1)
  1456.         sta _M+1
  1457.         inc _sqrt        ; R=R+D with D=1
  1458. skp116
  1459.         asl _M           ; M=M*2
  1460.         rol _M+1
  1461.         lda _M+2         ; remainder to M+2/M+3
  1462.         rol
  1463.         sta _M+3
  1464.         lda _M+1
  1465.         sta _M+2
  1466.         rts
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement