home *** CD-ROM | disk | FTP | other *** search
/ Brotikasten / BROTCD01.iso / texte / cbmhack7.txt < prev    next >
Text File  |  1995-08-20  |  165KB  |  3,604 lines

  1.                    ########
  2.              ##################
  3.          ######            ######
  4.       #####
  5.     #####  ####  ####      ##      #####   ####  ####  ####  ####  ####   #####
  6.   #####    ##    ##      ####    ##   ##   ##  ###     ##    ####  ##   ##   ##
  7.  #####    ########     ##  ##   ##        #####       ##    ## ## ##   ##
  8. #####    ##    ##    ########  ##   ##   ##  ###     ##    ##  ####   ##   ##
  9. #####  ####  ####  ####  ####  #####   ####  ####  ####  ####  ####   ######
  10. #####                                                                    ##
  11.  ######            ######           Issue #7
  12.    ##################               Feb. '94
  13.        ########
  14.  
  15. -----------------------------------------------------------------------------
  16. Editor's Notes:
  17. by Craig Taylor (duck@pembvax1.pembroke.edu)
  18.  
  19. This net-magazine is still alive after over two years suprising even
  20. myself. There should be more to come also!! And it's been late everytime
  21. it's been released. :-) I dunno - I'm trying not to make that a
  22. tradition but next time I don't think I'm going to set any firm dates so
  23. it can't possibly be late.
  24.  
  25. Lesee, first to address some questions and queries that have been going
  26. on over the network:
  27.  
  28.   - The C project that I mentioned a while back is now officially
  29.     defunct, dead, resting in peace... whatever you want to call it.
  30.     There may be other individuals working on their own version of an
  31.     ANSI C compiler but the group that was setup is no longer.
  32.     Basically, it was a problem of too many programmers, too few
  33.     managers (and we know programmers *grins* - They all want to do it
  34.     their way. Incidentilly - my way _was_ the best. ;-) )
  35.  
  36.   - The C65 exists but there are very few of them out there and
  37.     GrapeVine no longer sells them (out of stock I believe). It was only
  38.     made in small quantities for prototype work. There have been
  39.     numerous individuals reading comp.sys.cbm that see mention of the
  40.     C65 and assume that this creature Commodore released. Commodore sold
  41.     a warehouse and its contents to Grapevine and Grapevine stumbled
  42.     across them and sold 'em. They are functional but due to the low
  43.     number of them available I doubt that there will be any C65 targated
  44.     applications. (Someone prove me wrong, please?)
  45.  
  46.   - Geesh - That stupid article about the 1351 mouse that I kept
  47.     promising from issue 2 on I've officially declared dead. It may come
  48.     around later but for now it's dead. It's existed as a promise in one
  49.     form or another since issue 2 so this message officially kills it.
  50.  
  51.   - Also there was some confusion last time about my wording about not
  52.     writing any more articles and such (or rather, not as many as I had
  53.     been). Basically, yes - I'm still going to do C=Hacking - it's just
  54.     that because of time, frustration, school and jobs that I don't have
  55.     as much time to devote to researching and writing articles. That's
  56.     all that I meant to say - some people were concerned that C=Hacking
  57.     was no longer going to be released...
  58.  
  59. As always, here's the obligatory begging for authors on any type of
  60. software or hardware project that involves the Commodore computers.
  61. Please, Please if you or your user group has any information or material
  62. concerning the Commodore computers that you think may be appropriate for
  63. C=Hacking let me know via e-mail at duck@pembvax1.pembroke.edu. I'm
  64. looking for anything from hardware schematic, programming theory to
  65. actual programming techniques, programs.
  66.  
  67. The articles in this issue of C=Hacking I'm especially pleased with.
  68. There are two articles concerning the VIC chip and its operations that
  69. detail how certain "magical" techniques are performed. Also, Marko
  70. Makela has written a very detailed, interesting article on various
  71. memory techniques for the C-64. We also have a summary of the ACE
  72. programming / operating system and a referance guide on how to write
  73. applications for it. I've also included an InterNet guide that I've
  74. started writing to show individuals how to use the InterNet to get
  75. Commodore-64/128/Vic-20 related material. Included within that is a list
  76. of FTP sites containing numerous programs.
  77.  
  78. =============================================================================
  79.  
  80.   Please note that this issue and prior ones are available via anonymous
  81.   FTP from ccosun.caltech.edu (among others) under pub/rknop/hacking.mag
  82.   and via a mailserver which documentation can be obtained by sending
  83.   mail to "duck@pembvax1.pembroke.edu" with a subject line of
  84.   "mailserver" and the line "help" in the body of the mesage.
  85.  
  86. =============================================================================
  87.  
  88.   NOTICE: Permission is granted to re-distribute this "net-magazine", in
  89.   whole, freely for non-profit use. However, please contact individual
  90.   authors for permission to publish or re-distribute articles
  91.   seperately. A charge of no greater than 5 US dollars or equivlent may
  92.   be charged for library service / diskette costs for this
  93.   "net-magazine".
  94.  
  95. =============================================================================
  96. In This Issue:
  97.  
  98. Commodore Trivia Corner
  99.  
  100. This section of C=Hacking will contain numerous questions that will test
  101. your knowledge of trivia for the Commodore computers. Each issue they'll
  102. be answers to the previous issues questions and new questions. How much
  103. do you know?
  104.  
  105. InterNet Resources for the Commodore 64 / 128 V1.0
  106.  
  107. This article goes into detail about the available resources on the InterNet
  108. and is meant to introduce people to the wonderful, wacky world of the
  109. InterNet. It covers what the InterNet is, what capabilities it has and
  110. how to access those capabilities. In addition, it also includes Howard
  111. Herman's latest list of File Transfer sites for the Commodore computers.
  112.  
  113. Hiding kilobytes
  114.  
  115. Most Commodore 64 programs do not utilize even nearly all of the 64 kB
  116. random access memory space. By default, there are only 44 kilobytes of
  117. accessible RAM. This article describes how you can take the hiding 20
  118. kilobytes to use.
  119.  
  120. FLD - Scrolling the Screen
  121.  
  122. This article, using a technique described by Pasi Ojala in the last
  123. issue of C=Hacking, gives an example of a program using Flexible Line
  124. Distance technique.
  125.  
  126. Tech-tech - more resolution to vertical shift
  127.  
  128. At one time half of the demos had pictures waving horizontally on the width
  129. of the whole screen. This effect is named tech-tech and it is done using
  130. character graphics. How exactly and is the same possible with sprites ?
  131.  
  132. ACE-128/64 PROGRAMMER'S REFERENCE GUIDE (version 0.9, for Release #10)
  133.  
  134. This article explains the complete system interface for the ACE-128/64
  135. computing environment.  It is intended to be used by programmers for
  136. developing software to run on top of the ACE kernel.  ACE is a program
  137. for the Commodore 128 and Commodore 64 that provides a command shell
  138. environment that is similar to that of Unix.
  139.  
  140. ===============================================================================
  141. Commodore Trivia Corner
  142. by Jim Brain (brain@mail.msen.com)
  143.  
  144. Everyone who reads this article has had, or presently owns a Commodore
  145. computer of some kind.  I own more than one, which is not uncommon among
  146. Commodore enthusiasts.  Well, I bought my first Commodore computer in
  147. 1982, a brand new Vic-20 with some game cartridges.  I had wanted an
  148. Atari, but father knew best and he told the then 11 year old son that
  149. computers would shape my life more than any game machine.  Well, it is
  150. 11 years later and a Computer Engineering Degree earned, and I have
  151. spent many a night during that time playing on many models of Commdore
  152. equipment.  Now, I would like to share the knowledge I have with you in
  153. an interesting way.
  154.  
  155. As you now know a little about me, let us see how much you know about
  156. the machines and company that binds us all together.  The following is
  157. an installment of Commodore Trivia.  These questions have been gleaned
  158. from books, magazines, persoanl knowledge, work on the machines in
  159. questions, and other fellow commodore users happy to share interesting
  160. bits of semi- useless knowledge concerning the CBM systems.
  161.  
  162. This installment consists of two parts, the December 1993 edition
  163. complete with answers and the January 1994 edition without answers.
  164. Each new issue of Commodore Hacking Magazine will contain more
  165. questions, as well as answers to the previous issue's questions.  Each
  166. new edition is also posted every month on the 12th of the month on the
  167. Usenet newsgroup comp.sys.cbm. Winners will be announced on the
  168. newsgroup, and prizes may be awarded. For anyone wishing to submit
  169. answers from this article, please email your responses with question
  170. numbers preceeding each answer to :
  171.  
  172.   brain@msen.com
  173.   
  174. The answers to this edition will be posted on the 12th of February in
  175. comp.sys.cbm with the next edition of questions.  Have fun trying to
  176. answer the questions and feel free to send me a note with new questions.
  177. I can always use them.
  178.  
  179.   [Ed's Note: In addition, the mailserver that I have setup for
  180.   C=Hacking will make provisions to allow individuals to retrieve the
  181.   newest set of questions and last month's answers. Currently not
  182.   implemented, it should be available soon. Details in the next issue.
  183.  
  184.   Also due to C= Hacking being published fairly irregularly and not
  185.   every month the column here will contain answers to the last issue of
  186.   C=Hacking's questions and have new questions for the month that it's
  187.   released in.]
  188.  
  189. -----------------------------------------------------------------------------
  190. Here are the answers to the 10 questions in Commdore Triva Edition #1 for
  191. December 1993. [that were posted on comp.sys.cbm]
  192.  
  193. Q $000) Commodore started out into computing with the PET series of
  194.         computers.  I am not sure if the first ones had PET emblem, but
  195.         nonetheless, What does P E T stand for?
  196.  
  197. A $000) Personal Electronic Transactor
  198.         Since the acronym was made up before the expansion, the following
  199.         are also valid:
  200.   
  201.     Personal Electronic Translator
  202.     Peddle's Ego Trip
  203.                       
  204. Q $001) Commodore planned to manufacture a successor series to the 
  205.         successful Commodore 64 home computer.  Both were intended to
  206.         be Business machines.  We all know this resulted in the Commodore
  207.         Plus 4, but what were the machines originally called and what was
  208.         the difference between the two?
  209.  
  210. A $001) the 364, which had, among other things, a larger Plus 4 style case
  211.         that housed the regular keyboard plus a numeric keypad. the 264
  212.         turned into the Plus 4, with 64K of RAm.  We will never know much
  213.         more about the 364, since it got scrapped.
  214.   
  215. Q $002) How much free memory does a Vic-20 have (unexpanded)?
  216.      
  217. A $002) Oooh! There are many answers for this.
  218.       The VIC has 3583 bytes of RAM for BASIC
  219.       The VIC has 4096 bytes of RAM for ML
  220.       The VIC has 5120 bytes of RAM. 4K of RAM + 1K for Video.
  221.       
  222. Q $003) What early 80's Commodore software company had a Light Bulb
  223.         as a company logo?
  224.  
  225. A $003) Skyles Electric Works.
  226.      
  227.       The Vic-20 came out with a few peripherals I want the model
  228.       numbers for the :
  229.  
  230. Q $004) Disk Drive
  231.      
  232. A $004) VIC-1540 - Same as 1541, only faster serial spped.
  233.       
  234. Q $005) Cassette Player
  235.      
  236. A $005) VIC-1530
  237.      
  238. Q $006) Printer
  239.      
  240. A $006) VIC 1515, which, by a miscommunication, could only use 7.5" paper.
  241.         Evidently, someone thought 8.5" meant full width of paper w/ perfs!
  242.         This printer was quickly supplanted and overtaken by the 1525, which
  243.         should own this title in the first place!
  244.  
  245. Q $007) 16 K Ram Expansion.
  246.      
  247. A $007) VIC-1111
  248.            
  249. Q $008) Commodore Introduced 3 printers that used the same printer mechanism.
  250.         What are the model numbers.
  251.  
  252. A $008) MPS 802 (Square Dots, Serial), CBM 1526 (Round Dots, Serial), 
  253.         PET 4023 (Round Dots, IEEE-488).
  254.  
  255. Q $009) What is the diferences between the printers in #9
  256.      
  257. A $009) MPS 802 (Square Dots, Serial), CBM 1526 (Round Dots, Serial), 
  258.         PET 4023 (Round Dots, IEEE-488).
  259.       
  260. -----------------------------------------------------------------------------
  261. Here are the questions for Commodore Trivia Edition #2 for January 1994.        
  262.  
  263. Q $00A) What was the Code-Name of the Amiga while in Development?
  264.  
  265. Q $00B) What is Lord British's Real Name (The creator of the Ultima
  266.         Series)?
  267.   
  268. Q $00C) What is the POKE location and value that will fry an early model
  269.         PET?
  270.   
  271. Q $00D) On the Plus 4 and C-16, the VIC chip was replaced with the TED
  272.         chip.  What does TED stand for?
  273.   
  274. Q $00E) Commodore Produced a Letter Quality Printer in North America
  275.         (maybe elsewhere) for the Commdore Serial Line.  Name it.
  276.  
  277. Q $00F) What is the version of DOS in the 1541?
  278.  
  279. Q $010) What is the Version of BASIC in the Plus 4 and the C-16?
  280.  
  281. Q $011) What are the nicknames of the original three custom Amiga chips?
  282.  
  283. Q $012) Commodore produced a 64 in a PET case.  What is its name and model
  284.         number?
  285.   
  286. Q $013) Commodore sold a 1 megabyte floppy disk drive in a 1541 case.
  287.         Give the model number.
  288.   
  289. Q $014) What does GCR stand for?
  290.  
  291. Q $015) Commdore produced a drive to accompany the Plus 4 introduction.
  292.         Give the model number.
  293.   
  294. Q $016) What does SID stand for?
  295.  
  296. Q $017) What does the acronym KERNAL stand for?
  297.  
  298. Q $018) What version of DOS does the 1571 have?
  299.  
  300. Q $019) What other two Commdore Disk Drives share the same DOS version
  301.         number as the 1571?
  302.  
  303. Q $01A) How many files will the 1571 hold?
  304.       
  305. Q $10B) How many files will the 1541 hold?
  306.      
  307. Q $01C) What did Commodore make right before entering the computer market?
  308.      
  309. Q $01D) Commodore introduced an ill-fated 4 color plotter.  Give the model
  310.         number.
  311.   
  312. Q $01E) Some formats of CP/M write disks using the MFM format.  What does
  313.         MFM stand for?
  314.   
  315. Q $01F) On the Commodore 128, the user manual left two commands undocumented.
  316.         One works, and the other gives a not-implemented error.  Name both
  317.         commands and what each one does or does not do.
  318.  
  319. Some are easy, some are hard, try your hand at it.
  320.  
  321.     Jim Brain
  322.     brain@msen.com
  323. =============================================================================
  324. InterNet Resources for the Commodore 64 / 128 V1.0
  325. by Craig Taylor (duck@pembvax1.pembroke.edu)
  326.  
  327. [This article is placed into public domain by the author. Copying encouraged]
  328.  
  329. The Internet
  330.  
  331. Let me start this article with a quote by another author that everyone
  332. should heed when dealing with the InterNet:
  333.  
  334. "One warning is perhaps in order---this territory we are entering can
  335. become a fantastic time-sink.  Hours can slip by, people can come and
  336. go, and you'll be locked into Cyberspace.  Remember to do your work!
  337.  
  338. With that, I welcome you, the new user, to The Net."
  339.  
  340.                     brendan@cs.widener.edu
  341.                      - Author, Zen and the Art of the Internet
  342.  
  343. What is the InterNet?
  344.  
  345. What exactly is the InterNet? Imagine if you will, when you were a kid
  346. stringing wires between houses in your neighborhood so that you could
  347. talk with the kids that lived beside you. You could talk to those beside
  348. you but not the ones that lived across town. Now, suppose that you
  349. wanted to relay a message to a buddy across town. The only feasible way
  350. would be to send a message to the guy next door; then have him send it
  351. to the correct person. 
  352.  
  353. This is the basic system of the Internet. Computers connected to other
  354. computers that are connected to others. In the above paragrph
  355. communication was limited because of geography - how close individuals
  356. were. The InterNet system; while geography does play a factor, relies
  357. more on how the sites grew up and were established as to how messages
  358. will get passed back and forth. 
  359.  
  360. There are also other networks hooked up to the InterNet that provide
  361. auxilary services to their local group of computers. One large one is
  362. BITNET and UUCP.  Various bbs's also carry items from the InterNet such
  363. as the BitNet news. In addition, online services such as Genie,
  364. Compuserve, and others offer "gate-ways" or ways of getting access to
  365. the resources of the InterNet.
  366.  
  367. Access To The InterNet
  368.  
  369. Gaining Access to the InterNet There are several ways of gaining access
  370. to the InterNet. Your local college may be your best low-cost
  371. opportunity. Typically, if you are a student or faculty or staff, you
  372. may qualify to have an account that allows you to access all the
  373. InterNet facilities described above. If you don't fall into any of these
  374. categories your next best bet is an online service such as America
  375. Online, Genie, or Compuserve as these all support what is known as an
  376. InterNet gateway - allowing you t o access the InterNet through t hem.
  377. (At this time, I don't believe Prodigy has an InterNet gateway - if I'm
  378. wrong I'm sure I'll get tons of mail. Other online services also exist -
  379. I've only listed what I consider the "primary" ones.)
  380.  
  381. Once you've gotten access to the InterNet you may be asking "Okay, I
  382. know what the InterNet _can_ give me - how do I do it?"  Unfortunately,
  383. because the InterNet is run on differant computer systems this will vary
  384. from system to system. Your best bet would be to examine the
  385. documentation and help screens associated with the online service or
  386. college's facilities. Study them over until you can quote them backwards
  387. (well, not quite that much) - Study them over until you understand what
  388. they are saying. Also, having someone who is already experienced with
  389. the InterNet aid you in your explorations is a great help.
  390.  
  391. What is E-MAIL?
  392.  
  393. There are numerous individuals using the InterNet each day. Each is also
  394. able to write the other through the use of Electronic Mail or, as it's
  395. commonly called "e-mail". 
  396.  
  397. To send a message to me you'd use your mail program (the actual
  398. procedure varies depending on what type of machine you use) and tell it
  399. to send the message to my user name, "duck" at my site that I login at -
  400. (currently going to Pembroke State University) hence
  401. "pembvax1.pembroke.edu". So the full address with an "@" sign the
  402. computer needs to use to know how to seperate the computer name and the
  403. user name is "duck@pembvax1.pembroke.edu". 
  404.  
  405. It's easy to talk to somebody in Mexico, Germany, Australia with this
  406. method and it's quicker than the U.S. Postal system (which, on the
  407. InterNet you'll see referred to as Snail Mail (or s-mail) due to it's
  408. slow delivery time compared to e-mail). Projects, Questions, Answers,
  409. Ideas and general chit-chat on how the family is doing, etc can be
  410. relayed over the InterNet.
  411.  
  412. There are also numerous abbreviations and notations that are used in
  413. E-Mail. Some of them are:
  414.  
  415. ttyal8r     - Talk to you later
  416. rtfm      - Read the *uckin' manual
  417. imho      - In My Humble Opinion
  418. rotfl     - Rolls on the Floor Laughing
  419. lol       - Laughs Out Loud.
  420. l8r       - Later
  421. ;-)       - (winks)
  422. :-)       - (smile)
  423. :-(       - (frowns)
  424.  
  425. There are _many_ _many_ more - you can also find a huge list of the
  426. smiley faces (turn your head sideways and look at the ones in
  427. parenthesis above) on the InterNet.
  428.  
  429. You may also hear the phrase "my e-mail bounced". What this means is
  430. that your message, much like a bounced check, did not work right and it
  431. was returned to your account. Typically this happens because of
  432. incorrect addresses, or an incorrect user name.
  433.  
  434. Email Servers
  435.  
  436. Another large way of getting information is from individuals running
  437. what are E-Mail servers from their accounts or from specific accounts.
  438. From Email servers you may request certain files; catalogs of programs
  439. that are availble for request; send messages to be distributed to other
  440. individuals and automatically subscribe yourself to the mailing list for
  441. new items. 
  442.  
  443. The only Email Server specifically designed for the Commodore computers
  444. is one ran by the author. It major intent is that of distributing the
  445. Commodore Hacking magazine as well as programs that are in the
  446. magazine. To get help on how to use it send a message to the author in
  447. the following format:
  448.   To:   duck@pembvax1.pembroke.edu
  449.   Subj: MAILSERV
  450.   Body of message: HELP
  451.  
  452. This specific mailserver is ran twice a day so you should get your reply
  453. within approximately 12 hours. Please be sure to have a subject line of
  454. "MAILSERV".
  455.  
  456. If anyone knows of any other Email Servers existing for the Commodore
  457. computers please let the author know.
  458.  
  459. NewsGroups
  460.  
  461. One of the primary purposes of the InterNet is for educational research
  462. and discussion. For this purpose, there are currently over 2000
  463. newsgroups established dealing with a wide range of social, politicial,
  464. science, computer and educational topics. Some of these range to inane,
  465. whimsical, to practical and useful. 
  466.  
  467. Two of these for the Commodore 64/128 line of computers are:
  468.     comp.sys.cbm
  469.     comp.binaries.cbm
  470.  
  471. The names for the newsgroups start with a short abbreviation such as
  472. "comp" for computers, "sci" for science, "bio" for biology, etc...  The
  473. second group of letters stand for the type of newsgroup "sys for system,
  474. binaries for binaries etc..." while the third describes it better -
  475. "cbm" in this case for Commodore Business Machines. 
  476.  
  477. The newsgroup, Comp.Sys.Cbm supports discussion about anything under the
  478. sun involving the Commodore 8 bit line of computers (and lately, even
  479. talking about the old old ancient calculators that Commodore mae that
  480. might not have even been 8 bit). Comp.Binaries.Cbm allows programs to be
  481. "posted" or made available to everyone who wishes them. There are
  482. programs available that will let you take the "encrypted" text-only
  483. version of the program that you see on the screen and convert them into
  484. the correct binary p rogram.
  485.  
  486. Basically the rules for newsgroups are: 1) Enjoy yourself, 2) Don't
  487. harass others and 3) Try to stay on topic. Newsgroups are read by many
  488. many people - typically you'll get a response to an inquiry within only
  489. an hour or so - sometimes even sooner. But because they're read by so
  490. many people chatter or "babble" as it's known, is also discouraged.
  491. Don't hesitate to post any questions, concerns or comments but make sure
  492. in each message that you post that you have a reason to post.
  493.  
  494. So What's Out There?
  495.  
  496. So why should you be interested in the Internet? Imagine, if you will,
  497. being able to ask questions to numerous individuals, download the latest
  498. in shareware and public-domain software, know the "rumours" and topics
  499. before they exist all for free? (Or at least, only for what your
  500. "hookup" method charges - see Gaining Access to the InterNet latter).
  501. That's what's out on the Internet. Any question you have - there is sure
  502. to be an answer for - any software you're looking for you stand an
  503. extremely good chance of finding something along the lines of your
  504. needs.
  505.  
  506. The major benefit of the Internet as I see it consists of the continued
  507. support for the Commodore computers. Because all these differant means
  508. of obtaining information are not sponsored by any one specific company
  509. or individual the Commodore 8-bit line of computers are guranteed
  510. continued support over the Internet. In addition, because the Internet
  511. strongly frowns upon Commercial advertising you won't find numerous ads
  512. or any other material urging you to "buy this, buy that" like you will
  513. on some other serv ices.
  514.  
  515. FTP Sites
  516.  
  517. FTP stands for File Transfer Protocols and is a method of obtaining
  518. programs that are stored on another system's computers. There are
  519. numerous FTP sites out there in InterNet land - one of the best
  520. currently available for the Commodore computers is that of R.Knop's site
  521. at ccosun.caltech.edu. 
  522.  
  523. [ The following is a list of FTP sites for the Commodore 64 and 128
  524. computes and is currenty maintained by Howard Herman
  525. (h.herman@GEnie.geis.com) and is used with his permission. He usually
  526. posts an updated list to comp.sys.cbm newsgroup every month or so.]
  527. -----------------------------------------------------------------------------
  528. This is the list of FTP sites containing software and programs
  529. specific to the Commodore 64 and 128 computers.
  530.  
  531. I will try to keep this list as current and accurate as possible, so
  532. that it can be a useful resource for users of the newsgroup.
  533.  
  534. PLEASE cooperate and send E-mail to me with any corrections and
  535. updates.  If a site has closed or no longer carries CBM software, let
  536. me know and it will be deleted.  If you uncover a site not listed,
  537. tell me so that it can be added.
  538. -----
  539.  
  540. To use this list on a UNIX system, just type 'ftp <sitename>', where
  541. <sitename> is any of the sites listed below.  Use 'anonymous' as
  542. your login, and your E-mail address for the password.  You can change
  543. and list directories with 'cd' and 'dir', respectively, and download
  544. files to your system using 'get'.  Be sure to specify either 'binary'
  545. if you are getting a program, or 'ascii' for a text file before you
  546. begin the download.
  547. -----
  548.  
  549. In addition to the sites listed below there are hundreds of other
  550. FTP sites on INet with interesting files covering every topic
  551. imaginable.  Take some time to seek out and explore these too.
  552.  
  553. Enjoy!
  554. -----
  555.  
  556. Host sol.cs.ruu.nl   (131.211.80.17)
  557. Last updated 00:39  4 Sep 1993
  558.     Location: /pub/MIDI/PROGRAMS
  559.       DIRECTORY rwxr-xr-x      1024  Aug 26 09:58   C64
  560.     Location: /pub/MIDI/DOC
  561.       FILE      rw-r--r--     40183  Jan 19  1993   C64midi-interface.txt
  562.  
  563. Host uceng.uc.edu   (129.137.33.1)
  564. Last updated 04:38  6 Sep 1993
  565.     Location: /pub/wuarchive/systems/cpm/c128
  566.       FILE      rw-r--r--     24576  Nov  6  1986   c128-mex.com
  567.     Location: /pub/wuarchive/systems/cpm/c64
  568.       FILE      rw-r--r--      1615  Mar 14  1984   c64-cpm.msg
  569.       FILE      rw-r--r--      1536  Feb  9  1985   c64modem.com
  570.       FILE      rw-r--r--      4199  Feb 10  1984   c64modem.doc
  571.       FILE      rw-r--r--     19200  Feb  9  1985   md730c64.com
  572.       FILE      rw-r--r--      2192  Oct  1  1984   md730c64.doc
  573.     Location: /pub/wuarchive/doc/misc/if-archive/infocom/tools
  574.       FILE      r--r--r--      5798  Aug  5 14:42   c64todat.tar.Z
  575.  
  576. Host aix370.rrz.uni-koeln.de   (134.95.80.1)
  577.     Location: /.disk2/usenet/comp.archives/auto/comp.sys.cbm
  578.       DIRECTORY rwxrwxr-x       384  comp.sys.cbm
  579.  
  580. Host ftp.csv.warwick.ac.uk     (137.205.192.5)
  581. Last updated 00:00 18 Jan 1994
  582.     Location: /pub/c64
  583.       FILE      rw-r--r--       909 Jan  8 19:52 C64progs.doc
  584.       FILE      rw-r--r--     19558 Jan  8 19:49 backgamm.sfx
  585.       FILE      rw-r--r--     21384 Jan  8 19:49 chequebo.sfx
  586.       FILE      rw-r--r--     11449 Jan  8 19:49 countdow.sfx
  587.       FILE      rw-r--r--     18136 Jan  8 19:49 draughts.sfx
  588.       FILE      rw-r--r--      5011 Jan  8 19:49 loader.sfx
  589.       FILE      rw-r--r--     17423 Jan  8 19:49 whitewas.sfx
  590. Descriptions:
  591. ============
  592. backgamm - Backgammon board game
  593. chequebo - Cheque Book Organiser, written in basic with UK pound sign as
  594.            currency, but could be changed to suit another.
  595. countdow - LOAD"count example",8,1 and watch the countdown during loading.
  596. draughts - Draughts board game.
  597. loader   - Press RESTORE key and MENU on disk will be automatically re-loaded.
  598. whitewas - Colour squares board game.
  599.     Location: /tmp/c64
  600.      >Temporary files stored here.  If /tmp directory not found, try
  601.      >again at another time.  /tmp directory not always available.
  602.  
  603. Host clover.csv.warwick.ac.uk   (137.205.192.6)
  604. Last updated 13:29 27 Sep 1993
  605.     Location: /pub/c64
  606.       FILE      rw-r--r--       812  c64progs.doc
  607.       FILE      rw-r--r--     73696  c64progs.sfx
  608.  
  609. Host nexus.yorku.ca   (130.63.9.66)
  610. Last updated 00:00 21 Dec 1993
  611.     Location: /pub/Internet-info
  612.       FILE      rw-r--r--      6308  commodore.ftp
  613.      >An older version of this listing.
  614.  
  615. Host rigel.acs.oakland.edu   (141.210.10.117)
  616. Last updated 01:42  3 Sep 1993
  617.     Location: /pub2/cpm
  618.       DIRECTORY rwxr-xr-x      1536  Jun  4  1992   c128
  619.       DIRECTORY rwxr-xr-x       512  c64
  620.     Location: /pub2/cpm/c64
  621.       FILE      rw-r--r--      1615  Mar 14  1984   c64-cpm.msg
  622.       FILE      rw-r--r--      1536  Feb  9  1985   c64modem.com
  623.       FILE      rw-r--r--      4199  Feb 10  1984   c64modem.doc
  624.       FILE      rw-r--r--     19200  Feb  9  1985   md730c64.com
  625.       FILE      rw-r--r--      2192  Oct  2  1984   md730c64.doc
  626.  
  627. Host oak.oakland.edu
  628. Last updated 00:00 18 Dec 1993
  629.     Location: /pub2/cpm
  630.      >For CP/M software, most all of which will run on the C128.
  631.  
  632. Host src.doc.ic.ac.uk   (146.169.2.1)
  633.     Location: /usenet/comp.archives/auto
  634.       DIRECTORY rwxr-xr-x       512  comp.sys.cbm
  635.     Location: /usenet/comp.archives
  636.       DIRECTORY rwxr-xr-x       512  commodore-64-128
  637.       DIRECTORY rwxr-xr-x       512  May  3  1991   c64
  638.     Location: /media/visual/collections/funet-pics/jpeg/games
  639.       DIRECTORY rwxr-xr-x       512  Mar 20 05:48   c64
  640.     Location: /media/visual/collections/funet-pics/jpeg/comp/games
  641.       DIRECTORY rwxr-xr-x       512  May  6 03:55   c64
  642.  
  643. Host tupac-amaru.informatik.rwth-aachen.de   (137.226.112.31)
  644. Last updated 04:59  7 Oct 1992
  645.     Location: /pub/rz.archiv/simtel/cpm
  646.       DIRECTORY rwxr-xr-x       512  c64
  647.       DIRECTORY rwxr-xr-x       512  Sep 21 20:56   c128
  648.  
  649. Host wuarchive.wustl.edu   (128.252.135.4)
  650. Last updated 02:40 23 May 1993
  651.     Location: /systems/amiga/incoming/misc
  652.       FILE      rw-rw-r--     21815  Jan 23 14:26   C64View.lha
  653.       FILE      rw-rw-r--       120  Jan 23 14:26   C64View.readme
  654.     Location: /mirrors/cpm
  655.       DIRECTORY rwxr-xr-x       512  c64
  656.       DIRECTORY rwxr-xr-x      1536  Nov 22  1992   c128
  657.  
  658. Host watsun.cc.columbia.edu   (128.59.39.2)
  659. Last updated 02:07  8 Sep 1993
  660.     Location: /kermit2/old
  661.       DIRECTORY rwxrwxr-x      1024  Jul 12 18:30   c64
  662.     Location: /kermit/bin
  663.  
  664. Host cs.columbia.edu   (128.59.1.2)
  665. Last updated 01:29 12 Sep 1993
  666.     Location: /archives/mirror1/kermit
  667.       FILE      rw-rw-r--     15016  Aug 24  1988   c644th.prg.gz
  668.       FILE      rw-rw-r--       733  Sep 29  1992   c64help.txt.gz
  669.       FILE      rw-rw-r--      6095  Sep 29  1992   c64ker1660.sda.gz
  670.       FILE      rw-rw-r--      5904  Sep 29  1992   c64kerfast.sda.gz
  671.       FILE      rw-rw-r--     26484  Sep 29  1992   c64kerv22a.sda.gz
  672.       FILE      rw-rw-r--     42552  Sep 29  1992   c64kerv22b.sda.gz
  673.       FILE      rw-rw-r--     31982  Sep 29  1992   c64slkv22s.sda.gz
  674.  
  675. Host plaza.aarnet.edu.au   (139.130.4.6)
  676. Last updated 00:00 28 Dec 1993
  677.     Location: /pub/kermit/c
  678.       FILE      r--r--r--      3073  Aug 16  1988   c64boot.bas
  679.       FILE      r--r--r--      1547  Aug 16  1988   c64boot.c
  680.       FILE      r--r--r--      1151  Aug 16  1988   c64boot.clu
  681.       FILE      r--r--r--      3002  Aug 16  1988   c64boot.for
  682.       FILE      r--r--r--      3315  Aug 16  1988   c64boot.sim
  683.      >There are more Kermit files which are not listed.  Be sure to
  684.      >get the complete set of C64/128 Kermit files.
  685.  
  686. Host flubber.cs.umd.edu   (128.8.128.99)
  687. Last updated 00:00 03 Jan 1994
  688.     Location: /rec/newballistic
  689.       FILE      rw-r--r--      8576  Mar 23 21:21   balistic.c64
  690. --------------------------------
  691.  
  692. Host f.ms.uky.edu (128.163.128.6)
  693. Last updated 00:00 28 Dec 1993
  694.     Location: /archive/c64.zip
  695.  
  696. Host ftp.funet.fi (128.214.6.100)
  697. Last updated 06:11 22 Mar 1993
  698.     Location: /pub/pics/jpeg/games
  699.       DIRECTORY rwxrwxr-x       512  Mar 20 02:07   c64
  700.     Location: /pub/misc
  701.       DIRECTORY rwxrwxr-x       512  Mar 13 23:30   c64
  702.     Location: /pub/kermit
  703.       DIRECTORY rwxrwxr-x      1024  Jan 13  1992   c64
  704.     Location: /pub/amiga/audio/misc/sid-tunes
  705.       FILE      rw-rw-r--    671490  Jun 18  1992   C64MusicShow-1.lha
  706.       FILE      rw-rw-r--    316521  Jun 18  1992   C64MusicShow-2.lha
  707.               /pub/cbm
  708.  
  709. Host nic.switch.ch   (130.59.1.40)
  710. Last updated 00:39 31 Aug 1993
  711.     Location: /mirror/kermit/bin
  712.  
  713. Host gmdzi.gmd.de   (129.26.8.90)
  714. Last updated 01:08  1 Aug 1993
  715.     Location: /if-archive/infocom/tools
  716.       FILE      rw-rw-r--      5668  Apr 27 15:00   c64.to.dat
  717.  
  718. Host micros.hensa.ac.uk   (148.88.8.84)
  719.     Location /kermit
  720.       DIRECTORY rwxr-x---      1024  Nov 11 09:20   c64
  721.  
  722. Host wilbur.stanford.edu   (36.14.0.36)
  723.     Location /pub/emulators
  724.       DIRECTORY rwxr-xr-x       512  Jun 30 00:57   c64
  725.  
  726. Host syrinx.umd.edu (128.8.2.114)
  727. Last updated 00:00 28 Dec 1993
  728.     Location: /rush/c64-sounds
  729.  
  730. Host tolsun.oulu.fi (130.231.96.16)
  731. Last updated 01:53  6 Sep 1993
  732.     Location: /pub
  733.       DIRECTORY rwxr-xr-x      1024  Jul 15  1990   c64
  734.     Location: /incoming
  735.       DIRECTORY ---------      1024  Jun 20  1992   c64
  736.         /pub/amiga/4/c64trans.zoo
  737.         /pub/c64
  738.      >Uploading to /pub/c64 is disabled because of lack of disk space.
  739.      >However, for downloading it is still fully accessible.
  740.      >Currently there is no administration for /pub/c64.
  741.      >/pub/amiga is active, though.
  742.  
  743. Host ccosun.caltech.edu (131.215.139.2)
  744. Last updated 00:00 31 JAN 1994
  745.     Location: /pub/rknop
  746.     Location: /pub/rknop/misc
  747.      > 64/128 programs can be found within directories according to
  748.      > function.  When searching, be sure to check related directories.
  749.  
  750. Host ucsd.edu (128.54.16.1)
  751. Last updated 04:46  6 Sep 1993
  752.     Location: /midi/software
  753.       DIRECTORY rwxr-xr-x       512  Jan 27  1992   c64
  754.  
  755. Host cs.dal.ca   (129.173.4.5)
  756. Last updated 01:36 12 Sep 1993
  757.     Location: /comp.archives
  758.       DIRECTORY rwxrwxr-x      3584  Apr  7 04:05   c64
  759.                pub/comp.archives/comp.sys.cbm
  760.  
  761. Host ccnga.uwaterloo.ca
  762. Last updated 00:00 01 Jan 1994
  763.     Location: /pub/cbm/vbm110.uua
  764.      > For VBM Bitmap Viewer version 1.10
  765.  
  766. Host bert.psyc.upei.ca
  767. Last updated 00:00 31 Jan 1994
  768.     Location: /pub
  769.      > All the releases of the major demo parties of '93
  770.  
  771. --------------------------------
  772. Send all info regarding changes/additions/corrections [to the FTP list] to:
  773.  
  774. 72560.3467@CompuServe.COM   or:     h.herman1@GEnie.geis.COM
  775. =============================================================================
  776. Hiding kilobytes
  777. by Marko M"akel"a <Marko.Makela@Helsinki.FI>
  778.  
  779. Most Commodore 64 programs do not utilize even nearly all of the 64 kB
  780. random access memory space. By default, there are only 44 kilobytes of
  781. accessible RAM. This article describes how you can take the hiding 20
  782. kilobytes to use.
  783.  
  784.  
  785. _Memory management_
  786.  
  787.   The Commodore 64 has access to more memory than its processor can
  788. directly handle. This is possible by banking the memory. There are
  789. five user configurable inputs that affect the banking. Three of them
  790. can be controlled by program, and the rest two serve as control lines
  791. on the memory expansion port.
  792.  
  793.   The 6510 MPU has an integrated I/O port with six I/O lines. This
  794. port is accessed through the memory locations 0 and 1. The location 0
  795. is the Data Direction Register for the Peripheral data Register, which
  796. is mapped to the other location. When a bit in the DDR is set, the
  797. corresponding PR bit controls the state of a corresponding Peripheral
  798. line as an output. When it is clear, the state of the Peripheral line
  799. is reflected by the Peripheral register. The Peripheral lines are
  800. numbered from 0 to 5, and they are mapped to the DDR and PR bits 0 - 5,
  801. respectively. The 8502 processor, which is used in the Commodore 128,
  802. has seven Peripheral lines in its I/O port. The seventh line is connected
  803. to the Caps lock or ASC/CC key.
  804.  
  805.   The I/O lines have the following functions:
  806.  
  807.      Direction  Line  Function
  808.      ---------  ----  --------
  809.         out      P5   Cassette motor control. (0 = motor spins)
  810.         in       P4   Cassette sense. (0 = PLAY button depressed)
  811.         out      P3   Cassette write data.
  812.         out      P2   CHAREN
  813.         out      P1   HIRAM
  814.         out      P0   LORAM
  815.  
  816.   The default value of the DDR register is $2F, so all lines except
  817. Cassette sense are outputs. The default PR value is $37 (Datassette
  818. motor stopped, and all three memory management lines high).
  819.  
  820.   Like most chips in the Commodore 64, the 6510 MPU uses the NMOS
  821. (N-channel metal oxide semiconductor) technology. The NMOS switches
  822. produce strong logical '0' levels, but weak '1' levels. The opposite
  823. is the PMOS (P-channel metal oxide semiconductor) technology, which
  824. cannot pull strong signals low, but is able to drive them high. The CMOS
  825. technology (complementary metal oxide semiconductor), which combines
  826. these two technologies, is able to drive both logical levels.
  827.  
  828.   Because most integrated circuits in the C64 use the NMOS technology,
  829. all hardware lines that are not outputs are driven to +5 volts with a
  830. weak current. This is usually accomplished by pull-up resistors, large
  831. resistances between the hardware lines and the +5 volt power supply
  832. line. The resistors can be inside a chip or on the printed circuit
  833. board. This allows any NMOS or CMOS chip to drive the line to the
  834. desired state (low or high voltage level).
  835.  
  836.   The difference between an input and an output is that an output uses
  837. more current to drive the signal to the desired level. An input and an
  838. output outputting logical '1' are equivalent for any other inputting
  839. chip. But if a chip is trying to drive a signal to ground level, it
  840. needs more current to sink an output than an input. You can even use
  841. outputs as inputs, i.e. read them in your program.
  842.  
  843.         You can use this feature to distinquish between the left
  844.       shift and the shift lock keys, although they are connected
  845.       to same hardware lines. The shift lock key has smaller
  846.       resistance than the left shift. If you make both CIA 1
  847.       ports to outputs (write $FF to $DC03 and $DC01) prior
  848.       reading the left shift key, only shift lock can change the
  849.       values you read from CIA 1 port B ($DC01).)
  850.  
  851.   So, if you turn any memory management line to input, the external
  852. pull-up resistors will make it look like it is outputting logical
  853. '1'. This is actually why the computer always switches the ROMs in
  854. upon startup: Pulling the -RESET line low resets all Peripheral lines
  855. to inputs, thus driving all three processor-driven memory management
  856. lines high.
  857.  
  858.   The two remaining memory management lines are -EXROM and -GAME on
  859. the cartridge port. Each line has a pull-up resistor, so the lines are
  860. '1' by default. (In the Commodore 128, you can set the state of these
  861. two lines prior to selecting the C64 mode, provided that you write the
  862. mode switch routine yourself.)
  863.  
  864.   Even though the memory banking has been implemented with a 82S100
  865. Programmable _Logic_ Array, there is only one control line that seems
  866. to behave logically at first sight, the -CHAREN line. It is mostly
  867. used to choose between I/O address space and the character generator
  868. ROM. The following memory map introduces the oddities of -CHAREN and
  869. the other memory management lines. It is based on the memory maps in
  870. the Commodore 64 Programmer's Reference Guide, pp. 263 - 267, and some
  871. errors and inaccuracies have been corrected.
  872.  
  873.   The leftmost column of the table contains addresses in hexadecimal
  874. notation. The columns aside it introduce all possible memory
  875. configurations. The default mode is on the left, and the absolutely
  876. most rarely used Ultimax game console configuration is on the right.
  877. (There have been at least two Ultimax cartridges on the market.) Each
  878. memory configuration column has one or more four-digit binary numbers
  879. as a title. The bits, from left to right, represent the state of the
  880. -LORAM, -HIRAM, -GAME and -EXROM lines, respectively. The bits whose
  881. state does not matter are marked with "x". For instance, when the
  882. Ultimax video game configuration is active (the -GAME line is shorted
  883. to ground, -EXROM kept high), the -LORAM and -HIRAM lines have no effect.
  884.  
  885.  
  886.       default                                                         Ultimax
  887.         1111    101x    1000    011x    001x    1110    0100    1100    xx01
  888.                                 00x0
  889. 10000
  890. -----------------------------------------------------------------------------
  891.  F000
  892.         Kernal  RAM     RAM     Kernal  RAM     Kernal  Kernal  Kernal  ROMH(*
  893.  E000
  894. -----------------------------------------------------------------------------
  895.  D000   IO/C    IO/C    IO/RAM  IO/C    RAM     IO/C    IO/C    IO/C    I/O
  896. -----------------------------------------------------------------------------
  897.  C000   RAM     RAM     RAM     RAM     RAM     RAM     RAM     RAM      -
  898. -----------------------------------------------------------------------------
  899.  B000
  900.         BASIC   RAM     RAM     RAM     RAM     BASIC   ROMH    ROMH     -
  901.  A000
  902. -----------------------------------------------------------------------------
  903.  9000
  904.         RAM     RAM     RAM     RAM     RAM     ROML    RAM     ROML    ROML(*
  905.  8000
  906. -----------------------------------------------------------------------------
  907.  7000
  908.  
  909.  6000
  910.         RAM     RAM     RAM     RAM     RAM     RAM     RAM     RAM      -
  911.  5000
  912.  
  913.  4000
  914. -----------------------------------------------------------------------------
  915.  3000    
  916.  
  917.  2000   RAM     RAM     RAM     RAM     RAM     RAM     RAM     RAM      -
  918.  
  919.  1000
  920. -----------------------------------------------------------------------------
  921.  0000   RAM     RAM     RAM     RAM     RAM     RAM     RAM     RAM     RAM
  922. -----------------------------------------------------------------------------
  923.  
  924.     *) Internal memory does not respond to write accesses to these areas.
  925.  
  926.  
  927.     Legend: Kernal      E000-FFFF       Kernal ROM.
  928.  
  929.             IO/C        D000-DFFF       I/O address space or Character
  930.                                         generator ROM, selected by -CHAREN.
  931.                                         If the CHAREN bit is clear,
  932.                                         the character generator ROM is
  933.                                         chosen. If it is set, the
  934.                                         I/O chips are accessible.
  935.  
  936.             IO/RAM      D000-DFFF       I/O address space or RAM,
  937.                                         selected by -CHAREN.
  938.                                         If the CHAREN bit is clear,
  939.                                         the character generator ROM is
  940.                                         chosen. If it is set, the
  941.                                         internal RAM is accessible.
  942.  
  943.             I/O         D000-DFFF       I/O address space.
  944.                                         The -CHAREN line has no effect.
  945.  
  946.             BASIC       A000-BFFF       BASIC ROM.
  947.  
  948.             ROMH        A000-BFFF or    External ROM with the -ROMH line
  949.                         E000-FFFF       connected to its -CS line.
  950.  
  951.             ROML        8000-9FFF       External ROM with the -ROML line
  952.                                         connected to its -CS line.
  953.  
  954.             RAM         various ranges  Commodore 64's internal RAM.
  955.  
  956.             -           1000-7FFF and   Open address space. 
  957.                         A000-CFFF       The Commodore 64's memory chips
  958.                                         do not detect any memory accesses
  959.                                         to this area except the VIC-II's
  960.                                         DMA and memory refreshes.
  961.  
  962.     NOTE:   Whenever the processor tries to write to any ROM area
  963.             (Kernal, BASIC, CHAROM, ROML, ROMH), the data will get
  964.             "through the ROM" to the C64's internal RAM.
  965.  
  966.             For this reason, you can easily copy data from ROM to RAM,
  967.             without any bank switching. But implementing external
  968.             memory expansions without DMA is very hard, as you have to
  969.             use the Ultimax memory configuration, or the data will be
  970.             written both to internal and external RAM.
  971.  
  972.             However, this is not true for the Ultimax game
  973.             configuration. In that mode, the internal RAM ignores all
  974.             memory accesses outside the area $0000-$0FFF, unless they are
  975.             performed by the VIC, and you can write to external memory
  976.             at $1000-$CFFF and $E000-$FFFF, if any, without changing
  977.             the contents of the internal RAM.
  978.  
  979.  
  980. _A note concerning the I/O area_
  981.  
  982.   The I/O area is divided as follows:
  983.  
  984.      Address range  Owner
  985.      -------------  -----
  986.        D000-D3FF    MOS 6567/6569 VIC-II Video Interface Controller
  987.        D400-D7FF    MOS 6581 SID Sound Interface Device
  988.        D800-DBFF    Color RAM (only lower nybbles are connected)
  989.        DC00-DCFF    MOS 6526 CIA Complex Interface Adapter #1
  990.        DD00-DDFF    MOS 6526 CIA Complex Interface Adapter #2
  991.        DE00-DEFF    User expansion #1 (-I/O1 on Expansion Port)
  992.        DF00-DFFF    User expansion #2 (-I/O2 on Expansion Port)
  993.  
  994.   As you can see, the address ranges for the chips are much larger
  995. than required. Because of this, you can access the chips through
  996. multiple memory areas. The VIC-II appears in its window every $40
  997. addresses. For instance, the addresses $D040 and $D080 are both mapped
  998. to the Sprite 0 X co-ordinate register. The SID has one register
  999. selection line less, thus it appears at every $20 bytes. The CIA
  1000. chips have only 16 registers, so there are 16 copies of each in their
  1001. memory area.
  1002.  
  1003.   However, you should not use other addresses than those specified by
  1004. Commodore. For instance, the Commodore 128 mapped its additional I/O
  1005. chips to this same memory area, and the SID responds only to the
  1006. addresses D400-D4FF, also when in C64 mode. And the Commodore 65,
  1007. which unfortunately did not make its way to the market, could narrow
  1008. the memory window reserved for the MOS 6569/6567 VIC-II (or CSG 4567
  1009. VIC-III in that machine).
  1010.  
  1011.  
  1012. _The video chip_
  1013.  
  1014.   The MOS 6567/6569 VIC-II Video Interface Controller has access to
  1015. only 16 kilobytes at a time. To enable the VIC-II to access the whole
  1016. 64 kB memory space, the main memory is divided to four banks of 16 kB
  1017. each. The lines PA0 and PA1 of the second CIA are the inverse of the
  1018. virtual VIC-II address lines VA14 and VA15, respectively. To select a
  1019. VIC-II bank other than the default, you must program the CIA lines to
  1020. output the desired bit pair. For instance, the following code selects
  1021. the memory area $4000-$7FFF (bank 1) for the video controller:
  1022.  
  1023.     LDA $DD02 ; Data Direction Register A
  1024.     ORA #$03  ; Set pins PA0 and PA1 to outputs
  1025.     STA $DD02
  1026.     LDA $DD00
  1027.     AND #$FC  ; Mask the lowmost bit pair off
  1028.     ORA #$02  ; Select VIC-II bank 1 (the inverse of binary 01 is 10)
  1029.     STA $DD00
  1030.  
  1031.   Why should you set the pins to outputs? Hardware RESET resets all
  1032. I/O lines to inputs, and thanks to the CIA's internal pull-up
  1033. resistors, the inputs actually output logical high voltage level. So,
  1034. upon -RESET, the video bank 0 is selected automatically, and older
  1035. Kernals could leave it uninitialized.
  1036.  
  1037.   Note that the VIC-II always fetches its information from the
  1038. internal RAM, totally ignoring the memory configuration lines. There
  1039. is only one exception to this rule: The character generator ROM.
  1040. Unless the Ultimax mode is selected, VIC-II "sees" character generator
  1041. ROM in the memory areas 1000-1FFF and 9000-9FFF. If the Ultimax
  1042. configuration is active, the VIC-II will fetch all data from the
  1043. internal RAM.
  1044.  
  1045.  
  1046. _An application: Making an operating system extension_
  1047.  
  1048.   If you are making a memory resident program and want to make it as
  1049. invisible to the system as possible, probably the best method is
  1050. keeping most of your code under the I/O area (in the RAM at
  1051. $D000-$DFFF). This area is very safe, since programs utilizing it are
  1052. rare, since they are very difficult to implement and to debug. You
  1053. need only a short routine in the normally visible RAM that pushes the
  1054. current value of the processor's I/O register $01 on stack, switches
  1055. RAM on to $D000-$DFFF and jumps to this area. Returning from the
  1056. $D000-$DFFF area is possible even without any routine in the normally
  1057. visible RAM area. Just write an RTS or an RTI to an I/O register and
  1058. return through it.
  1059.  
  1060.   But what if your program needs to use I/O? And how can you write the
  1061. return instruction to an I/O register while the I/O area is switched
  1062. off? You need a swap area for your program in normally visible memory.
  1063. The first thing your routine at $D000-$DFFF does is copying the I/O
  1064. routines (or the whole program) to normally visible memory, swapping
  1065. the bytes. For instance, if your I/O routines are initially being
  1066. stored at $D200-$D3FF, exchange the bytes in $D200-$D3FF with the
  1067. contents of $C000-$C1FF. Now you can call the I/O routines from your
  1068. routine at $D000-$DFFF, and the I/O routines can switch the I/O area
  1069. temporarily on to access the I/O chips. And right before exiting your
  1070. program at $D000-$DFFF swaps the old contents of that I/O routine area
  1071. in, e.g. exchanges the memory areas $D200-$D3FF and $C000-$C1FF
  1072. again.
  1073.  
  1074.   What I/O registers can you use for the return instruction? There are
  1075. basically two alternatives: 8-bit VIC sprite registers or either CIA's
  1076. serial port register. The VIC registers are easiest to use, as they
  1077. act precisely like memory places: you can easily write the desired
  1078. value to a register. But the CIA register is usually better, as
  1079. changing the VIC registers might change the screen layout.
  1080.  
  1081.   However, also the SP register has some drawbacks: If the machine's
  1082. CNT1 and CNT2 lines are connected to a frequency source, you must stop
  1083. either CIA's Timer A to use the SP register method. Normally the 1st
  1084. CIA's Timer A is the main hardware interrupt source. And if you use
  1085. the Kernal's RS232, you cannot stop the 2nd CIA's Timer A either. Also,
  1086. if you don't want to lose any CIA interrupts, you might want to know
  1087. that executing the RTS or RTI at SP register has the side effect of
  1088. reading the Interrupt Control Register, thus acknowledging an interrupt
  1089. that might have been waiting.
  1090.  
  1091.   If you can't use either method, you can use either CIA's ToD seconds
  1092. or minutes or ToD alarm time for storing an RTI. Or, if you don't want
  1093. to alter any registers, use the VIC-II's light pen register. Before
  1094. exiting, wait for appropriate raster line and trig the light pen latch
  1095. with CIA1's PB4 bit. However, this method assumes that the control
  1096. port 1's button/light pen line remains up for that frame. After
  1097. trigging the light pen, causing the light pen Y co-ordinate register
  1098. ($D014) to be $40 or $60, you have more than half a frame time to
  1099. restore the state of the I/O chips and return through the register.
  1100.  
  1101.   You can also use the SID to store an RTI or RTS command. How is this
  1102. possible, you might ask. After all, the chip consists of read only or
  1103. write only registers. However, there are two registers that can be
  1104. controlled by program, the envelope generator and oscillator outputs
  1105. of the third voice. This method requires you to change the frequency
  1106. of voice 3 and to select a waveform for it. This will affect on the
  1107. voice output by turning the voice 3 off, but who would keep the voice
  1108. 3 producing a tone while calling an operating system routine?
  1109.  
  1110.   Also keep in mind that the user could press RESTORE while the Kernal
  1111. ROM and I/O areas are disabled. You could write your own non-maskable
  1112. interrupt (NMI) handler (using the NMI vector at $FFFA), but a fast
  1113. loader that uses very tight timing would still stop working if the
  1114. user pressed RESTORE in the middle of a data block transfer. So, to
  1115. make a robust program, you have to disable NMI interrupts. But how is
  1116. this possible? They are Non-Maskable after all. The NMI interrupt is
  1117. edge-sensitive, the processor jumps to NMI handler only when the -NMI
  1118. line drops from +5V to ground. To disable the interrupt, simply cause
  1119. an NMI with CIA2's timer, but don't read the Interrupt Control
  1120. register. If you need to read $DD0D in your program, you must add a
  1121. NMI handler just in case the user presses RESTORE. And don't forget to
  1122. raise the -NMI line upon exiting the program.  Otherwise the RESTORE
  1123. key does not work until the user issues a -RESET or reads the ICR
  1124. register explicitly. (The Kernal does not read $DD0D, unless it is
  1125. handling an interrupt.) This can be done automatically by the two
  1126. following SP register examples due to one of the 6510's undocumented
  1127. features (refer to the descriptions of RTS and RTI below).
  1128.  
  1129.         ; Returning via VIC sprite 7 X co-ordinate register
  1130.  
  1131.         Initialization:   ; This is executed when I/O is switched on
  1132.                 LDA #$60
  1133.                 STA $D015 ; Write RTS to VIC register $15.
  1134.  
  1135.         Exiting:          ; NOTE: This procedure must start at VIC register
  1136.                           ; $12. You have multiple alternatives, as the VIC
  1137.                           ; appears in memory at $D000+$40*n, where $0<=n<=$F.
  1138.  
  1139.                 PLA       ; Pull the saved 6510 I/O register state from stack
  1140.                 STA $01   ; Restore original memory bank configuration
  1141.                           ; Now the processor fetches the RTS command from the
  1142.                           ; VIC register $15.
  1143.  
  1144.  
  1145.         ; Returning via CIA 2's ToD or ToD alarm seconds register
  1146.  
  1147.         Initialization:   ; This is executed when I/O is switched on
  1148.                 LDA #$40  
  1149.                 STA $DD08 ; Set ToD tenths of seconds
  1150.                           ; (clear it so that the seconds register
  1151.                           ; would not overflow)
  1152.                           ; If ToD alarm register is selected, this
  1153.                           ; instruction will be unnecessary.
  1154.                 STA $DD09 ; Set ToD seconds
  1155.                 LDA $DD0B ; Read ToD hours (freeze ToD display)
  1156.  
  1157.         Exiting:          ; NOTE: This procedure must start at CIA 2 register
  1158.                           ; $6. As the CIA 2 appears in memory at $DD00+$10*n,
  1159.                           ; where 0<=n<=$F, you have sixteen alternatives.
  1160.                 PLA
  1161.                 STA $01   ; Restore original memory bank configuration
  1162.                           ; Now the processor fetches the RTS command from
  1163.                           ; the CIA 2 register $9.
  1164.  
  1165.  
  1166.         ; Returning via CIA 2's SP register (assuming that CNT2 is stable)
  1167.  
  1168.         Initialization:   ; This is executed when I/O is switched on
  1169.                 LDA $DD0E ; CIA 2's Control Register A
  1170.                 AND #$BF  ; Set Serial Port to input
  1171.                 STA $DD0E ; (make the SP register to act as a memory place)
  1172.                 LDA #$60
  1173.                 STA $DD0C ; Write RTS to CIA 2 register $C.
  1174.  
  1175.         Exiting:          ; NOTE: This procedure must start at CIA 2 register
  1176.                           ; $9. As the CIA 2 appears in memory at $DD00+$10*n,
  1177.                           ; where 0<=n<=$F, you have sixteen alternatives.
  1178.                 PLA
  1179.                 STA $01   ; Restore original memory bank configuration
  1180.                           ; Now the processor fetches the RTS command from
  1181.                           ; the CIA 2 register $C.
  1182.  
  1183.  
  1184.         ; Returning via CIA 2's SP register, stopping the Timer A
  1185.         ; and forcing SP2 and CNT2 to output
  1186.  
  1187.         Initialization:   ; This is executed when I/O is switched on
  1188.                 LDA $DD0E ; CIA 2's Control Register A
  1189.                 AND #$FE  ; Stop Timer A
  1190.                 ORA #$40  ; Set Serial Port to output
  1191.                 STA $DD0E ; (make the SP register to act as a memory place)
  1192.                 LDA #$60
  1193.                 STA $DD0C ; Write RTS to CIA register $C.
  1194.  
  1195.         Exiting:          ; NOTE: This procedure must start at CIA 2 register
  1196.                           ; $9. As the CIA 2 appears in memory at $DD00+$10*n,
  1197.                           ; where 0<=n<=$F, you have sixteen alternatives.
  1198.                 PLA
  1199.                 STA $01   ; Restore original memory bank configuration
  1200.                           ; Now the processor fetches the RTS command from
  1201.                           ; the CIA 2 register $C.
  1202.  
  1203.         ; Returning via SID oscillator 3 output register
  1204.  
  1205.         Initialization:   ; This is executed when I/O is switched on
  1206.                 LDA #$20  ; Select sawtooth waveform
  1207.                 STA $D412 ; but do not enable the sound
  1208.                 LDY #$00  ; Select frequency
  1209.                 STY $D40E ; (system clock)/$FF00,
  1210.                 LDA #$FF  ; causing the OSC3 output to increment by one
  1211.                 STY $D40F ; every $10000/$FF00 cycles.
  1212.  
  1213.                 LDA #$0E
  1214.                 LDX #$60
  1215.  
  1216.                 BIT $D41B ; Wait for the oscillator 3 output
  1217.                 BMI *-3   ; to be in the range
  1218.                 BVS *-5   ; $00-$3F.
  1219.                 BIT $D41B ; Wait for the oscillator 3 output
  1220.                 BVC *-3   ; to be at least $40.
  1221.  
  1222.                 STA $D40F ; Slow down the frequency to (system clock)/$0E00.
  1223.                 CPX $D41B ; Wait for the oscillator 3
  1224.                 BNE *-3   ; output to reach $60 (RTS)
  1225.  
  1226.                 STY $D40F ; Reset the frequency of voice 3
  1227.                           ; (stop the OSC3 register from increasing)
  1228.  
  1229.         Exiting:          ; NOTE: This procedure must start at SID register
  1230.                           ; $18. As the SID appears in memory at $D400+$20*n,
  1231.                           ; where 0<=n<=$20, you have thirty-two alternatives.
  1232.                           ; However, in C128 there are only eight alternatives,
  1233.                           ; as the SID is only at $D400-$D4FF.
  1234.  
  1235.                 PLA
  1236.                 STA $01   ; Restore original memory bank configuration
  1237.                           ; Now the processor fetches the RTS command from
  1238.                           ; the SID register $1B.
  1239.  
  1240.  
  1241.   For instance, if you want to make a highly compatible fast loader,
  1242. make the ILOAD vector ($0330) point to the beginning of the stack
  1243. area. Remember that the BASIC interpreter uses the first bytes of
  1244. stack while converting numbers to text. A good address is $0120.
  1245. Robust programs practically never use so much stack that it could
  1246. corrupt this routine. Usually only crunched programs (demos and alike)
  1247. use all stack in the decompression phase. They also make use of the
  1248. $D000-$DFFF area.
  1249.  
  1250.   This stack routine will jump to your routine at $D000-$DFFF, as
  1251. described above. For performance's sake, copy the whole byte transfer
  1252. loop to the swap area, e.g. $C000-$C1FF, and call that subroutine
  1253. after doing the preliminary work. But what about files that load over
  1254. $C000-$C1FF? Wouldn't that destroy the transfer loop and jam the
  1255. machine? Not necessarily. If you copy those bytes to your swap area at
  1256. $D000-$DFFF, they will be loaded properly, as your program restores
  1257. the original $C000-$C1FF area.
  1258.  
  1259.   If you want to make your program user-friendly, put a vector
  1260. initialization routine to the stack area as well, so that the user can
  1261. restore the fast loader by issuing a SYS command, rather than loading
  1262. it each time he has pressed RESET.
  1263.  
  1264.  
  1265. _An example: A "hello world" program_
  1266.  
  1267.   To help you in getting started, I have written a small example
  1268. program that echoes the famous message "hello, world!" to standard
  1269. output (normally screen) using the Kernal's CHROUT subroutine. After
  1270. the initialization routine has been run, the program can be started by
  1271. commanding SYS 300. I used the Commodore 128's machine language
  1272. monitor to put it up, but it was still pretty difficult to debug the
  1273. program. Here it is in uuencoded format:
  1274.  
  1275. begin 644 hello
  1276. M`0@+",D'GC(P-C$```!XI0%(*?B%`:(,O3`(G2P!RA#WHHN]/`B=8]W*T/=H
  1277. MA0%88*4!JBGX"01XA0%,I-WF`:*!C@W=H@".!=WHC@3=HMV.#MVB0(X,W<8!
  1278. M8*4!2`D#A0&@#+DSP"#2_X@0]VB%`6`A1$Q23U<@+$],3$5(BDBM^O](K?O_
  1279. M2*D6C?K_J<"-^_\@W-T@`,!HC?O_:(WZ_R`=P"#<W6BHJ0!(NOX"`=`#_@,!
  1280. 5A`&@/[X`P+EDW9D`P(J99-V($/!@
  1281. `
  1282. end
  1283.  
  1284.   In order to fully understand the operation of this program, you need
  1285. to know how the instructions RTI, RTS and PHA work. There is some work
  1286. going on to reverse engineer the NMOS 6502 microprocessor to large
  1287. extent, and it is now known for most instructions what memory places
  1288. they access during their execution and for what purpose. The internal
  1289. procedures haven't been described in detail yet, but these
  1290. descriptions should be easier to read anyway.
  1291.  
  1292.   For curiosity, I quote here the description of all instructions that
  1293. use the stack. The descriptions of internal operations are yet
  1294. inaccurate, but the memory accesses have been verified with an
  1295. oscilloscope. I will mail copies the whole document upon request. When
  1296. finished, the document will be put on an FTP site.
  1297.  
  1298.      JSR
  1299.  
  1300.         #  address R/W description
  1301.        --- ------- --- -------------------------------------------------
  1302.         1    PC     R  fetch opcode, increment PC
  1303.         2    PC     R  fetch address's low byte to latch, increment PC
  1304.         3  $0100,S  R
  1305.         4  $0100,S  W  push PCH on stack, decrement S
  1306.         5  $0100,S  W  push PCL on stack, decrement S
  1307.         6    PC     R  copy latch to PCL, fetch address's high byte to
  1308.                        latch, copy latch to PCH
  1309.  
  1310.  
  1311.      RTS
  1312.  
  1313.         #  address R/W description
  1314.        --- ------- --- -----------------------------------------------
  1315.         1    PC     R  fetch opcode, increment PC
  1316.         2    PC     R  read next instruction byte (and throw it away),
  1317.                        increment PC
  1318.         3  $0100,S  R  increment S
  1319.         4  $0100,S  R  pull PCL from stack, increment S
  1320.         5  $0100,S  R  pull PCH from stack
  1321.         6    PC     R  increment PC
  1322.  
  1323.  
  1324.      BRK
  1325.  
  1326.         #  address R/W description
  1327.        --- ------- --- -----------------------------------------------
  1328.         1    PC     R  fetch opcode, increment PC
  1329.         2    PC     R  read next instruction byte (and throw it away),
  1330.                        increment PC
  1331.         3  $0100,S  W  push PCH on stack, decrement S
  1332.         4  $0100,S  W  push PCL on stack, decrement S
  1333.         5  $0100,S  W  push P on stack (with B flag set), decrement S,
  1334.                        set I flag
  1335.         6   $FFFE   R  fetch PCL
  1336.         7   $FFFF   R  fetch PCH
  1337.  
  1338.  
  1339.      RTI
  1340.  
  1341.         #  address R/W description
  1342.        --- ------- --- -----------------------------------------------
  1343.         1    PC     R  fetch opcode, increment PC
  1344.         2    PC     R  read next instruction byte (and throw it away),
  1345.                        increment PC
  1346.         3  $0100,S  R  increment S
  1347.         4  $0100,S  R  pull P from stack, increment S
  1348.         5  $0100,S  R  pull PCL from stack, increment S
  1349.         6  $0100,S  R  pull PCH from stack
  1350.  
  1351.  
  1352.      PHA, PHP
  1353.  
  1354.         #  address R/W description
  1355.        --- ------- --- -----------------------------------------------
  1356.         1    PC     R  fetch opcode, increment PC
  1357.         2    PC     R  read next instruction byte (and throw it away),
  1358.                        increment PC
  1359.         3  $0100,S  W  push register on stack, decrement S
  1360.  
  1361.  
  1362.      PLA, PLP
  1363.  
  1364.         #  address R/W description
  1365.        --- ------- --- -----------------------------------------------
  1366.         1    PC     R  fetch opcode, increment PC
  1367.         2    PC     R  read next instruction byte (and throw it away),
  1368.                        increment PC
  1369.         3  $0100,S  R  increment S
  1370.         4  $0100,S  R  pull register from stack
  1371.  
  1372.  
  1373.   The example program consists of three parts. The first part
  1374. transfers the other parts to appropriate memory areas. The second part
  1375. is located in stack area (300-312), and it invokes the third part, the
  1376. main module.
  1377.  
  1378.   The loader part ($0801-$08C7) is as follows:
  1379.  
  1380.         1993 SYS2061
  1381.  
  1382.         080D SEI          Disable interrupts.
  1383.         080E LDA $01
  1384.         0810 PHA          Store the state of the processor's I/O lines.
  1385.         0811 AND #$F8
  1386.         0813 STA $01      Select 64 kB RAM memory configuration.
  1387.  
  1388.         0815 LDX #$0C     Copy the invoking part to 300-312.
  1389.         0817 LDA $0830,X
  1390.         081A STA $012C,X
  1391.         081D DEX
  1392.         081E BPL $0817
  1393.  
  1394.         0820 LDX #$8B     Copy the main part to $DD64-$DDEE.
  1395.         0822 LDA $083C,X
  1396.         0825 STA $DD63,X
  1397.         0828 DEX
  1398.         0829 BNE $0822
  1399.  
  1400.         082B PLA          Restore original memory configuration.
  1401.         082C STA $01
  1402.         082E CLI          Enable interrupts.
  1403.         082F RTS          Return.
  1404.  
  1405.   The user invokes the following part by issuing SYS 300. This part
  1406. changes the memory configuration and jumps to the main part.
  1407.  
  1408.         012C LDA $01
  1409.         012E TAX          Store original memory configuration to X register.
  1410.         012F AND #$F8
  1411.         0131 ORA #$04
  1412.         0133 SEI          Disable interrupts.
  1413.         0134 STA $01      Select 64 kB RAM memory configuration.
  1414.         0136 JMP $DDA4    Jump to the main part.
  1415.  
  1416.   The main part actually consists of two parts. It may be a bit
  1417. complicated, and it might teach new tricks to you.
  1418.  
  1419.         DDA4 TXA
  1420.         DDA5 PHA          Push original memory configuration on stack.
  1421.         DDA6 LDA $FFFA
  1422.         DDA9 PHA
  1423.         DDAA LDA $FFFB
  1424.         DDAD PHA          Store the original values of $FFFA and $FFFB.
  1425.         DDAE LDA #$16
  1426.         DDB0 STA $FFFA    Set ($FFFA) to point to RTI.
  1427.         DDB3 LDA #$C0
  1428.         DDB5 STA $FFFB
  1429.         DDB8 JSR $DDDC    Swap the auxiliary routines in.
  1430.         DDBB JSR $C000    Disable NMI's and initialize CIA2.
  1431.         DDBE PLA
  1432.         DDBF STA $FFFB    Restore original values to $FFFA and $FFFB.
  1433.         DDC2 PLA
  1434.         DDC3 STA $FFFA
  1435.         DDC6 JSR $C01D    Print the message.
  1436.         DDC9 JSR $DDDC    Swap the auxiliary routines out.
  1437.         DDCC PLA
  1438.         DDCD TAY          Load original memory configuration to Y register.
  1439.         DDCE LDA #$00     Push desired stack register value on stack
  1440.         DDD0 PHA          (clear all flags, especially the I flag).
  1441.         DDD1 TSX
  1442.         DDD2 INC $0102,X  Increment the return address.
  1443.         DDD5 BNE $DDDA    (RTS preincrements it, but RTI does not.)
  1444.         DDD7 INC $0103,X
  1445.         DDDA STY $01      Restore original memory configuration.
  1446.  
  1447.         (The 6510 fetches the next instruction from $DDDC, which is now
  1448.         connected to the CIA2's register $C, the Serial Port register.
  1449.         The initialization routine wrote an RTI to it. The processor also
  1450.         reads from $DDDD as a side effect of the instruction fetch,
  1451.         thus re-enabling NMI's.)
  1452.  
  1453.         DDDC LDY #$3F     Subroutine: Swap the memory areas $C000-$C03F
  1454.         DDDE LDX $C000,Y              and $DD64-$DDA3 with each other.
  1455.         DDE1 LDA $DD64,Y
  1456.         DDE4 STA $C000,Y
  1457.         DDE7 TXA
  1458.         DDE8 STA $DD64,Y
  1459.         DDEB DEY
  1460.         DDEC BPL $DDDE 
  1461.         DDEE RTS
  1462.  
  1463.         C000 INC $01      Enable the I/O area.
  1464.         C002 LDX #$81
  1465.         C004 STX $DD0D    Enable Timer A interrupts of CIA2.
  1466.         C007 LDX #$00
  1467.         C009 STX $DD05
  1468.         C00C INX
  1469.         C00D STX $DD04    Prepare Timer A to count from 1 to 0.
  1470.         C010 LDX #$DD
  1471.         C012 STX $DD0E    Cause an interrupt.
  1472.  
  1473.         (The instruction sets SP to output, makes Timer A to count
  1474.         system clock pulses, forces the CIA to load the initial value
  1475.         to the counter, selects one-shot counting and starts the timer.)
  1476.  
  1477.         C015 LDX #$40
  1478.  
  1479.         (The processor now jumps to the NMI handler ($C016), and
  1480.         the SP register starts to act as a memory place.)
  1481.  
  1482.         C017 STX $DD0C    Write an RTI to Serial Port register.
  1483.         C01A DEC $01      Disable the I/O area.
  1484.         C01C RTS          Return.
  1485.  
  1486.         C01D LDA $01
  1487.         C01F PHA
  1488.         C020 ORA #$03     Enable I/O and ROMs.
  1489.         C022 STA $01
  1490.         C024 LDY #$0C     Print the message.
  1491.         C026 LDA $C033,Y
  1492.         C029 JSR $FFD2
  1493.         C02C DEY
  1494.         C02D BPL $C026
  1495.         C02F PLA
  1496.         C030 STA $01      Restore the 64 kB memory configuration.
  1497.         C032 RTS
  1498.  
  1499.         C033 "!DLROW ,OLLEH"
  1500.  
  1501.         (The string is backwards in memory, since I don't want to
  1502.         waste cycles in explicit comparisons. This method results in
  1503.         more readable code than doing a forward loop with an index
  1504.         value $100-(number of characters).)
  1505.  
  1506.   This program is not excellent. It has the following bugs:
  1507.  
  1508.    o The 6510's memory management lines P0 and P1 (LORAM and HIRAM,
  1509.      respectively) are assumed to be outputs. If you issued the
  1510.      command POKE0,PEEK(0)AND252, this program would not work.
  1511.      This could be easily corrected by setting the P0 and P1 lines
  1512.      to output in the beginning of the interfacing routine (300 - 312):
  1513.  
  1514.         LDA $00
  1515.         ORA #$02
  1516.         STA $00
  1517.  
  1518.    o The program does not restore the original state of the CIA2
  1519.      Control Register A or Interrupt Control Register. It might be
  1520.      impossible to start using the Kernal's RS-232 routines after
  1521.      running this.
  1522.  
  1523.    o If the user redirected output to cassette or RS-232, interrupts
  1524.      would be required. However, they are completely disabled.
  1525.  
  1526.    o If a non-maskable interrupt occurs while the loader part is being
  1527.      executed, the program will screw up. This will happen also in the
  1528.      main part, if an NMI is issued after disabling ROMs and I/O in
  1529.      $0134 but before exchanging the contents of the memory places
  1530.      $C016 and $DD7A.
  1531.  
  1532.  
  1533. _Freezer cartridges_
  1534.  
  1535. There are many cartridges that let you to stop almost any program for
  1536. "back-up" purposes. One of the most popular of these freezer
  1537. cartridges is the Action Replay VI made by Datel Electronics back in
  1538. 1989. The cartridge has 8 kilobytes RAM and 32 kilobytes ROM on board,
  1539. and it has a custom chip for fiddling with the C64 cartridge port
  1540. lines -EXROM, -GAME, -IRQ, -NMI and BA.
  1541.  
  1542. If the -NMI line is not asserted (the NMI interrupts are enabled), all
  1543. freezer cartridges should be able to halt any program. When the user
  1544. presses the "freeze" button, the cartridges halt the processor by
  1545. dropping the BA line low. Then they switch some of their own ROM to
  1546. the $E000 - $FFFF block by selecting the UltiMax configuration with
  1547. the -EXROM and -GAME lines. After this, they assert the -NMI line and
  1548. release the BA line. After completing the current instruction, the
  1549. processor will take the NMI interrupt and load the program counter
  1550. from the vector at $FFFA, provided that the NMI line was not asserted
  1551. already.
  1552.  
  1553. This approach is prone to many flaws. Firstly, if the processor is
  1554. executing a write instruction when the program is being halted, and if
  1555. the write occurred outside the area $0000 - $0FFF, the data would get
  1556. lost, if the UltiMax configuration was asserted too early. This can be
  1557. corrected to some extent by waiting at least two cycles after
  1558. asserting the BA line, as the processor will not stop during write
  1559. cycles. However, this is of no help if the processor has not gotten to
  1560. the write stage yet.
  1561.  
  1562. Secondly, if the instruction being executed is outside the area
  1563. $0000 - $0FFF, or if it accesses any data outside that area, the
  1564. processor will fetch either wrong parameters or incorrect data, or
  1565. both. If the instruction does not write anything, will only corrupt
  1566. one processor register.
  1567.  
  1568. Thirdly, if the NMI interrupts are disabled, pressing the "freeze"
  1569. button does not have any other immediate effect than leaving the
  1570. UltiMax mode asserted, which makes any system RAM outside the area
  1571. $0000 - $0FFF unavailable. It also forces the I/O area ($D000 - $DFFF)
  1572. on. If the program has any instructions or data outside the lowmost
  1573. four kilobytes, it will eventually jam, as that data will be something
  1574. else than the program expects.
  1575.  
  1576. One might except that reading from open address space should return
  1577. random bytes. But, in at least two C64's, the bytes read are mostly
  1578. $BD, which is the opcode for LDA absolute,X. So, if the processor has
  1579. a "good luck", it will happily execute only LDA $BDBD,X commands, and
  1580. it might survive to the cartridge ROM area without jamming. Or it
  1581. could eventually fetch a BRK and jump to the cartridge ROM via the
  1582. IRQ/BRK vector at $FFFE. The Action Replay VI has the familiar
  1583. autostart data in the beginning of both the ROML and ROMH blocks by
  1584. default, and that data could be interpreted as sensible commands. The
  1585. Action Replay VI was indeed able to freeze my test program, even
  1586. though I had covered its -RESET, -IRQ and -NMI lines with a piece of
  1587. tape, until I relocated the program to the first 4 kilobyte block.
  1588.  
  1589.  
  1590. _Building an unbeatable freezer circuit_
  1591.  
  1592. As you can see, it is totally impossible to design a freezer cartridge
  1593. that freezes any program. If the program to be freezed has disabled
  1594. the NMI interrupts, and if its code runs mostly at $0000 - $0FFF or
  1595. $D000 - $DFFF, the computer will more probably hang than succeed in
  1596. freezing the program.
  1597.  
  1598. However, it is possible to make some internal modifications to a C64,
  1599. so that it can freeze literally any program. You need to expand your
  1600. machine to 256 kilobytes following the documents on ftp.funet.fi in
  1601. the /pub/cbm/hardware/256kB directory. It will let you to reset the
  1602. computer so that all of the 64 kilobytes the previous program used,
  1603. will remain intact. If you add a switch to one of the memory expansion
  1604. controller's chip selection lines, the program being examined will
  1605. have no way to screw the machine up, as the additional memory management
  1606. registers will not be available.
  1607.  
  1608. A few enhancements to this circuit are required so that you can freeze
  1609. the programs without losing the state of the I/O chips. You will also
  1610. need to replace the Kernal ROM chip with your own code, if you do not
  1611. want to lose the state of the A, X, P and S registers. Unfortunately
  1612. this circuit will not preserve the state of the processor's Peripheral
  1613. lines (its built-in I/O port mapped to the memory addresses 0 and 1),
  1614. nor does it record the program counter (PC). I have a partial solution
  1615. to the PC problem, though.
  1616.  
  1617. If you are interested in this project, contact me. I will design the
  1618. additional hardware, and I will program the startup routines, but I
  1619. certainly do not have the time to program all of the freezer software.
  1620. Most of the freezer software could be in RAM, so it would be very easy
  1621. to develop it, and you could even use existing tools by patching them
  1622. slightly.
  1623.  
  1624. =============================================================================
  1625. FLD - Scrolling the screen
  1626. by Marek Klampar (klampar@elf.stuba.sk)
  1627.  
  1628.  
  1629.                  Scrolling the screen
  1630.                  --------------------
  1631.       [inspirated by Pasi Ojala article 'Opening the borders' from issue#6]
  1632.  
  1633. From Pasi 'Albert' Ojala's (po87553@cs.tut.fi or albert@cc.tut.fi) article:
  1634.  
  1635.   _Scrolling the screen_
  1636.  
  1637.   VIC begins to draw the screen from the first bad line. VIC will know
  1638.   what line is a bad line by comparing its scan line counter to the
  1639.   vertical scroll register : when they match, the next line is a bad
  1640.   line. If we change the vertical scroll register ($d011), the first bad
  1641.   line will move also. If we do this on every line, the line counter in
  1642.   VIC will never match with it and the drawing never starts (until it is
  1643.   allowed to do so).
  1644.  
  1645.   When we don't have to worry about bad lines, we have enough time to
  1646.   open the borders and do some other effects too. It is not necassary to
  1647.   change the vertical scroll on every line to get rid of the bad lines,
  1648.   just make sure that it never matches the line counter (or actually the
  1649.   least significant 3 bits).
  1650.  
  1651.   You can even scroll the bad lines independently and you have FLD -
  1652.   Flexible Line Distance. You just allow a bad line when it is time to
  1653.   display the next character row. With this you can bounce the lines or
  1654.   scroll a hires picture very fast down the screen.
  1655.  
  1656. (*** end of Albert's paragraph ***)
  1657.  
  1658.   Well, everything important was written. I'm just adding this:
  1659.  
  1660. For moving hires picture replace ORA #$10 by ORA #$30.
  1661.  
  1662. For another FX try to replace part of irq routine begining with ORA #$10 by:
  1663.     ORA #$C0
  1664.     STA $D016,
  1665. remove  JSR CHOFS,
  1666. replace    LDX OFSET
  1667. by    LDX #$ff
  1668. and enjoy =)
  1669.  
  1670.  
  1671. The demonstartion program for FLD application
  1672. ;---------------------------------------
  1673. ; Commodore Cracker 1993
  1674. ;---------------------------------------
  1675. FROM     = $32
  1676. TO       = $FA
  1677. ;---------------------------------------
  1678.       *= $C000
  1679. ;---------------------------------------
  1680. INIT    LDA #0
  1681.       STA DIR     ; Direction
  1682.       LDA #$FF    ; Set garbage
  1683.       STA $3FFF
  1684.       LDA #FROM
  1685.       STA OFSET   ; Set ofset
  1686.       SEI         ; Disable interrupt
  1687.       LDA #$7F    ; Disable timer interrupt
  1688.       STA $DC0D
  1689.       LDA #1      ; Enable raster interrupt
  1690.       STA $D01A
  1691.       LDA #<IRQ   ; Set irq vector
  1692.       STA $0314
  1693.       LDA #>IRQ
  1694.       STA $0315
  1695.       LDA #0      ; To evoke our irq routine on 0th line
  1696.       STA $D012
  1697.       CLI         ; Enable interrupt
  1698.       RTS
  1699. ;---------------------------------------
  1700. IRQ     LDX OFSET
  1701. L2    LDY $D012   ; Moving 1st bad line
  1702. L1    CPY $D012
  1703.       BEQ L1      ; Wait for begin of next line
  1704.       DEY         ; IY - bad line
  1705.       TYA
  1706.       AND #$07    ; Clear higher 5 bits
  1707.       ORA #$10    ; Set text mode
  1708.       STA $D011
  1709.       DEX
  1710.       BNE L2
  1711.       INC $D019   ; Acknowledge the raster interrupt
  1712.       JSR CHOFS
  1713.       JMP $EA31   ; Do standard irq routine
  1714. ;---------------------------------------
  1715. OFSET .BYTE FROM
  1716. DIR   .BYTE 0
  1717. ;---------------------------------------
  1718. CHOFS LDA DIR     ; Change OFSET of screen
  1719.       BNE UP
  1720.       INC OFSET   ; Down
  1721.       LDA OFSET
  1722.       CMP #TO
  1723.       BNE SKIP
  1724.       STA DIR
  1725. SKIP    RTS
  1726. ;---------------------------------------
  1727. UP    DEC OFSET   ; Up
  1728.       LDA OFSET
  1729.       CMP #FROM
  1730.       BNE SKIP
  1731.       LDA #0
  1732.       STA DIR
  1733.       RTS
  1734.  
  1735. =============================================================================
  1736. Tech-tech - more resolution to vertical shift.
  1737. by Pasi 'Albert' Ojala (po87553@cs.tut.fi _or_ albert@cc.tut.fi)
  1738. Written on 16-May-91  Translation 02-Jun-92
  1739.  
  1740. (All timings are in PAL, principles will apply to NTSC too)
  1741.  
  1742. One time half of the demos had pictures waving horizontally on the
  1743. width of the whole screen. This effect is named tech-tech, and the
  1744. audience was puzzled. You can move the screen only eight pixels using
  1745. the horizontal scroll register. This effect was done using character
  1746. graphics. How exactly and is the same possible with sprites ?
  1747.  
  1748.  
  1749. Horizontal scroll register can move the screen by eight pixels. This
  1750. isn't even nearly enough to produce a really stunning effect. You have
  1751. to move the graphics itself, fortunately with a resolution of one
  1752. character position (one byte) only, the rest can be done with the scroll
  1753. register. During one scan line there is no time to move the actual data,
  1754. you can only move a pointer. Changing the video matrix pointer won't
  1755. help, because VIC (video interface controller) will fetch the character
  1756. codes only at certain times, called bad lines. You can change the
  1757. character set pointer instead, because VIC reads the data it displays
  1758. directly from the character set memory.
  1759.  
  1760.  
  1761. Character set-implementation has its restrictions
  1762.  
  1763. Because horizontal movement is done by changing the character sets, the
  1764. picture or text must be pure graphic and the character codes in the
  1765. video matrix must be in a numerical order. The normal picture is in the
  1766. first character memory and in the next one it is shifted one character
  1767. position to the right. One video bank can hold only seven full character
  1768. memories besides the video matrix. This limits the movement of the
  1769. picture to 56 pixels. It is possible to get more movement if you use
  1770. smaller picture or another video bank.
  1771.  
  1772. The shift is done so that on each scan line we update the horizontal
  1773. scroll register ($D016) with the three lowest bits of the shift value.
  1774. We use the other bits to select the right character set ($D018). In a
  1775. tech-tech the shift value changes during the display of the whole
  1776. picture, and the values are stored in a table. In addition to that, the
  1777. shift values should be put into two tables, one for the horizontal
  1778. scroll register and another for the character set select. This is
  1779. necessary, because there is no time for extra calculations on a bad
  1780. line.
  1781.  
  1782. Because we have to change the character set and x-scroll dynamically, we
  1783. also need a raster routine to show a tech-tech. A raster routine is a
  1784. routine which is synchronized to the electron beam. This eats up the
  1785. processor time: the bigger the picture, the less time is left over for
  1786. other activities. On other than bad lines you can do other funny things,
  1787. like change the color of the background or border.
  1788.  
  1789.  
  1790. An example program
  1791.  
  1792. The demo program uses video bank 2, memory addesses $4000-7fff. The
  1793. video matrix is in the beginning of the bank. Only inverted chars are
  1794. used for the graphics, this way we have all eight character memories
  1795. available and the maximum shift is 64 pixels. The area for the tech-tech
  1796. in the video matrix is eight character rows high, but it has identical
  1797. graphics on every line. This is why we use only 320 bytes from each
  1798. character set.
  1799.  
  1800. You can use a joystick to control the movement of the tech-tech. The
  1801. stick decreases or increases the shift add value in a resolution of a
  1802. half pixel. When the shift reaches its highest/lowest value, the
  1803. direction of the add is reversed. Just experiment with it.
  1804.  
  1805.  
  1806. You can do it on the screen, how about borders ?
  1807.  
  1808. Because you cannot get characters to the border, you might think that it
  1809. is impossible to make a tech-tech effect in the borders. It takes so
  1810. much time to change sprite x-coordinates, that you can change only some
  1811. of them. There is time for five sprite moves, if you do not need to
  1812. change the most significant (9th) bit of the x-coordinate. On the other
  1813. hand, you could design the movements directly to the sprites and then
  1814. just change the images, but then the movements would be constant.
  1815.  
  1816. However, there is one trick you can use to get all of the sprites on the
  1817. screen, with variable movements and color bars etc. You do not change
  1818. the x-coordinates, but the data itself on each scan line. In fact you
  1819. change the sprite image pointers. There is multiple sprite pictures,
  1820. where the graphics is shifted horizontally, just like the normal
  1821. tech-tech charsets. Because of this, the sprites have to be placed side
  1822. by side. No gaps are allowed. By changing the image pointers you can get
  1823. the graphics to move horizontally on each line as you wish. With
  1824. multicolor sprites you have to remember that one pixel corresponds to
  1825. two bits - the movement is not so smooth.
  1826.  
  1827. Wait ! How come there is enough time to change the sprite pointers, when
  1828. there is not time to change the coordinates ? This is another pointer
  1829. trick. VIC reads the sprite image pointers from the end of the current
  1830. video matrix, normally $07f8. You just have to change the video matrix
  1831. pointer ($D018) to change all of the image pointers. This takes only
  1832. eight cycles and there is plenty of time left for other effects on each
  1833. scan line. If you use only one video bank, you can get the sprite
  1834. picture to 16 different places. This allows also another kind of
  1835. effects, just use your imagination.
  1836.  
  1837. --------------------------------------------------------------------------
  1838. Tech-tech demo program (PAL)
  1839.  
  1840. BANK=   $96     ; The value of the video bank register (CIA2) in the tech-area
  1841. ZP=     $FB     ; Zero page for indirect addressing
  1842. START=  $4400   ; Start of the charsets (we use inverted chars)
  1843. SCREEN= $4000   ; Position of the video matrix
  1844. SHIFTL= $CF00   ; x-shift, lowest 3 bits
  1845. SHIFTH= $CE00   ; x-shift, highest 3 bittid (multiplied with two)
  1846. POINTER= $033C  ; Pointer to shift-table
  1847. VALUE=  $033D   ; Shift now
  1848. SPEED=  $033E   ; Shift change
  1849.  
  1850. *= $C000  ; Start address..
  1851.  
  1852. INIT    SEI             ; Disable interrupts
  1853.         LDA #$7F
  1854.         STA $DC0D       ; Disable timer interrupt
  1855.         LDA #$81
  1856.         STA $D01A       ; Enable raster interrupt
  1857.         LDA #<IRQ
  1858.         STA $0314       ; Our own interrupt handler
  1859.         LDA #>IRQ
  1860.         STA $0315
  1861.         LDA #49         ; The interrupt to the line before the first bad line
  1862.         STA $D012
  1863.         LDA #$1B
  1864.         STA $D011       ; 9th bit of the raster compare
  1865.  
  1866.         LDY #0
  1867.         LDX #$40
  1868.         STX ZP+1
  1869.         STY ZP
  1870.         TYA
  1871. LOOP0   STA (ZP),Y      ; Clear the whole video bank ($4000-7FFF)
  1872.         INY
  1873.         BNE LOOP0
  1874.         INC ZP+1
  1875.         BPL LOOP0
  1876.  
  1877.         LDA #>START
  1878.         STA ZP+1
  1879.         LDA #$32        ; Character ROM to address space ($D000-)
  1880.         STA $01
  1881. LOOP1   TYA             ; (Y-register is zero initially)
  1882.         LSR
  1883.         LSR
  1884.         LSR
  1885.         TAX
  1886.         LDA TEXT,X      ; Which char to plot ?
  1887.         ASL             ; Source
  1888.         ASL
  1889.         ASL
  1890.         TAX             ; low byte to X
  1891.         LDA #$D0
  1892.         ADC #0          ; high byte (one bit) taken into account
  1893.         STA LOOP2+2 ; Self-modifying again..
  1894. LOOP2   LDA $D000,X
  1895.         STA (ZP),Y
  1896.         INX
  1897.         INY
  1898.         TXA
  1899.         AND #7
  1900.         BNE LOOP2       ; Copy one char
  1901.         CPY #0
  1902.         BNE LOOP1       ; Copy 32 chars (256 bytes)
  1903.         LDA #$37        ; Memory configuration back to normal
  1904.         STA $01
  1905.  
  1906. LOOP3   LDA START,Y       ; Copy the data to each charset, shifted by one
  1907.         STA START+2056,Y  ;  position to the right
  1908.         STA START+4112,Y
  1909.         STA START+6168,Y
  1910.         STA START+8224,Y
  1911.         STA START+10280,Y
  1912.         STA START+12336,Y
  1913.         STA START+14392,Y
  1914.         INY
  1915.         BNE LOOP3
  1916.         LDA #0          ; Clear the pointer, value and speed
  1917.         STA POINTER
  1918.         STA VALUE
  1919.         STA SPEED
  1920.  
  1921. LOOP4   TYA             ; (Y was zero)
  1922.         ORA #$80        ; Use the inverted chars
  1923.         STA SCREEN,Y    ; Set the character codes to video matrix
  1924.         STA SCREEN+40,Y
  1925.         STA SCREEN+80,Y
  1926.         STA SCREEN+120,Y
  1927.         STA SCREEN+160,Y
  1928.         STA SCREEN+200,Y
  1929.         STA SCREEN+240,Y
  1930.         STA SCREEN+280,Y
  1931.         LDA #239        ; leave the last line empty
  1932.         STA SCREEN+320,Y
  1933.         INY
  1934.         CPY #40
  1935.         BNE LOOP4       ; Loop until the whole area is filled
  1936.         CLI             ; Enable interrupts
  1937.         RTS
  1938.  
  1939. IRQ     LDA #BANK       ; Change the video bank, some timing
  1940.         STA $DD00
  1941.         NOP
  1942.         NOP
  1943.  
  1944.         LDY POINTER     ; Y-register will point to x-shift
  1945.         JMP BAD         ; next line is a bad line
  1946. LOOP5   NOP
  1947. LOOP6   LDA SHIFTL,Y    ; Do the shift
  1948.         STA $D016       ; 3 lowest bits
  1949.         LDA SHIFTH,Y
  1950.         STA $D018       ; another 3 bits
  1951.         NOP : NOP : NOP : NOP : NOP : NOP ; waste some time
  1952.         NOP : NOP : NOP : NOP : NOP : NOP
  1953.         NOP : NOP : NOP
  1954.         LDA $D012       ; check if it is time to stop
  1955.         CMP #$78
  1956.         BPL OVER
  1957.         INY   ; next position in table
  1958.         DEX
  1959.         BNE LOOP5       ; No bad line, loop
  1960. BAD     LDA SHIFTL,Y    ; This is a bad line, a bit more hurry
  1961.         STA $D016
  1962.         LDA SHIFTH,Y
  1963.         STA $D018
  1964.         INY
  1965.         LDX #7          ; New bad line coming up
  1966.         JMP LOOP6
  1967.  
  1968. OVER    LDA #$97        ; Video bank to 'normal'
  1969.         STA $DD00
  1970.         LDA #22         ; Same with the charset
  1971.         STA $D018
  1972.         LDA #8          ; and the horizontal scroll register
  1973.         STA $D016
  1974.  
  1975.         LDA $DC00       ; Let's check the joysticks
  1976.         AND $DC01
  1977.         TAX
  1978.         LDY SPEED
  1979.         AND #8          ; Turned right, add speed
  1980.         BNE EIP
  1981.         INY
  1982.         CPY #4          ; Don't store, too much speed
  1983.         BPL EIP
  1984.         STY SPEED
  1985. EIP     TXA
  1986.         AND #4          ; Turned left
  1987.         BNE ULOS
  1988.         DEY
  1989.         CPY #$FC        ; Too much ?
  1990.         BMI ULOS
  1991.         STY SPEED
  1992. ULOS    LDA VALUE       ; Add speed to value (signed)
  1993.         CLC
  1994.         ADC SPEED
  1995.         BPL OK
  1996.         LDA SPEED       ; Banged to the side ?
  1997.         EOR #$FF
  1998.         CLC
  1999.         ADC #1
  2000.         STA SPEED
  2001.         LDA VALUE
  2002. OK      STA VALUE
  2003.         LSR             ; Value is twice the shift
  2004.         TAX             ; Remember the shift
  2005.         AND #7          ; lowest 3 bits
  2006.         ORA #8          ; (screen 40 chars wide)
  2007.         LDY POINTER
  2008.         STA SHIFTL,Y
  2009.         TXA
  2010.         LSR
  2011.         LSR
  2012.         LSR             ; highest 3 bits too
  2013.         ASL             ;  multiplicated by two
  2014.         STA SHIFTH,Y
  2015.         DEC POINTER
  2016.  
  2017.         LDA #1          ; Ack the interrupt
  2018.         STA $D019
  2019.         JMP $EA31       ; The normal interrupt routine
  2020.  
  2021. TEXT    SCR "THIS IS TECH-TECH FOR C=64 BY ME" ; Test text
  2022.                         ; SCR converts to screen codes
  2023.  
  2024. --------------------------------------------------------------------------
  2025. Basic loader for the Tech-tech demo program (PAL)
  2026.  
  2027. 1 S=49152
  2028. 2 DEFFNH(C)=C-48+7*(C>64)
  2029. 3 CH=0:READA$,A:PRINTA$:IFA$="END"THENPRINT"<clr>":SYS49152:END
  2030. 4 FORF=0TO31:Q=FNH(ASC(MID$(A$,F*2+1)))*16+FNH(ASC(MID$(A$,F*2+2)))
  2031. 5 CH=CH+Q:POKES,Q:S=S+1:NEXT:IFCH=ATHEN3
  2032. 6 PRINT"CHECKSUM ERROR":END
  2033. 100 DATA 78A97F8D0DDCA9818D1AD0A9AD8D1403A9C08D1503A9318D12D0A91B8D11D0A0, 
  2034. 3802
  2035. 101 DATA 00A24086FC84FB9891FBC8D0FBE6FC10F7A94485FCA9328501984A4A4AAABD5E, 
  2036. 4749
  2037. 102 DATA C10A0A0AAAA9D069008D4EC0BD00D091FBE8C88A2907D0F4C000D0DDA9378501, 
  2038. 4128
  2039. 103 DATA B9004499084C99105499185C99206499286C99307499387CC8D0E5A9008D3C03, 3258
  2040. 104 DATA 8D3D038D3E0398098099004099284099504099784099A04099C84099F0409918, 3236
  2041. 105 DATA 41A9EF994041C8C028D0DB5860A9968D00DDEAEAAC3C034CE1C0EAB900CF8D16, 
  2042. 4464
  2043. 106 DATA 
  2044. D0B900CE8D18D0EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAAD12D0C9781016C8CAD0, 
  2045. 5850
  2046. 107 DATA D9B900CF8D16D0B900CE8D18D0C8A2074CBBC0A9978D00DDA9168D18D0A9088D, 
  2047. 4132
  2048. 108 DATA 16D0AD00DC2D01DCAAAC3E032908D008C8C00410038C3E038A2904D00888C0FC, 
  2049. 3160
  2050. 109 DATA 30038C3E03AD3D03186D3E03100EAD3E0349FF1869018D3E03AD3D038D3D034A, 2139
  2051. 110 DATA AA29070908AC3C039900CF8A4A4A4A0A9900CECE3C03A9018D19D04C31EA1408, 
  2052. 2759
  2053. 111 DATA 091320091320140503082D1405030820060F1220033D3634200219200D050F12, 652
  2054. 200 DATA END,0
  2055.  
  2056. --------------------------------------------------------------------------
  2057. Uuencoded C64 executable version of the demo program (PAL)
  2058.  
  2059. begin 644 tech.64
  2060. M`0@-"`$`4[(T.3$U,@`F"`(`EJ5(*$,ILD.K-#BJ-ZPH0[$V-"D`7`@#`$-(J
  2061. MLC`ZAT$D+$$ZF4$D.HM!)+(B14Y$(J>9(CS7R,G4Q3X\P\S2/B(ZGC0Y,34R;
  2062. M.H``DP@$`(%&LC"D,S$Z4;*E2"C&*,HH020L1JPRJC$I*2FL,3:JI4@HQBC*1
  2063. M*$$D+$:L,JHR*2DI`+0(!0!#2+)#2*I1.I=3+%$Z4[)3JC$Z@CJ+0TBR0:<S?
  2064. M`,P(!@"9(D-(14-+4U5-($524D]2(CJ``!D)9`"#(#<X03DW1CA$,$1$0T$YN
  2065. M.#$X1#%!1#!!.4%$.$0Q-#`S03E#,#A$,34P,T$Y,S$X1#$R1#!!.3%".$0Q+
  2066. M,40P03`L(#,X,#(`9@EE`(,@,#!!,C0P.#9&0S@T1D(Y.#DQ1D)#.$0P1D)%G
  2067. M-D9#,3!&-T$Y-#0X-49#03DS,C@U,#$Y.#1!-$$T04%!0D0U12P@-#<T.0"S+
  2068. M"68`@R!#,3!!,$$P04%!03E$,#8Y,#`X1#1%0S!"1#`P1#`Y,49"13A#.#A!]
  2069. M,CDP-T0P1C1#,#`P1#!$1$$Y,S<X-3`Q+"`T,3(X```*9P"#($(Y,#`T-#DYE
  2070. M,#@T0SDY,3`U-#DY,3@U0SDY,C`V-#DY,C@V0SDY,S`W-#DY,S@W0T,X1#!%,
  2071. M-4$Y,#`X1#-#,#,L(#,R-3@`30IH`(,@.$0S1#`S.$0S13`S.3@P.3@P.3DPU
  2072. M,#0P.3DR.#0P.3DU,#0P.3DW.#0P.3E!,#0P.3E#.#0P.3E&,#0P.3DQ."P@?
  2073. M,S(S-@":"FD`@R`T,4$Y148Y.30P-#%#.$,P,CA$,$1"-3@V,$$Y.38X1#`P-
  2074. M1$1%045!04,S0S`S-$-%,4,P14%".3`P0T8X1#$V+"`T-#8T`.<*:@"#($0PN
  2075. M0CDP,$-%.$0Q.$0P14%%045!14%%045!14%%045!14%%045!14%%045!040Q,
  2076. M,D0P0SDW.#$P,39#.$-!1#`L(#4X-3``-`MK`(,@1#E".3`P0T8X1#$V1#!"Q
  2077. M.3`P0T4X1#$X1#!#.$$R,#<T0T)"0S!!.3DW.$0P,$1$03DQ-CA$,3A$,$$Y_
  2078. M,#@X1"P@-#$S,@"!"VP`@R`Q-D0P040P,$1#,D0P,41#04%!0S-%,#,R.3`XN
  2079. M1#`P.$,X0S`P-#$P,#,X0S-%,#,X03(Y,#1$,#`X.#A#,$9#+"`S,38P`,X+'
  2080. M;0"#(#,P,#,X0S-%,#-!1#-$,#,Q.#9$,T4P,S$P,$5!1#-%,#,T.49&,3@V7
  2081. M.3`Q.$0S13`S040S1#`S.$0S1#`S-$$L(#(Q,SD`&PQN`(,@04$R.3`W,#DP;
  2082. M.$%#,T,P,SDY,#!#1CA!-$$T031!,$$Y.3`P0T5#13-#,#-!.3`Q.$0Q.40PI
  2083. M-$,S,45!,30P."P@,C<U.0!G#&\`@R`P.3$S,C`P.3$S,C`Q-#`U,#,P.#)$_
  2084. M,30P-3`S,#@R,#`V,$8Q,C(P,#,S1#,V,S0R,#`R,3DR,#!$,#4P1C$R+"`V&
  2085. 4-3(`<PS(`(,@14Y$+#````````HS!
  2086. ``
  2087. end
  2088.  
  2089. =============================================================================
  2090. ACE-128/64 PROGRAMMER'S REFERENCE GUIDE (version 0.9, for Release #10)
  2091. by Craig Bruce  <csbruce@ccnga.uwaterloo.ca>
  2092.  
  2093. 1. INTRODUCTION
  2094.  
  2095. ACE is a program for the Commodore 128 and Commodore 64 that provides a
  2096. command shell environment that is similar to that of Unix.  It is still
  2097. in the development stage, but enough of it is complete to be useful.
  2098. BTW, "ACE" means "Advanced Computing Environment" (well, advanced for
  2099. the 128/64).
  2100.  
  2101. So what is ACE all about?  Well, originally I tried a very ambitious
  2102. project of writing a multitasking operating system for the 128.  It got
  2103. it partially working, but it was much too fragile and incomplete to be
  2104. released.  It was a white-elephant project.  So, then then it came to me
  2105. that I was aiming much too high.  What I needed was a much simpler
  2106. system, one that would give the type of programming interface and
  2107. built-in features that I wanted, but one that was close enough to the
  2108. Commodore Kernal that it would not require much of a programming effort
  2109. to hack together a minimal implementation.  And thus, there was ACE-128
  2110. Release #1.  And I saw it was good.
  2111.  
  2112. What I wanted was a system that would be easier to program than the
  2113. Commodore Kernal with all its weird and wonderful device types,
  2114. non-existent memory management, and single-application design.  The
  2115. first important feature of this environment was to be able to pass
  2116. arguments from a command line to an application program by typing them
  2117. on the command line of the shell.  It is so annoying to load up a
  2118. program in BASIC, run it, and have it ask you for filenames in some
  2119. highly inconvenient way.
  2120.  
  2121. Another important system feature is to make near and far memory
  2122. management part of the system, and to make far memory convenient to use
  2123. for storing massively bulky data.  And so it was.  Also, we want to use
  2124. custom device drivers.  Commodore didn't really come through with the
  2125. device drivers it provided.  They are all REALLY SLOW.  And so that was,
  2126. also, although more custom device drivers are needed.  We want to have
  2127. the capability of making programs work together, rather than having
  2128. programs that are totally incompatible.  This functionality is still
  2129. under construction.  Programs will work together in this uni-tasking
  2130. environment by allowing a program to execute another program as a
  2131. sub-task, and then having control return to the calling program upon
  2132. exit.  Finally, we want some good quality applications and a powerful
  2133. command shell.  This is still being worked on and progress is coming
  2134. slowly.  Oh, almost forgot; we also want all programs to work on both
  2135. the C64 and C128, and they do.
  2136.  
  2137. This documentation refers to ACE release #10, which has not been
  2138. released yet (or even programmed).  In fact, the current release is #9.
  2139. Release #10 will be spruced up from the inside out to support the system
  2140. interface described in this document.  The current release is not being
  2141. described, because some of its features are not the best they could
  2142. possibly be.  Note, however, that the basic features, like "open",
  2143. "read", "dirread", and argv are not going to change.  Note also that the
  2144. version number of this "P.R.G." is 0.9.  This is because this is the
  2145. first incarnation of this document and, considering its nature, is bound
  2146. to hold a large number of small errors.
  2147.  
  2148. 2. SYSTEM INTERFACE
  2149.  
  2150. This section describes the interface between user programs and the ACE
  2151. kernel. I am very careful throughout this interface specification about
  2152. revealing any internal details that you do not strictly need to know.
  2153. The interface with ACE is not specified in terms of absolute addresses;
  2154. to aid in portability and extensibility, all interfaces are specified in
  2155. terms of symbolic assembler labels.  All of the ACE code is currently
  2156. written for the Buddy-128 assembler. Also, because these interface
  2157. absolute addresses are subject to change from version to version of the
  2158. kernel, executables compiled for use with an old version of ACE may not
  2159. work with a new version.
  2160.  
  2161. 2.1. ZERO-PAGE VARIABLES
  2162.  
  2163. There are four zero-page variables used for passing arguments in most
  2164. system calls.  They are as follows:
  2165.  
  2166. SYMBOL   BYTES   DESCRIPTION
  2167. -------  -----   -----------
  2168. zp           2   zeropage pointer
  2169. zw           2   zeropage word
  2170. mp           4   memory pointer
  2171. syswork     16   system work area / arguments
  2172.  
  2173. The first two, "zp" and "zw" are used in most calls.  They store simple
  2174. 16-bit values; "zp" usually stores pointers to strings in RAM0 memory.
  2175. The "mp" variable is 32-bits in length and is used exclusively for
  2176. passing far memory pointers for use with the far memory routines.  All
  2177. three of these variables will remain unchanged inside of system call
  2178. unless they will contain a return value.  "syswork" is a 16-byte array
  2179. used mainly when there are too many arguments for other variables to
  2180. hold, and all non-input and non-output bytes of "syswork" are subject to
  2181. change by the kernel.  All input arguments placed in the "syswork"
  2182. locations will be preserved unless otherwise indicated. [Note: In
  2183. Release #9, "zp" took on the rolls of both "zp" and "mp"].
  2184.  
  2185. 2.2. SYSTEM VARIABLES
  2186.  
  2187. There are several non-zeropage variables for storing system status and
  2188. return values:
  2189.  
  2190. SYMBOL          BYTES   DESCRIPTION
  2191. ----------      -----   -----------
  2192. errno               1   error number code returned by failed system calls
  2193. aceID               2   proof that user program is running on top of ACE
  2194. aceArgc             2   argument count for current process
  2195. aceArgv             2   argument vector address for current process
  2196. aceMemTop           2   highest address, plus one, that user prog can use
  2197. aceShellPath        2   ptr to storage for search path for executable programs
  2198. aceShellAlias       2   ptr to storage for shell command aliases
  2199. aceCurDirName       2   ptr to storage for the current directory name
  2200. aceExitData         2   ptr to storage for exit status from the last called prg
  2201. aceDirentBuffer <next>  storage for directory entries read from disk
  2202. aceDirentLength     -   really a constant: length in bytes of "aceDirentBuffer"
  2203. aceDirentBytes      4   bytes in file (usually inexact)
  2204. aceDirentDate       8   date of file in "YY:YY:MM:DD:HH:MM:SS:TW" format
  2205. aceDirentType       4   type of file in null-terminated string
  2206. aceDirentFlags      1   flags of file, "drwx*-et" format
  2207. aceDirentNameLen    1   length of name of file
  2208. aceDirentName      17   null-terminated name of file
  2209.  
  2210. ERRNO: "errno" is used to return error codes from system calls.  When a
  2211. system call ends in error, it sets the carry flag to "1", puts the error
  2212. code in "errno", and returns to the user program, after undoing any
  2213. system work completed at the time the error is encountered and aborting
  2214. the operation.  An error code number is stored in binary in the
  2215. single-byte "errno" location. The symbolic names for the possible error
  2216. codes are given in the next section. If no error occurs in a system
  2217. call, the carry flag will be cleared on return from the call.  Note that
  2218. not all system calls can run into errors, so not all set the carry flag
  2219. accordingly.
  2220.  
  2221. ID: "aceID" is a two-byte variable.  Its purpose is to allow user
  2222. programs to be sure that they are executing on top of ACE.  The low byte
  2223. (i.e., the first byte) must be equal to the symbolic constant "aceID1",
  2224. and the high, "aceID2". This will allow ACE applications to inform idiot
  2225. users that they cannot simply BOOT the program from BASIC, but rather
  2226. they must run ACE first.
  2227.  
  2228. ARGC: "aceArgc" is a two-byte unsigned number.  It gives the number of
  2229. arguments passed to the application by the program (usually the command
  2230. shell) that called the application.  The first argument is always the
  2231. name of the application program, so the count will always be at least
  2232. one.  Other arguments are optional.
  2233.  
  2234. ARGV: "aceArgv" is a two-byte RAM0 pointer.  Pay attention.  This
  2235. pointer points to the first entry of an array of two-byte pointers which
  2236. point to the null-terminated strings that are the arguments passed to
  2237. the application program by the caller.  (A null-terminated string is one
  2238. that ends with a zero byte).  To find the address of the N-th argument
  2239. to an application, multiply N by two, add the "aceArgv" contents to
  2240. that, and fetch the pointer from that address.  In this scheme, the
  2241. ever-present application name is the 0-th argument.  The argv[argc]
  2242. element of the argument vector will always contain a value of $0000, a
  2243. null pointer.
  2244.  
  2245. MEM-TOP: "aceMemTop" is a two-byte RAM0 pointer.  This points to one
  2246. byte past the highest byte that the application program is allowed to
  2247. use.  All application programs are loaded into memory at address
  2248. "aceAppAddress" (next section), and all memory between the end of the
  2249. progam code and "aceMemTop" can be used for temporary variables, file
  2250. buffers, etc.  The main problem with this approach is that there are no
  2251. guarantees about how much memory your application will get to play with.
  2252. Many applications, such as simple file utilities, can simply use all
  2253. available memory for a file buffer, but other programs, such as a file
  2254. compressor, may have much greater demand for "near" memory.  [Note: this
  2255. variable has a different name in Release #9].
  2256.  
  2257. SHELL-PATH: "aceShellPath" is a two-byte RAM0 pointer.  This points to
  2258. the page of memory that stores the pathnames of directories to search
  2259. through in order to find executable files.  Each pathname is stored as a
  2260. null-terminated string, and the list is terminated by an empty string
  2261. (containing only the zero character).  This is intended to be used by
  2262. the shell program, or any other program that is so inclined, to examine
  2263. or alter the search path.  The search paths specified in the path page
  2264. are global variables and are used by all programs that make the "exec"
  2265. system call.  This mechanism for reading/altering the executable search
  2266. path may be changed in the future.
  2267.  
  2268. SHELL-ALIAS: "aceShellAlias" is a two-byte RAM0 pointer.  This points to
  2269. the page of memory that stores the aliases to be used with the command
  2270. shell.  An alias is a string that is substituted in the place of a
  2271. command name on a shell command line whenever a certain command name
  2272. comes up.  For example, you might specify if the user enters the command
  2273. "list a:" that the command name "list" be string-replaced with "cls;xls
  2274. -l".  Each alias is stored with the command name first, followed by an
  2275. equals character ("="), followed by the string to substitute, followed
  2276. by a zero.  The alias list is terminated by an empty string.  This
  2277. mechanism may be extended in the future to allow multiple pages of
  2278. aliases, or may be changed completely.
  2279.  
  2280. CUR-DIR-NAME: "aceCurDirName" is a two-byte RAM0 pointer.  It points to
  2281. the null-terminated string indicating the current directory.  The user
  2282. is not supposed to modify this value, and the value will not always give
  2283. a full pathname.  The implementation of this feature may need to change
  2284. in future versions of ACE.
  2285.  
  2286. ACE-EXIT-DATA: "aceExitData" is a two-byte RAM0 pointer.  It points to
  2287. the 256-byte buffer allocated for user programs to give detailed return
  2288. information upon exiting back to their parent program.  See the "exit"
  2289. system call.  User programs are allowed to read and write this storage.
  2290. An example use of this feature would be a compiler program returning the
  2291. line number and character position, and description of a compilation
  2292. error to a text editor, so the editor can position the cursor and
  2293. display the error message for user convenience.  The implementation of
  2294. this feature may need to change in future versions of ACE.
  2295.  
  2296. DIRENT-BUFFER: "aceDirentBuffer" is a buffer used for storing directory
  2297. information read with the "dirread" system call, and is
  2298. "aceDirentLength" bytes long.  Only a single directory entry is
  2299. (logically) read from disk at a time.  The individual fields of a read
  2300. directory entry are accessed by the fields described next.  This field
  2301. is also used for returning disk name information and the number of bytes
  2302. free on a disk drive (see the "dirread" system call).
  2303.  
  2304. DIRENT-BYTES: "aceDirentBytes" is a four-byte (32-bit) unsigned field.
  2305. As always, the bytes are addressed from least significant to most
  2306. significant. This field gives the number of bytes in the file.  Note
  2307. that this value may not be exact, since Commodore decided to store sizes
  2308. in disk blocks rather than bytes.  For devices that report only block
  2309. counts (i.e., every disk device currently supported), the number of
  2310. bytes returned is the number of blocks multiplied by 254.  This field,
  2311. as well and the other dirent fields are absolute addresses, not offsets
  2312. from aceDirentBuffer.
  2313.  
  2314. DIRENT-DATE: "aceDirentDate" is an eight-byte array of binary coded
  2315. decimal values, stored from most significant digits to least
  2316. significant.  The first byte contains the BCD century, the second the
  2317. year, and so on, and the last byte contains the number of tenths of
  2318. seconds in its most significant nybble and a code for the day-of-week in
  2319. its least significant nybble.  Sunday has code 1, Monday 2, etc.,
  2320. Saturday 7, and a code of 0 means "unknown".  This is the standard
  2321. format for all dates used in ACE.  This format is abstracted as
  2322. "YY:YY:MM:DD:HH:MM:SS:TW".  For disk devices that don't support dates,
  2323. this field will be set to all zeroes, which can be conveniently
  2324. interpreted as the NULL date, negative infinity, or as the time that
  2325. J.C. was a seven-year-old boy.
  2326.  
  2327. DIRENT-TYPE: "aceDirentType" is a three-character (four-byte)
  2328. null-terminated string.  It indicates what type the file is, in
  2329. lowercase PETSCII.  Standard types such as "SEQ" and "PRG" will be
  2330. returned, as well and other possibilities for custom device drivers.
  2331.  
  2332. DIRENT-FLAGS: "aceDirentFlags" is a one-byte field that is interpreted
  2333. as consisting of eight independent one-bit fields.  The abstract view of
  2334. the fields is "drwx*-et".  "d" means that the item is a subdirectory
  2335. (otherwise it is a regular file), "r" means the item is readable, "w"
  2336. means the item is writable, and "x" means the item is executable.  The
  2337. "x" option is really not supported currently.  "*" means the item is
  2338. improperly closed (a "splat" file in Commodore-DOS terminology).  The
  2339. "-" field is currently undefined.  "e" means that the value given in the
  2340. "aceDirentBytes" field is actually exact, and "t" means the file should
  2341. be interpreted as being a "text" file (otherwise, its type is either
  2342. binary or unknown).  The bit fields are all booleans; a value of "1"
  2343. means true, "0", false.  The "d" bit occupies the 128-bit position, etc.
  2344.  
  2345. DIRENT-NAME-LEN: "aceDirentNameLen" is a one-byte number.  It gives the
  2346. number of characters in the filename.  It is present for convenience.
  2347.  
  2348. DIRENT-NAME: "aceDirentName" is a 16-character (17-byte) null-terminated
  2349. character string field.  It gives the name of the file or directory or
  2350. disk. Filenames used with ACE are limited to 16 characters.
  2351.  
  2352. 2.3. SYSTEM CONSTANTS
  2353.  
  2354. There are several symbolic constants that are used with the ACE system
  2355. interface:
  2356.  
  2357. SYMBOL                   DESCRIPTION
  2358. -------------------      -------------------------
  2359. aceAppAddress            the start address of applications
  2360. aceID1                   the id characters used to identify ACE applications
  2361. aceID2                   ...
  2362. aceID3                   ...
  2363. aceMemNull               the far memory type code used to indicate null ptrs
  2364. aceMemREU                far mem type code for Ram Expansion Unit memory
  2365. aceMemInternal           far mem type code for internal memory
  2366. aceMemRLREU              far mem type code for REU memory accessed thru RAMLink
  2367. aceMemRL                 far mem type code for direct-access RAMLink memory
  2368. aceErrStopped            error code for syscall aborted by STOP key
  2369. aceErrTooManyFiles       err: too many files already opened to open another
  2370. aceErrFileOpen           err: don't know what this means
  2371. aceErrFileNotOpen        err: the given file descriptor is not actually open
  2372. aceErrFileNotFound       err: named file to open for reading does not exist
  2373. aceErrDeviceNotPresent   err: the specified physical device is not online
  2374. aceErrFileNotInput       err: file cannot be opened for reading
  2375. aceErrFileNotOutput      err: file cannot be opened for writing
  2376. aceErrMissingFilename    err: pathname component is the null string
  2377. aceErrIllegalDevice      err: the specified device cannot do what you want
  2378. aceErrWriteProtect       err: trying to write to a disk that is write-protected
  2379. aceErrFileExists         err: trying to open for writing file that exists
  2380. aceErrFileTypeMismatch   err: you specified the file type incorrectly
  2381. aceErrNoChannel          err: too many open files on disk drive to open another
  2382. aceErrInsufficientMemory err: ACE could not allocate the memory you requested
  2383. aceErrOpenDirectory      err: you are trying to open a dir as if it were a file
  2384. aceErrDiskOnlyOperation  err: trying to perform disk-only op on char device
  2385. aceErrNullPointer        err: trying to dereference a null far pointer
  2386. aceErrInvalidFreeParms   err: bad call to "pagefree": misaligned/wrong size
  2387. aceErrFreeNotOwned       err: trying to free far memory you don't own
  2388. stdin                    file descriptor reserved for stdin input stream
  2389. stdout                   file descriptor reserved for stdout output stream
  2390. stderr                   file descriptor reserved for stderr output stream
  2391.  
  2392. "aceAppAddress", as discussed before, is the address that application
  2393. programs are loaded into memory at.  They must, of course, be compiled
  2394. to execute starting at this address.
  2395.  
  2396. The "aceMem" group of constants are for use with the "pagealloc" system
  2397. call, except for "aceMemNull", which may be used by application programs
  2398. for indicating null far pointers.  The "pagealloc" call allows you to
  2399. specify what types of memory you are willing to accept.  This is
  2400. important because the difference types of memory have different
  2401. performance characteristics.  ACE will try to give you the fastest
  2402. memory that is available.  Ram Expansion Unit memory has startup and
  2403. byte-transfer times of about 60 us (microseconds) and 1 us,
  2404. respectively.  This is the fastest type of far memory.  Internal memory
  2405. has a startup time of 24 us and a byte-transfer time of between 7 and 14
  2406. us (depending on whether accessing RAM0 or RAM1+).  REU memory accessed
  2407. through a RAMLink has a terrible startup time of 1000 us and a
  2408. byte-transfer time of 2 us.  Direct-access RAMLink memory has a startup
  2409. time of 1000 us and a byte-transfer time of 16 us.  All these times are
  2410. for the C128 in 2 MHz mode.
  2411.  
  2412. The "aceErr" group gives the error codes returned by system calls.  The
  2413. error codes are returned in the "errno" variable.  Not all possible
  2414. error codes from Commodore disk drives are covered, but the important
  2415. ones are.  Finally, the "std" files group give the symbolic file
  2416. descriptor identifiers of the default input, output, and error output
  2417. file streams.
  2418.  
  2419. 2.4. SYSTEM CALLS
  2420.  
  2421. All system calls are called by setting up arguments in specified
  2422. processor registers and memory locations, executing a JSR to the system
  2423. call address, and pulling the return values out of processor registers
  2424. and memory locations.
  2425.  
  2426. 2.1. FILE CALLS
  2427.  
  2428. NAME   :  open
  2429. PURPOSE:  open a file
  2430. ARGS   :  (zp) = pathname
  2431.           .A   = file mode ("r", "w", or "a")
  2432. RETURNS:  .A   = file descriptor number
  2433.           .CS  = error occurred flag
  2434. ALTERS :  .X, .Y, errno
  2435.  
  2436. Opens a file.  The name of the file is given by a pointer to a
  2437. null-terminated string, and may contain device names and pathnames as
  2438. specified in the ACE user documentation.  The file mode is a PETSCII
  2439. character.  "r" means to open the file for reading, "w" means to open
  2440. the file for writing, and "a" means to open the file for appending
  2441. (writing, starting at the end of the file).  An error will be returned
  2442. if you attempt to open for reading or appending a file that does not
  2443. exist, or if you attempt to open for writing a file that does already
  2444. exist.  If you wish to overwrite an existing file, you will have to call
  2445. "remove" to delete the old version before opening the new version for
  2446. writing.
  2447.  
  2448. The function returns a file descriptor number, which is a small unsigned
  2449. integer that is used with other file calls to specify the file that has
  2450. been opened.  File descriptors numbered 0, 1, and 2 are used for stdin,
  2451. stdout, and stderr, respectively.  The file descriptor returned will be
  2452. the minimum number that is not currently in use.  These numbers are
  2453. system-wide (rather than local to a process as in Unix), and this has
  2454. some implications for I/O redirection (see the "fdswap" call below).
  2455.  
  2456. Restrictions: only so many Kernal files allowed to be open on a disk
  2457. device, and there is a system maximum of open files.  You will get a
  2458. "too many files" error if you ever exceed this limit.  Also, because of
  2459. the nature of Commodore-DOS, there may be even tighter restrictions on
  2460. the number of files that can be simultaneously open on a single disk
  2461. device, resulting in a "no channel" error.  Note that this call checks
  2462. the status channel of Commodore disk drives on each open, so you don't
  2463. have to (and should not anyway).
  2464.  
  2465. If the current program exits either by calling "exit" or simply by doing
  2466. the last RTS, all files that were opened by the program and are still
  2467. open will be automatically closed by the system before returning to the
  2468. parent program.
  2469.  
  2470. NAME   :  close
  2471. PURPOSE:  close an open file
  2472. ARGS   :  .A   = File descriptor number
  2473. RETURNS:  .CS  = error occurred flag
  2474. ALTERS :  .A, .X, .Y, errno
  2475.  
  2476. Closes an open file.  Not much to say about this one.
  2477.  
  2478. NAME   :  read
  2479. PURPOSE:  read data from an open file
  2480. ARGS   :  .X   = File descriptor number
  2481.           (zp) = pointer to buffer to store data into
  2482.           .AY  = maximum number of bytes to read
  2483. RETURNS:  (zw) = .AY=number of bytes actually read in
  2484.           .CS  = error occurred flag
  2485.           .ZS  = EOF reached flag
  2486. ALTERS :  .X, errno
  2487.  
  2488. Reads data from the current position of an open file.  Up to the
  2489. specified maximum number of bytes will be read.  You should not give a
  2490. maximum of zero bytes, or you may misinterpret an EOF (end of file).
  2491. The buffer must be at least the size of the maximum number of bytes to
  2492. read.  The data are not interpreted in any way, so it is the
  2493. programmer's responsibility to search for carriage return characters to
  2494. locate lines of input, if he so desires. However, for the console the
  2495. input is naturally divided up into lines, so each call will return an
  2496. entire line of bytes if the buffer is large enough.  There are no
  2497. guarantees about the number of bytes that will be returned, except that
  2498. it will be between 1 and the buffer size.  So, if you wish to read a
  2499. certain number of bytes, you may have to make multiple read calls.
  2500.  
  2501. The call returns the number of bytes read in both the .AY register pair
  2502. and in (zw), for added convenience.  [Note: in ACE Release #9, the
  2503. number of bytes read are returned only in the .AY registers, not in
  2504. (zw).]  A return of zero bytes read means that the end of the file has
  2505. been reached.  An attempt to read beyond the end of file will simply
  2506. give another EOF return.  End of file is also returned in the .Z flag of
  2507. the processor.
  2508.  
  2509. NAME   :  write
  2510. PURPOSE:  write data to an open file
  2511. ARGS   :  .X   = file descriptor number
  2512.           (zp) = pointer to data to be written
  2513.           .AY  = length of data to be written in bytes
  2514. RETURNS:  .CS  = error occurred
  2515. ALTERS :  .A, .X, .Y, errno
  2516.  
  2517. Writes data at the current position of an open file.  [Note: ACE Release
  2518. #9 also alters locations (zw) when writing to the console.  This problem
  2519. will be corrected.]
  2520.  
  2521. NAME   :  fastopen
  2522. PURPOSE:  open a file for fast reading
  2523. ARGS   :  (zp) = Name
  2524.           .A   = file mode (must be "r")
  2525. RETURNS:  .A   = file descriptor number
  2526.           .CS  = error occurred flag
  2527. ALTERS :  .X, .Y, errno
  2528.  
  2529. This performs the same function as the regular "open" call, except this
  2530. style of file accessing will allow files to be read much faster than the
  2531. other.  On devices that are so equipped, the "fastload" burst command is
  2532. used (similar shortcuts may be possible with other devices too).  The
  2533. drawback of this increased speed is that no other device I/O can take
  2534. place while a file is opened for "fast" access, not even to other
  2535. devices, except for output to the console.  Other files can be open,
  2536. just not accessed.  You also cannot open more than one "fast" file at a
  2537. time.  Interrupts will be disabled while a file is open for fast
  2538. accessing, so the user cannot re-enable them, for technical reasons.
  2539. The arguments to this call are exactly the same as the regular "open" to
  2540. make it easy to switch from using one to the other.  [Note: these "fast"
  2541. calls do not exist in Release #9].
  2542.  
  2543. NAME   :  fastclose
  2544. PURPOSE:  close the file that was opened for fast reading
  2545. ARGS   :  .A   = File descriptor number
  2546. RETURNS:  .CS  = error occurred flag
  2547. ALTERS :  .A, .X, .Y, errno
  2548.  
  2549. Closes the file that was opened for fast reading.
  2550.  
  2551. NAME   :  fastread
  2552. PURPOSE:  read data from the file opened for fast reading
  2553. ARGS   :  .X   = File descriptor number
  2554.           (zp) = pointer to buffer to store data into
  2555.           .AY  = maximum number of bytes to read
  2556. RETURNS:  (zw) = .AY=number of bytes actually read in
  2557.           .CS  = error occurred flag
  2558.           .ZS  = EOF reached flag
  2559. ALTERS :  .X, errno
  2560.  
  2561. Read data from the (one) file that is currently opened for "fast"
  2562. reading. The arguments and semantics are equivalent to the regular
  2563. "read" call.
  2564.  
  2565. NAME   :  bload
  2566. PURPOSE:  binary load
  2567. ARGS   :  (zp) = pathname
  2568.           .AY  = address to load file
  2569.           (zw) = highest address that file may occupy, plus one
  2570. RETURNS:  .AY  = end address of load, plus one
  2571.           .CS  = error occurred flag
  2572. ALTERS :  .X, errno
  2573.  
  2574. Binary-load a file directly into memory.  If the file will not fit into
  2575. the specified space, an error will be returned and the load truncated if
  2576. the device supports truncation; otherwise, important data may be
  2577. overwritten.
  2578.  
  2579. NAME   :  remove
  2580. PURPOSE:  delete a file
  2581. ARGS   :  (zp) = pathname
  2582. RETURNS:  .CS  = error occurred flag
  2583. ALTERS :  .A, .X, .Y, errno
  2584.  
  2585. Delete the named file.
  2586.  
  2587. NAME   :  rename
  2588. PURPOSE:  rename a file or directory
  2589. ARGS   :  (zp) = old filename
  2590.           (zw) = new filename
  2591. RETURNS:  .CS  = error occurred flag
  2592. ALTERS :  .A, .X, .Y, errno
  2593.  
  2594. Renames a file or directory.  If a file with the new name already
  2595. exists, then the operation will be aborted and a "file exists" error
  2596. will be returned.  On most devices, the file to be renamed must be in
  2597. the current directory and the new name may not include any path, just a
  2598. filename.
  2599.  
  2600. NAME   :  devinfo
  2601. PURPOSE:  give information about device
  2602. ARGS   :  .X   = file descriptor number
  2603. RETURNS:  .A   = device type code
  2604.           .X   = number of columns on device
  2605.           .Y   = number of rows per "page" of device
  2606.           .CS  = error occurred flag
  2607. ALTERS :  errno
  2608.  
  2609. This call returns information about the device of an open file.  There
  2610. are four possible values for the device type code: 0==console,
  2611. 1==character-oriented device, and 2==disk device.  The number of rows
  2612. and columns per "page" of the device are also returned.  For the
  2613. console, this will be the current window size.  For a character-oriented
  2614. device, it will be the natural size (typically 80 columns by 66 rows),
  2615. and for a disk, it will be 40 columns in 64 mode or 80 columns in 128
  2616. mode, both by 66 rows.
  2617.  
  2618. NAME   :  fdswap
  2619. PURPOSE:  swap two file descriptor numbers
  2620. ARGS   :  .X   = first file descriptor number
  2621.           .Y   = second file descriptor number
  2622. RETURNS:  .CS  = error occurred flag
  2623. ALTERS :  .A, .X, .Y, errno
  2624.  
  2625. This call swaps meanings of two file descriptor numbers.  The file
  2626. descriptors may be either in use or not use when the call is made.  This
  2627. call is intended to be used to redirect the stdin, stdout, and stderr
  2628. file streams.  To do this, simply open the new file intended to be, for
  2629. example, stdout, and swap the file descriptor number returned from the
  2630. open with file descriptor number 1 (stdout).  Poof.  Then call your
  2631. subroutine or external program, and on return, swap the two file
  2632. descriptors back, and close the redirection file.
  2633.  
  2634. 2.2. DIRECTORY CALLS
  2635.  
  2636. NAME   :  diropen
  2637. PURPOSE:  open a directory for scanning its directory entries
  2638. ARGS   :  (zp) = directory pathname
  2639. RETURNS:  .A   = file descriptor number
  2640.           .CS  = error occurred flag
  2641. ALTERS :  .X, .Y, errno
  2642.  
  2643. This call opens a directory for reading its entries.  It returns a
  2644. "file" descriptor number to you to use for reading successive directory
  2645. entires with the "dirread" call.  The pathname that you give to this
  2646. call must be a proper directory name like "a:" or "c:2//c64/games/:",
  2647. ending with a colon character. You can have directories from multiple
  2648. devices open for reading at one time, but you cannot have the directory
  2649. of one device open multiple times.  Also note that you cannot pass
  2650. wildcards to this call; you will receive the entire directory listing.
  2651.  
  2652. NAME   :  dirclose
  2653. PURPOSE:  close a directory opened for scanning
  2654. ARGS   :  .A   = file descriptor number
  2655. RETURNS:  .CS  = error occurred flag
  2656. ALTERS :  .A, .X, .Y, errno
  2657.  
  2658. Closes a directory that is open for reading.  You can make this call at
  2659. any point while scanning a directory; you do not have to finish scanning
  2660. an entire directory first.
  2661.  
  2662. NAME   :  dirread
  2663. PURPOSE:  read the next directory entry from an open directory
  2664. ARGS   :  .X   = file descriptor number
  2665. RETURNS:  .Z   = end of directory flag
  2666.           .CS  = error occurred flag
  2667.           aceDirentBuffer = new directory entry data
  2668. ALTERS :  .A, .X, .Y, errno
  2669.  
  2670. Reads the next directory entry from the specified open directory into
  2671. the system interface global variable "aceDirentBuffer" described
  2672. earlier.  After opening a directory for reading, the first time you call
  2673. this routine, you will receive the name of the disk (or directory).  The
  2674. "aceDirentNameLen" and "aceDirentName" fields are the only ones that
  2675. will contain information; the rest of the fields should be ignored.
  2676.  
  2677. Each subsequent call to this routine will return the next directory
  2678. entry in the directory.  All of the "dirent" fields will be valid for
  2679. these.
  2680.  
  2681. Then, after all directory entries have been read through, the last call
  2682. will return a directory entry with a null (zero-length) name.  This
  2683. corresponds to the "blocks free" line in a Commodore disk directory
  2684. listing.  The "aceDirentBytes" field for this last entry will be set to
  2685. the number of bytes available for storage on the disk.  On a Commodore
  2686. disk drive, this will be the number of blocks free multiplied by 254.
  2687. After reading this last entry, you should close the directory.
  2688.  
  2689. At any time, if something bizarre happens to the listing from the disk
  2690. that is not considered an error (I don't actually know if this is
  2691. possible or not), then the .Z flag will be set, indicating the abrupt
  2692. ending of the directory listing.
  2693.  
  2694. NAME   :  isdir
  2695. PURPOSE:  determine whether the given pathname is for a file or a directory
  2696. ARGS   :  (zp) = pathname
  2697. RETURNS:  .A   = device identifier
  2698.           .X   = is a disk device flag
  2699.           .Y   = is a directory flag
  2700.           .CS  = error occurred flag
  2701. ALTERS :  errno
  2702.  
  2703. Given a properly formatted directoryname or filename, this routine will
  2704. return whether the name is for a file or a directory, whether the device
  2705. of the file or directory is a disk or character device, and the system
  2706. identifier for the device.  The two flags return $FF for true and $00
  2707. for false.  The device identifier is superfluous for now, but a
  2708. "devinfo" call may be added later. Note that this file does not indicate
  2709. whether the file/directory actually exists or not.
  2710.  
  2711. NAME   :  chdir
  2712. PURPOSE:  change the current working directory
  2713. ARGS   :  (zp) = new directory pathname
  2714. RETURNS:  .CS  = error occurred flag
  2715. ALTERS :  .A, .X, .Y, errno
  2716.  
  2717. Changes the current working directory to the named directory.  Too bad
  2718. the Commodore Kernal doesn't have a similar call.  Unlike the "cd" shell
  2719. command, the argument has to be a properly formatted directory name.
  2720. Note that only directories in native partitions on CMD devices are
  2721. supported by this command; the 1581's crummy idea of partitions is not
  2722. supported.
  2723.  
  2724. NAME   :  cdhome
  2725. PURPOSE:  change the current working directory back to the "home" directory
  2726. ARGS   :  <none>
  2727. RETURNS:  .CS  = error occurred flag
  2728. ALTERS :  .A, .X, .Y, errno
  2729.  
  2730. Changes the current working directory back to the "home" directory that
  2731. is defined in the "config.sys" file as the initial directory.
  2732.  
  2733. NAME   :  mkdir
  2734. PURPOSE:  create a new directory
  2735. ARGS   :  (zp) = pathname of new directory
  2736. RETURNS:  .CS  = error occurred flag
  2737. ALTERS :  .A, .X, .Y, errno
  2738.  
  2739. Creates a new directory.  I'm not sure, but I think that the current
  2740. directory has to be the parent directory of the directory you want to
  2741. create.  This may be required by CMD devices, which will be the lowest
  2742. common denominator for directory support.  [Note: this call is not
  2743. implemented in Release #9].
  2744.  
  2745. NAME   :  rmdir
  2746. PURPOSE:  delete an empty existing directory
  2747. ARGS   :  (zp) = pathname of empty directory to remove
  2748. RETURNS:  .CS  = error occurred flag
  2749. ALTERS :  .A, .X, .Y, errno
  2750.  
  2751. Deletes an existing directory.  The directory must be empty (have no
  2752. directory entries) in order for this command to succeed.  Again, I am
  2753. pretty sure that you have to be "in" the parent directory of the one to
  2754. be deleted, since this is probably required by CMD devices.  [Note: this
  2755. call is not implemented in Release #9].
  2756.  
  2757. 2.3. MEMORY CALLS
  2758.  
  2759. The calls given in this section are to be used for accessing "far"
  2760. memory in ACE, which includes all REU, RAMLink, RAM1 and above, and
  2761. sections of RAM0 that are not in the application program area.
  2762. Applications are not allowed to access "far" memory directly, because
  2763. the practice of bypassing the operating system would undoubtedly lead to
  2764. problems (can you say "MS-DOS"?).
  2765.  
  2766. All of these calls use a 32-bit pointer that is stored in the zero-page
  2767. argument field "mp" (memory pointer).  This field is to be interpreted
  2768. as consisting of low and high words.  The low word, which of course come
  2769. first, is the offset into the memory "bank" that is contained in the
  2770. high word. Users may assume that offsets within a bank are continuous,
  2771. so operations like addition may be performed without fear on offsets, to
  2772. access subfields of a structure, for example.  You may not, however,
  2773. make any interpretation of the bank word.  An application should only
  2774. access far memory that it has allocated for itself via the "pagealloc"
  2775. call.
  2776.  
  2777. NAME   :  zpload
  2778. ARGS   :  [mp] = source far memory pointer
  2779.           .X   = destination zero-page address
  2780.           .Y   = transfer length
  2781. RETURNS:  .CS  = error occurred flag
  2782. ALTERS :  .A, .X, .Y, errno
  2783.  
  2784. Load zero-page locations with the contents of far memory.  "mp", of
  2785. course, gives the address of the first byte of far memory to be
  2786. retrieved.  The X register is loaded with the first address of the
  2787. storage space for the data on zero page.  It must be in the application
  2788. zero-page space.  The Y register holds the number of bytes to be
  2789. transferred, which, considering that transfers must be to the
  2790. application zero-page storage, must be 126 bytes or less.  This routine
  2791. will return a "reference through null pointer" if [mp] contains a null
  2792. pointer.
  2793.  
  2794. NAME   :  zpstore
  2795. ARGS   :  .X   = source zero-page address
  2796.           [mp] = destination far memory pointer
  2797.           .Y   = transfer length
  2798. RETURNS:  .CS  = error occurred flag
  2799. ALTERS :  .A, .X, .Y, errno
  2800.  
  2801. This routine is the complement of "zpload"; this transfers data from
  2802. zero page to far memory.  The arguments and restrictions are the same as
  2803. "zpload".
  2804.  
  2805. NAME   :  fetch
  2806. ARGS   :  [mp] = source far memory pointer
  2807.           (zp) = destination RAM0 pointer
  2808.           .AY  = transfer length
  2809. RETURNS:  .CS  = error occurred flag
  2810. ALTERS :  .A, .X, .Y, errno
  2811.  
  2812. This routine will fetch up to 64K of data from far memory into RAM0
  2813. memory where it can be accessed directly by the processor.  The
  2814. arguments should mostly speak for themselves.  You should not fetch into
  2815. RAM0 memory that is not specifically allocated to the application.  You
  2816. will get an error if you try to use a null far pointer.
  2817.  
  2818. NAME   :  stash
  2819. ARGS   :  (zp) = source RAM0 pointer
  2820.           [mp] = destination far memory pointer
  2821.           .AY  = transfer length
  2822. RETURNS:  .CS  = error occurred flag
  2823. ALTERS :  .A, .X, .Y, errno
  2824.  
  2825. This is the complement of "fetch" and operates analogously, except that
  2826. it transfers data from RAM0 to far memory.
  2827.  
  2828. NAME   :  pagealloc
  2829. ARGS   :  .A   = requested number of pages to be allocated
  2830.           .X   = starting "type" of memory to search
  2831.           .Y   = ending "type" of memory to search, inclusive
  2832. RETURNS:  [mp] = far memory pointer to start of allocated memory
  2833.           .CS  = error occurred flag
  2834. ALTERS :  .A, .X, .Y, errno
  2835.  
  2836. This routine allocates a given number of contiguous far-memory pages for
  2837. use by the application, and returns a pointer to the first byte of the
  2838. first page. On calling, the accumulator contains the number of pages to
  2839. allocate (a page is 256 contiguous bytes aligned on a 256-byte address
  2840. (i.e., the low byte of a page address is all zeros)).
  2841.  
  2842. The X and Y registers contain the start and end "types" of far memory to
  2843. search for the required allocation.  The possible types are mentioned in
  2844. the System Constants section.  The numeric values for the "aceMem"
  2845. constants are arranged in order of accessing speed.  So, if your
  2846. application has speed requirements that dictate, for example, that
  2847. RAMLink memory should not be used, then you would call "pagealloc" with
  2848. a search range of .X=0 to .Y=aceMemInternal.  If you wanted to say you
  2849. are willing to accept any memory the system can give to you, you would
  2850. specify .X=0 to .Y=255.  The values of 0 and 255 will be converted to
  2851. the fastest and slowest memory available.  ACE will give you the fastest
  2852. type of memory, from what you specify as acceptable, that it can.  If
  2853. you had an application that you didn't want to waste the high-speed
  2854. memory on, you could first call "pagealloc" asking for slow memory, such
  2855. as .X=aceMemRLREU to .Y=255, and if there is none of that type of memory
  2856. left, make another call with .X=0 to .Y=aceMemRLREU-1.
  2857.  
  2858. This routine will then search its available free memory for a chunk
  2859. fitting your specifications.  If it cannot find one, the routine will
  2860. return a "insufficient memory" error and a null pointer.  Note that this
  2861. error may occur if there is actually the correct amount of memory free
  2862. but just not in a big enough contiguous chunk.  If successful, this
  2863. routine will return in "mp" a pointer to the first byte of the first
  2864. page of the allocated memory.
  2865.  
  2866. If you call a subprogram with the "exec" call while the current program
  2867. is holding far memory, that far memory will be kept allocated to your
  2868. program and will be safe while the child program is executing.  If you
  2869. don't deallocate the memory with "pagefree" before exiting back to your
  2870. parent program, then the system will automatically deallocate all memory
  2871. allocated to you.  So, have no fear about calling "exit" if you are in
  2872. the middle of complicated far memory manipulation when a fatal error
  2873. condition is discovered and you don't feel like figuring out what memory
  2874. your program owns and deallocating it.
  2875.  
  2876. Some applications will want to have the most amount of memory to work
  2877. with, and if there is free space in the application program area that
  2878. the program is not using directly, then you may want to use that as
  2879. "far" memory.  To do this, you will need to write your own stub routines
  2880. that manage page allocation and deallocation requests to the near
  2881. memory, and calls the "pagealloc" and "pagefree" routines to manage the
  2882. far memory.  The "sort" program distributed with ACE does this.  Please
  2883. note that you CANNOT simply free the unused memory of the application
  2884. program area and expect the system to manage it.  Bad stuff would
  2885. happen.
  2886.  
  2887. Some applications will want to have a byte-oriented memory allocation
  2888. service rather than a page-oriented service.  You can build a
  2889. byte-oriented service on top of the page-oriented service in your
  2890. application programs that manage memory for the application and ask the
  2891. system for pages whenever more memory is required by the application.
  2892. Note that this still means that allocated memory will be freed
  2893. automatically when an application exits.  The "sort" program implements
  2894. this byte-oriented service, so you can check its source code to see how
  2895. this is done (or to simply cut and paste the code into your own
  2896. program).
  2897.  
  2898. NAME   :  pagefree
  2899. ARGS   :  [mp] = far memory pointer to start of memory to be freed
  2900.           .A   = number of pages to be freed
  2901. RETURNS:  .CS  = error occurred flag
  2902. ALTERS :  .A, .X, .Y, errno
  2903.  
  2904. This deallocates memory that was allocated to a process by using the
  2905. "pagealloc" system call.  You will get an error return if you try to
  2906. deallocate memory that you don't own.
  2907.  
  2908. 2.4. SCREEN CONTROL CALLS
  2909.  
  2910. This section describes the system calls that are available to
  2911. application programmers for full-screen applications.  These calls are
  2912. intended to be general enough to handle different screen hardware (the
  2913. VIC and VDC chips and a VIC soft-80-column bitmap screen, and possibly
  2914. others).  These calls are also designed to be efficient as possible, to
  2915. discourage progammers from attempting to bypass using them.  Bypassing
  2916. these calls would be a bad thing.
  2917.  
  2918. The calls are designed around the C-128/PET concept of a window.  There
  2919. is only one active window on the display at a time, which may be is
  2920. large as the entire screen or as small as 1x1 character cells.  This
  2921. window is very cheap to setup and tear down.  An application can have
  2922. multiple windows on the screen by switching the active window around.
  2923.  
  2924. In the calls below, all mention of "sw" in the arguments and return
  2925. values refer to the "syswork" array.  For many calls, there is a
  2926. "char/color/ high-attribute" argument.  This argument determines which
  2927. parts of a screen location will be modified.  There are three components
  2928. to each screen location: the character code, the color code, and the
  2929. high-attributes.  The character code is exactly the same as the PETSCII
  2930. code for the character that you want to display (unlike the screen-code
  2931. arrangement that Commodore chose). There are 128 individual characters
  2932. in the normal PETSCII positions, and 128 reversed images of the
  2933. characters in the most sensible other positions.  The codes are as
  2934. follows:
  2935.  
  2936. CODES (hex)   DESCRIPTION
  2937. -----------   -----------
  2938. $00-$1f       reverse lowercase letters
  2939. $20-$3f       digits and punctuation
  2940. $40-$5f       lowercase letters
  2941. $60-$7f       reverse graphics characters
  2942. $80-$9f       reverse uppercase letters
  2943. $a0-$bf       graphics characters
  2944. $c0-$df       uppercase letters
  2945. $e0-$ef       reverse digits and punctuation
  2946.  
  2947. There are sixteen color codes, occupying the lower four bits of the color
  2948. value.  These are RGBI codes, as follows:
  2949.  
  2950. CODE(dec)   (hex)   (bin)   DESCRIPTION
  2951. ---------   -----   -rgbi   -----------
  2952.         0      $0   %0000   black
  2953.         1      $1   %0001   dark grey
  2954.         2      $2   %0010   blue
  2955.         3      $3   %0011   light blue
  2956.         4      $4   %0100   green
  2957.         5      $5   %0101   light green
  2958.         6      $6   %0110   dark cyan on VDC, medium grey on VIC-II
  2959.         7      $7   %0111   cyan
  2960.         8      $8   %1000   red
  2961.         9      $9   %1001   light red
  2962.        10      $a   %1010   purple
  2963.        11      $b   %1011   light purple on VDC, orange on VIC-II
  2964.        12      $c   %1100   brown
  2965.        13      $d   %1101   yellow
  2966.        14      $e   %1110   light grey
  2967.        15      $f   %1111   white
  2968.  
  2969. Finally, there are the high-attribute bits.  These occupy the four most
  2970. significant bits of the color value.  Depending on the type of display
  2971. (VIC text, VDC text, or VIC/VDC bitmap), these bits have one of three
  2972. meanings: character attributes, background character color, or no
  2973. effect.  Thus, care must be taken in using these bits; they will have
  2974. different effects on different displays.  The background character codes
  2975. are the same as the foreground character codes listed above.  The
  2976. character attributes have the following meanings:
  2977.  
  2978. BIT VALUE   (dec)   (hex)   DESCRIPTION
  2979. -avub----   -----   -----   -----------
  2980. %10000000     128     $80   alternate characterset (italic)
  2981. %01000000      64     $40   reverse character
  2982. %00100000      32     $20   underline
  2983. %00010000      16     $10   blink
  2984.  
  2985. These values are additive (or, should I say, "or-ative"); you can use
  2986. any combination of them at one time.  Normally, you may wish to leave
  2987. the high-attribute bits alone, unless you take the values to give them
  2988. from the color palettes (next section).  To specify which of you wish to
  2989. have changed, set bits in the "char/color/high-attribute" argument to
  2990. system calls.  The flags have the following values.  They are or-ative
  2991. as well:
  2992.  
  2993. BIT VALUE   (dec)   (hex)   DESCRIPTION
  2994. -cah-----   -----   -----   -----------
  2995. %10000000     128     $80   modify character
  2996. %01000000      64     $40   modify color
  2997. %00100000      32     $20   modify high-attribute bits
  2998.  
  2999. The screen calls that deal with placing characters on the screen refer
  3000. to screen locations using absolute addresses of locations in screen
  3001. memory.  This scheme is used for increased efficiency.  You can obtain
  3002. information about the absolute screen address of the top left-hand
  3003. corner of the current window and the number of screen addresses between
  3004. successive rows, to figure out screen addresses for your applications.
  3005. For added convenience, there is a call which will accept row and column
  3006. numbers and return the corresponding absolute screen address.
  3007.  
  3008. The screen-control system calls are as follows:
  3009.  
  3010. NAME   :  winmax
  3011. ARGS   :  <none>
  3012. RETURNS:  <none>
  3013. ALTERS :  .A, .X, .Y
  3014.  
  3015. Sets the current window to cover the entire screen.
  3016.  
  3017. NAME   :  winclear
  3018. ARGS   :  .A   = char/color/high-attribute modification flags
  3019.           .X   = character fill value
  3020.           .Y   = color fill value
  3021. RETURNS:  <none>
  3022. ALTERS :  .A, .X, .Y
  3023.  
  3024. This call "clears" the current window by filling it with the
  3025. character/color you specify.  You can use the char/color/hi-attr to
  3026. limit what gets cleared. [Note: The arguments for this call are slightly
  3027. different in Release #9].
  3028.  
  3029. NAME   :  winset
  3030. ARGS   :  .A   = number of rows in window
  3031.           .X   = number of columns in window
  3032.           sw+0 = absolute screen row of top left corner of window
  3033.           sw+1 = absolute screen column of top left corner of window
  3034. RETURNS:  .CS  = error occurred flag
  3035. ALTERS :  .A, .X, .Y, errno
  3036.  
  3037. Sets the current window to the size you specify.  You will get an error
  3038. return if the window will not fit on the screen or of it does not
  3039. contain at least one character. [Note: This call is not implemented in
  3040. Release #9].
  3041.  
  3042. NAME   :  winsize
  3043. ARGS   :  <none>
  3044. RETURNS:  .A   = number of rows in window
  3045.           .X   = number of columns in window
  3046.           sw+0 = absolute screen row of top left corner of window
  3047.           sw+1 = absolute screen column of top left corner of window
  3048.          (sw+2)= screen address of top left corner
  3049.          (sw+4)= screen address increment between successive rows on screen
  3050. ALTERS :  <none>
  3051.  
  3052. Returns information about the current window. [Note: the arguments are
  3053. slightly different in Release #9].
  3054.  
  3055. NAME   :  winput
  3056. ARGS   : (sw+0)= absolute screen address to start putting data at
  3057.          (sw+2)= character string pointer
  3058.           .X   = length of character string
  3059.           .Y   = color
  3060.           .A   = char/color/high-attribute modification flags
  3061.           sw+4 = fill character
  3062.           sw+5 = total field length
  3063. RETURNS:  <none>
  3064. ALTERS :  .A, .X, .Y
  3065.  
  3066. Puts text onto the screen.  The output region is given by the absolute
  3067. starting screen address and the total field length.  This region must be
  3068. contained on one line of the current window, or bad things will happen.
  3069. A pointer to the characters to be printed is given, as well as the
  3070. length of the character array.  Control characters in this string are
  3071. ignored; they are poked literally onto the screen, including the null
  3072. character.  The length of the character string must be less than or
  3073. equal to the total length of the field.  Remaining spaces in the field
  3074. will be filled in with the "fill character".
  3075.  
  3076. The color of the total field length will be filled in with "color".  You
  3077. can use the "char/color/hi-attr" modification flags to specify what is
  3078. to be changed.  If you were to, for example, specify that the colors of
  3079. the field are not to be changed, then the call would execute faster.
  3080.  
  3081. NAME   :  wincolor
  3082. ARGS   :  .X   = new RGBI screen color
  3083.           .Y   = new RGBI border color
  3084.           .A   = which colors to change ($80=screen + $40=border)
  3085. RETURNS:  .X   = resulting RGBI screen color
  3086.           .Y   = resulting RGBI border color
  3087. ALTERS :  .A
  3088.  
  3089. Sets the color of the screen and border.  You may optionally set one,
  3090. the other, both, or neither.  The resulting colors for colors changed,
  3091. and the existing colors for colors unchaned will be returned.  Note that
  3092. not all screens have an adjustable color, so the border argument may be
  3093. ignored.
  3094.  
  3095. NAME   :  winpos
  3096. ARGS   :  .A   = row
  3097.           .X   = column
  3098. RETURNS: (sw+0)= screen memory address of position
  3099. ALTERS :  .A, .X, .Y
  3100.  
  3101. Given a row and column in the current window, returns the corresponding
  3102. absolute screen memory location for use with other calls.  No errors are
  3103. returned, so garbage in, garbage out.
  3104.  
  3105. NAME   :  wincursor
  3106. ARGS   : (sw+0)= screen address to place cursor
  3107.           .A   = enable flag ($ff=cursor-on / $00=cursor-off)
  3108.           .Y   = color to show cursor in
  3109. RETURNS:  <none>
  3110. ALTERS :  .A, .X, .Y
  3111.  
  3112. Displays or undisplays the cursor at the given screen address.  This
  3113. call returns immediately in either case.  No errors are returned.  Do
  3114. not display anything in or scroll the window while the cursor is being
  3115. displayed, do not display the cursor twice, and do not undisplay the
  3116. cursor twice in a row or bad things will happen.  Also, make sure you
  3117. give the same address when undisplaying the cursor as you did when
  3118. displaying the cursor.  When the system starts, the cursor will be in
  3119. its undisplayed state (duh!).  You also get to specify the color you
  3120. want the cursor to be shown in.  The high-attribute bits of this color
  3121. are ignored.
  3122.  
  3123. NAME   :  winscroll
  3124. ARGS   :  .A   = flags: char/color/hi-attr + $08=up + $04=down
  3125.           .X   = number of rows to scroll up/down
  3126.           sw+4 = fill character
  3127.           .Y   = fill color
  3128. RETURNS:  <none>
  3129. ALTERS :  .A, .X, .Y
  3130.  
  3131. Scrolls the contents of the current window up or down.  You can scroll
  3132. any number of rows at a time.  After scrolling, the bottom (or top) rows
  3133. will be filled with the fill character and color.  You can limit whether
  3134. the characters and/or colors are to be scrolled by using the "flags"
  3135. byte in the usual way.  Scrolling only the characters, for example, will
  3136. be twice as fast as scrolling both characters and attributes.  Whether
  3137. to scroll up or down is specified also using bits in the "flags" field,
  3138. as indicated in the input arguments above.  You can specify scrolling in
  3139. more than one way, and the result will be to scroll in each specified
  3140. direction in turn, in the order up, then down.  In the future, scrolling
  3141. left and right may be added to this call. [Note: The arguments and
  3142. semantics of this call are a little different in Release #9].
  3143.  
  3144. 2.5. CONSOLE CALLS
  3145.  
  3146. The calls in this section refer to the system "console", which includes
  3147. the screen and keyboard.  The screen-related calls are at a higher level
  3148. than the calls in the previous section.
  3149.  
  3150. NAME   :  stopkey
  3151. ARGS   :  <none>
  3152. RETURNS:  .CS  = stop key pressed
  3153. ALTERS :  .A, .X, .Y, errno
  3154.  
  3155. Indicates whether the STOP (RUN/STOP) key is currently being held down
  3156. by the user.  If so, carry flag is set on return (and clear if not).  If
  3157. the stop key is discovered to be pressed by this call, then the keyboard
  3158. buffer will also be cleared.
  3159.  
  3160. NAME   :  getkey
  3161. ARGS   :  <none>
  3162. RETURNS:  .A   = keyboard character
  3163. ALTERS :  .X, .Y
  3164.  
  3165. Waits for the user to type a key (or takes a previous keystroke from the
  3166. keyboard buffer).  Regular characters are returned in their regular
  3167. PETSCII codes, but there are many special control keystrokes.  They are
  3168. not listed here (yet) because I haven't figured out what all of the
  3169. special codes should be, but all 256 possible character values will be
  3170. covered.  Special codes like "page up", etc. should help in
  3171. standardizing control keystrokes for applications.  The key code is
  3172. returned in the accumulator.  No errors are possible.
  3173.  
  3174. NAME   :  concolor
  3175. ARGS   :  .A   = which colors to modify: $02=character + $01=cursor 
  3176.                  + $80=modify high-attributes of colors
  3177.           .X   = new RGBI character color
  3178.           .Y   = new RGBI cursor color
  3179. RETURNS:  .X   = resulting character color
  3180.           .Y   = resulting cursor color
  3181. ALTERS :  .A
  3182.  
  3183. Sets the character and cursor colors to be used by the console for the
  3184. "read" and "write" system calls that refer to files opened to the
  3185. console device. You can use the flags argument to limit what gets
  3186. changed. [Note: flags argument is slightly different in Release #9].
  3187.  
  3188. NAME   :  conpalette
  3189. ARGS   :  <none>
  3190. RETURNS:  sw+0 = main character color
  3191.           sw+1 = cursor color
  3192.           sw+2 = status character color
  3193.           sw+3 = separator character color
  3194.           sw+4 = highlight character color
  3195.           sw+5 = alert character color
  3196.           sw+6 = screen border color
  3197.           sw+7 = screen background color
  3198. ALTERS :  .A, .X, .Y
  3199.  
  3200. Returns the palette of colors that are recommended to be used in
  3201. applications. These colors are chosen by the user in the system
  3202. configuration, so they can be interpreted as being what the user wants
  3203. and expects applications to use. A different selection is made by the
  3204. user for each different screen type, and the palette returned will be
  3205. for the screen type currently in use.  The high-attribute bits of these
  3206. colors are valid.  Eight colors are included in the palette, and you may
  3207. interpret their meaning according to the application. The suggested
  3208. usages are given in the return arguments listed above.
  3209.  
  3210. NAME   :  conscreen
  3211. ARGS   :  .A   = number of text rows required, minimum
  3212.           .X   = number of text columns required, minimum
  3213. RETURNS:  .A   = number of text rows you get
  3214.           .X   = number of text columns you get
  3215.           .CS  = error occurred flag (requested size cannot be given)
  3216. ALTERS :  .Y, errno
  3217.  
  3218. This call selects an appropriate display device, screen, and layout for
  3219. displaying text.  You ask for the minimum number of rows and columns you
  3220. require on the screen, and the call returns to you what you receive.  If
  3221. the system cannot match your minimum requirements, an error will be
  3222. returned, and the current screen will be unchanged.  The clock speed of
  3223. the processor will be changed to match the screen selected, if
  3224. appropriate.
  3225.  
  3226. NAME   :  conpos
  3227. ARGS   :  .A   = row
  3228.           .X   = column
  3229. RETURNS:  .CS  = error encountered flag
  3230. ALTERS :  .A, .X, .Y
  3231.  
  3232. This call will set the screen location that the next console "read" or
  3233. "write" system call will operate from.  If the "cursor" position is
  3234. outside the boundaries of the current window on the screen, an error
  3235. will be returned. [Note: this function is not implemented in Release
  3236. #9].
  3237.  
  3238. 2.6. PROCESS CONTROL CALLS
  3239.  
  3240. This section describes calls that are used to control the execution of
  3241. processes (active programs).  From within one program, you can call for
  3242. the execution of another program, have it execute, and then return to
  3243. the calling program.  Since only one program is allowed in memory at a
  3244. time, some special problems arise.  Also, only rudimentary versions of
  3245. these system calls are implemented in Release #9 and I haven't decided
  3246. completely how they should work.  So, this section is a bit tentative.
  3247.  
  3248. NAME   :  exec
  3249. PURPOSE:  execute external program as a child process
  3250. ARGS   :  (zp) = program name of executable
  3251.           (zw) = start address of argument vector
  3252.           .AY  = number of arguments
  3253.           [mp] = pointer to far memory volatile storage
  3254. RETURNS:  .A   = exit code
  3255.           .X   = number of bytes in "aceExitData" used
  3256.           [mp] = pointer to far memory volatile storage
  3257.           .CS  = error occurred flag
  3258. ALTERS :  .Y, errno
  3259.  
  3260. Calling this routine will cause a new "frame" to be set up on the
  3261. "system stack" (lowering the available application area memory a
  3262. little), the specified program to be loaded into memory over top of the
  3263. current one, the new program to be executed, the old program to be
  3264. reloaded from whatever disk unit it came from originally upon exit of
  3265. the new program, and control to be returned to the old process with the
  3266. return values from the executed program. This is a complicated procedure
  3267. and many things can go wrong.
  3268.  
  3269. The first thing that a process that wants to call another program must
  3270. do is set up the arguments to be passed in.  All arguments must be
  3271. null-terminated strings.  These arguments are to be put into high
  3272. memory, starting from one less than the location pointed to by
  3273. "aceMemTop" and working downward.  It does not matter in which order the
  3274. strings are placed, as long as they are all grouped together.  Then,
  3275. immediately below the strings comes the vector of two-byte RAM0 pointers
  3276. that point to the strings.  This array must be in order, with the lowest
  3277. entry pointing to the first (zero subscript) string, etc., the second
  3278. highest entry pointing to the last string, and the highest entry
  3279. containing the value $0000.  An asciigram follows:
  3280.  
  3281.   HIGHER ADDRESSES
  3282. |           |
  3283. |           | <--(aceMemTop)
  3284. +-----------+
  3285. |           |
  3286. | string    |
  3287. |           |         : collection of null-terminated strings
  3288. |  contents |
  3289. |           |
  3290. |           |
  3291. +-----------+
  3292. |   $0000   |         : argv[N] : null argument pointer
  3293. +-----------+
  3294. | strptrN-1 |         : argv[N-1]
  3295. +-----------+
  3296. | strptrN-2 |         : argv[N-2]
  3297. +-----------+
  3298. .           .
  3299. .           .
  3300. +-----------+
  3301. | strptr 1  |         : argv[1] : first actual argument
  3302. +-----------+
  3303. | strptr 0  | <--(zw) : argv[0] : filename of program to be executed
  3304. +-----------+
  3305. |           |
  3306.   LOWER ADDRESSES
  3307.  
  3308. The first entry should indicate the filename or command name of the
  3309. program being executed, and the subsequent arguments are the actual
  3310. input arguments to the program being called.  The address of the first
  3311. argument vector table entry is loaded into (zw), and the number of
  3312. arguments is loaded into .AY. Note that this value also includes the
  3313. command name, so if, for example, you were to call program "wc" to count
  3314. two filenames "hello" and "goodbye", then you would pass an argument
  3315. count of 3.  The name pointed to by "argv[0]" does not actually have to
  3316. be the literal command name, but the one pointed to by (zp) does.  If a
  3317. relative executable name is given in (zp), then the search path will be
  3318. used to locate the executable.  Oh, don't screw up the organization of
  3319. the arguments or bad things will happen; there is no structure checking.
  3320.  
  3321. After setting up the arguments, you'll want to set up any redirections
  3322. of stdin, stdout, or stderr you'll be needing.  Because there is only
  3323. one open file table in the whole uni-tasking system, you'll have to
  3324. manipulate existing entries using the "fdswap" system call described
  3325. earlier.  The open file table is inherited by the child process.  Note
  3326. that if it closes any of the open files it inherited, then they are also
  3327. closed to your use also.  If the child accidentally leaves open any
  3328. files it opened, they will be closed by the system before you are
  3329. reactivated.
  3330.  
  3331. Finally, before the call is made, you have to save any volatile local
  3332. information into "far" memory.  All application zeropage and application
  3333. area memory will be modified by the called program, so you must save
  3334. whatever you will need to continue after the return to be able to
  3335. continue.  As mentioned earlier, all of the "far" memory that a parent
  3336. program owns will be safe, so you can save your volatile information
  3337. there, in any format you wish.  All you have to do is save the pointer
  3338. to the far memory into the [mp] pointer.  Upon return of the child
  3339. process, the value you put into [mp] will be restored, and you can then
  3340. restore your volatile information out of far storage.  If you wish to
  3341. save no volatile information, then you can just leave garbage in the
  3342. [mp] value, since it will not be interpreted by the system.
  3343.  
  3344. Alright, so now you call the "exec" primitive, the child program is
  3345. loaded, executed, and it returns.
  3346.  
  3347. At this time, the parent program (that's you) is reloaded from wherever
  3348. it was loaded originally and you are returned to the instruction
  3349. immediately following the "jsr exec", with your processor stack intact
  3350. but the rest of your volatile storage invalid.  Even if there is an
  3351. error return (carry flag set), your volatile storage will still need to
  3352. be restored, since the application area may have been overwritten before
  3353. the error was discovered.  In the case of an error return, the child
  3354. process will not have been executed.  If the system is unable to reload
  3355. the parent program (you), then an error return is given to your parent,
  3356. and so on, as far back as necessary.  (This is a minor exception to the
  3357. rule that an error return indicates that a child didn't execute; in this
  3358. case, the child didn't complete).
  3359.  
  3360. You are also returned an "exit code", which will have
  3361. application-specific meaning, although standard programs (e.g., shell
  3362. script) interpret the value as: 0==normal exit, anything else==error
  3363. exit.  The X register is also set to indicate the amount of
  3364. "aceExitData" that is used, to allow for more complicated return values.
  3365.  
  3366. [Note: This call is different in Release #9].
  3367.  
  3368. NAME   :  execsub
  3369. PURPOSE:  execute internal subroutine as a separate process
  3370. ARGS   :  (zp) = address of subroutine
  3371.           (zw) = address of argument vector
  3372. RETURNS:  .A   = exit code
  3373.           .X   = number of bytes in "aceExitData" used
  3374.           .CS  = error occurred flag
  3375. ALTERS :  .Y, errno
  3376.  
  3377. This call is very similar to "exec", except that it calls an internal
  3378. subroutine rather than an external program.  Thus, you don't have to
  3379. save or restore your volatile storage, or worry about loading the child
  3380. or reloading the parent.  You do, however, set up the arguments and file
  3381. redirections as you would for a full "exec".  [Note: this call is
  3382. different in Release #9].
  3383.  
  3384. NAME   :  exit
  3385. PURPOSE:  exit current program, return to parent
  3386. ARGS   :  .A   = exit code
  3387.           .X   = number of bytes in "aceExitData" used
  3388. RETURNS:  <there is no return, brah-ha-ha-ha-ha-ha!!!>
  3389. ALTERS :  <don't bloody well matter>
  3390.  
  3391. This call causes the current program to exit back to its parent. A
  3392. program that exits simply by returning to its environment will give back
  3393. an exit code of 0, which should be interpreted as a normal return.  If
  3394. you wish to indicate a special return, you should use some exit code
  3395. other than zero.  Many utilities will interpret non-zero error codes as
  3396. actual errors and may abort further operations because of this.
  3397.  
  3398. You may set up a return data in "aceExitData", up to 255 bytes worth,
  3399. and load the number of bytes used into .X if you wish.  It is
  3400. recommended that the first field of this data be a special identifier
  3401. code so programs that cannot interpret your data will not try.  You
  3402. cannot give any far pointers in your return data, since all far memory
  3403. allocated to you will be freed by the system before returning to your
  3404. parent.
  3405.  
  3406. NAME   :  memstat
  3407. PURPOSE:  get "far" memory status plus process id
  3408. ARGS   :  <none>
  3409. RETURNS:  .A   = current process id
  3410.          [sw+0]= amount of "far" memory free
  3411.          [sw+4]= total amount of "far" memory
  3412. ALTERS :  .X, .Y
  3413.  
  3414. This call returns the current process id, the number of bytes of far
  3415. memory currently free, and the total amount of far memory.
  3416.  
  3417. 2.7. MISCELLANEOUS CALLS
  3418.  
  3419. NAME   :  utoa
  3420. PURPOSE:  convert unsigned 32-bit number to a decimal PETSCII string
  3421. ARGS   :  .A   = minimum length for return string
  3422.           .X   = zero-page address of 32-bit number
  3423.          (sw+0)= pointer to string buffer to store string
  3424. RETURNS:  .Y   = length of string
  3425. ALTERS :  .A, .X
  3426.  
  3427. This is a utility call in the kernel.  It is really not necessary for it
  3428. to be in the kernel, but so many programs make use of it that it makes
  3429. sense for it to be factored out.  You give a pointer to a 32-bit
  3430. unsigned value in zero page memory, a pointer to a buffer to store that
  3431. string that is at least as long as necessary to store the value plus the
  3432. null-character terminator that will be put on the end of the string, and
  3433. a minimum length value for the string.  If the number requires fewer
  3434. digits than the minimum length, the string will be padded with spaces on
  3435. the left.  Since a 32-bit quantity can only contain an maximum of ten
  3436. decimal digits, the string buffer will only need to be a maximum of
  3437. eleven bytes in size.
  3438.  
  3439. NAME   :  getdate
  3440. PURPOSE:  get the current date and time
  3441. ARGS   : (.AY) = address of buffer to put BCD-format date into
  3442. RETURNS:  <none>
  3443. ALTERS :  .A, .X, .Y
  3444.  
  3445. Returns the current date and time in the BCD format described in the
  3446. paragraph on "aceDirentDate".  It puts it into the at-least-eight-byte
  3447. storage area pointed to by (.AY).
  3448.  
  3449. NAME   :  setdate
  3450. PURPOSE:  set the current date and time
  3451. ARGS   : (.AY) = address of date in BCD format
  3452. RETURNS:  <none>
  3453. ALTERS :  .A, .X, .Y
  3454.  
  3455. Sets the current date and time in the system.  (.AY) points to the BCD
  3456. date string whose format is discussed in the paragraph on
  3457. "aceDirentDate".  No validity checking is performed on the date given.
  3458.  
  3459. NAME   :  cmdopen
  3460. PURPOSE:  open command channel to Commodore disk drives
  3461. ARGS   :  (zp) = device name
  3462. RETURNS:  .A   = file descriptor number
  3463.           .CS  = error occurred flag
  3464. ALTERS :  .X, .Y, errno
  3465.  
  3466. This "cmd" set of system calls really should not be present, but they
  3467. will be needed until the full complement of disk-utility system calls
  3468. are implemented. It is really not recommended that any application
  3469. program rely on these calls being around very long.  This call opens the
  3470. command channel on the named device (standard ACE device name string)
  3471. and returns the file descriptor number to use thereafter.
  3472.  
  3473. NAME   :  cmdclose
  3474. PURPOSE:  close command channel to Commodore disk drives
  3475. ARGS   :  .A   = file descriptor number
  3476. RETURNS:  .CS  = error occurred flag
  3477. ALTERS :  .A, .X, .Y, errno
  3478.  
  3479. This closes an opened command channel to a disk drive.  Closing the
  3480. status will NOT affect any other open files on the disk unit at the
  3481. time.
  3482.  
  3483. NAME   :  cmdsend
  3484. PURPOSE:  send command over command channel to Commodore disk drives
  3485. ARGS   :  .X   = file descriptor number
  3486.          (.AY) = pointer to null-terminated command string
  3487. RETURNS:  .CS  = error occurred flag
  3488. ALTERS :  .A, .X, .Y, errno
  3489.  
  3490. This sends a command string to a disk drive.  Since a null-terminated
  3491. string representation is used, not all Commodore/CMD-DOS commands can be
  3492. sent, but the important ones can be.
  3493.  
  3494. NAME   :  cmdstatus
  3495. PURPOSE:  receive current status from command channel of Commodore disk drives
  3496. ARGS   :  .X   = file descriptor number
  3497.          (.AY) = pointer to buffer for null-terminated status string
  3498. RETURNS:  .A   = status code in binary
  3499.           .CS  = error occurred
  3500. ALTERS :  .X, .Y, errno
  3501.  
  3502. This returns the status of a disk drive in a string as well as the
  3503. binary disk status number in the accumulator.  The given status buffer
  3504. must be at least 50 or so characters long (whatever is the longest
  3505. possible disk status string).
  3506.  
  3507. 3. USER PROGRAM ORGANIZATION
  3508.  
  3509. The ACE system itself is written using the Buddy-128 assembler, so it is
  3510. recommended that applications be written in this also.  User programs
  3511. for ACE have a very simple structure.  Here is the standard "hello,
  3512. world" example program written in Buddy assembler for ACE:
  3513.  
  3514. -----=-----
  3515. .seq acehead.s
  3516. .org aceAppAddress
  3517. .obj "@0:hello"
  3518.  
  3519. jmp main
  3520. .byte aceID1,aceID2,aceID3
  3521.  
  3522. main = *
  3523.    lda #<helloMsg
  3524.    ldy #>helloMsg
  3525.    sta zp+0
  3526.    sty zp+1
  3527.    lda #<helloMsgEnd-helloMsg
  3528.    ldy #>helloMsgEnd-helloMsg
  3529.    ldx #stdout
  3530.    jsr write
  3531.    rts
  3532.  
  3533. helloMsg = *
  3534.    .asc "Hello, cruel world."
  3535.    .byte 13
  3536. helloMsgEnd = *
  3537. -----=-----
  3538.  
  3539. This would normally be put into a file called "hello.s".  The ".s"
  3540. extension means that this is an assembler file (a la Unix).  The first
  3541. thing this program does is include the "acehead.s" file.  This is the
  3542. Buddy assembler file that contains the header information declarations
  3543. required to access the ACE system interface.  The next line gives the
  3544. start address to start assembling to; it must be "aceAppAddress", which
  3545. is the address that ACE will load the program at.  The next line is a
  3546. directive to the assembler to write the executable code to a
  3547. Commodore-DOS "PRG" file named "hello".  This will be the command to
  3548. enter at the ACE shell prompt.
  3549.  
  3550. The next six bytes of object code (which are the first six bytes of a
  3551. program) describe the header required by ACE programs.  The first three
  3552. bytes must be a JMP to the main routine of the program.  The next three
  3553. bytes must have the values "aceID1", "aceID2", and "aceID3",
  3554. respectively.  And that's all there is to it.  The rest of the program
  3555. can be organized however you want it to be.
  3556.  
  3557. In this example, we set up the arguments for the "write" system call to
  3558. print the string "Hello, cruel world." plus a carriage return to
  3559. standard output.  Note that this string does not need a terminating null
  3560. ($00) character since the write call takes a buffer length.  The program
  3561. then returns to its calling environment via an RTS.  This will cause an
  3562. implied "exit(0)" to be performed by the system, returning to the parent
  3563. program.
  3564.  
  3565. Although this program does not take advantage of this, an application
  3566. program may use zero-page locations $0002 through $007f for storage
  3567. without fear of having the storage trodden upon by the system.  Also,
  3568. the processor stack may be used from the point it was at upon entry to
  3569. your program all the way down to the bottom.  I will be doing something
  3570. about ensuring there is always enough processor space for an application
  3571. to use in the future, but for now, all applications have to share the
  3572. single page of processor stack storage.
  3573.  
  3574. Finally, an application program starts at location "aceAppAddress" (plus
  3575. six) and is allowed to use memory all the way up to one byte less than
  3576. the address pointed to by "aceMemTop" for its own purposes.  Currently,
  3577. this amount of space is on the order of magnitude of about 24K.  This
  3578. will be increased in the future.
  3579.  
  3580. Application programs are not to access I/O features or even change the
  3581. current memory configuration during execution.  All I/O and unusual
  3582. contortions must be performed by ACE system calls; otherwise, we could
  3583. end up in as bad a shape as MESS-DOS.
  3584.  
  3585. 4. CONCLUSION
  3586.  
  3587. Cool, eh?
  3588. =============================================================================
  3589. Looking Ahead: (Learned my lesson about "In The Next Issue" :-) (re: the
  3590.                 mouse article etc....) )
  3591.  
  3592. Either a Multi-Tasking article or a look at the Internals of Ace.
  3593.  
  3594. More graphics techniques.
  3595.  
  3596. Answers to the Trivia in this issue.
  3597.  
  3598. More articles and other information.
  3599.  
  3600. (Sorry that this is a little bit more vague than last time - Just have some
  3601.  authors actually finding real jobs, and others that forgot to include what
  3602.  they were going to do for the next issue.)
  3603.  
  3604.