home *** CD-ROM | disk | FTP | other *** search
/ UpTime Volume 2 #8 / utv2n8s1.d64 / ml < prev    next >
Encoding:
Text File  |  1988-01-01  |  8.4 KB  |  164 lines

  1. @@
  2.  
  3.   Programming with Machine Language
  4.  
  5.       Volume Two, Number Eight
  6.  
  7.  
  8. Copyright 1989 by Robert Rockefeller
  9.         All Rights Reserved
  10.  
  11.  
  12.             Published by
  13.      Softdisk Publishing, Inc.
  14.  
  15.  
  16.      This month we continue our look 'under the hood' of BASIC 2.0.  As mentioned last month, variables in BASIC 2.0 are stored immediately following the BASIC program text.  Function definitions are also stored there.  Each type of variable must be stored slightly differently in order to distinguish, for example, between the variables A, A%, A$ and the function FN A().
  17.  
  18.      Each variable or function defintion uses seven bytes of memory, two bytes for the variable or function name followed by five bytes for the storage of data.
  19.  
  20.  
  21. %cVARIABLE AND FUNCTION STRUCTURE:
  22.  
  23. %c{$f0}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f2}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f2}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f2}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f2}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f2}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f2}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$ee}
  24. %c{SHIFT--} Name  {SHIFT--}       Data        {SHIFT--}
  25. %c{$ed}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f1}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f1}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f1}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f1}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f1}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f1}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$fd}
  26.  
  27.      Legal variable or function names consist of a letter (A..Z) with an optional second character which may be alphabetic or numeric.  Since these characters are all of value less than 128 this means bit seven, the sign bit, is available for use as a flag to distinguish between the different types of variables.  A two character name gives four possible combinations of sign bits set on or off.
  28.  
  29.  
  30.  
  31. %cFLOATING POINT NAME:
  32.  
  33. %c{$f0}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f2}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$ee}
  34. %c{SHIFT--}   ASCII   {SHIFT--}   ASCII   {SHIFT--}
  35. %c{SHIFT--}           {SHIFT--}   or 0    {SHIFT--}
  36. %c{$ed}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f1}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$fd}
  37.  
  38. %cINTEGER NAME:
  39.  
  40. %c{$f0}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f2}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$ee}
  41. %c{SHIFT--}ASCII + 128{SHIFT--}ASCII + 128{SHIFT--}
  42. %c{SHIFT--}           {SHIFT--}  or 128   {SHIFT--}
  43. %c{$ed}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f1}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$fd}
  44.  
  45.  
  46. %cSTRING NAME:
  47.  
  48. %c{$f0}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f2}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$ee}
  49. %c{SHIFT--}   ASCII   {SHIFT--}ASCII + 128{SHIFT--}
  50. %c{SHIFT--}           {SHIFT--}  or 128   {SHIFT--}
  51. %c{$ed}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f1}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$fd}
  52.  
  53. %cFUNCTION NAME:
  54.  
  55. %c{$f0}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f2}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$ee}
  56. %c{SHIFT--}ASCII + 128{SHIFT--}   ASCII   {SHIFT--}
  57. %c{SHIFT--}           {SHIFT--}   or 0    {SHIFT--}
  58. %c{$ed}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f1}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$fd}
  59.  
  60.      For example a floating point variable named B would have its name stored as 66 and 0 (66=ASC("B")).  An integer variable named B% would have its name stored as 194 and 128 (66+128=194).  A string variable's name BC$ would be stored as 66 and 195 (67+128=195).
  61.  
  62.      Although each variable is allocated five bytes for data, only floating point variables use all five bytes.  A floating point number consists of a one byte binary exponent and four bytes of mantissa.  The sign bit of the first byte of the mantissa, M1, contains the sign of the number.  If negative the number is negative.  Floating point numbers will be discussed in more detail later.
  63.  
  64.  
  65.  
  66. %cFLOATING POINT DATA:
  67.  
  68. %c{$f0}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f2}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f2}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f2}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f2}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$ee}
  69. %c{SHIFT--} Exp  {SHIFT--}        Mantissa           {SHIFT--}
  70. %c{SHIFT--}      {SHIFT--} M1   {SHIFT--} M2   {SHIFT--} M3   {SHIFT--} M4   {SHIFT--}
  71. %c{$ed}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f1}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f1}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f1}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f1}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$fd}
  72.  
  73.      Integer variables are held as two's complement numbers and use only two bytes for data.  The high byte, also containing the sign of the integer, is put in the first byte, followed by the low byte.  Note that this is contrary to normal 6502 convention wherein the low byte usually appears first.  This is done for convenience when converting the number from integer to floating point.  Conversion is necessary whenever an integer variable appears in a BASIC expression (such as PRINT 5*B%).  Integer variables are slower than floating point variables because they require the additional step of conversion to floating point.
  74.  
  75.  
  76.  
  77.  
  78. %cINTEGER DATA:
  79.  
  80. %c{$f0}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f2}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f2}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f2}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f2}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$ee}
  81. %c{SHIFT--}   Integer   {SHIFT--}       Unused       {SHIFT--}
  82. %c{SHIFT--} High {SHIFT--} Low  {SHIFT--}  0   {SHIFT--}  0   {SHIFT--}  0   {SHIFT--}
  83. %c{$ed}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f1}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f1}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f1}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f1}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$fd}
  84.  
  85.      String variables use three bytes of the five, consisting of a length byte (the length of the string) followed by a pointer to the string (the address at which the string is stored):
  86.  
  87.  
  88. %cSTRING DATA:
  89.  
  90. %c{$f0}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f2}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f2}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f2}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f2}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$ee}
  91. %c{SHIFT--}Length{SHIFT--}   Pointer   {SHIFT--}   Unused    {SHIFT--}
  92. %c{SHIFT--}      {SHIFT--} Low  {SHIFT--} High {SHIFT--}  0   {SHIFT--}  0   {SHIFT--}
  93. %c{$ed}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f1}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f1}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f1}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f1}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$fd}
  94.  
  95.      In order to better understand how strings are stored the following program was created and RUN.  For the INPUT statement "dddd" was entered.
  96.  
  97.  
  98.  
  99. 10 a$="a": READb$: c$="c"+"c": INPUTd$
  100. 20 DATA bbb
  101.  
  102.      A memory dump of the program and variable storage area was then done using a machine-language monitor.  As mentioned last month, the start address of the BASIC text area is defined in TXTTAB ($2B).  The end address plus one of the variable storage area is defined in ARYTAB ($2F).  These addresses were examined to determine which area of memory to dump.
  103.  
  104. %c:0801  22 08 0A 00 41 24  "..@a$
  105. %c:0807  B2 22 41 22 3A 20  {$f2}"a": 
  106. %c:080D  87 42 24 3A 20 43  .b$: c
  107. %c:0813  24 b2 22 43 22 AA  ${$f2}"c"{$f6}
  108. %c:0819  22 43 22 3A 20 85  "c": .
  109. %c:081F  44 24 00 2C 08 14  d$@,..
  110. %c:0825  00 83 20 42 42 42  @. bbb
  111. %c:082B  00 00 00 41 80 01  @@@a..
  112. %c:0831  09 08 00 00 42 80  ..@@b.
  113. %c:0837  03 28 08 00 00 43  .(.@@c
  114. %c:083D  80 02 FE 7F 00 00  ....@@
  115. %c:0843  44 80 04 FA 7F 00  d....@
  116. %c:0849  00 FF FF FF FF FF  @{$de}{$de}{$de}{$de}{$de}
  117.  
  118.      Line 10 occupies $0801 to $0821 including four bytes at the start of the line for the link and line number fields.  Line 20 occupies $0822 to $082B.  Variables occupy memory from $082E to $0849.  Variable a$ is stored starting at address $082E.  Examining a$'s data we see a length byte of 1 at address $0830 and a pointer to address $0809 stored at address $0831.  Examining address $0809 we can see that this is where the string literal "a" occurs within the BASIC text area.  Examining variable b$ at address $0835 we find a length byte of 3 and a pointer to address $0828, at which address the string literal "bbb" is stored following the DATA statement in line 20.
  119.  
  120.      What happens when the text of the BASIC program does not contain the string, such as when a string is INPUT or is the result of a string operation such as concatenation with the '+' operator?  Examining variable c$ at address $083C we find a length byte of 2 and a pointer to address $7FFE.  Examining variable d$ we find a length of 4 and a pointer to address $7FFA.  A memory dump from $7FFA to $7FFF is below.
  121.  
  122. %c:7FFA  44 44 44 44 43 43  ddddcc
  123.  
  124.      When a new string is created, such as by INPUT, BASIC stores the string in a special area at the top of memory available to BASIC.  The bottom address of this area is defined by STREND ($31), the top by MEMSIZ ($37).  FRETOP ($33) always contains the start address of the last string added to the string storage area.  By POKEing a lower value into MEMSIZ one can reserve memory normally used by BASIC for some other purpose, such as a machine-language program.
  125.  
  126.  
  127.  
  128.  
  129.  
  130.  
  131.  
  132.  
  133.      Function definitions use four bytes of the five available.  Unlike normal variables, the unused byte is not cleared to 0.  Function definitions contain two pointers.
  134.  
  135.  
  136. %cFUNCTION DEFINITION DATA:
  137.  
  138. %c{$f0}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f2}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f2}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f2}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f2}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$ee}
  139. %c{SHIFT--} Pointer 1   {SHIFT--} Pointer 2   {SHIFT--}Unused{SHIFT--}
  140. %c{SHIFT--} Low  {SHIFT--} High {SHIFT--} Low  {SHIFT--} High {SHIFT--}  ?   {SHIFT--}
  141. %c{$ed}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f1}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f1}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f1}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f1}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$fd}
  142.  
  143.      To better understand the structure of a function definition, the below BASIC program was created and RUN, and a memory dump was made of the start of BASIC memory.
  144.  
  145. %c10 DEFFN t(x)=y
  146.  
  147. %c:0801  10 08 0A 00 96 A5  ...@V{$e5}
  148. %c:0807  20 54 28 58 29 B2   t(x){$f2}
  149. %c:080D  59 00 00 00 D4 00  y@@@.@
  150. %c:0813  0D 08 1A 08 FF 58  .....x
  151. %c:0819  00 00 00 00 00 00  @@@@@@
  152.  
  153.      BASIC program text runs from $0801 to $0810.  Variable storage uses memory from $0811 to $081E.  Note that the function t and the floating point variable x were created by DEFFN.  The variable y was not created.  BASIC never creates a new variable unless that variable is being assigned a value.  For instance assuming variable A$ does not exist it would be created by either of the following BASIC statements:
  154.  
  155.  
  156. %cINPUT A$ 
  157. %cA$="TEXT"
  158.  
  159.      A$ would not be created by the statement PRINT A$ since PRINT does not assign a value.
  160.  
  161.      The function data structure (it's not a real variable) runs from $0811 to $0817, the function name occupying the first two bytes.  The first pointer points to address $080D, just after the = in the function definition in the BASIC text.  This is the function expression to be evaluated each time the function is used.
  162.  
  163.      The second pointer points to address $081A, which is the data field address of the variable X.  X is the function's 'dependent variable.'  Before a function is evaluated the argument is deposited at this address, then the function expression is evaluated.  For example assume we have a function definition DEFFN SQ(A)=A*A.  If we then execute PRINT FN SQ(5), the 5 is known as the function's argument or parameter.  The value 5 is stored in variable A's data field using pointer 2 in function SQ's data structure, then the function expression A*A is evaluated.
  164.