home *** CD-ROM | disk | FTP | other *** search
/ World of Shareware - Software Farm 2 / wosw_2.zip / wosw_2 / GENERAL / DSCALC.ZIP / DSCALC.SC next >
Text File  |  1990-01-23  |  180KB  |  5,301 lines

  1. ;-- library creation, errorchecking, messaging routine
  2.  
  3. if version() < 3 then
  4.    message "Sorry, version 3 or higher of Paradox required for DSCalc."
  5.    for x from 1 to 5
  6.       beep
  7.       sleep 250
  8.    endfor
  9.    return false
  10. endif
  11.  
  12.  
  13. if version() > 3 then
  14.    beep beep
  15.    style reverse
  16.    clear
  17.    @ 00,00 ?? format("w80,al",
  18.       "Warning! Creating the DSCalc library under" +
  19.       " a Version greater than 3 of Paradox    ")
  20.    @ 01,00 ?? format("w80,al",
  21.       "will not allow you to run the calculator i" +
  22.       "n version 3 of Paradox.")
  23.    @ 02,00 ?? format("w80,al",
  24.       "Creating the library under version 3 will " +
  25.       "allow you to use the calculator with")
  26.    @ 03,00 ?? format("w80,al",
  27.       "a version greater than 3 of Paradox however.")
  28.    @ 04,00 ?? format("w80,al",
  29.       "Press [F2] to continue, any other key to cancel creating the library.")
  30.    key.pressed.s = getchar()
  31.    if key.pressed.s <> -60 then
  32.       message "Creating of the library has been canceled!"
  33.       for x from 1 to 5
  34.          beep
  35.          sleep 250
  36.       endfor
  37.       sleep 2500
  38.       return false
  39.    endif
  40. endif
  41.  
  42. ? "Creating the DSCalc Library."
  43.  
  44. if not isassigned(ds.aplib.a) or
  45.    not isdirname(ds.aplib.a) then
  46.    ds.aplib.a = "dscalc"
  47. endif
  48.  
  49. createlib ds.aplib.a size 65
  50. ;-------------------------------------------------------------------------------
  51. ;                                                                    ds.calc.v()
  52. ;-------------------------------------------------------------------------------
  53. ; purpose: main level procedure for displaying and operating this application
  54. proc closed ds.calc.v(
  55. ds.aplib.a,                   ;-- the library name for autolib
  56. ds.tape.length.s,             ;-- number of entries allowed in the tape
  57. ds.set.swap.n,                ;-- the setswap value
  58. ds.save.memory.l,             ;-- logical flag to save memory arrays
  59. ds.custom.lib.a,              ;-- name of custom library
  60. ds.print.tape.a)              ;-- "ON" or "OFF to allow/disallow printing
  61.  
  62.  
  63.  
  64. private
  65. ds.neg.key.a,                 ;-- alpha string ala DETK to determine whether
  66.                               ;-- to accept or reject keys pressed by the user
  67. ds.pos.key.a,                 ;-- neg.key to process negative ascii values
  68.                               ;-- pos.key to process positive ascii values
  69. ds.char.s,                    ;-- ascii value assigned with getchar()
  70. ds.char.was.v,                ;-- the previous key pressed.  it may also
  71.                               ;-- hold the value "No" if the previous key
  72.                               ;-- need not be determined
  73. ds.key.type.a,                ;-- value extracted from ds.neg.key.a or
  74.                               ;-- ds.pos.key.a based on the value in ds.char.s
  75. autolib,                      ;-- allows declaration of a private autolib
  76. ds.tape.count.s,              ;-- array element number for ds.tape.r,
  77.                               ;-- ds.tape.function.r, ds.decimal.r and
  78.                               ;-- ds.total.was.r arrays
  79. ds.tape.r,                    ;-- array of tape entries
  80. ds.tape.function.r,           ;-- sign array associated with ds.tape.r
  81.                               ;--  "-", "+", "/", "*" or "="
  82. ds.memory.r,                  ;-- memory array
  83. ds.decimal.r,                 ;-- logical storage array to determine
  84.                               ;-- format of the value stored in ds.tape.r
  85. ds.total.was.r,               ;-- array of sub totals created
  86. ds.total.element.num.was.s,   ;-- remembers the last array element that
  87.                               ;-- stores a value in the ds.total.was.r array
  88. ds.memory.element.r,          ;-- a listing of array elements for ds.memory.r
  89. ds.rebuild.l,                 ;-- logical flag determines when the calculator
  90.                               ;-- need to be re-displayed on the screen
  91. ds.loop.counter.s,            ;-- a general loop counter
  92. ds.press.it.a                 ;-- saves  from having to type
  93.                               ;-- "Press any key to continue." a few hundred
  94.                               ;-- times
  95.  
  96. ;-- define the private autolib for this application
  97. autolib = ds.aplib.a
  98.  
  99. ;-- set this global variable
  100. ds.press.it.a = "Press any key to continue."
  101.  
  102. ;-- set up arrays, global variables, etc.
  103. ds.set.vars.u("all")
  104.  
  105. ;-- setup the setswap value
  106. setswap ds.set.swap.n
  107.  
  108. ;-- define the memory arrays from a previous session when ds.save.memory.l
  109. ;-- is set to true
  110. if ds.save.memory.l and
  111.    isfile( privdir() + "dssvmem.sc") then
  112.    play privdir() + "dssvmem"
  113. endif
  114.  
  115. ;-- define the variables that determine if a key stroke is legal
  116. ;-- two variables are used as the maximum length of a variable is
  117. ;-- 255 characters and there are 398 possible keys values that can be
  118. ;-- accepted with a getchar()
  119. ;-- this may be a bit of an overkill but it allows a lot of customizing
  120. ;-- quite easily using the dskeys.sc to re-define the acceptable keys
  121. ;-- used in this application
  122. ds.neg.key.a="iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiisiiiiiiiiiiiissiii"+
  123.              "iisisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiissiiiiiiiiiiiiiiii"+
  124.              "iiiii"
  125.  
  126. ds.pos.key.a="iiiiiiisiiiisiiiiiiiiiiiiieiiiiiiiiiiiiiississsrrrrrrrrrriiisiii"+
  127.              "iisiiiiiiiiisiiiiiiiiiiiiiiiiiiiiisiiiiiiiiisiiiiiiiiiiiiiiiiisi"+
  128.              "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"+
  129.              "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"
  130.  
  131. cursor off
  132.  
  133. ;-- places a picture of a calculator on the screen
  134. ds.calc.screen.u()
  135.  
  136. ;-- the main loop in the application.  this loop will not be exited until
  137. ;-- the user chooses to stop using the calculator.  all other procedures
  138. ;-- are called from within this loop or from procedures that this loop calls
  139. while true
  140.  
  141.    ;-- error checking so that the array size will not be exceeded
  142.    if ds.tape.count.s < ds.tape.length.s then
  143.       ds.char.s = getchar()
  144.    else
  145.       ;-- ds.error.u sets up and displays various messages
  146.       ;-- to the user as required
  147.       ds.error.u(
  148.       "SORRY! YOU HAVE REACHED THE LIMIT OF THE TAPE!" +
  149.       " ALL ENTRIES WILL BE CLEARED!",
  150.       "Press any key to clear the calculator and continue.")
  151.       ;-- sometimes paradox "erases" the last column on the canvas
  152.       ;-- this has something to do with the prompt placed
  153.       ;-- regarding selection of menu choices
  154.       ;-- at least this did happen in version 2
  155.       ;-- this little trick brings back the last line on the screen!
  156.       canvas off
  157.       message ""
  158.       @ 22,78 clear eol
  159.       canvas on
  160.  
  161.       ;-- pass on a clear the calculator keypress
  162.       ds.char.s = -111
  163.    endif
  164.  
  165.    ;-- determine what type of key was pressed by extracting the
  166.    ;-- letter from ds.neg.key.a or ds.pos.key.a
  167.    if ds.char.s > 0 then
  168.       ds.key.type.a = substr(ds.pos.key.a,ds.char.s,1)
  169.    else
  170.       ds.key.type.a = substr(ds.neg.key.a,1-ds.char.s,1)
  171.    endif
  172.  
  173.    ;-- this switch processes the key that was pressed
  174.    switch
  175.  
  176.       ;-- illegal
  177.       case ds.key.type.a = "i" :
  178.          beep
  179.  
  180.       ;-- regular
  181.       case ds.key.type.a = "r" :
  182.          ;-- press the key on the calculator
  183.          ds.key.press.u()
  184.          ;-- actually process it
  185.          ds.regular.u()
  186.          ;-- now display and/or update the calculator screen
  187.          ds.display.u()
  188.  
  189.       ;-- special keys get processed in this loop
  190.       case ds.key.type.a = "s" :
  191.          ds.special.key.u()
  192.  
  193.       ;-- process the request to exit
  194.       case ds.key.type.a = "e" :
  195.          ds.exit.v()
  196.          ;-- again, make the bottom line re-appear
  197.          canvas off
  198.          message ""
  199.          @ 22,78 clear eol
  200.          canvas on
  201.  
  202.          ;-- process the returned value of ds.exit.v
  203.          switch
  204.  
  205.             ;-- the canceled the exit
  206.             case retval = "No " :
  207.                loop
  208.  
  209.             ;-- the do want to leave with a value so now another switch
  210.             case retval :
  211.                ;-- process the last value in the tape and
  212.                ;-- make the proper assignment to retval
  213.                switch
  214.  
  215.                   ;-- returns the current entry in the calculator
  216.                   ;-- only if there is a single entry
  217.                   case ds.tape.count.s = 1 and
  218.                      isassigned(ds.tape.r[ds.tape.count.s]) and
  219.                      ds.tape.r[ds.tape.count.s] <> blanknum() :
  220.                      retval = numval(ds.tape.r[ds.tape.count.s])
  221.  
  222.                   ;-- returns the current entry in the calculator
  223.                   case ds.tape.count.s > 1 and
  224.                      isassigned(ds.tape.r[ds.tape.count.s]) and
  225.                      ds.tape.r[ds.tape.count.s] <> blanknum() :
  226.                      retval = numval(ds.tape.r[ds.tape.count.s])
  227.  
  228.                   ;-- returns the last assigned tape entry
  229.                   case ds.tape.count.s > 1 and
  230.                      isassigned(ds.tape.r[ds.tape.count.s-1]) and
  231.                      ds.tape.r[ds.tape.count.s-1] <> blanknum() :
  232.                      retval = numval(ds.tape.r[ds.tape.count.s-1])
  233.  
  234.                   ;-- in case there is no usable entry to return
  235.                   otherwise :
  236.                      retval= false
  237.  
  238.                endswitch
  239.  
  240.             ;-- the last possible retval of ds.exit.v
  241.             ;-- probably not required but what the hey
  242.             case not retval :
  243.                retval = false
  244.  
  245.          endswitch
  246.  
  247.       ;-- if the last value in the tape did not have a
  248.       ;-- numeric value the re-assign retval
  249.       if lower(retval) = "error" then
  250.          retval = false
  251.       endif
  252.  
  253.       ;-- save the memory variables if saving is enabled
  254.       if ds.save.memory.l then
  255.          @ 00,00 clear eol ?? "Working"
  256.          style blink ?? "....."
  257.          @ 01,00 clear eol style
  258.          ?? "Saving Memory Arrays."
  259.          ds.save.memory.u()
  260.       endif
  261.  
  262.       return retval
  263.  
  264.    endswitch
  265.  
  266. endwhile
  267.  
  268. endproc
  269.  
  270. ?? "." message memleft() writelib ds.aplib.a ds.calc.v
  271. release procs ds.calc.v
  272.  
  273.  
  274. ;-------------------------------------------------------------------------------
  275. ;                                                             ds.calc.screen.u()
  276. ;-------------------------------------------------------------------------------
  277. ; purpose: places the calculator on the screen
  278. proc ds.calc.screen.u()
  279.  
  280. ;-- inform the user something is happening
  281. @ 00,00 clear eol ?? "Working"
  282. style blink ?? "....."
  283. @ 01,00 clear eol style
  284.  
  285. ;-- turns the canvas off
  286. canvas off
  287.  
  288. clear
  289. style
  290.  
  291. ;-- place the main prompt on the screen
  292. ds.main.prompt.u()
  293.  
  294. ;-- set the reverse video mode
  295. style reverse
  296.  
  297. ;-- set a margin for this block
  298. setmargin 43
  299.  
  300. @ 2,43
  301. text
  302. ╔═════ [Alt-F7] Review/Print ═════╗
  303. ║       Tape             Function ║
  304. ╟──────────────────────────┬──────╢
  305. endtext
  306.  
  307. ;-- now turn it off
  308. setmargin off
  309.  
  310. ;-- normal video
  311. style
  312.  
  313. ;-- fill in the rest of the calculator
  314. @ 2,0
  315. text
  316. ┌───────────────────────────┐
  317. │░░░░░░░░░░░░░░░░░░░░░░░░░░░│
  318. │░░╔═════════════════════╗░░│
  319. │░░║                     ║░░│              ║                          │      ║
  320. │░░╚═════════════════════╝░░│              ║                          │      ║
  321. │░░░░░░░░░░░░░░░░░░░░░░░░░░░│              ║                          │      ║
  322. │░░┌───┐  ┌───┐  ┌───┐░░░░░░│              ║                          │      ║
  323. │░░│ 7 │  │ 8 │  │ 9 │░░ + ░│ Add          ║                          │      ║
  324. │░░└───┘  └───┘  └───┘░░░░░░│              ║                          │      ║
  325. │░░┌───┐  ┌───┐  ┌───┐░░ - ░│ Subtract     ║                          │      ║
  326. │░░│ 4 │  │ 5 │  │ 6 │░░░░░░│              ║                          │      ║
  327. │░░└───┘  └───┘  └───┘░░ * ░│ Multiply     ║                          │      ║
  328. │░░┌───┐  ┌───┐  ┌───┐░░░░░░│              ║                          │      ║
  329. │░░│ 1 │  │ 2 │  │ 3 │░░ / ░│ Divide       ║                          │      ║
  330. │░░└───┘  └───┘  └───┘░░░░░░│              ║                          │      ║
  331. │░░ ┌───────┐  ┌───┐  ░░░░░░│              ║                          │      ║
  332. │░░ │   0   │  │ . │  ░░ = ░│ Equals or    ║                          │      ║
  333. │░░ └───────┘  └───┘  ░░░░░░│ Enter        ║                          │      ║
  334. │░░░░░░░░░░░░░░░░░░░░░░░░░░░│              ║                          │      ║
  335. │░░░ [Alt-C] = Clear All ░░░│              ║                          │      ║
  336. │░░░  [C] = Clear Entry  ░░░│              ║                          │      ║
  337. │░░░░░░ [M]= Memory ░░░░░░░░│              ║                          │      ║
  338. └───────────────────────────┘              ╚ Tape Entries Left =   ═══╧══════╝
  339. endtext
  340.  
  341. ;-- displays number of tape entries left in the array
  342. @ 24,65 ?? strval(ds.tape.length.s-1) + " "
  343.  
  344. ;-- turn the canvas back on
  345. canvas on
  346.  
  347. endproc
  348.  
  349. ?? "." message memleft() writelib ds.aplib.a ds.calc.screen.u
  350. release procs ds.calc.screen.u
  351.  
  352. ;-------------------------------------------------------------------------------
  353. ;                                                                    ds.exit.v()
  354. ;-------------------------------------------------------------------------------
  355. ; purpose: displays the exit menu and the choices
  356. proc ds.exit.v()
  357.  
  358. private
  359. ds.exit.choice.a
  360.  
  361. showmenu
  362.    "No "     : " Do not exit DSCalc.",
  363.    "Return " : " Return with the last entry in the calculator.",
  364.    "Esc "    : " Return without the a value."
  365.    to ds.exit.choice.a
  366.    switch
  367.        ;-- user wanted to return to using the calculator
  368.        case ds.exit.choice.a = "No " :
  369.           return ds.exit.choice.a
  370.        ;-- user wants the last entry returned
  371.        case ds.exit.choice.a = "Return " :
  372.          return true
  373.        ;-- "Esc " or "Esc" was selected
  374.        otherwise : return false
  375.    endswitch
  376. endproc
  377.  
  378. ?? "." message memleft() writelib ds.aplib.a ds.exit.v
  379. release procs ds.exit.v
  380.  
  381. ;-------------------------------------------------------------------------------
  382. ;                                                                 ds.regular.u()
  383. ;-------------------------------------------------------------------------------
  384. ; purpose: handles keys that are defined as "regular" keys.  no special
  385. ;          handling.  unless changed, the only regular keys are the
  386. ;          numbers 0 through 9
  387. proc ds.regular.u()
  388.  
  389. ;-- the ds.char.r array elements are stored as strings
  390. ;-- this way the strings can be added together to create ]
  391. ;-- whole number
  392. ;-- if the element was numeric, then when attempting
  393. ;-- to type in "12", the variable would become 3
  394. ;-- so if it is previously assigned add the strings
  395. if isassigned(ds.tape.r[ds.tape.count.s]) then
  396.    ds.tape.r[ds.tape.count.s] =
  397.       strval(ds.tape.r[ds.tape.count.s]) +
  398.       strval(chr(ds.char.s))
  399.  else
  400.    ds.tape.r[ds.tape.count.s] =
  401.       chr(ds.char.s)
  402. endif
  403.  
  404. switch
  405.    ;-- this case eliminates leading zeros
  406.    case numval(ds.tape.r[ds.tape.count.s]) = 0 and
  407.       not ds.decimal.r[ds.tape.count.s]     :
  408.       ds.tape.r[ds.tape.count.s] = blanknum()
  409.       beep
  410.    ;-- this case allows negatives and negative decimals
  411.    case numval(ds.tape.r[ds.tape.count.s]) = "error" and
  412.       len(ds.tape.r[ds.tape.count.s]) = 2      :
  413.       ds.tape.r[ds.tape.count.s] = "-0."
  414. endswitch
  415.  
  416. endproc
  417.  
  418. ?? "." message memleft() writelib ds.aplib.a ds.regular.u
  419. release procs ds.regular.u
  420.  
  421.  
  422. ;-------------------------------------------------------------------------------
  423. ;                                                             ds.special.key.u()
  424. ;-------------------------------------------------------------------------------
  425. ; purpose: handles the "special" keys accepted by the program.  these include
  426. ;          the math keys, help systems, clear entries, clear the calculator,
  427. ;          etc.
  428. proc ds.special.key.u()
  429.  
  430. switch
  431.  
  432.    ; alt-f7 - review-print tape
  433.    case ds.char.s = -110 :
  434.       ;-- clear the top 2 lines
  435.       @ 00,00 clear eol
  436.       @ 01,00 clear eol
  437.       ;-- call the procedure that processes this request
  438.       ds.review.print.u()
  439.       ;-- this variable is set to true if the screen needs to
  440.       ;-- be "refreshed"
  441.       if ds.rebuild.l then
  442.          ;-- if it does then do_it!
  443.          ds.rebuild.l()
  444.       else
  445.          ;-- replace the main prompt
  446.          ds.main.prompt.u()
  447.       endif
  448.       ;-- place the appropriate entry into the calculator screen
  449.       ds.display.u()
  450.  
  451.    ;-- alt-f8 or alt-c indicates to reset and clear the calculator
  452.    case ds.char.s = -111 or
  453.         ds.char.s =  -46 :
  454.  
  455.       ;-- re-assign the variable to the value used by the other procedures
  456.       ds.char.s = -111
  457.       ;-- toggle the keypad on
  458.       ds.key.press.u()
  459.       ;-- a slight delay for effect
  460.       sleep 250
  461.       ;-- re-assign it again to clear the keypad
  462.       ds.char.s = 1000
  463.       ;-- toggle the keypad off
  464.       ds.key.press.u()
  465.       ;-- clear the calculator window
  466.       @ 05,04 ?? spaces(21)
  467.       ;-- reset the required variables
  468.       ds.set.vars.u("some")
  469.       ;-- now clear and re-display the screen
  470.       ds.calc.screen.u()
  471.  
  472.    ;-- [f8], ctrlbackspace, C or c indicates
  473.    ;-- to clear the current entry only
  474.    case ds.char.s = -66 or
  475.         ds.char.s = 127 or
  476.         ds.char.s =  99 or
  477.         ds.char.s =  67 :
  478.  
  479.       ;-- re-assign the variable to the value used by the other procedures
  480.       ds.char.s = -66
  481.       ;-- toggle the keypad on
  482.       ds.key.press.u()
  483.       ;-- a slight delay for effect
  484.       sleep 250
  485.       ;-- re-assign it again to clear the keypad
  486.       ds.char.s = 1000
  487.       ;-- reset the current array element
  488.       ds.decimal.r[ds.tape.count.s] = false
  489.       ;-- toggle the keypad off
  490.       ds.key.press.u()
  491.       ;-- reset the current array element
  492.       ds.tape.r[ds.tape.count.s] = blanknum()
  493.       ;-- clear the calculator window
  494.       @ 05,04 ?? spaces(21)
  495.  
  496.    ;-- the user opted to see the menu by pressing [f10]
  497.    case ds.char.s = -68 :
  498.       ;-- clear the top 2 lines
  499.       @ 00,00 clear eol
  500.       @ 01,00 clear eol
  501.       ;-- so call the menu procedure
  502.       ds.menu.u()
  503.       ;-- this variable is set to true if the screen needs to
  504.       ;-- be "refreshed"
  505.       if ds.rebuild.l then
  506.          ;-- if it does then do_it!
  507.          ds.rebuild.l()
  508.       else
  509.          ;-- replace the main prompt
  510.          ds.main.prompt.u()
  511.       endif
  512.       ;-- re-display the calculator window
  513.       ds.display.u()
  514.  
  515.    ;-- [f2], = or enter indicates to calculate the total
  516.    case ds.char.s = -60 or
  517.         ds.char.s =  61 or
  518.         ds.char.s =  13 :
  519.  
  520.       ;-- re-assign the variable to the value used by the other procedures
  521.       ds.char.s = 61
  522.       ;-- toggle the keypad on
  523.       ds.key.press.u()
  524.       ;-- now actually compute the total
  525.       ds.total.u()
  526.       ;-- toggle the keypad off
  527.       ds.key.press.u()
  528.       ;-- re-display the main prompt
  529.       ds.main.prompt.u()
  530.  
  531.    ;-- user wants some help!  presses [f1]
  532.    case ds.char.s = -59 :
  533.       ;-- clear the top 2 lines
  534.       @ 00,00 clear eol
  535.       @ 01,00 clear eol
  536.       ;-- call the help routine
  537.       ds.help.menu.u()
  538.       ;-- this variable is set to true if the screen needs to
  539.       ;-- be "refreshed"
  540.       if ds.rebuild.l then
  541.          ;-- if it does then do_it!
  542.          ds.rebuild.l()
  543.          ;-- replace the main prompt
  544.          ds.main.prompt.u()
  545.       endif
  546.  
  547.    ;-- the user pressed the backspace key to delete the last
  548.    ;-- character typed in.  nice touch!  try this on a regular
  549.    ;-- calculator some time!
  550.    case ds.char.s = 8 :
  551.       ;-- toggle the keypad off as 8 is not a valid
  552.       ;-- keypad key
  553.       ds.key.press.u()
  554.       ;-- this only works if the array element is assigned a value
  555.       ;-- and it's length is > 1
  556.       if isassigned(ds.tape.r[ds.tape.count.s]) and
  557.          len(ds.tape.r[ds.tape.count.s]) > 1 then
  558.          ;-- find out the last key pressed
  559.          ds.char.was.v =
  560.          substr(ds.tape.r[ds.tape.count.s],len(ds.tape.r[ds.tape.count.s]),1)
  561.          ;-- shorten the string by one character
  562.          ds.tape.r[ds.tape.count.s] =
  563.          substr(ds.tape.r[ds.tape.count.s],1,len(ds.tape.r[ds.tape.count.s])-1)
  564.          ;-- if the last character was a period, reset the array
  565.          ;-- element that defines the variable as a whole or fractional
  566.          ;-- value for display purposes
  567.          if asc(ds.char.was.v) = 46 then
  568.             ds.decimal.r[ds.tape.count.s] = false
  569.          endif
  570.          ;-- re-display the new value in the calculator window
  571.          ds.display.u()
  572.       else
  573.          ;-- re-assign the arrays as required just in case
  574.          ds.tape.r[ds.tape.count.s] = blanknum()
  575.          ds.decimal.r[ds.tape.count.s] = false
  576.          ;-- beep at the user, there really wasn't anything
  577.          ;-- to backspace anyway
  578.          beep
  579.          ;-- clear the calculator window
  580.          @ 05,04 ?? spaces(21)
  581.       endif
  582.  
  583.    ;-- user wants to indicate that the value is to be multiplied (*),
  584.    ;-- added (+) or divided (/) into the preceding value
  585.    case ds.char.s = 42 or            ; multiply *
  586.         ds.char.s = 43 or            ; add +
  587.         ds.char.s = 47 :             ; divide /
  588.  
  589.       ;-- toggle the keypad on
  590.       ds.key.press.u()
  591.       ;-- add it to the tape window
  592.       ds.tape.display.l()
  593.  
  594.    ;-- subtract takes special processing.  the user may be indicating
  595.    ;-- that the number is negative.
  596.    case ds.char.s = 45 :
  597.  
  598.       ;-- this is a negative number
  599.       if not isassigned(ds.tape.r[ds.tape.count.s]) or
  600.          len(ds.tape.r[ds.tape.count.s]) = 0 then
  601.          ;-- toggle the keypad on
  602.          ds.key.press.u()
  603.          ;-- so it becomes a regular key instead of special
  604.          ds.regular.u()
  605.          ;-- update the calculator window
  606.          ds.display.u()
  607.       else
  608.          ;-- here it is added it to the tape window
  609.          ;-- because they want to subtract it!
  610.          ds.tape.display.l()
  611.       endif
  612.  
  613.    ;-- user is indication a decimal
  614.    case ds.char.s = 46 :
  615.  
  616.       ;-- toggle the keypad on
  617.       ds.key.press.u()
  618.       ;-- if it's already a decimal, beep at them for being dumb!
  619.       if ds.decimal.r[ds.tape.count.s] then
  620.          beep
  621.       else
  622.          ;-- set the array variable as appropriate
  623.          ds.decimal.r[ds.tape.count.s] = true
  624.          ;-- it now becomes a regular key
  625.          ds.regular.u()
  626.          ;-- update/display the calculator window
  627.          ds.display.u()
  628.       endif
  629.  
  630.    ; user pressed M or m for memory
  631.    case ds.char.s = 77 or
  632.         ds.char.s = 109 :
  633.  
  634.       ;-- re-assign the variable to the value used by the other procedures
  635.       ds.char.s = 77
  636.       ;-- toggle the keypad on
  637.       ds.key.press.u()
  638.       ;-- clear the top 2 lines
  639.       @ 00,00 clear eol
  640.       @ 01,00 clear eol
  641.       ;-- call the memory procedure
  642.       ds.memory.u()
  643.       ;-- replace the main prompt
  644.       ds.main.prompt.u()
  645.  
  646. endswitch
  647.  
  648. endproc
  649.  
  650. ?? "." message memleft() writelib ds.aplib.a ds.special.key.u
  651. release procs ds.special.key.u
  652.  
  653.  
  654. ;-------------------------------------------------------------------------------
  655. ;                                                               ds.key.press.u()
  656. ;-------------------------------------------------------------------------------
  657. ; purpose: simulates pressing a key on the keypad by toggling styles
  658. proc ds.key.press.u()
  659.  
  660. ;-- there was a previous key to turn off so turn
  661. ;-- it off with this call
  662. if lower(ds.char.was.v) <> "no" then
  663.    ds.key.press.toggle.u(ds.char.was.v)
  664. endif
  665.  
  666. ;-- this sets up a slight flicker between turning
  667. ;-- one key off and the next one on
  668. if ds.char.was.v = ds.char.s then
  669.    sleep 50
  670. endif
  671.  
  672. ;-- re-assign the variable for the next call to this procedure
  673. ds.char.was.v = ds.char.s
  674.  
  675. ;-- set the style
  676. style reverse
  677.  
  678. ;-- toggle the last key pressed on
  679. ds.key.press.toggle.u(ds.char.s)
  680.  
  681. ;-- reset the style
  682. style
  683.  
  684. endproc
  685.  
  686. ?? "." message memleft() writelib ds.aplib.a ds.key.press.u
  687. release procs ds.key.press.u
  688.  
  689.  
  690. ;-------------------------------------------------------------------------------
  691. ;                                               ds.key.press.toggle.u(ds.char.s)
  692. ;-------------------------------------------------------------------------------
  693. ; purpose: repaints the required area of the screen with the appropriate key
  694. ;          that was pressed
  695. proc ds.key.press.toggle.u(
  696. ds.char.s)                    ;-- passed parameter for the following
  697.                               ;-- case statement
  698.  
  699. switch
  700.    case ds.char.s =   48 : @ 18,07  ?? " 0 "
  701.    case ds.char.s =   49 : @ 15,04  ?? " 1 "
  702.    case ds.char.s =   50 : @ 15,11  ?? " 2 "
  703.    case ds.char.s =   51 : @ 15,18  ?? " 3 "
  704.    case ds.char.s =   52 : @ 12,04  ?? " 4 "
  705.    case ds.char.s =   53 : @ 12,11  ?? " 5 "
  706.    case ds.char.s =   54 : @ 12,18  ?? " 6 "
  707.    case ds.char.s =   55 : @ 09,04  ?? " 7 "
  708.    case ds.char.s =   56 : @ 09,11  ?? " 8 "
  709.    case ds.char.s =   57 : @ 09,18  ?? " 9 "
  710.    case ds.char.s = -111 : @ 21,05  ?? "[Alt-C]"
  711.    case ds.char.s =  -66 : @ 22,06  ?? "[C]"
  712.    case ds.char.s =   61 : @ 18,24  ?? " = "
  713.    case ds.char.s =   42 : @ 13,24  ?? " * "
  714.    case ds.char.s =   43 : @ 09,24  ?? " + "
  715.    case ds.char.s =   45 : @ 11,24  ?? " - "
  716.    case ds.char.s =   46 : @ 18,16  ?? " . "
  717.    case ds.char.s =   47 : @ 15,24  ?? " / "
  718.    case ds.char.s =   77 : @ 23,08  ?? "[M]"
  719. endswitch
  720.  
  721. endproc
  722.  
  723. ?? "." message memleft() writelib ds.aplib.a ds.key.press.toggle.u
  724. release procs ds.key.press.toggle.u
  725.  
  726.  
  727. ;-------------------------------------------------------------------------------
  728. ;                                                                 ds.display.u()
  729. ;-------------------------------------------------------------------------------
  730. ; purpose: displays the value of the current tape element in the calculator
  731. ;          window
  732. proc ds.display.u()
  733.  
  734. switch
  735.  
  736.    ;-- no assignment yet or is was re-assigned to
  737.    ;-- blanknum()
  738.    case not isassigned(ds.tape.r[ds.tape.count.s]) or
  739.         ds.tape.r[ds.tape.count.s] = blanknum() :
  740.  
  741.       ;-- clear the window
  742.       @ 05,04 ?? spaces(21)
  743.  
  744.    ;-- indicates a negative number or zero or
  745.    ;-- the value is a decimal
  746.    ;-- decimal values are not formatted with commas as there
  747.    ;-- would need to be a special case for the number places
  748.    ;-- after the decimal to be displayed and formatted
  749.    ;-- correctly
  750.    ;-- this became cumbersome so it was decided to take
  751.    ;-- this approach
  752.    case ds.tape.r[ds.tape.count.s] = "-" or
  753.         numval(ds.tape.r[ds.tape.count.s]) = 0 or
  754.         ds.decimal.r[ds.tape.count.s] :
  755.  
  756.       ;-- no special formatting to display the variable
  757.       @ 05,04 ?? format("w20,ar",strval(ds.tape.r[ds.tape.count.s]))
  758.  
  759.    ;-- non-decimals
  760.    case not ds.decimal.r[ds.tape.count.s] :
  761.  
  762.       ;-- format with commas
  763.       @ 05,04 ?? format("w20,ar,ec",numval(ds.tape.r[ds.tape.count.s]))
  764.  
  765. endswitch
  766.  
  767. endproc
  768.  
  769. ?? "." message memleft() writelib ds.aplib.a ds.display.u
  770. release procs ds.display.u
  771.  
  772. ;-------------------------------------------------------------------------------
  773. ;                                                                ds.set.vars.u()
  774. ;-------------------------------------------------------------------------------
  775. ; purpose: sets/reset some or all of the variables used in this program
  776. ;          called in the initial start up and during clear alls of the
  777. ;          calculator and clearing memory, etc.
  778. proc ds.set.vars.u(
  779. all.or.some.a)      ;-- this variable controls which variables
  780.                     ;-- need to be set/reset
  781.  
  782. private
  783. ds.loop.counter.s   ;-- a loop counter
  784.  
  785. ;-- sets memory variables as required based on the passed parameter
  786. if lower(all.or.some.a) = "all" or
  787.    lower(all.or.some.a) = "memory" then
  788.    ;-- defines the arrays.  if they were previously defined,
  789.    ;-- this will clear all of the elements
  790.    ;-- these arrays are used in a showarray
  791.    array ds.memory.r[20]
  792.    array ds.memory.element.r[20]
  793.    ;-- go through this loop and assign elements of the arrays
  794.    ;-- except the first
  795.    for ds.loop.counter.s from 2 to 20
  796.       ds.memory.r[ds.loop.counter.s] = "Not Assigned"
  797.       ds.memory.element.r[ds.loop.counter.s] = strval(ds.loop.counter.s-1)
  798.    endfor
  799.    ;-- assign the first elements of the arrays
  800.    ds.memory.element.r[1] = "Select »"
  801.    ds.memory.r[1] = "Use the [] [" + chr(26) +
  802.                     "] keys to select the Memory # then press [Enter]." +
  803.                     " [Esc] to leave."
  804.    ;-- if all we were doing was resetting the memory arrays, return
  805.    if lower(all.or.some.a) = "memory" then
  806.       return
  807.    endif
  808. endif
  809.  
  810.  
  811.  
  812. ;-- this sets/resets user defined/default variables
  813. ;-- from the calling parameters to ds.calc.v
  814. if lower(all.or.some.a) = "all" then
  815.  
  816.    ;-- define the array size of the tape based on
  817.    ;-- called parameter or assign it the default
  818.    ;-- this is incremented by one as the application uses the last
  819.    ;-- element in totals, etc.
  820.    if isassigned(ds.tape.length.s) then
  821.       ;-- since you can't check the numval of a number,
  822.       ;-- all tests are performed on the numval of
  823.       ;-- the strval of the variable
  824.       switch
  825.          ;-- a number wasn't passed
  826.          case lower(numval(strval(ds.tape.length.s))) = "error" :
  827.             ds.tape.length.s = 51
  828.          ;-- an out of range number
  829.          case (numval(strval(ds.tape.length.s)) < 20) or
  830.               (numval(strval(ds.tape.length.s)) > 500) :
  831.             ds.tape.length.s = 51
  832.          ;-- assign the value that was passed here
  833.          otherwise :
  834.             ds.tape.length.s = int(numval(strval(ds.tape.length.s))+1)
  835.       endswitch
  836.    else
  837.       ;-- default setting if no parameter was passed
  838.       ds.tape.length.s = 51
  839.    endif
  840.  
  841.    ;-- here the setswap point is determined
  842.    if isassigned(ds.set.swap.n) then
  843.       switch
  844.          ;-- checking for a number
  845.          case lower(numval(strval(ds.set.swap.n))) = "error" :
  846.             ds.set.swap.n = 35000
  847.          ;-- checking to see if it exceeds the maximum allowed
  848.          case numval(strval(ds.set.swap.n)) > memleft() :
  849.             ds.set.swap.n = 35000
  850.          ;-- checking for below the minimum
  851.          case numval(strval(ds.set.swap.n)) < 35000 :
  852.             ds.set.swap.n = 35000
  853.          ;-- to get here none of the above needed to be true
  854.          otherwise :
  855.             ds.set.swap.n = int(numval(strval(ds.set.swap.n)))
  856.       endswitch
  857.    else
  858.       ;-- default setting for setswap
  859.       ds.set.swap.n = 35000
  860.    endif
  861.  
  862.    ;-- here error checking is performed on the ds.save.memory
  863.    ;-- parameter
  864.    if isassigned(ds.save.memory.l) and
  865.       lower(type(ds.save.memory.l)) <> "l" then
  866.       if lower(ds.save.memory.l) = "true" then
  867.          ds.save.memory.l = true
  868.       else
  869.          ds.save.memory.l = false
  870.       endif
  871.    endif
  872.    if not isassigned(ds.save.memory.l) then
  873.       ds.save.memory.l = false
  874.    endif
  875. endif
  876.  
  877.  
  878. ;-- here the arrays are defined or re-defined
  879. ;-- re-defining an array effectively releases any
  880. ;-- assignments to any element in the array
  881.  
  882. ;-- the tape itself
  883. array ds.tape.r[ds.tape.length.s]
  884.  
  885. ;-- the function sign displayed with the corresponding
  886. ;-- tape element
  887. array ds.tape.function.r[ds.tape.length.s]
  888.  
  889. ;-- whether or not the tape entries' corresponding
  890. ;-- element has a decimal in it
  891. array ds.decimal.r[ds.tape.length.s]
  892.  
  893. ;-- an array that keeps subtotals
  894. array ds.total.was.r[ds.tape.length.s]
  895.  
  896. ;-- the counter that keeps track of which element
  897. ;-- we are working with
  898. ds.tape.count.s = 1
  899.  
  900. ;-- initial setting of some of the variables
  901. ;-- no previous key to un-press
  902. ds.char.was.v = "no"
  903. ;-- the first element is not a decimal
  904. ds.decimal.r[1] = false
  905. ;-- the previous sub-total array element that was assigned
  906. ds.total.element.num.was.s = 1
  907. ;-- initial assignment
  908. ds.total.was.r[1] = 0
  909. ;-- initially false, changed to true as required
  910. ds.rebuild.l = false
  911.  
  912. endproc
  913.  
  914. ?? "." message memleft() writelib ds.aplib.a ds.set.vars.u
  915. release procs ds.set.vars.u
  916.  
  917.  
  918. ;-------------------------------------------------------------------------------
  919. ;                                                            ds.tape.display.l()
  920. ;-------------------------------------------------------------------------------
  921. ; purpose: displays the tape entries in the tape window
  922. proc ds.tape.display.l()
  923.  
  924. private
  925. ds.loop.counter.s,        ;-- a loop counter
  926. position.pointer.s        ;-- this variable is used for @ to position
  927.                           ;-- text to be displayed to the screen
  928.  
  929. ;-- if there are is nothing to display then there is nothing to do
  930. if not isassigned(ds.tape.r[ds.tape.count.s]) or
  931.    lower(numval(strval(ds.tape.r[ds.tape.count.s]))) = "error" then
  932.    beep
  933.    ;-- inform calling procedure of failure
  934.    return false
  935. endif
  936.  
  937. ;-- make an assignment to this array element based on the key
  938. ;-- last pressed by the user
  939. ds.tape.function.r[ds.tape.count.s] = ds.char.s
  940.  
  941. ;-- clear the calculator window
  942. @ 05,04 ?? spaces(21)
  943.  
  944. ;-- if there are less entries in the calculator then 19
  945. ;-- we simply add the entry to the end of the list
  946. if ds.tape.count.s < 19 then
  947.  
  948.    ;-- only if not the first entry
  949.    if ds.tape.count.s > 1 then
  950.       ;-- if it's a sub-total then display the = sign
  951.       ;-- with the previous entry in and set intense mode
  952.       ;-- other wise set normal video mode
  953.       if ds.tape.function.r[ds.tape.count.s-1] = 61 then
  954.          @ ds.tape.count.s+3,73 ?? chr(ds.tape.function.r[ds.tape.count.s-1])
  955.          style intense
  956.       else
  957.          style
  958.       endif
  959.    endif
  960.  
  961.    ;-- use the format appropriate for the tape type ie. decimal or non-decimal
  962.    @ ds.tape.count.s+4,45
  963.    if ds.decimal.r[ds.tape.count.s] then
  964.       ?? format("w20.15,ar",numval(ds.tape.r[ds.tape.count.s]))
  965.    else
  966.       ?? format("w20,ar,ec",numval(ds.tape.r[ds.tape.count.s]))
  967.    endif
  968.  
  969.    ;-- display the function that goes along with this entry
  970.    @ ds.tape.count.s+4,73 ?? chr(ds.tape.function.r[ds.tape.count.s])
  971.  
  972. else
  973.    ;-- turn the canvas off
  974.    canvas off
  975.  
  976.    ;-- define the position
  977.    position.pointer.s = 6
  978.  
  979.    ;-- this informs the user that there is more to the tape
  980.    ;-- that they can no longer see
  981.    style reverse
  982.    @ 05,43 ?? "║        More            │      ║"
  983.    style
  984.  
  985.    ;-- this loop places the last 17 entries in the tape into the tape
  986.    ;-- window
  987.    for ds.loop.counter.s from (ds.tape.count.s - 17) to ds.tape.count.s
  988.       ;-- set the style for totals if the previous tape
  989.       ;-- function was a =
  990.       if ds.tape.function.r[ds.loop.counter.s-1] = 61 then
  991.          style intense
  992.       else
  993.          style
  994.       endif
  995.  
  996.       ;-- place the cursor at the right position
  997.       @ position.pointer.s,45
  998.  
  999.       ;-- select proper format to display the tape entry
  1000.       if ds.decimal.r[ds.loop.counter.s] then
  1001.          ?? format("w20.15,ar",numval(ds.tape.r[ds.loop.counter.s]))
  1002.       else
  1003.          ?? format("w20,ar,ec",numval(ds.tape.r[ds.loop.counter.s]))
  1004.       endif
  1005.  
  1006.       ;-- place the corresponding function character
  1007.       @ position.pointer.s,73
  1008.       ?? chr(ds.tape.function.r[ds.loop.counter.s])
  1009.  
  1010.       ;-- increment the pointer by 1
  1011.       position.pointer.s = position.pointer.s + 1
  1012.  
  1013.    endfor
  1014.  
  1015.    ;-- turn the canvas back on
  1016.    canvas on
  1017.  
  1018. endif
  1019.  
  1020. ;-- now some beeps and style differences if the tape
  1021. ;-- is running low on entries
  1022. switch
  1023.  
  1024.    ;-- more than 5 entries left, just set normal style
  1025.    case ds.tape.length.s - ds.tape.count.s - 1 > 5  :
  1026.       style
  1027.    ;-- only 5, intense and a beep
  1028.    case ds.tape.length.s - ds.tape.count.s - 1 = 5  :
  1029.       style intense
  1030.       beep
  1031.    ;-- 4 left, another style - 2 beeps
  1032.    case ds.tape.length.s - ds.tape.count.s - 1 = 4  :
  1033.       style reverse
  1034.       beep beep
  1035.    ;-- 3 left, blink and 3 beeps
  1036.    case ds.tape.length.s - ds.tape.count.s - 1 = 3  :
  1037.       style blink, intense
  1038.       beep beep beep
  1039.    ;-- 2 left, reverse and 4 beeps
  1040.    case ds.tape.length.s - ds.tape.count.s - 1 = 2  :
  1041.       style blink, reverse
  1042.       beep beep beep beep
  1043.    ;-- one left, blinking reverse., 5 beeps
  1044.    case ds.tape.length.s - ds.tape.count.s - 1 <= 1 :
  1045.       style blink, reverse
  1046.       beep beep beep beep beep
  1047. endswitch
  1048.  
  1049. ;-- display number of entries left
  1050. @ 24,65 ?? strval(ds.tape.length.s-ds.tape.count.s-1) + " "
  1051.  
  1052. ;-- increment the array counter for the next entry
  1053. ds.tape.count.s = ds.tape.count.s + 1
  1054.  
  1055. ;-- set the decimal array element
  1056. ds.decimal.r[ds.tape.count.s] = false
  1057.  
  1058. ;-- make sure style is back to normal
  1059. style
  1060.  
  1061. ;-- inform calling procedure of successful completion
  1062. return true
  1063.  
  1064. endproc
  1065.  
  1066. ?? "." message memleft() writelib ds.aplib.a ds.tape.display.l
  1067. release procs ds.tape.display.l
  1068.  
  1069. ;-------------------------------------------------------------------------------
  1070. ;                                                                   ds.total.u()
  1071. ;-------------------------------------------------------------------------------
  1072. ; purpose: computes the total
  1073. proc ds.total.u()
  1074.  
  1075. private
  1076. ds.loop.counter.s  ;-- a loop counter
  1077.  
  1078. switch
  1079.  
  1080.    ;-- nothing to total with less then 2 entries
  1081.    case ds.tape.count.s < 2 :
  1082.       beep
  1083.       return
  1084.  
  1085.    ;-- if the last element is assigned and it's non-numeric and
  1086.    ;-- it's not blank, can't do any processing
  1087.    case isassigned(ds.tape.r[ds.tape.count.s]) and
  1088.         lower(numval(strval(ds.tape.r[ds.tape.count.s]))) = "error" and
  1089.         not isblank(ds.tape.r[ds.tape.count.s])  :
  1090.       beep
  1091.       return
  1092.  
  1093.    ;-- if it's not assigned or 0 and there are only 2 entries,
  1094.    ;-- nothing to compute
  1095.    case (not isassigned(ds.tape.r[ds.tape.count.s]) or
  1096.          numval(strval(ds.tape.r[ds.tape.count.s])) = 0) and
  1097.          ds.tape.count.s = 2 :
  1098.       beep
  1099.       return
  1100.  
  1101.    ;-- if it's not assigned or 0 and then a case statement
  1102.    ;-- so the following otherwise will not be executed
  1103.    case (not isassigned(ds.tape.r[ds.tape.count.s]) or
  1104.          numval(strval(ds.tape.r[ds.tape.count.s])) = 0 ) :
  1105.  
  1106.    ;-- add the last entry to the tape window which
  1107.    ;-- increments ds.tape.count.s by 1
  1108.    ;-- that's the reason for the previous case
  1109.    otherwise :  ds.tape.display.l()
  1110.  
  1111. endswitch
  1112.  
  1113. ;-- if the total element counter is not 1 then
  1114. ;-- assign the last tape element the last total that
  1115. ;-- was computed
  1116. if ds.total.element.num.was.s <> 1 then
  1117.    ds.tape.r[ds.tape.count.s] =
  1118.    strval(ds.total.was.r[ds.total.element.num.was.s])
  1119. endif
  1120.  
  1121. ;-- if the total element counter is not 1 then
  1122. if ds.total.element.num.was.s <> 1 then
  1123.    ;-- loop
  1124.    for ds.loop.counter.s
  1125.       ;-- from the previous total element plus 1
  1126.       from (ds.total.element.num.was.s + 1)
  1127.       ;-- to the previous element
  1128.       to (ds.tape.count.s - 1)
  1129.       ;-- execute the functions (+-*/)
  1130.       execute "ds.tape.r[ds.tape.count.s]=numval(ds.tape.r[ds.tape.count.s])" +
  1131.               chr(ds.tape.function.r[ds.loop.counter.s-1]) +
  1132.               "numval(ds.tape.r[ds.loop.counter.s])"
  1133.       ;-- convert to a string
  1134.       ds.tape.r[ds.tape.count.s] = strval(ds.tape.r[ds.tape.count.s])
  1135.    endfor
  1136. ;-- if it is 1
  1137. else
  1138.    ;-- let the currently entry = the first entry
  1139.    ds.tape.r[ds.tape.count.s] = ds.tape.r[1]
  1140.    ;-- calculate the second to the next to last entries
  1141.    for ds.loop.counter.s from 2 to (ds.tape.count.s - 1)
  1142.       ;-- execute the functions (+-*/)
  1143.       execute "ds.tape.r[ds.tape.count.s]=numval(ds.tape.r[ds.tape.count.s])" +
  1144.               chr(ds.tape.function.r[ds.loop.counter.s-1]) +
  1145.               "numval(ds.tape.r[ds.loop.counter.s])"
  1146.       ;-- convert to a string
  1147.       ds.tape.r[ds.tape.count.s] = strval(ds.tape.r[ds.tape.count.s])
  1148.    endfor
  1149. endif
  1150.  
  1151. ;-- re-position which element has the previous total
  1152. ds.total.element.num.was.s = ds.tape.count.s
  1153.  
  1154. ;-- make the assignment to the proper array element
  1155. ds.total.was.r[ds.total.element.num.was.s] = strval(ds.tape.r[ds.tape.count.s])
  1156.  
  1157. ;-- identify that this is a total value
  1158. ds.tape.function.r[ds.tape.count.s-1] = 61
  1159.  
  1160. ;-- determine if the total has a decimal in it or not
  1161. ds.set.decimal.u()
  1162.  
  1163. ;-- to toggle the key pad off
  1164. ds.char.s = 1000
  1165.  
  1166. ;-- set the style for a total value
  1167. style intense
  1168.  
  1169. ;-- display it in the calculator window
  1170. ds.display.u()
  1171.  
  1172. ;-- back to normal style
  1173. style
  1174.  
  1175. ;-- increment the array element counter
  1176. ds.tape.count.s = ds.tape.count.s + 1
  1177.  
  1178. ;-- turn the keypad off
  1179. ds.key.press.u()
  1180.  
  1181. ;-- place a prompt on the top 2 lines
  1182. @ 00,00
  1183. ?? format("w80,ac",
  1184. "Press a function key to continue the tape (i.e. +, -, /, *, = )")
  1185. @ 01,00
  1186. ?? format("w80,ac",
  1187. "or [Alt-F8] to clear the calculator and start a new tape.")
  1188.  
  1189. ;-- wait to get an acceptable key to exit this loop
  1190. while true
  1191.  
  1192.    ;-- a getchar waiting for something to be pressed
  1193.    ds.char.s = getchar()
  1194.  
  1195.    switch
  1196.       ;-- user opted to clear the calculator by
  1197.       ;-- pressing [alt][f8] or [alt][c]
  1198.       case ds.char.s = -111 or
  1199.            ds.char.s =  -46 :
  1200.  
  1201.          ;-- reset ds.char.s if required
  1202.          ds.char.s = -111
  1203.          ;-- clear the calculator window
  1204.          @ 05,04 ?? spaces(21)
  1205.          ;-- re-define the arrays
  1206.          ds.set.vars.u("some")
  1207.          ;-- re-paint the calculator
  1208.          ds.calc.screen.u()
  1209.          ;-- all done
  1210.          return
  1211.  
  1212.       ;-- user pressed a function key
  1213.       case ds.char.s =  42 or     ; multiply
  1214.            ds.char.s =  43 or     ; add
  1215.            ds.char.s =  45 or     ; subtract
  1216.            ds.char.s =  47 :      ; divide
  1217.  
  1218.          ;-- leave the loop
  1219.          quitloop
  1220.  
  1221.       ;-- user pressed enter, = or [f2]
  1222.       case ds.char.s = -60 or      ; f2
  1223.            ds.char.s =  61 or      ; =
  1224.            ds.char.s =  13 :       ; enter
  1225.  
  1226.          ;-- default to add and let the user decide
  1227.          ;-- to clearall, memory, etc.
  1228.          ds.char.s =  43
  1229.          ;-- leave the loop
  1230.          quitloop
  1231.  
  1232.       ;-- need to press something so beep at them
  1233.       otherwise :
  1234.          beep
  1235.    endswitch
  1236. endwhile
  1237.  
  1238. ;-- assign the tape function pressed
  1239. ds.tape.function.r[ds.tape.count.s-1] = ds.char.s
  1240.  
  1241. ;-- the call to ds.tape.display.l will
  1242. ;-- increment ds.tape.count.s by 1 so adjust
  1243. ;-- it down so it will be right
  1244. ds.tape.count.s = ds.tape.count.s - 1
  1245.  
  1246. ;-- display the tape
  1247. ds.tape.display.l()
  1248.  
  1249. endproc
  1250.  
  1251. ?? "." message memleft() writelib ds.aplib.a ds.total.u
  1252. release procs ds.total.u
  1253.  
  1254. ;-------------------------------------------------------------------------------
  1255. ;                                                             ds.save.memory.u()
  1256. ;-------------------------------------------------------------------------------
  1257. ; purpose: creates the file dssvmem.sc in the private directory so that
  1258. ;          it can be played later to retrieve memory the next time
  1259. ;          the calculator is used
  1260. ;          the individual elements could have been printed in for loops,
  1261. ;          however I believe this approach might be just a tad faster
  1262. proc ds.save.memory.u()
  1263.  
  1264. private
  1265. ds.file.to.print    ;-- file to print to
  1266.  
  1267. ;-- define the file name
  1268. ;-- this may not be required but if somehow
  1269. ;-- privdir() returns " " instead of "" then the
  1270. ;-- print file might bomb
  1271. if isblank(privdir()) then
  1272.    ds.file.to.print = "dssvmem.sc"
  1273. else
  1274.    ds.file.to.print = privdir() + "dssvmem.sc"
  1275. endif
  1276.  
  1277. ;-- delete current file if it exists
  1278. ;-- this will work in any sysmode
  1279. if isfile(ds.file.to.print) then
  1280.    run norefresh "del " + ds.file.to.print
  1281. endif
  1282.  
  1283. ;-- define the array
  1284. print file ds.file.to.print
  1285. "array ds.memory.r[20]\n",
  1286.  
  1287. ;-- save the first element of the array
  1288. ;-- this takes special handling as the escape character
  1289. ;-- used to display the left arrow sets up an end-of-file marker
  1290. "ds.memory.r[1]=\"Use the [] [\"+chr(26)+\"",
  1291. "] keys to select the Memory # then press [Enter].",
  1292. " [Esc] to leave.\"\n",
  1293. ;-- and save the rest of the elements of that array
  1294. "ds.memory.r[2]=\"" + ds.memory.r[2] + "\"\n",
  1295. "ds.memory.r[3]=\"" + ds.memory.r[3] + "\"\n",
  1296. "ds.memory.r[4]=\"" + ds.memory.r[4] + "\"\n",
  1297. "ds.memory.r[5]=\"" + ds.memory.r[5] + "\"\n",
  1298. "ds.memory.r[6]=\"" + ds.memory.r[6] + "\"\n",
  1299. "ds.memory.r[7]=\"" + ds.memory.r[7] + "\"\n",
  1300. "ds.memory.r[8]=\"" + ds.memory.r[8] + "\"\n",
  1301. "ds.memory.r[9]=\"" + ds.memory.r[9] + "\"\n",
  1302. "ds.memory.r[10]=\"" + ds.memory.r[10] + "\"\n",
  1303. "ds.memory.r[11]=\"" + ds.memory.r[11] + "\"\n",
  1304. "ds.memory.r[12]=\"" + ds.memory.r[12] + "\"\n",
  1305. "ds.memory.r[13]=\"" + ds.memory.r[13] + "\"\n",
  1306. "ds.memory.r[14]=\"" + ds.memory.r[14] + "\"\n",
  1307. "ds.memory.r[15]=\"" + ds.memory.r[15] + "\"\n",
  1308. "ds.memory.r[16]=\"" + ds.memory.r[16] + "\"\n",
  1309. "ds.memory.r[17]=\"" + ds.memory.r[17] + "\"\n",
  1310. "ds.memory.r[18]=\"" + ds.memory.r[18] + "\"\n",
  1311. "ds.memory.r[19]=\"" + ds.memory.r[19] + "\"\n",
  1312. "ds.memory.r[20]=\"" + ds.memory.r[20] + "\"\n",
  1313.  
  1314. ;-- define this array
  1315. ;print file ds.file.to.print
  1316. "array ds.memory.element.r[20]\n",
  1317.  
  1318. ;-- and save the elements of that array
  1319. "ds.memory.element.r[1]=\"" + ds.memory.element.r[1] + "\"\n",
  1320. "ds.memory.element.r[2]=\"" + ds.memory.element.r[2] + "\"\n",
  1321. "ds.memory.element.r[3]=\"" + ds.memory.element.r[3] + "\"\n",
  1322. "ds.memory.element.r[4]=\"" + ds.memory.element.r[4] + "\"\n",
  1323. "ds.memory.element.r[5]=\"" + ds.memory.element.r[5] + "\"\n",
  1324. "ds.memory.element.r[6]=\"" + ds.memory.element.r[6] + "\"\n",
  1325. "ds.memory.element.r[7]=\"" + ds.memory.element.r[7] + "\"\n",
  1326. "ds.memory.element.r[8]=\"" + ds.memory.element.r[8] + "\"\n",
  1327. "ds.memory.element.r[9]=\"" + ds.memory.element.r[9] + "\"\n",
  1328. "ds.memory.element.r[10]=\"" + ds.memory.element.r[10] + "\"\n",
  1329. "ds.memory.element.r[11]=\"" + ds.memory.element.r[11] + "\"\n",
  1330. "ds.memory.element.r[12]=\"" + ds.memory.element.r[12] + "\"\n",
  1331. "ds.memory.element.r[13]=\"" + ds.memory.element.r[13] + "\"\n",
  1332. "ds.memory.element.r[14]=\"" + ds.memory.element.r[14] + "\"\n",
  1333. "ds.memory.element.r[15]=\"" + ds.memory.element.r[15] + "\"\n",
  1334. "ds.memory.element.r[16]=\"" + ds.memory.element.r[16] + "\"\n",
  1335. "ds.memory.element.r[17]=\"" + ds.memory.element.r[17] + "\"\n",
  1336. "ds.memory.element.r[18]=\"" + ds.memory.element.r[18] + "\"\n",
  1337. "ds.memory.element.r[19]=\"" + ds.memory.element.r[19] + "\"\n",
  1338. "ds.memory.element.r[20]=\"" + ds.memory.element.r[20] + "\"\n"
  1339.  
  1340.  
  1341. endproc
  1342.  
  1343. ?? "." message memleft() writelib ds.aplib.a ds.save.memory.u
  1344. release procs ds.save.memory.u
  1345.  
  1346.  
  1347. ;-------------------------------------------------------------------------------
  1348. ;                                                                  ds.memory.u()
  1349. ;-------------------------------------------------------------------------------
  1350. ; purpose: displays the memory menu
  1351. proc ds.memory.u()
  1352.  
  1353. private
  1354. ds.memory.choice.a,       ;-- menu choice variable
  1355. ds.array.element.num.s,   ;-- which tape element to use
  1356. ds.array.to.show.v        ;-- array element to display
  1357.  
  1358. ;-- initialize the default menu choice
  1359. ds.memory.choice.a = "Add "
  1360.  
  1361. ;-- stay in this loop until the user opts to exit
  1362. while true
  1363.  
  1364.    ;-- memory menu choices
  1365.    showmenu
  1366.       "Add "      : " Add to Memory.",
  1367.       "Subtract " : " Subtract from memory.",
  1368.       "Recall "   : " Recall from Memory.",
  1369.       "Display "  : " Display Memory.",
  1370.       "Clear "    : " Clear ALL Memory.",
  1371.       "Esc "      : " Return to DSCalc."
  1372.    default ds.memory.choice.a
  1373.    to ds.memory.choice.a
  1374.  
  1375.    ;-- re-displays the last line which is occasionally blanked out
  1376.    ;-- by paradox - this is used throughout the application
  1377.    ;-- in some case, it may not be required as I threw it
  1378.    ;-- in where ever I thought it might be needed
  1379.    canvas off
  1380.    message ""
  1381.    @ 22,78 clear eol
  1382.    canvas on
  1383.  
  1384.    ;-- turns the keypad off
  1385.    ds.char.s = 1000
  1386.    ds.key.press.u()
  1387.  
  1388.    ;-- okay, what was selected
  1389.    switch
  1390.  
  1391.       ;-- user opted to cancel
  1392.       case ds.memory.choice.a = "Esc " or
  1393.            ds.memory.choice.a = "Esc" :
  1394.  
  1395.          ;-- re-displays the last line
  1396.          canvas off
  1397.          message ""
  1398.          @ 22,78 clear eol
  1399.          canvas on
  1400.          return
  1401.  
  1402.       case ds.memory.choice.a = "Clear " :
  1403.  
  1404.          ;-- clears the memory arrays
  1405.          ds.set.vars.u("memory")
  1406.          ;-- but doesn't exit
  1407.          loop
  1408.  
  1409.  
  1410.       ;-- all other menu choices are handled here
  1411.       otherwise :
  1412.  
  1413.          ;-- default menu choice
  1414.          ds.array.to.show.v = "Select »"
  1415.  
  1416.          ;-- a loop until they are done working with the arrays
  1417.          while true
  1418.  
  1419.             ;-- display the element numbers on the top line and
  1420.             ;-- the contents on the prompt line
  1421.             showarray ds.memory.element.r ds.memory.r
  1422.             default ds.array.to.show.v
  1423.             to ds.array.to.show.v
  1424.  
  1425.             ;-- opted to cancel
  1426.             if ds.array.to.show.v = "Esc" or
  1427.                ds.array.to.show.v = "Select »" then
  1428.                canvas off
  1429.                message ""
  1430.                @ 22,78 clear eol
  1431.                canvas on
  1432.                quitloop
  1433.             else
  1434.                ;-- otherwise convert the selected menu option
  1435.                ;-- to a number to decide further handling
  1436.                ds.array.to.show.v = numval(ds.array.to.show.v)
  1437.             endif
  1438.  
  1439.             canvas off
  1440.             message ""
  1441.             @ 22,78 clear eol
  1442.             canvas on
  1443.  
  1444.             ;-- this handles the initial choice, ie. what to do
  1445.             ;-- with the memory elements
  1446.             switch
  1447.  
  1448.                ;-- this case handles adding and subtracting
  1449.                case ds.memory.choice.a = "Add " or
  1450.                     ds.memory.choice.a = "Subtract " :
  1451.  
  1452.                   ;-- if it is currently a non numeric value, then
  1453.                   ;-- assign it = 0
  1454.                   if lower(numval(ds.memory.r[ds.array.to.show.v+1])) =
  1455.                      "error" then
  1456.                      ds.memory.r[ds.array.to.show.v+1] = "0"
  1457.                   endif
  1458.  
  1459.                   ;-- handle the adding and subtracting based on
  1460.                   ;-- the current tape position
  1461.                   switch
  1462.                      ;-- the first entry of the tape is handled here
  1463.                      case ds.tape.count.s = 1 and
  1464.                           (not isassigned(ds.tape.r[ds.tape.count.s]) or
  1465.                           isblank(ds.tape.r[ds.tape.count.s]) or
  1466.                           lower(strval(numval(ds.tape.r[ds.tape.count.s]))) =
  1467.                           "error") :
  1468.  
  1469.                         ;-- beep the error
  1470.                         beep
  1471.                         ;-- set up a error trap
  1472.                         ds.array.element.num.s = "error"
  1473.  
  1474.                      ;-- this handles the current entry
  1475.                      case isassigned(ds.tape.r[ds.tape.count.s]) and
  1476.                           ds.tape.r[ds.tape.count.s] <> blanknum() and
  1477.                           lower(numval(ds.tape.r[ds.tape.count.s])) <> "error":
  1478.  
  1479.                         ;-- the current element is a number so use it
  1480.                         ds.array.element.num.s = ds.tape.count.s
  1481.  
  1482.                      ;-- the current entry was illegal so this check the
  1483.                      ;-- previous entry
  1484.                      case isassigned(ds.tape.r[ds.tape.count.s-1]) and
  1485.                           ds.tape.r[ds.tape.count.s-1] <> blanknum() and
  1486.                           lower(numval(ds.tape.r[ds.tape.count.s-1])) <>
  1487.                           "error":
  1488.  
  1489.                         ;-- the use the previous element
  1490.                         ds.array.element.num.s = ds.tape.count.s - 1
  1491.  
  1492.                      ;-- everything failed the test!
  1493.                      otherwise :
  1494.                         ;-- shame shame
  1495.                         beep
  1496.                         ;-- set up a error trap
  1497.                         ds.array.element.num.s = "error"
  1498.  
  1499.                   endswitch
  1500.  
  1501.                   ;-- if there was no error process here
  1502.                   if lower(ds.array.element.num.s) <> "error" then
  1503.                      ;-- if add then add it to the current value
  1504.                      if lower(ds.memory.choice.a) = "add " then
  1505.                         ds.memory.r[ds.array.to.show.v+1] =
  1506.                         numval(ds.memory.r[ds.array.to.show.v+1]) +
  1507.                         numval(ds.tape.r[ds.array.element.num.s])
  1508.                      ;-- otherwise subtract
  1509.                      else
  1510.                         ds.memory.r[ds.array.to.show.v+1] =
  1511.                         numval(ds.memory.r[ds.array.to.show.v+1]) -
  1512.                         numval(ds.tape.r[ds.array.element.num.s])
  1513.                      endif
  1514.                      ;-- shouldn't be an error here but just in case
  1515.                      if lower(ds.memory.r[ds.array.to.show.v+1]) = "error" then
  1516.                         ds.memory.r[ds.array.to.show.v+1] = "Not Assigned"
  1517.                      ;-- else store the string value
  1518.                      else
  1519.                         ds.memory.r[ds.array.to.show.v+1] =
  1520.                         strval(ds.memory.r[ds.array.to.show.v+1])
  1521.                      endif
  1522.                   endif
  1523.  
  1524.                ;-- user wants to recall the value
  1525.                case ds.memory.choice.a = "Recall " :
  1526.  
  1527.                   ;-- if there is a number then
  1528.                   if lower(numval(ds.memory.r[ds.array.to.show.v+1]))
  1529.                      <> "error" then
  1530.                      ;-- recall it into the current tape entry
  1531.                      ds.tape.r[ds.tape.count.s] =
  1532.                      strval(ds.memory.r[ds.array.to.show.v+1])
  1533.                      ;-- set the decimal array element
  1534.                      ds.set.decimal.u()
  1535.                      ;-- display it in the window
  1536.                      ds.display.u()
  1537.                      ;-- all done
  1538.                      return
  1539.                   ;-- nothing to recall
  1540.                   else
  1541.                      beep
  1542.                   endif
  1543.  
  1544.             endswitch
  1545.  
  1546.             ;-- re-assign the variable to the sting value of itself
  1547.             ;-- otherwise the showarray crashes - it doesn't
  1548.             ;-- work with numbers
  1549.             ds.array.to.show.v = strval(ds.array.to.show.v)
  1550.  
  1551.          endwhile
  1552.  
  1553.    endswitch
  1554.  
  1555.    ;-- that last line again
  1556.    canvas off
  1557.    message ""
  1558.    @ 22,78 clear eol
  1559.    canvas on
  1560.  
  1561. endwhile
  1562.  
  1563. endproc
  1564.  
  1565. ?? "." message memleft() writelib ds.aplib.a ds.memory.u
  1566. release procs ds.memory.u
  1567.  
  1568. ;-------------------------------------------------------------------------------
  1569. ;                                                                 ds.rebuild.l()
  1570. ;-------------------------------------------------------------------------------
  1571. ; purpose: rebuilds the tape when it has been covered with a help screen
  1572. ;          or otherwise erased
  1573. proc ds.rebuild.l()
  1574.  
  1575. private
  1576. ds.loop.counter.s,   ;-- another loop counter
  1577. ds.end.of.loop.s     ;-- a variable to end the loop
  1578.  
  1579. ;-- places the calculator on the screen
  1580. ds.calc.screen.u()
  1581.  
  1582. ;-- clears the keypad
  1583. ds.char.s = 1000
  1584. ds.key.press.u()
  1585.  
  1586. ;-- if greater then 19 entries then ds.tape.display.l procedure
  1587. ;-- handles this very nicely
  1588. if ds.tape.count.s > 19 then
  1589.    ;-- needs to be decreased by one
  1590.    ds.tape.count.s = ds.tape.count.s - 1
  1591.    ;-- get the last key pressed for the procedure call
  1592.    ds.char.s = asc(ds.tape.function.r[ds.tape.count.s])
  1593.    ;-- repaint the tape in the tape window
  1594.    ds.tape.display.l()
  1595. ;-- ds.tape.display.l need to be called one entry at a time
  1596. else
  1597.    ;-- determine how many times
  1598.    ds.end.of.loop.s = ds.tape.count.s - 1
  1599.    ;-- turn the canvas off
  1600.    canvas off
  1601.    ;-- place each tape entry back in the tape window
  1602.    for ds.loop.counter.s from 1 to ds.end.of.loop.s
  1603.       ;-- fake out the procedure by altering the
  1604.       ;-- element pointer
  1605.       ds.tape.count.s = ds.loop.counter.s
  1606.       ;-- get the last key pressed for the procedure call
  1607.       ds.char.s = asc(ds.tape.function.r[ds.loop.counter.s])
  1608.       ;-- define the ds.decimal.r array elements
  1609.       ;-- must have had a bug here that's why the check
  1610.       ;-- the elements should be assigned already
  1611.       if search(".",ds.tape.r[ds.loop.counter.s]) = 0 then
  1612.          ds.decimal.r[ds.loop.counter.s] = false
  1613.       else
  1614.          ds.decimal.r[ds.loop.counter.s] = true
  1615.       endif
  1616.       ;-- display the tape entry
  1617.       ds.tape.display.l()
  1618.    endfor
  1619.    ;-- turn the canvas on
  1620.    canvas on
  1621. endif
  1622.  
  1623. ;-- if the current entry is assigned and it's not blank
  1624. ;-- then place it in the window
  1625. if isassigned(ds.tape.r[ds.tape.count.s]) and
  1626.    not isblank(ds.tape.r[ds.tape.count.s]) then
  1627.    ;-- check decimal status
  1628.    ds.set.decimal.u()
  1629.    ;-- paint it in the calculator window
  1630.    ds.display.u()
  1631.    ;-- this not isblank is probably an overkill but what the hey
  1632.    if not isblank(ds.tape.r[ds.tape.count.s]) then
  1633.        ;-- now what was the last key pressed?
  1634.        ds.char.s =
  1635.        asc(                           ;-- ascii is what we want
  1636.        substr(                        ;-- part of a string
  1637.        strval(                        ;-- the string val
  1638.        ds.tape.r[ds.tape.count.s]),   ;-- of this array element
  1639.        len(                           ;-- starting position of the substr
  1640.        ds.tape.r[ds.tape.count.s]     ;-- is the length of the string
  1641.        ),1                            ;-- only 1 character
  1642.        )                              ;-- did you understand this?
  1643.        )                              ;-- I didn't
  1644.      else
  1645.        ds.char.s = 1000               ;-- to turn the keypad off
  1646.    endif
  1647. endif
  1648.  
  1649. endproc
  1650.  
  1651. ?? "." message memleft() writelib ds.aplib.a ds.rebuild.l
  1652. release procs ds.rebuild.l
  1653.  
  1654. ;-------------------------------------------------------------------------------
  1655. ;                                                                    ds.math.u()
  1656. ;-------------------------------------------------------------------------------
  1657. ; purpose: displays the math menu choices
  1658. proc ds.math.u()
  1659.  
  1660. private
  1661. ds.math.choice.a,   ;-- variable assigned by showmenu
  1662. ds.tape.to.use.s    ;-- which ds.tape.r element to use
  1663.  
  1664.  
  1665. ;-- set to false, if required will be changed to true
  1666. ds.rebuild.l = false
  1667.  
  1668. ;-- bottom line recovery
  1669. canvas off
  1670. message ""
  1671. @ 22,78 clear eol
  1672. canvas on
  1673.  
  1674. ;-- display a menu of choices
  1675. showmenu
  1676.    "ABS "   : " Absolute value of the last entry.",
  1677.    "EXP "   : " Exponential value of the last entry.",
  1678.    "INT "   : " Integer part of the last entry.",
  1679.    "LN "    : " Natural logarithm value of the last entry.",
  1680.    "LOG "   : " Base 10 logarithm value of the last entry.",
  1681.    "MOD "   : " Remainder of one number divided by another number.",
  1682.    "PI "    : " Return the value of Pi.",
  1683.    "POW "   : " Raises the last entry to a power.",
  1684.    "RAND "  : " Returns a random number between 0 and 1.",
  1685.    "ROUND " : " Rounds the last entry to a specified number of digits.",
  1686.    "SQRT "  : " Returns the square root of the last entry.",
  1687.    "Esc "   : " Return to what you were doing before pressing [F10]."
  1688. to ds.math.choice.a
  1689.  
  1690. ;-- bottom line recovery
  1691. canvas off
  1692. message ""
  1693. @ 22,78 clear eol
  1694. canvas on
  1695.  
  1696. ;-- process the selected choice
  1697. switch
  1698.  
  1699.    ;-- user opted to leave this menu without selecting a menu item
  1700.    case ds.math.choice.a = "Esc " or
  1701.         ds.math.choice.a = "Esc" :
  1702.       return
  1703.  
  1704.    ;-- call the appropriate procedure that handles mod
  1705.    case ds.math.choice.a = "MOD " :
  1706.       style reverse
  1707.       ds.math.mod.u()
  1708.       style
  1709.       return
  1710.  
  1711.    ;-- enter the value of pi into the latest tape array element
  1712.    case ds.math.choice.a = "PI " :
  1713.       ds.tape.r[ds.tape.count.s] = strval(pi())
  1714.       ds.decimal.r[ds.tape.count.s] = true
  1715.       return
  1716.  
  1717.    ;-- enter a random number into the latest tape array element
  1718.    case ds.math.choice.a = "RAND " :
  1719.       ds.tape.r[ds.tape.count.s] = strval(rand())
  1720.       ds.decimal.r[ds.tape.count.s] = true
  1721.       return
  1722.  
  1723.    ;-- all other functions require at least 1 valid entry in the tape
  1724.    case ds.tape.count.s = 1 and
  1725.         not isassigned(ds.tape.r[1]) or
  1726.         isblank(ds.tape.r[1]) or
  1727.         lower(strval(numval(ds.tape.r[1]))) = "error" :
  1728.       ;-- display a error message
  1729.       ds.error.u(
  1730.       "Sorry, there must be at least one entry in the calculator" +
  1731.       " to perform the",
  1732.       "requested calculation.                        Press any key" +
  1733.       " to continue.")
  1734.       return
  1735.  
  1736. endswitch
  1737.  
  1738. ds.math.proc.1.u(ds.math.choice.a)
  1739.  
  1740. endproc
  1741.  
  1742. ?? "." message memleft() writelib ds.aplib.a ds.math.u
  1743. release procs ds.math.u
  1744.  
  1745.  
  1746. ;-------------------------------------------------------------------------------
  1747. ;                                                             ds.math.proc.1.u()
  1748. ;-------------------------------------------------------------------------------
  1749. ; purpose: handles the other possible menu choices from ds.math.u
  1750. ;          this procedure was created to hold the size of ds.math.u down
  1751. proc ds.math.proc.1.u(
  1752. ds.math.choice.a)      ;-- the menu choice selected from ds.math.u
  1753.  
  1754.  
  1755. ;-- identify which tape element to use
  1756. if (not isassigned(ds.tape.r[ds.tape.count.s])) or
  1757.    (ds.tape.r[ds.tape.count.s] = blanknum()) or
  1758.    (lower(numval(ds.tape.r[ds.tape.count.s])) = "error") then
  1759.    ds.tape.to.use.s = ds.tape.count.s - 1
  1760. else
  1761.    ds.tape.to.use.s = ds.tape.count.s
  1762. endif
  1763.  
  1764. ;-- handle the other possible choices
  1765. switch
  1766.  
  1767.    ;-- convert the last entry to the absolute value of that entry
  1768.    case ds.math.choice.a = "ABS " :
  1769.       ds.tape.r[ds.tape.count.s] =
  1770.       strval(abs(numval(ds.tape.r[ds.tape.to.use.s])))
  1771.       ;-- set the decimal array element
  1772.       ds.set.decimal.u()
  1773.  
  1774.    ;-- the exponential value
  1775.    case ds.math.choice.a = "EXP " :
  1776.       ;-- version 2 used to choke on this if the value was
  1777.       ;-- out of this range
  1778.       ;-- version 3 returns error but this is still here because it
  1779.       ;-- need to be handled somehow anyway
  1780.       if numval(ds.tape.r[ds.tape.to.use.s]) < -708 or
  1781.          numval(ds.tape.r[ds.tape.to.use.s]) >  709 then
  1782.          ;-- display the error message
  1783.          ds.error.u(
  1784.          "Sorry, the exponential of a number less than -708" +
  1785.          " or greater than 709 can not",
  1786.          "be computed.                                  " +
  1787.          "     Press any key to continue.")
  1788.       else
  1789.          ;-- make the conversion
  1790.          ds.tape.r[ds.tape.count.s] =
  1791.          strval(exp(numval(ds.tape.r[ds.tape.to.use.s])))
  1792.          ;-- set the decimal array element
  1793.          ds.set.decimal.u()
  1794.       endif
  1795.  
  1796.    ;-- convert to an integer
  1797.    case ds.math.choice.a = "INT " :
  1798.       ;-- this one's easy
  1799.       ds.tape.r[ds.tape.count.s] =
  1800.       strval(int(numval(ds.tape.r[ds.tape.to.use.s])))
  1801.       ;-- set the decimal array element
  1802.       ds.decimal.r[ds.tape.count.s] = false
  1803.  
  1804.    ;-- natural logarithm
  1805.    case ds.math.choice.a = "LN " :
  1806.       ;-- version 2 used to choke on this if the value was
  1807.       ;-- out of this range
  1808.       ;-- version 3 returns error but this is still here because it
  1809.       ;-- need to be handled somehow anyway
  1810.       if numval(ds.tape.r[ds.tape.to.use.s]) <= 0 then
  1811.          ;-- display the error message
  1812.          ds.error.u(
  1813.          "Sorry, the natural logarithm can not be computed" +
  1814.          " on a number less than or",
  1815.          "equal to zero.                                " +
  1816.          " Press any key to continue.")
  1817.       else
  1818.          ;-- make the conversion
  1819.          ds.tape.r[ds.tape.count.s] =
  1820.          strval(ln(numval(ds.tape.r[ds.tape.to.use.s])))
  1821.          ;-- set the decimal array element
  1822.          ds.set.decimal.u()
  1823.       endif
  1824.  
  1825.    case ds.math.choice.a = "LOG " :
  1826.       ;-- version 2 used to choke on this if the value was
  1827.       ;-- out of this range
  1828.       ;-- version 3 returns error but this is still here because it
  1829.       ;-- need to be handled somehow anyway
  1830.       if numval(ds.tape.r[ds.tape.to.use.s]) <=0 then
  1831.          ;-- display the error message
  1832.          ds.error.u(
  1833.          "Sorry, the base 10 logarithm can not be computed on a number less then or",
  1834.          "equal to zero.                                 Press any key to continue.")
  1835.       else
  1836.          ;-- make the conversion
  1837.          ds.tape.r[ds.tape.count.s] =
  1838.          strval(log(numval(ds.tape.r[ds.tape.to.use.s])))
  1839.          ;-- set the decimal array element
  1840.          ds.set.decimal.u()
  1841.       endif
  1842.  
  1843.    ;-- takes another proc
  1844.    case ds.math.choice.a = "POW " :
  1845.       ds.math.pow.u()
  1846.       style
  1847.  
  1848.    ;-- so does this one
  1849.    case ds.math.choice.a = "ROUND " :
  1850.       style reverse
  1851.       ds.math.round.u()
  1852.       style
  1853.  
  1854.    ;-- get square man!
  1855.    case ds.math.choice.a = "SQRT " :
  1856.       ;-- you can only do a square root on a positive number
  1857.       ;-- version 2 hangs with this one
  1858.       if numval(ds.tape.r[ds.tape.to.use.s]) >= 0 then
  1859.          ds.tape.r[ds.tape.count.s] =
  1860.          strval(sqrt(numval(ds.tape.r[ds.tape.to.use.s])))
  1861.          ds.set.decimal.u()
  1862.       else
  1863.          ds.error.u(
  1864.          "Sorry, you can not compute the Square Root of a negative number.",
  1865.          ;-- there's that variable I assigned way back in the beginning!
  1866.          ds.press.it.a)
  1867.       endif
  1868.  
  1869. endswitch
  1870.  
  1871. endproc
  1872.  
  1873. ?? "." message memleft() writelib ds.aplib.a ds.math.proc.1.u
  1874. release procs ds.math.proc.1.u
  1875.  
  1876. ;-------------------------------------------------------------------------------
  1877. ;                                                                ds.math.mod.u()
  1878. ;-------------------------------------------------------------------------------
  1879. ; purpose: prompts the user for 2 values and computes the modulas of those
  1880. ;          numbers
  1881. proc ds.math.mod.u()
  1882.  
  1883. private
  1884. ds.dividend.n,   ;-- the dividend
  1885. ds.divisor.n     ;-- the divisor
  1886.  
  1887. ;-- clear the top two lines
  1888. @ 1,0 clear eol
  1889. @ 0,0 clear eol
  1890.  
  1891. ;-- turn the cursor on
  1892. cursor normal
  1893. ;-- place a prompt
  1894. ?? "Enter the dividend: "
  1895. ;-- get a value
  1896. accept "n" to ds.dividend.n
  1897. ;-- user left blank or pressed escape
  1898. if not isassigned(ds.dividend.n) or
  1899.    isblank(ds.dividend.n) then
  1900.    return
  1901. endif
  1902.  
  1903. ;-- place another prompt on the next line
  1904. ? "  To be divided by: "
  1905. ;-- get a value
  1906. accept "n" to ds.divisor.n
  1907. ;-- user left blank or pressed escape
  1908. if not isassigned(ds.divisor.n) or
  1909.    isblank(ds.divisor.n) then
  1910.    return
  1911. endif
  1912.  
  1913. ;-- make the conversion
  1914. ds.tape.r[ds.tape.count.s] = mod(ds.dividend.n,ds.divisor.n)
  1915.  
  1916. ;-- the following statement is necessary because paradox cannot properly handle
  1917. ;-- mod(x,y) if either x or y are not whole numbers and the remainder is truly 0
  1918. ;-- this problem has been been reported to borland
  1919. ;-- this was true in version 2 however I haven't tested to see if it
  1920. ;-- was corrected in version 3
  1921. if ds.tape.r[ds.tape.count.s] = ds.dividend.n then
  1922.    ;-- make it the string "0"
  1923.    ds.tape.r[ds.tape.count.s] = "0"
  1924.    ;-- set this variable
  1925.    ds.decimal.r[ds.tape.count.s] = false
  1926. else
  1927.    ;-- convert it to a string
  1928.    ds.tape.r[ds.tape.count.s] = strval(ds.tape.r[ds.tape.count.s])
  1929.    ;-- set the decimal array
  1930.    ds.set.decimal.u()
  1931. endif
  1932.  
  1933. endproc
  1934.  
  1935. ?? "." message memleft() writelib ds.aplib.a ds.math.mod.u
  1936. release procs ds.math.mod.u
  1937.  
  1938.  
  1939. ;-------------------------------------------------------------------------------
  1940. ;                                                                ds.math.pow.u()
  1941. ;-------------------------------------------------------------------------------
  1942. ; purpose: converts the current entry to a specified power
  1943. ;          this math function caused me the most trouble
  1944. ;          most of the math functions in version 2 would crash, ie. lock up the
  1945. ;          computer when they were out of range even though the manual
  1946. ;          stated the returned value would be "Error"
  1947. ;          through a lot of testing, I determined the acceptable ranges for
  1948. ;          all of the math functions accept this one
  1949. ;          I could find no pattern or relationship that I could test that
  1950. ;          would not lock up the computer
  1951. ;          if you convert this script to run under version 2 this procedure may
  1952. ;          cause your computer to lock up and you will have to reboot
  1953. proc ds.math.pow.u()
  1954.  
  1955. private
  1956. ds.power.n    ;-- the power to raise the last value to
  1957.  
  1958. ;-- clear the top 2 lines
  1959. @ 01,00 clear eol
  1960. @ 00,00 clear eol
  1961.  
  1962. ;-- set the style
  1963. style reverse
  1964.  
  1965. ;-- enter a prompt
  1966. ?? "Enter the power: "
  1967.  
  1968. ;-- turn the cursor on
  1969. cursor normal
  1970.  
  1971. ;-- get a value
  1972. accept "n" to ds.power.n
  1973.  
  1974. ;== user pressed escape or left the entry blank
  1975. if not retval or
  1976.    isblank(ds.power.n) then
  1977.    return
  1978. endif
  1979.  
  1980. ;-- do_it!
  1981. ds.tape.r[ds.tape.count.s] =
  1982. strval(pow(numval(ds.tape.r[ds.tape.to.use.s]),ds.power.n))
  1983.  
  1984. ;-- set the decimal array element
  1985. ds.set.decimal.u()
  1986.  
  1987. if lower( ds.tape.r[ds.tape.count.s] ) = "error" then
  1988.    ds.error.u(
  1989.    "Sorry, the computer could not handle the requested calculation.",
  1990.    ;-- there's that global variable again!
  1991.    ds.press.it.a )
  1992. endif
  1993.  
  1994. endproc
  1995.  
  1996. ?? "." message memleft() writelib ds.aplib.a ds.math.pow.u
  1997. release procs ds.math.pow.u
  1998.  
  1999. ;-------------------------------------------------------------------------------
  2000. ;                                                              ds.math.round.u()
  2001. ;-------------------------------------------------------------------------------
  2002. ; purpose: rounds a number to a given number of places
  2003. proc ds.math.round.u()
  2004.  
  2005. private
  2006. ds.round.s   ;-- the number of places to round to
  2007.  
  2008. ;-- clear the top 2 lines
  2009. @ 1,0 clear eol
  2010. @ 0,0 clear eol
  2011.  
  2012. ;-- place a prompt
  2013. ?? "Enter a whole number between -15 and 15 to round the last entry to: "
  2014.  
  2015. ;-- turn the cursor on
  2016. cursor normal
  2017.  
  2018. ;-- get a legal value
  2019. ;-- you can round to a negative number of places, ie the nearest thousand
  2020. accept "s" min -15 max 15 picture "[-]#[#]" to ds.round.s
  2021.  
  2022. ;-- if assigned and not blank, round the value
  2023. if isassigned(ds.round.s) and
  2024.    not isblank(ds.round.s) then
  2025.    ;-- the round function sometimes returns the wrong value
  2026.    ;-- so decimals need to be adjusted a bit to make it
  2027.    ;-- work correctly
  2028.    if ds.round.s > 0 then
  2029.       ds.tape.r[ds.tape.to.use.s] =
  2030.       strval(
  2031.       numval(ds.tape.r[ds.tape.to.use.s]) +
  2032.       numval("." + fill(0,ds.round.s+1) + "1")
  2033.       )
  2034.    endif
  2035.    ;-- round it the specified number of places
  2036.    ds.tape.r[ds.tape.count.s] =
  2037.    strval(round(numval(ds.tape.r[ds.tape.to.use.s]),ds.round.s))
  2038.    ;-- set the  decimal array element
  2039.    ds.set.decimal.u()
  2040. endif
  2041.  
  2042. endproc
  2043.  
  2044. ?? "." message memleft() writelib ds.aplib.a ds.math.round.u
  2045. release procs ds.math.round.u
  2046.  
  2047. ;-------------------------------------------------------------------------------
  2048. ;                                                             ds.set.decimal.u()
  2049. ;-------------------------------------------------------------------------------
  2050. ; purpose: sets the array element ds.decimal.r to true or false by searching
  2051. ;          the string for a period
  2052. ;          this originally attempted to compare the value of the number
  2053. ;          against the integer of the number to perform this function
  2054. ;          however, doing this on a large number took as long a 15 seconds
  2055. ;          on a 25mhz 386
  2056. ;          the current routine runs very fast however
  2057. proc ds.set.decimal.u()
  2058.  
  2059. ;-- search for a period in the string
  2060. if search(".",ds.tape.r[ds.tape.count.s]) = 0 then
  2061.    ds.decimal.r[ds.tape.count.s] = false
  2062. else
  2063.    ds.decimal.r[ds.tape.count.s] = true
  2064. endif
  2065.  
  2066. endproc
  2067.  
  2068. ?? "." message memleft() writelib ds.aplib.a ds.set.decimal.u
  2069. release procs ds.set.decimal.u
  2070.  
  2071. ;-------------------------------------------------------------------------------
  2072. ;                                                                    ds.menu.u()
  2073. ;-------------------------------------------------------------------------------
  2074. ; purpose: displays the menu when [f10] is pressed - a special key
  2075. proc ds.menu.u()
  2076.  
  2077. private
  2078. ds.menu.choice.a,   ;-- private menu choice variable
  2079. errorproc,          ;-- private errorproc used for the call to ds.custom.v()
  2080. autolib,            ;-- autolib is private here as it is re-defined to
  2081.                     ;-- to attempt to read the procedure ds.custom.v
  2082. ds.not.defined.a    ;-- returned value of the errorproc that indicates
  2083.                     ;-- if the procedure existed or not
  2084.  
  2085.  
  2086. ;-- re-set the autolib because it is declared
  2087. ;-- as a private variable in this procedure
  2088. autolib = ds.aplib.a
  2089.  
  2090. ;-- initial setting of this variable
  2091. ds.rebuild.l = false
  2092.  
  2093. ;-- display the choices
  2094. showmenu
  2095.    "Mathematical " : " Perform Mathematical functions.",
  2096.    "Trigonometry " : " Perform Trigonometry calculations.",
  2097.    "Financial "    : " Perform Financial calculations.",
  2098.    "Custom "       : " Perform Custom Designed calculations.",
  2099.    "Esc "          : " Return to what you were doing before pressing [F10]."
  2100. to ds.menu.choice.a
  2101.  
  2102. switch
  2103.  
  2104.    ;-- call the proper procedure
  2105.    case ds.menu.choice.a = "Mathematical " :
  2106.       ds.math.u()
  2107.  
  2108.    ;-- call up the trig procedures
  2109.    case ds.menu.choice.a = "Trigonometry " :
  2110.       ;-- assign retval for the following while loop
  2111.       retval = "dsloop"
  2112.       ;-- until ds.trig.a returns a value other then
  2113.       ;-- "dsloop" then call the procedure again
  2114.       while (lower(retval) = "dsloop")
  2115.          ds.trig.a()
  2116.       endwhile
  2117.       ;-- reset this variable, the calculator need to be
  2118.       ;-- re-painted on the screen
  2119.       ds.rebuild.l = true
  2120.  
  2121.    ;-- call the financial procedure
  2122.    case ds.menu.choice.a = "Financial " :
  2123.       ds.finance.u()
  2124.  
  2125.    ;-- this was fun, the procedure and/or the library
  2126.    ;-- may not exist at all
  2127.    case ds.menu.choice.a = "Custom " :
  2128.       ;-- bottom line re-appearer
  2129.       canvas off
  2130.       message ""
  2131.       @ 22,78 clear eol
  2132.       canvas on
  2133.       ;-- define the errorproc
  2134.       ;-- I parted from the normal pbe notation here as
  2135.       ;-- ds.oops.1 always returns a 1 - to step over
  2136.       ;-- the offending command
  2137.       errorproc = "ds.oops.1"
  2138.       ;-- read it into memory
  2139.       readlib ds.aplib.a ds.oops.1
  2140.       ;-- reset the autolib to the custom library name
  2141.       ;-- passed in the parameter to ds.calc.v
  2142.       ;-- I could try a isfile on the library but this works
  2143.       ;-- so why fix it
  2144.       autolib = ds.custom.lib.a
  2145.       ;-- attempt to call this procedure from
  2146.       ;-- the custom library
  2147.       ;-- if it does not exist, then ds.oops.1 returns 1 to step
  2148.       ;-- over this call
  2149.       ds.custom.v()
  2150.       ;-- reset the errorproc
  2151.       errorproc = ""
  2152.       ;-- reset the autolib
  2153.       autolib = ds.aplib.a
  2154.       ;-- ds.not.defined.a would have been assigned in the errorproc
  2155.       ;-- if it was called
  2156.       ;-- make an assignment if it isn't for the next if statement
  2157.       if not isassigned(ds.not.defined.a) then
  2158.          ds.not.defined.a = "ok"
  2159.       endif
  2160.       ;-- if the error proc wasn't called, assure that the returned value
  2161.       ;-- from ds,custom.v was really a numeric value
  2162.       if lower(ds.not.defined.a) <> "noproc" then
  2163.          if lower(numval(strval(retval))) <> "error" then
  2164.             ;-- okay, make the assignment to the tape entry
  2165.             ds.tape.r[ds.tape.count.s] = strval(retval)
  2166.             ;-- set the ds.decimal.r array element
  2167.             ds.set.decimal.u()
  2168.          endif
  2169.          ;-- set the variable to re-paint the canvas
  2170.          ds.rebuild.l = true
  2171.       endif
  2172.  
  2173. endswitch
  2174.  
  2175. ;-- bottom line re-appearer
  2176. if lower(ds.menu.choice.a) <> "trigonometry " then
  2177.    cursor off
  2178.    message ""
  2179.    @ 22,78 clear eol
  2180.    canvas on
  2181. else
  2182.    cursor off
  2183.    message ""
  2184.    @ 22,78 ?? " ║"
  2185.    canvas on
  2186. endif
  2187.  
  2188. ;-- replace the main prompt message
  2189. ds.main.prompt.u()
  2190.  
  2191. return
  2192.  
  2193. endproc
  2194.  
  2195. ?? "." message memleft() writelib ds.aplib.a ds.menu.u
  2196. release procs ds.menu.u
  2197.  
  2198. ;-------------------------------------------------------------------------------
  2199. ;                                                                 ds.finance.u()
  2200. ;-------------------------------------------------------------------------------
  2201. ; purpose: displays the financial menu choices
  2202. proc ds.finance.u()
  2203.  
  2204. private
  2205. ds.finance.choice.a    ;-- menu choice variable
  2206.  
  2207. ;-- bottom line re-appearer
  2208. canvas off
  2209. message ""
  2210. @ 22,78 clear eol
  2211. canvas on
  2212.  
  2213. ;-- display menu choices
  2214. showmenu
  2215.  
  2216.    "Future Value "     : " The future value of a series of equal payments.",
  2217.    "Periodic Payment " : " The periodic payment to pay off a loan.",
  2218.    "Present Value "    : " The present value of a series of equal payments.",
  2219.    "Esc "              : " Return to what you were doing before pressing [F10]."
  2220. to ds.finance.choice.a
  2221.  
  2222. ;-- bottom line re-appearer
  2223. canvas off
  2224. message ""
  2225. @ 22,78 clear eol
  2226. canvas on
  2227. style reverse
  2228.  
  2229. switch
  2230.  
  2231.    ;-- call the appropriate procedure passing the
  2232.    ;-- menu choice variable
  2233.    case ds.finance.choice.a = "Future Value " or
  2234.         ds.finance.choice.a = "Present Value " :
  2235.       ds.finance.values.l(ds.finance.choice.a)
  2236.  
  2237.    ;-- call the appropriate procedure
  2238.    case ds.finance.choice.a = "Periodic Payment " :
  2239.       ds.finance.payment.l()
  2240.  
  2241. endswitch
  2242.  
  2243. style
  2244.  
  2245. ;-- user opted to quit so set retval for the
  2246. ;-- next if statement
  2247. if ds.finance.choice.a = "Esc" or
  2248.    ds.finance.choice.a = "Esc " then
  2249.    retval = false
  2250. endif
  2251.  
  2252. ;-- retval set above or from the called procedures
  2253. ;-- if required, call the procedure used to set the
  2254. ;-- tape decimal array element
  2255. if retval then
  2256.    ds.set.decimal.u()
  2257. endif
  2258.  
  2259. endproc
  2260.  
  2261. ?? "." message memleft() writelib ds.aplib.a ds.finance.u
  2262. release procs ds.finance.u
  2263.  
  2264. ;-------------------------------------------------------------------------------
  2265. ;                                       ds.finance.values.l(ds.finance.choice.a)
  2266. ;-------------------------------------------------------------------------------
  2267. ; purpose: computes the future or present values of payments, interest rates and
  2268. ;          periods
  2269. proc ds.finance.values.l(
  2270. ds.finance.choice.a)  ;-- which function to use
  2271.  
  2272. private
  2273. ds.payment.c,     ;-- payment amount used in the computation
  2274. ds.interest.n,    ;-- interest amount used in the computation
  2275. ds.periods.s      ;-- number of monthly periods used in the computation
  2276.  
  2277. ;-- clear the top 2 lines
  2278. @ 01,00 clear eol
  2279. @ 00,00 clear eol
  2280.  
  2281. ;-- turn the cursor on
  2282. cursor normal
  2283.  
  2284. ;-- place a prompt on the screen
  2285. ?? "Enter the periodic payment: "
  2286.  
  2287. ;-- get a dollar value for the payment
  2288. accept "$"
  2289. ;-- min of 1 please
  2290. min 1
  2291. to ds.payment.c
  2292.  
  2293. ;-- user pressed escape or left the entry blank
  2294. if not isassigned(ds.payment.c) or
  2295.    isblank(ds.payment.c) then
  2296.    return false
  2297. endif
  2298.  
  2299. ;-- reposition the cursor
  2300. @ 00,00
  2301.  
  2302. ;-- place the next prompt on the screen
  2303. ?? "Enter the yearly interest rate {##.###}: "
  2304.  
  2305. ;-- get a numeric value
  2306. accept "n"
  2307. ;-- I like this one - now if I can get the bank to agree!
  2308. min .001
  2309. ;-- nasty loan shark interest rate!
  2310. max 99.999
  2311. ;-- give them a picture to help them
  2312. picture "{[#][#].[#][#][#],[#].[#][#][#],[#]}"
  2313. to ds.interest.n
  2314.  
  2315. ;-- user pressed escape or left the entry blank
  2316. if not isassigned(ds.interest.n) or
  2317.    isblank(ds.interest.n) then
  2318.    return false
  2319. endif
  2320.  
  2321. ;-- convert it to the interest per period
  2322. ;-- 12 = months / 100 to convert to the decimal of the percentage
  2323. ds.interest.n = ds.interest.n / 12 / 100
  2324.  
  2325. ;-- reposition the cursor
  2326. @ 00,00
  2327.  
  2328. ;-- place the next prompt on the screen
  2329. ?? "Enter the number of periods (in months): "
  2330.  
  2331. ;-- get a short numeric value
  2332. accept "s"
  2333. ;-- my kind of payment!
  2334. min 1
  2335. ;-- okay, a max of 85 years
  2336. ;-- sometimes fv(..) and pv(..) will blow up on large numbers
  2337. ;-- as they use the pow() function somehow.
  2338. max 1020
  2339. to ds.periods.s
  2340.  
  2341. ;-- user pressed escape or left the entry blank
  2342. if not isassigned(ds.periods.s) or
  2343.    isblank(ds.periods.s) then
  2344.    return false
  2345. endif
  2346.  
  2347. ;-- perform the proper function for the selected choice
  2348. if lower(ds.finance.choice.a) = "future value " then
  2349.    ds.tape.r[ds.tape.count.s] =
  2350.    strval(fv(ds.payment.c,ds.interest.n,ds.periods.s))
  2351. else
  2352.    ds.tape.r[ds.tape.count.s] =
  2353.    strval(pv(ds.payment.c,ds.interest.n,ds.periods.s))
  2354. endif
  2355.  
  2356. ;-- inform the calling procedure that this procedure
  2357. ;-- completed successfully
  2358. return true
  2359.  
  2360. endproc
  2361.  
  2362. ?? "." message memleft() writelib ds.aplib.a ds.finance.values.l
  2363. release procs ds.finance.values.l
  2364.  
  2365.  
  2366. ;-------------------------------------------------------------------------------
  2367. ;                                                         ds.finance.payment.l()
  2368. ;-------------------------------------------------------------------------------
  2369. ; purpose: computes the payment on a given loan for a given interest for a
  2370. ;          given number of months
  2371. proc ds.finance.payment.l()
  2372.  
  2373. private
  2374. ds.principal.c,    ;-- principal amount used in the computation
  2375. ds.interest.n,     ;-- interest amount used in the computation
  2376. ds.periods.s       ;-- number of monthly periods used in the computation
  2377.  
  2378.  
  2379. ;-- clear the top 2 lines
  2380. @ 01,00 clear eol
  2381. @ 00,00 clear eol
  2382.  
  2383. ;-- turn the cursor on
  2384. cursor normal
  2385.  
  2386. ;-- place the next prompt on the screen
  2387. ?? "Enter the loan principal payment: "
  2388.  
  2389. ;-- get a dollar value for the principal
  2390. accept "$"
  2391. ;-- my kind of loan!
  2392. min 1 to
  2393. ds.principal.c
  2394.  
  2395. ;-- user pressed escape or left the entry blank
  2396. if not isassigned(ds.principal.c) or
  2397.    isblank(ds.principal.c) then
  2398.    return false
  2399. endif
  2400.  
  2401. ;-- reposition the cursor
  2402. @ 00,00
  2403.  
  2404. ;-- place the next prompt on the screen
  2405. ?? "Enter the yearly interest rate {##.###}: "
  2406.  
  2407. ;-- get a numeric value
  2408. accept "n"
  2409. ;-- I like this one - now if I can get the bank to agree!
  2410. min .001
  2411. ;-- nasty loan shark interest rate!
  2412. max 99.999
  2413. ;-- give them a picture to help them
  2414. picture "{[#][#].[#][#][#],[#].[#][#][#],[#]}"
  2415. to ds.interest.n
  2416.  
  2417. ;-- user pressed escape or left the entry blank
  2418. if not isassigned(ds.interest.n) or
  2419.    isblank(ds.interest.n) then
  2420.    return false
  2421. endif
  2422.  
  2423. ;-- convert it to the interest per period
  2424. ;-- 12 = months / 100 to convert to the decimal of the percentage
  2425. ds.interest.n = ds.interest.n / 12 / 100
  2426.  
  2427. ;-- reposition the cursor
  2428. @ 00,00
  2429.  
  2430. ;-- place the next prompt on the screen
  2431. ?? "Enter the number of periods (in months): "
  2432.  
  2433. ;-- get a short numeric value
  2434. accept "s"
  2435. ;-- my kind of loan!
  2436. min 1
  2437. ;-- okay, a max of 85 years
  2438. ;-- sometimes pmt(..) will blow up on large numbers
  2439. ;-- as it uses the pow() function somehow.
  2440. max 1020
  2441. to ds.periods.s
  2442.  
  2443. ;-- user pressed escape or left the entry blank
  2444. if not isassigned(ds.periods.s) or
  2445.    isblank(ds.periods.s) then
  2446.    return false
  2447. endif
  2448.  
  2449. ;-- perform the proper function
  2450. ds.tape.r[ds.tape.count.s] =
  2451. strval(pmt(ds.principal.c,ds.interest.n,ds.periods.s))
  2452.  
  2453. ;-- inform the calling procedure that this procedure
  2454. ;-- completed successfully
  2455. return true
  2456.  
  2457. endproc
  2458.  
  2459. ?? "." message memleft() writelib ds.aplib.a ds.finance.payment.l
  2460. release procs ds.finance.payment.l
  2461.  
  2462. ;-------------------------------------------------------------------------------
  2463. ;                                                             ds.main.prompt.u()
  2464. ;-------------------------------------------------------------------------------
  2465. ; purpose: displays the main prompt on the top 2 lines of the screen
  2466. proc ds.main.prompt.u()
  2467.  
  2468. @ 00,00
  2469. ?? format("w80,ac",
  2470.           "Press [F10] for special functions and formulas, [F1] for help.")
  2471. @ 01,00
  2472. ?? format("w80,ac",
  2473.           "Press [Esc] to return to what you were doing.")
  2474. endproc
  2475.  
  2476. ?? "." message memleft() writelib ds.aplib.a ds.main.prompt.u
  2477. release procs ds.main.prompt.u
  2478.  
  2479.  
  2480. ;-------------------------------------------------------------------------------
  2481. ;                                                                    ds.trig.a()
  2482. ;-------------------------------------------------------------------------------
  2483. ; purpose: main procedure for the trig module of ds.calc.v
  2484. proc ds.trig.a()
  2485.  
  2486. private
  2487. ds.trig.choice.s,        ;-- the highlight menu choice selected by the
  2488.                          ;-- user from the choices in the menu box on the
  2489.                          ;-- right hand side of the screen
  2490. ds.movement.key.s,       ;-- the movement key pressed to move the
  2491.                          ;-- highlighted menu bar
  2492. ds.trig.choice.was.s,    ;-- what the previous highlighted menu choice
  2493.                          ;-- was so that it can be turned off
  2494. ds.side.a.n,             ;-- variable that holds the length of side a
  2495.                          ;-- of the triangle
  2496. ds.side.b.n,             ;-- " side b
  2497. ds.side.c.n,             ;-- " side c
  2498. ds.degrees.a.s,          ;-- variable that holds the angle in degrees of
  2499.                          ;-- angle a of the triangle
  2500. ds.degrees.b.s,          ;-- " angle b
  2501. ds.degrees.c.s,          ;-- " angle c
  2502. ds.minutes.a.s,          ;-- variable that holds the angles' minutes of
  2503.                          ;-- angle a of the triangle
  2504. ds.minutes.b.s,          ;-- " angle b
  2505. ds.minutes.c.s,          ;-- " angle c
  2506. ds.seconds.a.s,          ;-- variable that holds the angles' seconds of
  2507.                          ;-- angle a of the triangle
  2508. ds.seconds.b.s,          ;-- " angle b
  2509. ds.seconds.c.s,          ;-- " angle c
  2510. ds.radians.a.s,          ;-- variable that holds the angles' radian value of
  2511.                          ;-- angle a of the triangle
  2512. ds.radians.b.s,          ;-- " angle b
  2513. ds.radians.c.s,          ;-- " angle c
  2514. ds.precision.choice.s,   ;-- variable that is used when angles need to be
  2515.                          ;-- entered to determine what need to be accepted
  2516.                          ;-- from the user, ie. degrees, degrees & minutes,
  2517.                          ;-- degrees, minutes & seconds or radians
  2518. ds.periphery.n,          ;-- the variable which holds the calculated
  2519.                          ;-- periphery of the triangle
  2520. ds.area.n,               ;-- the variable which holds the calculated
  2521.                          ;-- area of the triangle
  2522. ds.trig.loop.getchar.s   ;-- variable assigned with getchar() that the user
  2523.                          ;-- presses to indicate what he wishes to do next
  2524.  
  2525.  
  2526. ;-- initialize the variable
  2527. ds.trig.choice.s = 1
  2528.  
  2529. ;-- paint the trig screen
  2530. ds.trig.screen.u()
  2531.  
  2532. ;-- stay here till the program says you can leave!
  2533. while true
  2534.  
  2535.    ;-- get a keystroke from the user
  2536.    ds.movement.key.s = getchar()
  2537.  
  2538.    ;-- now determine what the user pressed
  2539.    switch
  2540.  
  2541.       ;-- pressed escape, let me out of here!
  2542.       case ds.movement.key.s = 27 :
  2543.          ;-- return escape to the calling procedure
  2544.          return ds.movement.key.s
  2545.  
  2546.       ;-- user made a selection [enter]
  2547.       case ds.movement.key.s = 13 :
  2548.          ;-- leave the while true loop to do some other processing
  2549.          quitloop
  2550.  
  2551.       otherwise :
  2552.          ;-- move the highlight menu bar per the key pressed
  2553.          ds.trig.selection.l()
  2554.          ;-- non legal keys make me want to beep!
  2555.          if not retval then
  2556.             beep
  2557.          endif
  2558.  
  2559.    endswitch
  2560.  
  2561. endwhile
  2562.  
  2563. ;-- user pressed enter, selecting a menu choice
  2564. ;-- to get this far
  2565.  
  2566. ;-- for these choices, we need to find out how the user
  2567. ;-- wants to enter the angles
  2568. if ds.trig.choice.s > 3 and
  2569.    ds.trig.choice.s < 13 then
  2570.    ;-- call the procedure that sets the variable
  2571.    ;-- based on user input
  2572.    ds.set.trig.precision.l()
  2573. else
  2574.    ;-- this variable = 0 when no angles,
  2575.    ;-- all the sides are entered by the user
  2576.    ds.precision.choice.s = 0
  2577.    retval = true
  2578. endif
  2579.  
  2580. ;-- user escaped out of ds.set.trig.precision.l()
  2581. ;-- and it returned false
  2582. if not retval then
  2583.    ;-- this indicates to the calling procedure
  2584.    ;-- to return to this procedure again
  2585.    ;-- this is necessary to clear all of the private variables
  2586.    ;-- as private variables can not be released except by
  2587.    ;-- exiting the procedure that declared them as private
  2588.    ;-- otherwise, values in various variables may be left
  2589.    ;-- from another "loop" and would be used when they
  2590.    ;-- don't apply
  2591.    return "dsloop"
  2592. endif
  2593.  
  2594. ;-- set the style
  2595. style reverse
  2596.  
  2597. ;-- get the info from the user
  2598. switch
  2599.  
  2600.    ;-- gets the lengths of the sides, no angles
  2601.    ;-- required per selected choice
  2602.    case ds.precision.choice.s = 0 :
  2603.       ;-- call the procedure that gets the lengths of sides
  2604.       ds.trig.get.sides.l(ds.trig.choice.s)
  2605.  
  2606.    ;-- user choose to enter the angles in degrees
  2607.    ;-- and/or minutes and/or seconds
  2608.    case ds.precision.choice.s > 0 and
  2609.         ds.precision.choice.s < 4 :
  2610.       ;-- this procedure gets this info
  2611.       ds.trig.get.angles.dms.l(ds.trig.choice.s)
  2612.  
  2613.    ;-- gets the angles in radians
  2614.    case ds.precision.choice.s = 4 :
  2615.       ;-- this procedure gets this info
  2616.       ds.trig.get.angles.radians.l(ds.trig.choice.s)
  2617.  
  2618. endswitch
  2619.  
  2620. ;-- turn style back to normal mode
  2621. style
  2622. ;-- and turn the cursor off
  2623. cursor off
  2624.  
  2625. ;-- user quit out of one of the previous procedures,
  2626. ;-- this call clears the variables and starts this procedure again
  2627. if not retval then
  2628.    return "dsloop"
  2629. endif
  2630.  
  2631. ;-- converts known angles in degrees and.or minutes
  2632. ;-- and/or seconds to radians
  2633. ;-- all of the trig functions require radians
  2634. if ds.precision.choice.s >0 and
  2635.    ds.precision.choice.s <4 then
  2636.    ds.convert.degrees.u()
  2637. endif
  2638.  
  2639. ;-- user supplied two angles
  2640. if ds.trig.choice.s = 10 then
  2641.    ;-- and they gave me some bum info!
  2642.    if (round((ds.radians.a.s + ds.radians.b.s),15) >= 3.141592653589) then
  2643.       ds.error.u(
  2644.       "The angles supplied for A and B can not be greater" +
  2645.       " than or equal to 180°!",
  2646.       ds.press.it.a)
  2647.       return "dsloop"
  2648.    endif
  2649. endif
  2650.  
  2651. ;-- based on the fact we know two angles
  2652. ;-- based on the choice selected, compute the third
  2653. ;-- remaining angle
  2654. if ds.trig.choice.s > 3 and
  2655.    ds.trig.choice.s < 11 then
  2656.    ds.compute.third.angle.u()
  2657. endif
  2658.  
  2659. ;-- now based on the choice (and the known values),
  2660. ;-- select the proper set of calculations needed
  2661. ;-- to compute the unknowns
  2662. switch
  2663.    case ds.trig.choice.s > 0 and
  2664.         ds.trig.choice.s < 4  :
  2665.       ds.trig.calc.set.1.u()
  2666.    case ds.trig.choice.s > 3 and
  2667.         ds.trig.choice.s < 10 :
  2668.       ds.trig.calc.set.2.u()
  2669.    case ds.trig.choice.s = 10 :
  2670.       ds.trig.calc.set.3.u()
  2671.    case ds.trig.choice.s = 11 :
  2672.       ds.trig.calc.set.4.u()
  2673.    case ds.trig.choice.s = 12 :
  2674.       ds.trig.calc.set.5.u()
  2675.    otherwise :
  2676.       ds.trig.calc.set.6.u()
  2677. endswitch
  2678.  
  2679. ;-- at this point, all of the angles are known in
  2680. ;-- radians, so compute the unknown degrees, minutes,
  2681. ;-- and seconds
  2682. ds.trig.convert.radians.u()
  2683.  
  2684. ;-- now the periphery can ge calculated based on
  2685. ;-- the total of the three sides
  2686. ds.periphery.n = ds.side.a.n + ds.side.b.n + ds.side.c.n
  2687.  
  2688. ;-- and finally display the answer
  2689. ds.trig.display.answer.u()
  2690.  
  2691. ;-- set the style for the prompt
  2692. style reverse
  2693.  
  2694. ;-- now find out what the user wants to do next
  2695. @ 00,00
  2696. ?? format("w80,ac","Press any key to clear the work" +
  2697.           " space and re-calculate another triangle.")
  2698. @ 01,00
  2699. ?? format("w80,ac","Press [Esc] to return to the calculator.")
  2700.  
  2701. ;-- reset to normal style
  2702. style
  2703.  
  2704. ;-- and get a keystroke from the user
  2705. ds.trig.loop.getchar.s = getchar()
  2706.  
  2707. ;-- user wants to do another
  2708. if ds.trig.loop.getchar.s <> 27 then
  2709.    return "dsloop"
  2710. else
  2711.    ;-- or display a menu to determine a value
  2712.    ;-- to be returned to the calculator window
  2713.    ds.trig.return.menu.u()
  2714.    ;-- don't come back to this procedure
  2715.    return "escape"
  2716. endif
  2717.  
  2718. endproc
  2719.  
  2720. ?? "." message memleft() writelib ds.aplib.a ds.trig.a
  2721. release procs ds.trig.a
  2722.  
  2723.  
  2724. ;-------------------------------------------------------------------------------
  2725. ;                                                        ds.trig.return.menu.u()
  2726. ;-------------------------------------------------------------------------------
  2727. ; purpose: displays a menu of choices upon leaving the trig module to determine
  2728. ;          if the user wishes to return a value to the calculator window
  2729. proc ds.trig.return.menu.u()
  2730.  
  2731.  
  2732. private
  2733. ds.trig.return.choice.a   ;-- menu choice selection
  2734.  
  2735. ;-- stay in the loop until a selection is
  2736. ;-- made that allows leaving the loop
  2737. while true
  2738.  
  2739.    ;-- display menu choices
  2740.    showmenu
  2741.       "Side "      : " Return the value of a side to the calculator.",
  2742.       "Radian "    : " Return the value of an angle to the calculator.",
  2743.       "Periphery " : " Return the value of the periphery of" +
  2744.                      " the triangle to the calculator.",
  2745.       "Area "      : " Return the value of the area of the " +
  2746.                      "triangle to the calculator.",
  2747.       "Esc "       : " Return to the calculator with out a value."
  2748.    to ds.trig.return.choice.a
  2749.  
  2750.    ;-- bottom line restorer
  2751.    canvas off
  2752.    message ""
  2753.    @ 22,78 ?? " ║"
  2754.    canvas on
  2755.  
  2756.    ;-- evaluate the selected choice
  2757.    switch
  2758.  
  2759.       ;-- if side, another menu
  2760.       case ds.trig.return.choice.a = "Side " :
  2761.          ;-- get which side to return
  2762.          showmenu
  2763.             "Side a " : " Return side \"a\".",
  2764.             "Side b " : " Return side \"b\".",
  2765.             "Side c " : " Return side \"c\".",
  2766.             "Esc " : " Return to the previous menu."
  2767.          to ds.trig.return.choice.a
  2768.  
  2769.          ;-- evaluate the choice
  2770.          switch
  2771.  
  2772.             ;-- go back to the previous menu
  2773.             case ds.trig.return.choice.a = "Esc" or
  2774.                  ds.trig.return.choice.a = "Esc " :
  2775.  
  2776.                ;-- bottom line restorer
  2777.                canvas off
  2778.                message ""
  2779.                @ 22,78 ?? " ║"
  2780.                canvas on
  2781.                loop
  2782.  
  2783.             ;-- user choose side a
  2784.             case ds.trig.return.choice.a = "Side a " :
  2785.                ;-- make assignment to the tape variable
  2786.                ds.tape.r[ds.tape.count.s] = strval(ds.side.a.n)
  2787.                ;-- set the decimal array
  2788.                ds.set.decimal.u()
  2789.  
  2790.             ;-- user choose side b
  2791.             case ds.trig.return.choice.a = "Side b " :
  2792.                ;-- make assignment to the tape variable
  2793.                ds.tape.r[ds.tape.count.s] = strval(ds.side.b.n)
  2794.                ;-- set the decimal array
  2795.                ds.set.decimal.u()
  2796.  
  2797.             ;-- user choose side c
  2798.             case ds.trig.return.choice.a = "Side c " :
  2799.                ;-- make assignment to the tape variable
  2800.                ds.tape.r[ds.tape.count.s] = strval(ds.side.c.n)
  2801.                ;-- set the decimal array
  2802.                ds.set.decimal.u()
  2803.  
  2804.          endswitch
  2805.  
  2806.  
  2807.  
  2808.       ;-- if radian, another menu
  2809.       case ds.trig.return.choice.a = "Radian " :
  2810.          ;-- get which radian to return
  2811.          showmenu
  2812.             "Radian of A " : " Return the radian of angle \"A\".",
  2813.             "Radian of B " : " Return the radian of angle \"B\".",
  2814.             "Radian of C " : " Return the radian of angle \"C\".",
  2815.             "Esc " : " Return to the previous menu."
  2816.          to ds.trig.return.choice.a
  2817.  
  2818.          switch
  2819.  
  2820.             ;-- go back to the previous menu
  2821.             case ds.trig.return.choice.a = "Esc" or
  2822.                  ds.trig.return.choice.a = "Esc " :
  2823.                ;-- bottom line restorer
  2824.                canvas off
  2825.                message ""
  2826.                @ 22,78 ?? " ║"
  2827.                canvas on
  2828.                loop
  2829.  
  2830.             ;-- user choose radian a
  2831.             case ds.trig.return.choice.a = "Radian of A " :
  2832.                ;-- make assignment to the tape variable
  2833.                ds.tape.r[ds.tape.count.s] = strval(ds.radians.a.s)
  2834.                ;-- set the decimal array
  2835.                ds.set.decimal.u()
  2836.  
  2837.             ;-- user choose radian b
  2838.             case ds.trig.return.choice.a = "Radian of B " :
  2839.                ;-- make assignment to the tape variable
  2840.                ds.tape.r[ds.tape.count.s] = strval(ds.radians.b.s)
  2841.                ;-- set the decimal array
  2842.                ds.set.decimal.u()
  2843.  
  2844.             ;-- user choose radian c
  2845.             case ds.trig.return.choice.a = "Radian of C " :
  2846.                ;-- make assignment to the tape variable
  2847.                ds.tape.r[ds.tape.count.s] = strval(ds.radians.c.s)
  2848.                ;-- set the decimal array
  2849.                ds.set.decimal.u()
  2850.  
  2851.          endswitch
  2852.  
  2853.       ;-- user choose periphery
  2854.       case ds.trig.return.choice.a = "Periphery " :
  2855.          ;-- make assignment to the tape variable
  2856.          ds.tape.r[ds.tape.count.s] = strval(ds.periphery.n)
  2857.          ;-- set the decimal array
  2858.          ds.set.decimal.u()
  2859.  
  2860.       ;-- user choose area
  2861.       case ds.trig.return.choice.a = "Area " :
  2862.          ;-- make assignment to the tape variable
  2863.          ds.tape.r[ds.tape.count.s] = strval(ds.area.n)
  2864.          ;-- set the decimal array
  2865.          ds.set.decimal.u()
  2866.  
  2867.    endswitch
  2868.  
  2869.    ;-- back to where we came from
  2870.    return
  2871.  
  2872. endwhile
  2873.  
  2874. endproc
  2875.  
  2876. ?? "." message memleft() writelib ds.aplib.a ds.trig.return.menu.u
  2877. release procs ds.trig.return.menu.u
  2878.  
  2879. ;-------------------------------------------------------------------------------
  2880. ;                                                             ds.trig.screen.u()
  2881. ;-------------------------------------------------------------------------------
  2882. ; purpose: displays the trig screen
  2883. proc ds.trig.screen.u()
  2884.  
  2885. ;-- inform the user something is happening
  2886. @ 00,00 clear eol ?? "Working"
  2887. style blink ?? "....."
  2888. @ 01,00 clear eol style
  2889.  
  2890. ;-- turn the canvas off
  2891. canvas off
  2892.  
  2893. ;-- display the trig prompt lines
  2894. @ 00,00 ?? format("w80,ac",
  2895.                   "Use the cursor keys to select the appropriate" +
  2896.                   " menu choice to input the known")
  2897. @ 01,00 ?? format("w80,ac",
  2898.                   "values of either a right or oblique angle" +
  2899.                   " triangle and press [Enter].")
  2900.  
  2901. ;-- place the screen on the canvas
  2902. text
  2903. ╔══════════════════════════════════════════════════════════════════════════════╗
  2904. ║                                                                              ║
  2905. ║     Angle C =                         ╔═════════════════╦══════════════════╗ ║
  2906. ║    Radians =                         ║   Right Angle   ║  Oblique Angle   ║ ║
  2907. ║                                     ╠═════════════════╬══════════════════╣ ║
  2908. ║                                     ║ Angle A = 90°   ║ Known values:    ║ ║
  2909. ║                                     ║ Known values:   ║ Side a with      ║ ║
  2910. ║                                     ║                 ║  Angles A & B    ║ ║
  2911. ║              Side a =               ║ Sides a & c     ║                  ║ ║
  2912. ║                                     ║ Sides b & c     ║ Sides a & b with ║ ║
  2913. ║                                     ║ Side a; Angle B ║  Angle C         ║ ║
  2914. ║                                     ║ Side a; Angle C ║                  ║ ║
  2915. ║   Side b =                          ║ Side b; Angle B ║ Sides a & b with ║ ║
  2916. ║                                     ║ Side b; Angle C ║  Angle A         ║ ║
  2917. ║                                     ║ Side c; Angle B ║                  ║ ║
  2918. ║                                     ║ Side c; Angle C ║ Sides a, b & c   ║ ║
  2919. ║                                     ╚═════════════════╩══════════════════╝ ║
  2920. ║   Angle A =                                                                ║
  2921. ║   Radians =                     Angle B =                                  ║
  2922. ║                  Radians =                                  ║
  2923. ║    Side c =                                 Periphery =                      ║
  2924. ║                                                  Area =                      ║
  2925. ╚═══════════════════ Press [Esc] to return to the calculator ══════════════════╝
  2926. endtext
  2927.  
  2928. ;-- highlight the default menu selection
  2929. style reverse
  2930. @ 09,42 ?? "Sides a & b    "
  2931.  
  2932. ;-- style back to normal
  2933. style
  2934.  
  2935. ;-- turn the canvas back on
  2936. canvas on
  2937.  
  2938. endproc
  2939.  
  2940. ?? "." message memleft() writelib ds.aplib.a ds.trig.screen.u
  2941. release procs ds.trig.screen.u
  2942.  
  2943. ;-------------------------------------------------------------------------------
  2944. ;                                                          ds.trig.selection.l()
  2945. ;-------------------------------------------------------------------------------
  2946. ; purpose: determines the key pressed and moves the highlighted menu choice
  2947. ;          accordingly
  2948. proc ds.trig.selection.l()
  2949.  
  2950.  
  2951. ;-- only accept the four movement keys and
  2952. ;-- home and end
  2953. if ds.movement.key.s > -71 or
  2954.    ds.movement.key.s < -80 or
  2955.    ds.movement.key.s = -73 or
  2956.    ds.movement.key.s = -74 or
  2957.    ds.movement.key.s = -76 or
  2958.    ds.movement.key.s = -78 then
  2959.    return false
  2960. endif
  2961.  
  2962. ;-- set the was variable to turn the previous
  2963. ;-- highlighted menu selection off
  2964. ds.trig.choice.was.s = ds.trig.choice.s
  2965.  
  2966. ;-- evaluate the movement required
  2967. switch
  2968.  
  2969.    ;-- user pressed home
  2970.    case ds.movement.key.s = -71 :
  2971.       ;-- was already there
  2972.       if ds.trig.choice.s = 1 then
  2973.          beep
  2974.          return true
  2975.       else
  2976.          ;-- set the position to be highlighted
  2977.          ds.trig.choice.s = 1
  2978.       endif
  2979.  
  2980.    ;-- user pressed end
  2981.    case ds.movement.key.s = -79 :
  2982.       ;-- was already there
  2983.       if ds.trig.choice.s = 13 then
  2984.          beep
  2985.          return true
  2986.       else
  2987.          ;-- set the position to be highlighted
  2988.          ds.trig.choice.s = 13
  2989.       endif
  2990.  
  2991.    ;-- user pressed up or left
  2992.    case ds.movement.key.s = -72 or
  2993.         ds.movement.key.s = -75 :
  2994.       ;-- adjust the position down one number
  2995.       ds.trig.choice.s = ds.trig.choice.s - 1
  2996.       ;-- oops, went to far, reset to the last choice
  2997.       if ds.trig.choice.s = 0 then
  2998.          ds.trig.choice.s = 13
  2999.       endif
  3000.  
  3001.    ;-- user pressed down or right
  3002.    case ds.movement.key.s = -77 or
  3003.         ds.movement.key.s = -80 :
  3004.       ;-- adjust the position up one number
  3005.       ds.trig.choice.s = ds.trig.choice.s + 1
  3006.       ;-- oops, went to far, reset to the first choice
  3007.       if ds.trig.choice.s = 14 then
  3008.          ds.trig.choice.s = 1
  3009.       endif
  3010.  
  3011. endswitch
  3012.  
  3013. ;-- set the highlight style
  3014. style reverse
  3015.  
  3016. ;-- toggle the new position on
  3017. ds.trig.choice.toggle.u(ds.trig.choice.s)
  3018.  
  3019. ;-- normal style
  3020. style
  3021.  
  3022. ;-- toggle the old position off
  3023. ds.trig.choice.toggle.u(ds.trig.choice.was.s)
  3024.  
  3025. return true
  3026.  
  3027. endproc
  3028.  
  3029. ?? "." message memleft() writelib ds.aplib.a ds.trig.selection.l
  3030. release procs ds.trig.selection.l
  3031.  
  3032. ;-------------------------------------------------------------------------------
  3033. ;                                               ds.trig.choice.toggle.u()
  3034. ;-------------------------------------------------------------------------------
  3035. ; purpose: toggles the menu choice on and off depending on the key pressed
  3036. proc ds.trig.choice.toggle.u(
  3037. ds.trig.choice.s)           ;-- passed parameter for the following
  3038.                             ;-- case statement
  3039.  
  3040. ;-- evaluate where to update the screen
  3041. switch
  3042.    case ds.trig.choice.s = 1  :
  3043.       @ 09,42 ?? "Sides a & b    "
  3044.    case ds.trig.choice.s = 2  :
  3045.       @ 10,42 ?? "Sides a & c    "
  3046.    case ds.trig.choice.s = 3  :
  3047.       @ 11,42 ?? "Sides b & c    "
  3048.    case ds.trig.choice.s = 4  :
  3049.       @ 12,42 ?? "Side a; Angle B"
  3050.    case ds.trig.choice.s = 5  :
  3051.       @ 13,42 ?? "Side a; Angle C"
  3052.    case ds.trig.choice.s = 6  :
  3053.       @ 14,42 ?? "Side b; Angle B"
  3054.    case ds.trig.choice.s = 7  :
  3055.       @ 15,42 ?? "Side b; Angle C"
  3056.    case ds.trig.choice.s = 8  :
  3057.       @ 16,42 ?? "Side c; Angle B"
  3058.    case ds.trig.choice.s = 9  :
  3059.       @ 17,42 ?? "Side c; Angle C"
  3060.    case ds.trig.choice.s = 10 :
  3061.       @ 08,60 ?? "Side a with     "
  3062.       @ 09,60 ?? " Angles A & B   "
  3063.    case ds.trig.choice.s = 11 :
  3064.       @ 11,60 ?? "Sides a & b with"
  3065.       @ 12,60 ?? " Angle C        "
  3066.    case ds.trig.choice.s = 12 :
  3067.       @ 14,60 ?? "Sides a & b with"
  3068.       @ 15,60 ?? " Angle A        "
  3069.    case ds.trig.choice.s = 13 :
  3070.       @ 17,60 ?? "Sides a, b & c  "
  3071. endswitch
  3072.  
  3073. endproc
  3074.  
  3075. ?? "." message memleft() writelib ds.aplib.a ds.trig.choice.toggle.u
  3076. release procs ds.trig.choice.toggle.u
  3077.  
  3078.  
  3079. ;-------------------------------------------------------------------------------
  3080. ;                                                      ds.set.trig.precision.l()
  3081. ;-------------------------------------------------------------------------------
  3082. ; purpose: when angles need to be entered to do the trig, this procedure
  3083. ;          gets from the user what he/she will enter so that other procedures
  3084. ;          know how many prompts and what to accept for input of that data
  3085. proc ds.set.trig.precision.l()
  3086.  
  3087. ;-- turn the cursor on
  3088. cursor normal
  3089.  
  3090. ;-- highlight the following
  3091. style reverse
  3092.  
  3093. ;-- place the prompt on the screen
  3094. @ 00,00 ?? format("w80,al",
  3095.                   "Will you be entering Angles in 1.(Degrees only)," +
  3096.                   " 2.(Degrees and Minutes),")
  3097. @ 01,00 ?? format("w80,al",
  3098.                   "3.(Degrees, Minutes and Seconds) or in 4.(Radians)? " +
  3099.                   "Enter Choice:")
  3100.  
  3101. ;-- place the cursor
  3102. @ 01,66
  3103.  
  3104. ;-- get the users selection
  3105. accept "s"
  3106. picture"{1,2,3,4}"
  3107. to ds.precision.choice.s
  3108.  
  3109. ;-- turn the cursor off
  3110. cursor off
  3111.  
  3112. ;-- reset to normal style
  3113. style
  3114.  
  3115. ;-- user pressed esc or left the prompt blank
  3116. if not isassigned(ds.precision.choice.s) or
  3117.    isblank(ds.precision.choice.s) then
  3118.    ;-- return false to cancel
  3119.    return false
  3120. endif
  3121.  
  3122. ;-- return true to continue
  3123. return true
  3124.  
  3125. endproc
  3126.  
  3127. ?? "." message memleft() writelib ds.aplib.a ds.set.trig.precision.l
  3128. release procs ds.set.trig.precision.l
  3129.  
  3130. ;-------------------------------------------------------------------------------
  3131. ;                                          ds.trig.get.sides.l(ds.trig.choice.s)
  3132. ;-------------------------------------------------------------------------------
  3133. ; purpose: this procedure gets the sides required of the triangle
  3134. proc ds.trig.get.sides.l(
  3135. ds.trig.choice.s)      ;-- this value determines which
  3136.                        ;--accept statements to use
  3137.  
  3138. ;-- clear the top 2 lines
  3139. @ 01,00 clear eol
  3140. @ 00,00 clear eol
  3141.  
  3142. ;-- turn the cursor on
  3143. cursor normal
  3144.  
  3145. ;-- these menu choices use this accept statement
  3146. if ds.trig.choice.s < 3 or
  3147.    ds.trig.choice.s = 13 then
  3148.    ;-- the prompt
  3149.    ?? "Enter the length of side a: "
  3150.    ;-- get the info
  3151.    accept "n"
  3152.    ;-- kind of small but where to draw the line?
  3153.    min .00000000001
  3154.    ;-- well, they could still press esc
  3155.    required
  3156.    to ds.side.a.n
  3157.    ;-- did they press esc?
  3158.    if not isassigned(ds.side.a.n) then
  3159.       return false
  3160.    endif
  3161.    @ 00,00
  3162. endif
  3163.  
  3164. ;-- and these menu choices use this accept statement
  3165. if ds.trig.choice.s = 1 or
  3166.    ds.trig.choice.s = 3 or
  3167.    ds.trig.choice.s = 13 then
  3168.    ;-- the prompt
  3169.    ?? "Enter the length of side b: "
  3170.    ;-- get the info
  3171.    accept "n"
  3172.    ;-- kind of small but where to draw the line?
  3173.    min .00000000001
  3174.    ;-- well, they could still press esc
  3175.    required
  3176.    to ds.side.b.n
  3177.    ;-- did they press esc?
  3178.    if not isassigned(ds.side.b.n) then
  3179.       return false
  3180.    endif
  3181.    @ 00,00
  3182. endif
  3183.  
  3184. ;-- and these menu choices use this accept statement
  3185. if ds.trig.choice.s = 2 or
  3186.    ds.trig.choice.s = 3 or
  3187.    ds.trig.choice.s = 13 then
  3188.    ;-- the prompt
  3189.    ?? "Enter the length of side c: "
  3190.    ;-- get the info
  3191.    accept "n"
  3192.    ;-- kind of small but where to draw the line?
  3193.    min .00000000001
  3194.    ;-- well, they could still press esc
  3195.    required
  3196.    to ds.side.c.n
  3197.    ;-- did they press esc?
  3198.    if not isassigned(ds.side.c.n) then
  3199.       return false
  3200.    endif
  3201. endif
  3202.  
  3203. ;-- some error trapping here
  3204. if ds.trig.choice.s <> 13  then
  3205.    ;-- side a was assigned so compare it to the other
  3206.    ;-- known value and do some error checking
  3207.    ;-- if the error check is tripped, inform the user what
  3208.    ;-- the error was
  3209.    if isassigned(ds.side.a.n) then
  3210.       switch
  3211.          case isassigned(ds.side.b.n) :
  3212.             if ds.side.b.n >= ds.side.a.n then
  3213.                ds.error.u(
  3214.                "The length of side b can not be greater than or" +
  3215.                " equal to side a!",
  3216.                ds.press.it.a)
  3217.                return false
  3218.             endif
  3219.          case isassigned(ds.side.c.n) :
  3220.             if ds.side.c.n >= ds.side.a.n then
  3221.                ds.error.u("The length of side c can not be greater" +
  3222.                " than or equal to side a!",
  3223.                ds.press.it.a)
  3224.                return false
  3225.             endif
  3226.       endswitch
  3227.    endif
  3228. else
  3229.    ;-- all three sides were entered, so check if the sides can
  3230.    ;-- intersect into a triangle
  3231.    if (round(ds.side.a.n,15) >= round((ds.side.b.n + ds.side.c.n),15)) or
  3232.       (round(ds.side.b.n,15) >= round((ds.side.a.n + ds.side.c.n),15)) or
  3233.       (round(ds.side.c.n,15) >= round((ds.side.a.n + ds.side.b.n),15)) then
  3234.       ds.error.u(
  3235.       "The length of any 1 side can not be greater" +
  3236.       " than or equal to the other 2 sides!",
  3237.       ds.press.it.a)
  3238.       return false
  3239.    endif
  3240. endif
  3241.  
  3242. ;-- passed the test
  3243. return true
  3244.  
  3245. endproc
  3246.  
  3247. ?? "." message memleft() writelib ds.aplib.a ds.trig.get.sides.l
  3248. release procs ds.trig.get.sides.l
  3249.  
  3250. ;-------------------------------------------------------------------------------
  3251. ;                                     ds.trig.get.angles.dms.l(ds.trig.choice.s)
  3252. ;-------------------------------------------------------------------------------
  3253. ; purpose: gets from the user the angles in degrees and/or minutes
  3254. ;          and/or seconds
  3255. proc ds.trig.get.angles.dms.l(
  3256. ds.trig.choice.s)                ;-- which choice, which angles to get
  3257.  
  3258. private
  3259. ds.side.a,             ;-- variable used in prompt of accept statement
  3260. ds.angle.a,            ;-- variable used in prompt of accept statement
  3261. ds.min.a,              ;-- variable used in prompt of accept statement
  3262. ds.sec.a,              ;-- variable used in prompt of accept statement
  3263. ds.side.value.n,       ;-- variable used in hold value of ds.side.(a,b or c).n
  3264. ds.degrees.value.s,    ;-- variable used in hold value of
  3265.                        ;-- ds.degrees.(a,b or c).s
  3266. ds.minutes.value.s,    ;-- variable used in hold value of
  3267.                        ;-- ds.minutes.(a,b or c).s
  3268. ds.seconds.value.s     ;-- variable used in hold value of
  3269.                        ;-- ds.seconds.(a,b or c).s
  3270.  
  3271.  
  3272. ;-- clear the top 2 lines
  3273. @ 01,00 clear eol
  3274. @ 00,00 clear eol
  3275.  
  3276. ;-- turn cursor on
  3277. cursor normal
  3278.  
  3279. ;-- evaluate what info to accept based on the menu choice
  3280. switch
  3281.  
  3282.    ;-- call the following routine for these menu choices
  3283.    case ds.trig.choice.s > 3 and
  3284.         ds.trig.choice.s < 10 :
  3285.       ds.trig.get.dms.1.l()
  3286.       ;-- based on the return value, continue or return
  3287.       if not retval then
  3288.          return false
  3289.       endif
  3290.  
  3291.    ;-- and call the following routine for these menu choices
  3292.    case ds.trig.choice.s = 10 :
  3293.         ds.trig.get.dms.2.l()
  3294.       ;-- based on the return value, continue or return
  3295.       if not retval then
  3296.          return false
  3297.       endif
  3298.  
  3299.    ;-- all other menu choices will be processed here
  3300.    otherwise :
  3301.  
  3302.       ;-- the prompt
  3303.       ?? "Enter the length of side a: "
  3304.       ;-- get a value
  3305.       accept "n"
  3306.       min .00000000001
  3307.       required
  3308.       to ds.side.a.n
  3309.       ;-- user pressed escape or left the value blank
  3310.       if not isassigned(ds.side.a.n) then
  3311.          return false
  3312.       endif
  3313.  
  3314.       ;-- move the cursor
  3315.       @ 00,00
  3316.       ;-- the next prompt
  3317.       ?? "Enter the length of side b: "
  3318.       ;-- get a value
  3319.       accept "n"
  3320.       min .00000000001
  3321.       required
  3322.       to ds.side.b.n
  3323.       ;-- reposition the cursor
  3324.       @ 00,00
  3325.  
  3326.       switch
  3327.          ;-- user left the previous entry blank or pressed escape
  3328.          case not isassigned(ds.side.b.n) :
  3329.             return false
  3330.          ;-- this menu choice, make these assignments to these variables
  3331.          case ds.trig.choice.s = 11 :
  3332.             ds.angle.a = "C"
  3333.             ds.min.a   = "C"
  3334.             ds.sec.a   = "C"
  3335.          ;-- all other menu choices, make these assignments to these variables
  3336.          otherwise :
  3337.             ds.angle.a = "A"
  3338.             ds.min.a   = "A"
  3339.             ds.sec.a   = "A"
  3340.       endswitch
  3341.  
  3342.       ;-- a prompt for degrees
  3343.       ?? "Enter the degrees of angle " + ds.angle.a + ": "
  3344.       ;-- get the info
  3345.       accept "s"
  3346.       min 0 max 179
  3347.       required
  3348.       to ds.degrees.value.s
  3349.       ;-- user escaped or left entry blank
  3350.       if not isassigned(ds.degrees.value.s) then
  3351.          return false
  3352.       endif
  3353.  
  3354.       ;-- user wants to enter minutes
  3355.       if ds.precision.choice.s > 1 then
  3356.          ;-- reposition the cursor
  3357.          @ 00,00
  3358.          ;-- next prompt
  3359.          ?? "Enter the minutes of angle " + ds.min.a + ": "
  3360.          ;-- get the value
  3361.          accept "s"
  3362.          min 0
  3363.          max 59
  3364.          required
  3365.          to ds.minutes.value.s
  3366.          ;-- was one really entered?
  3367.          if not isassigned(ds.minutes.value.s) then
  3368.             return false
  3369.          endif
  3370.       else
  3371.          ;-- make an assignment
  3372.          ds.minutes.value.s = 0
  3373.       endif
  3374.  
  3375.  
  3376.       ;-- user wants to enter seconds
  3377.       if ds.precision.choice.s = 3 then
  3378.          ;-- reposition the cursor
  3379.          @ 00,00
  3380.          ;-- next prompt
  3381.          ?? "Enter the seconds of angle " + ds.sec.a + ": "
  3382.          ;-- get the value
  3383.          accept "s"
  3384.          min 0
  3385.          max 59
  3386.          required
  3387.          to ds.seconds.value.s
  3388.          ;-- was one really entered?
  3389.          if not isassigned(ds.seconds.value.s) then
  3390.             return false
  3391.          endif
  3392.       else
  3393.          ;-- make an assignment
  3394.          ds.seconds.value.s = 0
  3395.       endif
  3396.  
  3397.       ;-- error checking on entered values
  3398.       switch
  3399.  
  3400.          ;-- user entered a bunch of zeros!
  3401.          case ds.degrees.value.s +
  3402.               ds.minutes.value.s +
  3403.               ds.seconds.value.s = 0 :
  3404.             ds.error.u(
  3405.             "NO ANGLE ENTERED FOR ANGLE " + ds.angle.a + "!",
  3406.             ds.press.it.a)
  3407.             return false
  3408.  
  3409.          ;-- make the assignments if this menu choice was selected
  3410.          case ds.trig.choice.s = 11 :
  3411.             ds.degrees.c.s = ds.degrees.value.s
  3412.             ds.minutes.c.s = ds.minutes.value.s
  3413.             ds.seconds.c.s = ds.seconds.value.s
  3414.  
  3415.          ;-- all other menu choices processed here
  3416.          otherwise:
  3417.             ds.degrees.a.s = ds.degrees.value.s
  3418.             ds.minutes.a.s = ds.minutes.value.s
  3419.             ds.seconds.a.s = ds.seconds.value.s
  3420.  
  3421.       endswitch
  3422.  
  3423. endswitch
  3424.  
  3425. ;-- good input, true means continue
  3426. return true
  3427.  
  3428. endproc
  3429.  
  3430. ?? "." message memleft() writelib ds.aplib.a ds.trig.get.angles.dms.l
  3431. release procs ds.trig.get.angles.dms.l
  3432.  
  3433. ;-------------------------------------------------------------------------------
  3434. ;                                                          ds.trig.get.dms.1.l()
  3435. ;-------------------------------------------------------------------------------
  3436. ; purpose: same as above accept this procedure was created to keep
  3437. ;          ds.trig.get.angles.dms.l's size down
  3438. proc ds.trig.get.dms.1.l()
  3439.  
  3440.  
  3441. ;-- make variable assignments per the selected menu choice
  3442. switch
  3443.    case ds.trig.choice.s = 4 :
  3444.       ds.side.a  = "a"
  3445.       ds.angle.a = "B"
  3446.       ds.min.a   = "B"
  3447.       ds.sec.a   = "B"
  3448.    case ds.trig.choice.s = 5 :
  3449.       ds.side.a  = "a"
  3450.       ds.angle.a = "C"
  3451.       ds.min.a   = "C"
  3452.       ds.sec.a   = "C"
  3453.    case ds.trig.choice.s = 6 :
  3454.       ds.side.a  = "b"
  3455.       ds.angle.a = "B"
  3456.       ds.min.a   = "B"
  3457.       ds.sec.a   = "B"
  3458.    case ds.trig.choice.s = 7 :
  3459.       ds.side.a  = "b"
  3460.       ds.angle.a = "C"
  3461.       ds.min.a   = "C"
  3462.       ds.sec.a   = "C"
  3463.    case ds.trig.choice.s = 8 :
  3464.       ds.side.a  = "c"
  3465.       ds.angle.a = "B"
  3466.       ds.min.a   = "B"
  3467.       ds.sec.a   = "B"
  3468.    case ds.trig.choice.s = 9 :
  3469.       ds.side.a  = "c"
  3470.       ds.angle.a = "C"
  3471.       ds.min.a   = "C"
  3472.       ds.sec.a   = "C"
  3473. endswitch
  3474.  
  3475. ?? "Enter the length of side " + ds.side.a + ": "
  3476. accept "n"
  3477. min .00000000001
  3478. required
  3479. to ds.side.value.n
  3480. if not isassigned(ds.side.value.n) then
  3481.    return false
  3482. endif
  3483.  
  3484. @ 00,00
  3485. ?? "Enter the degrees of angle " + ds.angle.a + ": "
  3486. accept "s"
  3487. min 0
  3488. max 89
  3489. required
  3490. to ds.degrees.value.s
  3491. if not isassigned(ds.degrees.value.s) then
  3492.    return false
  3493. endif
  3494.  
  3495.  
  3496. if ds.precision.choice.s > 1 then
  3497.    @ 00,00
  3498.    ?? "Enter the minutes of angle " + ds.min.a +": "
  3499.    accept "s"
  3500.    min 0
  3501.    max 59
  3502.    required
  3503.    to ds.minutes.value.s
  3504.    if not isassigned(ds.minutes.value.s) then
  3505.       return false
  3506.    endif
  3507. else
  3508.    ds.minutes.value.s = 0
  3509. endif
  3510.  
  3511. if ds.precision.choice.s = 3 then
  3512.    @ 00,00
  3513.    ?? "Enter the seconds of angle " + ds.sec.a + ": "
  3514.    accept "s"
  3515.    min 0
  3516.    max 59
  3517.    required
  3518.    to ds.seconds.value.s
  3519.    if not isassigned(ds.seconds.value.s) then
  3520.       return false
  3521.    endif
  3522. else
  3523.    ds.seconds.value.s = 0
  3524. endif
  3525.  
  3526.  
  3527. switch
  3528.    case ds.degrees.value.s + ds.minutes.value.s + ds.seconds.value.s = 0 :
  3529.       ds.error.u(
  3530.       "NO ANGLE ENTERED FOR ANGLE " + ds.angle.a + "!",
  3531.       ds.press.it.a)
  3532.       return false
  3533.    case ds.trig.choice.s = 4 :
  3534.       ds.side.a.n    = ds.side.value.n
  3535.       ds.degrees.b.s = ds.degrees.value.s
  3536.       ds.minutes.b.s = ds.minutes.value.s
  3537.       ds.seconds.b.s = ds.seconds.value.s
  3538.    case ds.trig.choice.s = 5 :
  3539.       ds.side.a.n    = ds.side.value.n
  3540.       ds.degrees.c.s = ds.degrees.value.s
  3541.       ds.minutes.c.s = ds.minutes.value.s
  3542.       ds.seconds.c.s = ds.seconds.value.s
  3543.    case ds.trig.choice.s = 6 :
  3544.       ds.side.b.n    = ds.side.value.n
  3545.       ds.degrees.b.s = ds.degrees.value.s
  3546.       ds.minutes.b.s = ds.minutes.value.s
  3547.       ds.seconds.b.s = ds.seconds.value.s
  3548.    case ds.trig.choice.s = 7 :
  3549.       ds.side.b.n    = ds.side.value.n
  3550.       ds.degrees.c.s = ds.degrees.value.s
  3551.       ds.minutes.c.s = ds.minutes.value.s
  3552.       ds.seconds.c.s = ds.seconds.value.s
  3553.    case ds.trig.choice.s = 8 :
  3554.       ds.side.c.n = ds.side.value.n
  3555.       ds.degrees.b.s = ds.degrees.value.s
  3556.       ds.minutes.b.s = ds.minutes.value.s
  3557.       ds.seconds.b.s = ds.seconds.value.s
  3558.    case ds.trig.choice.s = 9 :
  3559.       ds.side.c.n = ds.side.value.n
  3560.       ds.degrees.c.s = ds.degrees.value.s
  3561.       ds.minutes.c.s = ds.minutes.value.s
  3562.       ds.seconds.c.s = ds.seconds.value.s
  3563. endswitch
  3564.  
  3565. return true
  3566.  
  3567. endproc
  3568.  
  3569. ?? "." message memleft() writelib ds.aplib.a ds.trig.get.dms.1.l
  3570. release procs ds.trig.get.dms.1.l
  3571.  
  3572. ;-------------------------------------------------------------------------------
  3573. ;                                                          ds.trig.get.dms.2.l()
  3574. ;-------------------------------------------------------------------------------
  3575. ; purpose: same as above accept this procedure was created to keep
  3576. ;          ds.trig.get.angles.dms.l's size down
  3577.  
  3578. proc ds.trig.get.dms.2.l()
  3579.  
  3580.  
  3581. ?? "Enter the length of side a: "
  3582. accept "n"
  3583. min .00000000001
  3584. required
  3585. to ds.side.a.n
  3586. if not isassigned(ds.side.a.n) then
  3587.    return false
  3588. endif
  3589.  
  3590. @ 00,00
  3591. ?? "Enter the degrees of angle A: "
  3592. accept "s"
  3593. min 0
  3594. max 179
  3595. required
  3596. to ds.degrees.a.s
  3597. if not isassigned(ds.degrees.a.s) then
  3598.    return false
  3599. endif
  3600.  
  3601.  
  3602. if ds.precision.choice.s > 1 then
  3603.    @ 00,00
  3604.    ?? "Enter the minutes of angle A: "
  3605.    accept "s"
  3606.    min 0
  3607.    max 59
  3608.    required
  3609.    to ds.minutes.a.s
  3610.    if not isassigned(ds.minutes.a.s) then
  3611.       return false
  3612.    endif
  3613. else
  3614.    ds.minutes.a.s = 0
  3615. endif
  3616.  
  3617.  
  3618. if ds.precision.choice.s = 3 then
  3619.    @ 00,00
  3620.    ?? "Enter the seconds of angle A: "
  3621.    accept "s"
  3622.    min 0
  3623.    max 59
  3624.    required
  3625.    to ds.seconds.a.s
  3626.    if not isassigned(ds.seconds.a.s) then
  3627.       return false
  3628.    endif
  3629. else
  3630.    ds.seconds.a.s = 0
  3631. endif
  3632.  
  3633. @ 00,00
  3634. if ds.degrees.a.s + ds.minutes.a.s + ds.seconds.a.s = 0 then
  3635.    ds.error.u(
  3636.    "NO ANGLE ENTERED FOR ANGLE A!",
  3637.    ds.press.it.a)
  3638.    return false
  3639. endif
  3640.  
  3641. ?? "Enter the degrees of angle B: "
  3642. accept "s"
  3643. min 0
  3644. max 179
  3645. required
  3646. to ds.degrees.b.s
  3647. if not isassigned(ds.degrees.b.s) then
  3648.    return false
  3649. endif
  3650.  
  3651.  
  3652. if ds.precision.choice.s > 1 then
  3653.    @ 00,00
  3654.    ?? "Enter the minutes of angle B: "
  3655.    accept "s"
  3656.    min 0
  3657.    max 59
  3658.    required
  3659.    to ds.minutes.b.s
  3660.    if not isassigned(ds.minutes.b.s) then
  3661.       return false
  3662.    endif
  3663. else
  3664.    ds.minutes.b.s = 0
  3665. endif
  3666.  
  3667. if ds.precision.choice.s = 3 then
  3668.    @ 00,00
  3669.    ?? "Enter the seconds of Angle B: "
  3670.    accept "s"
  3671.    min 0
  3672.    max 59
  3673.    required
  3674.    to ds.seconds.b.s
  3675.    if not isassigned(ds.seconds.b.s) then
  3676.       return false
  3677.    endif
  3678. else
  3679.    ds.seconds.b.s = 0
  3680. endif
  3681.  
  3682. if ds.degrees.b.s + ds.minutes.b.s + ds.seconds.b.s = 0 then
  3683.    ds.error.u(
  3684.    "NO ANGLE ENTERED FOR ANGLE B!",
  3685.    ds.press.it.a)
  3686.    return false
  3687. endif
  3688.  
  3689. return true
  3690.  
  3691. endproc
  3692.  
  3693. ?? "." message memleft() writelib ds.aplib.a ds.trig.get.dms.2.l
  3694. release procs ds.trig.get.dms.2.l
  3695.  
  3696.  
  3697. ;-------------------------------------------------------------------------------
  3698. ;                                 ds.trig.get.angles.radians.l(ds.trig.choice.s)
  3699. ;-------------------------------------------------------------------------------
  3700. ; purpose: same as ds.trig.get.angles.dms.u except this procedure gets the
  3701. ;          values of the angles in radians
  3702. proc ds.trig.get.angles.radians.l(
  3703. ds.trig.choice.s)                     ;-- the selected menu choice
  3704.  
  3705. private
  3706. ds.side.a,
  3707. ds.radian.a,
  3708. ds.side.value.n,
  3709. ds.radian.value.n
  3710.  
  3711. @ 01,00 clear eol
  3712. @ 00,00 clear eol
  3713.  
  3714. cursor normal
  3715.  
  3716. switch
  3717.  
  3718.    case ds.trig.choice.s > 3 and
  3719.         ds.trig.choice.s < 10 :
  3720.       ds.trig.get.radians.1.l()
  3721.       if not retval then
  3722.          return false
  3723.       endif
  3724.  
  3725.    case ds.trig.choice.s = 10 :
  3726.       ds.trig.get.radians.2.l()
  3727.       if not retval then
  3728.          return false
  3729.       endif
  3730.  
  3731.    otherwise :
  3732.  
  3733.       ?? "Enter the length of side a: "
  3734.       accept "n"
  3735.       min .00000000001
  3736.       required
  3737.       to ds.side.a.n
  3738.       if not isassigned(ds.side.a.n) then
  3739.          return false
  3740.       endif
  3741.  
  3742.       @ 00,00
  3743.       ?? "Enter the length of side b: "
  3744.       accept "n"
  3745.       min .00000000001
  3746.       required
  3747.       to ds.side.b.n
  3748.       @ 00,00
  3749.  
  3750.       switch
  3751.          case not isassigned(ds.side.b.n) :
  3752.             return false
  3753.          case ds.trig.choice.s = 11 :
  3754.             ds.radian.a = "C"
  3755.          otherwise :
  3756.             ds.radian.a = "A"
  3757.       endswitch
  3758.  
  3759.       ?? "Enter the radians of angle " + ds.radian.a + ": "
  3760.       accept "n"
  3761.       min .0000048481368
  3762.       max 3.141587805452
  3763.       required
  3764.       to ds.radian.value.n
  3765.  
  3766.       switch
  3767.  
  3768.          case not isassigned(ds.radian.value.n) :
  3769.             return false
  3770.  
  3771.          case ds.trig.choice.s = 11 :
  3772.             ds.radians.c.s = ds.radian.value.n
  3773.  
  3774.          otherwise :
  3775.             ds.radians.a.s = ds.radian.value.n
  3776.  
  3777.       endswitch
  3778.  
  3779. endswitch
  3780.  
  3781. return true
  3782.  
  3783. endproc
  3784.  
  3785. ?? "." message memleft() writelib ds.aplib.a ds.trig.get.angles.radians.l
  3786. release procs ds.trig.get.angles.radians.l
  3787.  
  3788. ;-------------------------------------------------------------------------------
  3789. ;                                                      ds.trig.get.radians.1.l()
  3790. ;-------------------------------------------------------------------------------
  3791. ; purpose: same as above ds.trig.get.angles.radians.l except used
  3792. ;          to keep procedure size down
  3793. proc ds.trig.get.radians.1.l()
  3794.  
  3795. switch
  3796.    case ds.trig.choice.s = 4 :
  3797.       ds.side.a   = "a"
  3798.       ds.radian.a = "B"
  3799.    case ds.trig.choice.s = 5 :
  3800.       ds.side.a   = "a"
  3801.       ds.radian.a = "C"
  3802.    case ds.trig.choice.s = 6 :
  3803.       ds.side.a   = "b"
  3804.       ds.radian.a = "B"
  3805.    case ds.trig.choice.s = 7 :
  3806.       ds.side.a   = "b"
  3807.       ds.radian.a = "C"
  3808.    case ds.trig.choice.s = 8 :
  3809.       ds.side.a   = "c"
  3810.       ds.radian.a = "B"
  3811.    case ds.trig.choice.s = 9 :
  3812.       ds.side.a   = "c"
  3813.       ds.radian.a = "C"
  3814. endswitch
  3815.  
  3816. ?? "Enter the length of side " + ds.side.a + ": "
  3817. accept "n"
  3818. min .00000000001
  3819. required
  3820. to ds.side.value.n
  3821. if not isassigned(ds.side.value.n) then
  3822.    return false
  3823. endif
  3824.  
  3825. @ 00,00
  3826. ?? "Enter the radians of angle " + ds.radian.a + ": "
  3827. accept "n"
  3828. min .0000048481368
  3829. max 1.570791478658
  3830. required
  3831. to ds.radian.value.n
  3832.  
  3833. switch
  3834.    case not isassigned(ds.radian.value.n) :
  3835.       return false
  3836.    case ds.trig.choice.s = 4 :
  3837.       ds.side.a.n    = ds.side.value.n
  3838.       ds.radians.b.s = ds.radian.value.n
  3839.    case ds.trig.choice.s = 5 :
  3840.       ds.side.a.n    = ds.side.value.n
  3841.       ds.radians.c.s = ds.radian.value.n
  3842.    case ds.trig.choice.s = 6 :
  3843.       ds.side.b.n    = ds.side.value.n
  3844.       ds.radians.b.s = ds.radian.value.n
  3845.    case ds.trig.choice.s = 7 :
  3846.       ds.side.b.n    = ds.side.value.n
  3847.       ds.radians.c.s = ds.radian.value.n
  3848.    case ds.trig.choice.s = 8 :
  3849.       ds.side.c.n    = ds.side.value.n
  3850.       ds.radians.b.s = ds.radian.value.n
  3851.    case ds.trig.choice.s = 9 :
  3852.       ds.side.c.n    = ds.side.value.n
  3853.       ds.radians.c.s = ds.radian.value.n
  3854. endswitch
  3855.  
  3856. return true
  3857.  
  3858. endproc
  3859.  
  3860. ?? "." message memleft() writelib ds.aplib.a ds.trig.get.radians.1.l
  3861. release procs ds.trig.get.radians.1.l
  3862.  
  3863. ;-------------------------------------------------------------------------------
  3864. ;                                                      ds.trig.get.radians.2.l()
  3865. ;-------------------------------------------------------------------------------
  3866. ; purpose: same as above ds.trig.get.angles.radians.l except used
  3867. ;          to keep procedure size down
  3868. proc ds.trig.get.radians.2.l()
  3869.  
  3870. ?? "Enter the length of side a: "
  3871. accept "n"
  3872. min .00000000001
  3873. required
  3874. to ds.side.a.n
  3875. if not isassigned(ds.side.a.n) then
  3876.    return false
  3877. endif
  3878.  
  3879. @ 00,00
  3880. ?? "Enter the radians of angle A: "
  3881. accept "n"
  3882. min .0000048481368
  3883. max 3.141587805452
  3884. required
  3885. to ds.radians.a.s
  3886. if not isassigned(ds.radians.a.s) then
  3887.    return false
  3888. endif
  3889.  
  3890. @ 00,00
  3891. ?? "Enter the radians of angle B: "
  3892. accept "n" min .0000048481368 max 3.141587805452 required to ds.radians.b.s
  3893. if not isassigned(ds.radians.b.s) then
  3894.    return false
  3895. endif
  3896.  
  3897. return true
  3898.  
  3899. endproc
  3900.  
  3901. ?? "." message memleft() writelib ds.aplib.a ds.trig.get.radians.2.l
  3902. release procs ds.trig.get.radians.2.l
  3903.  
  3904. ;-------------------------------------------------------------------------------
  3905. ;                                                         ds.convert.degrees.u()
  3906. ;-------------------------------------------------------------------------------
  3907. ; purpose: converts angles in degrees, minutes and seconds to radians
  3908. proc ds.convert.degrees.u()
  3909.  
  3910. if ds.trig.choice.s < 10 then
  3911.    ds.radians.a.s = 1.570796326794
  3912.    ds.degrees.a.s = 90
  3913.    ds.minutes.a.s = 0
  3914.    ds.seconds.a.s = 0
  3915. endif
  3916.  
  3917. if isassigned(ds.degrees.a.s) and
  3918.    ds.trig.choice.s > 9 then
  3919.    ds.radians.a.s = round(ds.degrees.a.s * .0174532925199,15)
  3920.    if isassigned(ds.minutes.a.s) then
  3921.       ds.radians.a.s =
  3922.       round(ds.radians.a.s + ds.minutes.a.s * .0002908882086,15)
  3923.    endif
  3924.    if isassigned(ds.seconds.a.s) then
  3925.       ds.radians.a.s =
  3926.       round(ds.radians.a.s + ds.seconds.a.s * .0000048481368,15)
  3927.    endif
  3928. endif
  3929.  
  3930. if isassigned(ds.degrees.b.s) then
  3931.    ds.radians.b.s = round(ds.degrees.b.s * .0174532925199,15)
  3932.    if isassigned(ds.minutes.b.s) then
  3933.       ds.radians.b.s =
  3934.       round(ds.radians.b.s + ds.minutes.b.s * .0002908882086,15)
  3935.    endif
  3936.    if isassigned(ds.seconds.b.s) then
  3937.       ds.radians.b.s =
  3938.       round(ds.radians.b.s + ds.seconds.b.s * .0000048481368,15)
  3939.    endif
  3940. endif
  3941.  
  3942. if isassigned(ds.degrees.c.s) then
  3943.    ds.radians.c.s = round(ds.degrees.c.s * .0174532925199,15)
  3944.    if isassigned(ds.minutes.c.s) then
  3945.       ds.radians.c.s =
  3946.       round(ds.radians.c.s + ds.minutes.c.s * .0002908882086,15)
  3947.    endif
  3948.    if isassigned(ds.seconds.c.s) then
  3949.       ds.radians.c.s =
  3950.       round(ds.radians.c.s + ds.seconds.c.s * .0000048481368,15)
  3951.    endif
  3952. endif
  3953.  
  3954.  
  3955. endproc
  3956.  
  3957. ?? "." message memleft() writelib ds.aplib.a ds.convert.degrees.u
  3958. release procs ds.convert.degrees.u
  3959.  
  3960. ;-------------------------------------------------------------------------------
  3961. ;                                                     ds.compute.third.angle.u()
  3962. ;-------------------------------------------------------------------------------
  3963. ; purpose: computes the third angle when the other 2 are known
  3964. proc ds.compute.third.angle.u()
  3965.  
  3966. if ds.trig.choice.s < 10 then
  3967.    ds.radians.a.s = 1.570796326794
  3968.    ds.degrees.a.s = 90
  3969.    ds.minutes.a.s = 0
  3970.    ds.seconds.a.s = 0
  3971. endif
  3972.  
  3973. switch
  3974.    case isassigned(ds.radians.a.s) and
  3975.         isassigned(ds.radians.b.s) :
  3976.       ds.radians.c.s =
  3977.       round(3.141592653589 - ds.radians.a.s - ds.radians.b.s,15)
  3978.    case isassigned(ds.radians.a.s) and
  3979.         isassigned(ds.radians.c.s) :
  3980.       ds.radians.b.s =
  3981.       round(3.141592653589 - ds.radians.a.s - ds.radians.c.s,15)
  3982.    case isassigned(ds.radians.b.s) and
  3983.         isassigned(ds.radians.c.s) :
  3984.       ds.radians.a.s =
  3985.       round(3.141592653589 - ds.radians.b.s - ds.radians.c.s,15)
  3986. endswitch
  3987.  
  3988.  
  3989. endproc
  3990.  
  3991. ?? "." message memleft() writelib ds.aplib.a ds.compute.third.angle.u
  3992. release procs ds.compute.third.angle.u
  3993.  
  3994. ;-------------------------------------------------------------------------------
  3995. ;                                                         ds.trig.calc.set.1.u()
  3996. ;-------------------------------------------------------------------------------
  3997. ; purpose: calculates trig answers - set 1 of 6
  3998. proc ds.trig.calc.set.1.u()
  3999.  
  4000. switch
  4001.    case isassigned(ds.side.a.n) and isassigned(ds.side.b.n) :
  4002.       ds.side.c.n =
  4003.       round(sqrt(round(((ds.side.a.n*ds.side.a.n)-
  4004.            (ds.side.b.n*ds.side.b.n)),15)),15)
  4005.    case isassigned(ds.side.a.n) and isassigned(ds.side.c.n) :
  4006.       ds.side.b.n =
  4007.       round(sqrt(round(((ds.side.a.n*ds.side.a.n)-
  4008.            (ds.side.c.n*ds.side.c.n)),15)),15)
  4009.    case isassigned(ds.side.b.n) and isassigned(ds.side.c.n) :
  4010.       ds.side.a.n =
  4011.       round(sqrt(round(((ds.side.b.n*ds.side.b.n)+
  4012.            (ds.side.c.n*ds.side.c.n)),15)),15)
  4013. endswitch
  4014.  
  4015. ds.radians.b.s = round(asin(round(ds.side.b.n/ds.side.a.n,15)),15)
  4016. ds.radians.c.s = round(asin(round(ds.side.c.n/ds.side.a.n,15)),15)
  4017.  
  4018. ds.radians.a.s = 1.570796326794
  4019. ds.degrees.a.s = 90
  4020. ds.minutes.a.s = 0
  4021. ds.seconds.a.s = 0
  4022.  
  4023. ds.area.n = round(ds.side.b.n * ds.side.c.n / 2 ,15)
  4024.  
  4025. endproc
  4026.  
  4027. ?? "." message memleft() writelib ds.aplib.a ds.trig.calc.set.1.u
  4028. release procs ds.trig.calc.set.1.u
  4029.  
  4030. ;-------------------------------------------------------------------------------
  4031. ;                                                         ds.trig.calc.set.2.u()
  4032. ;-------------------------------------------------------------------------------
  4033. ; purpose: calculates trig answers - set 2 of 6
  4034. proc ds.trig.calc.set.2.u()
  4035.  
  4036. switch
  4037.    case isassigned(ds.side.a.n) :
  4038.       ds.side.b.n = round(ds.side.a.n * sin(ds.radians.b.s),15)
  4039.       ds.side.c.n = round(ds.side.a.n * cos(ds.radians.b.s),15)
  4040.   case isassigned(ds.side.b.n) :
  4041.       ds.side.a.n = round(ds.side.b.n / sin(ds.radians.b.s),15)
  4042.       ds.side.c.n = round(ds.side.b.n * tan(ds.radians.c.s),15)
  4043.   case isassigned(ds.side.c.n) :
  4044.       ds.side.a.n = round(ds.side.c.n / cos(ds.radians.b.s),15)
  4045.       ds.side.b.n = round(ds.side.c.n * tan(ds.radians.b.s),15)
  4046. endswitch
  4047.  
  4048. ds.area.n = round(ds.side.b.n * ds.side.c.n / 2,15)
  4049.  
  4050. ds.radians.a.s = 1.570796326794
  4051. ds.degrees.a.s = 90
  4052. ds.minutes.a.s = 0
  4053. ds.seconds.a.s = 0
  4054.  
  4055. endproc
  4056.  
  4057. ?? "." message memleft() writelib ds.aplib.a ds.trig.calc.set.2.u
  4058. release procs ds.trig.calc.set.2.u
  4059.  
  4060. ;-------------------------------------------------------------------------------
  4061. ;                                                         ds.trig.calc.set.3.u()
  4062. ;-------------------------------------------------------------------------------
  4063. ; purpose: calculates trig answers - set 3 of 6
  4064. proc ds.trig.calc.set.3.u()
  4065.  
  4066. switch
  4067.    case isassigned(ds.side.a.n) :
  4068.       ds.side.b.n =
  4069.       round(ds.side.a.n * sin(ds.radians.b.s) / sin(ds.radians.a.s),15)
  4070.       ds.side.c.n =
  4071.       round(ds.side.a.n * sin(ds.radians.c.s) / sin(ds.radians.a.s),15)
  4072.    case isassigned(ds.side.b.n) :
  4073.       ds.side.a.n =
  4074.       round(ds.side.b.n * sin(ds.radians.c.s) / sin(ds.radians.b.s),15)
  4075.       ds.side.c.n =
  4076.       round(ds.side.b.n * sin(ds.radians.a.s) / sin(ds.radians.b.s),15)
  4077.    case isassigned(ds.side.c.n) :
  4078.       ds.side.a.n =
  4079.       round(ds.side.c.n * sin(ds.radians.a.s) / sin(ds.radians.c.s),15)
  4080.       ds.side.b.n =
  4081.       round(ds.side.c.n * sin(ds.radians.b.s) / sin(ds.radians.c.s),15)
  4082. endswitch
  4083.  
  4084. ds.area.n = round(ds.side.a.n * ds.side.b.n * sin(ds.radians.c.s) / 2,15)
  4085.  
  4086. endproc
  4087.  
  4088. ?? "." message memleft() writelib ds.aplib.a ds.trig.calc.set.3.u
  4089. release procs ds.trig.calc.set.3.u
  4090.  
  4091.  
  4092. ;-------------------------------------------------------------------------------
  4093. ;                                                         ds.trig.calc.set.4.u()
  4094. ;-------------------------------------------------------------------------------
  4095. ; purpose: calculates trig answers - set 4 of 6
  4096. proc ds.trig.calc.set.4.u()
  4097.  
  4098. ds.radians.a.s =
  4099. round(atan(((ds.side.a.n*sin(ds.radians.c.s))/
  4100.      (ds.side.b.n-(ds.side.a.n*cos(ds.radians.c.s))))),15)
  4101.  
  4102. ds.side.c.n =
  4103. round(ds.side.a.n*sin(ds.radians.c.s)/sin(ds.radians.a.s),15)
  4104.  
  4105. ds.radians.b.s =
  4106. round(atan(((ds.side.b.n*sin(ds.radians.a.s))/
  4107.      (ds.side.c.n-(ds.side.b.n*cos(ds.radians.a.s))))),15)
  4108.  
  4109. ds.area.n =
  4110. round(ds.side.a.n * ds.side.b.n * sin(ds.radians.c.s) / 2,15)
  4111.  
  4112. endproc
  4113.  
  4114. ?? "." message memleft() writelib ds.aplib.a ds.trig.calc.set.4.u
  4115. release procs ds.trig.calc.set.4.u
  4116.  
  4117. ;-------------------------------------------------------------------------------
  4118. ;                                                         ds.trig.calc.set.5.u()
  4119. ;-------------------------------------------------------------------------------
  4120. ; purpose: calculates trig answers - set 5 of 6
  4121. proc ds.trig.calc.set.5.u()
  4122.  
  4123. ds.radians.b.s =
  4124. round(asin((ds.side.b.n * sin(ds.radians.a.s) / ds.side.a.n)),15)
  4125.  
  4126. ds.radians.c.s =
  4127. round(3.141592653589 - (ds.radians.a.s + ds.radians.b.s),15)
  4128.  
  4129. ds.side.c.n =
  4130. round(ds.side.a.n * sin(ds.radians.c.s) / sin(ds.radians.a.s),15)
  4131.  
  4132. ds.area.n =
  4133. round(ds.side.a.n * ds.side.b.n * sin(ds.radians.c.s) / 2,15)
  4134.  
  4135. endproc
  4136.  
  4137. ?? "." message memleft() writelib ds.aplib.a ds.trig.calc.set.5.u
  4138. release procs ds.trig.calc.set.5.u
  4139.  
  4140. ;-------------------------------------------------------------------------------
  4141. ;                                                         ds.trig.calc.set.6.u()
  4142. ;-------------------------------------------------------------------------------
  4143. ; purpose: calculates trig answers - set 6 of 6
  4144.  
  4145. proc ds.trig.calc.set.6.u()
  4146.  
  4147. ds.radians.a.s =
  4148. round(acos(((ds.side.b.n*ds.side.b.n+ds.side.c.n*
  4149.       ds.side.c.n-ds.side.a.n*ds.side.a.n)/(2*ds.side.b.n*ds.side.c.n))),15)
  4150.  
  4151. ds.radians.b.s =
  4152. round(acos(((ds.side.a.n*ds.side.a.n+ds.side.c.n*
  4153.       ds.side.c.n-ds.side.b.n*ds.side.b.n)/(2*ds.side.a.n*ds.side.c.n))),15)
  4154.  
  4155. ds.radians.c.s =
  4156. round(acos(((ds.side.a.n*ds.side.a.n+ds.side.b.n*
  4157.       ds.side.b.n-ds.side.c.n*ds.side.c.n)/(2*ds.side.a.n*ds.side.b.n))),15)
  4158.  
  4159. ds.area.n =
  4160. round(ds.side.a.n * ds.side.b.n * sin(ds.radians.c.s) / 2,15)
  4161.  
  4162. endproc
  4163.  
  4164. ?? "." message memleft() writelib ds.aplib.a ds.trig.calc.set.6.u
  4165. release procs ds.trig.calc.set.6.u
  4166.  
  4167.  
  4168. ;-------------------------------------------------------------------------------
  4169. ;                                                    ds.trig.convert.radians.u()
  4170. ;-------------------------------------------------------------------------------
  4171. ; purpose: converts known radians to degrees, minutes and seconds
  4172. proc ds.trig.convert.radians.u()
  4173.  
  4174. private
  4175. ds.remainder.n  ;-- used to handle the remainder after extracting the
  4176.                 ;-- degrees and minutes from the radians
  4177.  
  4178. if ds.trig.choice.s >9 then
  4179.    ds.degrees.a.s = int(ds.radians.a.s / .0174532925199)
  4180.    ds.remainder.n = round(ds.radians.a.s - ds.degrees.a.s * .0174532925199,15)
  4181.    ds.minutes.a.s = int(ds.remainder.n / .0002908882086)
  4182.    ds.remainder.n = round(ds.remainder.n - ds.minutes.a.s * .0002908882086,15)
  4183.    ds.seconds.a.s = int(round((ds.remainder.n / .0000048481368),0))
  4184. endif
  4185.  
  4186. ds.degrees.b.s = int(ds.radians.b.s / .0174532925199)
  4187.  
  4188. ds.remainder.n = round(ds.radians.b.s - ds.degrees.b.s * .0174532925199,15)
  4189.  
  4190. ds.minutes.b.s = int(ds.remainder.n / .0002908882086)
  4191.  
  4192. ds.remainder.n = round(ds.remainder.n - ds.minutes.b.s * .0002908882086,15)
  4193.  
  4194. ds.seconds.b.s = int(round((ds.remainder.n / .0000048481368),0))
  4195.  
  4196. ds.degrees.c.s = int(ds.radians.c.s / .0174532925199)
  4197.  
  4198. ds.remainder.n = round(ds.radians.c.s - ds.degrees.c.s * .0174532925199,15)
  4199.  
  4200. ds.minutes.c.s = int(ds.remainder.n / .0002908882086)
  4201.  
  4202. ds.remainder.n = round(ds.remainder.n - ds.minutes.c.s * .0002908882086,15)
  4203.  
  4204. ds.seconds.c.s = int(round((ds.remainder.n / .0000048481368),0))
  4205.  
  4206. endproc
  4207.  
  4208. ?? "." message memleft() writelib ds.aplib.a ds.trig.convert.radians.u
  4209. release procs ds.trig.convert.radians.u
  4210.  
  4211. ;-------------------------------------------------------------------------------
  4212. ;                                                     ds.trig.display.answer.u()
  4213. ;-------------------------------------------------------------------------------
  4214. ; purpose: formats and displays the answers to the trig problem presented
  4215. proc ds.trig.display.answer.u()
  4216.  
  4217. private
  4218. ds.line.1.a,
  4219. ds.line.2.a,
  4220. ds.line.3.a,
  4221. ds.line.4.a,
  4222. ds.line.5.a,
  4223. ds.line.6.a,
  4224. ds.line.7.a,
  4225. ds.line.8.a,
  4226. ds.line.9.a,
  4227. ds.line.10.a,
  4228. ds.line.11.a
  4229.  
  4230. ds.line.1.a  = format("w4,ar",ds.degrees.c.s) +
  4231.                "° " +
  4232.                format("w3,ar",ds.minutes.c.s) +
  4233.                "' " +
  4234.                format("w3,ar",ds.seconds.c.s) + "\""
  4235.  
  4236. ds.line.2.a  = format("w15.15,al",ds.radians.c.s)
  4237.  
  4238. ds.line.3.a  = format("w15.15,al",ds.side.a.n)
  4239.  
  4240. ds.line.4.a  = format("w15.15,al",ds.side.b.n)
  4241.  
  4242. ds.line.5.a  = format("w4,ar",ds.degrees.a.s) +
  4243.                "° " +
  4244.                format("w3,ar",ds.minutes.a.s) +
  4245.                "' " +
  4246.                format("w3,ar",ds.seconds.a.s) + "\""
  4247.  
  4248. ds.line.6.a  = format("w15.15,al",ds.radians.a.s)
  4249.  
  4250. ds.line.7.a  = format("w4,ar",ds.degrees.b.s) +
  4251.                "° " + format("w3,ar",ds.minutes.b.s) +
  4252.                "' " +
  4253.                format("w3,ar",ds.seconds.b.s) + "\""
  4254.  
  4255. ds.line.8.a  = format("w15.15,al",ds.radians.b.s)
  4256.  
  4257. ds.line.9.a  = format("w15.15,al",ds.side.c.n)
  4258.  
  4259. ds.line.10.a = format("w15.15,al",ds.periphery.n)
  4260.  
  4261. ds.line.11.a = format("w15.15,al",ds.area.n)
  4262.  
  4263. style reverse
  4264. @ 04,16 ?? ds.line.1.a
  4265. @ 05,16 ?? ds.line.2.a
  4266. @ 11,17 ?? ds.line.3.a
  4267. @ 15,05 ?? ds.line.4.a
  4268. @ 19,15 ?? ds.line.5.a
  4269. @ 20,15 ?? ds.line.6.a
  4270. @ 20,46 ?? ds.line.7.a
  4271. @ 21,46 ?? ds.line.8.a
  4272. @ 23,05 ?? ds.line.9.a
  4273. @ 22,58 ?? ds.line.10.a
  4274. @ 23,58 ?? ds.line.11.a
  4275. style
  4276.  
  4277. endproc
  4278.  
  4279. ?? "." message memleft() writelib ds.aplib.a ds.trig.display.answer.u
  4280. release procs ds.trig.display.answer.u
  4281.  
  4282.  
  4283.  
  4284. ;-------------------------------------------------------------------------------
  4285. ;                                                            ds.review.print.u()
  4286. ;-------------------------------------------------------------------------------
  4287. ; purpose: displays the appropriate menu choice depending on the parameter
  4288. ;          passed in the call to ds.calc.v that turns the printing option
  4289. ;          on or leaves it off
  4290. proc ds.review.print.u()
  4291.  
  4292. private
  4293. ds.menu.choice.a       ;-- selected menu choice
  4294.  
  4295. ds.rebuild.l = false   ;-- initialize the variable
  4296.  
  4297.  
  4298. ;-- display the proper menu for the current state of the
  4299. ;-- tape display window and whether printing is turned
  4300. ;-- on or off
  4301. ;-- there is no review required if all of the tape entries
  4302. ;-- can be seen on the screen currently
  4303. switch
  4304.  
  4305.    ;-- less than 20 entries and no printing
  4306.    case ds.tape.count.s < 20 and
  4307.         (not isassigned(ds.print.tape.a) or
  4308.         lower(ds.print.tape.a) <> "on") :
  4309.       ds.error.u(
  4310.       "Sorry, the print function is not enabled at this time.",
  4311.       ds.press.it.a)
  4312.       ds.main.prompt.u()
  4313.       return
  4314.  
  4315.  
  4316.    ;-- less than 20 entries and printing enabled
  4317.    case ds.tape.count.s < 20 and
  4318.         isassigned(ds.print.tape.a) and
  4319.         lower(ds.print.tape.a) = "on" :
  4320.  
  4321.       showmenu
  4322.          "Print " : " Print the tape.",
  4323.          "Esc "   : " Cancel printing and return to the calculator."
  4324.       to ds.menu.choice.a
  4325.  
  4326.       canvas off
  4327.       message ""
  4328.       @ 22,78 clear eol
  4329.       canvas on
  4330.  
  4331.       if ds.menu.choice.a = "Print " then
  4332.          ds.print.tape.u()
  4333.       else
  4334.          return
  4335.       endif
  4336.  
  4337.    ;-- greater than 19 entries and no printing
  4338.    case ds.tape.count.s > 19 and
  4339.         not isassigned(ds.print.tape.a) or
  4340.         lower(ds.print.tape.a) <> "on" :
  4341.  
  4342.       showmenu
  4343.          "Review " : " Review the tape.",
  4344.          "Esc "    : " Return to the calculator."
  4345.       to ds.menu.choice.a
  4346.  
  4347.       canvas off
  4348.       message ""
  4349.       @ 22,78 clear eol
  4350.       canvas on
  4351.       if ds.menu.choice.a = "Review " then
  4352.          ds.review.tape.u()
  4353.          ds.rebuild.l = true
  4354.       else
  4355.          return
  4356.       endif
  4357.  
  4358.    ;-- greater than 19 entries and printing enabled
  4359.    otherwise:
  4360.  
  4361.       showmenu
  4362.          "Review " : " Review the tape.",
  4363.          "Print "  : " Print the tape.",
  4364.          "Esc "    : " Return to the calculator."
  4365.       to ds.menu.choice.a
  4366.  
  4367.       canvas off
  4368.       message ""
  4369.       @ 22,78 clear eol
  4370.       canvas on
  4371.  
  4372.       switch
  4373.          case ds.menu.choice.a = "Review " :
  4374.             ds.review.tape.u()
  4375.             ds.rebuild.l = true
  4376.  
  4377.          case ds.menu.choice.a = "Print " :
  4378.             ds.print.tape.u()
  4379.  
  4380.          otherwise :
  4381.             return
  4382.       endswitch
  4383. endswitch
  4384.  
  4385.  
  4386. endproc
  4387.  
  4388. ?? "." message memleft() writelib ds.aplib.a ds.review.print.u
  4389. release procs ds.review.print.u
  4390.  
  4391.  
  4392. ;-------------------------------------------------------------------------------
  4393. ;                                                             ds.review.tape.u()
  4394. ;-------------------------------------------------------------------------------
  4395. ; purpose: re-runs the tape through the tape window pausing on each screen
  4396. ;          until a key is pressed
  4397. proc ds.review.tape.u()
  4398.  
  4399. Private
  4400. ds.number.of.loops.1.s,   ;-- number of loops in a for statement
  4401. ds.number.of.loops.2.s,   ;-- and another one
  4402. ds.loop.counter.1.s,      ;-- a loop counter
  4403. ds.loop.counter.2.s,      ;-- and another one
  4404. ds.at.position.s,         ;-- where to print to the screen
  4405. ds.get.char.s,            ;-- used to capture a keystroke
  4406. ds.clear.position.s       ;-- another screen positioner
  4407.  
  4408.  
  4409. style reverse
  4410. @ 00,00
  4411. ?? format("w80,ac",
  4412.           "After reviewing each section of the tape, press any key" +
  4413.           " to continue and view")
  4414. @ 01,00 ?? format("w80,ac",
  4415.                   "the next section. At the end of the tape, you" +
  4416.                   " will return to normal mode.")
  4417. style
  4418.  
  4419. ;-- how many screens to re-run
  4420. ds.number.of.loops.1.s = int(ds.tape.count.s/18)
  4421.  
  4422. ;-- adjust as required
  4423. if ds.number.of.loops.1.s <> ds.tape.count.s/18 then
  4424.    ds.number.of.loops.1.s = ds.number.of.loops.1.s + 1
  4425. endif
  4426.  
  4427. ;-- initialize the variable
  4428. ds.number.of.loops.2.s = 1
  4429.  
  4430. ;-- for the number of times the tape need to be re-run
  4431. for ds.loop.counter.1.s from 1 to ds.number.of.loops.1.s
  4432.    ;-- start here
  4433.    ds.at.position.s = 6
  4434.    ;-- turn the canvas off
  4435.    canvas off
  4436.    ;-- first time through place this at the top of the tape
  4437.    if ds.loop.counter.1.s = 1 then
  4438.       style reverse
  4439.       @ 05,43 ?? "║                          │      ║"
  4440.       style blink, reverse
  4441.       @ 05,44 ?? "    Tape Review Mode"
  4442.       style
  4443.    else
  4444.       ;-- if not the first time, place this at the top of the tape
  4445.       style reverse
  4446.       @ 05,43 ?? "║                          │      ║"
  4447.       style blink, reverse
  4448.       @ 05,44 ?? "    Tape Review Mode  "
  4449.       style
  4450.    endif
  4451.    ;-- place the tape entries on the screen
  4452.    for ds.loop.counter.2.s
  4453.       from ds.number.of.loops.2.s
  4454.       to (ds.number.of.loops.2.s + 17)
  4455.       ;-- this if clears to the bottom of the tape
  4456.       ;-- any entries placed there earlier
  4457.       if ds.loop.counter.2.s > ds.tape.count.s or
  4458.          (ds.loop.counter.2.s = ds.tape.count.s and
  4459.          (not isassigned(ds.tape.r[ds.tape.count.s]) or
  4460.          ds.tape.r[ds.tape.count.s] = blanknum() or
  4461.          lower(numval(ds.tape.r[ds.tape.count.s])) = "error" or
  4462.          not isassigned(ds.tape.function.r[ds.tape.count.s]))) then
  4463.          for ds.clear.position.s from ds.at.position.s to 23
  4464.             @ ds.clear.position.s,43 ?? "║                          │      ║"
  4465.          endfor
  4466.          quitloop
  4467.       else
  4468.          ;-- set the style for totals or regular tape entries
  4469.          if ds.loop.counter.2.s > 1 then
  4470.             if ds.tape.function.r[ds.loop.counter.2.s-1] = 61 then
  4471.                style intense
  4472.             else
  4473.                style
  4474.             endif
  4475.          endif
  4476.          ;-- place the tape entry on the screen using
  4477.          ;-- the proper format for the number type
  4478.          if ds.decimal.r[ds.loop.counter.2.s] then
  4479.             @ ds.at.position.s,45
  4480.             ?? format("w20.15,ar",numval(ds.tape.r[ds.loop.counter.2.s]))
  4481.          else
  4482.             @ ds.at.position.s,45
  4483.             ?? format("w20,ar,ec",numval(ds.tape.r[ds.loop.counter.2.s]))
  4484.          endif
  4485.          ;-- place the function key
  4486.          @ ds.at.position.s,73 ?? chr(ds.tape.function.r[ds.loop.counter.2.s])
  4487.          style
  4488.          ;-- increment the position pointer
  4489.          ds.at.position.s = ds.at.position.s + 1
  4490.       endif
  4491.    endfor
  4492.    ;-- turn the canvas on
  4493.    canvas on
  4494.    ds.get.char.s = getchar()
  4495.    ;-- reset the variable for the next set
  4496.    ds.number.of.loops.2.s = ds.loop.counter.2.s
  4497. endfor
  4498.  
  4499. endproc
  4500.  
  4501. ?? "." message memleft() writelib ds.aplib.a ds.review.tape.u
  4502. release procs ds.review.tape.u
  4503.  
  4504. ;-------------------------------------------------------------------------------
  4505. ;                                                              ds.print.tape.u()
  4506. ;-------------------------------------------------------------------------------
  4507. ; purpose: sends the tape to the attached printer
  4508. proc ds.print.tape.u()
  4509.  
  4510. private
  4511. ds.loop.counter.s    ;-- a loop counter
  4512.  
  4513. ;-- only if the printer is on
  4514. if printerstatus() then
  4515.    ;-- double check, some machines return true the first time,
  4516.    ;-- false the second
  4517.    if printerstatus() then
  4518.       ;-- for networks
  4519.       open printer
  4520.       ;-- the header
  4521.       print "                Tape Entry #:\n"
  4522.       for ds.loop.counter.s from 1 to ds.tape.count.s
  4523.          ;-- the footer
  4524.          if not isassigned(ds.tape.function.r[ds.loop.counter.s]) then
  4525.             print "\n" + "      ** End of Tape **\n"
  4526.             quitloop
  4527.          else
  4528.             ;-- pick the proper format
  4529.             if ds.decimal.r[ds.loop.counter.s] then
  4530.                print format("w20.15,ar",
  4531.                             numval(ds.tape.r[ds.loop.counter.s])) +
  4532.                             "  " +
  4533.                             chr(ds.tape.function.r[ds.loop.counter.s])
  4534.             else
  4535.                print format("w20,ar,ec",
  4536.                             numval(ds.tape.r[ds.loop.counter.s])) +
  4537.                             "  " +
  4538.                             chr(ds.tape.function.r[ds.loop.counter.s])
  4539.             endif
  4540.             ;-- print the tape entry number
  4541.             print "     : " + strval(ds.loop.counter.s) + "\n"
  4542.          endif
  4543.       endfor
  4544.       ;-- spit the page out
  4545.       print "\f"
  4546.       ;-- close the printer
  4547.       close printer
  4548.       return
  4549.    endif
  4550. endif
  4551.  
  4552. ds.error.u(
  4553. "Please turn on or reset your printer before attempting to print the tape.",
  4554. "Press any key to continue.")
  4555.  
  4556. ds.main.prompt.u()
  4557.  
  4558. return
  4559.  
  4560. endproc
  4561.  
  4562. ?? "." message memleft() writelib ds.aplib.a ds.print.tape.u
  4563. release procs ds.print.tape.u
  4564.  
  4565. ;-------------------------------------------------------------------------------
  4566. ;                                                                   ds.error.u()
  4567. ;-------------------------------------------------------------------------------
  4568. ; purpose: displays error messages on the top 2 lines of the screen
  4569. proc ds.error.u(
  4570. ds.line.1.a,       ;-- passed parameters to this procedure
  4571. ds.line.2.a)       ;-- of the message to be displayed
  4572.  
  4573. private
  4574. ds.get.char.s   ;-- keystroke to get
  4575.  
  4576. style reverse
  4577. canvas off
  4578. @ 00,00 ?? format("w80,ac",ds.line.1.a)
  4579. @ 01,00 ?? format("w80,ac",ds.line.2.a)
  4580. canvas on
  4581. style
  4582.  
  4583. while charwaiting()
  4584.    ds.get.char.s = getchar()
  4585. endwhile
  4586.  
  4587. for ds.get.char.s from 1 to 4
  4588.    beep
  4589.    sleep 250
  4590. endfor
  4591.  
  4592. ds.get.char.s = getchar()
  4593.  
  4594. @ 01,00 clear eol
  4595. @ 00,00 clear eol
  4596.  
  4597. endproc
  4598.  
  4599. ?? "." message memleft() writelib ds.aplib.a ds.error.u
  4600. release procs ds.error.u
  4601.  
  4602. ;-------------------------------------------------------------------------------
  4603. ;                                                                    ds.oops.1()
  4604. ;-------------------------------------------------------------------------------
  4605. ; purpose: errorproc to be called when no custom added in procedures exist
  4606. proc ds.oops.1()
  4607.  
  4608. private
  4609. autolib
  4610.  
  4611. autolib = ds.aplib.a
  4612.  
  4613. ;-- bottom line restorer
  4614. canvas off
  4615. message ""
  4616. @ 22,78 clear eol
  4617. canvas on
  4618.  
  4619. ;-- was there a proc?
  4620. if lower(errormessage()) =
  4621.    "run error: procedure ds.custom.v is not defined" then
  4622.    ds.error.u(
  4623.    "Sorry, no custom formulas have been added into the calculator.",
  4624.    ds.press.it.a)
  4625.    ds.not.defined.a = "noproc"
  4626. else
  4627.    ;-- some other unknown error tripped us up!
  4628.    ;-- display that message to the user
  4629.    ds.error.u(errormessage(),
  4630.    ds.press.it.a)
  4631. endif
  4632.  
  4633. ;-- attempt to step over the offending line of code
  4634. return 1
  4635.  
  4636. endproc
  4637.  
  4638. ?? "." message memleft() writelib ds.aplib.a ds.oops.1
  4639. release procs ds.oops.1
  4640.  
  4641.  
  4642. ;-------------------------------------------------------------------------------
  4643. ;                                                               ds.help.menu.u()
  4644. ;-------------------------------------------------------------------------------
  4645. ; purpose: displays the dscalc help menu
  4646. proc ds.help.menu.u()
  4647.  
  4648. private
  4649. ds.help.choice.a  ;-- menu choice selected
  4650.  
  4651. ;-- initialize this variable
  4652. ds.rebuild.l = true
  4653.  
  4654. showmenu
  4655.    "Basic "    : " Basic information about the use of DSCalc.",
  4656.    "Memory "   : " How to use the Memory functions of the calculator.",
  4657.    "Specials " : " How to call up and use the special" +
  4658.                  " Functions and Formulas Menu.",
  4659.    "The Tape " : " How to Review and/or Print the tape.",
  4660.    "General "  : " Some general tips on using DSCalc.",
  4661.    "Info "     : " Information about the author of DSCalc.",
  4662.    "Esc "      : " Return to what you were doing before asking for help."
  4663. to ds.help.choice.a
  4664.  
  4665. canvas off
  4666. message ""
  4667. @ 22,78 clear eol
  4668. canvas on
  4669.  
  4670. ;-- evaluate the menu item selected and call
  4671. ;-- the appropriate procedure or exit
  4672. switch
  4673.    case ds.help.choice.a = "Esc" or
  4674.         ds.help.choice.a = "Esc " :
  4675.       ds.rebuild.l = false
  4676.  
  4677.    case ds.help.choice.a = "Basic " :
  4678.       ds.basic.help.u()
  4679.  
  4680.    case ds.help.choice.a = "Memory " :
  4681.       ds.memory.help.u()
  4682.  
  4683.    case ds.help.choice.a = "Specials " :
  4684.       ds.specials.help.u()
  4685.  
  4686.    case ds.help.choice.a = "The Tape " :
  4687.       DS.Tape.Help.u()
  4688.  
  4689.    case ds.help.choice.a = "General " :
  4690.       ds.general.help.u()
  4691.  
  4692.    case ds.help.choice.a = "Info " :
  4693.       ds.info.help.u()
  4694.  
  4695. endswitch
  4696.  
  4697. endproc
  4698.  
  4699. ?? "." message memleft() writelib ds.aplib.a ds.help.menu.u
  4700. release procs ds.help.menu.u
  4701.  
  4702. ;-------------------------------------------------------------------------------
  4703. ;                                                              ds.basic.help.u()
  4704. ;-------------------------------------------------------------------------------
  4705. ; purpose: displays the main help screen
  4706. proc ds.basic.help.u()
  4707.  
  4708. private
  4709. ds.get.char.s
  4710.  
  4711. @ 00,00
  4712. canvas off
  4713. text
  4714. ╔══════════════════════════════════════════════════════════════════════════════╗
  4715. ║                                                                              ║
  4716. ╠══════════════════════════════════════════════════════════════════════════════╣
  4717. ║ Since the keypad for the calculator is the standard computer keyboard there  ║
  4718. ║ may be some slight adjustments required from what you are accustomed to.     ║
  4719. ║                                                                              ║
  4720. ║ There are also some special keys that may be used that are not shown on the  ║
  4721. ║ screen that make this calculator easier to use. (i.e. [Backspace] clears     ║
  4722. ║ one digit at a time from the right of the calculator window.)                ║
  4723. ║                                                                              ║
  4724. ║ The basic keys and a brief definition of their use in the calculator are:    ║
  4725. ║                                                                              ║
  4726. ║          +      :  Used to indicate addition.                                ║
  4727. ║          -      :  Used to indicate subtraction or negative numbers.         ║
  4728. ║          *      :  Used to indicate multiplication.                          ║
  4729. ║          /      :  Used to indicate division.                                ║
  4730. ║          .      :  Used to indicate a decimal.                               ║
  4731. ║          =      :  Used to tell DSCalc to perform the calculations.          ║
  4732. ║                             (Also [Enter] and [F2].)                         ║
  4733. ║      [Alt-C]    :  Completely clear the calculator (Except memory values.)   ║
  4734. ║        [C]      :  Clear just the current entry. (Also [Ctrl-BackSpace].)    ║
  4735. ║        [M]      :  Call up the Memory Menu.                                  ║
  4736. ║       [F10]     :  Call up the Special Functions and Formulas Menu.          ║
  4737. ║      [Alt-F7]   :  Review and/or Print the tape.                             ║
  4738. ╚═════════════════                                            ═════════════════╝
  4739. endtext
  4740.  
  4741. style reverse
  4742. @ 01,10
  4743. ?? " DSCalc is similar in use to most four function calculators. "
  4744. style
  4745.  
  4746. style intense
  4747. @ 24,18
  4748. ?? " Press any key to return to the calculator. "
  4749. style
  4750.  
  4751. canvas on
  4752.  
  4753. ds.get.char.s = getchar()
  4754.  
  4755. endproc
  4756.  
  4757. ?? "." message memleft() writelib ds.aplib.a ds.basic.help.u
  4758. release procs ds.basic.help.u
  4759.  
  4760.  
  4761. ;-------------------------------------------------------------------------------
  4762. ;                                                             ds.memory.help.u()
  4763. ;-------------------------------------------------------------------------------
  4764. ; purpose: displays the memory help screen
  4765. proc ds.memory.help.u()
  4766.  
  4767. private
  4768. ds.get.char.s
  4769.  
  4770. @ 00,00
  4771. canvas off
  4772. text
  4773. ╔══════════════════════════════════════════════════════════════════════════════╗
  4774. ║                                                                              ║
  4775. ╠══════════════════════════════════════════════════════════════════════════════╣
  4776. ║ By pressing "M" or "m" while in the calculator, DSCalc will present on the   ║
  4777. ║ top two lines the Memory menu and prompts.                                   ║
  4778. ║                                                                              ║
  4779. ║ By highlighting a specific choice with the cursor keys on the top line, the  ║
  4780. ║ second line will reveal some more information about that particular choice.  ║
  4781. ║ To select the choice, either press the first letter of the choice or when    ║
  4782. ║ that choice is highlighted, press the [Enter] key.                           ║
  4783. ║                                                                              ║
  4784. ║ After selecting the appropriate Memory function, use the cursor keys to      ║
  4785. ║ highlight the memory location number and the second line will reveal either  ║
  4786. ║ "Not Assigned" or the value that is kept in that Memory location.            ║
  4787. ║                                                                              ║
  4788. ║ If you had selected "Add " or "Subtract " from the Memory menu, after        ║
  4789. ║ highlighting a Memory location, pressing the [Enter] key will add to or      ║
  4790. ║ subtract from that location the last entry in the calculator and then show   ║
  4791. ║ you the result on the second line. Selecting "Recall " will recall that      ║
  4792. ║ value and enter it into the calculator window. (Any current entry will be    ║
  4793. ║ overwritten with the recalled value.)   The "Display " function simply lets  ║
  4794. ║ you view the stored memory values with no manipulation and the "Clear "      ║
  4795. ║ function clears all of the stored values from memory. Use the [Esc] key to   ║
  4796. ║ cancel and/or return to the previous Menu and/or the calculator.             ║
  4797. ╚═════════════════                                            ═════════════════╝
  4798. endtext
  4799.  
  4800. style reverse
  4801. @ 01,05
  4802. ?? " DSCalc has the capability to store and use nineteen memory values. "
  4803. style
  4804.  
  4805. style intense
  4806. @ 24,18
  4807. ?? " Press any key to return to the calculator. "
  4808. style
  4809.  
  4810. canvas on
  4811.  
  4812. ds.get.char.s = getchar()
  4813.  
  4814. endproc
  4815.  
  4816. ?? "." message memleft() writelib ds.aplib.a ds.memory.help.u
  4817. release procs ds.memory.help.u
  4818.  
  4819. ;-------------------------------------------------------------------------------
  4820. ;                                                           ds.specials.help.u()
  4821. ;-------------------------------------------------------------------------------
  4822. ; purpose: displays the specials help screen
  4823. proc ds.specials.help.u()
  4824.  
  4825. private
  4826. ds.special.choice.a
  4827.  
  4828. @ 02,00
  4829. canvas off
  4830. text
  4831. ╔══════════════════════════════════════════════════════════════════════════════╗
  4832. ║                                                                              ║
  4833. ║                                                                              ║
  4834. ╠══════════════════════════════════════════════════════════════════════════════╣
  4835. ║ You can call up the Special Functions and Formulas Menu by pressing the      ║
  4836. ║ [F10] key when the top two lines on the screen display the message:          ║
  4837. ║                                                                              ║
  4838. ║       "Press [F10] for special functions and formulas, [F1] for help."       ║
  4839. ║              "Press [Esc] to return to what you were doing."                 ║
  4840. ║                                                                              ║
  4841. ║ After pressing the [F10] key, a Menu will appear on the top two lines like   ║
  4842. ║ the Menu that now appears on the top two lines of this screen.               ║
  4843. ║                                                                              ║
  4844. ║ To select a Menu choice (True when any menu appears on the top two lines of  ║
  4845. ║ this program), use the cursor keys to highlight your choice and press the    ║
  4846. ║ [Enter] key or press the letter key corresponding to the first letter of     ║
  4847. ║ your choice. (When there is more than one choice starting with the same      ║
  4848. ║ letter or number, you must highlight your choice and press the [Enter] key.) ║
  4849. ║                                                                              ║
  4850. ║ Select one of the above choices for more help with Mathematical,             ║
  4851. ║ Trigonometry, Financial or the Custom functions or press [Esc] to return     ║
  4852. ║ to the calculator.                                                           ║
  4853. ╚══════════════════════════════════════════════════════════════════════════════╝
  4854. endtext
  4855.  
  4856. style reverse
  4857. @ 03,04
  4858. ?? " DSCalc has a Special Functions and Formulas Menu for Mathematical, "
  4859.  
  4860. @ 04,04
  4861. ?? "   Trigonometry, Financial and user defined customized formulas.    "
  4862. style
  4863.  
  4864. canvas on
  4865.  
  4866. showmenu
  4867.    "Mathematical " : " Help with Mathematical functions.",
  4868.    "Trigonometry " : " Help with Trigonometry calculations.",
  4869.    "Financial "    : " Help with Financial calculations.",
  4870.    "Custom "       : " Help with Custom Designed calculations.",
  4871.    "Esc "          : " Return to what you were doing."
  4872. to ds.special.choice.a
  4873.  
  4874. switch
  4875.  
  4876.    case ds.special.choice.a = "Mathematical " :
  4877.       ds.math.help.u()
  4878.  
  4879.    case ds.special.choice.a = "Trigonometry " :
  4880.       ds.trig.help.u()
  4881.  
  4882.    case ds.special.choice.a = "Financial " :
  4883.       ds.finance.help.u()
  4884.  
  4885.    case ds.special.choice.a = "Custom " :
  4886.       ds.custom.help.u()
  4887.  
  4888. endswitch
  4889.  
  4890. canvas off
  4891. message ""
  4892. @ 22,78 clear eol
  4893. canvas on
  4894.  
  4895. return
  4896.  
  4897.  
  4898. endproc
  4899.  
  4900. ?? "." message memleft() writelib ds.aplib.a ds.specials.help.u
  4901. release procs ds.specials.help.u
  4902.  
  4903. ;-------------------------------------------------------------------------------
  4904. ;                                                               ds.math.help.u()
  4905. ;-------------------------------------------------------------------------------
  4906. ; purpose: displays the math help screen
  4907. proc ds.math.help.u()
  4908.  
  4909. private
  4910. ds.get.char.s
  4911.  
  4912. @ 00,00
  4913. canvas off
  4914. text
  4915. ╔══════════════════════════════════════════════════════════════════════════════╗
  4916. ║                                                                              ║
  4917. ║                                                                              ║
  4918. ║                                                                              ║
  4919. ╠══════════════════════════════════════════════════════════════════════════════╣
  4920. ║ The following math functions require at least one entry in the calculator.   ║
  4921. ║  ABS : The absolute value (always positive.) of a number.                    ║
  4922. ║  EXP : The exponential (base e) of a number.                                 ║
  4923. ║  INT : The integer part of a number (i.e. the whole part of a number).       ║
  4924. ║  LN  : The natural logarithm of a number.                                    ║
  4925. ║  LOG : The base 10 logarithm of a number.                                    ║
  4926. ║ SQRT : The square root of a number.                                          ║
  4927. ╟──────────────────────────────────────────────────────────────────────────────╢
  4928. ║ The next group of functions require at least one entry and an additional     ║
  4929. ║ number is required to be supplied via a prompt on the top lines.             ║
  4930. ║    POW : Raises the last entry to a given power.                             ║
  4931. ║  ROUND : Round the last entry to a specified number of places. (A whole      ║
  4932. ║          number between -15 and 15)                                          ║
  4933. ╟──────────────────────────────────────────────────────────────────────────────╢
  4934. ║  MOD : The remainder of one number divided by another.                       ║
  4935. ╟──────────────────────────────────────────────────────────────────────────────╢
  4936. ║   PI : Returns the value of PI (3.141592653589)                              ║
  4937. ║ RAND : Returns a random decimal number between 0 and 1.                      ║
  4938. ║                                                                              ║
  4939. ╚═════════════════                                            ═════════════════╝
  4940. endtext
  4941.  
  4942. style reverse
  4943. @ 01,03
  4944. ?? "       DSCalc will perform the following mathematical functions:         "
  4945. @ 02,03
  4946. ?? " (Note: The resulting answer will be displayed in the calculator window, "
  4947. @ 03,03
  4948. ?? "  replacing any value already there.)                                    "
  4949. style
  4950.  
  4951. style intense
  4952. @ 24,18
  4953. ?? " Press any key to return to the calculator. "
  4954. style
  4955.  
  4956. canvas on
  4957.  
  4958. ds.get.char.s = getchar()
  4959.  
  4960. endproc
  4961.  
  4962. ?? "." message memleft() writelib ds.aplib.a ds.math.help.u
  4963. release procs ds.math.help.u
  4964.  
  4965. ;-------------------------------------------------------------------------------
  4966. ;                                                               ds.trig.help.u()
  4967. ;-------------------------------------------------------------------------------
  4968. ; purpose: displays the trig help screen
  4969. proc ds.trig.help.u()
  4970.  
  4971. private
  4972. ds.get.char.s
  4973.  
  4974. @ 00,00
  4975. canvas off
  4976. text
  4977. ╔══════════════════════════════════════════════════════════════════════════════╗
  4978. ║                                                                              ║
  4979. ╠══════════════════════════════════════════════════════════════════════════════╣
  4980. ║ The Trigonometry section of DSCalc was designed for ease of use without      ║
  4981. ║ having to dig out your Trig tables and formulas. DSCalc performs all of the  ║
  4982. ║ Trig functions automatically.  After selecting the Trigonometry Menu choice, ║
  4983. ║ the Trig screen will appear with a "Menu" box on the right hand side of the  ║
  4984. ║ screen.  The box is divided into two columns.  The column on the left is for ║
  4985. ║ Right Angle Triangles (Any triangle having one angle of 90°) and the right   ║
  4986. ║ column is for Oblique Triangles (A triangle that does not have a 90° angle). ║
  4987. ║ Use the cursor keys to select the appropriate choice for the known values.   ║
  4988. ║ You will be prompted on the top lines for the information and DSCalc will    ║
  4989. ║ do the rest.                                                                 ║
  4990. ║                                                                              ║
  4991. ║ When there is a known angle to be input, DSCalc will prompt you to let it    ║
  4992. ║ know what precision you will be imputing the angle.  Angles may be input as  ║
  4993. ║ Degrees, Degrees with Minutes, Degrees with Minutes and Seconds or as        ║
  4994. ║ Radians.                                                                     ║
  4995. ║                                                                              ║
  4996. ║ After you have completed the triangle, you may return the answer to the      ║
  4997. ║ calculator by pressing [Esc] and then selecting the appropriate menu choice. ║
  4998. ║                                                                              ║
  4999. ║ Note: The precision of any answer is only accurate to 15 places. It is up to ║
  5000. ║ the user to determine to what place to round off the answer to.              ║
  5001. ╚═════════════════                                            ═════════════════╝
  5002. endtext
  5003.  
  5004. style reverse
  5005. @ 01,08
  5006. ?? "  DSCalc performs Trigonometry functions simply and quickly. "
  5007. style
  5008.  
  5009. style intense
  5010. @ 24,18
  5011. ?? " Press any key to return to the calculator. "
  5012. style
  5013. canvas on
  5014. ds.get.char.s = getchar()
  5015.  
  5016. endproc
  5017.  
  5018. ?? "." message memleft() writelib ds.aplib.a ds.trig.help.u
  5019. release procs ds.trig.help.u
  5020.  
  5021. ;-------------------------------------------------------------------------------
  5022. ;                                                            ds.finance.help.u()
  5023. ;-------------------------------------------------------------------------------
  5024. ; purpose: displays the financial help screen
  5025. proc ds.finance.help.u()
  5026.  
  5027. private
  5028. ds.get.char.s
  5029.  
  5030. @ 00,00
  5031. canvas off
  5032. text
  5033. ╔══════════════════════════════════════════════════════════════════════════════╗
  5034. ║                                                                              ║
  5035. ╠══════════════════════════════════════════════════════════════════════════════╣
  5036. ║ DSCalc will perform the following financial functions when the appropriate   ║
  5037. ║ information is supplied at the prompts on the top line of the screen:        ║
  5038. ║                                                                              ║
  5039. ║  FV : The future value of a series of equal payments.  This function is      ║
  5040. ║       sometimes called the compound value of an annuity.  It will calculate  ║
  5041. ║       the amount accumulated in a annuity fund by making regular payments    ║
  5042. ║       over a specified period of time at a specified interest rate.          ║
  5043. ║                                                                              ║
  5044. ║ PMT : The periodic payment to pay off a loan.  This formula returns the      ║
  5045. ║       amount of the payment required to pay off a loan amount over a given   ║
  5046. ║       time span at a specific interest rate.                                 ║
  5047. ║                                                                              ║
  5048. ║  PV : The present value of a series of equal payments.  This function is     ║
  5049. ║       sometimes called the present value of an annuity.  By supplying the    ║
  5050. ║       the amount of a payment, the interest rate and the number of pay       ║
  5051. ║       periods, this formula will compute the size of a loan that could be    ║
  5052. ║       paid off with that payment or how much money would be required in an   ║
  5053. ║       annuity fund to supply a given amount of money over a specified time   ║
  5054. ║       period.                                                                ║
  5055. ║                                                                              ║
  5056. ║   (Note: The maximum time period is 1020 months for the above formulas.)     ║
  5057. ╚═════════════════                                            ═════════════════╝
  5058. endtext
  5059.  
  5060. style reverse
  5061. @ 01,21
  5062. ?? " Financial Functions with DSCalc "
  5063. style
  5064.  
  5065. style intense
  5066. @ 24,18
  5067. ?? " Press any key to return to the calculator. "
  5068. style
  5069. canvas on
  5070. ds.get.char.s = getchar()
  5071.  
  5072. endproc
  5073.  
  5074. ?? "." message memleft() writelib ds.aplib.a ds.finance.help.u
  5075. release procs ds.finance.help.u
  5076.  
  5077.  
  5078.  
  5079. ;-------------------------------------------------------------------------
  5080. ;                                                          ds.custom.help.u()
  5081. ;-------------------------------------------------------------------------
  5082. ; purpose: displays the custom help screen
  5083. proc ds.custom.help.u()
  5084.  
  5085. private
  5086. ds.get.char.s
  5087.  
  5088. @ 00,00
  5089. canvas off
  5090. text
  5091. ╔══════════════════════════════════════════════════════════════════════════════╗
  5092. ║                                                                              ║
  5093. ╠══════════════════════════════════════════════════════════════════════════════╣
  5094. ║                                                                              ║
  5095. ║                                                                              ║
  5096. ║ Custom formulas may be added into to DSCalc for specific formulas that are   ║
  5097. ║ used frequently by the user.                                                 ║
  5098. ║                                                                              ║
  5099. ║                                                                              ║
  5100. ║                                                                              ║
  5101. ║ If selecting the Custom menu choice results in an error message on the top   ║
  5102. ║ two lines of the screen, then there have not been any custom formulas added  ║
  5103. ║ to the calculator.                                                           ║
  5104. ║                                                                              ║
  5105. ║                                                                              ║
  5106. ║                                                                              ║
  5107. ║ If you wish to add a custom formula to the calculator, refer to the script   ║
  5108. ║ "DSCustom.sc" supplied with this program as an example of how to add on your ║
  5109. ║ own formulas to the calculator.                                              ║
  5110. ║                                                                              ║
  5111. ║                                                                              ║
  5112. ║                                                                              ║
  5113. ║                                                                              ║
  5114. ║                                                                              ║
  5115. ╚═════════════════                                            ═════════════════╝
  5116. endtext
  5117.  
  5118. style reverse
  5119. @ 01,21
  5120. ?? " Custom add on formulas for DSCalc "
  5121. style
  5122.  
  5123. style intense
  5124. @ 24,18
  5125. ?? " Press any key to return to the calculator. "
  5126. style
  5127. canvas on
  5128. ds.get.char.s = getchar()
  5129.  
  5130. endproc
  5131.  
  5132. ?? "." message memleft() writelib ds.aplib.a ds.custom.help.u
  5133. release procs ds.custom.help.u
  5134.  
  5135. ;-------------------------------------------------------------------------------
  5136. ;                                                               ds.tape.help.u()
  5137. ;-------------------------------------------------------------------------------
  5138. ; purpose: displays the tape help screen
  5139. proc ds.tape.help.u()
  5140.  
  5141. private
  5142. ds.get.char.s
  5143.  
  5144. @ 00,00
  5145. canvas off
  5146. text
  5147. ╔══════════════════════════════════════════════════════════════════════════════╗
  5148. ║                                                                              ║
  5149. ╠══════════════════════════════════════════════════════════════════════════════╣
  5150. ║ Select Review/Print by holding down the [Alt] key and then press [F7].       ║
  5151. ║                                                                              ║
  5152. ║ Printing the tape:                                                           ║
  5153. ║  Printing of the tape is a function that is either "On" or "Off" by the way  ║
  5154. ║  that DSCalc is started.  If the print function is not turned "On" when the  ║
  5155. ║  calculator is started, then the tape may not be printed.  Otherwise, DSCalc ║
  5156. ║  sends the contents to the default printer.  DSCalc checks twice to see if   ║
  5157. ║  the printer is ready before attempting to print the tape.  Printer status   ║
  5158. ║  is checked twice as some computers will return "True" the first time that   ║
  5159. ║  the printer status is checked.  Note: Printer status is ALWAYS returned as  ║
  5160. ║  "True" on any port other then LPT1.  Print size will be determined by       ║
  5161. ║  the current printer settings. A "Form Feed" is generated at the end of the  ║
  5162. ║  tape.                                                                       ║
  5163. ║                                                                              ║
  5164. ║ Reviewing the tape:                                                          ║
  5165. ║  Review of the tape is only possible when the tape is longer than the screen.║
  5166. ║  This may be determined by the "   More   " at the top of the tape box.    ║
  5167. ║  Once the review mode has started, the entire tape must be reviewed.  After  ║
  5168. ║  viewing each section of the tape, press a key to view the next section.     ║
  5169. ║  After the entire tape has been reviewed, you will be returned to the normal ║
  5170. ║  calculator mode.                                                            ║
  5171. ╚═════════════════                                            ═════════════════╝
  5172. endtext
  5173.  
  5174. style reverse
  5175. @ 01,20
  5176. ?? " Reviewing and/or Printing of the Tape "
  5177. style
  5178.  
  5179. style intense
  5180. @ 24,18
  5181. ?? " Press any key to return to the calculator. "
  5182. style
  5183. canvas on
  5184. ds.get.char.s = getchar()
  5185.  
  5186. endproc
  5187.  
  5188. ?? "." message memleft() writelib ds.aplib.a ds.tape.help.u
  5189. release procs ds.tape.help.u
  5190.  
  5191. ;-------------------------------------------------------------------------------
  5192. ;                                                            ds.general.help.u()
  5193. ;-------------------------------------------------------------------------------
  5194. ; purpose: displays the general help screen
  5195. proc ds.general.help.u()
  5196.  
  5197. private
  5198. ds.get.char.s
  5199.  
  5200. @ 00,00
  5201. canvas off
  5202. text
  5203. ╔══════════════════════════════════════════════════════════════════════════════╗
  5204. ║                                                                              ║
  5205. ╠══════════════════════════════════════════════════════════════════════════════╣
  5206. ║  DSCalc is only accurate to 15 places!  It is the users responsibility to    ║
  5207. ║  determine the accuracy of any answer calculated with this calculator.       ║
  5208. ║                                                                              ║
  5209. ║  The [Esc] key may be used at almost any point to cancel the current         ║
  5210. ║  operation including but not limited to any value requested on the top two   ║
  5211. ║  lines of the screen.                                                        ║
  5212. ║                                                                              ║
  5213. ║  Keys defined like [Alt-F7] (Print/Review the tape) or [Alt-C] (Clear-All)   ║
  5214. ║  require that the first key ([Alt]) be held down and while holding that key  ║
  5215. ║  down, press the second key (Such as [F7] or [C]) to perform that function.  ║
  5216. ║                                                                              ║
  5217. ║  There may be alternate keys to some of the function keys.  [Enter] and [F2] ║
  5218. ║  perform the same as the [=] key.  [Ctrl-Backspace] and [F8] perform the     ║
  5219. ║  same functions as [C] (Clear Entry).  [Alt-F8] is the same as [Alt-C]       ║
  5220. ║  (Clear All).                                                                ║
  5221. ║                                                                              ║
  5222. ║  Leading zeros are NOT allowed.                                              ║
  5223. ║                                                                              ║
  5224. ║  [Backspace] deletes ONE digit at a time from the calculator window.         ║
  5225. ║                                                                              ║
  5226. ║                                                                              ║
  5227. ╚═════════════════                                            ═════════════════╝
  5228. endtext
  5229.  
  5230. style reverse
  5231. @ 01,13
  5232. ?? " Some general information and tips about DSCalc "
  5233. style
  5234.  
  5235. style intense
  5236. @ 24,18
  5237. ?? " Press any key to return to the calculator. "
  5238. style
  5239. canvas on
  5240. ds.get.char.s = getchar()
  5241.  
  5242. endproc
  5243.  
  5244. ?? "." message memleft() writelib ds.aplib.a ds.general.help.u
  5245. release procs ds.general.help.u
  5246.  
  5247. ;-------------------------------------------------------------------------------
  5248. ;                                                               ds.info.help.u()
  5249. ;-------------------------------------------------------------------------------
  5250. ; purpose: displays the info screen
  5251. proc ds.info.help.u()
  5252.  
  5253. private
  5254. ds.get.char.s
  5255.  
  5256. @ 00,00
  5257. canvas off
  5258. text
  5259. ╔══════════════════════════════════════════════════════════════════════════════╗
  5260. ║                                                                              ║
  5261. ╠══════════════════════════════════════════════════════════════════════════════╣
  5262. ║ DSCalc CopyRighted 1989, 1990:                               Version 1.10    ║
  5263. ║                                                        All rights reserved   ║
  5264. ║ Dave Schlieder                                                               ║
  5265. ║ Shared Logic, Inc.                                                           ║
  5266. ║ 1016 Second Street                                                           ║
  5267. ║ Encinitas, Ca.  92024                                                        ║
  5268. ║ (619)943-1086                                                                ║
  5269. ║                                                                              ║
  5270. ║  This program has been released to the public domain and can be used or      ║
  5271. ║  modified in any way.  It was written as an exercise in learning programming ║
  5272. ║  techniques and string and numeric manipulation. I hope you find this        ║
  5273. ║  program enlightening and educational.                                       ║
  5274. ║                                                                              ║
  5275. ║                                                                              ║
  5276. ║ Although the procedures are Copyright 1989,1990 Dave Schlieder you are hereby║
  5277. ║ granted the use of any of these Procs in your scripts, provided that you     ║
  5278. ║ retain the original names of my procedures.                                  ║
  5279. ║ (I usually include an acknowledgement in my script comments if I use other   ║
  5280. ║  peoples' code in this way.)                                                 ║
  5281. ║ If you distribute them, please do so UNALTERED.                              ║
  5282. ║                                                                              ║
  5283. ╚═════════════════                                            ═════════════════╝
  5284. endtext
  5285.  
  5286. style reverse
  5287. @ 01,17
  5288. ?? " Who to contact for information about DSCalc "
  5289. style
  5290.  
  5291. style intense
  5292. @ 24,18
  5293. ?? " Press any key to return to the calculator. "
  5294. style
  5295. canvas on
  5296. ds.get.char.s = getchar()
  5297.  
  5298. endproc
  5299.  
  5300. ?? "." message memleft() writelib ds.aplib.a ds.info.help.u
  5301. release procs ds.info.help.u