home *** CD-ROM | disk | FTP | other *** search
/ UpTime Volume 2 #9 / utv2n9s1.d64 / ml < prev    next >
Encoding:
Text File  |  1988-01-01  |  7.4 KB  |  132 lines

  1. @@
  2.  
  3.   Programming with Machine Language
  4.  
  5.        Volume Two, Number Nine
  6.  
  7.  
  8.  
  9. Copyright 1989 by Robert Rockefeller
  10.          All Rights Reserved
  11.  
  12.              Published by
  13.       Softdisk Publishing, Inc.
  14.  
  15.  
  16.      This month we will use flowcharts to illustrate how the BASIC interpreter operates.  The flowcharts flow from top to bottom except at a YES/NO branch, or where the flow is specifically shown to be in some direction other than downwards.  Below is a flowchart illustrating the highest level of BASIC 2.0.  [Editor's Note: Some of the flowcharts presented in this article may not completely fit on the text screen.  For maximum effect, we suggest that you print this article.]
  17. %c {$f0}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$ee}           
  18. %c {SHIFT--}Print READY.{$eb}{SHIFT-*}{SHIFT-*}<{SHIFT-*}{SHIFT-*}{$ee}     
  19. %c {$ed}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f2}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$fd}     {SHIFT--}     
  20. %c {$f0}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f1}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$ee}     ^     
  21. %c{$f0}{$f3}Input a line{SHIFT--}     {SHIFT--}     
  22. %c{SHIFT--}{$ed}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f2}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$fd}     {SHIFT--}     
  23. %c^{$f0}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f1}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$ee}  {$f0}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f1}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$ee} 
  24. %c{SHIFT--}{SHIFT--} Is first  {SHIFT--}  {SHIFT--}Execute{SHIFT--} 
  25. %c{SHIFT--}{SHIFT--} character {$eb}NO{$f3}BASIC  {SHIFT--} 
  26. %c{SHIFT--}{SHIFT--} a number? {SHIFT--}  {SHIFT--}command{SHIFT--} 
  27. %c^{$ed}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f2}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$fd}  {$ed}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$fd} 
  28. %c{SHIFT--}     YES                 
  29. %c{SHIFT--}{$f0}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f1}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$ee}
  30. %c{$ed}{$f3}Insert or Delete a line{SHIFT--}
  31. %c {SHIFT--}in the BASIC text area {SHIFT--}
  32. %c {$ed}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$fd}
  33.  
  34.      This flowchart omits much of the detail, but the behaviour illustrated should be familiar to every C64 user.  As you can see, the highest level is an endless loop which waits for the user to enter something, and then either tries to execute what was entered, or inserts or deletes a line from the BASIC program area.  When executing this endless loop BASIC is often referred to as being in 'direct mode.'  That is, the user can type in commands and have them executed directly without the necessity of a program.  This loop is also referred to as the Ready loop since "READY." is printed at the start of the loop.  The Ready loop occurs in the BASIC ROM from address $A474 to $A530 if you wish to study it.  [Editor's Note: "Supermon," which can be found on UpTime Volume One, Number Five, can be used to disassemble and examine any of the routines in the BASIC ROM.]
  35.  
  36.      One of the commands which can be entered in direct mode is the RUN command.  When RUN is executed BASIC enters 'program mode.'  That is, it is running a program.  Below is a flowchart illustrating program execution in BASIC 2.0.
  37.  
  38. %c {$f0}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f1}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$ee}               
  39. %c{$f0}{$f3}Get next byte{SHIFT--}               
  40. %c{SHIFT--}{SHIFT--}from BASIC   {SHIFT--}               
  41. %c{SHIFT--}{$ed}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f2}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$fd}               
  42. %c{SHIFT--}{$f0}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f1}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$ee}     
  43. %c^{SHIFT--}Execute BASIC statement{SHIFT--}     
  44. %c{SHIFT--}{$ed}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f2}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$fd}     
  45. %c{SHIFT--}{$f0}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f1}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$ee}            
  46. %c{SHIFT--}{SHIFT--}Is STOP pressed?{$eb}YES{SHIFT-*}{SHIFT-*}{SHIFT-*}{$ee}     
  47. %c{SHIFT--}{$ed}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f2}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$fd}{$f0}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f1}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$ee}
  48. %c{SHIFT--}      NO          {SHIFT--}Ready loop{SHIFT--}
  49. %c^{$f0}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f1}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$ee}    {$ed}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f2}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$fd}
  50. %c{SHIFT--}{SHIFT--}End of line?{$eb}YES{SHIFT-*}{$ee}     ^     
  51. %c{SHIFT--}{$ed}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f2}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$fd}    {SHIFT--}     {$ed}{SHIFT-*}{SHIFT-*}{$ee}  
  52. %c{SHIFT--}      NO {$f0}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f1}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$ee} ^  
  53. %c{$eb}{SHIFT-*}{SHIFT-*}{SHIFT-*}<{SHIFT-*}{SHIFT-*}{SHIFT-*}{$fd} {SHIFT--}End of program?{$eb}YES 
  54. %c^         {$ed}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f2}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$fd}    
  55. %c{SHIFT--}{$f0}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$ee} NO          
  56. %c{$ed}{$f3}Start next line{$eb}<{$fd}           
  57. %c {$ed}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$fd}             
  58.  
  59.      If you wish to examine the code it is in the BASIC ROM from address $A7AE to $A7EA.  The entry point is $A7E4.  Let's examine how BASIC implements the logic contained in this flowchart by looking at how BASIC goes about executing the below line.
  60.  
  61. %c10 PRINT SQR(66);
  62.  
  63.      First we will examine how BASIC fetches bytes from the BASIC program for the purposes of execution.  BASIC maintains a pointer called TXTPTR ($7A) which points to the address-1 of the next BASIC byte to be executed.  It is part of a special routine BASIC maintains in Zero Page (Memory addresses 0-255) called the CHRGET routine, listed below:
  64.  
  65.  
  66.  
  67.  
  68. %cCHRGET:                             
  69. %c 0073 INC $7A   ;increment pointer  
  70. %c 0075 BNE $0079                     
  71. %c 0077 INC $7B                       
  72. %cCHRGOT:                             
  73. %c 0079 LDA $0805 ;get BASIC byte     
  74. %c 007C CMP #$3A  ;if byte is a-      
  75. %c 007E BCS $008A ; colon then exit   
  76. %c 0080 CMP #$20  ;if byte is a space-
  77. %c 0082 BEQ $0073 ; then get next byte
  78. %c 0084 SEC                           
  79. %c 0085 SBC #$30  ;clear carry if byte
  80. %c 0087 SEC       ; is a decimal digit
  81. %c 0088 SBC #$D0                      
  82. %c 008A RTS                           
  83.  
  84.      JSR $0073, or JSR CHRGET gets the next byte from the BASIC text area.  JSR $0079, or JSR CHRGOT gets the current byte.  The status flags are conditioned in various ways depending on the value of the byte fetched.
  85.  
  86.      The CARRY flag will be cleared if the byte is a decimal digit (value $30 to $39).  BCC will succeed.  The CARRY is set otherwise.
  87.  
  88.      The ZERO flag will be set if the byte is a null (value $00) or a colon (value $3a).  Since BASIC statements are seperated by colons and BASIC lines are terminated by a null, BEQ succeeds when the end of a statement or line is reached.  The ZERO flag is cleared otherwise.
  89.  
  90.      BASIC calls CHRGET once for each byte it must fetch.  For example:
  91.  
  92. %c10 PRINT SQR(66);
  93.  
  94.      To execute this line BASIC would call CHRGET eight times.  First the token for PRINT is fetched, then the token for SQR, and then the characters '(', '6', '6', ')' and ';', each in turn.  Lastly, the zero byte delimiter would be fetched, marking the end of the command.  This consists of eight loops through our program execution flowchart.
  95.  
  96.  
  97.  
  98.  
  99. %c{$f0}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f1}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$ee}
  100. %c{SHIFT--}Execute BASIC statement{SHIFT--}
  101. %c{$ed}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f2}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$fd}
  102.  
  103.      This is the main step in the flowchart and does not reveal the enormous detail involved in executing BASIC statements.  In fact most of the BASIC ROM is dedicated to this step.  Execution results in the square root of 66 being printed to the current output device.
  104.  
  105.  
  106.  
  107. %c{$f0}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f1}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$ee}            
  108. %c{SHIFT--}Is STOP pressed?{$eb}YES{SHIFT-*}{SHIFT-*}{SHIFT-*}{$ee}     
  109. %c{$ed}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f2}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$fd}{$f0}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f1}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$ee}
  110. %c      NO          {SHIFT--}Ready loop{SHIFT--}
  111. %c       {SHIFT--}          {$ed}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f2}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$fd}
  112.  
  113.      The next step is relatively simple.  It checks if the RUN STOP key has been pressed.  If it is pressed the END command is executed and control of the CPU is returned to the Ready loop.  The END command copies TXTPTR to OLDTXT ($3D), and CURLIN ($39), the current BASIC line number, to OLDLIN ($3B).  The CONT command uses OLDTXT and OLDLIN to restart the program where it left off.
  114.  
  115. %c{SHIFT--}       {SHIFT--}          {$f0}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f1}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$ee}
  116. %c{SHIFT--}       {SHIFT--}          {SHIFT--}Ready loop{SHIFT--}
  117. %c^{$f0}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f1}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$ee}    {$ed}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f2}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$fd}
  118. %c{SHIFT--}{SHIFT--}End of line?{$eb}YES{SHIFT-*}{$ee}     ^     
  119. %c{SHIFT--}{$ed}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f2}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$fd}    {SHIFT--}     {$ed}{SHIFT-*}{SHIFT-*}{$ee}  
  120. %c{SHIFT--}      NO {$f0}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f1}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$ee} ^  
  121. %c{$eb}{SHIFT-*}{SHIFT-*}{SHIFT-*}<{SHIFT-*}{SHIFT-*}{SHIFT-*}{$fd} {SHIFT--}End of program?{$eb}YES 
  122. %c^         {$ed}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$f2}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$fd}    
  123. %c{SHIFT--}{$f0}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$ee} NO          
  124. %c{$ed}{$f3}Start next line{$eb}<{$fd}           
  125. %c {$ed}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{SHIFT-*}{$fd}             
  126.  
  127.      This last part of the flowchart determines if the end of the line has been reached by checking if TXTPTR is positioned over a null.  If the end of the line is not reached (this can only happen if the line has multiple statements) TXTPTR must be positioned over a ':' (colon) character, which is the valid statement seperator for BASIC.  Otherwise a SYNTAX ERROR occurs.  Then the statement execution loop begins again at the top of the flowchart.
  128.  
  129.      If the end of a line is reached then BASIC determines if the end of the program has been reached by checking if the high byte of the link field for the next line is zero.  If the end of the program is reached then a JMP is made to the Ready loop.
  130.  
  131.      If the end of a line is reached and it is not the end of the program then the line number of the next line is copied to CURLIN ($39) and 4 is added to TXTPTR so it will point to the start address-1 of the program text for the next line.  Then the statement execution loop begins again at the top of the flowchart.
  132.