home *** CD-ROM | disk | FTP | other *** search
/ World of Shareware - Software Farm 2 / wosw_2.zip / wosw_2 / QBAS / UBAS830.ZIP / MPQS#10.ASM < prev    next >
Assembly Source File  |  1989-04-04  |  18KB  |  1,181 lines

  1. ;MPQS#10.ASM
  2. ;    MACHINE LANGUAGE SUBROUTINE
  3. ;    FOR MULTIPLE POLYNOMIAL QUADRATIC SIEVE
  4. ;
  5. ;    Original Version           1987 by YUJI KIDA
  6. ;    Fantastic? English Version 1988 by Yuji KIDA
  7.  
  8.     INCLUDE    UB.MAC
  9.  
  10.     JMP    START0
  11.  
  12.     EVEN
  13. SIEVESEG    DW    ?
  14.  
  15. SEGSTEP    DW    ?
  16. SEGTOP    DW    ?
  17. SEGEND    DW    ?
  18.  
  19. MSIZE    DW    ?
  20. MWORDS    DW    ?
  21. ROWWORDS    DW    ?
  22. OFF2ND    DW    ?
  23. OFF3RD    DW    ?
  24.  
  25. ROWINDEXMIN    DW    ?
  26. ROWINDEXNOW    DW    ?
  27. ROWINDEXNOW2    DW    ?
  28. ROWINDEXLIM    DW    ?
  29. ROWINDEXMAX    DW    ?
  30. DS_INDEX    DW    ?
  31.  
  32. SEGNOW    DW    ?
  33. OFFNOW    DW    ?
  34. MASKNOW    DW    ?
  35. ANSNOW    DW    ?
  36.  
  37. OFF1    DW    ?
  38. SEG1    DW    ?
  39. OFF2    DW    ?
  40. SEG2    DW    ?
  41.  
  42. N_OFF    DW    ?
  43. N_SEG    DW    ?
  44. X_OFF    DW    ?
  45. X_SEG    DW    ?
  46. Y_OFF    DW    ?
  47. Y_SEG    DW    ?
  48. WW_OFF    DW    ?
  49. WW_SEG    DW    ?
  50. XA_SEG    DW    ?
  51. YA_SEG    DW    ?
  52.  
  53. YR_SEG    DW    ?
  54. YR_SIZE    DW    ?
  55. YR_KOSU    DW    ?
  56. MAXLOW    DW    ?
  57. MAXHIGH    DW    ?
  58.  
  59. P_OFF    DW    ?
  60. P_SEG    DW    ?
  61. P_NOW2    DW    ?
  62.  
  63. STOP_PTR    DW    ?
  64.  
  65. ADR_NOW    DW    ?
  66. REENT    DB    ?,?
  67.  
  68. LOG_INI    DW    ?
  69. LOG_MAX    DW    ?
  70.  
  71.  
  72.  
  73. ;** COMMAND BRANCH
  74.  
  75.  
  76. START0:
  77.     MOV_AX    AR0        ;get COMMAND frm ARRAY[0]
  78.     MOV    BX,OFFSET CMD_TBL
  79.     SHL    AX,1
  80.     ADD    BX,AX
  81.     JMP    CS:[BX]
  82.  
  83. CMD_TBL:
  84.     DW    INIT,SIEVE,SIEVE_ANS,TEST_DIV,LPV
  85.     DW    SET_ROW,GAUSS,SQUARE_ANS,GET_DIV,RE_INIT
  86.  
  87.  
  88. ;
  89. ;** reinitilization if one could not find a factor after 1st 
  90. ;   GAUSSian elimination
  91. ;
  92. ; COMMAND#=9
  93.  
  94. RE_INIT:
  95.     ;erase the column corresponding to discarded X
  96.  
  97.     MOV    SI,CS:[ROWINDEXNOW]
  98. REINI10:
  99.     CMP    SI,CS:[ROWINDEXMAX]
  100.     JB    REINI15
  101.  
  102.     MOV    AX,SS
  103.     MOV    DS,AX
  104.     MOV    ES,AX
  105.     RETF
  106.  
  107. REINI15:
  108.     MOV    ES,CS:[SI]    ;*keep ES,SI through main loop
  109.     MOV    DI,CS:[OFF3RD]
  110.     SUB    DI,2
  111.     MOV    CX,CS:[MWORDS]
  112.     INC    CX
  113.     XOR    AX,AX
  114.     STD
  115.     REP    SCASW
  116.     CLD
  117.     LEA    BX,[DI+2]
  118.     MOV    AX,ES:[BX]
  119.     MOV    DX,8000H
  120. REINI20:
  121.     TEST    DX,AX
  122.     JNZ    REINI30
  123.     SHR    DX,1
  124.     JMP    REINI20        
  125. REINI30:                
  126.     ;NOW DX is the highest bit of [BX]
  127.     ;erase this bit in the other rows
  128.  
  129.     MOV    DI,CS:[ROWINDEXMIN]
  130. REINI40:
  131.     CMP    DI,SI
  132.     JE    REINI60        ;do not erase the bit itself
  133.     CMP    DI,CS:[ROWINDEXMAX]
  134.     JAE    REINI70        ;last pass
  135.     MOV    DS,CS:[DI]
  136.     TEST    [BX],DX
  137.     JZ    REINI60        ;not match
  138.  
  139.     PUSH    SI
  140.     MOV    SI,CS:[OFF2ND]
  141.     MOV    CX,CS:[MWORDS]
  142.     INC    CX
  143. REINI50:
  144.     MOV    AX,ES:[SI]
  145.     XOR    [SI],AX
  146.     ADD    SI,2
  147.     LOOP    REINI50
  148.     POP    SI
  149.  
  150. REINI60:
  151.     ADD    DI,2
  152.     JMP    REINI40
  153.  
  154. REINI70:
  155.     ;set corresponding unit vector
  156.  
  157.     MOV    DI,CS:[OFF2ND]
  158.     MOV    CX,CS:[MWORDS]
  159.     INC    CX
  160.     XOR    AX,AX
  161.     REP    STOSW        ;SET 07s
  162.     MOV    ES:[BX],DX    ;SET 1
  163.  
  164.     ;set pointers to X(),Y()
  165.  
  166.     SUB    BX,CS:[OFF2ND]
  167.     SHL    BX,1
  168.     SHL    BX,1
  169.     SHL    BX,1
  170. REINI110:
  171.     INC    BX
  172.     SHR    DX,1
  173.     JNC    REINI110
  174.     DEC    BX
  175.     MOV_AX    LSIZE
  176.     MUL    BX
  177.     MOV    BX,CS:[OFF3RD]
  178.     MOV    ES:[BX],AX
  179.  
  180.     ADD    SI,2
  181.     JMP    REINI10
  182.  
  183. ;
  184. ;** get exponents of each prime in the factorization of X
  185. ;
  186. ; COMMAND#=8
  187. ; INPUT Y
  188. ; OUTPUT SV%()
  189.  
  190. GET_DIV:
  191.     PUSH    BP
  192.  
  193.     LDS    SI,DWORD PTR CS:[Y_OFF]
  194.     MOV    BX,SI        ;MEMO dividend
  195.     MOV    ES,CS:[P_SEG]
  196.     MOV    DI,AR0+10    ;start at 2
  197.     MOV    CS:[OFFNOW],0
  198.  
  199.     STD
  200.     MOV    CX,CS:[MSIZE]
  201.     DEC    CX        ;skip -1
  202. GDIVLP:
  203.     MOV    BP,ES:[DI]    ;divisor
  204.     ADD    CS:[OFFNOW],2
  205.     ADD    DI,10
  206.     PUSH    CX
  207. GDIV10:
  208.     MOV    SI,BX
  209.     MOV    AX,[SI]
  210.     MOV    CX,AX        ;WORDS
  211.     SHL    AX,1
  212.     ADD    SI,AX        ;highest word adr
  213.     XOR    DX,DX    
  214. GDIV20:
  215.     LODSW
  216.     DIV    BP
  217.     LOOP    GDIV20
  218.     OR    DX,DX
  219.     JZ    GDIV100        ;divide if divisible
  220.  
  221.     POP    CX
  222.     LOOP    GDIVLP
  223.  
  224.     POP    BP
  225.     CLD
  226.     RETF
  227.  
  228. GDIV100:
  229.     MOV    AX,DS
  230.     MOV    DS,CS:[SIEVESEG]
  231.     MOV    SI,CS:[OFFNOW]
  232.     INC    WORD PTR [SI]
  233.     MOV    DS,AX
  234.     MOV    SI,BX
  235.     MOV    AX,[SI]
  236.     MOV    CX,AX        ;WORDS
  237.     SHL    AX,1
  238.     ADD    SI,AX        ;highest word adr
  239.     XOR    DX,DX    
  240.     LODSW
  241.     DIV    BP
  242.     PUSH    AX        ;value of highest word
  243.     JMP    SHORT GDIV120
  244. GDIV110:
  245.     LODSW
  246.     DIV    BP
  247. GDIV120:
  248.     MOV    [SI+2],AX
  249.     LOOP    GDIV110
  250.     POP    AX        ;value of highest word
  251.     OR    AX,AX
  252.     JNZ    GDIV10
  253.     DEC    WORD PTR [SI]    ;dec len if highest word=0
  254.     JMP    GDIV10
  255.  
  256. ;
  257. ;** GAUSSian elimination
  258. ;
  259. ;COMMAND#=4
  260. ;
  261.  
  262. GO_GAUSSNEXT_C:
  263.     JMP    GAUSSNEXT_C
  264.  
  265.  
  266. GAUSS:
  267.     MOV    SI,CS:[ROWINDEXNOW]
  268.     MOV    CS:[ROWINDEXLIM],SI
  269.     MOV    ES,CS:[SI]
  270.     XOR    DI,DI
  271.     MOV    CX,CS:[MWORDS]
  272.     MOV    AX,0FFFFH
  273.     REP    STOSW        ;STOPPER
  274.  
  275.     MOV    SI,CS:[ROWINDEXMIN]
  276.     MOV    CS:[ROWINDEXNOW],SI
  277.     MOV    ES,CS:[SI]
  278.     MOV    BX,CS:[OFF2ND]    ;START OFFSET(right column first)
  279.     SUB    BX,2        ;
  280.     MOV    DX,8000H    ;BIT MASK
  281.  
  282. ;* search this column and exchange the row with 1st nonzero
  283.  
  284. GAUSS10:
  285.     MOV    SI,CS:[ROWINDEXNOW]
  286.     JMP    SHORT GAUSS25
  287. GAUSS20:
  288.     MOV    SI,CS:[DS_INDEX]
  289.     ADD    SI,2
  290. GAUSS25:
  291.     MOV    CS:[DS_INDEX],SI
  292.     MOV    DS,CS:[SI]
  293.     TEST    [BX],DX
  294.     JZ    GAUSS20
  295.  
  296.     CMP    SI,CS:[ROWINDEXLIM]
  297.     JAE    GO_GAUSSNEXT_C    ;go to next row for no NONZERO
  298.     CMP    SI,CS:[ROWINDEXNOW]
  299.     JE    GAUSS40        ;already NONZERO
  300.  
  301.     ;swap POINTERs
  302.  
  303.     MOV    SI,CS:[DS_INDEX]
  304.     MOV    DI,CS:[ROWINDEXNOW]
  305.     MOV    AX,CS:[SI]
  306.     XCHG    AX,CS:[DI]
  307.     MOV    CS:[SI],AX
  308.  
  309.     MOV    AX,DS
  310.     MOV    ES,AX
  311.  
  312. ;* eliminate this column
  313.  
  314. GAUSS40:
  315.     MOV    SI,CS:[DS_INDEX]
  316.     ADD    SI,2
  317.     MOV    CS:[DS_INDEX],SI
  318.     MOV    DS,CS:[SI]
  319.  
  320.     TEST    [BX],DX
  321.     JZ    GAUSS40        ;do not change this row
  322.  
  323.     CMP    SI,CS:[ROWINDEXLIM]
  324.     JAE    GAUSSNEXT_RC    ;go to next row&column
  325.  
  326.     MOV    CX,CS:[ROWWORDS]
  327.     DEC    CX
  328.     XOR    SI,SI
  329.     EVEN
  330. GAUSS60:
  331.     MOV    AX,ES:[SI]
  332.     XOR    [SI],AX
  333.     INC    SI
  334.     INC    SI
  335.     LOOP    GAUSS60
  336.  
  337.     JMP    GAUSS40
  338.  
  339.     ;next column or next row&column
  340.  
  341. GAUSSNEXT_RC:
  342.     MOV    SI,CS:[ROWINDEXNOW]
  343.     ADD    SI,2
  344.     MOV    CS:[ROWINDEXNOW],SI
  345.     MOV    ES,CS:[SI]
  346. GAUSSNEXT_C:
  347.     ROR    DX,1
  348.     JNC    GAUSS100
  349.     SUB    BX,2
  350.     JC    GAUSSEND
  351. GAUSS100:
  352.     JMP    GAUSS10
  353. GAUSSEND:
  354.     MOV    AX,CS:[ROWINDEXNOW]
  355.     MOV    CS:[ROWINDEXNOW2],AX
  356.     SUB    AX,CS:[ROWINDEXMIN]
  357.     SHR    AX,1
  358.     MOV    BX,AR3        ;return current rank in
  359.     MOV    CS:[BX],AX    ;ARRAY[3]
  360.  
  361.     MOV    AX,SS
  362.     MOV    DS,AX
  363.     MOV    ES,AX
  364.     RETF
  365.  
  366. ;
  367. ;** return a value got by SIEVE
  368. ;
  369. ;COMMAND#=5
  370. ;OUTPUT    X=OFFSET 
  371. ;     =-1 NO MORE DATA
  372.  
  373. SIEVE_ANS:
  374.     MOV    ES,CS:[SIEVESEG]
  375.     MOV    DI,CS:[ADR_NOW]
  376.     OR    DI,DI
  377.     JZ    GETD100
  378. GETD10:
  379.     MOV    AX,CS:[LOG_MAX]
  380.     MOV    CX,DI
  381.     NEG    CX
  382. GETDLP:
  383.     SCASB
  384.     JAE    GETIT
  385.     LOOP    GETDLP
  386. GETNO:
  387.     MOV    AX,8001H
  388.     MOV    DX,1
  389.     MOV    BX,DI
  390. GETOUT:
  391.     LES    DI,DWORD PTR CS:[X_OFF]
  392.     STOSW
  393.     MOV    ES:[DI],DX
  394.     MOV    CS:[ADR_NOW],BX
  395.     MOV    AX,SS
  396.     MOV    ES,AX
  397.     RETF
  398.  
  399. GETIT:
  400.     MOV    AX,1
  401.     MOV    DX,DI
  402.     DEC    DX
  403.     JNZ    GETIT20
  404.     XOR    AX,AX
  405. GETIT20:
  406.     MOV    BX,DI
  407.     JMP    GETOUT    
  408.  
  409.  
  410. GETD100:
  411.     TEST    CS:[REENT],-1
  412.     JNZ    GETNO
  413.     MOV    CS:[REENT],-1
  414.     JMP    GETD10
  415.  
  416.     
  417. ;** do the SIEVING
  418.  
  419. ;COMMAND#=1
  420.  
  421. SIEVE:
  422.     ;initialize sieve
  423.  
  424.     MOV    AX,CS:[SIEVESEG]
  425.     MOV    DS,AX
  426.     MOV    ES,AX
  427.  
  428.     XOR    DI,DI
  429.     MOV    CX,8000H
  430.     MOV    AX,CS:[LOG_INI]
  431.     REP    STOSW
  432.  
  433.     MOV    CS:[ADR_NOW],0
  434.     MOV    CS:[REENT],0
  435.  
  436.     MOV    AX,CS:[P_SEG]
  437.     MOV    ES,AX    
  438.     MOV    BX,AR0+20    ;skip -1,2
  439.  
  440.     ;SIEVE MAIN
  441.  
  442.     MOV    CX,CS:[MSIZE]
  443.     DEC    CX        ;skip -1
  444.     DEC    CX        ;skip 2
  445.  
  446. SIEVE_MAINLP:
  447.     MOV    DI,ES:[BX]    ;STEP
  448.     MOV    ax,ES:[BX+8]    ;LOG
  449.  
  450.     MOV    SI,ES:[BX+4]    ;START
  451. SIEVE20:
  452.     SUB    [SI],AL
  453.     ADD    SI,DI
  454.     jnc    SIEVE20
  455.     MOV    ES:[BX+4],SI    ;R1_OFF(for next entry)
  456.  
  457.     MOV    SI,ES:[BX+6]    ;R2_OFF START
  458. SIEVE40:
  459.     SUB    [SI],AL
  460.     ADD    SI,DI
  461.     jnc    SIEVE40
  462.     MOV    ES:[BX+6],SI    ;R2_OFF(for next entry)
  463.  
  464.     ADD    BX,10        ;update POINTER
  465.     LOOP    SIEVE_MAINLP
  466.  
  467.     MOV    AX,SS
  468.     MOV    DS,AX
  469.     MOV    ES,AX
  470.     RETF
  471.     
  472.  
  473. ;
  474. ;* use large 'primes' left after division
  475. ;    (CALLED LARGE PRIME VARIATION)
  476.  
  477. ;COMMAND#=3
  478. ;OUTPUT
  479. ;exists:  AR[0]=1,AR[1]=OLD INDEX
  480. ;insert:  AR[0]=0,AR[1]=NEW INDEX
  481. ;discard: AR[0]=0,AR[1]=-1
  482.  
  483. LPV:
  484.     ; GET W
  485.  
  486.     LDS    SI,DWORD PTR CS:[WW_OFF]
  487.     LODSW
  488.     MOV    CX,AX        ;LEN
  489.     XOR    DX,DX
  490.     LODSW
  491.     CMP    CX,2
  492.     JB    LARGE10
  493.     JA    LARGE200
  494.     MOV    DX,[SI]
  495. LARGE10:
  496.     ;SEARCH FOR DX:AX IN ZR
  497.     ; SO ONLY NUMBERS <=2 WORDS CAN BE TREATED
  498.  
  499.     CMP    DX,CS:[MAXHIGH]
  500.     JA    LARGE200
  501.     JB    LARGE15
  502.     CMP    AX,CS:[MAXLOW]
  503.     JA    LARGE200
  504. LARGE15:
  505.     MOV    SI,CS:[YR_SEG]
  506.     MOV    DS,SI
  507.     MOV    ES,SI    
  508.  
  509.     ;FIRST BINARY SEARCH
  510.  
  511.     MOV    BX,CS:[YR_KOSU]
  512.     SHL    BX,1
  513.     MOV    DI,OFFSET INDEX
  514. LARGE20:
  515.     SHR    BX,1
  516.     CMP    BX,1
  517.     JBE    LARGE100
  518.  
  519.     MOV    CX,BX
  520.     AND    CL,0FEH
  521.     ADD    DI,CX
  522.     MOV    SI,CS:[DI]
  523.     CMP    DX,[SI+2]
  524.     JB    LARGE40        ;D:A<MEM
  525.     JA    LARGE45        ;D:A>MEM
  526.     CMP    AX,[SI]
  527.     JA    LARGE45        ;D:A>MEM
  528.     JE    LARGE50        ;D:A=MEM
  529. LARGE40:
  530.     SUB    DI,CX
  531.     JMP    LARGE20
  532.  
  533. LARGE45:
  534.     ADD    DI,2
  535.     DEC    BX
  536.     JMP    LARGE20
  537.  
  538. LARGE50:
  539.     ;if 2 large primes are equal
  540.  
  541.     SHR    SI,1
  542.     SHR    SI,1        ;offset of the old 'prime'
  543.     MOV    BX,AR1
  544.     MOV    CS:[BX],SI    ;return it in AR[1]
  545.  
  546.     MOV    BX,AR0
  547.     MOV    WORD PTR CS:[BX],1    ;signal the match
  548.     MOV    AX,SS
  549.     MOV    DS,AX
  550.     MOV    ES,AX
  551.     RETF
  552.  
  553. LARGE200:
  554.     MOV    SI,8001H
  555.     MOV    BX,AR1        ;return -1 in AR[1]
  556.     MOV    CS:[BX],SI
  557.     JMP    LARGERET
  558.  
  559.  
  560.     ;NEXT CHECK CURRENT POSITION
  561.  
  562. LARGE100:
  563.     MOV    SI,CS:[DI]
  564.     CMP    DX,[SI+2]
  565.     JB    LARGE140    ;D:A<MEM
  566.     JA    LARGE110
  567.     CMP    AX,[SI]
  568.     JE    LARGE50        ;D:A=MEM
  569.     JB    LARGE140    ;D:A<MEM
  570. LARGE110:
  571.     ADD    DI,2
  572.     MOV    SI,CS:[DI]
  573.  
  574. LARGE140:
  575.     CMP    [SI+2],0FFFFH    ;STOPPER
  576.     JE    LARGE200    ;no free space
  577.     CMP    [SI+2],0FFFEH    ;DUMMY DATA
  578.     JNE    LARGE160
  579.  
  580.     ;insert it here
  581.  
  582.     INC    CS:[YR_KOSU]
  583.     MOV    [SI],AX
  584.     MOV    [SI+2],DX
  585.     SHR    SI,1
  586.     SHR    SI,1
  587.     MOV    BX,AR1        ;return array offset
  588.     MOV    CS:[BX],SI    ;in AR[1]
  589.     JMPS    LARGERET    
  590.  
  591. LARGE160:
  592.     ;free a space in the INDEX AREA
  593.  
  594.     PUSH    AX        ;*
  595.     MOV    BX,DI        ;MEMO PTR
  596.     MOV    DI,CS:[YR_KOSU]
  597.     CMP    DI,CS:[YR_SIZE]
  598.     JB    LARGE165
  599.     DEC    DI
  600. LARGE165:
  601.     SHL    DI,1
  602.     ADD    DI,OFFSET INDEX
  603.     PUSH    WORD PTR CS:[DI]    ;** offset for new prime
  604.     LEA    SI,[DI-2]
  605.     MOV    CX,DI
  606.     SUB    CX,BX
  607.     SHR    CX,1
  608.     PUSH    DS        ;***
  609.     MOV    AX,CS
  610.     MOV    DS,AX
  611.     MOV    ES,AX
  612.     STD
  613.     REP    MOVSW
  614.     CLD
  615.     POP    AX        ;***
  616.     MOV    DS,AX
  617.     MOV    ES,AX
  618.  
  619.     MOV    DI,BX
  620.     POP    SI        ;**
  621.     MOV    CS:[DI],SI
  622.     POP    AX        ;*
  623.     MOV    [SI],AX
  624.     MOV    [SI+2],DX
  625.     SHR    SI,1
  626.     SHR    SI,1
  627.     MOV    BX,AR1        ;return array offset
  628.     MOV    CS:[BX],SI    ;in AR[1]
  629.  
  630.     ;is YR full?
  631.  
  632.     MOV    AX,CS:[YR_KOSU]
  633.     MOV    BX,CS:[YR_SIZE]
  634.     CMP    AX,BX
  635.     JAE    LARGE170    ;full
  636.     INC    AX
  637.     MOV    CS:[YR_KOSU],AX
  638.     CMP    AX,BX
  639.     JAE    LARGE170    ;full
  640.  
  641. LARGERET:
  642.     MOV    BX,AR0
  643.     MOV    WORD PTR CS:[BX],0    ;mark of non_existence
  644.     MOV    AX,SS
  645.     MOV    DS,AX
  646.     MOV    ES,AX
  647.     RETF    
  648.     
  649.     ;update LOG LIMIT
  650.     ;to (maximum LP)^2
  651.  
  652. LARGE170:
  653.     DEC    BX
  654.     SHL    BX,1
  655.     ADD    BX,OFFSET INDEX
  656.     MOV    SI,CS:[BX]    
  657.     LODSW
  658.     MOV    CS:[MAXLOW],AX
  659.     MOV    CX,16
  660.     MOV    DX,[SI]
  661.     MOV    CS:[MAXHIGH],DX
  662.     OR    DX,DX
  663.     JZ    LARGE190
  664.     MOV    CX,32
  665.     MOV    AX,DX
  666. LARGE190:
  667.     DEC    CX
  668.     SHL    AX,1
  669.     JNC    LARGE190
  670.  
  671.     MOV    AX,CX
  672.     SHL    AX,1
  673.     SHL    AX,1
  674.     CMP    AX,CS:[LOG_MAX]
  675.     JAE    LARGE195
  676.     MOV    CS:[LOG_MAX],AX
  677. LARGE195:
  678.     JMP    LARGERET
  679.  
  680.  
  681. ;** check whether W# is divisible by PR%()
  682.  
  683. ;COMMAND#=7
  684.  
  685. TEST_DIV:
  686.     PUSH    BP
  687.  
  688.     LDS    SI,DWORD PTR CS:[WW_OFF]
  689.     MOV    BX,SI        ;MEMO dividend
  690.     MOV    ES,CS:[P_SEG]
  691.     MOV    DI,AR0+10    ;from 2
  692.  
  693.     STD
  694.     MOV    CX,CS:[MSIZE]
  695.     DEC    CX        ;pass -1
  696. TDIVLP:
  697.     PUSH    CX
  698.     MOV    BP,ES:[DI]    ;numerator
  699.     ADD    DI,10
  700. TDIV10:
  701.     MOV    SI,BX
  702.     MOV    AX,[SI]
  703.     MOV    CX,AX        ;WORDS
  704.     SHL    AX,1
  705.     ADD    SI,AX        ;highest word adr
  706.     XOR    DX,DX    
  707. TDIV20:
  708.     LODSW
  709.     DIV    BP
  710.     LOOP    TDIV20
  711.     OR    DX,DX
  712.     JZ    TDIV100        ;do divide if divisible
  713.  
  714.     POP    CX
  715.     LOOP    TDIVLP
  716.  
  717.     POP    BP
  718.     CLD
  719.     RETF
  720.  
  721. TDIV100:
  722.     MOV    SI,BX
  723.     MOV    AX,[SI]
  724.     MOV    CX,AX        ;WORDS
  725.     SHL    AX,1
  726.     ADD    SI,AX        ;highest word adr
  727.     XOR    DX,DX    
  728.     LODSW
  729.     DIV    BP
  730.     PUSH    AX        ;value of highest word
  731.     JMP    SHORT TDIV120
  732. TDIV110:
  733.     LODSW
  734.     DIV    BP
  735. TDIV120:
  736.     MOV    [SI+2],AX
  737.     LOOP    TDIV110
  738.     POP    AX        ;value of highest word
  739.     OR    AX,AX
  740.     JNZ    TDIV10
  741.     DEC    WORD PTR [SI]    ;dec len if highest word=0
  742.     JMP    TDIV10
  743.  
  744. ;
  745. ;** initialize work area
  746.  
  747. ;COMMAND#=0
  748.  
  749. ;    V1=PR%(0)
  750. ;    V2=W#
  751. ;    V3=N
  752. ;    V4=X
  753. ;    V5=Y
  754. ;    V6=X(0)
  755. ;    V7=Y(0)
  756. ;    V8=YR%(0)
  757. ;    V9=SV%(0)
  758.  
  759. ;    AR[1]    SIZE OF MATRIX
  760. ;    AR[2]    SIZE OF LARGE PRIMES BUFFER
  761. ;    AR[3]    INITIAL LOG
  762. ;    AR[4]    LIMIT LOG
  763.  
  764. INIT:
  765.     PUSH    BP
  766.  
  767.     MOV    BX,V1        ;set PR%(0,0) ADDRESS
  768.     MOV    AX,CS:[BX]
  769.     MOV    CS:[P_OFF],AX
  770.     MOV    AX,CS:[BX+2]
  771.     MOV    CS:[P_SEG],AX
  772.  
  773.     MOV    BX,V2        ;set W# ADDRESS
  774.     MOV    AX,CS:[BX]
  775.     MOV    CS:[WW_OFF],AX
  776.     MOV    AX,CS:[BX+2]
  777.     MOV    CS:[WW_SEG],AX
  778.  
  779.     MOV    BX,V3        ;set N ADDRESS
  780.     MOV    AX,CS:[BX]
  781.     MOV    CS:[N_OFF],AX
  782.     MOV    AX,CS:[BX+2]
  783.     MOV    CS:[N_SEG],AX
  784.  
  785.     MOV    BX,V4        ;set X ADDRESS
  786.     MOV    AX,CS:[BX]
  787.     MOV    CS:[X_OFF],AX
  788.     MOV    AX,CS:[BX+2]
  789.     MOV    CS:[X_SEG],AX
  790.  
  791.     MOV    BX,V5        ;set Y ADDRESS
  792.     MOV    AX,CS:[BX]
  793.     MOV    CS:[Y_OFF],AX
  794.     MOV    AX,CS:[BX+2]
  795.     MOV    CS:[Y_SEG],AX
  796.  
  797.     MOV_AX    V6+2        ;set X(0) ADDRESS
  798.     ADD    AX,ARRAYHEADSEG
  799.     MOV    CS:[XA_SEG],AX
  800.  
  801.     MOV_AX    V7+2        ;set Y(0) ADDRESS
  802.     ADD    AX,ARRAYHEADSEG
  803.     MOV    CS:[YA_SEG],AX
  804.  
  805.     MOV_AX    V9+2        ;WORK AREA FOR SIEVING
  806.     ADD    AX,ARRAYHEADSEG
  807.     MOV    CS:[SIEVESEG],AX
  808.  
  809.     MOV_AX    AR1        ;SIZE OF MATRIX
  810.     MOV    CS:[MSIZE],AX
  811.  
  812.     ;set index area for YR()
  813.  
  814.     MOV_AX    AR2        ;number of YR()'s
  815.     MOV    CS:[YR_SIZE],AX
  816.     INC    AX        ;1 more for end effect
  817.     SHL    AX,1
  818.     SHL    AX,1        ;4 BYTES per element
  819.     ADD    AX,OFFSET INDEX
  820.  
  821.     ;set index area for GAUSSian elimination
  822.  
  823.     MOV    CS:[ROWINDEXMIN],AX
  824.     MOV    CS:[ROWINDEXNOW],AX
  825.     MOV    BX,CS:[MSIZE]    
  826.     INC    BX        ;ADDITIONAL ROW
  827.     INC    BX        ;STOPPER ROW
  828.     SHL    BX,1        ;2 BYTES per element
  829.     ADD    AX,BX        ;AX=OFFSET OF NEXT BYTE OF INDEX AREA
  830.  
  831.     ;set MATRIX AREA
  832.  
  833.     ADD    AX,15
  834.     SHR    AX,1
  835.     SHR    AX,1
  836.     SHR    AX,1
  837.     SHR    AX,1
  838.     MOV    BX,CS
  839.     ADD    AX,BX
  840.     MOV    CS:[SEGTOP],AX    ;first segment of matrix
  841.  
  842.     MOV    AX,CS:[MSIZE]    ;MUST BE A MUTIPLE OF 16
  843.     SHR    AX,1
  844.     SHR    AX,1
  845.     SHR    AX,1
  846.     MOV    CS:[OFF2ND],AX    ;OFFSET OF 2ND MATRIX
  847.     SHR    AX,1
  848.     MOV    CS:[MWORDS],AX    ;MATRIX WORD SIZE
  849.     SHL    AX,1        ;use 2 matrices
  850.     INC    AX        ;2nd matrix needs 1 bit more
  851.     SHL    AX,1
  852.     MOV    CS:[OFF3RD],AX
  853.     SHR    AX,1
  854.     INC    AX        ;for pointers to X(),Y()
  855.     MOV    CS:[ROWWORDS],AX    ;number of words in 1 row
  856.     ADD    AX,7        ;round up for SEGMENTs
  857.     SHR    AX,1
  858.     SHR    AX,1
  859.     SHR    AX,1
  860.     MOV    CS:[SEGSTEP],AX
  861.  
  862.     MOV    AX,CS:[MSIZE]
  863.     INC    AX        ;ADDITIONAL ROW
  864.     MUL    CS:[SEGSTEP]
  865.     ADD    AX,CS:[SEGTOP]
  866.     MOV    CS:[SEGEND],AX    ;first segment after the matrix
  867.     
  868.     ;set 2ND MATRIX to unit matrix
  869.  
  870.     MOV    BX,CS:[SEGTOP]
  871.     MOV    DI,CS:[OFF2ND]
  872.     MOV    CX,CS:[MSIZE]
  873.     INC    CX        ;ADDITIONAL ROW
  874.     XOR    AX,AX
  875.     MOV    DX,CS:[SEGSTEP]
  876. INIT10:
  877.     PUSH    CX
  878.     MOV    ES,BX
  879.     MOV    DI,CS:[OFF2ND]
  880.     MOV    CX,CS:[MWORDS]
  881.     REP    STOSW
  882.     STOSW            ;ADDITIONAL COLUMN
  883.     ADD    BX,DX
  884.     POP    CX
  885.     LOOP    INIT10
  886.  
  887.     MOV    AX,CS:[SEGTOP]
  888.     MOV    SI,CS:[OFF2ND]
  889.     MOV    BX,CS:[SEGSTEP]
  890.     MOV    CX,CS:[MWORDS]    ;MSIZE/16
  891.     MOV    DX,1        ;DATA
  892. INIT20:
  893.     MOV    DS,AX
  894.     MOV    [SI],DX
  895.     ADD    AX,BX
  896.     ROL    DX,1
  897.     JNC    INIT20    
  898.     ADD    SI,2
  899.     LOOP    INIT20
  900.     MOV    DS,AX
  901.     MOV    [SI],DX        ;ADDITIONAL ROW & COLUMN
  902.  
  903.     ;set pointers to X(),Y()
  904.  
  905.     MOV_AX    LSIZE
  906.     MOV    DX,AX        ;number of bytes of X(),Y()
  907.     MOV    AX,CS:[SEGTOP]
  908.     MOV    SI,CS:[OFF3RD]
  909.     MOV    BX,CS:[SEGSTEP]
  910.     MOV    CX,CS:[MSIZE]
  911.     INC    CX
  912.     XOR    DI,DI
  913. INIT30:
  914.     MOV    DS,AX
  915.     MOV    [SI],DI
  916.     ADD    AX,BX
  917.     ADD    DI,DX
  918.     LOOP    INIT30
  919.     MOV    DS,AX
  920.     MOV    [SI],DI
  921.  
  922.     ;initialize index for GAUSSian elimination
  923.  
  924.     MOV    AX,CS
  925.     MOV    ES,AX
  926.     MOV    DI,CS:[ROWINDEXMIN]
  927.     MOV    CX,CS:[MSIZE]
  928.     MOV    AX,CS:[SEGTOP]
  929.     MOV    DX,CS:[SEGSTEP]
  930. INIT40:
  931.     STOSW
  932.     ADD    AX,DX
  933.     LOOP    INIT40
  934.     STOSW            ;ADDITIONAL ROW
  935.     MOV    CS:[ROWINDEXMAX],DI    ;STOPPER POSITION
  936.     ADD    AX,DX
  937.     STOSW            ;STOPPER ROW
  938.  
  939.     ;initialize YR%()
  940.  
  941.     MOV    BX,V8
  942.     MOV    AX,CS:[BX+2]
  943.     ADD    AX,ARRAYHEADSEG
  944.     MOV    CS:[YR_SEG],AX
  945.     MOV    ES,AX
  946.     MOV    CX,CS:[YR_SIZE]
  947.     XOR    DI,DI
  948.     XOR    AX,AX
  949.     MOV    BX,0FFFEH    ;DUMMY DATA
  950. INIT60:
  951.     STOSW
  952.     MOV    ES:[DI],BX
  953.     ADD    DI,2
  954.     LOOP    INIT60    
  955.     STOSW
  956.     INC    BX
  957.     MOV    ES:[DI],BX    ;FFFFH=STOPPER
  958.     MOV    CS:[STOP_PTR],DI
  959.  
  960.     ;initialize index for YR%()
  961.  
  962.     MOV    AX,CS
  963.     MOV    ES,AX
  964.     MOV    DI,OFFSET INDEX
  965.     XOR    AX,AX
  966.     MOV    CS:[YR_KOSU],AX
  967.     DEC    AX
  968.     MOV    CS:[MAXLOW],AX
  969.     MOV    CS:[MAXHIGH],AX
  970.     INC    AX
  971.     MOV    CX,CS:[YR_SIZE]
  972. INIT70:
  973.     STOSW
  974.     ADD    AX,4
  975.     LOOP    INIT70    
  976.     STOSW
  977.  
  978.     MOV_AX    AR3
  979.     MOV    AH,AL
  980.     MOV    CS:[LOG_INI],AX
  981.     MOV_AX    AR4
  982.     MOV    CS:[LOG_MAX],AX
  983.  
  984.     ;clear index
  985.  
  986.     XOR    AX,AX
  987.     MOV    [ROWINDEXNOW],AX
  988.  
  989.     MOV    AX,SS
  990.     MOV    DS,AX
  991.     MOV    ES,AX
  992.     POP    BP
  993.     RETF
  994.  
  995.  
  996. ;
  997. ; ** set a row
  998. ;    make row data from W#,X satisfying W#=X^2
  999.  
  1000. ;COMMAND#=2
  1001.  
  1002. SET_ROW:
  1003.     PUSH    BP
  1004.  
  1005.     ;copy X into X()
  1006.  
  1007.     MOV    SI,CS:[ROWINDEXNOW]
  1008.     MOV    AX,CS:[SI]
  1009.     MOV    CS:[SEGNOW],AX
  1010.     MOV    DS,AX
  1011.     MOV    BX,CS:[OFF3RD]
  1012.     MOV    DI,[BX]    
  1013.     MOV    ES,CS:[XA_SEG]
  1014.     LDS    SI,DWORD PTR CS:[X_OFF]
  1015.     MOV    CX,[SI]
  1016.     AND    CX,3FFFH
  1017.     INC    CX
  1018.     REP    MOVSW
  1019.  
  1020.     ;copy W into Y()
  1021.  
  1022.     MOV    DS,CS:[SEGNOW]
  1023.     MOV    BX,CS:[OFF3RD]
  1024.     MOV    DI,[BX]    
  1025.     MOV    ES,CS:[YA_SEG]
  1026.     LDS    SI,DWORD PTR CS:[WW_OFF]
  1027.     MOV    CX,[SI]
  1028.     AND    CX,3FFFH
  1029.     INC    CX
  1030.     REP    MOVSW
  1031.  
  1032. ;
  1033. ;* divide W#
  1034. ;
  1035.  
  1036.     LDS    SI,DWORD PTR CS:[WW_OFF]
  1037.     MOV    AX,[SI]
  1038.     AND    AX,8000H
  1039.     ROL    AX,1
  1040.     AND    WORD PTR [SI],3FFFH
  1041.     MOV    BX,SI        ;MEMO dividend
  1042.     MOV    ES,CS:[P_SEG]
  1043.     MOV    DI,AR0+10    ;pointer to PR%(1,0)
  1044.  
  1045.     MOV    CS:[ANSNOW],AX    ;16 bit result
  1046.     MOV    CS:[MASKNOW],2
  1047.     MOV    CS:[OFFNOW],0
  1048.  
  1049.     STD
  1050.  
  1051.     MOV    CX,CS:[MSIZE]
  1052.     DEC    CX        ;skip -1
  1053. DIVLP:
  1054.     MOV    BP,ES:[DI]    ;divisor
  1055.     ADD    DI,10
  1056.     PUSH    CX
  1057. DIV10:
  1058.     MOV    SI,BX
  1059.     MOV    AX,[SI]
  1060.     MOV    CX,AX        ;number of words
  1061.     SHL    AX,1
  1062.     ADD    SI,AX        ;highest word adr
  1063.     XOR    DX,DX    
  1064. DIV20:
  1065.     LODSW
  1066.     DIV    BP
  1067.     LOOP    DIV20
  1068.     OR    DX,DX
  1069.     JZ    DIV100        ;divide if divisible
  1070.  
  1071.     ROL    CS:[MASKNOW],1
  1072.     JNC    DIV30
  1073.     PUSH    DS        ;set result after each word
  1074.     PUSH    BX
  1075.     MOV    DS,CS:[SEGNOW]
  1076.     MOV    BX,CS:[OFFNOW]
  1077.     MOV    AX,CS:[ANSNOW]
  1078.     MOV    [BX],AX        ;set result
  1079.     MOV    CS:[ANSNOW],0
  1080.     ADD    BX,2
  1081.     MOV    CS:[OFFNOW],BX
  1082.     POP    BX
  1083.     POP    DS
  1084. DIV30:    
  1085.     POP    CX
  1086.     LOOP    DIVLP
  1087.     CLD
  1088.  
  1089.     ADD    CS:[ROWINDEXNOW],2
  1090.  
  1091.     MOV    AX,SS
  1092.     MOV    DS,AX
  1093.     MOV    ES,AX
  1094.     POP    BP
  1095.     RETF            ;EXIT POINT
  1096.  
  1097.  
  1098.     ;if completely decomposed
  1099. DIV100:
  1100.     MOV    AX,CS:[MASKNOW]
  1101.     XOR    CS:[ANSNOW],AX
  1102.  
  1103.     MOV    SI,BX
  1104.     MOV    AX,[SI]
  1105.     MOV    CX,AX        ;WORDS
  1106.     SHL    AX,1
  1107.     ADD    SI,AX        ;highest word adr
  1108.     XOR    DX,DX    
  1109.     LODSW
  1110.     DIV    BP
  1111.     PUSH    AX        ;value of highest word
  1112.     JMP    SHORT DIV120
  1113. DIV110:
  1114.     LODSW
  1115.     DIV    BP
  1116. DIV120:
  1117.     MOV    [SI+2],AX
  1118.     LOOP    DIV110
  1119.     POP    AX        ;value of highest word
  1120.     OR    AX,AX
  1121.     JNZ    DIV130
  1122.     DEC    WORD PTR [SI]    ;dec len if highest word = 0
  1123. DIV130:
  1124.     JMP    DIV10
  1125.  
  1126.  
  1127. ;** answer: square number got by GAUSSian elimination
  1128. ;     return BIT PATTERN in W#
  1129.  
  1130. ;COMMAND#=6
  1131.  
  1132.     ;STARTS HERE
  1133.  
  1134. SQUARE_ANS:
  1135.     MOV    SI,CS:[ROWINDEXNOW2]
  1136.     CMP    SI,CS:[ROWINDEXLIM]
  1137.     JAE    NO_ANS
  1138.  
  1139.     MOV    ES,CS:[SI]
  1140.     MOV    CX,CS:[MWORDS]
  1141.     MOV    DI,CX
  1142.     INC    CX
  1143.     SHL    DI,1
  1144.     SHL    DI,1        ;ADR OF LAST WORD OF 2ND MATRIX
  1145.     XOR    AX,AX
  1146.     STD
  1147.     REP    SCASW    
  1148.     CLD
  1149.     INC    CX        ;WORDS
  1150.  
  1151.     MOV    AX,ES
  1152.     MOV    DS,AX
  1153.     MOV    SI,CS:[OFF2ND]
  1154.  
  1155.     LES    DI,DWORD PTR CS:[WW_OFF]        
  1156.  
  1157.     MOV    AX,CX
  1158.     STOSW
  1159.     REP    MOVSW
  1160.  
  1161.     ADD    CS:[ROWINDEXNOW2],2
  1162. ANS100:
  1163.     MOV    AX,SS
  1164.     MOV    DS,AX
  1165.     MOV    ES,AX
  1166.     RETF
  1167.  
  1168.  
  1169. NO_ANS:
  1170.     LES    DI,DWORD PTR CS:[WW_OFF]        
  1171.     XOR    AX,AX
  1172.     STOSW
  1173.     JMP    ANS100
  1174.  
  1175.  
  1176.     EVEN
  1177. INDEX    DW    ?
  1178.  
  1179. CODE    ENDS
  1180. END    START
  1181.