home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / drdobbs / 1986 / 09 / letters.sep < prev    next >
Text File  |  1986-09-30  |  11KB  |  458 lines

  1. Listing One
  2.  
  3. Program Squareroot;
  4. {
  5.   Squareroot algorithm & testprogram; DDJ March 1986, p.122
  6.  
  7.   Features:  - sqrt routine in 68000 machine language;
  8.          - long integer loopcount;
  9. }
  10.  
  11. const    { Iteration count for test loop }
  12.     NNR = 6E4;    { real, for printing of statistics }
  13.     NNS = '60000';    { string, for assignment to long integer }
  14.  
  15. type    long = record
  16.           low,high : integer;
  17.         end;
  18.  
  19. var    finished    : boolean;    { flag for loop }
  20.     number, limit   : long;        { loop count, loop limit } 
  21.     sqrrt,                { square root result }
  22.     sqrrto,                { last displayed square root }
  23.     t1,t2        : integer;    { parameters for system time }
  24.     time1, time2    : real;     { start, end time }
  25.     
  26. { --- ROUTINES FOR LONG (32-BIT) INTEGER SUPPORT --- }
  27.  
  28. procedure lg_clr(var l:long);   external;
  29. { Clears long integer l }
  30.  
  31. procedure lg_asn_DU(s:string; var l:long);   external;
  32. { Assigns the unsigned decimal string s to the long integer l }
  33.  
  34. procedure lg_inc1(var l:long);   external;
  35. { Increments long integer l by 1 }
  36.  
  37. procedure lg_grt(a,b:long; var flag:boolean);   external;
  38. { Compares long integers a and b and assign result to flag }
  39.  
  40. { --- SQUAREROOT ROUTINE --- }
  41.  
  42. procedure sqrt(number:long; var result:integer);  external;
  43. { Calculates square root of 'number' and returns it in 'result' }
  44.  
  45. begin { main }
  46.  
  47.   sqrrto := 100;
  48.  
  49.   lg_clr(number);    { number := 0 }
  50.   lg_asn_DU(NNS,limit); {limit := NNS }
  51.   finished := false;
  52.  
  53.   write('Start...');
  54.   time(t1,t2);  time1 := t2;  { get start time }
  55.  
  56.   while not finished do { calculate sqrt(number) }
  57.     begin
  58.       sqrt(number,sqrrt);
  59.     {
  60.       if sqrrt <> sqrrto
  61.      then begin
  62.        write ('Number = ',number.high:6,' | ',number.low:6);
  63.        writeln('  ---  Sqrt = ',sqrrt:4);
  64.        sqrrto := sqrrt;
  65.      end;
  66.     }
  67.       lg_inc1(number);            { number := number + 1 }
  68.       lg_grt(number,limit,finished);    { finished := (number > limit) }
  69.     end;
  70.    
  71.     time(t1,t2);   time2 := t2;  { get end time }
  72.  
  73.     writeln('finished !'); writeln;
  74.     writeln('Time: ',(time2-time1)/60,' seconds');
  75.  
  76. end.
  77.  
  78. Listing Two
  79.  
  80. 1 *
  81. 2 * Squareroot algorithm;  DDJ March 1986, p.122
  82. 3 *
  83. 4 * 68000 assembly language version
  84. 5 *
  85. 6 * Features: - equivalent to compiler-generated code;
  86. 7 *
  87. 8 *
  88. 9 * procedure sqrt(number:long; var result:integer);
  89. 10 *
  90. 11 * Calculates integer square root of 'number' and returns it in 'result';
  91. 12 * 
  92. 13 *
  93. 14 * Register usage:
  94. 15 * --------------
  95. 16 *
  96. 17 * D0 : word register        A0 : parameter stack pointer
  97. 18 * D1 : number                A1 : scratch register
  98. 19 * D2 : guess1
  99. 20 * D3 : guess2
  100. 21 * D4 : error
  101. 22 *
  102. 23     proc    sqrt,2        ;2 words of parameters
  103. 24 *
  104. 25 * Get parameters from stack
  105. 26 *
  106. 27    move.l     (sp)+,a0    ;get return address    
  107. 28    move.w    2(sp),a1    ;get ^number
  108. 29    move.l    (a1),d1        ;get number
  109. 30 *
  110. 31 * bra Q15 ;--- for timing only
  111. 32 *
  112. 33    beq    Q8        ;if number=0, skip
  113. 34 *
  114. 35 * Set initial values
  115. 36 *
  116. 37 Q7    moveq    #1,d2        ;guess1 := 1
  117. 38        move.1    d1,d3        ;guess2 := number
  118. 39 *
  119. 40 * Do shifts until guess1 ~  guess2
  120. 41 *
  121. 42 Q9    move.l    d2,d0        ;guess1 to work register
  122. 43    asl.l    #1,d0        ;guess1 * 2
  123. 44    cmp.l    d3,d0        ;compare with guess2
  124. 45    bge    Q11        ;branch if guess1 * 2 >= guess2
  125. 46    asl.l     #1,d2        ;guess1 := guess1 * 2
  126. 47    asr.l    #1,d3        ;guess2 := guess2 / 2
  127. 48    bra    Q9
  128. 49 *
  129. 50 * Now do divisions
  130. 51 *
  131. 52 Q11
  132. 53 Q13    add.l    d3,d2        ;guess := guess1 + guess2
  133. 54    asr.l    #1,d2        ;guess1 := (guess1+guess2)/2
  134. 55    move.l    d1,d0        ;number to work register
  135. 56    divs    d2,d0        ;number / guess1
  136. 57    move.w    d0,d3        ;guess2 := number/guess1
  137. 58    ext.l    d3        ;extend to 32 bits
  138. 59    move.l    d2,d0        ;guess1 to work register
  139. 60    sub.l    d3,d0        ;guess1-guess2
  140. 61    move.l    d0,d4        ;error := guess1-guess2
  141. 62    ble    Q14        ;if error <= 0
  142. 63    bra    Q13        ;loop back if error > 0
  143. 64 Q14    move.l    d2,d0        ;result := guess1
  144. 65    bra    Q15
  145. 66 Q8    moveq     #0,d0        ;result := 0
  146. 67 *
  147. 68 * Set result & return to caller
  148. 69 *
  149. 70 Q15    movea.w (sp)+,a1    ;get ^result
  150. 71    move.w    d0,(a1)        ;store result
  151. 72 *
  152. 73    addq.l    #2,sp        ;drop ^number
  153. 74    jmp    (a0)        ;return to caller
  154. 75 *
  155. 76    .nolist
  156.  
  157. Listing Three
  158.  
  159. 1 *
  160. 2 * Squareroot algorithm; DDJ March 1986, p.122
  161. 3 *
  162. 4 * 68000 assembly language version
  163. 5 *
  164. 6 * Features:  - hand-optimized machine code;
  165. 7 *
  166. 8 * 
  167. 9 * procedure sqrt(number:integer; var result:integer);
  168. 10 *
  169. 11 * Calculates square root of 'number' and returns it in 'result';
  170. 12 *
  171. 13 *
  172. 14 * Register usage:
  173. 15 * --------------
  174. 16 *
  175. 17 * D0 : work register, error        A0 : ^result
  176. 18 * D1 : number            A1 : ^number
  177. 19 * D2 : guess1,result
  178. 20 * D3 : guess2
  179. 21 * D4 : temporary storage for return address
  180. 22 *
  181. 23 *
  182. 24     .proc    sqrt,2        ;2 words of parameters
  183. 25 *
  184. 26 * Get parameters from stack
  185. 27 * 
  186. 28    moveq #0,d2        ;result := 0 --- remove for timing
  187. 29 *
  188. 30     move.l     (sp)+,d4    ;get return address
  189. 31     move.w    (sp)+,a0    ;get ^result
  190. 32    move.w (sp)+,a1        ;get ^number
  191. 33    move.l    (a1),d1        ;get number
  192. 34 *
  193. 35 * bra Q15 ;--- for timing only
  194. 36 *
  195. 37    beq     Q15        ;if number=0, then result=0
  196. 38 *
  197. 39 * Set initial values
  198. 40 *
  199. 41 Q7    moveq    #1,d2        ;guess1 := 1
  200. 42        move.l    d1,d3        ;guess2 := number
  201. 43 *
  202. 44 * Do shifts until guess1 ~  guess2
  203. 45 *
  204. 46 Q9    asl.l    #1,d2        ;guess1 := guess1 * 2
  205. 47    cmp.l    d3,d2        ;compare with guess2
  206. 48    bge    Q11        ;branch if guess1 * 2 >= guess2
  207. 49    asr.l    #1,d3        ;guess2 := guess2 / 2
  208. 50    bra    Q9
  209. 51 *
  210. 52 Q11    asr.l    #1,d2        ;adjust guess1
  211. 53 *
  212. 54 * Now do divisions
  213. 55 *
  214. 56 Q13    add.l    d3,d2        ;guess1 := guess1 + guess2
  215. 57     asr.l    #1,d2        ;guess1 := (guess1+guess2)/2
  216. 58    move.l    d1,d3        ;guess2 := number
  217. 59    divs    d2,d3        ;guess2 := number / guess1
  218. 60    ext.l    d3        ;extend guess2 to 32 bits
  219. 61    move.l    d2,d0        ;guess1 to work register
  220. 62    sub.l    d3,d0        ;error := guess1 - guess2
  221. 63    bgt    Q13        ;loop back if error > 0
  222. 64 *
  223. 65 * Store result and return to caller
  224. 66 *
  225. 67 Q15    move.w     d2,(a0)        ;store result     
  226. 68 *
  227. 69     movea.l    d4,a0        ;move return address to adr-reg
  228. 70    jmp    (a0)        ;return to caller
  229. 71 *
  230. 72    .nolist
  231.  
  232. Listing Four
  233.  
  234. 1 *
  235. 2 * Squareroot algorithm; DDJ November 1985, p.88
  236. 3 *
  237. 4 * 68000 assembly language
  238. 5 *
  239. 6 * procedure sqrt(number:long; var result:integer);
  240. 7 *
  241. 8 * Calculates the integer squareroot of 'number' and returns it in 'result'
  242. 9 *
  243. 10 *
  244. 11 * Register usage
  245. 12 * --------------
  246. 13 *
  247. 14 * D0 : number        A0 : scratch, for pointers
  248. 15 * D1 : error term        A1 : scratch, for pointers
  249. 16 * D2 : estimate
  250. 17 * D3 : corrector term
  251. 18 * D4 : loop counter
  252. 19 *
  253. 20 *
  254. 21    .proc    sqrt,2        ;2 words of parameters
  255. 22 *
  256. 23     move.w     6(sp),a0    ;get ^number
  257. 24    move.l    (a0),d0        ;get number into d0
  258. 25 *
  259. 26 * bra exit ;--- for timing only
  260. 27 *
  261. 28    moveq    #16-1,d4    ;set loopcount,16*2 = 32 bits
  262. 29    moveq    #0,d1        ;clear error term
  263. 30     moveq    #0,d2        ;clear estimate
  264. 31 *
  265. 32 * Calculate squareroot
  266. 33 *
  267. 34 sqrtl asl.l #1,d0        ;get 2 leading bits,
  268. 35    roxl.l    #1,d1        ;one at a time, into
  269. 36    asl.l    #1,d0        ;the error term
  270. 37    roxl.l    #1,d1
  271. 38    asl.l     #1,d2        ;estimate * 2
  272. 39    move.l  d2,d3        
  273. 40    asl.l    #1,d3        ;corrector = 2 * new estimate
  274. 41    cmp.l    d3,d1
  275. 42    bls    sqrt2        ;branch if error term <= corrector
  276. 43    addq.l    #1,d2        ;otherwise, add low bit to estimate
  277. 44    addq.l    #1,d3
  278. 45    sub.l    d3,d1        ;and calculate new error term
  279. 46 *
  280. 47 sqrt2 dbra    d4,sqrtl    ;do all 16 bit-pairs
  281. 48 *
  282. 49 * Set result & return to caller
  283. 50 *
  284. 51 exit    move.l     (sp)+,a0    ;get return address
  285. 52    move.w    (sp)+,a1    ;get ^result
  286. 53    move.w    d2,(a1)        ;store integer result
  287. 54    addq.l    #2,sp        ;drop ^number
  288. 55    jmp    (a0)        ;return to caller
  289. 56 *
  290. 57     .nolist
  291.  
  292.  
  293. Listing Five
  294.  
  295. djnz:                    * 10   djnz e
  296.     move.b    (pseudopc)+,d0        * d0 <-- distance
  297.     subq.b    #1,regb(regs)        * dec b
  298.     beq    djnz2            * loop count expired
  299.     ext.w    d0            * to word
  300.     ext.l    d0            * to long
  301.     add.l    d0,pseudopc        * add distance
  302. djnz2:
  303.     NEXT
  304. jr:                    * 18   jr e
  305.     move.b    (pseudopc)+,d0        * d0 <-- distance
  306.     ext.w    d0            * to word
  307.     ext.l    d0            * to long
  308.     add.l    d0,pseudopc        * add distance
  309.     NEXT
  310. jrnz:                    * 20   jr nz,e
  311.     move.b    (pseudopc)+,d0        * d0 <-- distance
  312.     btst    #6,regf            * if Z bit set
  313.     bne    jrnz2            * then no branch
  314.     ext.w    d0            * to word
  315.     ext.l    d0            * to long
  316.     add.l    d0,pseudopc        * add distance
  317. jrnz2:
  318.     NEXT
  319. jrz:                    * 28   jr z,e
  320.     move.b    (pseudopc)+,d0        * d0 <-- distance
  321.     btst    #6,regf            * if Z bit reset
  322.     beq    jrz2            * then no branch
  323.     ext.w    d0            * to word
  324.     ext.l     d0            * to long
  325.     add.l    d0,pseudopc        * add distance
  326. jrz2:
  327.     NEXT
  328. jrnc:                    * 30   jr nc,e
  329.     move.b     (pseudopc)+,d0        * d0 <-- distance
  330.     btst    #0,regf            * if C bit set
  331.     bne    jrnc2            * then no branch
  332.     ext.w    d0            * to word
  333.     ext.l    d0            * to long
  334.     add.l    d0,pseudopc        * add distance
  335. jrnc2:
  336.     NEXT
  337. jrc:                    * 38 jr c,e
  338.     move.b     (pseudopc)+,d0        * d0 <-- distance
  339.     btst    #0,regf            * if C bit reset
  340.     beq    jrc2            * then no branch
  341.     ext.w    d0            * to word
  342.     ext.l    d0            * to long
  343.     add.l    d0,pseudopc        * add distance
  344. jrc2:
  345.     NEXT
  346.  
  347.  
  348. Listing Six
  349.  
  350. 1  /* c_draw.c */             /*   jnm  5-27-86  rev.1     */
  351. 2
  352. 3  /* corrected line drawing routine using Bresenham's algorithm...   */
  353. 4
  354. 5
  355. 6  c_draw (x1, y1, x2, y2, color)
  356. 7  int x1, y1, x2, y2, color;
  357. 8
  358. 9  {
  359. 10 int inc1, inc2, inc3, xend, yend;
  360. 11 int d, x, y, dx, dy;
  361. 12
  362. 13 dx = abs (x2 - x1);
  363. 14 dy = abs (y2 - y1);
  364. 15 if (dy <= dx)
  365. 16    {
  366. 17    if (x1 > x2)
  367. 18     {
  368. 19     x = x2;
  369. 20     y = y2;
  370. 21     xend = x1;
  371. 22     dy = y1 - y2;
  372. 23     }
  373. 24    else
  374. 25     {
  375. 26     x = x1;
  376. 27     y = y1;
  377. 28      xend = x2;
  378. 29     dy = y2 - y1;
  379. 30     }
  380. 31    inc1 = dy << 1;
  381. 32    inc2 = (dy - dx) << 1;
  382. 33    inc3 = (dy + dx) << 1;
  383. 34    d = (dy >= 0) ? inc1 - dx:inc1 + dx;
  384. 35    while (x < xend)
  385. 36     {
  386. 37     pcvwd (y, x, color);        /* or whatever point plotting */
  387. 38      x++;                /* function you have handy... */
  388. 39     if (d >= 0)
  389. 40        {
  390. 41        if (dy <= 0)
  391. 42           d += inc1;
  392. 43        else
  393. 44           {
  394. 45           y++;
  395. 46             d += inc2;
  396. 47           }
  397. 48        }
  398. 49     else
  399. 50        {
  400. 51        if (dy >= 0)
  401. 52           d += inc1;
  402. 53         else
  403. 54           {
  404. 55           y--;
  405. 56           d += inc3;
  406. 57           }
  407. 58        }
  408. 59     }
  409. 60    }
  410. 61 else
  411. 62    {
  412. 63    if (y1 > y2)
  413. 64     {
  414. 65     y = y2;
  415. 66     x = x2;
  416. 67     yend = y1;
  417. 68     dx = x1 - x2;
  418. 69     }
  419. 70    else
  420. 71     {
  421. 72     y = y1;
  422. 73      x = x1;
  423. 74     yend = y2
  424. 75     dx = x2 - x1;
  425. 76     }
  426. 77    inc1 = dx << 1;
  427. 78    inc2 = (dx - dy) << 1;
  428. 79    inc3 = (dx + dy) << 1;
  429. 80    d = (dx >= 0) ? inc1 - dy:inc1 + dy;
  430. 81    while (y < yend)
  431. 82     {
  432. 83     pcvwd (y, x, color);
  433. 84     y++;
  434. 85     if (d >= 0)
  435. 86        {
  436. 87        if (dx <= 0)
  437. 88           d += inc1;
  438. 89        else
  439. 90           {
  440. 91           x++;
  441. 92           d += inc2;
  442. 93             }
  443. 94        }
  444. 95     else
  445. 96        {
  446. 97        if (dx >= 0)
  447. 98             d += inc1;
  448. 99        else
  449. 100           {
  450. 101           x--;
  451. 102           d += inc3;
  452. 103           }
  453. 104         }
  454. 105     }
  455. 106   }
  456. 107 pcvwd (y, x, color);
  457. 108 }
  458. 109