home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / program / books / 68k_book / arp_doc / chap_02.doc < prev    next >
Text File  |  1985-11-20  |  87KB  |  2,308 lines

  1.    Atari ST Machine Specific Programming In Assembly
  2.    
  3. Chapter 2: The Editors/Assembler/Debugger
  4.        
  5.  
  6.      My recommendations concerning an assembly language 
  7. programming environment for the Atari ST are based on the 
  8. results of a comparative analysis which are so 
  9. overwhelmingly lopsided that I can present conclusions 
  10. without evidence of those results.  I have used three 
  11. MC68000 assemblers on the Atari ST; and I have concluded 
  12. that AssemPro is the only one worth discussing.  AssemPro, 
  13. written by Peter Schulz in 1986 and produced by Data Becker, 
  14. is distributed by Abacus.  Comparing this superior assembly 
  15. programming package to the others would serve no purpose.  
  16. Abacus products can be purchased from Atari ST dealers, but 
  17. if you can't find what you want, there is an order form in 
  18. the back of the Internals book.  The Abacus phone number is 
  19. (616)698-0330.
  20.  
  21. Establishing a Programming Environment
  22.   
  23.      Your programming environment will be composed of 
  24. computer hardware and software, furniture and ambiance.  If 
  25. you are accustomed to lengthy sessions with a computer, you 
  26. probably know that provisions for anatomical comfort during 
  27. those sessions are prerequisites for success.  Proper 
  28. lighting, comfortable furniture and an appropriate level of 
  29. seclusion create an ambiance that is conducive to 
  30. productivity.  A productive ambient environment can be 
  31. comprised of nothing more than a $45.00 computer desk, a 
  32. $16.00 swivel monitor stand, a $29.00 typing chair, a $9.99 
  33. lamp and the quietest corner of a room.
  34.      Within the computer system environment, appropriate 
  35. computer hardware and software amenities will contribute to 
  36. the proliferation of algorithmic ideas and programming 
  37. statements.  A hard disk drive and/or a second floppy drive 
  38. will permit faster file transfers; as will software designed 
  39. to format floppy disks in a more efficient manner than does 
  40. the ST operating system.  A hardware or software print 
  41. buffer permits one to continue programming while output is 
  42. being routed to the printer.  Additional ram allows the use 
  43. of a ram disk and other software amenities, such as a more 
  44. sophisticated file selector.  A programmer's calculator, a 
  45. hardware or software model, is an asset also.
  46.      I use the Compute! recoverable ram disk (Recoverable 
  47. RAM Disk, Schweitzer, K., Compute!'s Atari ST Disk & 
  48. Magazine, June, 1987).  My RAMDISK.INF file contains the 
  49. information shown in figure 2.1.  This file is stored on the 
  50. C partition of the hard disk.  I usually boot up with 
  51. RAMDISK.PRG in the AUTO folder, which is also on the C 
  52. partition.  A program called AUTOBOOT.PRG, written by Gordon 
  53. Moore, available from ST Informer (909 NW Starlite Place, 
  54. Grants Pass OR 97526) on disk PDM 887 (stored in 
  55. BOOTMAKR.ARC on that disk), makes this possible.  The 
  56. RAMDISK.PRG creates the 400K ram disk and automatically 
  57. loads the indicated files therein.  The magazine article 
  58. explains the usage of the ram disk.  If you understand the 
  59. article, then you should realize, by looking at the 
  60. information file, that I store the AssemPro and TEMPUS 
  61. files, as well as any source programs on which I may be 
  62. working, in a folder named ASSEMPRO on hard disk partition 
  63. D.
  64.  
  65. Figure 2.1. RAMDISK.INF file.
  66.  
  67.             * Configuration file for COMPUTE!'s June 1987
  68.             * recoverable RAM disk.
  69.             *
  70.             SIZE=400K
  71.             DISK=H
  72.             LOAD=D:\ASSEMPRO\ASSEMPRO.INF
  73.             LOAD=D:\ASSEMPRO\ASSEMPRO.PRG
  74.             LOAD=D:\ASSEMPRO\ASSEMPRO.RSC
  75.             LOAD=D:\ASSEMPRO\ASSEMPRO.TAB
  76.             LOAD=D:\ASSEMPRO\TEMPUS.PRG
  77.             LOAD=D:\ASSEMPRO\TEMPUS.INS
  78.             LOAD=D:\ASSEMPRO\PRESERVE.TTP
  79.             LOAD=D:\ASSEMPRO\*.S
  80.      
  81.   
  82.      You may choose to use a smaller ram disk.  With no 
  83. source file in the ram disk, the memory occupied by the 
  84. AssemPro and TEMPUS files is 222,279 bytes.  You must have 
  85. enough additional memory in the ram disk to accommodate your 
  86. source file and its backup, if you choose to have TEMPUS or 
  87. AssemPro back it up.  In addition, there must be room enough 
  88. to accommodate assembled files.  Whenever I work with very 
  89. large source programs, I don't use the ram disk at all; I 
  90. just execute TEMPUS and AssemPro from the hard disk.  But, 
  91. let me warn you about that.  There have been times when 
  92. AssemPro did not replace a file on disk with an updated 
  93. version; instead it stored the updated file with the same 
  94. name as that of the original file.  See figure 2.2A.  I 
  95. don't know whether or not this is caused by a system fault. 
  96.   
  97. Figure 2.2A. Updated and original files with identical 
  98. names.
  99.  
  100.  
  101.  
  102.  
  103.  
  104.  
  105.  
  106.      No specific sequence of events has precipitated the 
  107. incident described.  In trying to pin down the cause of the 
  108. problem, I have found that the severity of the problem 
  109. depends on the presence of certain load and stay resident 
  110. (LSR) programs.  Furthermore, the problem seems to worsen 
  111. with directory depth, and, although files with PRG and S 
  112. extensions are affected, those files with TOS and TTP 
  113. extensions are most often duplicated.  I had never 
  114. experienced this problem with any other ST application until 
  115. I began to use Supra Drive utilities to format my Atari 
  116. SH204 hard disk with 11 partitions.  Then I began to 
  117. experience the same problem with the Tempus editor.  See 
  118. figure 2.2B.
  119.   
  120. Figure 2.2B. Same problem shown in figure 2.2A, but these 
  121. files were saved from the Tempus editor.
  122.  
  123.  
  124.  
  125.  
  126.  
  127.  
  128.   
  129.      For a time, whenever this mishap occurred, if the 
  130. duplicated files were machine code, I simply discarded the 
  131. files and reassembled.  If a source file was involved, I 
  132. examined the files on disk and discarded those that were 
  133. erroneous.  Of course, the best protection against such 
  134. mishaps is backups on floppies.  I back up my files on two 
  135. separate floppies.  Eventually I found a better way to avoid 
  136. the problem.  If the AssemPro editor Back-up copy option, 
  137. under the File menu is selected, each time you attempt to 
  138. save a file that is already present on disk, a dialog box, 
  139. similar to that shown in figure 2.2C appears.  You can 
  140. choose to rename either of the files and avoid the 
  141. duplication problem.  I suggest that you change the 
  142. extension of eldest source files to .DUP because that is the 
  143. backup file extension used by the editor TEMPUS.  I suggest 
  144. that you alter the extension of eldest object files to BAK 
  145. or DIS (for discard).
  146.    
  147. Figure 2.2C. AssemPro dialog box which appears when a file 
  148. to be saved already exists on disk, if the Back-up copy 
  149. editor option is selected.  To avoid the file
  150. duplication problem, backspace over the TOS in the 
  151. extension of the old file and type BAK.  Then press the 
  152. Return key, or click on the OK button.
  153.  
  154.  
  155.  
  156.  
  157.  
  158.  
  159.  
  160.  
  161.  
  162.  
  163.  
  164.  
  165.  
  166.  
  167.  
  168.       
  169.      To avoid the file duplication problem with TEMPUS, you 
  170. can choose the Save with backup option.  When you choose 
  171. that option, TEMPUS automatically alters the extension of 
  172. the eldest file to DUP before it writes the new file to 
  173. disk.  Figure 2.2D shows the appearance of the backup disk 
  174. file icon when that option is used.  Pages 29 and 30 of the 
  175. TEMPUS manual discusses all of the Save options, as well as 
  176. their effects, from which you can choose.
  177.  
  178. Figure 2.2D. Avoiding the file duplication problem with the 
  179. TEMPUS Save with backup option.  The back up file has a DUP 
  180. extension.
  181.  
  182.  
  183.  
  184.  
  185.  
  186.  
  187.  
  188.      I use the Atari SH204 hard disk drive, the star NX-10 
  189. dot matrix printer and the Supra Corporation MicroStuffer 
  190. print buffer.  I have been very pleased with the performance 
  191. of all three items; but I have discovered that my star NX-10 
  192. prints at 68 characters per second in draft pica mode, not 
  193. at the specified 120 characters per second; and I have 
  194. learned that the quick response of a hard disk drive 
  195. degenerates rapidly when there are only four partitions; 
  196. that's why I now use Supra's hard disk utilities to format 
  197. my disk with eleven partitions.
  198.      I also consistently use the Hewlett-Packard HP-16C 
  199. programmer's calculator.  Occasionally I use the 
  200. programmer's calculator that is available from the TEMPUS 
  201. menu.  This type of calculator is required for the many 
  202. hexadecimal computations and number system conversions 
  203. involved in assembly language programming.
  204.      Finally, I have virtually every book and magazine ever 
  205. written in English (or translated thereto) about the ST.  I 
  206. have found that access to convenient tools and references 
  207. tends to keep frustration at a minimum level.  Furthermore, 
  208. even though I make statements about the inadequacies of some 
  209. portions of the references and the software I use, let me 
  210. make this clear: I could not have achieved any level of 
  211. success with the Atari ST without them.  I truly owe all 
  212. that I know to the people that took the time to learn and to 
  213. communicate their knowledge via the many books, magazine 
  214. articles and public domain disks.  Most of all, I owe to 
  215. Peter Schulz, the author of AssemPro, my gratitude for the 
  216. many productive hours I have spent with the ST.  I know that 
  217. I cannot match the efforts of so many, but I'm going to do 
  218. what I can to perpetuate interest in this fine machine.
  219.  
  220. The Editors
  221.   
  222.      I usually write my source programs with the TEMPUS 
  223. editor, then transfer the source to AssemPro for assembly, 
  224. reediting and final assembly.  When the amount of reediting 
  225. to be done is extensive, I go back to TEMPUS.  The number of 
  226. trips back and forth between TEMPUS and AssemPro depends on 
  227. the complexity of the program.  The TEMPUS editor is so much 
  228. faster than the AssemPro editor that any inconvenience 
  229. because of the switching between them is overlooked.
  230.      You will discover the many differences between the two 
  231. editors as you use them.  I only want to point out the less 
  232. obvious.  The AssemPro editor begins counting text on a line 
  233. in column 1; TEMPUS begins counting in column 0.  This is 
  234. the kind of, seemingly, non-critical information that one 
  235. can omit during the daily grind of writing.  In my work, I 
  236. have often found just such an item of information to be the 
  237. crucial key to solving a problem.  When I begin to discuss 
  238. the basepage command line and the manner in which it is 
  239. accessed by AssemPro, you will see just how critical an 
  240. offset of one character position can be.
  241.      The major difficulty I had experienced in switching 
  242. between the two editors is line deletion.  TEMPUS uses 
  243. function key F8; AssemPro uses Alternate - Delete.  
  244. Therefore, I redefined the AssemPro F8 key, according to the 
  245. instructions in section 1.6.1.3 on page 17 of the manual.  
  246. The command to be used in redefining the F8 key to a Delete 
  247. key is listed in the table in section 1.8.6 on page 32.  The 
  248. command of interest is LZ.  Figure 2.3 illustrates the 
  249. appearance of the the Function key redefinition dialog box 
  250. for this operation, just before you press the OK button.
  251.   
  252. Figure 2.3. Redefining the AssemPro F8 function key.  This 
  253. is a compressed representation of the dialog box.
  254.  
  255.  
  256.  
  257.  
  258.  
  259.  
  260.  
  261.  
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268.  
  269.  
  270.  
  271. The TEMPUS Editor
  272.   
  273.      This is an editor!  TEMPUS was written by M. Schuelein 
  274. in 1987.  The only caution I should give concerning the 
  275. TEMPUS editor is this: when I received the editor, the 
  276. single quote key was not functioning, therefore, I had to 
  277. return the disk for corrections.  The distributor, Eidersoft 
  278. USA Inc (P.O. Box 288, Burgettstown, PA 15021), explained 
  279. that the inconvenience was due to the difference between 
  280. European and American keyboards.  I accept that.  If you 
  281. purchase TEMPUS and find that the single quote key does not 
  282. function, you can send the original back to Eidersoft and 
  283. work with your backup disk, using double quotes, until the 
  284. corrected disk returns.  Or you can try the TMPUSFIX.ARC 
  285. file that has been posted to GEnie's ST User's Library as of 
  286. December 12, 1988.
  287.      TEMPUS requires a setup that involves the execution of 
  288. the program PRESERVE.TTP.  You can calculate the value that 
  289. must be entered into the parameter line, also known as (aka) 
  290. the command line, in various ways.  But since it is kind of 
  291. hokey to have to do this, I just usually use 307200.  Then, 
  292. if I don't have enough room in TEMPUS for the source on 
  293. which I am working, I execute PRESERVE.TTP again and enter a 
  294. smaller number on the command line (the value must be some 
  295. multiple of 1024).  The amount of memory assigned to TEMPUS 
  296. is the total amount of memory available minus the value 
  297. entered on the command line.
  298.      The only other complaints that I have concerning the 
  299. TEMPUS editor involves its custom file selector.  In the 
  300. first place, it displays only 7 disk buttons, enough for 
  301. floppies A and B and hard disk partitions C through G; it 
  302. should display enough for all possible hard disk partitions.  
  303. In the second place, TEMPUS does not allow one a choice 
  304. between one's standard file selector and its custom 
  305. selector; therefore, I cannot use the Universal Item 
  306. Selector; and furthermore, TEMPUS clashes with the operation 
  307. of the Universal Item Selector when it is being used as a 
  308. desk accessory.  These TEMPUS flaws are serious.  I hope 
  309. that someone will fix them soon, or I shall be forced to do 
  310. it myself.
  311.  
  312. The AssemPro Editor
  313.   
  314.      The first thing I want to mention is the error on pages 
  315. 7, 52, 119 and 130 of my AssemPro manual, and, unless 
  316. someone has corrected the documentation, it will be in your 
  317. manual also.  On those pages, reference to a menu called 
  318. Help is made.  This item actually appears as Table on the 
  319. menu line.  If necessary, make corrections to your 
  320. documentation, then execute ASSEMPRO.PRG.  With the 
  321. assembler window activated, (See pages 5 and 6 of the 
  322. AssemPro manual.  The assembler window is activated by 
  323. moving the mouse arrow to the assembler window and clicking 
  324. the left mouse button; the editor window is activated by 
  325. moving the arrow to the editor window and clicking.), move 
  326. the mouse arrow to the Assembler menu.  Now, activate the 
  327. following options, and only the following options, by 
  328. clicking on them (some may already be activated):
  329.  
  330.                  * Optimize backward Bcc's
  331.                  * Flag undef. variables
  332.                  * PC-relative
  333.                  * Original line
  334.   
  335.      When you are done, there should be four check-marks, 
  336. one for each of the options selected.  Refer to figure 2.4A.  
  337. All of the options are discussed in the AssemPro manual, and 
  338. I will be discussing each as its usage becomes appropriate.  
  339. The PC-relative and Relocatable assembly modes will be 
  340. discussed and compared in the next chapter, along with the 
  341. pc-relative addressing mode.  For now, if any other items 
  342. are checked, deactivate them.  Next, click on the Search 
  343. menu and deactivate the Replace selection if it is checked.
  344.  
  345. Figure 2.4A. Setting Assembler and Search Options
  346.          
  347.  
  348.  
  349.  
  350.  
  351.  
  352.  
  353.  
  354.  
  355.  
  356.  
  357.  
  358.  
  359.  
  360.  
  361.  
  362.  
  363.  
  364.  
  365.  
  366.  
  367.  
  368.  
  369.  
  370.  
  371.  
  372.  
  373.      Next, activate the Editor window and the Editor menu.  
  374. Click on the Function keys option; when the dialog box 
  375. appears, click on the F8 key button.  On the first line 
  376. under the label Program :, type LZ; on the line under the 
  377. label Explanation : type the following, or something 
  378. similar: Delete Line.  Then click on the OK box.  Refer to 
  379. figure 2.3.
  380.      Now, activate the File menu and click on the Back-up 
  381. copy option.  See figure 2.4B.  Activate the File menu 
  382. option again and click on the Save defaults option.  All of 
  383. the options you have selected will be saved in the 
  384. ASSEMPRO.INF file.  If you are working from a RAM disk, 
  385. leave AssemPro with the Quit option under the File menu and 
  386. copy the ASSEMPRO.INF file to the disk or partition on which 
  387. ASSEMPRO.PRG resides.  Thereafter, whenever you execute the 
  388. ASSEMPRO.PRG, your options will be read in from the INF file 
  389. and set automatically.
  390.  
  391. Figure 2.4B. Setting the File option.
  392.  
  393.  
  394.  
  395.  
  396.  
  397.  
  398.  
  399.  
  400.  
  401.  
  402.  
  403.  
  404.  
  405.  
  406.  
  407.  
  408.  
  409.  
  410.  
  411.  
  412.  
  413.  
  414.  
  415.  
  416.      As you receive the AssemPro package, each of the 
  417. function keys will most likely be assigned a default 
  418. program.  Redefining the F8 key to function as a Delete Line 
  419. key will hasten your adaptation to the switches from TEMPUS 
  420. to AssemPro and back. You can explore other key 
  421. reassignments to suit your taste.  In my version of 
  422. AssemPro, the function keys had been assigned the following 
  423. default functions:
  424.  
  425.                  F1 = BA = Mark blockstart
  426.                  F2 = BE = Mark blockend
  427.                  F3 = BV = Move block
  428.                  F4 = BK = Copy block
  429.                  F5 = BL = Delete block
  430.                  F6 = BD = Unmark block
  431.   
  432.      Functions defined with unprintable characters were 
  433. assigned to the F7, F8, F9 and F10 function keys.  You can 
  434. view those assignments by selecting the Function keys menu 
  435. option and by clicking the appropriate function key button 
  436. in the dialog box.  The program assigned to function key F10 
  437. is of special interest, only because it brings up the idea 
  438. of converting files prepared by resource construction sets 
  439. for use in assembly language programs.  I will return to 
  440. this subject in an appropriate, later chapter, however, I 
  441. want to point out here that the *.I file discussed on page 
  442. 34 of the AssemPro manual would be a *.H file for some 
  443. construction sets.  Furthermore, since the layout of such 
  444. files varies with the particular construction set used, the 
  445. default program assigned to F10 is not compatible with all 
  446. resource construction sets.
  447.  
  448. The Editor's Search Function
  449.   
  450.      AssemPro has two Search functions; one for the editor; 
  451. one for the debugger.  The editor's Search function, 
  452. discussed on page 18 of the manual, is particularly 
  453. inconvenient.  Using this function requires two, sometimes 
  454. three, trips to the Search menu.  First you must select the 
  455. For what ? option and define the search criteria in the 
  456. dialog box (see figure 2.5).  Then you must deactivate the 
  457. Replace selection if it is activated (Don't forget to do 
  458. this if you are only searching, not replacing.)  Finally, 
  459. you must click on the appropriate Search direction option 
  460. (see figure 2.4A).  Of course, the Replace function is 
  461. equally inconvenient.
  462.      The Search/Replace function has one more annoying 
  463. attribute.  When executing multiple replaces (enabled with 
  464. the all button), even though it has successfully completed 
  465. any number of them, it will end the event with the Not 
  466. found!, Sorry alert box, therefore, you must manually search 
  467. the file to determine whether or not the Replace operation 
  468. was successful.
  469.   
  470. Figure 2.5. The Editor's Search/Replace Dialog Box; a 
  471. slightly compressed representation.
  472.  
  473.  
  474.  
  475.  
  476.  
  477.  
  478.  
  479.  
  480.  
  481.  
  482.  
  483.  
  484.  
  485.  
  486. The First Program
  487.   
  488.      Before we begin to look at the debugger, we should 
  489. discuss and prepare a program.  I have stated that the 
  490. minimum amount of code necessary is a primary requirement of 
  491. any example program that I choose to discuss.  In order to 
  492. fulfill my desire to begin with the rudimentary, it seems 
  493. reasonable to attempt to construct the first program from a 
  494. single statement.  Consider the one statement which must 
  495. appear in every assembly language source program, the 
  496. instruction end.  However necessary it may be to every 
  497. program, end is not an instruction for the MC68000 
  498. processor; it is an instruction for the assembler.  This 
  499. instruction produces no executable code.  End belongs to a 
  500. group of such instructions called assembler directives, 
  501. pseudo-ops, or by any other name that differentiates them 
  502. from processor instructions.
  503.      Furthermore, because every program executed on the ST 
  504. must prohibit execution beyond its boundaries, the task of 
  505. declaring which instruction or function constitutes the most 
  506. rudimentary possible is preempted by necessity.  The single 
  507. executable algorithm that represents a minimum ST program is 
  508. the GEMDOS function number $0, which is one of many system 
  509. functions designed to transfer processor control.  
  510. Identified by various names such as p_term_old,  term or 
  511. terminate, this function causes processor control to be 
  512. transferred to the program that invoked the program which is 
  513. executing p_term_old.  Normally, the final goal of every 
  514. user program should be the return of control to the 
  515. operating system, but there times when control is returned 
  516. to another user program instead.
  517.      Referring back to the name of GEMDOS function $0, at 
  518. times the names given to ST operating system functions may 
  519. seem strange.  Actually, I am being facetious; the 
  520. names will seem to be totally undescriptive of the function 
  521. being performed most of the time.  I use the names that are 
  522. commonly seen in the references so that I can match them up, 
  523. but I always try to add my own descriptive label.  You will 
  524. find that I tend to use labels such as the following:
  525.  
  526. this_label_attempts_to_completely_describe_the_algorithm_below:.
  527.   
  528.      In addition to serving as the example for a short 
  529. tutorial on the AssemPro debugger, the first program will 
  530. help me to simultaneously illustrate several concepts 
  531. involving the relative execution speed and memory 
  532. requirements of similar processor instructions.  At the 
  533. conclusion of the discussion, the first program, the 
  534. concepts and a program that justifies their relevance will 
  535. be convincingly juxtapositioned (unless I screw it up in the 
  536. telling).
  537.   
  538. Program 1. A minimum ST program.
  539.   
  540.  ; Program Name: PRG_1AP.S
  541.  ;      Version: 1.001
  542.  
  543.  ; Assembly Instructions:
  544.  
  545.  ;    1. Assemble in AssemPro PC-relative mode and save the assembled
  546.  ;       program with a PRG extension, then save it with a TOS extension.
  547.  
  548.  ;    2. Click on the PC-relative option under the Assembler menu to activate
  549.  ;       the Absolute assembly mode.  The Absolute mode is active when there
  550.  ;       is no check mark in front of the PC-relative option and no check mark
  551.  ;       in front of the Relocatable option.  Change the name of the source
  552.  ;       file to PRG_1AA.  Do this by clicking on the File option under the
  553.  ;       File menu and, in the dialog box that appears, backspace over the
  554.  ;       letter P and type an A.  Do not save the new source file, but
  555.  ;       assemble it and save the assembled program with a PRG extension,
  556.  ;       then save it with a TOS extension.
  557.  
  558.  ;    3. Click on the Relocatable option under the Assembler menu.
  559.  ;       Change the name of the source file to PRG_1AR.  Do not save the
  560.  ;       source file, but assemble in the Relocatable mode and save with
  561.  ;       PRG and TOS extensions.
  562.  
  563.  ; Program Function:
  564.  
  565.  ;    This program invokes a single GEMDOS function.  That function performs
  566.  ; three services.  It relinquishes processor control, prohibits execution
  567.  ; beyond the program's upper boundary and removes the program from ram.
  568.  
  569.  ; Program Purpose:
  570.  
  571.  ;    To introduce the smallest possible ST program.  Every ST program must
  572.  ; accomplish at least two functions.  It must relinquish processor control,
  573.  ; and it must prevent execution beyond its boundaries.  Processor control
  574.  ; must be relinquished at some time during the life of each program, if for
  575.  ; no other reason, then because all programs must eventually finish the
  576.  ; task for which they were invoked.  Without some sort of demarcating code
  577.  ; within an executing program, the processor will continue to try to execute
  578.  ; whatever is in memory, until a fatal error eventually occurs. 
  579.  
  580.  ;    GEMDOS function $0, also known as (aka) p_term_old, term or terminate,
  581.  ; may be invoked to perform these two functions.  But, in addition, this
  582.  ; function also removes the program from memory.   
  583.  
  584.  ;    When GEMDOS $0 is invoked, processor control is returned to the 
  585.  ; agent that initiated the execution of the program that is now invoking
  586.  ; GEMDOS $0.  That agent may be the Desktop or some other program.
  587.  
  588.  ;    An additional purpose of this exercise is to compare the sizes of
  589.  ; the code files produced by the three assembly modes.  Furthermore, if
  590.  ; you are able to carefully observe the length of time it takes to execute
  591.  ; each type of program, where the mode of assembly indicates "type", you
  592.  ; will see that the time required to execute the Relocatable types is longer
  593.  ; than the time required to execute the other types.
  594.  
  595. terminate:                       ; My descriptive label.
  596.  move.w    #0, -(sp)             ; Function = p_term_old = GEMDOS $0.
  597.  trap      #1                    ; GEMDOS call.
  598.  end                             ; Assembler pseudo-op.
  599.  
  600.  
  601.      Upon invocation, p_term_old performs three functions.  
  602. It prohibits execution beyond the boundaries of the program; 
  603. it removes this program from ram; and it returns processor 
  604. control back to the program that invoked this one, which in 
  605. this case is the system program Desktop.  Without some sort 
  606. of termination code within an executing program, the 
  607. processor would continue to execute instructions until a 
  608. fatal error occurred.  I use the phrase termination code to 
  609. refer to code which sets an execution boundary, I do not use 
  610. it to connote execution termination.  I make this 
  611. distinction because both phenomena coincidentally occur when 
  612. the p_term_old function is used, however, these phenomena 
  613. are not mutually inclusive.
  614.      You should type program 1 into the AssemPro editor, 
  615. with or without the comments, and assemble it at this time.  
  616. Before you type the file into the the editor, name it by 
  617. clicking on the File : option under the File menu, then by 
  618. entering PRG_1AP on the parameter line of the dialog box 
  619. which subsequently appears.  If you have not yet read the 
  620. portion of the manual that describes assembling, the 
  621. following few sentences should contain enough information to 
  622. insure success.  Assemble PRG_1AP by activating the 
  623. assembler window, then the Assembler menu, and finally, by 
  624. clicking on the Assembling selection.  Now, save the source 
  625. file by clicking on the Save option under the File menu, and 
  626. by clicking on the S button in the dialog box after it 
  627. appears.  Next, save the object file by clicking on the TOS 
  628. button, after you activate the dialog box a second time.
  629.      Unfortunately, however routine it may be to save both 
  630. files, the saves must be done individually.  Finally, save 
  631. the object file again, but, this time, click on the PRG 
  632. button, after you activate the dialog box a third time.  For 
  633. each save that you perform, the filename extension button 
  634. that you choose tells AssemPro to affix that extension to 
  635. the basic filename before writing the file to disk.  Figure 
  636. 2.6 is a picture of the Save dialog box with the name of the 
  637. program typed therein.
  638.   
  639. Figure 2.6. The dialog box used to save files.
  640.  
  641.  
  642.  
  643.  
  644.  
  645.  
  646.  
  647.  
  648.  
  649.  
  650.  
  651.  
  652.  
  653.   Click on the File : option under the File menu and change 
  654. the file name to PRG_1AA.  There is no reason to save this 
  655. source file.  Click on the PC-relative option under the 
  656. Assembler menu to active the Absolute assembly mode; the 
  657. Absolute mode is active when there is neither a check in 
  658. front of the PC-relative option, nor in front of the 
  659. Relocatable option.  Assemble this new source and save the 
  660. object code with TOS and PRG extensions.  Finally, change 
  661. the file name to PRG_1AR and click on the Relocatable option 
  662. under the Assembler menu to activate the Relocatable 
  663. assembly mode.  Do not save the source file, but assemble 
  664. and save the object code with TOS and PRG extensions.  
  665. Comparisons between the size of each of the six assembled 
  666. programs and their execution speeds will be accomplished 
  667. shortly.
  668.      Although it may not be obvious, there are algorithmic 
  669. choices to be made for even so elementary a program as 
  670. PRG_1AP.  Only two requirements are necessary for successful 
  671. execution of the function.  The number of the function, $0, 
  672. must be pushed onto the stack, and a trap #1 call must be 
  673. invoked.  No choices are available as far as the trap 
  674. instruction is concerned (at this elementary stage).  It 
  675. must appear as shown.  However, there is more than one way 
  676. to push the $0 onto the stack.  Table 2.1 lists three 
  677. algorithms that accomplish the task.  The number of clock 
  678. periods and memory requirements for each are indicated.  For 
  679. this table, the clock periods were calculated from 
  680. information in appropriate charts provided in the Motorola 
  681. M68000 Programmer's Reference Manual, fifth edition.
  682.   
  683. Table 2.1. Three ways to store 0 on the stack.  Comparison 
  684. of the execution speed and memory requirements of three ways 
  685. to push zero onto the stack.  Although -(sp) is used as the 
  686. destination operand in the table, the data applies to any
  687. -(An).
  688.  
  689.  
  690.  
  691.  
  692.  
  693.  
  694.  
  695.  
  696.  
  697.  
  698.  
  699.  
  700.  
  701.  
  702.      
  703.      Instruction execution time is measured in clock 
  704. periods; memory requirement is measured in bytes.  The 
  705. method used to calculate the execution times as they are 
  706. shown in table 2.1 is discussed in a later chapter.  In 
  707. addition, I shall present programs that accomplish the task, 
  708. in the sense that relative execution speeds are calculated, 
  709. with much less bother and with precision that is tied to the 
  710. ST's operating system and internal hardware.
  711.      The data in the table illustrate the classic speed 
  712. versus memory requirement tradeoff so often discussed in 
  713. computer literature.  To wit: if we are willing to sacrifice 
  714. 2 more bytes of memory, we can take advantage of the faster 
  715. execution speed exhibited by either of the second or the 
  716. third algorithm.  Of course, in PRG_1AP there is only a 
  717. single incident of the algorithm involved, therefore, one 
  718. might think that it doesn't matter which of the three 
  719. algorithms is used.  I insist that the choice should be made 
  720. deliberately.  If a conscious effort is being made to 
  721. sacrifice speed for conservation of memory, then the first 
  722. algorithm should be chosen, otherwise one of the others 
  723. should be used, because I prefer that the default 
  724. consideration always be speed.  Let me illustrate how much 
  725. just one casual choice costs in overall machine performance.
  726.      The ST has an 8mhz clock.  Each clock period is 1.25 X 
  727. 10-7 seconds.  The 14 clock period instruction takes 14 X 
  728. 1.25 X 10-7 = 1.75 X 10-6 seconds = 1.75 microseconds.  
  729. Neglecting any extraneous delays, in one second, the ST can 
  730. execute 1,000,000 / 1.75 = 571,428 instructions of this 
  731. type.  An instruction that requires 12 clock periods takes 
  732. 1.5 microseconds.  Neglecting extraneous delays again, in 
  733. one second, the ST can execute 666,666 instructions of this 
  734. type.  By choosing the instruction that requires 14 clock 
  735. periods, we lose an execution capability of 666,666 - 
  736. 571,428 = 95,238 instructions per second.
  737.      When you start doing things such as moving zeroes into 
  738. 32000 bytes of memory to clear a video screen or two every 
  739. so often in a program, such loses begin to pile up and 
  740. performance becomes unsatisfactory.  The insidious thing 
  741. about choosing unconsciously is that it becomes a habit.  By 
  742. habitually using slower, albeit more familiar, instructions 
  743. we risk using them as the worst choice for an algorithm in 
  744. which we are trying to emphasize speed.
  745.  
  746. Executing Program 1 From the Desktop
  747.   
  748.      Exit AssemPro by clicking on the Quit option under the 
  749. File menu.  Then execute PRG_1AA.PRG from the desktop.  The 
  750. operating system will briefy display a gray screen (assuming 
  751. a monochrome monitor) with the program name at the top and a 
  752. busy bee cursor.  Now, execute PRG_1AA.TOS.  The operating 
  753. system will briefly display a blank white screen with a 
  754. black, blinking cursor in the upper left hand corner of the 
  755. screen.  The difference in screens occurs because programs 
  756. with a PRG extension are expected to use windows, while 
  757. those with a TOS extension are expected to be keyboard 
  758. driven.
  759.      The quickest way to understand the difference is to 
  760. change the extension of a program that uses windows, such as 
  761. a word processor, from PRG to TOS and execute it.  There 
  762. will be no mouse activity, so you will not be able to make 
  763. any selections.  The only way out will be to reset the 
  764. computer with the reset switch.  On the other hand, if you 
  765. alter the suffix of a TOS program to PRG and execute, the 
  766. mouse pointer will be present, but the cursor will be 
  767. absent.  And, of course, the screen will not be clear.
  768.      The PRG_1AA programs were assembled using AssemPro's 
  769. Absolute mode.  Execute PRG_1AP.PRG and PRG_1AP.TOS from the 
  770. desktop also.  These programs were assembled using 
  771. AssemPro's PC-relative mode.  The behavior of these programs 
  772. will be identical to that of the programs which were 
  773. assembled using the Absolute mode.
  774.      Now execute PRG_1AR.PRG and PRG_1AR.TOS.  The same 
  775. types of screens will appear, but they will remain longer 
  776. than they did when the PRG_1AA and PRG_1AP programs were 
  777. executed.  The time differential, as well as the reason it 
  778. exists, will be explored in the next chapter.  For now, I 
  779. just want you to observe that the difference is noticeable.
  780.      To observe another difference in the way the operating 
  781. system processes these programs, click on PRG_1AA.PRG, then 
  782. click on the Show Info option under the File menu.  Note the 
  783. file size in bytes.  Do this for each of the other five 
  784. files.  You will see that the Absolute and PC-relative files 
  785. consume 34 bytes of disk space, while the Relocatable files 
  786. consume 42 bytes.  To my knowledge, the only reference that 
  787. explains the 8-bytes difference (two longwords) is the 
  788. AssemPro manual, on page 80.  These 8 bytes contain 
  789. information for the relocator.  However, in the next chapter 
  790. we will see that this 8-byte differential is just the 
  791. minimum size difference incurred by a program assembled in 
  792. the Relocatable mode.
  793.  
  794. An Executable File's Disk Image
  795.   
  796.      Each executable ST file has a distinctive header which 
  797. identifies it as such.  An executable file's header (and the 
  798. entire file) can be examined using a utility such as The 
  799. Disk Doctor, copyright 1985, 1986 by Daniel Matejka, or File 
  800. Viewer, by Richard Smereka, COMPUTE!'s Atari ST, August 
  801. 1987.  A disk image for the file with the PRG extension from 
  802. each of the three assembled sets is shown in file 2.1.  The 
  803. file header extends from word $0 of the file through word 
  804. $1B.  Of particular interest during this discussion is the 
  805. word at location $1A.  If this word is $0000, then the file 
  806. has been assembled in AssemPro's Relocatable mode, otherwise 
  807. the file has been assembled in one of the other two modes.  
  808. When a program is loaded into ram, the ST's relocator will 
  809. adjust addresses as necessary, if this word is $0000, as 
  810. explained on page 79 of the AssemPro manual.  It is this 
  811. extra step which is partly responsible for the increase in 
  812. execution time that is experienced when a Relocatable 
  813. program is executed.  If the overall execution time is 
  814. divided into two parts, one of which is a loading time 
  815. component, then the relocation step clearly adds to this 
  816. component.
  817.  
  818. File 2.1.  A hex dump of programs PRG_1AA.PRG, PRG_1AP.PRG 
  819. and PRG_1AR.PRG.  The disk images of the three executable 
  820. files are shown.
  821.  
  822. PRG_1AY.DMP
  823.  
  824. Hex dump of programs PRG_1AA.PRG, PRG_1AP.PRG and PRG_1AR.PRG.
  825.  
  826.      The first word of each of the three files is a branch instruction.
  827. The branch is to the location that is the sum of the 8-bit displacement,
  828. 1A, plus 2: that is, to location 1C.  In each file that location is marked
  829. as "start of text segment".
  830.  
  831.      The word immediately preceding the "start of text segment" marks the
  832. program as relocatable if the word is $0000.  In files that are assembled in
  833. AssemPro's Absolute and PC-relative modes, this word will be $FFFF.
  834.  
  835.      The longword beginning at location $02 is the size of the text segment;
  836. for each of the three programs the size of the text segment is 6 bytes.  The
  837. longword beginning at location $06 is the size of the data segment, which is
  838. zero for the three programs.  The longword beginning at location $0A is the
  839. size of the BSS segment, which is zero for the three programs.
  840.  
  841.      Note that the size of the relocatable program, PRG_1AR.PRG, is 42 bytes,
  842. eight bytes longer than the size of the other two programs.
  843.  
  844.  
  845.  ADDRESSES          CONTENTS OF FILE PRG_1AA.PRG
  846.  FROM   TO
  847. 00000 00000F   601A 0000 0006 0000 0000 0000 0000 0000
  848. 00010 00001F   0000 0000 0000 0000 0000 FFFF 3F3C 0000
  849. 00020 000021   4E41                          ^start of text         
  850.                                               segment
  851.  
  852.                     CONTENTS OF FILE PRG_1AP.PRG
  853.  
  854. 00000 00000F   601A 0000 0006 0000 0000 0000 0000 0000
  855. 00010 00001F   0000 0000 0000 0000 0000 FFFF 3F3C 0000
  856. 00020 000021   4E41                          ^start of text         
  857.                                               segment
  858.  
  859.                     CONTENTS OF FILE PRG_1AR.PRG
  860.  
  861. 00000 00000F   601A 0000 0006 0000 0000 0000 0000 0000
  862. 00010 00001F   0000 0000 0000 0000 0000 0000 3F3C 0000
  863. 00020 000029   4E41 0000 0000 0000 0000      ^start of text         
  864.                                               segment
  865.  
  866. The AssemPro Debugger
  867.   
  868.      To prepare for this discussion, load PRG_1AP.S in the 
  869. editor by clicking on the Load option under the File menu, 
  870. then by clicking on the S button when the dialog box 
  871. appears.  The file selector will appear after you click the 
  872. S button.  After the source is loaded into the editor, 
  873. assemble it using either the PC-relative mode or the 
  874. Relocatable mode.
  875.      Now, activate the debugger by clicking on the Debugger 
  876. option under the Debugger menu.  When the debugger screen 
  877. appears, if the program was assembled with the Relocatable 
  878. option checked, click on the relocate button.  You will be 
  879. able to see the two statements of the program in the output 
  880. field of the debugger window.  The output field is 
  881. displaying memory in normal disassembled mnemonic format.  
  882. See figure 2.7.  In this format, memory addresses are 
  883. followed by their content in both hexadecimal digits and, 
  884. where possible, the assembly language translation of those 
  885. digits.  In this figure, and in all future figures and 
  886. discussions, the memory addresses that you will see in your 
  887. debugger window will most likely never match those of mine, 
  888. except when we are both viewing locations assigned to the 
  889. system.  That is so because the addresses we see depend on 
  890. the desk accessories and other load and stay resident 
  891. programs we have previously loaded into ram.
  892.  
  893. Figure 2.7. Normal disassembled mnemonic format.
  894.   
  895.  
  896.  
  897.  
  898.  
  899.  
  900.  
  901.  
  902.  
  903.  
  904.  
  905.  
  906.  
  907.  
  908.  
  909.  
  910.  
  911.  
  912.  
  913.  
  914.  
  915.  
  916.  
  917.  
  918.  
  919.  
  920.  
  921.  
  922.  
  923.  
  924.  
  925.      Note the appearance of the program statements, then 
  926. click on the symbolic button.  The output field now displays 
  927. the TERMINATE: label also.  Refer to figure 2.8.  This 
  928. display, called the symbolic disassembled mnemonic format, 
  929. eliminates the hexadecimal representation of instructions 
  930. after the addresses.
  931.  
  932. Figure 2.8. Symbolic disassembled mnemonic format.
  933.  
  934.  
  935.  
  936.  
  937.  
  938.  
  939.  
  940.  
  941.  
  942.  
  943.  
  944.  
  945.  
  946.  
  947.  
  948.  
  949.  
  950.  
  951.  
  952.  
  953.  
  954.  
  955.  
  956.  
  957.  
  958.  
  959.  
  960.  
  961.  
  962.  
  963.  
  964.      Displaying the source text labels in the debugger 
  965. output field is one of AssemPro's most prominent features.  
  966. You enable this option by doing two things, if the program 
  967. is assembled in PC-relative mode, three things if it is 
  968. assembled in Relocatable mode.  First you must load the 
  969. source code into the editor and assemble it (of course, if 
  970. you create the source code as new text, loading it is not 
  971. necessary).  If the program is assembled in the Relocatable 
  972. mode, you must click on the relocate button in the debugger 
  973. window.  Then you must click on the symbolic button in the 
  974. debugger window.
  975.      The dark line that you see in the output field is the 
  976. program counter cursor; therefore, it indicates the next 
  977. instruction to be executed, if execution is to take place.  
  978. The address that you see in the output field for the first 
  979. instruction of the program will depend on the exact 
  980. configuration of your machine.  In any case, the address 
  981. that you see for the second instruction will be the address 
  982. of the first instruction plus four.  The memory occupied by 
  983. the first instruction is the address of the second 
  984. instruction minus the address of the first instruction, that 
  985. is, four bytes.  You should be able to deduce the memory 
  986. occupied by the second instruction; it is two bytes.
  987.      Click on the disassembled button; the state of the 
  988. symbolic button is of no consequence.  The output field will 
  989. display memory in the hexadecimal/ASCII dump format.  See 
  990. figure 2.9.  In this format, you can view the content of 
  991. memory in hexadecimal digits, and, if any sequence of those 
  992. digits forms a valid ASCII string, you will be able to 
  993. observe that string.  The most significant feature available 
  994. via this format (aside from viewing data in ASCII) is the 
  995. ability to directly alter the content of memory.  Refer to 
  996. page 85 of the AssemPro manual.  This feature will be 
  997. explored, in detail, in a later chapter.
  998.   
  999. Figure 2.9. Hexadecimal/ASCII Dump Format.  In this mode, 
  1000. the symbolic button has no effect of the display.
  1001.  
  1002.  
  1003.  
  1004.  
  1005.  
  1006.  
  1007.  
  1008.  
  1009.  
  1010.  
  1011.  
  1012.  
  1013.  
  1014.  
  1015.  
  1016.  
  1017.  
  1018.  
  1019.  
  1020.  
  1021.  
  1022.  
  1023.  
  1024.  
  1025.  
  1026.  
  1027.  
  1028.  
  1029.  
  1030.  
  1031.  
  1032.      Click on the disassembled button to return to a 
  1033. mnemonic formatted output field, then click on the Execute 
  1034. program button; it is located just above the => erase button 
  1035. (called => delete in the AssemPro manual), which is located 
  1036. just above the relocate button.  Clicking the Execute 
  1037. program button will not execute the program.  In the dialog 
  1038. box that appears, click on the OK button.  Refer to figure 
  1039. 2.10.  You will be presented with the file selector box; 
  1040. choose PRG_1AP.PRG or PRG_1AR.PRG, one of the assembled 
  1041. files previously saved.
  1042.   
  1043.      A Special Note: To remove a program from memory, 
  1044.      after it has been loaded with the Execute program 
  1045.      button, click on the => erase button while pressing 
  1046.      the Control key on the keyboard.
  1047.  
  1048.  
  1049. Figure 2.10. The Execute program dialog box; a slightly 
  1050. compressed representation.
  1051.   
  1052.  
  1053.  
  1054.  
  1055.  
  1056.  
  1057.  
  1058.  
  1059.  
  1060.  
  1061.  
  1062.  
  1063.  
  1064.  
  1065.  
  1066.  
  1067.  
  1068.      AssemPro will load in the object code for the program 
  1069. and you will be able to see the program's two instructions 
  1070. in the output field again.  Activate the symbolic button, if 
  1071. it has been deactivated; in this mode, the label TERMINATE: 
  1072. can't be seen in the output field.  When you load a program 
  1073. into memory using the Execute program button, AssemPro knows 
  1074. nothing about labels in the source code.  It is only when a 
  1075. program has just been assembled that such information is 
  1076. available to the debugger.
  1077.      There are two memory configuration differences existing 
  1078. between this object code and that which you had been 
  1079. viewing; this object code has a basepage (See pages 145 and 
  1080. 146 of the Internals book.), the other did not.  Any program 
  1081. that is in debugger memory because it has just been 
  1082. assembled does not have a basepage.  The significance of the 
  1083. distinction is this: if the basepage is not present, then 
  1084. you will not be able to execute instructions which depend on 
  1085. information stored in the basepage.
  1086.      In addition, this program has claimed all of available 
  1087. memory for its own use.  You can verify this by clicking on 
  1088. the box in the upper left corner of the debugger screen to 
  1089. get back to the Assemble/Edit screens.  There you will see 
  1090. that there are only 50 bytes of available memory.  The rest 
  1091. of it is being consumed by PRG_1AP.  These important 
  1092. distinctions will be explored later, when I discuss the 
  1093. function which returns excess memory back to the operating 
  1094. system.
  1095.  
  1096. Executing the Program
  1097.   
  1098.      As you can see, there are many other debugger options 
  1099. present.  We will cover them all in time.  For now, you can 
  1100. simply execute the program by clicking on the Run program 
  1101. option.  After the program has executed, address $000000 
  1102. appears in the output field as the next instruction to be 
  1103. executed.  See figure 2.11.  Another alteration of interest 
  1104. has also taken place.  Observe the ten status register bits 
  1105. that are shown as buttons under the label Statusregister, 
  1106. just to the left of the second output field instruction 
  1107. line.
  1108.   
  1109. Figure 2.11. Output field and status register after 
  1110. executing program 1.
  1111.  
  1112.  
  1113.  
  1114.  
  1115.  
  1116.  
  1117.  
  1118.  
  1119.  
  1120.  
  1121.  
  1122.  
  1123.  
  1124.  
  1125.  
  1126.  
  1127.  
  1128.  
  1129.  
  1130.  
  1131.  
  1132.  
  1133.  
  1134.  
  1135.  
  1136.  
  1137.  
  1138.  
  1139.  
  1140.  
  1141.      There you will see that three of the status register 
  1142. bits have been set (the S bit and two bits of the interrupt 
  1143. mask), apparent because of their dark color (reverse video).  
  1144. The new state of these bits will not interfere with the 
  1145. repeated execution of this program, however, their state 
  1146. could be a matter of importance, of which we are unaware, to 
  1147. AssemPro.  Furthermore, such a change in the status register 
  1148. bits could have drastic effects on a program that utilized 
  1149. the state of those bits.  Therefore, it is a good idea to 
  1150. put things back in order whenever we can, so reset those 
  1151. bits by clicking on them.  The reset condition of a bit is 
  1152. indicated by a white color in the bit button.
  1153.      In addition to the changes in the microprocessor status 
  1154. register caused by a program's execution, there are 
  1155. alterations in data register and address register contents.  
  1156. Figure 2.12 illustrates typical alterations.  You can look 
  1157. at the register field of your debugger screen to view 
  1158. similar changes.
  1159.   
  1160. Figure 2.12. Changes in register content after program  
  1161. execution.
  1162.  
  1163.  
  1164.  
  1165.  
  1166.  
  1167.  
  1168.  
  1169.  
  1170.  
  1171.  
  1172.  
  1173.  
  1174.  
  1175.  
  1176.  
  1177.  
  1178.  
  1179.  
  1180.  
  1181.  
  1182.  
  1183.  
  1184.  
  1185.  
  1186.  
  1187.  
  1188.  
  1189.  
  1190.  
  1191.  
  1192.  
  1193.      Now look to the top right corner of the debugger 
  1194. screen.  There you see the label Program start :, followed 
  1195. by a hexadecimal number.  That number is the starting memory 
  1196. address of the your program.  At the moment, the PC (program 
  1197. counter) cursor is located at memory location $000000.  If 
  1198. you were to click on the Run program button now, you would 
  1199. be greeted by a warning box, telling you that a Bus error 
  1200. has occurred at address 000000.  When this type of error 
  1201. occurs, it is sometimes possible to get back to the debugger 
  1202. by clicking on the Debugger button in the warning box.  
  1203. Sometimes you will simply get another warning box, or the 
  1204. system may freeze.  The only way to be sure that everything 
  1205. is as it should be after a Bus error is to reset the machine 
  1206. by pressing the reset button, holding it for at least 10 
  1207. seconds.
  1208.      To execute the program again, you must, as step one of 
  1209. two steps, get the first executable instruction of your 
  1210. program back in the debugger output field (This is not 
  1211. always the first instruction of the program.).  To do this, 
  1212. you rapidly double click on the from address button in the 
  1213. lower right hand corner of the debugger screen.  If you 
  1214. don't click rapidly enough, the output field will not be 
  1215. altered; instead, an editable line will open at the Change 
  1216. register field, located at the very bottom of the debugger 
  1217. window.
  1218.      In this particular case, you would see *=$___________.  
  1219. When the $ is present, you can enter a hexadecimal address.  
  1220. The address you would enter now, if the editable line has 
  1221. indeed appeared, is that which is labeled Program start at 
  1222. the top of the screen.  Never leave a space between the $ 
  1223. and the first digit of the address.  Conclude the dialog by 
  1224. pressing the Return key on the keyboard.
  1225.      When the correct address appears in the output field, 
  1226. perform step two, which is placing the PC cursor at the 
  1227. appropriate instruction.  Do this by moving the mouse 
  1228. pointer to the instruction line, then hold down the Control 
  1229. key on the keyboard, while clicking the left mouse button.  
  1230. Now you may execute the program again, by clicking on the 
  1231. Run program button.
  1232.      Referring to the from address button and the Change 
  1233. register editable parameter line again, if the program in 
  1234. debugger memory is there because it was recently assembled, 
  1235. and if it has been relocated as described previously 
  1236. (required only if the program was assembled in the 
  1237. relocatable mode), then you can go to any labeled line by 
  1238. backspacing over the $ on the parameter line, and by typing 
  1239. the label on the line.  When done correctly, the line will 
  1240. read *=label________.  The $ is permitted and necessary only 
  1241. if it is followed by a hexadecimal number.
  1242.      As an example of the proper use of this function, if 
  1243. you have just assembled program 1 and are now in the 
  1244. debugger mode; and, if you have just executed the program, 
  1245. you can get back to the program's start address by clicking 
  1246. once on the from address button, then by backspacing over 
  1247. the $ on the change register parameter line, and, finally, 
  1248. by typing the name of the label terminate on the line.  When 
  1249. you press the return key, the first line of program 1 will 
  1250. appear as the first line in the output field.
  1251.  
  1252. Loading Programs With Other Extensions
  1253.   
  1254.      The Execute program function, by default, looks for 
  1255. programs with the PRG extension.  To load a program that has 
  1256. any other extension, you must edit the path specification in 
  1257. the file selector when it appears.  Loading programs with a 
  1258. TOS extension incurs no special considerations; but AssemPro 
  1259. does not handle TTP programs correctly.
  1260.      Recall the Execute program dialog box shown in figure 
  1261. 2.10.  The Command line evident in that figure invites TTP 
  1262. parameters that are to be stored at the program's basepage 
  1263. address plus $80.  Although AssemPro accepts the data typed 
  1264. on the command line, it does not store the data in an ST 
  1265. specific format.  Figure 2.13 illustrates the manner in 
  1266. which the operating system stores TTP command line data.
  1267.      The program start address for the program which 
  1268. produced the results shown in the figure was $25956.  The 
  1269. basepage address was $25956 - $100 = $25856.  The command 
  1270. line address was $25856 + $80 = $258D6, as shown in figure 
  1271. 2.13.  There you see that the first byte of the command 
  1272. line, $0D, is the number of characters typed on the TTP 
  1273. program's input parameter line (command line).  Following 
  1274. that you see the ASCII codes for the 11 characters, 
  1275. PRG_1AP.TOS, which were typed as input.  Then you see the 
  1276. code for a carriage return, 0D, which is placed at the end 
  1277. of the command line input, whether the mouse or the Return 
  1278. key was used to terminate the dialog.
  1279.  
  1280. Figure 2.13. Command line data stored by the ST operating 
  1281. system.
  1282.  
  1283.  
  1284.  
  1285.  
  1286.  
  1287.  
  1288.  
  1289.  
  1290.      In figure 2.14 you can see why the manner in which 
  1291. AssemPro stores the input parameters creates two major 
  1292. problems.  AssemPro does not store the input parameter 
  1293. character count; therefore, any program that processes the 
  1294. command line in a loop which uses that count is doomed.  
  1295. And, to compound the problem, AssemPro stores the first 
  1296. character at basepage address plus $80 instead of at 
  1297. basepage address plus $81; therefore, any program which 
  1298. processes the command line by looking for the first 
  1299. character at basepage plus $81 is also doomed.  Although not 
  1300. as critical, AssemPro does not store a carriage return at 
  1301. the end of the command line string.
  1302.  
  1303. Figure 2.14. Command line data stored by AssemPro.
  1304.  
  1305.  
  1306.  
  1307.  
  1308.  
  1309.  
  1310.  
  1311.  
  1312.      My solution to the problem is this: when the Execute 
  1313. program dialog box appears, type a leading space on the 
  1314. command line, then follow with the input parameters.  This 
  1315. will place the first character of the input at basepage 
  1316. address plus $81, where it belongs.  Remember, the stored 
  1317. command line parameters (as they are placed in the basepage 
  1318. by the operating system) are a mixture composed of a one-
  1319. byte binary number and ASCII characters, so you can't just 
  1320. type in a number in place of that leading space.  After the 
  1321. TTP program has been loaded by AssemPro, manually replace 
  1322. the leading space with the ASCII character count.  To do 
  1323. that, click on the from address bar at the bottom of the 
  1324. debugger screen; and, on the parameter line which appears, 
  1325. type the address of the command line, which is basepage 
  1326. address + $80 or program start address - $80.  When you 
  1327. press the Return key, the command line address will appear 
  1328. as the first line in the output field window.
  1329.      Click on the disassembled bar located just above the 
  1330. from address bar at the bottom of the screen.  When the 
  1331. hexadecimal characters appear in the output field, the first 
  1332. two digits will be the ASCII code for the leading space that 
  1333. you typed on the command line.  Using the mouse, move the 
  1334. cursor to the first digit, which is 2, and type the number 
  1335. of characters in the command line.  The number you type must 
  1336. be in hexadecimal and you must include a leading 0 if the 
  1337. number you type is less than hexadecimal $10.
  1338.      Referring to that dialog box again, the load option 
  1339. should always be selected (reverse video).  The parameter 
  1340. line labeled Environment: refers to something called an 
  1341. environment string.  Just so you'll know what it is, I'll 
  1342. tell you.  It is used to pass an ordinary string as a 
  1343. parameter to be stored at offset $2C from the start of the 
  1344. program's basepage.  The program can access the string at 
  1345. that location.  I will show you how this can be done in a 
  1346. later program.  The address of a block of environmental 
  1347. strings can be passed, on the stack, to a spawned process, 
  1348. using the GEMDOS $4B (p_exec) function.
  1349.  
  1350. A Program With User Interaction
  1351.   
  1352.      Let's add something to PRG_1AP that will prevent the 
  1353. program from returning control to the operating system until 
  1354. we permit it to do so.  For now, I am relying on the GEMDOS 
  1355. (trap #1) functions, even though these are the farthest from 
  1356. the hardware, because they are the least complex.  As a 
  1357. matter of fact, none of the operating system functions 
  1358. should be considered taboo simply because they are not the 
  1359. fastest.  The important thing is to choose deliberately, 
  1360. with a knowledge of which is which and what does what, to 
  1361. whom, when.
  1362.      All of the GEMDOS functions, as well as the BIOS and 
  1363. XBIOS functions are discussed in the Abacus Internals book; 
  1364. and, in general, the functions are adequately described; 
  1365. therefore, I shall not have much to say about most of them.  
  1366. However, there are some errors present in some descriptions.  
  1367. Charles F. Johnson has written an article, Errors in Abacus, 
  1368. ST-LOG, June, 1988, describing some of the more critical 
  1369. errors in the Internals book, as they exist in revision two.  
  1370. Some of these errors were corrected in revision three.  I 
  1371. suggest that you obtain a copy of the article mentioned 
  1372. above to use as a reference for functions that I won't have 
  1373. a reason to use.
  1374.   
  1375. Program 2. Halting program execution.
  1376.   
  1377.  ; Program Name: PRG_1BP.S
  1378.  
  1379.  ; Assembly Instructions:
  1380.  
  1381.  ;    Assemble in AssemPro PC-relative mode and save the assembled program
  1382.  ; with a PRG extension, then save it with a TOS extension.
  1383.  
  1384.  ; Program Function:
  1385.  
  1386.  ;    This program waits until a key is pressed on the keyboard.  When
  1387.  ; that event occurs, it returns control to the operating system.
  1388.  
  1389.  ; NOTE: This program cannot be executed repeatedly in the debugger unless
  1390.  ;       the S bit of the status register is reset after each execution.
  1391.  ;       If the S bit is not reset as stated, the system will freeze, and
  1392.  ;       must be reset with the computer's reset switch.
  1393.  
  1394. wait_for_keypress: 
  1395.  move.w     #8, -(sp)           ; Function = c_necin = GEMDOS $8.
  1396.  trap       #1                  ; GEMDOS call.
  1397.  addq.l     #2, sp              ; Reposition stack pointer at top of stack.
  1398.  
  1399. terminate:                      ; My descriptive label.
  1400.  move.w    #0, -(sp)            ; Function = p_term_old = GEMDOS $0.
  1401.  trap      #1                   ; GEMDOS call.
  1402.  
  1403.  end                            ; Assembler pseudo-op.
  1404.  
  1405.  
  1406.      After you have installed PRG_1BP in the editor, 
  1407. assemble it, save the source with an S suffix, save the 
  1408. object code with both a PRG and a TOS suffix, then activate 
  1409. the debugger.  On the debugger screen, click the symbolic 
  1410. button.  You should see the wait_for_keypress label as the 
  1411. first instruction in the debugger output field; it should be 
  1412. shown in reverse video, indicating that the PC counter 
  1413. contains the address of this instruction.
  1414.      Observe the condition of the status register bits; they 
  1415. are all reset.  Also, notice that the content of all 
  1416. registers shown in the register field is zero (except for 
  1417. register A7).  These are the initial conditions of the 
  1418. registers at the start of the program run.  As we shall soon 
  1419. discover, these initial conditions are forced by AssemPro, 
  1420. and they are not identical to those imposed by the operating 
  1421. system when a program is loaded from the desktop.  You 
  1422. should notice that the content of A7 matches neither that of 
  1423. the SSP nor that of the USP.  This should seem unreasonable, 
  1424. and it is.  The AssemPro manual provides an explanation, of 
  1425. sorts, on p.90.  This discrepancy will not interfere with 
  1426. our work.
  1427.      Click on the Run program button to execute the program.  
  1428. There will be no change in the AssemPro screen, however, the 
  1429. mouse pointer will disappear; an indication that the program 
  1430. is running.  In fact, the program will be waiting for an 
  1431. event to occur; that being the press of a keyboard key.  
  1432. Press the Return key.  As you have come to expect, address 
  1433. 000000 is now the topmost line in the debugger output field, 
  1434. and the program counter now contains that address.  Look at 
  1435. the status register and notice the same alterations that you 
  1436. observed after executing program 1.  Also, look at the 
  1437. register output field and notice that the content of many 
  1438. registers have been changed.  Our initial conditions have 
  1439. been altered by AssemPro and the operating system.
  1440.      By the way, the L that precedes each register label 
  1441. indicates that you are viewing long word data.  Get in the 
  1442. habit of noticing that prefix.  It can be set to B, W or L, 
  1443. and what you see as a register's content varies greatly 
  1444. depending on that prefix.  Furthermore, the lines at which 
  1445. register contents are displayed may be altered to display 
  1446. the contents of memory locations or their addresses.
  1447.      Without resetting anything, get the program start 
  1448. address back in the output window, move the program counter 
  1449. cursor to that line (Move the mouse pointer to the line, 
  1450. hold down the Control key and press the left mouse button.), 
  1451. then execute the program again.  Things seem to be as they 
  1452. were during the first execution.  But they are not.  Press 
  1453. the Return key and notice the lack of response.  The system 
  1454. is frozen because the alteration of the S bit is of 
  1455. consequence to the proper execution of this program.  
  1456. Furthermore, it is safe to assume that all initial 
  1457. conditions must be reset between repeated executions of any 
  1458. program in the debugger.  You must manually reset the 
  1459. computer.
  1460.      Load in the source code for program 2 again, assemble 
  1461. it and go to the debugger.  Click the symbolic button, as is 
  1462. usual, then execute the program.  This time, reset all 
  1463. initial conditions before the second execution.  Click on 
  1464. the dark status register bits to set them to zero.  For each 
  1465. register (except A7) shown in the register window, with a 
  1466. nonzero content do the following:
  1467.  
  1468.      1. Click on the Change register bar at the bottom of 
  1469.         the debugger screen.
  1470.  
  1471.      2. On the parameter line which appears, type the 
  1472.         register label, an equal sign and a zero.
  1473.  
  1474.         example: d0=0 or D0=0
  1475.  
  1476.         There must be no spaces between the characters.
  1477.   
  1478.      3. Press the Return key.
  1479.   
  1480.      Execute the program and press the Return key.  The 
  1481. execution should be normal.  Reset all initial conditions 
  1482. again, then click on the Save screen button.  With the 
  1483. content of PC as it should be, execute the program.  Now, 
  1484. you see that a blank white screen appears.  The program is 
  1485. still waiting for a keypress, but AssemPro has presented a 
  1486. screen for program usage.  Terminate the execution by 
  1487. pressing the Return key.
  1488.      Once again, reset all initial conditions, but leave the 
  1489. Save screen feature checked.  Features such as this and 
  1490. symbolic are not included in the term initial conditions.  
  1491. Set a breakpoint at the TERMINATE  label.  To do this, move 
  1492. the mouse pointer to the Breakpoint button.  Press the left 
  1493. mouse button and, while holding it pressed, move the pointer 
  1494. to the instruction line containing the label, before 
  1495. releasing the mouse button.  You should see the word 
  1496. BREAKPOINT appear on the line just to the right of the 
  1497. label.  Refer to figure 2.15.  Run the program and press the 
  1498. Return key.  Execution will stop at the breakpoint, apparent 
  1499. by the instruction line being highlighted by the program 
  1500. counter cursor.  Notice that the S bit has not yet been set 
  1501. and notice that only the D0 and A0 registers have been 
  1502. altered (ignoring A7, as we should).  Refer to the 
  1503. compressed register field, also shown in figure 2.15.
  1504.   
  1505. Figure 2.15A. Installing a breakpoint to halt execution.
  1506.  
  1507.  
  1508.  
  1509.  
  1510.  
  1511.  
  1512.  
  1513.  
  1514.  
  1515.  
  1516.  
  1517.  
  1518.  
  1519.  
  1520.  
  1521.  
  1522.  
  1523.  
  1524.  
  1525.  
  1526.  
  1527.  
  1528.  
  1529.  
  1530.  
  1531. Figure 2.15B. Content of Registers at the breakpoint.
  1532.      
  1533.  
  1534.  
  1535.  
  1536.  
  1537.  
  1538.  
  1539.  
  1540.  
  1541.  
  1542.  
  1543.  
  1544.  
  1545.  
  1546.  
  1547.  
  1548.  
  1549.  
  1550.  
  1551.  
  1552.  
  1553.  
  1554.  
  1555.  
  1556.  
  1557.  
  1558.  
  1559.      These are the only two registers we expect to be 
  1560. altered, according to the Internals book p.106.  We must be 
  1561. cognizant of this type of information so that we may know in 
  1562. which registers data is safe during operating system 
  1563. function calls.  Remember, we have learned (via the 
  1564. references and an experiment) that all registers but D0 and 
  1565. A0 are safe during GEMDOS (trap #1) calls; this example 
  1566. provides no information concerning register alteration 
  1567. during other calls.
  1568.      Of course, we have not seen conclusive proof that all 
  1569. GEMDOS calls behave identically, and we will be looking out 
  1570. for deviations from the norm.  The aforementioned page also 
  1571. informs us that any values returned by the function call 
  1572. will be in D0.  Looking at the register field, you should 
  1573. see the ASCII code for a carriage return, the hexadecimal 
  1574. character D, in the lower word of that register.  For this 
  1575. example, we are not interested in the content of register 
  1576. A0, nor are we interested in the upper word of D0.  But we 
  1577. do need to remember that the character received from the 
  1578. keyboard is returned in the lower byte of the lower word of 
  1579. D0, because there will be times when we want to process that 
  1580. input.
  1581.      Remove the breakpoint.  To do this, move the mouse 
  1582. pointer to the line containing the breakpoint, press the 
  1583. left mouse button, and, while holding the button down, move 
  1584. the pointer to the Breakpoint button, then release the mouse 
  1585. button.  Click on the Run program button to conclude the 
  1586. execution.
  1587.      Exit AssemPro without saving the object code.  Back at 
  1588. the desktop, execute PRG_1BP.PRG.  You will see the PRG type 
  1589. screen, as you did when you executed program 1; but, this 
  1590. time, the program will be waiting for the keyboard event.  
  1591. You will notice that you can move the busy bee cursor to any 
  1592. position on the screen without affecting anything.  
  1593. Terminate the program by pressing any key.
  1594.      Now, execute PRG_1BP.TOS.  You will see the clear 
  1595. screen with the blinking cursor in the upper left hand 
  1596. corner of the screen.  Terminate the program at any time, by 
  1597. pressing any key.  Note this please: there are times when 
  1598. you will exit from the debugger after doing many strange 
  1599. things as far as the computer is concerned.  Occasionally, 
  1600. after you are back at the desktop, you will execute some 
  1601. program that you know is bug-free (If there is such a 
  1602. thing.), yet the program will bomb.  This happens.  You just 
  1603. have to reset the machine and try again, that's all.
  1604.  
  1605. Writing to an AssemPro Screen
  1606.   
  1607.      When a program is to write text or graphics to a screen 
  1608. without destroying the debugger screen, the debugger option 
  1609. Save screen must be selected before the program is loaded 
  1610. into the debugger; or before a just assembled Relocatable 
  1611. program is relocated; or just after the function which 
  1612. returns excess memory to the operating system has been 
  1613. executed.  Unfortunately, even though the option is 
  1614. selected, the very first line of output usually overwrites a 
  1615. critical portion of the debugger screen.  The location of 
  1616. overwrite is random unless the program being executed 
  1617. actually positions the cursor at some selected position on 
  1618. the screen.  The problem is introduced by program 3.
  1619.      I am going to assume that, unless I say otherwise, you 
  1620. will know that, as each program is introduced, you must get 
  1621. it into the editor, assemble it and save everything in the 
  1622. manner described for the programs previously introduced, 
  1623. unless the new program instructs you to do something 
  1624. different.  Further, I will assume that you will go to the 
  1625. debugger screen and select Save screen, relocate (if the 
  1626. program was assembled in Relocatable mode) and symbolic.  In 
  1627. addition, I trust you to reset initial conditions between 
  1628. repeated executions.
  1629.      You should realize that you will receive the warning 
  1630. message about saving object code every time you load a 
  1631. source file and assemble, then attempt to quit AssemPro 
  1632. without saving the assembled file.  Having previously saved 
  1633. the object code, you will be able to simply click on the NO 
  1634. button.
  1635.   
  1636. Program 3. A program that contaminates the debugger screen.
  1637.  
  1638.  ; Program Name: PRG_1CP.S
  1639.  ;      Version: 1.002
  1640.  
  1641.  ; Assembly Instructions:
  1642.  
  1643.  ;     Assemble in AssemPro PC-relative mode and save the assembled program
  1644.  ; with PRG and TOS extensions.
  1645.  
  1646.  ; Program Function:
  1647.  
  1648.  ;     Prints a string to the video screen.  If the program is executed
  1649.  ; within the AssemPro debugger, the string should overwrite the debugger
  1650.  ; screen, even if the AssemPro "Save Screen" option has been selected.  To
  1651.  ; verify this phenomenon, power the computer down, then back up.  Execute
  1652.  ; ASSEMPRO.PRG, then load or type this program into the editor.  Assemble,
  1653.  ; then activate the debugger.  Select "Save Screen" and "symbolic".  Finally,
  1654.  ; select "Run Program".  The debugger screen will be overwritten in an
  1655.  ; unpredictable area.
  1656.  
  1657.  ;     Watch the debugger screen carefully, during execution, so that you
  1658.  ; will be able to see the writeover occur. 
  1659.  
  1660.  ;     Depending on the location of the overwritten area, AssemPro may
  1661.  ; redraw a portion of its screen after the event.
  1662.  
  1663.  ;     The overwrite is likely to occur only once, the first time a program
  1664.  ; which writes to the screen is executed within the debugger.
  1665.  
  1666.  ;     After the string has been written, the program waits until a key
  1667.  ; is pressed on the keyboard.  When that event occurs, it returns control
  1668.  ; to the debugger.
  1669.  
  1670.  ; Note - We have not defined a program stack.  We are using the default
  1671.  ;        system stack located at $4DB8, according to Internals page 276.
  1672.  
  1673. print_string:
  1674.  pea        string              ; Push address of the string onto stack.
  1675.  move.w     #9, -(sp)           ; Function = c_conws = GEMDOS $9.
  1676.  trap       #1                  ; GEMDOS call
  1677.  addq.l     #6, sp              ; Reset stack pointer to top of stack.
  1678.  
  1679. wait_for_keypress: 
  1680.  move.w     #8, -(sp)           ; Function = c_necin = GEMDOS $8.
  1681.  trap       #1                  ; GEMDOS call.
  1682.  addq.l     #2, sp              ; Reposition stack pointer at top of stack.
  1683.  
  1684. terminate:                      ; My descriptive label.
  1685.  move.w    #0, -(sp)            ; Function = p_term_old = GEMDOS $0.
  1686.  trap      #1                   ; GEMDOS call.
  1687.  
  1688. string:     dc.b 'This string will overwrite the AssemPro debugger screen.'
  1689.             dc.b $D,$A,0  ; The string is continued on this line.  Here, we
  1690.                           ; declare a carriage return and linefeed, then
  1691.                           ; terminate the entire string with a NULL = 0.
  1692.  
  1693.  end                      ; Assembler pseudo-op.
  1694.  
  1695.  
  1696.      When you execute this program in the debugger, the 
  1697. program screen will appear, but the line which was printed 
  1698. will not be on that screen.  Terminate execution and go back 
  1699. to the AssemPro screen by pressing the Esc key on the 
  1700. keyboard.  As the debugger screen appears you will see, just 
  1701. before the output fields of the debugger screen are redrawn, 
  1702. that the line has overwritten the debugger screen.  Any 
  1703. portion of the line that had overwritten the output fields 
  1704. of the debugger screen will be cleared by the redraw.  On my 
  1705. screen the line was written at a location that caused a 
  1706. portion of the Single step button to be overwritten.  See 
  1707. figure 2.16.  Execute the program a second time; the 
  1708. sentence will be written on the program screen.  Use the Esc 
  1709. key to terminate execution and get back to the debugger 
  1710. screen; it will be as it was previously.
  1711.   
  1712. Figure 2.16. Text improperly written on the debugger 
  1713. screen.
  1714.  
  1715.  
  1716.  
  1717.  
  1718.  
  1719.  
  1720.  
  1721.  
  1722.  
  1723.  
  1724.  
  1725.  
  1726.  
  1727.  
  1728.  
  1729.      Now deselect the Save screen option and execute the 
  1730. program again.  Probably, nothing will be written on the 
  1731. debugger screen this time.  Press any key to terminate 
  1732. execution.  Select Save screen and execute again.  You 
  1733. should see the clear program screen, and when you press Esc 
  1734. to terminate and go back to the debugger screen, you will 
  1735. probably see that the program's sentence has overwritten the 
  1736. debugger screen in a different location.  By the way, the 
  1737. Esc key is the key which permits flipping between the 
  1738. program's screen and the debugger screen.
  1739.      Go to the desktop and execute PRG_1CP.PRG several 
  1740. times.  Then execute PRG_1CP.TOS several times.  You should 
  1741. notice that each time the program with the TOS suffix is 
  1742. executed, the operating system prints the sentence on the 
  1743. first line of the screen.  This is because the cursor is 
  1744. initialized to the upper left corner of screen when a 
  1745. program has a TOS suffix.  When a program with a PRG suffix 
  1746. is executed, the sentence is printed with the cursor 
  1747. positioned wherever the previous program execution happened 
  1748. to leave it.  Occasionally, you may not even see the results 
  1749. of GEMDOS function $9 when the program has a PRG suffix, 
  1750. unless the program initializes the cursor position.
  1751.      If you execute the TOS program, then immediately 
  1752. execute the PRG program, the PRG program's output will 
  1753. appear on the first line of the screen.  Do that a few times 
  1754. so that you understand what I mean.  Now you see that 
  1755. execution of a program can be influenced by a previous 
  1756. program execution.  To drive this point deeper, execute the 
  1757. PRG program several times.  Notice that, with each 
  1758. execution, the sentence is printed one line lower on the 
  1759. screen.  Via these experiments, I want you to understand 
  1760. that the way in which the operating system processes 
  1761. programs varies according to the suffix attached to the 
  1762. program name.  As a programmer, you must know when you can 
  1763. relinquish control to the system and when you must provide 
  1764. control of even the most basic of functions within your 
  1765. program.
  1766.      The next program sends a newline (carriage return + 
  1767. line feed) to the screen as an initialization character.  I 
  1768. believe that this eliminates the debugger screen overwrite 
  1769. problem because the character forces AssemPro to switch 
  1770. logical screen bases.  Refer to page 168 of the Internals 
  1771. book: XBIOS function 3.  You should assemble this program 
  1772. and execute it from the debugger to confirm that it 
  1773. functions as I have specified.
  1774.   
  1775. Program 4. Eliminating debugger screen overwrite.
  1776.   
  1777.  ; Program Name: PRG_1DP.S
  1778.  ;      Version: 1.002
  1779.  
  1780.  ; Assembly Instructions:
  1781.  
  1782.  ;    Assemble in PC-relative mode and save with PRG and TOS extensions.
  1783.  
  1784.  ; Program Function: 
  1785.  
  1786.  ;    Prints a newline (combination of a carriage return and a linefeed)
  1787.  ; to the video screen before it prints a string.  This added feature
  1788.  ; prevents the string from overwriting the AssemPro debugger screen, if
  1789.  ; the Save Screen debugger option is chosen before the assembled program
  1790.  ; is relocated with the Relocate option or before it is loaded with the
  1791.  ; Execute Program option.
  1792.  
  1793.  ;    After the string has been written, the program waits until a key is
  1794.  ; pressed on the keyboard.  When that event occurs, it returns control to
  1795.  ; AssemPro.
  1796.  
  1797.  ; Note - We have not defined a program stack.  We are using the default
  1798.  ;        system stack located at $4DB8, according to Internals p. 276.
  1799.  
  1800. print_newline:                  ; Prints a carriage return and linefeed.
  1801.  pea        newline             ; Push address of string onto stack.
  1802.  move.w     #9, -(sp)           ; Function = c_conws = GEMDOS $9.
  1803.  trap       #1                
  1804.  addq.l     #6, sp
  1805.  
  1806. print_string:
  1807.  pea        string              ; Push address of the string onto stack.
  1808.  move.w     #9, -(sp)           ; Function = c_conws = GEMDOS $9.
  1809.  trap       #1                
  1810.  addq.l     #6, sp            
  1811.  
  1812. wait_for_keypress: 
  1813.  move.w     #8, -(sp)           ; Function = c_necin = GEMDOS $8.
  1814.  trap       #1                
  1815.  addq.l     #2, sp            
  1816.  
  1817. terminate:
  1818.  move.w    #0, -(sp)            ; Function = p_term_old = GEMDOS $0.
  1819.  trap      #1                 
  1820.  
  1821.  data
  1822. newline: dc.b $D,$A,0  ; All strings must be NULL terminated because the
  1823.                        ; function we are used to print them requires it.
  1824. string:  dc.b 'This string will not overwrite the AssemPro debugger screen.'
  1825.          dc.b $D,$A,0  ; The string is continued on this line.  Here, we
  1826.                        ; declare a carriage return, linefeed and terminate
  1827.                        ; the entire string with a NULL = 0.
  1828.  end               
  1829.  
  1830.  
  1831. Declaring Data Within the Text Area of a Program
  1832.  
  1833.      Notice that the all of the data of program 4 has been 
  1834. declared in a more conventional location within the program.  
  1835. There is no reason to declare the data at the end of the 
  1836. program, other than that programmers find it convenient to 
  1837. do so.  There are times, however, when it is more convenient 
  1838. to declare data within a program's text area.  Program 5 
  1839. illustrates a method of doing that.
  1840.   
  1841. Program 5. Declaring data within a text area.
  1842.  
  1843.  ; Program Name: PRG_1EP.S
  1844.  ;      Version: 1.002
  1845.  
  1846.  ; Assembly Instructions:
  1847.  
  1848.  ;    Assemble in AssemPro PC-relative mode and save the assembled program
  1849.  ; program with PRG and TOS extensions.
  1850.  
  1851.  ; Program Function:
  1852.  
  1853.  ; Illustrates a method of program organization which places declarations
  1854.  ; at the beginning of a program.
  1855.  
  1856.  ; Note - We have not defined a program stack.  We are using the default
  1857.  ;        system stack located at $4DB8, according to Internals p. 276.
  1858.  
  1859.  bra.s      print_string  ; Jump over the declarations below.
  1860.  
  1861. string:     dc.b 'This string will not overwrite the AssemPro debugger screen.'
  1862.             dc.b $D,$A,0  ; The string is continued on this line.  Here, we
  1863.                           ; declare a carriage return and linefeed, then
  1864.                           ; terminate the entire string with a NULL = 0.
  1865. newline:    dc.b $D,$A,0  ; All strings must be NULL terminated because the
  1866.                           ; function we are used to print them requires it.
  1867.  
  1868.  align      ; This is the assembler pseudo-op that forces the next
  1869.             ; instruction to start at a word boundary.  It is necessary
  1870.             ; because we have declared byte data above and we don't care to
  1871.             ; count the bytes to confirm that there is an even number of 
  1872.             ; byte-size data.
  1873.  
  1874.  text       ; This is an assembler pseudo-op.  dc.b is a pseudo-op also.  We
  1875.             ; can define the string above the source code if we put this
  1876.             ; pseudo-op between the declaration and the text of the source.
  1877.             ; Of course, since the processor will attempt to execute the
  1878.             ; first thing it sees, whether it be an instruction or data, we
  1879.             ; must jump over the data.  You don't jump when the data is
  1880.             ; actually an instruction you want to execute, such as when an
  1881.             ; a-line (illegal) instruction is declared as data.
  1882.  
  1883. print_string:            
  1884.  pea        newline             ; Prints a carriage return and linefeed.
  1885.  move.w     #9, -(sp)           ; Function = c_conws = GEMDOS $9.
  1886.  trap       #1                
  1887.  addq.l     #6, sp
  1888.  
  1889.  pea        string              ; Push address of the string onto stack.
  1890.  move.w     #9, -(sp)           ; Function = c_conws = GEMDOS $9.
  1891.  trap       #1                  ; GEMDOS call
  1892.  addq.l     #6, sp              ; Reset stack pointer to top of stack.
  1893.  
  1894. wait_for_keypress: 
  1895.  move.w     #8, -(sp)           ; Function = c_necin = GEMDOS $8.
  1896.  trap       #1                  ; GEMDOS call.
  1897.  addq.l     #2, sp              ; Reposition stack pointer at top of stack.
  1898.  
  1899. terminate:                      ; My descriptive label.
  1900.  move.w    #0, -(sp)            ; Function = p_term_old = GEMDOS $0.
  1901.  trap      #1                   ; GEMDOS call.
  1902.  
  1903.  end                            ; Assembler pseudo-op.
  1904.   
  1905.  
  1906.      Don't execute the program yet, but when you do, the 
  1907. first thing you will notice is that, although it does output 
  1908. correctly to the program's screen, the sentence is not 
  1909. likely to appear on the top line of the screen.  This is 
  1910. true because AssemPro does not initialize the cursor on that 
  1911. screen; at least, not for this program.  After you look at 
  1912. the output on the program's screen, you can go back to the 
  1913. debugger by pressing the Esc key.
  1914.      For now, notice that the first instruction of the 
  1915. program is a branch to the label print_string.  Under that 
  1916. instruction you see the label string followed by the 
  1917. instruction
  1918.  
  1919.                  ADDQ.W #2,$6973(A0)
  1920.                
  1921. which is certainly not one of the instructions we included 
  1922. in our program.  We declared a string at that point in the 
  1923. program.  Figure 2.17 depicts the situation.
  1924.  
  1925. Figure 2.17. PRG_1EP in symbolic disassembled format.
  1926.  
  1927.  
  1928.  
  1929.  
  1930.  
  1931.  
  1932.  
  1933.  
  1934.  
  1935.  
  1936.  
  1937.  
  1938.  
  1939.  
  1940.  
  1941.  
  1942.  
  1943.  
  1944.  
  1945.  
  1946.  
  1947.  
  1948.  
  1949.  
  1950.  
  1951.  
  1952.      It so happens that our declared data is just that which 
  1953. would be the binary representation of that instruction.  You 
  1954. should convince yourself that this is true by going to the 
  1955. editor and typing in that instruction just before the branch 
  1956. instruction.  Then assemble, and return to the debugger.  
  1957. After relocating, click the symbolic button so that it is 
  1958. unchecked.  Now you can see that the normal disassembled 
  1959. format of both the first and third lines in the output field 
  1960. are identical.  Refer to figure 2.18.
  1961.   
  1962. Figure 2.18. PRG_1EP with added statement in normal 
  1963. disassembled format.
  1964.  
  1965.  
  1966.  
  1967.  
  1968.  
  1969.  
  1970.  
  1971.  
  1972.  
  1973.  
  1974.  
  1975.  
  1976.  
  1977.  
  1978.  
  1979.  
  1980.  
  1981.  
  1982.  
  1983.  
  1984.  
  1985.  
  1986.  
  1987.  
  1988.  
  1989.  
  1990.  
  1991.  
  1992.  
  1993.      Now click the disassembled button so that you can view 
  1994. the content of memory in hexadecimal and ASCII.  You can see 
  1995. that the same sequence of hexadecimal digits (54586973) and 
  1996. ASCII characters are formed by both the instruction ADDQ.W 
  1997. #2,$6973(A0) and the string THIS.  See figure 2.19.  We are 
  1998. tipped that something is not legitimate about the sequence 
  1999. of "instructions" directly following the branch instruction 
  2000. by the line DC.W $2073 which is definitely not a legitimate 
  2001. instruction.  You will learn to be suspicious of any 
  2002. instruction whose hexadecimal representation forms a neat 
  2003. ASCII string.
  2004.   
  2005. Figure 2.19. PRG_1EP with added statement in 
  2006. hexadecimal/ASCII dump format.
  2007.  
  2008.  
  2009.  
  2010.  
  2011.  
  2012.  
  2013.  
  2014.  
  2015.  
  2016.  
  2017.  
  2018.  
  2019.  
  2020.  
  2021.  
  2022.  
  2023.  
  2024.  
  2025.  
  2026.  
  2027.  
  2028.  
  2029.  
  2030.  
  2031.  
  2032. Some Other Debugger Functions
  2033.  
  2034.      After eliminating the addq.w statement that you added 
  2035. to the program for the demonstration, assemble and go back 
  2036. to the debugger.  Click on the appropriate buttons to get 
  2037. back to the symbolic format.  Notice that the label to which 
  2038. the branch is to be taken is not visible in the output 
  2039. field.  You will be able to see it if you click on the 
  2040. window's right hand scroll bar.  After doing that, double 
  2041. click on the from address button to go back to program 
  2042. start.  Now, go over to the from address button with the 
  2043. mouse pointer and click once.  When the parameter line 
  2044. appears in place of the Change register bar, backspace over 
  2045. the $ and type PRINT_STRING, then press the Return key.
  2046.      The line containing the PRINT_STRING label will replace 
  2047. the line containing the branch instruction as the first line 
  2048. in the output field.  Use this method to branch to labels in 
  2049. your programs; do not use the Search function.  The AssemPro 
  2050. manual indicates, on page 95, under the Search heading, that 
  2051. you can use labels with this function, however, if you 
  2052. attempt to do this, you will sit waiting while an exhaustive 
  2053. search through all of memory is conducted, then you will be 
  2054. greeted with a Not found, sorry message.
  2055.      Use the Search function to search (forward) for a 
  2056. declared string or a numerical quantity.  The string for 
  2057. which you are searching must be typed on the parameter line, 
  2058. within single or double quotes, as indicated in the AssemPro 
  2059. manual, however, do not type the word Byte: before the 
  2060. string as is indicated in the manual.  Instead, as shown in 
  2061. figure 2.20, you must click on the .B button which appears 
  2062. in the Search function's dialog box.
  2063.  
  2064. Figure 2.20. The debugger Search function's dialog box; a 
  2065. slightly compressed representation.
  2066.  
  2067.  
  2068.  
  2069.  
  2070.  
  2071.  
  2072.  
  2073.  
  2074.  
  2075.  
  2076.  
  2077.      When searching for a numerical quantity, you must use 
  2078. the appropriate base indicator ($ for hexadecimal, % for 
  2079. binary, or nothing for decimal), and select the appropriate 
  2080. button (.B, .W or .L), depending on the size of the data you 
  2081. are looking for.  You do not type anything else in front of 
  2082. your search criteria.  The manual does not properly describe 
  2083. the use of the Search function.
  2084.  
  2085. The Register Field
  2086.   
  2087.      Below the debugger register field there is a button 
  2088. labeled Show register.  If you click on this button, the 
  2089. register field disappears.  I can't imagine why anyone would 
  2090. want to do that, but the manual tells us that displaying the 
  2091. register field is optional.  Figure 2.21 is a representation 
  2092. of the register field.  The dotted lines shown in the figure 
  2093. are not actually visible on the AssemPro screen.  I have 
  2094. included them so that you can understand the manner in which 
  2095. the content of the field is divided.  It is the area between 
  2096. a set of those dotted lines on which you must double click 
  2097. to activate the dialog box discussed on page 89 of the 
  2098. manual.
  2099.   
  2100. Figure 2.21. The debugger register field.  If you double 
  2101. click on an area between a set of dotted lines, a dialog box 
  2102. will appear.
  2103.  
  2104.  
  2105.  
  2106.  
  2107.  
  2108.  
  2109.  
  2110.  
  2111.  
  2112.  
  2113.  
  2114.  
  2115.  
  2116.  
  2117.  
  2118.  
  2119.  
  2120.  
  2121.  
  2122.  
  2123.  
  2124.  
  2125.  
  2126.  
  2127.  
  2128.  
  2129.  
  2130.  
  2131.  
  2132.      The dialog box permits you to specify an effective 
  2133. address to be flagged.  Usually, you will want to view the 
  2134. content or address of a variable or a pointer.  In that 
  2135. case, you would press the Esc key to clear the parameter 
  2136. line, then you would type in a label or some other effective 
  2137. address such as (A0), 6(A1) or $72FB0.  You must also select 
  2138. a button to indicate whether the content or the address of 
  2139. the effective address is to be shown in the register field.  
  2140. Finally, you must chose .B, .W, or .L to indicate the length 
  2141. of the data that will be shown.  However, the manual does 
  2142. not properly describe the manner in which a label must be 
  2143. typed on the parameter line.  Figure 2.22 shows a label 
  2144. correctly specified on the parameter line.
  2145.   
  2146. Figure 2.22. Flagging a string for the register field.
  2147.  
  2148.  
  2149.  
  2150.  
  2151.  
  2152.  
  2153.  
  2154.  
  2155.  
  2156.  
  2157.  
  2158.  
  2159.  
  2160.      In the discussion to follow, I will be using figures 
  2161. that indicate specific addresses and the content of those 
  2162. addresses.  These are the values which appeared on my 
  2163. debugger screen while I was preparing the example.  When you 
  2164. run through the example on your computer, the values will 
  2165. probably be different because they depend on each system's 
  2166. particular configuration.
  2167.      With PRG_1EP in the debugger, figure 2.23 shows the 
  2168. register field after four sessions with the dialog box.  All 
  2169. we care to see is the content of memory at the location 
  2170. labeled STRING.  The address at which the label STRING is 
  2171. located is $72FBO.  But when STRING is typed on the 
  2172. parameter line, with the button options Content and .L 
  2173. selected, the long word $2B540000  is shown in the field as 
  2174. the content of that location.  There are two reasons why we 
  2175. know this information is not correct: we did not store that 
  2176. information after the STRING label, and we can see the true 
  2177. data in the disassembled field.  The register field is 
  2178. showing the content of memory location $2FB0.  It is showing 
  2179. that because it has incorrectly recorded the memory location 
  2180. of STRING.
  2181.  
  2182. Figure 2.23. Appearance of the register field when the 
  2183. parameter line of the dialog box has been prepared according 
  2184. to the instructions in the AssemPro manual.
  2185.  
  2186.  
  2187.  
  2188.  
  2189.  
  2190.  
  2191.  
  2192.  
  2193.  
  2194.  
  2195.  
  2196.  
  2197.  
  2198.  
  2199.  
  2200.  
  2201.  
  2202.  
  2203.  
  2204.  
  2205.  
  2206.  
  2207.  
  2208.  
  2209.  
  2210.  
  2211.  
  2212.  
  2213.  
  2214.      Fortunately, I have discovered a solution to this 
  2215. problem.  When you are specifying a label on the parameter 
  2216. line, type .L after the label name.  Both the label and the 
  2217. extension may be in lower case or upper case.  For example, 
  2218. STRING.L and string.l are equivalent.  Figure 2.24 
  2219. illustrates the effectiveness of this solution.
  2220.   
  2221. Figure 2.24. The appearance of the register field when the 
  2222. label has been followed by the suffix .L.  Note that a ^ 
  2223. replaces the = when an address is being shown.
  2224.  
  2225.  
  2226.  
  2227.  
  2228.  
  2229.  
  2230.  
  2231.  
  2232.  
  2233.  
  2234.  
  2235.  
  2236.  
  2237.  
  2238.  
  2239.  
  2240.  
  2241.  
  2242.  
  2243.  
  2244.  
  2245.  
  2246.  
  2247.  
  2248.  
  2249.  
  2250.  
  2251.  
  2252.  
  2253.      In this figure you are able to see the .L suffix in the 
  2254. register field.  Note that it will only be visible when the 
  2255. label name is short enough so that truncation is not 
  2256. required.  Figure 2.25 shows what happens when a label 
  2257. composed of more than seven characters is flagged.
  2258.  
  2259. Figure 2.25. Register field showing the truncation 
  2260. of a flagged label.
  2261.  
  2262.  
  2263.  
  2264.  
  2265.  
  2266.  
  2267.  
  2268.  
  2269.  
  2270.  
  2271.  
  2272.  
  2273.  
  2274.  
  2275.  
  2276.  
  2277.  
  2278.  
  2279.  
  2280.  
  2281.  
  2282.  
  2283.  
  2284.  
  2285.  
  2286.  
  2287.  
  2288.  
  2289. Conclusion
  2290.   
  2291.      I have suggested an assembly language programming 
  2292. environment for the Atari ST with a great deal of 
  2293. confidence.  I was able to do that because the AssemPro and 
  2294. TEMPUS packages are, respectively, the most powerful 
  2295. assembler and programming editor available for the ST, 
  2296. beyond question.  Furthermore, both of the packages are 
  2297. reasonably priced.
  2298.      However, although I recommend the packages without 
  2299. hesitation, I have had to point out certain undesirable 
  2300. effects noticed during their use, and I have suggested 
  2301. methods of dealing with those faults.  I assign no 
  2302. responsibility for the faults because the environment in 
  2303. which AssemPro and TEMPUS are forced to operate is not 
  2304. without flaws itself.  I have simply reported my 
  2305. observations and the solutions that I have found to be 
  2306. satisfactory.
  2307.  
  2308.