|
|
Line 1: |
Line 1: |
| Taken from [http://www.ffd2.com/fridge/chacking/ The Fridge C=Hacking Section] | | Taken from [http://www.ffd2.com/fridge/chacking/ The Fridge C=Hacking Section] C=Hacking Issue #7 |
| <pre>
| |
| ########
| |
| ##################
| |
| ###### ######
| |
| #####
| |
| ##### #### #### ## ##### #### #### #### #### #### #####
| |
| ##### ## ## #### ## ## ## ### ## #### ## ## ##
| |
| ##### ######## ## ## ## ##### ## ## ## ## ##
| |
| ##### ## ## ######## ## ## ## ### ## ## #### ## ##
| |
| ##### #### #### #### #### ##### #### #### #### #### #### ######
| |
| ##### ##
| |
| ###### ###### Issue #7
| |
| ################## Feb. '94
| |
| ########
| |
| | |
| -----------------------------------------------------------------------------
| |
| Editor's Notes:
| |
| by Craig Taylor (duck@pembvax1.pembroke.edu)
| |
|
| |
|
| This net-magazine is still alive after over two years suprising even | | This issue of '''C=Hacking #7''' was stripped down to just the ''Hiding kilobytes'' article by Marko Mäkela which contains the interesting sections "_Freezer cartridges_" and "_Building an unbeatable freezer circuit_". |
| myself. There should be more to come also!! And it's been late everytime
| |
| it's been released. :-) I dunno - I'm trying not to make that a
| |
| tradition but next time I don't think I'm going to set any firm dates so
| |
| it can't possibly be late.
| |
|
| |
|
| Lesee, first to address some questions and queries that have been going
| |
| on over the network:
| |
|
| |
|
| - The C project that I mentioned a while back is now officially
| | <pre> |
| defunct, dead, resting in peace... whatever you want to call it.
| |
| There may be other individuals working on their own version of an
| |
| ANSI C compiler but the group that was setup is no longer.
| |
| Basically, it was a problem of too many programmers, too few
| |
| managers (and we know programmers *grins* - They all want to do it
| |
| their way. Incidentilly - my way _was_ the best. ;-) )
| |
| | |
| - The C65 exists but there are very few of them out there and
| |
| GrapeVine no longer sells them (out of stock I believe). It was only
| |
| made in small quantities for prototype work. There have been
| |
| numerous individuals reading comp.sys.cbm that see mention of the
| |
| C65 and assume that this creature Commodore released. Commodore sold
| |
| a warehouse and its contents to Grapevine and Grapevine stumbled
| |
| across them and sold 'em. They are functional but due to the low
| |
| number of them available I doubt that there will be any C65 targated
| |
| applications. (Someone prove me wrong, please?)
| |
| | |
| - Geesh - That stupid article about the 1351 mouse that I kept
| |
| promising from issue 2 on I've officially declared dead. It may come
| |
| around later but for now it's dead. It's existed as a promise in one
| |
| form or another since issue 2 so this message officially kills it.
| |
| | |
| - Also there was some confusion last time about my wording about not
| |
| writing any more articles and such (or rather, not as many as I had
| |
| been). Basically, yes - I'm still going to do C=Hacking - it's just
| |
| that because of time, frustration, school and jobs that I don't have
| |
| as much time to devote to researching and writing articles. That's
| |
| all that I meant to say - some people were concerned that C=Hacking
| |
| was no longer going to be released...
| |
| | |
| As always, here's the obligatory begging for authors on any type of
| |
| software or hardware project that involves the Commodore computers.
| |
| Please, Please if you or your user group has any information or material
| |
| concerning the Commodore computers that you think may be appropriate for
| |
| C=Hacking let me know via e-mail at duck@pembvax1.pembroke.edu. I'm
| |
| looking for anything from hardware schematic, programming theory to
| |
| actual programming techniques, programs.
| |
| | |
| The articles in this issue of C=Hacking I'm especially pleased with.
| |
| There are two articles concerning the VIC chip and its operations that
| |
| detail how certain "magical" techniques are performed. Also, Marko
| |
| Makela has written a very detailed, interesting article on various
| |
| memory techniques for the C-64. We also have a summary of the ACE
| |
| programming / operating system and a referance guide on how to write
| |
| applications for it. I've also included an InterNet guide that I've
| |
| started writing to show individuals how to use the InterNet to get
| |
| Commodore-64/128/Vic-20 related material. Included within that is a list
| |
| of FTP sites containing numerous programs.
| |
| | |
| =============================================================================
| |
| | |
| Please note that this issue and prior ones are available via anonymous
| |
| FTP from ccosun.caltech.edu (among others) under pub/rknop/hacking.mag
| |
| and via a mailserver which documentation can be obtained by sending
| |
| mail to "duck@pembvax1.pembroke.edu" with a subject line of
| |
| "mailserver" and the line "help" in the body of the mesage.
| |
| | |
| =============================================================================
| |
| | |
| NOTICE: Permission is granted to re-distribute this "net-magazine", in
| |
| whole, freely for non-profit use. However, please contact individual
| |
| authors for permission to publish or re-distribute articles
| |
| seperately. A charge of no greater than 5 US dollars or equivlent may
| |
| be charged for library service / diskette costs for this
| |
| "net-magazine".
| |
| | |
| =============================================================================
| |
| In This Issue:
| |
| | |
| Commodore Trivia Corner
| |
| | |
| This section of C=Hacking will contain numerous questions that will test
| |
| your knowledge of trivia for the Commodore computers. Each issue they'll
| |
| be answers to the previous issues questions and new questions. How much
| |
| do you know?
| |
| | |
| InterNet Resources for the Commodore 64 / 128 V1.0
| |
| | |
| This article goes into detail about the available resources on the InterNet
| |
| and is meant to introduce people to the wonderful, wacky world of the
| |
| InterNet. It covers what the InterNet is, what capabilities it has and
| |
| how to access those capabilities. In addition, it also includes Howard
| |
| Herman's latest list of File Transfer sites for the Commodore computers.
| |
| | |
| Hiding kilobytes
| |
| | |
| Most Commodore 64 programs do not utilize even nearly all of the 64 kB
| |
| random access memory space. By default, there are only 44 kilobytes of
| |
| accessible RAM. This article describes how you can take the hiding 20
| |
| kilobytes to use.
| |
| | |
| FLD - Scrolling the Screen
| |
| | |
| This article, using a technique described by Pasi Ojala in the last
| |
| issue of C=Hacking, gives an example of a program using Flexible Line
| |
| Distance technique.
| |
| | |
| Tech-tech - more resolution to vertical shift
| |
| | |
| At one time half of the demos had pictures waving horizontally on the width
| |
| of the whole screen. This effect is named tech-tech and it is done using
| |
| character graphics. How exactly and is the same possible with sprites ?
| |
| | |
| ACE-128/64 PROGRAMMER'S REFERENCE GUIDE (version 0.9, for Release #10)
| |
| | |
| This article explains the complete system interface for the ACE-128/64
| |
| computing environment. It is intended to be used by programmers for
| |
| developing software to run on top of the ACE kernel. ACE is a program
| |
| for the Commodore 128 and Commodore 64 that provides a command shell
| |
| environment that is similar to that of Unix.
| |
| | |
| ===============================================================================
| |
| Commodore Trivia Corner
| |
| by Jim Brain (brain@mail.msen.com)
| |
| | |
| Everyone who reads this article has had, or presently owns a Commodore
| |
| computer of some kind. I own more than one, which is not uncommon among
| |
| Commodore enthusiasts. Well, I bought my first Commodore computer in
| |
| 1982, a brand new Vic-20 with some game cartridges. I had wanted an
| |
| Atari, but father knew best and he told the then 11 year old son that
| |
| computers would shape my life more than any game machine. Well, it is
| |
| 11 years later and a Computer Engineering Degree earned, and I have
| |
| spent many a night during that time playing on many models of Commdore
| |
| equipment. Now, I would like to share the knowledge I have with you in
| |
| an interesting way.
| |
| | |
| As you now know a little about me, let us see how much you know about
| |
| the machines and company that binds us all together. The following is
| |
| an installment of Commodore Trivia. These questions have been gleaned
| |
| from books, magazines, persoanl knowledge, work on the machines in
| |
| questions, and other fellow commodore users happy to share interesting
| |
| bits of semi- useless knowledge concerning the CBM systems.
| |
| | |
| This installment consists of two parts, the December 1993 edition
| |
| complete with answers and the January 1994 edition without answers.
| |
| Each new issue of Commodore Hacking Magazine will contain more
| |
| questions, as well as answers to the previous issue's questions. Each
| |
| new edition is also posted every month on the 12th of the month on the
| |
| Usenet newsgroup comp.sys.cbm. Winners will be announced on the
| |
| newsgroup, and prizes may be awarded. For anyone wishing to submit
| |
| answers from this article, please email your responses with question
| |
| numbers preceeding each answer to :
| |
| | |
| brain@msen.com
| |
|
| |
| The answers to this edition will be posted on the 12th of February in
| |
| comp.sys.cbm with the next edition of questions. Have fun trying to
| |
| answer the questions and feel free to send me a note with new questions.
| |
| I can always use them.
| |
| | |
| [Ed's Note: In addition, the mailserver that I have setup for
| |
| C=Hacking will make provisions to allow individuals to retrieve the
| |
| newest set of questions and last month's answers. Currently not
| |
| implemented, it should be available soon. Details in the next issue.
| |
| | |
| Also due to C= Hacking being published fairly irregularly and not
| |
| every month the column here will contain answers to the last issue of
| |
| C=Hacking's questions and have new questions for the month that it's
| |
| released in.]
| |
| | |
| -----------------------------------------------------------------------------
| |
| Here are the answers to the 10 questions in Commdore Triva Edition #1 for
| |
| December 1993. [that were posted on comp.sys.cbm]
| |
| | |
| Q $000) Commodore started out into computing with the PET series of
| |
| computers. I am not sure if the first ones had PET emblem, but
| |
| nonetheless, What does P E T stand for?
| |
| | |
| A $000) Personal Electronic Transactor
| |
| Since the acronym was made up before the expansion, the following
| |
| are also valid:
| |
|
| |
| Personal Electronic Translator
| |
| Peddle's Ego Trip
| |
|
| |
| Q $001) Commodore planned to manufacture a successor series to the
| |
| successful Commodore 64 home computer. Both were intended to
| |
| be Business machines. We all know this resulted in the Commodore
| |
| Plus 4, but what were the machines originally called and what was
| |
| the difference between the two?
| |
| | |
| A $001) the 364, which had, among other things, a larger Plus 4 style case
| |
| that housed the regular keyboard plus a numeric keypad. the 264
| |
| turned into the Plus 4, with 64K of RAm. We will never know much
| |
| more about the 364, since it got scrapped.
| |
|
| |
| Q $002) How much free memory does a Vic-20 have (unexpanded)?
| |
|
| |
| A $002) Oooh! There are many answers for this.
| |
| The VIC has 3583 bytes of RAM for BASIC
| |
| The VIC has 4096 bytes of RAM for ML
| |
| The VIC has 5120 bytes of RAM. 4K of RAM + 1K for Video.
| |
|
| |
| Q $003) What early 80's Commodore software company had a Light Bulb
| |
| as a company logo?
| |
| | |
| A $003) Skyles Electric Works.
| |
|
| |
| The Vic-20 came out with a few peripherals I want the model
| |
| numbers for the :
| |
| | |
| Q $004) Disk Drive
| |
|
| |
| A $004) VIC-1540 - Same as 1541, only faster serial spped.
| |
|
| |
| Q $005) Cassette Player
| |
|
| |
| A $005) VIC-1530
| |
|
| |
| Q $006) Printer
| |
|
| |
| A $006) VIC 1515, which, by a miscommunication, could only use 7.5" paper.
| |
| Evidently, someone thought 8.5" meant full width of paper w/ perfs!
| |
| This printer was quickly supplanted and overtaken by the 1525, which
| |
| should own this title in the first place!
| |
| | |
| Q $007) 16 K Ram Expansion.
| |
|
| |
| A $007) VIC-1111
| |
|
| |
| Q $008) Commodore Introduced 3 printers that used the same printer mechanism.
| |
| What are the model numbers.
| |
| | |
| A $008) MPS 802 (Square Dots, Serial), CBM 1526 (Round Dots, Serial),
| |
| PET 4023 (Round Dots, IEEE-488).
| |
| | |
| Q $009) What is the diferences between the printers in #9
| |
|
| |
| A $009) MPS 802 (Square Dots, Serial), CBM 1526 (Round Dots, Serial),
| |
| PET 4023 (Round Dots, IEEE-488).
| |
|
| |
| -----------------------------------------------------------------------------
| |
| Here are the questions for Commodore Trivia Edition #2 for January 1994.
| |
| | |
| Q $00A) What was the Code-Name of the Amiga while in Development?
| |
| | |
| Q $00B) What is Lord British's Real Name (The creator of the Ultima
| |
| Series)?
| |
|
| |
| Q $00C) What is the POKE location and value that will fry an early model
| |
| PET?
| |
|
| |
| Q $00D) On the Plus 4 and C-16, the VIC chip was replaced with the TED
| |
| chip. What does TED stand for?
| |
|
| |
| Q $00E) Commodore Produced a Letter Quality Printer in North America
| |
| (maybe elsewhere) for the Commdore Serial Line. Name it.
| |
| | |
| Q $00F) What is the version of DOS in the 1541?
| |
| | |
| Q $010) What is the Version of BASIC in the Plus 4 and the C-16?
| |
| | |
| Q $011) What are the nicknames of the original three custom Amiga chips?
| |
| | |
| Q $012) Commodore produced a 64 in a PET case. What is its name and model
| |
| number?
| |
|
| |
| Q $013) Commodore sold a 1 megabyte floppy disk drive in a 1541 case.
| |
| Give the model number.
| |
|
| |
| Q $014) What does GCR stand for?
| |
| | |
| Q $015) Commdore produced a drive to accompany the Plus 4 introduction.
| |
| Give the model number.
| |
|
| |
| Q $016) What does SID stand for?
| |
| | |
| Q $017) What does the acronym KERNAL stand for?
| |
| | |
| Q $018) What version of DOS does the 1571 have?
| |
| | |
| Q $019) What other two Commdore Disk Drives share the same DOS version
| |
| number as the 1571?
| |
| | |
| Q $01A) How many files will the 1571 hold?
| |
|
| |
| Q $10B) How many files will the 1541 hold?
| |
|
| |
| Q $01C) What did Commodore make right before entering the computer market?
| |
|
| |
| Q $01D) Commodore introduced an ill-fated 4 color plotter. Give the model
| |
| number.
| |
|
| |
| Q $01E) Some formats of CP/M write disks using the MFM format. What does
| |
| MFM stand for?
| |
|
| |
| Q $01F) On the Commodore 128, the user manual left two commands undocumented.
| |
| One works, and the other gives a not-implemented error. Name both
| |
| commands and what each one does or does not do.
| |
| | |
| Some are easy, some are hard, try your hand at it.
| |
| | |
| Jim Brain
| |
| brain@msen.com
| |
| =============================================================================
| |
| InterNet Resources for the Commodore 64 / 128 V1.0
| |
| by Craig Taylor (duck@pembvax1.pembroke.edu)
| |
| | |
| [This article is placed into public domain by the author. Copying encouraged]
| |
| | |
| The Internet
| |
| | |
| Let me start this article with a quote by another author that everyone
| |
| should heed when dealing with the InterNet:
| |
| | |
| "One warning is perhaps in order---this territory we are entering can
| |
| become a fantastic time-sink. Hours can slip by, people can come and
| |
| go, and you'll be locked into Cyberspace. Remember to do your work!
| |
|
| |
| With that, I welcome you, the new user, to The Net."
| |
|
| |
| brendan@cs.widener.edu
| |
| - Author, Zen and the Art of the Internet
| |
| | |
| What is the InterNet?
| |
| | |
| What exactly is the InterNet? Imagine if you will, when you were a kid
| |
| stringing wires between houses in your neighborhood so that you could
| |
| talk with the kids that lived beside you. You could talk to those beside
| |
| you but not the ones that lived across town. Now, suppose that you
| |
| wanted to relay a message to a buddy across town. The only feasible way
| |
| would be to send a message to the guy next door; then have him send it
| |
| to the correct person.
| |
| | |
| This is the basic system of the Internet. Computers connected to other
| |
| computers that are connected to others. In the above paragrph
| |
| communication was limited because of geography - how close individuals
| |
| were. The InterNet system; while geography does play a factor, relies
| |
| more on how the sites grew up and were established as to how messages
| |
| will get passed back and forth.
| |
| | |
| There are also other networks hooked up to the InterNet that provide
| |
| auxilary services to their local group of computers. One large one is
| |
| BITNET and UUCP. Various bbs's also carry items from the InterNet such
| |
| as the BitNet news. In addition, online services such as Genie,
| |
| Compuserve, and others offer "gate-ways" or ways of getting access to
| |
| the resources of the InterNet.
| |
| | |
| Access To The InterNet
| |
| | |
| Gaining Access to the InterNet There are several ways of gaining access
| |
| to the InterNet. Your local college may be your best low-cost
| |
| opportunity. Typically, if you are a student or faculty or staff, you
| |
| may qualify to have an account that allows you to access all the
| |
| InterNet facilities described above. If you don't fall into any of these
| |
| categories your next best bet is an online service such as America
| |
| Online, Genie, or Compuserve as these all support what is known as an
| |
| InterNet gateway - allowing you t o access the InterNet through t hem.
| |
| (At this time, I don't believe Prodigy has an InterNet gateway - if I'm
| |
| wrong I'm sure I'll get tons of mail. Other online services also exist -
| |
| I've only listed what I consider the "primary" ones.)
| |
| | |
| Once you've gotten access to the InterNet you may be asking "Okay, I
| |
| know what the InterNet _can_ give me - how do I do it?" Unfortunately,
| |
| because the InterNet is run on differant computer systems this will vary
| |
| from system to system. Your best bet would be to examine the
| |
| documentation and help screens associated with the online service or
| |
| college's facilities. Study them over until you can quote them backwards
| |
| (well, not quite that much) - Study them over until you understand what
| |
| they are saying. Also, having someone who is already experienced with
| |
| the InterNet aid you in your explorations is a great help.
| |
| | |
| What is E-MAIL?
| |
| | |
| There are numerous individuals using the InterNet each day. Each is also
| |
| able to write the other through the use of Electronic Mail or, as it's
| |
| commonly called "e-mail".
| |
| | |
| To send a message to me you'd use your mail program (the actual
| |
| procedure varies depending on what type of machine you use) and tell it
| |
| to send the message to my user name, "duck" at my site that I login at -
| |
| (currently going to Pembroke State University) hence
| |
| "pembvax1.pembroke.edu". So the full address with an "@" sign the
| |
| computer needs to use to know how to seperate the computer name and the
| |
| user name is "duck@pembvax1.pembroke.edu".
| |
| | |
| It's easy to talk to somebody in Mexico, Germany, Australia with this
| |
| method and it's quicker than the U.S. Postal system (which, on the
| |
| InterNet you'll see referred to as Snail Mail (or s-mail) due to it's
| |
| slow delivery time compared to e-mail). Projects, Questions, Answers,
| |
| Ideas and general chit-chat on how the family is doing, etc can be
| |
| relayed over the InterNet.
| |
| | |
| There are also numerous abbreviations and notations that are used in
| |
| E-Mail. Some of them are:
| |
| | |
| ttyal8r - Talk to you later
| |
| rtfm - Read the *uckin' manual
| |
| imho - In My Humble Opinion
| |
| rotfl - Rolls on the Floor Laughing
| |
| lol - Laughs Out Loud.
| |
| l8r - Later
| |
| ;-) - (winks)
| |
| :-) - (smile)
| |
| :-( - (frowns)
| |
| | |
| There are _many_ _many_ more - you can also find a huge list of the
| |
| smiley faces (turn your head sideways and look at the ones in
| |
| parenthesis above) on the InterNet.
| |
| | |
| You may also hear the phrase "my e-mail bounced". What this means is
| |
| that your message, much like a bounced check, did not work right and it
| |
| was returned to your account. Typically this happens because of
| |
| incorrect addresses, or an incorrect user name.
| |
| | |
| Email Servers
| |
| | |
| Another large way of getting information is from individuals running
| |
| what are E-Mail servers from their accounts or from specific accounts.
| |
| From Email servers you may request certain files; catalogs of programs
| |
| that are availble for request; send messages to be distributed to other
| |
| individuals and automatically subscribe yourself to the mailing list for
| |
| new items.
| |
| | |
| The only Email Server specifically designed for the Commodore computers
| |
| is one ran by the author. It major intent is that of distributing the
| |
| Commodore Hacking magazine as well as programs that are in the
| |
| magazine. To get help on how to use it send a message to the author in
| |
| the following format:
| |
| To: duck@pembvax1.pembroke.edu
| |
| Subj: MAILSERV
| |
| Body of message: HELP
| |
| | |
| This specific mailserver is ran twice a day so you should get your reply
| |
| within approximately 12 hours. Please be sure to have a subject line of
| |
| "MAILSERV".
| |
| | |
| If anyone knows of any other Email Servers existing for the Commodore
| |
| computers please let the author know.
| |
| | |
| NewsGroups
| |
| | |
| One of the primary purposes of the InterNet is for educational research
| |
| and discussion. For this purpose, there are currently over 2000
| |
| newsgroups established dealing with a wide range of social, politicial,
| |
| science, computer and educational topics. Some of these range to inane,
| |
| whimsical, to practical and useful.
| |
| | |
| Two of these for the Commodore 64/128 line of computers are:
| |
| comp.sys.cbm
| |
| comp.binaries.cbm
| |
| | |
| The names for the newsgroups start with a short abbreviation such as
| |
| "comp" for computers, "sci" for science, "bio" for biology, etc... The
| |
| second group of letters stand for the type of newsgroup "sys for system,
| |
| binaries for binaries etc..." while the third describes it better -
| |
| "cbm" in this case for Commodore Business Machines.
| |
| | |
| The newsgroup, Comp.Sys.Cbm supports discussion about anything under the
| |
| sun involving the Commodore 8 bit line of computers (and lately, even
| |
| talking about the old old ancient calculators that Commodore mae that
| |
| might not have even been 8 bit). Comp.Binaries.Cbm allows programs to be
| |
| "posted" or made available to everyone who wishes them. There are
| |
| programs available that will let you take the "encrypted" text-only
| |
| version of the program that you see on the screen and convert them into
| |
| the correct binary p rogram.
| |
| | |
| Basically the rules for newsgroups are: 1) Enjoy yourself, 2) Don't
| |
| harass others and 3) Try to stay on topic. Newsgroups are read by many
| |
| many people - typically you'll get a response to an inquiry within only
| |
| an hour or so - sometimes even sooner. But because they're read by so
| |
| many people chatter or "babble" as it's known, is also discouraged.
| |
| Don't hesitate to post any questions, concerns or comments but make sure
| |
| in each message that you post that you have a reason to post.
| |
| | |
| So What's Out There?
| |
| | |
| So why should you be interested in the Internet? Imagine, if you will,
| |
| being able to ask questions to numerous individuals, download the latest
| |
| in shareware and public-domain software, know the "rumours" and topics
| |
| before they exist all for free? (Or at least, only for what your
| |
| "hookup" method charges - see Gaining Access to the InterNet latter).
| |
| That's what's out on the Internet. Any question you have - there is sure
| |
| to be an answer for - any software you're looking for you stand an
| |
| extremely good chance of finding something along the lines of your
| |
| needs.
| |
| | |
| The major benefit of the Internet as I see it consists of the continued
| |
| support for the Commodore computers. Because all these differant means
| |
| of obtaining information are not sponsored by any one specific company
| |
| or individual the Commodore 8-bit line of computers are guranteed
| |
| continued support over the Internet. In addition, because the Internet
| |
| strongly frowns upon Commercial advertising you won't find numerous ads
| |
| or any other material urging you to "buy this, buy that" like you will
| |
| on some other serv ices.
| |
| | |
| FTP Sites
| |
| | |
| FTP stands for File Transfer Protocols and is a method of obtaining
| |
| programs that are stored on another system's computers. There are
| |
| numerous FTP sites out there in InterNet land - one of the best
| |
| currently available for the Commodore computers is that of R.Knop's site
| |
| at ccosun.caltech.edu.
| |
|
| |
|
| [ The following is a list of FTP sites for the Commodore 64 and 128
| |
| computes and is currenty maintained by Howard Herman
| |
| (h.herman@GEnie.geis.com) and is used with his permission. He usually
| |
| posts an updated list to comp.sys.cbm newsgroup every month or so.]
| |
| -----------------------------------------------------------------------------
| |
| This is the list of FTP sites containing software and programs
| |
| specific to the Commodore 64 and 128 computers.
| |
|
| |
| I will try to keep this list as current and accurate as possible, so
| |
| that it can be a useful resource for users of the newsgroup.
| |
|
| |
| PLEASE cooperate and send E-mail to me with any corrections and
| |
| updates. If a site has closed or no longer carries CBM software, let
| |
| me know and it will be deleted. If you uncover a site not listed,
| |
| tell me so that it can be added.
| |
| -----
| |
|
| |
| To use this list on a UNIX system, just type 'ftp <sitename>', where
| |
| <sitename> is any of the sites listed below. Use 'anonymous' as
| |
| your login, and your E-mail address for the password. You can change
| |
| and list directories with 'cd' and 'dir', respectively, and download
| |
| files to your system using 'get'. Be sure to specify either 'binary'
| |
| if you are getting a program, or 'ascii' for a text file before you
| |
| begin the download.
| |
| -----
| |
|
| |
| In addition to the sites listed below there are hundreds of other
| |
| FTP sites on INet with interesting files covering every topic
| |
| imaginable. Take some time to seek out and explore these too.
| |
|
| |
| Enjoy!
| |
| -----
| |
|
| |
| Host sol.cs.ruu.nl (131.211.80.17)
| |
| Last updated 00:39 4 Sep 1993
| |
| Location: /pub/MIDI/PROGRAMS
| |
| DIRECTORY rwxr-xr-x 1024 Aug 26 09:58 C64
| |
| Location: /pub/MIDI/DOC
| |
| FILE rw-r--r-- 40183 Jan 19 1993 C64midi-interface.txt
| |
|
| |
| Host uceng.uc.edu (129.137.33.1)
| |
| Last updated 04:38 6 Sep 1993
| |
| Location: /pub/wuarchive/systems/cpm/c128
| |
| FILE rw-r--r-- 24576 Nov 6 1986 c128-mex.com
| |
| Location: /pub/wuarchive/systems/cpm/c64
| |
| FILE rw-r--r-- 1615 Mar 14 1984 c64-cpm.msg
| |
| FILE rw-r--r-- 1536 Feb 9 1985 c64modem.com
| |
| FILE rw-r--r-- 4199 Feb 10 1984 c64modem.doc
| |
| FILE rw-r--r-- 19200 Feb 9 1985 md730c64.com
| |
| FILE rw-r--r-- 2192 Oct 1 1984 md730c64.doc
| |
| Location: /pub/wuarchive/doc/misc/if-archive/infocom/tools
| |
| FILE r--r--r-- 5798 Aug 5 14:42 c64todat.tar.Z
| |
|
| |
| Host aix370.rrz.uni-koeln.de (134.95.80.1)
| |
| Location: /.disk2/usenet/comp.archives/auto/comp.sys.cbm
| |
| DIRECTORY rwxrwxr-x 384 comp.sys.cbm
| |
|
| |
| Host ftp.csv.warwick.ac.uk (137.205.192.5)
| |
| Last updated 00:00 18 Jan 1994
| |
| Location: /pub/c64
| |
| FILE rw-r--r-- 909 Jan 8 19:52 C64progs.doc
| |
| FILE rw-r--r-- 19558 Jan 8 19:49 backgamm.sfx
| |
| FILE rw-r--r-- 21384 Jan 8 19:49 chequebo.sfx
| |
| FILE rw-r--r-- 11449 Jan 8 19:49 countdow.sfx
| |
| FILE rw-r--r-- 18136 Jan 8 19:49 draughts.sfx
| |
| FILE rw-r--r-- 5011 Jan 8 19:49 loader.sfx
| |
| FILE rw-r--r-- 17423 Jan 8 19:49 whitewas.sfx
| |
| Descriptions:
| |
| ============
| |
| backgamm - Backgammon board game
| |
| chequebo - Cheque Book Organiser, written in basic with UK pound sign as
| |
| currency, but could be changed to suit another.
| |
| countdow - LOAD"count example",8,1 and watch the countdown during loading.
| |
| draughts - Draughts board game.
| |
| loader - Press RESTORE key and MENU on disk will be automatically re-loaded.
| |
| whitewas - Colour squares board game.
| |
| Location: /tmp/c64
| |
| >Temporary files stored here. If /tmp directory not found, try
| |
| >again at another time. /tmp directory not always available.
| |
|
| |
| Host clover.csv.warwick.ac.uk (137.205.192.6)
| |
| Last updated 13:29 27 Sep 1993
| |
| Location: /pub/c64
| |
| FILE rw-r--r-- 812 c64progs.doc
| |
| FILE rw-r--r-- 73696 c64progs.sfx
| |
|
| |
| Host nexus.yorku.ca (130.63.9.66)
| |
| Last updated 00:00 21 Dec 1993
| |
| Location: /pub/Internet-info
| |
| FILE rw-r--r-- 6308 commodore.ftp
| |
| >An older version of this listing.
| |
|
| |
| Host rigel.acs.oakland.edu (141.210.10.117)
| |
| Last updated 01:42 3 Sep 1993
| |
| Location: /pub2/cpm
| |
| DIRECTORY rwxr-xr-x 1536 Jun 4 1992 c128
| |
| DIRECTORY rwxr-xr-x 512 c64
| |
| Location: /pub2/cpm/c64
| |
| FILE rw-r--r-- 1615 Mar 14 1984 c64-cpm.msg
| |
| FILE rw-r--r-- 1536 Feb 9 1985 c64modem.com
| |
| FILE rw-r--r-- 4199 Feb 10 1984 c64modem.doc
| |
| FILE rw-r--r-- 19200 Feb 9 1985 md730c64.com
| |
| FILE rw-r--r-- 2192 Oct 2 1984 md730c64.doc
| |
|
| |
| Host oak.oakland.edu
| |
| Last updated 00:00 18 Dec 1993
| |
| Location: /pub2/cpm
| |
| >For CP/M software, most all of which will run on the C128.
| |
|
| |
| Host src.doc.ic.ac.uk (146.169.2.1)
| |
| Location: /usenet/comp.archives/auto
| |
| DIRECTORY rwxr-xr-x 512 comp.sys.cbm
| |
| Location: /usenet/comp.archives
| |
| DIRECTORY rwxr-xr-x 512 commodore-64-128
| |
| DIRECTORY rwxr-xr-x 512 May 3 1991 c64
| |
| Location: /media/visual/collections/funet-pics/jpeg/games
| |
| DIRECTORY rwxr-xr-x 512 Mar 20 05:48 c64
| |
| Location: /media/visual/collections/funet-pics/jpeg/comp/games
| |
| DIRECTORY rwxr-xr-x 512 May 6 03:55 c64
| |
|
| |
| Host tupac-amaru.informatik.rwth-aachen.de (137.226.112.31)
| |
| Last updated 04:59 7 Oct 1992
| |
| Location: /pub/rz.archiv/simtel/cpm
| |
| DIRECTORY rwxr-xr-x 512 c64
| |
| DIRECTORY rwxr-xr-x 512 Sep 21 20:56 c128
| |
|
| |
| Host wuarchive.wustl.edu (128.252.135.4)
| |
| Last updated 02:40 23 May 1993
| |
| Location: /systems/amiga/incoming/misc
| |
| FILE rw-rw-r-- 21815 Jan 23 14:26 C64View.lha
| |
| FILE rw-rw-r-- 120 Jan 23 14:26 C64View.readme
| |
| Location: /mirrors/cpm
| |
| DIRECTORY rwxr-xr-x 512 c64
| |
| DIRECTORY rwxr-xr-x 1536 Nov 22 1992 c128
| |
|
| |
| Host watsun.cc.columbia.edu (128.59.39.2)
| |
| Last updated 02:07 8 Sep 1993
| |
| Location: /kermit2/old
| |
| DIRECTORY rwxrwxr-x 1024 Jul 12 18:30 c64
| |
| Location: /kermit/bin
| |
|
| |
| Host cs.columbia.edu (128.59.1.2)
| |
| Last updated 01:29 12 Sep 1993
| |
| Location: /archives/mirror1/kermit
| |
| FILE rw-rw-r-- 15016 Aug 24 1988 c644th.prg.gz
| |
| FILE rw-rw-r-- 733 Sep 29 1992 c64help.txt.gz
| |
| FILE rw-rw-r-- 6095 Sep 29 1992 c64ker1660.sda.gz
| |
| FILE rw-rw-r-- 5904 Sep 29 1992 c64kerfast.sda.gz
| |
| FILE rw-rw-r-- 26484 Sep 29 1992 c64kerv22a.sda.gz
| |
| FILE rw-rw-r-- 42552 Sep 29 1992 c64kerv22b.sda.gz
| |
| FILE rw-rw-r-- 31982 Sep 29 1992 c64slkv22s.sda.gz
| |
|
| |
| Host plaza.aarnet.edu.au (139.130.4.6)
| |
| Last updated 00:00 28 Dec 1993
| |
| Location: /pub/kermit/c
| |
| FILE r--r--r-- 3073 Aug 16 1988 c64boot.bas
| |
| FILE r--r--r-- 1547 Aug 16 1988 c64boot.c
| |
| FILE r--r--r-- 1151 Aug 16 1988 c64boot.clu
| |
| FILE r--r--r-- 3002 Aug 16 1988 c64boot.for
| |
| FILE r--r--r-- 3315 Aug 16 1988 c64boot.sim
| |
| >There are more Kermit files which are not listed. Be sure to
| |
| >get the complete set of C64/128 Kermit files.
| |
|
| |
| Host flubber.cs.umd.edu (128.8.128.99)
| |
| Last updated 00:00 03 Jan 1994
| |
| Location: /rec/newballistic
| |
| FILE rw-r--r-- 8576 Mar 23 21:21 balistic.c64
| |
| --------------------------------
| |
|
| |
| Host f.ms.uky.edu (128.163.128.6)
| |
| Last updated 00:00 28 Dec 1993
| |
| Location: /archive/c64.zip
| |
|
| |
| Host ftp.funet.fi (128.214.6.100)
| |
| Last updated 06:11 22 Mar 1993
| |
| Location: /pub/pics/jpeg/games
| |
| DIRECTORY rwxrwxr-x 512 Mar 20 02:07 c64
| |
| Location: /pub/misc
| |
| DIRECTORY rwxrwxr-x 512 Mar 13 23:30 c64
| |
| Location: /pub/kermit
| |
| DIRECTORY rwxrwxr-x 1024 Jan 13 1992 c64
| |
| Location: /pub/amiga/audio/misc/sid-tunes
| |
| FILE rw-rw-r-- 671490 Jun 18 1992 C64MusicShow-1.lha
| |
| FILE rw-rw-r-- 316521 Jun 18 1992 C64MusicShow-2.lha
| |
| /pub/cbm
| |
|
| |
| Host nic.switch.ch (130.59.1.40)
| |
| Last updated 00:39 31 Aug 1993
| |
| Location: /mirror/kermit/bin
| |
|
| |
| Host gmdzi.gmd.de (129.26.8.90)
| |
| Last updated 01:08 1 Aug 1993
| |
| Location: /if-archive/infocom/tools
| |
| FILE rw-rw-r-- 5668 Apr 27 15:00 c64.to.dat
| |
|
| |
| Host micros.hensa.ac.uk (148.88.8.84)
| |
| Location /kermit
| |
| DIRECTORY rwxr-x--- 1024 Nov 11 09:20 c64
| |
|
| |
| Host wilbur.stanford.edu (36.14.0.36)
| |
| Location /pub/emulators
| |
| DIRECTORY rwxr-xr-x 512 Jun 30 00:57 c64
| |
|
| |
| Host syrinx.umd.edu (128.8.2.114)
| |
| Last updated 00:00 28 Dec 1993
| |
| Location: /rush/c64-sounds
| |
|
| |
| Host tolsun.oulu.fi (130.231.96.16)
| |
| Last updated 01:53 6 Sep 1993
| |
| Location: /pub
| |
| DIRECTORY rwxr-xr-x 1024 Jul 15 1990 c64
| |
| Location: /incoming
| |
| DIRECTORY --------- 1024 Jun 20 1992 c64
| |
| /pub/amiga/4/c64trans.zoo
| |
| /pub/c64
| |
| >Uploading to /pub/c64 is disabled because of lack of disk space.
| |
| >However, for downloading it is still fully accessible.
| |
| >Currently there is no administration for /pub/c64.
| |
| >/pub/amiga is active, though.
| |
|
| |
| Host ccosun.caltech.edu (131.215.139.2)
| |
| Last updated 00:00 31 JAN 1994
| |
| Location: /pub/rknop
| |
| Location: /pub/rknop/misc
| |
| > 64/128 programs can be found within directories according to
| |
| > function. When searching, be sure to check related directories.
| |
|
| |
| Host ucsd.edu (128.54.16.1)
| |
| Last updated 04:46 6 Sep 1993
| |
| Location: /midi/software
| |
| DIRECTORY rwxr-xr-x 512 Jan 27 1992 c64
| |
|
| |
| Host cs.dal.ca (129.173.4.5)
| |
| Last updated 01:36 12 Sep 1993
| |
| Location: /comp.archives
| |
| DIRECTORY rwxrwxr-x 3584 Apr 7 04:05 c64
| |
| pub/comp.archives/comp.sys.cbm
| |
|
| |
| Host ccnga.uwaterloo.ca
| |
| Last updated 00:00 01 Jan 1994
| |
| Location: /pub/cbm/vbm110.uua
| |
| > For VBM Bitmap Viewer version 1.10
| |
|
| |
| Host bert.psyc.upei.ca
| |
| Last updated 00:00 31 Jan 1994
| |
| Location: /pub
| |
| > All the releases of the major demo parties of '93
| |
|
| |
| --------------------------------
| |
| Send all info regarding changes/additions/corrections [to the FTP list] to:
| |
|
| |
| 72560.3467@CompuServe.COM or: h.herman1@GEnie.geis.COM
| |
| =============================================================================
| |
| Hiding kilobytes | | Hiding kilobytes |
| by Marko M"akel"a <Marko.Makela@Helsinki.FI> | | by Marko M"akel"a <Marko.Makela@Helsinki.FI> |
Line 1,625: |
Line 855: |
|
| |
|
| ============================================================================= | | ============================================================================= |
| FLD - Scrolling the screen
| |
| by Marek Klampar (klampar@elf.stuba.sk)
| |
|
| |
|
| |
| Scrolling the screen
| |
| --------------------
| |
| [inspirated by Pasi Ojala article 'Opening the borders' from issue#6]
| |
|
| |
| From Pasi 'Albert' Ojala's (po87553@cs.tut.fi or albert@cc.tut.fi) article:
| |
|
| |
| _Scrolling the screen_
| |
|
| |
| VIC begins to draw the screen from the first bad line. VIC will know
| |
| what line is a bad line by comparing its scan line counter to the
| |
| vertical scroll register : when they match, the next line is a bad
| |
| line. If we change the vertical scroll register ($d011), the first bad
| |
| line will move also. If we do this on every line, the line counter in
| |
| VIC will never match with it and the drawing never starts (until it is
| |
| allowed to do so).
| |
|
| |
| When we don't have to worry about bad lines, we have enough time to
| |
| open the borders and do some other effects too. It is not necassary to
| |
| change the vertical scroll on every line to get rid of the bad lines,
| |
| just make sure that it never matches the line counter (or actually the
| |
| least significant 3 bits).
| |
|
| |
| You can even scroll the bad lines independently and you have FLD -
| |
| Flexible Line Distance. You just allow a bad line when it is time to
| |
| display the next character row. With this you can bounce the lines or
| |
| scroll a hires picture very fast down the screen.
| |
|
| |
| (*** end of Albert's paragraph ***)
| |
|
| |
| Well, everything important was written. I'm just adding this:
| |
|
| |
| For moving hires picture replace ORA #$10 by ORA #$30.
| |
|
| |
| For another FX try to replace part of irq routine begining with ORA #$10 by:
| |
| ORA #$C0
| |
| STA $D016,
| |
| remove JSR CHOFS,
| |
| replace LDX OFSET
| |
| by LDX #$ff
| |
| and enjoy =)
| |
|
| |
|
| |
| The demonstartion program for FLD application
| |
| ;---------------------------------------
| |
| ; Commodore Cracker 1993
| |
| ;---------------------------------------
| |
| FROM = $32
| |
| TO = $FA
| |
| ;---------------------------------------
| |
| *= $C000
| |
| ;---------------------------------------
| |
| INIT LDA #0
| |
| STA DIR ; Direction
| |
| LDA #$FF ; Set garbage
| |
| STA $3FFF
| |
| LDA #FROM
| |
| STA OFSET ; Set ofset
| |
| SEI ; Disable interrupt
| |
| LDA #$7F ; Disable timer interrupt
| |
| STA $DC0D
| |
| LDA #1 ; Enable raster interrupt
| |
| STA $D01A
| |
| LDA #<IRQ ; Set irq vector
| |
| STA $0314
| |
| LDA #>IRQ
| |
| STA $0315
| |
| LDA #0 ; To evoke our irq routine on 0th line
| |
| STA $D012
| |
| CLI ; Enable interrupt
| |
| RTS
| |
| ;---------------------------------------
| |
| IRQ LDX OFSET
| |
| L2 LDY $D012 ; Moving 1st bad line
| |
| L1 CPY $D012
| |
| BEQ L1 ; Wait for begin of next line
| |
| DEY ; IY - bad line
| |
| TYA
| |
| AND #$07 ; Clear higher 5 bits
| |
| ORA #$10 ; Set text mode
| |
| STA $D011
| |
| DEX
| |
| BNE L2
| |
| INC $D019 ; Acknowledge the raster interrupt
| |
| JSR CHOFS
| |
| JMP $EA31 ; Do standard irq routine
| |
| ;---------------------------------------
| |
| OFSET .BYTE FROM
| |
| DIR .BYTE 0
| |
| ;---------------------------------------
| |
| CHOFS LDA DIR ; Change OFSET of screen
| |
| BNE UP
| |
| INC OFSET ; Down
| |
| LDA OFSET
| |
| CMP #TO
| |
| BNE SKIP
| |
| STA DIR
| |
| SKIP RTS
| |
| ;---------------------------------------
| |
| UP DEC OFSET ; Up
| |
| LDA OFSET
| |
| CMP #FROM
| |
| BNE SKIP
| |
| LDA #0
| |
| STA DIR
| |
| RTS
| |
|
| |
| =============================================================================
| |
| Tech-tech - more resolution to vertical shift.
| |
| by Pasi 'Albert' Ojala (po87553@cs.tut.fi _or_ albert@cc.tut.fi)
| |
| Written on 16-May-91 Translation 02-Jun-92
| |
|
| |
| (All timings are in PAL, principles will apply to NTSC too)
| |
|
| |
| One time half of the demos had pictures waving horizontally on the
| |
| width of the whole screen. This effect is named tech-tech, and the
| |
| audience was puzzled. You can move the screen only eight pixels using
| |
| the horizontal scroll register. This effect was done using character
| |
| graphics. How exactly and is the same possible with sprites ?
| |
|
| |
|
| |
| Horizontal scroll register can move the screen by eight pixels. This
| |
| isn't even nearly enough to produce a really stunning effect. You have
| |
| to move the graphics itself, fortunately with a resolution of one
| |
| character position (one byte) only, the rest can be done with the scroll
| |
| register. During one scan line there is no time to move the actual data,
| |
| you can only move a pointer. Changing the video matrix pointer won't
| |
| help, because VIC (video interface controller) will fetch the character
| |
| codes only at certain times, called bad lines. You can change the
| |
| character set pointer instead, because VIC reads the data it displays
| |
| directly from the character set memory.
| |
|
| |
|
| |
| Character set-implementation has its restrictions
| |
|
| |
| Because horizontal movement is done by changing the character sets, the
| |
| picture or text must be pure graphic and the character codes in the
| |
| video matrix must be in a numerical order. The normal picture is in the
| |
| first character memory and in the next one it is shifted one character
| |
| position to the right. One video bank can hold only seven full character
| |
| memories besides the video matrix. This limits the movement of the
| |
| picture to 56 pixels. It is possible to get more movement if you use
| |
| smaller picture or another video bank.
| |
|
| |
| The shift is done so that on each scan line we update the horizontal
| |
| scroll register ($D016) with the three lowest bits of the shift value.
| |
| We use the other bits to select the right character set ($D018). In a
| |
| tech-tech the shift value changes during the display of the whole
| |
| picture, and the values are stored in a table. In addition to that, the
| |
| shift values should be put into two tables, one for the horizontal
| |
| scroll register and another for the character set select. This is
| |
| necessary, because there is no time for extra calculations on a bad
| |
| line.
| |
|
| |
| Because we have to change the character set and x-scroll dynamically, we
| |
| also need a raster routine to show a tech-tech. A raster routine is a
| |
| routine which is synchronized to the electron beam. This eats up the
| |
| processor time: the bigger the picture, the less time is left over for
| |
| other activities. On other than bad lines you can do other funny things,
| |
| like change the color of the background or border.
| |
|
| |
|
| |
| An example program
| |
|
| |
| The demo program uses video bank 2, memory addesses $4000-7fff. The
| |
| video matrix is in the beginning of the bank. Only inverted chars are
| |
| used for the graphics, this way we have all eight character memories
| |
| available and the maximum shift is 64 pixels. The area for the tech-tech
| |
| in the video matrix is eight character rows high, but it has identical
| |
| graphics on every line. This is why we use only 320 bytes from each
| |
| character set.
| |
|
| |
| You can use a joystick to control the movement of the tech-tech. The
| |
| stick decreases or increases the shift add value in a resolution of a
| |
| half pixel. When the shift reaches its highest/lowest value, the
| |
| direction of the add is reversed. Just experiment with it.
| |
|
| |
|
| |
| You can do it on the screen, how about borders ?
| |
|
| |
| Because you cannot get characters to the border, you might think that it
| |
| is impossible to make a tech-tech effect in the borders. It takes so
| |
| much time to change sprite x-coordinates, that you can change only some
| |
| of them. There is time for five sprite moves, if you do not need to
| |
| change the most significant (9th) bit of the x-coordinate. On the other
| |
| hand, you could design the movements directly to the sprites and then
| |
| just change the images, but then the movements would be constant.
| |
|
| |
| However, there is one trick you can use to get all of the sprites on the
| |
| screen, with variable movements and color bars etc. You do not change
| |
| the x-coordinates, but the data itself on each scan line. In fact you
| |
| change the sprite image pointers. There is multiple sprite pictures,
| |
| where the graphics is shifted horizontally, just like the normal
| |
| tech-tech charsets. Because of this, the sprites have to be placed side
| |
| by side. No gaps are allowed. By changing the image pointers you can get
| |
| the graphics to move horizontally on each line as you wish. With
| |
| multicolor sprites you have to remember that one pixel corresponds to
| |
| two bits - the movement is not so smooth.
| |
|
| |
| Wait ! How come there is enough time to change the sprite pointers, when
| |
| there is not time to change the coordinates ? This is another pointer
| |
| trick. VIC reads the sprite image pointers from the end of the current
| |
| video matrix, normally $07f8. You just have to change the video matrix
| |
| pointer ($D018) to change all of the image pointers. This takes only
| |
| eight cycles and there is plenty of time left for other effects on each
| |
| scan line. If you use only one video bank, you can get the sprite
| |
| picture to 16 different places. This allows also another kind of
| |
| effects, just use your imagination.
| |
|
| |
| --------------------------------------------------------------------------
| |
| Tech-tech demo program (PAL)
| |
|
| |
| BANK= $96 ; The value of the video bank register (CIA2) in the tech-area
| |
| ZP= $FB ; Zero page for indirect addressing
| |
| START= $4400 ; Start of the charsets (we use inverted chars)
| |
| SCREEN= $4000 ; Position of the video matrix
| |
| SHIFTL= $CF00 ; x-shift, lowest 3 bits
| |
| SHIFTH= $CE00 ; x-shift, highest 3 bittid (multiplied with two)
| |
| POINTER= $033C ; Pointer to shift-table
| |
| VALUE= $033D ; Shift now
| |
| SPEED= $033E ; Shift change
| |
|
| |
| *= $C000 ; Start address..
| |
|
| |
| INIT SEI ; Disable interrupts
| |
| LDA #$7F
| |
| STA $DC0D ; Disable timer interrupt
| |
| LDA #$81
| |
| STA $D01A ; Enable raster interrupt
| |
| LDA #<IRQ
| |
| STA $0314 ; Our own interrupt handler
| |
| LDA #>IRQ
| |
| STA $0315
| |
| LDA #49 ; The interrupt to the line before the first bad line
| |
| STA $D012
| |
| LDA #$1B
| |
| STA $D011 ; 9th bit of the raster compare
| |
|
| |
| LDY #0
| |
| LDX #$40
| |
| STX ZP+1
| |
| STY ZP
| |
| TYA
| |
| LOOP0 STA (ZP),Y ; Clear the whole video bank ($4000-7FFF)
| |
| INY
| |
| BNE LOOP0
| |
| INC ZP+1
| |
| BPL LOOP0
| |
|
| |
| LDA #>START
| |
| STA ZP+1
| |
| LDA #$32 ; Character ROM to address space ($D000-)
| |
| STA $01
| |
| LOOP1 TYA ; (Y-register is zero initially)
| |
| LSR
| |
| LSR
| |
| LSR
| |
| TAX
| |
| LDA TEXT,X ; Which char to plot ?
| |
| ASL ; Source
| |
| ASL
| |
| ASL
| |
| TAX ; low byte to X
| |
| LDA #$D0
| |
| ADC #0 ; high byte (one bit) taken into account
| |
| STA LOOP2+2 ; Self-modifying again..
| |
| LOOP2 LDA $D000,X
| |
| STA (ZP),Y
| |
| INX
| |
| INY
| |
| TXA
| |
| AND #7
| |
| BNE LOOP2 ; Copy one char
| |
| CPY #0
| |
| BNE LOOP1 ; Copy 32 chars (256 bytes)
| |
| LDA #$37 ; Memory configuration back to normal
| |
| STA $01
| |
|
| |
| LOOP3 LDA START,Y ; Copy the data to each charset, shifted by one
| |
| STA START+2056,Y ; position to the right
| |
| STA START+4112,Y
| |
| STA START+6168,Y
| |
| STA START+8224,Y
| |
| STA START+10280,Y
| |
| STA START+12336,Y
| |
| STA START+14392,Y
| |
| INY
| |
| BNE LOOP3
| |
| LDA #0 ; Clear the pointer, value and speed
| |
| STA POINTER
| |
| STA VALUE
| |
| STA SPEED
| |
|
| |
| LOOP4 TYA ; (Y was zero)
| |
| ORA #$80 ; Use the inverted chars
| |
| STA SCREEN,Y ; Set the character codes to video matrix
| |
| STA SCREEN+40,Y
| |
| STA SCREEN+80,Y
| |
| STA SCREEN+120,Y
| |
| STA SCREEN+160,Y
| |
| STA SCREEN+200,Y
| |
| STA SCREEN+240,Y
| |
| STA SCREEN+280,Y
| |
| LDA #239 ; leave the last line empty
| |
| STA SCREEN+320,Y
| |
| INY
| |
| CPY #40
| |
| BNE LOOP4 ; Loop until the whole area is filled
| |
| CLI ; Enable interrupts
| |
| RTS
| |
|
| |
| IRQ LDA #BANK ; Change the video bank, some timing
| |
| STA $DD00
| |
| NOP
| |
| NOP
| |
|
| |
| LDY POINTER ; Y-register will point to x-shift
| |
| JMP BAD ; next line is a bad line
| |
| LOOP5 NOP
| |
| LOOP6 LDA SHIFTL,Y ; Do the shift
| |
| STA $D016 ; 3 lowest bits
| |
| LDA SHIFTH,Y
| |
| STA $D018 ; another 3 bits
| |
| NOP : NOP : NOP : NOP : NOP : NOP ; waste some time
| |
| NOP : NOP : NOP : NOP : NOP : NOP
| |
| NOP : NOP : NOP
| |
| LDA $D012 ; check if it is time to stop
| |
| CMP #$78
| |
| BPL OVER
| |
| INY ; next position in table
| |
| DEX
| |
| BNE LOOP5 ; No bad line, loop
| |
| BAD LDA SHIFTL,Y ; This is a bad line, a bit more hurry
| |
| STA $D016
| |
| LDA SHIFTH,Y
| |
| STA $D018
| |
| INY
| |
| LDX #7 ; New bad line coming up
| |
| JMP LOOP6
| |
|
| |
| OVER LDA #$97 ; Video bank to 'normal'
| |
| STA $DD00
| |
| LDA #22 ; Same with the charset
| |
| STA $D018
| |
| LDA #8 ; and the horizontal scroll register
| |
| STA $D016
| |
|
| |
| LDA $DC00 ; Let's check the joysticks
| |
| AND $DC01
| |
| TAX
| |
| LDY SPEED
| |
| AND #8 ; Turned right, add speed
| |
| BNE EIP
| |
| INY
| |
| CPY #4 ; Don't store, too much speed
| |
| BPL EIP
| |
| STY SPEED
| |
| EIP TXA
| |
| AND #4 ; Turned left
| |
| BNE ULOS
| |
| DEY
| |
| CPY #$FC ; Too much ?
| |
| BMI ULOS
| |
| STY SPEED
| |
| ULOS LDA VALUE ; Add speed to value (signed)
| |
| CLC
| |
| ADC SPEED
| |
| BPL OK
| |
| LDA SPEED ; Banged to the side ?
| |
| EOR #$FF
| |
| CLC
| |
| ADC #1
| |
| STA SPEED
| |
| LDA VALUE
| |
| OK STA VALUE
| |
| LSR ; Value is twice the shift
| |
| TAX ; Remember the shift
| |
| AND #7 ; lowest 3 bits
| |
| ORA #8 ; (screen 40 chars wide)
| |
| LDY POINTER
| |
| STA SHIFTL,Y
| |
| TXA
| |
| LSR
| |
| LSR
| |
| LSR ; highest 3 bits too
| |
| ASL ; multiplicated by two
| |
| STA SHIFTH,Y
| |
| DEC POINTER
| |
|
| |
| LDA #1 ; Ack the interrupt
| |
| STA $D019
| |
| JMP $EA31 ; The normal interrupt routine
| |
|
| |
| TEXT SCR "THIS IS TECH-TECH FOR C=64 BY ME" ; Test text
| |
| ; SCR converts to screen codes
| |
|
| |
| --------------------------------------------------------------------------
| |
| Basic loader for the Tech-tech demo program (PAL)
| |
|
| |
| 1 S=49152
| |
| 2 DEFFNH(C)=C-48+7*(C>64)
| |
| 3 CH=0:READA$,A:PRINTA$:IFA$="END"THENPRINT"<clr>":SYS49152:END
| |
| 4 FORF=0TO31:Q=FNH(ASC(MID$(A$,F*2+1)))*16+FNH(ASC(MID$(A$,F*2+2)))
| |
| 5 CH=CH+Q:POKES,Q:S=S+1:NEXT:IFCH=ATHEN3
| |
| 6 PRINT"CHECKSUM ERROR":END
| |
| 100 DATA 78A97F8D0DDCA9818D1AD0A9AD8D1403A9C08D1503A9318D12D0A91B8D11D0A0, 3802
| |
| 101 DATA 00A24086FC84FB9891FBC8D0FBE6FC10F7A94485FCA9328501984A4A4AAABD5E, 4749
| |
| 102 DATA C10A0A0AAAA9D069008D4EC0BD00D091FBE8C88A2907D0F4C000D0DDA9378501, 4128
| |
| 103 DATA B9004499084C99105499185C99206499286C99307499387CC8D0E5A9008D3C03, 3258
| |
| 104 DATA 8D3D038D3E0398098099004099284099504099784099A04099C84099F0409918, 3236
| |
| 105 DATA 41A9EF994041C8C028D0DB5860A9968D00DDEAEAAC3C034CE1C0EAB900CF8D16, 4464
| |
| 106 DATA D0B900CE8D18D0EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAAD12D0C9781016C8CAD0, 5850
| |
| 107 DATA D9B900CF8D16D0B900CE8D18D0C8A2074CBBC0A9978D00DDA9168D18D0A9088D, 4132
| |
| 108 DATA 16D0AD00DC2D01DCAAAC3E032908D008C8C00410038C3E038A2904D00888C0FC, 3160
| |
| 109 DATA 30038C3E03AD3D03186D3E03100EAD3E0349FF1869018D3E03AD3D038D3D034A, 2139
| |
| 110 DATA AA29070908AC3C039900CF8A4A4A4A0A9900CECE3C03A9018D19D04C31EA1408, 2759
| |
| 111 DATA 091320091320140503082D1405030820060F1220033D3634200219200D050F12, 652
| |
| 200 DATA END,0
| |
|
| |
| --------------------------------------------------------------------------
| |
| Uuencoded C64 executable version of the demo program (PAL)
| |
|
| |
| begin 644 tech.64
| |
| M`0@-"`$`4[(T.3$U,@`F"`(`EJ5(*$,ILD.K-#BJ-ZPH0[$V-"D`7`@#`$-(J
| |
| MLC`ZAT$D+$$ZF4$D.HM!)+(B14Y$(J>9(CS7R,G4Q3X\P\S2/B(ZGC0Y,34R;
| |
| M.H``DP@$`(%&LC"D,S$Z4;*E2"C&*,HH020L1JPRJC$I*2FL,3:JI4@HQBC*1
| |
| M*$$D+$:L,JHR*2DI`+0(!0!#2+)#2*I1.I=3+%$Z4[)3JC$Z@CJ+0TBR0:<S?
| |
| M`,P(!@"9(D-(14-+4U5-($524D]2(CJ``!D)9`"#(#<X03DW1CA$,$1$0T$YN
| |
| M.#$X1#%!1#!!.4%$.$0Q-#`S03E#,#A$,34P,T$Y,S$X1#$R1#!!.3%".$0Q+
| |
| M,40P03`L(#,X,#(`9@EE`(,@,#!!,C0P.#9&0S@T1D(Y.#DQ1D)#.$0P1D)%G
| |
| M-D9#,3!&-T$Y-#0X-49#03DS,C@U,#$Y.#1!-$$T04%!0D0U12P@-#<T.0"S+
| |
| M"68`@R!#,3!!,$$P04%!03E$,#8Y,#`X1#1%0S!"1#`P1#`Y,49"13A#.#A!]
| |
| M,CDP-T0P1C1#,#`P1#!$1$$Y,S<X-3`Q+"`T,3(X```*9P"#($(Y,#`T-#DYE
| |
| M,#@T0SDY,3`U-#DY,3@U0SDY,C`V-#DY,C@V0SDY,S`W-#DY,S@W0T,X1#!%,
| |
| M-4$Y,#`X1#-#,#,L(#,R-3@`30IH`(,@.$0S1#`S.$0S13`S.3@P.3@P.3DPU
| |
| M,#0P.3DR.#0P.3DU,#0P.3DW.#0P.3E!,#0P.3E#.#0P.3E&,#0P.3DQ."P@?
| |
| M,S(S-@":"FD`@R`T,4$Y148Y.30P-#%#.$,P,CA$,$1"-3@V,$$Y.38X1#`P-
| |
| M1$1%045!04,S0S`S-$-%,4,P14%".3`P0T8X1#$V+"`T-#8T`.<*:@"#($0PN
| |
| M0CDP,$-%.$0Q.$0P14%%045!14%%045!14%%045!14%%045!14%%045!040Q,
| |
| M,D0P0SDW.#$P,39#.$-!1#`L(#4X-3``-`MK`(,@1#E".3`P0T8X1#$V1#!"Q
| |
| M.3`P0T4X1#$X1#!#.$$R,#<T0T)"0S!!.3DW.$0P,$1$03DQ-CA$,3A$,$$Y_
| |
| M,#@X1"P@-#$S,@"!"VP`@R`Q-D0P040P,$1#,D0P,41#04%!0S-%,#,R.3`XN
| |
| M1#`P.$,X0S`P-#$P,#,X0S-%,#,X03(Y,#1$,#`X.#A#,$9#+"`S,38P`,X+'
| |
| M;0"#(#,P,#,X0S-%,#-!1#-$,#,Q.#9$,T4P,S$P,$5!1#-%,#,T.49&,3@V7
| |
| M.3`Q.$0S13`S040S1#`S.$0S1#`S-$$L(#(Q,SD`&PQN`(,@04$R.3`W,#DP;
| |
| M.$%#,T,P,SDY,#!#1CA!-$$T031!,$$Y.3`P0T5#13-#,#-!.3`Q.$0Q.40PI
| |
| M-$,S,45!,30P."P@,C<U.0!G#&\`@R`P.3$S,C`P.3$S,C`Q-#`U,#,P.#)$_
| |
| M,30P-3`S,#@R,#`V,$8Q,C(P,#,S1#,V,S0R,#`R,3DR,#!$,#4P1C$R+"`V&
| |
| 4-3(`<PS(`(,@14Y$+#````````HS!
| |
| ``
| |
| end
| |
|
| |
| =============================================================================
| |
| ACE-128/64 PROGRAMMER'S REFERENCE GUIDE (version 0.9, for Release #10)
| |
| by Craig Bruce <csbruce@ccnga.uwaterloo.ca>
| |
|
| |
| 1. INTRODUCTION
| |
|
| |
| ACE is a program for the Commodore 128 and Commodore 64 that provides a
| |
| command shell environment that is similar to that of Unix. It is still
| |
| in the development stage, but enough of it is complete to be useful.
| |
| BTW, "ACE" means "Advanced Computing Environment" (well, advanced for
| |
| the 128/64).
| |
|
| |
| So what is ACE all about? Well, originally I tried a very ambitious
| |
| project of writing a multitasking operating system for the 128. It got
| |
| it partially working, but it was much too fragile and incomplete to be
| |
| released. It was a white-elephant project. So, then then it came to me
| |
| that I was aiming much too high. What I needed was a much simpler
| |
| system, one that would give the type of programming interface and
| |
| built-in features that I wanted, but one that was close enough to the
| |
| Commodore Kernal that it would not require much of a programming effort
| |
| to hack together a minimal implementation. And thus, there was ACE-128
| |
| Release #1. And I saw it was good.
| |
|
| |
| What I wanted was a system that would be easier to program than the
| |
| Commodore Kernal with all its weird and wonderful device types,
| |
| non-existent memory management, and single-application design. The
| |
| first important feature of this environment was to be able to pass
| |
| arguments from a command line to an application program by typing them
| |
| on the command line of the shell. It is so annoying to load up a
| |
| program in BASIC, run it, and have it ask you for filenames in some
| |
| highly inconvenient way.
| |
|
| |
| Another important system feature is to make near and far memory
| |
| management part of the system, and to make far memory convenient to use
| |
| for storing massively bulky data. And so it was. Also, we want to use
| |
| custom device drivers. Commodore didn't really come through with the
| |
| device drivers it provided. They are all REALLY SLOW. And so that was,
| |
| also, although more custom device drivers are needed. We want to have
| |
| the capability of making programs work together, rather than having
| |
| programs that are totally incompatible. This functionality is still
| |
| under construction. Programs will work together in this uni-tasking
| |
| environment by allowing a program to execute another program as a
| |
| sub-task, and then having control return to the calling program upon
| |
| exit. Finally, we want some good quality applications and a powerful
| |
| command shell. This is still being worked on and progress is coming
| |
| slowly. Oh, almost forgot; we also want all programs to work on both
| |
| the C64 and C128, and they do.
| |
|
| |
| This documentation refers to ACE release #10, which has not been
| |
| released yet (or even programmed). In fact, the current release is #9.
| |
| Release #10 will be spruced up from the inside out to support the system
| |
| interface described in this document. The current release is not being
| |
| described, because some of its features are not the best they could
| |
| possibly be. Note, however, that the basic features, like "open",
| |
| "read", "dirread", and argv are not going to change. Note also that the
| |
| version number of this "P.R.G." is 0.9. This is because this is the
| |
| first incarnation of this document and, considering its nature, is bound
| |
| to hold a large number of small errors.
| |
|
| |
| 2. SYSTEM INTERFACE
| |
|
| |
| This section describes the interface between user programs and the ACE
| |
| kernel. I am very careful throughout this interface specification about
| |
| revealing any internal details that you do not strictly need to know.
| |
| The interface with ACE is not specified in terms of absolute addresses;
| |
| to aid in portability and extensibility, all interfaces are specified in
| |
| terms of symbolic assembler labels. All of the ACE code is currently
| |
| written for the Buddy-128 assembler. Also, because these interface
| |
| absolute addresses are subject to change from version to version of the
| |
| kernel, executables compiled for use with an old version of ACE may not
| |
| work with a new version.
| |
|
| |
| 2.1. ZERO-PAGE VARIABLES
| |
|
| |
| There are four zero-page variables used for passing arguments in most
| |
| system calls. They are as follows:
| |
|
| |
| SYMBOL BYTES DESCRIPTION
| |
| ------- ----- -----------
| |
| zp 2 zeropage pointer
| |
| zw 2 zeropage word
| |
| mp 4 memory pointer
| |
| syswork 16 system work area / arguments
| |
|
| |
| The first two, "zp" and "zw" are used in most calls. They store simple
| |
| 16-bit values; "zp" usually stores pointers to strings in RAM0 memory.
| |
| The "mp" variable is 32-bits in length and is used exclusively for
| |
| passing far memory pointers for use with the far memory routines. All
| |
| three of these variables will remain unchanged inside of system call
| |
| unless they will contain a return value. "syswork" is a 16-byte array
| |
| used mainly when there are too many arguments for other variables to
| |
| hold, and all non-input and non-output bytes of "syswork" are subject to
| |
| change by the kernel. All input arguments placed in the "syswork"
| |
| locations will be preserved unless otherwise indicated. [Note: In
| |
| Release #9, "zp" took on the rolls of both "zp" and "mp"].
| |
|
| |
| 2.2. SYSTEM VARIABLES
| |
|
| |
| There are several non-zeropage variables for storing system status and
| |
| return values:
| |
|
| |
| SYMBOL BYTES DESCRIPTION
| |
| ---------- ----- -----------
| |
| errno 1 error number code returned by failed system calls
| |
| aceID 2 proof that user program is running on top of ACE
| |
| aceArgc 2 argument count for current process
| |
| aceArgv 2 argument vector address for current process
| |
| aceMemTop 2 highest address, plus one, that user prog can use
| |
| aceShellPath 2 ptr to storage for search path for executable programs
| |
| aceShellAlias 2 ptr to storage for shell command aliases
| |
| aceCurDirName 2 ptr to storage for the current directory name
| |
| aceExitData 2 ptr to storage for exit status from the last called prg
| |
| aceDirentBuffer <next> storage for directory entries read from disk
| |
| aceDirentLength - really a constant: length in bytes of "aceDirentBuffer"
| |
| aceDirentBytes 4 bytes in file (usually inexact)
| |
| aceDirentDate 8 date of file in "YY:YY:MM:DD:HH:MM:SS:TW" format
| |
| aceDirentType 4 type of file in null-terminated string
| |
| aceDirentFlags 1 flags of file, "drwx*-et" format
| |
| aceDirentNameLen 1 length of name of file
| |
| aceDirentName 17 null-terminated name of file
| |
|
| |
| ERRNO: "errno" is used to return error codes from system calls. When a
| |
| system call ends in error, it sets the carry flag to "1", puts the error
| |
| code in "errno", and returns to the user program, after undoing any
| |
| system work completed at the time the error is encountered and aborting
| |
| the operation. An error code number is stored in binary in the
| |
| single-byte "errno" location. The symbolic names for the possible error
| |
| codes are given in the next section. If no error occurs in a system
| |
| call, the carry flag will be cleared on return from the call. Note that
| |
| not all system calls can run into errors, so not all set the carry flag
| |
| accordingly.
| |
|
| |
| ID: "aceID" is a two-byte variable. Its purpose is to allow user
| |
| programs to be sure that they are executing on top of ACE. The low byte
| |
| (i.e., the first byte) must be equal to the symbolic constant "aceID1",
| |
| and the high, "aceID2". This will allow ACE applications to inform idiot
| |
| users that they cannot simply BOOT the program from BASIC, but rather
| |
| they must run ACE first.
| |
|
| |
| ARGC: "aceArgc" is a two-byte unsigned number. It gives the number of
| |
| arguments passed to the application by the program (usually the command
| |
| shell) that called the application. The first argument is always the
| |
| name of the application program, so the count will always be at least
| |
| one. Other arguments are optional.
| |
|
| |
| ARGV: "aceArgv" is a two-byte RAM0 pointer. Pay attention. This
| |
| pointer points to the first entry of an array of two-byte pointers which
| |
| point to the null-terminated strings that are the arguments passed to
| |
| the application program by the caller. (A null-terminated string is one
| |
| that ends with a zero byte). To find the address of the N-th argument
| |
| to an application, multiply N by two, add the "aceArgv" contents to
| |
| that, and fetch the pointer from that address. In this scheme, the
| |
| ever-present application name is the 0-th argument. The argv[argc]
| |
| element of the argument vector will always contain a value of $0000, a
| |
| null pointer.
| |
|
| |
| MEM-TOP: "aceMemTop" is a two-byte RAM0 pointer. This points to one
| |
| byte past the highest byte that the application program is allowed to
| |
| use. All application programs are loaded into memory at address
| |
| "aceAppAddress" (next section), and all memory between the end of the
| |
| progam code and "aceMemTop" can be used for temporary variables, file
| |
| buffers, etc. The main problem with this approach is that there are no
| |
| guarantees about how much memory your application will get to play with.
| |
| Many applications, such as simple file utilities, can simply use all
| |
| available memory for a file buffer, but other programs, such as a file
| |
| compressor, may have much greater demand for "near" memory. [Note: this
| |
| variable has a different name in Release #9].
| |
|
| |
| SHELL-PATH: "aceShellPath" is a two-byte RAM0 pointer. This points to
| |
| the page of memory that stores the pathnames of directories to search
| |
| through in order to find executable files. Each pathname is stored as a
| |
| null-terminated string, and the list is terminated by an empty string
| |
| (containing only the zero character). This is intended to be used by
| |
| the shell program, or any other program that is so inclined, to examine
| |
| or alter the search path. The search paths specified in the path page
| |
| are global variables and are used by all programs that make the "exec"
| |
| system call. This mechanism for reading/altering the executable search
| |
| path may be changed in the future.
| |
|
| |
| SHELL-ALIAS: "aceShellAlias" is a two-byte RAM0 pointer. This points to
| |
| the page of memory that stores the aliases to be used with the command
| |
| shell. An alias is a string that is substituted in the place of a
| |
| command name on a shell command line whenever a certain command name
| |
| comes up. For example, you might specify if the user enters the command
| |
| "list a:" that the command name "list" be string-replaced with "cls;xls
| |
| -l". Each alias is stored with the command name first, followed by an
| |
| equals character ("="), followed by the string to substitute, followed
| |
| by a zero. The alias list is terminated by an empty string. This
| |
| mechanism may be extended in the future to allow multiple pages of
| |
| aliases, or may be changed completely.
| |
|
| |
| CUR-DIR-NAME: "aceCurDirName" is a two-byte RAM0 pointer. It points to
| |
| the null-terminated string indicating the current directory. The user
| |
| is not supposed to modify this value, and the value will not always give
| |
| a full pathname. The implementation of this feature may need to change
| |
| in future versions of ACE.
| |
|
| |
| ACE-EXIT-DATA: "aceExitData" is a two-byte RAM0 pointer. It points to
| |
| the 256-byte buffer allocated for user programs to give detailed return
| |
| information upon exiting back to their parent program. See the "exit"
| |
| system call. User programs are allowed to read and write this storage.
| |
| An example use of this feature would be a compiler program returning the
| |
| line number and character position, and description of a compilation
| |
| error to a text editor, so the editor can position the cursor and
| |
| display the error message for user convenience. The implementation of
| |
| this feature may need to change in future versions of ACE.
| |
|
| |
| DIRENT-BUFFER: "aceDirentBuffer" is a buffer used for storing directory
| |
| information read with the "dirread" system call, and is
| |
| "aceDirentLength" bytes long. Only a single directory entry is
| |
| (logically) read from disk at a time. The individual fields of a read
| |
| directory entry are accessed by the fields described next. This field
| |
| is also used for returning disk name information and the number of bytes
| |
| free on a disk drive (see the "dirread" system call).
| |
|
| |
| DIRENT-BYTES: "aceDirentBytes" is a four-byte (32-bit) unsigned field.
| |
| As always, the bytes are addressed from least significant to most
| |
| significant. This field gives the number of bytes in the file. Note
| |
| that this value may not be exact, since Commodore decided to store sizes
| |
| in disk blocks rather than bytes. For devices that report only block
| |
| counts (i.e., every disk device currently supported), the number of
| |
| bytes returned is the number of blocks multiplied by 254. This field,
| |
| as well and the other dirent fields are absolute addresses, not offsets
| |
| from aceDirentBuffer.
| |
|
| |
| DIRENT-DATE: "aceDirentDate" is an eight-byte array of binary coded
| |
| decimal values, stored from most significant digits to least
| |
| significant. The first byte contains the BCD century, the second the
| |
| year, and so on, and the last byte contains the number of tenths of
| |
| seconds in its most significant nybble and a code for the day-of-week in
| |
| its least significant nybble. Sunday has code 1, Monday 2, etc.,
| |
| Saturday 7, and a code of 0 means "unknown". This is the standard
| |
| format for all dates used in ACE. This format is abstracted as
| |
| "YY:YY:MM:DD:HH:MM:SS:TW". For disk devices that don't support dates,
| |
| this field will be set to all zeroes, which can be conveniently
| |
| interpreted as the NULL date, negative infinity, or as the time that
| |
| J.C. was a seven-year-old boy.
| |
|
| |
| DIRENT-TYPE: "aceDirentType" is a three-character (four-byte)
| |
| null-terminated string. It indicates what type the file is, in
| |
| lowercase PETSCII. Standard types such as "SEQ" and "PRG" will be
| |
| returned, as well and other possibilities for custom device drivers.
| |
|
| |
| DIRENT-FLAGS: "aceDirentFlags" is a one-byte field that is interpreted
| |
| as consisting of eight independent one-bit fields. The abstract view of
| |
| the fields is "drwx*-et". "d" means that the item is a subdirectory
| |
| (otherwise it is a regular file), "r" means the item is readable, "w"
| |
| means the item is writable, and "x" means the item is executable. The
| |
| "x" option is really not supported currently. "*" means the item is
| |
| improperly closed (a "splat" file in Commodore-DOS terminology). The
| |
| "-" field is currently undefined. "e" means that the value given in the
| |
| "aceDirentBytes" field is actually exact, and "t" means the file should
| |
| be interpreted as being a "text" file (otherwise, its type is either
| |
| binary or unknown). The bit fields are all booleans; a value of "1"
| |
| means true, "0", false. The "d" bit occupies the 128-bit position, etc.
| |
|
| |
| DIRENT-NAME-LEN: "aceDirentNameLen" is a one-byte number. It gives the
| |
| number of characters in the filename. It is present for convenience.
| |
|
| |
| DIRENT-NAME: "aceDirentName" is a 16-character (17-byte) null-terminated
| |
| character string field. It gives the name of the file or directory or
| |
| disk. Filenames used with ACE are limited to 16 characters.
| |
|
| |
| 2.3. SYSTEM CONSTANTS
| |
|
| |
| There are several symbolic constants that are used with the ACE system
| |
| interface:
| |
|
| |
| SYMBOL DESCRIPTION
| |
| ------------------- -------------------------
| |
| aceAppAddress the start address of applications
| |
| aceID1 the id characters used to identify ACE applications
| |
| aceID2 ...
| |
| aceID3 ...
| |
| aceMemNull the far memory type code used to indicate null ptrs
| |
| aceMemREU far mem type code for Ram Expansion Unit memory
| |
| aceMemInternal far mem type code for internal memory
| |
| aceMemRLREU far mem type code for REU memory accessed thru RAMLink
| |
| aceMemRL far mem type code for direct-access RAMLink memory
| |
| aceErrStopped error code for syscall aborted by STOP key
| |
| aceErrTooManyFiles err: too many files already opened to open another
| |
| aceErrFileOpen err: don't know what this means
| |
| aceErrFileNotOpen err: the given file descriptor is not actually open
| |
| aceErrFileNotFound err: named file to open for reading does not exist
| |
| aceErrDeviceNotPresent err: the specified physical device is not online
| |
| aceErrFileNotInput err: file cannot be opened for reading
| |
| aceErrFileNotOutput err: file cannot be opened for writing
| |
| aceErrMissingFilename err: pathname component is the null string
| |
| aceErrIllegalDevice err: the specified device cannot do what you want
| |
| aceErrWriteProtect err: trying to write to a disk that is write-protected
| |
| aceErrFileExists err: trying to open for writing file that exists
| |
| aceErrFileTypeMismatch err: you specified the file type incorrectly
| |
| aceErrNoChannel err: too many open files on disk drive to open another
| |
| aceErrInsufficientMemory err: ACE could not allocate the memory you requested
| |
| aceErrOpenDirectory err: you are trying to open a dir as if it were a file
| |
| aceErrDiskOnlyOperation err: trying to perform disk-only op on char device
| |
| aceErrNullPointer err: trying to dereference a null far pointer
| |
| aceErrInvalidFreeParms err: bad call to "pagefree": misaligned/wrong size
| |
| aceErrFreeNotOwned err: trying to free far memory you don't own
| |
| stdin file descriptor reserved for stdin input stream
| |
| stdout file descriptor reserved for stdout output stream
| |
| stderr file descriptor reserved for stderr output stream
| |
|
| |
| "aceAppAddress", as discussed before, is the address that application
| |
| programs are loaded into memory at. They must, of course, be compiled
| |
| to execute starting at this address.
| |
|
| |
| The "aceMem" group of constants are for use with the "pagealloc" system
| |
| call, except for "aceMemNull", which may be used by application programs
| |
| for indicating null far pointers. The "pagealloc" call allows you to
| |
| specify what types of memory you are willing to accept. This is
| |
| important because the difference types of memory have different
| |
| performance characteristics. ACE will try to give you the fastest
| |
| memory that is available. Ram Expansion Unit memory has startup and
| |
| byte-transfer times of about 60 us (microseconds) and 1 us,
| |
| respectively. This is the fastest type of far memory. Internal memory
| |
| has a startup time of 24 us and a byte-transfer time of between 7 and 14
| |
| us (depending on whether accessing RAM0 or RAM1+). REU memory accessed
| |
| through a RAMLink has a terrible startup time of 1000 us and a
| |
| byte-transfer time of 2 us. Direct-access RAMLink memory has a startup
| |
| time of 1000 us and a byte-transfer time of 16 us. All these times are
| |
| for the C128 in 2 MHz mode.
| |
|
| |
| The "aceErr" group gives the error codes returned by system calls. The
| |
| error codes are returned in the "errno" variable. Not all possible
| |
| error codes from Commodore disk drives are covered, but the important
| |
| ones are. Finally, the "std" files group give the symbolic file
| |
| descriptor identifiers of the default input, output, and error output
| |
| file streams.
| |
|
| |
| 2.4. SYSTEM CALLS
| |
|
| |
| All system calls are called by setting up arguments in specified
| |
| processor registers and memory locations, executing a JSR to the system
| |
| call address, and pulling the return values out of processor registers
| |
| and memory locations.
| |
|
| |
| 2.1. FILE CALLS
| |
|
| |
| NAME : open
| |
| PURPOSE: open a file
| |
| ARGS : (zp) = pathname
| |
| .A = file mode ("r", "w", or "a")
| |
| RETURNS: .A = file descriptor number
| |
| .CS = error occurred flag
| |
| ALTERS : .X, .Y, errno
| |
|
| |
| Opens a file. The name of the file is given by a pointer to a
| |
| null-terminated string, and may contain device names and pathnames as
| |
| specified in the ACE user documentation. The file mode is a PETSCII
| |
| character. "r" means to open the file for reading, "w" means to open
| |
| the file for writing, and "a" means to open the file for appending
| |
| (writing, starting at the end of the file). An error will be returned
| |
| if you attempt to open for reading or appending a file that does not
| |
| exist, or if you attempt to open for writing a file that does already
| |
| exist. If you wish to overwrite an existing file, you will have to call
| |
| "remove" to delete the old version before opening the new version for
| |
| writing.
| |
|
| |
| The function returns a file descriptor number, which is a small unsigned
| |
| integer that is used with other file calls to specify the file that has
| |
| been opened. File descriptors numbered 0, 1, and 2 are used for stdin,
| |
| stdout, and stderr, respectively. The file descriptor returned will be
| |
| the minimum number that is not currently in use. These numbers are
| |
| system-wide (rather than local to a process as in Unix), and this has
| |
| some implications for I/O redirection (see the "fdswap" call below).
| |
|
| |
| Restrictions: only so many Kernal files allowed to be open on a disk
| |
| device, and there is a system maximum of open files. You will get a
| |
| "too many files" error if you ever exceed this limit. Also, because of
| |
| the nature of Commodore-DOS, there may be even tighter restrictions on
| |
| the number of files that can be simultaneously open on a single disk
| |
| device, resulting in a "no channel" error. Note that this call checks
| |
| the status channel of Commodore disk drives on each open, so you don't
| |
| have to (and should not anyway).
| |
|
| |
| If the current program exits either by calling "exit" or simply by doing
| |
| the last RTS, all files that were opened by the program and are still
| |
| open will be automatically closed by the system before returning to the
| |
| parent program.
| |
|
| |
| NAME : close
| |
| PURPOSE: close an open file
| |
| ARGS : .A = File descriptor number
| |
| RETURNS: .CS = error occurred flag
| |
| ALTERS : .A, .X, .Y, errno
| |
|
| |
| Closes an open file. Not much to say about this one.
| |
|
| |
| NAME : read
| |
| PURPOSE: read data from an open file
| |
| ARGS : .X = File descriptor number
| |
| (zp) = pointer to buffer to store data into
| |
| .AY = maximum number of bytes to read
| |
| RETURNS: (zw) = .AY=number of bytes actually read in
| |
| .CS = error occurred flag
| |
| .ZS = EOF reached flag
| |
| ALTERS : .X, errno
| |
|
| |
| Reads data from the current position of an open file. Up to the
| |
| specified maximum number of bytes will be read. You should not give a
| |
| maximum of zero bytes, or you may misinterpret an EOF (end of file).
| |
| The buffer must be at least the size of the maximum number of bytes to
| |
| read. The data are not interpreted in any way, so it is the
| |
| programmer's responsibility to search for carriage return characters to
| |
| locate lines of input, if he so desires. However, for the console the
| |
| input is naturally divided up into lines, so each call will return an
| |
| entire line of bytes if the buffer is large enough. There are no
| |
| guarantees about the number of bytes that will be returned, except that
| |
| it will be between 1 and the buffer size. So, if you wish to read a
| |
| certain number of bytes, you may have to make multiple read calls.
| |
|
| |
| The call returns the number of bytes read in both the .AY register pair
| |
| and in (zw), for added convenience. [Note: in ACE Release #9, the
| |
| number of bytes read are returned only in the .AY registers, not in
| |
| (zw).] A return of zero bytes read means that the end of the file has
| |
| been reached. An attempt to read beyond the end of file will simply
| |
| give another EOF return. End of file is also returned in the .Z flag of
| |
| the processor.
| |
|
| |
| NAME : write
| |
| PURPOSE: write data to an open file
| |
| ARGS : .X = file descriptor number
| |
| (zp) = pointer to data to be written
| |
| .AY = length of data to be written in bytes
| |
| RETURNS: .CS = error occurred
| |
| ALTERS : .A, .X, .Y, errno
| |
|
| |
| Writes data at the current position of an open file. [Note: ACE Release
| |
| #9 also alters locations (zw) when writing to the console. This problem
| |
| will be corrected.]
| |
|
| |
| NAME : fastopen
| |
| PURPOSE: open a file for fast reading
| |
| ARGS : (zp) = Name
| |
| .A = file mode (must be "r")
| |
| RETURNS: .A = file descriptor number
| |
| .CS = error occurred flag
| |
| ALTERS : .X, .Y, errno
| |
|
| |
| This performs the same function as the regular "open" call, except this
| |
| style of file accessing will allow files to be read much faster than the
| |
| other. On devices that are so equipped, the "fastload" burst command is
| |
| used (similar shortcuts may be possible with other devices too). The
| |
| drawback of this increased speed is that no other device I/O can take
| |
| place while a file is opened for "fast" access, not even to other
| |
| devices, except for output to the console. Other files can be open,
| |
| just not accessed. You also cannot open more than one "fast" file at a
| |
| time. Interrupts will be disabled while a file is open for fast
| |
| accessing, so the user cannot re-enable them, for technical reasons.
| |
| The arguments to this call are exactly the same as the regular "open" to
| |
| make it easy to switch from using one to the other. [Note: these "fast"
| |
| calls do not exist in Release #9].
| |
|
| |
| NAME : fastclose
| |
| PURPOSE: close the file that was opened for fast reading
| |
| ARGS : .A = File descriptor number
| |
| RETURNS: .CS = error occurred flag
| |
| ALTERS : .A, .X, .Y, errno
| |
|
| |
| Closes the file that was opened for fast reading.
| |
|
| |
| NAME : fastread
| |
| PURPOSE: read data from the file opened for fast reading
| |
| ARGS : .X = File descriptor number
| |
| (zp) = pointer to buffer to store data into
| |
| .AY = maximum number of bytes to read
| |
| RETURNS: (zw) = .AY=number of bytes actually read in
| |
| .CS = error occurred flag
| |
| .ZS = EOF reached flag
| |
| ALTERS : .X, errno
| |
|
| |
| Read data from the (one) file that is currently opened for "fast"
| |
| reading. The arguments and semantics are equivalent to the regular
| |
| "read" call.
| |
|
| |
| NAME : bload
| |
| PURPOSE: binary load
| |
| ARGS : (zp) = pathname
| |
| .AY = address to load file
| |
| (zw) = highest address that file may occupy, plus one
| |
| RETURNS: .AY = end address of load, plus one
| |
| .CS = error occurred flag
| |
| ALTERS : .X, errno
| |
|
| |
| Binary-load a file directly into memory. If the file will not fit into
| |
| the specified space, an error will be returned and the load truncated if
| |
| the device supports truncation; otherwise, important data may be
| |
| overwritten.
| |
|
| |
| NAME : remove
| |
| PURPOSE: delete a file
| |
| ARGS : (zp) = pathname
| |
| RETURNS: .CS = error occurred flag
| |
| ALTERS : .A, .X, .Y, errno
| |
|
| |
| Delete the named file.
| |
|
| |
| NAME : rename
| |
| PURPOSE: rename a file or directory
| |
| ARGS : (zp) = old filename
| |
| (zw) = new filename
| |
| RETURNS: .CS = error occurred flag
| |
| ALTERS : .A, .X, .Y, errno
| |
|
| |
| Renames a file or directory. If a file with the new name already
| |
| exists, then the operation will be aborted and a "file exists" error
| |
| will be returned. On most devices, the file to be renamed must be in
| |
| the current directory and the new name may not include any path, just a
| |
| filename.
| |
|
| |
| NAME : devinfo
| |
| PURPOSE: give information about device
| |
| ARGS : .X = file descriptor number
| |
| RETURNS: .A = device type code
| |
| .X = number of columns on device
| |
| .Y = number of rows per "page" of device
| |
| .CS = error occurred flag
| |
| ALTERS : errno
| |
|
| |
| This call returns information about the device of an open file. There
| |
| are four possible values for the device type code: 0==console,
| |
| 1==character-oriented device, and 2==disk device. The number of rows
| |
| and columns per "page" of the device are also returned. For the
| |
| console, this will be the current window size. For a character-oriented
| |
| device, it will be the natural size (typically 80 columns by 66 rows),
| |
| and for a disk, it will be 40 columns in 64 mode or 80 columns in 128
| |
| mode, both by 66 rows.
| |
|
| |
| NAME : fdswap
| |
| PURPOSE: swap two file descriptor numbers
| |
| ARGS : .X = first file descriptor number
| |
| .Y = second file descriptor number
| |
| RETURNS: .CS = error occurred flag
| |
| ALTERS : .A, .X, .Y, errno
| |
|
| |
| This call swaps meanings of two file descriptor numbers. The file
| |
| descriptors may be either in use or not use when the call is made. This
| |
| call is intended to be used to redirect the stdin, stdout, and stderr
| |
| file streams. To do this, simply open the new file intended to be, for
| |
| example, stdout, and swap the file descriptor number returned from the
| |
| open with file descriptor number 1 (stdout). Poof. Then call your
| |
| subroutine or external program, and on return, swap the two file
| |
| descriptors back, and close the redirection file.
| |
|
| |
| 2.2. DIRECTORY CALLS
| |
|
| |
| NAME : diropen
| |
| PURPOSE: open a directory for scanning its directory entries
| |
| ARGS : (zp) = directory pathname
| |
| RETURNS: .A = file descriptor number
| |
| .CS = error occurred flag
| |
| ALTERS : .X, .Y, errno
| |
|
| |
| This call opens a directory for reading its entries. It returns a
| |
| "file" descriptor number to you to use for reading successive directory
| |
| entires with the "dirread" call. The pathname that you give to this
| |
| call must be a proper directory name like "a:" or "c:2//c64/games/:",
| |
| ending with a colon character. You can have directories from multiple
| |
| devices open for reading at one time, but you cannot have the directory
| |
| of one device open multiple times. Also note that you cannot pass
| |
| wildcards to this call; you will receive the entire directory listing.
| |
|
| |
| NAME : dirclose
| |
| PURPOSE: close a directory opened for scanning
| |
| ARGS : .A = file descriptor number
| |
| RETURNS: .CS = error occurred flag
| |
| ALTERS : .A, .X, .Y, errno
| |
|
| |
| Closes a directory that is open for reading. You can make this call at
| |
| any point while scanning a directory; you do not have to finish scanning
| |
| an entire directory first.
| |
|
| |
| NAME : dirread
| |
| PURPOSE: read the next directory entry from an open directory
| |
| ARGS : .X = file descriptor number
| |
| RETURNS: .Z = end of directory flag
| |
| .CS = error occurred flag
| |
| aceDirentBuffer = new directory entry data
| |
| ALTERS : .A, .X, .Y, errno
| |
|
| |
| Reads the next directory entry from the specified open directory into
| |
| the system interface global variable "aceDirentBuffer" described
| |
| earlier. After opening a directory for reading, the first time you call
| |
| this routine, you will receive the name of the disk (or directory). The
| |
| "aceDirentNameLen" and "aceDirentName" fields are the only ones that
| |
| will contain information; the rest of the fields should be ignored.
| |
|
| |
| Each subsequent call to this routine will return the next directory
| |
| entry in the directory. All of the "dirent" fields will be valid for
| |
| these.
| |
|
| |
| Then, after all directory entries have been read through, the last call
| |
| will return a directory entry with a null (zero-length) name. This
| |
| corresponds to the "blocks free" line in a Commodore disk directory
| |
| listing. The "aceDirentBytes" field for this last entry will be set to
| |
| the number of bytes available for storage on the disk. On a Commodore
| |
| disk drive, this will be the number of blocks free multiplied by 254.
| |
| After reading this last entry, you should close the directory.
| |
|
| |
| At any time, if something bizarre happens to the listing from the disk
| |
| that is not considered an error (I don't actually know if this is
| |
| possible or not), then the .Z flag will be set, indicating the abrupt
| |
| ending of the directory listing.
| |
|
| |
| NAME : isdir
| |
| PURPOSE: determine whether the given pathname is for a file or a directory
| |
| ARGS : (zp) = pathname
| |
| RETURNS: .A = device identifier
| |
| .X = is a disk device flag
| |
| .Y = is a directory flag
| |
| .CS = error occurred flag
| |
| ALTERS : errno
| |
|
| |
| Given a properly formatted directoryname or filename, this routine will
| |
| return whether the name is for a file or a directory, whether the device
| |
| of the file or directory is a disk or character device, and the system
| |
| identifier for the device. The two flags return $FF for true and $00
| |
| for false. The device identifier is superfluous for now, but a
| |
| "devinfo" call may be added later. Note that this file does not indicate
| |
| whether the file/directory actually exists or not.
| |
|
| |
| NAME : chdir
| |
| PURPOSE: change the current working directory
| |
| ARGS : (zp) = new directory pathname
| |
| RETURNS: .CS = error occurred flag
| |
| ALTERS : .A, .X, .Y, errno
| |
|
| |
| Changes the current working directory to the named directory. Too bad
| |
| the Commodore Kernal doesn't have a similar call. Unlike the "cd" shell
| |
| command, the argument has to be a properly formatted directory name.
| |
| Note that only directories in native partitions on CMD devices are
| |
| supported by this command; the 1581's crummy idea of partitions is not
| |
| supported.
| |
|
| |
| NAME : cdhome
| |
| PURPOSE: change the current working directory back to the "home" directory
| |
| ARGS : <none>
| |
| RETURNS: .CS = error occurred flag
| |
| ALTERS : .A, .X, .Y, errno
| |
|
| |
| Changes the current working directory back to the "home" directory that
| |
| is defined in the "config.sys" file as the initial directory.
| |
|
| |
| NAME : mkdir
| |
| PURPOSE: create a new directory
| |
| ARGS : (zp) = pathname of new directory
| |
| RETURNS: .CS = error occurred flag
| |
| ALTERS : .A, .X, .Y, errno
| |
|
| |
| Creates a new directory. I'm not sure, but I think that the current
| |
| directory has to be the parent directory of the directory you want to
| |
| create. This may be required by CMD devices, which will be the lowest
| |
| common denominator for directory support. [Note: this call is not
| |
| implemented in Release #9].
| |
|
| |
| NAME : rmdir
| |
| PURPOSE: delete an empty existing directory
| |
| ARGS : (zp) = pathname of empty directory to remove
| |
| RETURNS: .CS = error occurred flag
| |
| ALTERS : .A, .X, .Y, errno
| |
|
| |
| Deletes an existing directory. The directory must be empty (have no
| |
| directory entries) in order for this command to succeed. Again, I am
| |
| pretty sure that you have to be "in" the parent directory of the one to
| |
| be deleted, since this is probably required by CMD devices. [Note: this
| |
| call is not implemented in Release #9].
| |
|
| |
| 2.3. MEMORY CALLS
| |
|
| |
| The calls given in this section are to be used for accessing "far"
| |
| memory in ACE, which includes all REU, RAMLink, RAM1 and above, and
| |
| sections of RAM0 that are not in the application program area.
| |
| Applications are not allowed to access "far" memory directly, because
| |
| the practice of bypassing the operating system would undoubtedly lead to
| |
| problems (can you say "MS-DOS"?).
| |
|
| |
| All of these calls use a 32-bit pointer that is stored in the zero-page
| |
| argument field "mp" (memory pointer). This field is to be interpreted
| |
| as consisting of low and high words. The low word, which of course come
| |
| first, is the offset into the memory "bank" that is contained in the
| |
| high word. Users may assume that offsets within a bank are continuous,
| |
| so operations like addition may be performed without fear on offsets, to
| |
| access subfields of a structure, for example. You may not, however,
| |
| make any interpretation of the bank word. An application should only
| |
| access far memory that it has allocated for itself via the "pagealloc"
| |
| call.
| |
|
| |
| NAME : zpload
| |
| ARGS : [mp] = source far memory pointer
| |
| .X = destination zero-page address
| |
| .Y = transfer length
| |
| RETURNS: .CS = error occurred flag
| |
| ALTERS : .A, .X, .Y, errno
| |
|
| |
| Load zero-page locations with the contents of far memory. "mp", of
| |
| course, gives the address of the first byte of far memory to be
| |
| retrieved. The X register is loaded with the first address of the
| |
| storage space for the data on zero page. It must be in the application
| |
| zero-page space. The Y register holds the number of bytes to be
| |
| transferred, which, considering that transfers must be to the
| |
| application zero-page storage, must be 126 bytes or less. This routine
| |
| will return a "reference through null pointer" if [mp] contains a null
| |
| pointer.
| |
|
| |
| NAME : zpstore
| |
| ARGS : .X = source zero-page address
| |
| [mp] = destination far memory pointer
| |
| .Y = transfer length
| |
| RETURNS: .CS = error occurred flag
| |
| ALTERS : .A, .X, .Y, errno
| |
|
| |
| This routine is the complement of "zpload"; this transfers data from
| |
| zero page to far memory. The arguments and restrictions are the same as
| |
| "zpload".
| |
|
| |
| NAME : fetch
| |
| ARGS : [mp] = source far memory pointer
| |
| (zp) = destination RAM0 pointer
| |
| .AY = transfer length
| |
| RETURNS: .CS = error occurred flag
| |
| ALTERS : .A, .X, .Y, errno
| |
|
| |
| This routine will fetch up to 64K of data from far memory into RAM0
| |
| memory where it can be accessed directly by the processor. The
| |
| arguments should mostly speak for themselves. You should not fetch into
| |
| RAM0 memory that is not specifically allocated to the application. You
| |
| will get an error if you try to use a null far pointer.
| |
|
| |
| NAME : stash
| |
| ARGS : (zp) = source RAM0 pointer
| |
| [mp] = destination far memory pointer
| |
| .AY = transfer length
| |
| RETURNS: .CS = error occurred flag
| |
| ALTERS : .A, .X, .Y, errno
| |
|
| |
| This is the complement of "fetch" and operates analogously, except that
| |
| it transfers data from RAM0 to far memory.
| |
|
| |
| NAME : pagealloc
| |
| ARGS : .A = requested number of pages to be allocated
| |
| .X = starting "type" of memory to search
| |
| .Y = ending "type" of memory to search, inclusive
| |
| RETURNS: [mp] = far memory pointer to start of allocated memory
| |
| .CS = error occurred flag
| |
| ALTERS : .A, .X, .Y, errno
| |
|
| |
| This routine allocates a given number of contiguous far-memory pages for
| |
| use by the application, and returns a pointer to the first byte of the
| |
| first page. On calling, the accumulator contains the number of pages to
| |
| allocate (a page is 256 contiguous bytes aligned on a 256-byte address
| |
| (i.e., the low byte of a page address is all zeros)).
| |
|
| |
| The X and Y registers contain the start and end "types" of far memory to
| |
| search for the required allocation. The possible types are mentioned in
| |
| the System Constants section. The numeric values for the "aceMem"
| |
| constants are arranged in order of accessing speed. So, if your
| |
| application has speed requirements that dictate, for example, that
| |
| RAMLink memory should not be used, then you would call "pagealloc" with
| |
| a search range of .X=0 to .Y=aceMemInternal. If you wanted to say you
| |
| are willing to accept any memory the system can give to you, you would
| |
| specify .X=0 to .Y=255. The values of 0 and 255 will be converted to
| |
| the fastest and slowest memory available. ACE will give you the fastest
| |
| type of memory, from what you specify as acceptable, that it can. If
| |
| you had an application that you didn't want to waste the high-speed
| |
| memory on, you could first call "pagealloc" asking for slow memory, such
| |
| as .X=aceMemRLREU to .Y=255, and if there is none of that type of memory
| |
| left, make another call with .X=0 to .Y=aceMemRLREU-1.
| |
|
| |
| This routine will then search its available free memory for a chunk
| |
| fitting your specifications. If it cannot find one, the routine will
| |
| return a "insufficient memory" error and a null pointer. Note that this
| |
| error may occur if there is actually the correct amount of memory free
| |
| but just not in a big enough contiguous chunk. If successful, this
| |
| routine will return in "mp" a pointer to the first byte of the first
| |
| page of the allocated memory.
| |
|
| |
| If you call a subprogram with the "exec" call while the current program
| |
| is holding far memory, that far memory will be kept allocated to your
| |
| program and will be safe while the child program is executing. If you
| |
| don't deallocate the memory with "pagefree" before exiting back to your
| |
| parent program, then the system will automatically deallocate all memory
| |
| allocated to you. So, have no fear about calling "exit" if you are in
| |
| the middle of complicated far memory manipulation when a fatal error
| |
| condition is discovered and you don't feel like figuring out what memory
| |
| your program owns and deallocating it.
| |
|
| |
| Some applications will want to have the most amount of memory to work
| |
| with, and if there is free space in the application program area that
| |
| the program is not using directly, then you may want to use that as
| |
| "far" memory. To do this, you will need to write your own stub routines
| |
| that manage page allocation and deallocation requests to the near
| |
| memory, and calls the "pagealloc" and "pagefree" routines to manage the
| |
| far memory. The "sort" program distributed with ACE does this. Please
| |
| note that you CANNOT simply free the unused memory of the application
| |
| program area and expect the system to manage it. Bad stuff would
| |
| happen.
| |
|
| |
| Some applications will want to have a byte-oriented memory allocation
| |
| service rather than a page-oriented service. You can build a
| |
| byte-oriented service on top of the page-oriented service in your
| |
| application programs that manage memory for the application and ask the
| |
| system for pages whenever more memory is required by the application.
| |
| Note that this still means that allocated memory will be freed
| |
| automatically when an application exits. The "sort" program implements
| |
| this byte-oriented service, so you can check its source code to see how
| |
| this is done (or to simply cut and paste the code into your own
| |
| program).
| |
|
| |
| NAME : pagefree
| |
| ARGS : [mp] = far memory pointer to start of memory to be freed
| |
| .A = number of pages to be freed
| |
| RETURNS: .CS = error occurred flag
| |
| ALTERS : .A, .X, .Y, errno
| |
|
| |
| This deallocates memory that was allocated to a process by using the
| |
| "pagealloc" system call. You will get an error return if you try to
| |
| deallocate memory that you don't own.
| |
|
| |
| 2.4. SCREEN CONTROL CALLS
| |
|
| |
| This section describes the system calls that are available to
| |
| application programmers for full-screen applications. These calls are
| |
| intended to be general enough to handle different screen hardware (the
| |
| VIC and VDC chips and a VIC soft-80-column bitmap screen, and possibly
| |
| others). These calls are also designed to be efficient as possible, to
| |
| discourage progammers from attempting to bypass using them. Bypassing
| |
| these calls would be a bad thing.
| |
|
| |
| The calls are designed around the C-128/PET concept of a window. There
| |
| is only one active window on the display at a time, which may be is
| |
| large as the entire screen or as small as 1x1 character cells. This
| |
| window is very cheap to setup and tear down. An application can have
| |
| multiple windows on the screen by switching the active window around.
| |
|
| |
| In the calls below, all mention of "sw" in the arguments and return
| |
| values refer to the "syswork" array. For many calls, there is a
| |
| "char/color/ high-attribute" argument. This argument determines which
| |
| parts of a screen location will be modified. There are three components
| |
| to each screen location: the character code, the color code, and the
| |
| high-attributes. The character code is exactly the same as the PETSCII
| |
| code for the character that you want to display (unlike the screen-code
| |
| arrangement that Commodore chose). There are 128 individual characters
| |
| in the normal PETSCII positions, and 128 reversed images of the
| |
| characters in the most sensible other positions. The codes are as
| |
| follows:
| |
|
| |
| CODES (hex) DESCRIPTION
| |
| ----------- -----------
| |
| $00-$1f reverse lowercase letters
| |
| $20-$3f digits and punctuation
| |
| $40-$5f lowercase letters
| |
| $60-$7f reverse graphics characters
| |
| $80-$9f reverse uppercase letters
| |
| $a0-$bf graphics characters
| |
| $c0-$df uppercase letters
| |
| $e0-$ef reverse digits and punctuation
| |
|
| |
| There are sixteen color codes, occupying the lower four bits of the color
| |
| value. These are RGBI codes, as follows:
| |
|
| |
| CODE(dec) (hex) (bin) DESCRIPTION
| |
| --------- ----- -rgbi -----------
| |
| 0 $0 %0000 black
| |
| 1 $1 %0001 dark grey
| |
| 2 $2 %0010 blue
| |
| 3 $3 %0011 light blue
| |
| 4 $4 %0100 green
| |
| 5 $5 %0101 light green
| |
| 6 $6 %0110 dark cyan on VDC, medium grey on VIC-II
| |
| 7 $7 %0111 cyan
| |
| 8 $8 %1000 red
| |
| 9 $9 %1001 light red
| |
| 10 $a %1010 purple
| |
| 11 $b %1011 light purple on VDC, orange on VIC-II
| |
| 12 $c %1100 brown
| |
| 13 $d %1101 yellow
| |
| 14 $e %1110 light grey
| |
| 15 $f %1111 white
| |
|
| |
| Finally, there are the high-attribute bits. These occupy the four most
| |
| significant bits of the color value. Depending on the type of display
| |
| (VIC text, VDC text, or VIC/VDC bitmap), these bits have one of three
| |
| meanings: character attributes, background character color, or no
| |
| effect. Thus, care must be taken in using these bits; they will have
| |
| different effects on different displays. The background character codes
| |
| are the same as the foreground character codes listed above. The
| |
| character attributes have the following meanings:
| |
|
| |
| BIT VALUE (dec) (hex) DESCRIPTION
| |
| -avub---- ----- ----- -----------
| |
| %10000000 128 $80 alternate characterset (italic)
| |
| %01000000 64 $40 reverse character
| |
| %00100000 32 $20 underline
| |
| %00010000 16 $10 blink
| |
|
| |
| These values are additive (or, should I say, "or-ative"); you can use
| |
| any combination of them at one time. Normally, you may wish to leave
| |
| the high-attribute bits alone, unless you take the values to give them
| |
| from the color palettes (next section). To specify which of you wish to
| |
| have changed, set bits in the "char/color/high-attribute" argument to
| |
| system calls. The flags have the following values. They are or-ative
| |
| as well:
| |
|
| |
| BIT VALUE (dec) (hex) DESCRIPTION
| |
| -cah----- ----- ----- -----------
| |
| %10000000 128 $80 modify character
| |
| %01000000 64 $40 modify color
| |
| %00100000 32 $20 modify high-attribute bits
| |
|
| |
| The screen calls that deal with placing characters on the screen refer
| |
| to screen locations using absolute addresses of locations in screen
| |
| memory. This scheme is used for increased efficiency. You can obtain
| |
| information about the absolute screen address of the top left-hand
| |
| corner of the current window and the number of screen addresses between
| |
| successive rows, to figure out screen addresses for your applications.
| |
| For added convenience, there is a call which will accept row and column
| |
| numbers and return the corresponding absolute screen address.
| |
|
| |
| The screen-control system calls are as follows:
| |
|
| |
| NAME : winmax
| |
| ARGS : <none>
| |
| RETURNS: <none>
| |
| ALTERS : .A, .X, .Y
| |
|
| |
| Sets the current window to cover the entire screen.
| |
|
| |
| NAME : winclear
| |
| ARGS : .A = char/color/high-attribute modification flags
| |
| .X = character fill value
| |
| .Y = color fill value
| |
| RETURNS: <none>
| |
| ALTERS : .A, .X, .Y
| |
|
| |
| This call "clears" the current window by filling it with the
| |
| character/color you specify. You can use the char/color/hi-attr to
| |
| limit what gets cleared. [Note: The arguments for this call are slightly
| |
| different in Release #9].
| |
|
| |
| NAME : winset
| |
| ARGS : .A = number of rows in window
| |
| .X = number of columns in window
| |
| sw+0 = absolute screen row of top left corner of window
| |
| sw+1 = absolute screen column of top left corner of window
| |
| RETURNS: .CS = error occurred flag
| |
| ALTERS : .A, .X, .Y, errno
| |
|
| |
| Sets the current window to the size you specify. You will get an error
| |
| return if the window will not fit on the screen or of it does not
| |
| contain at least one character. [Note: This call is not implemented in
| |
| Release #9].
| |
|
| |
| NAME : winsize
| |
| ARGS : <none>
| |
| RETURNS: .A = number of rows in window
| |
| .X = number of columns in window
| |
| sw+0 = absolute screen row of top left corner of window
| |
| sw+1 = absolute screen column of top left corner of window
| |
| (sw+2)= screen address of top left corner
| |
| (sw+4)= screen address increment between successive rows on screen
| |
| ALTERS : <none>
| |
|
| |
| Returns information about the current window. [Note: the arguments are
| |
| slightly different in Release #9].
| |
|
| |
| NAME : winput
| |
| ARGS : (sw+0)= absolute screen address to start putting data at
| |
| (sw+2)= character string pointer
| |
| .X = length of character string
| |
| .Y = color
| |
| .A = char/color/high-attribute modification flags
| |
| sw+4 = fill character
| |
| sw+5 = total field length
| |
| RETURNS: <none>
| |
| ALTERS : .A, .X, .Y
| |
|
| |
| Puts text onto the screen. The output region is given by the absolute
| |
| starting screen address and the total field length. This region must be
| |
| contained on one line of the current window, or bad things will happen.
| |
| A pointer to the characters to be printed is given, as well as the
| |
| length of the character array. Control characters in this string are
| |
| ignored; they are poked literally onto the screen, including the null
| |
| character. The length of the character string must be less than or
| |
| equal to the total length of the field. Remaining spaces in the field
| |
| will be filled in with the "fill character".
| |
|
| |
| The color of the total field length will be filled in with "color". You
| |
| can use the "char/color/hi-attr" modification flags to specify what is
| |
| to be changed. If you were to, for example, specify that the colors of
| |
| the field are not to be changed, then the call would execute faster.
| |
|
| |
| NAME : wincolor
| |
| ARGS : .X = new RGBI screen color
| |
| .Y = new RGBI border color
| |
| .A = which colors to change ($80=screen + $40=border)
| |
| RETURNS: .X = resulting RGBI screen color
| |
| .Y = resulting RGBI border color
| |
| ALTERS : .A
| |
|
| |
| Sets the color of the screen and border. You may optionally set one,
| |
| the other, both, or neither. The resulting colors for colors changed,
| |
| and the existing colors for colors unchaned will be returned. Note that
| |
| not all screens have an adjustable color, so the border argument may be
| |
| ignored.
| |
|
| |
| NAME : winpos
| |
| ARGS : .A = row
| |
| .X = column
| |
| RETURNS: (sw+0)= screen memory address of position
| |
| ALTERS : .A, .X, .Y
| |
|
| |
| Given a row and column in the current window, returns the corresponding
| |
| absolute screen memory location for use with other calls. No errors are
| |
| returned, so garbage in, garbage out.
| |
|
| |
| NAME : wincursor
| |
| ARGS : (sw+0)= screen address to place cursor
| |
| .A = enable flag ($ff=cursor-on / $00=cursor-off)
| |
| .Y = color to show cursor in
| |
| RETURNS: <none>
| |
| ALTERS : .A, .X, .Y
| |
|
| |
| Displays or undisplays the cursor at the given screen address. This
| |
| call returns immediately in either case. No errors are returned. Do
| |
| not display anything in or scroll the window while the cursor is being
| |
| displayed, do not display the cursor twice, and do not undisplay the
| |
| cursor twice in a row or bad things will happen. Also, make sure you
| |
| give the same address when undisplaying the cursor as you did when
| |
| displaying the cursor. When the system starts, the cursor will be in
| |
| its undisplayed state (duh!). You also get to specify the color you
| |
| want the cursor to be shown in. The high-attribute bits of this color
| |
| are ignored.
| |
|
| |
| NAME : winscroll
| |
| ARGS : .A = flags: char/color/hi-attr + $08=up + $04=down
| |
| .X = number of rows to scroll up/down
| |
| sw+4 = fill character
| |
| .Y = fill color
| |
| RETURNS: <none>
| |
| ALTERS : .A, .X, .Y
| |
|
| |
| Scrolls the contents of the current window up or down. You can scroll
| |
| any number of rows at a time. After scrolling, the bottom (or top) rows
| |
| will be filled with the fill character and color. You can limit whether
| |
| the characters and/or colors are to be scrolled by using the "flags"
| |
| byte in the usual way. Scrolling only the characters, for example, will
| |
| be twice as fast as scrolling both characters and attributes. Whether
| |
| to scroll up or down is specified also using bits in the "flags" field,
| |
| as indicated in the input arguments above. You can specify scrolling in
| |
| more than one way, and the result will be to scroll in each specified
| |
| direction in turn, in the order up, then down. In the future, scrolling
| |
| left and right may be added to this call. [Note: The arguments and
| |
| semantics of this call are a little different in Release #9].
| |
|
| |
| 2.5. CONSOLE CALLS
| |
|
| |
| The calls in this section refer to the system "console", which includes
| |
| the screen and keyboard. The screen-related calls are at a higher level
| |
| than the calls in the previous section.
| |
|
| |
| NAME : stopkey
| |
| ARGS : <none>
| |
| RETURNS: .CS = stop key pressed
| |
| ALTERS : .A, .X, .Y, errno
| |
|
| |
| Indicates whether the STOP (RUN/STOP) key is currently being held down
| |
| by the user. If so, carry flag is set on return (and clear if not). If
| |
| the stop key is discovered to be pressed by this call, then the keyboard
| |
| buffer will also be cleared.
| |
|
| |
| NAME : getkey
| |
| ARGS : <none>
| |
| RETURNS: .A = keyboard character
| |
| ALTERS : .X, .Y
| |
|
| |
| Waits for the user to type a key (or takes a previous keystroke from the
| |
| keyboard buffer). Regular characters are returned in their regular
| |
| PETSCII codes, but there are many special control keystrokes. They are
| |
| not listed here (yet) because I haven't figured out what all of the
| |
| special codes should be, but all 256 possible character values will be
| |
| covered. Special codes like "page up", etc. should help in
| |
| standardizing control keystrokes for applications. The key code is
| |
| returned in the accumulator. No errors are possible.
| |
|
| |
| NAME : concolor
| |
| ARGS : .A = which colors to modify: $02=character + $01=cursor
| |
| + $80=modify high-attributes of colors
| |
| .X = new RGBI character color
| |
| .Y = new RGBI cursor color
| |
| RETURNS: .X = resulting character color
| |
| .Y = resulting cursor color
| |
| ALTERS : .A
| |
|
| |
| Sets the character and cursor colors to be used by the console for the
| |
| "read" and "write" system calls that refer to files opened to the
| |
| console device. You can use the flags argument to limit what gets
| |
| changed. [Note: flags argument is slightly different in Release #9].
| |
|
| |
| NAME : conpalette
| |
| ARGS : <none>
| |
| RETURNS: sw+0 = main character color
| |
| sw+1 = cursor color
| |
| sw+2 = status character color
| |
| sw+3 = separator character color
| |
| sw+4 = highlight character color
| |
| sw+5 = alert character color
| |
| sw+6 = screen border color
| |
| sw+7 = screen background color
| |
| ALTERS : .A, .X, .Y
| |
|
| |
| Returns the palette of colors that are recommended to be used in
| |
| applications. These colors are chosen by the user in the system
| |
| configuration, so they can be interpreted as being what the user wants
| |
| and expects applications to use. A different selection is made by the
| |
| user for each different screen type, and the palette returned will be
| |
| for the screen type currently in use. The high-attribute bits of these
| |
| colors are valid. Eight colors are included in the palette, and you may
| |
| interpret their meaning according to the application. The suggested
| |
| usages are given in the return arguments listed above.
| |
|
| |
| NAME : conscreen
| |
| ARGS : .A = number of text rows required, minimum
| |
| .X = number of text columns required, minimum
| |
| RETURNS: .A = number of text rows you get
| |
| .X = number of text columns you get
| |
| .CS = error occurred flag (requested size cannot be given)
| |
| ALTERS : .Y, errno
| |
|
| |
| This call selects an appropriate display device, screen, and layout for
| |
| displaying text. You ask for the minimum number of rows and columns you
| |
| require on the screen, and the call returns to you what you receive. If
| |
| the system cannot match your minimum requirements, an error will be
| |
| returned, and the current screen will be unchanged. The clock speed of
| |
| the processor will be changed to match the screen selected, if
| |
| appropriate.
| |
|
| |
| NAME : conpos
| |
| ARGS : .A = row
| |
| .X = column
| |
| RETURNS: .CS = error encountered flag
| |
| ALTERS : .A, .X, .Y
| |
|
| |
| This call will set the screen location that the next console "read" or
| |
| "write" system call will operate from. If the "cursor" position is
| |
| outside the boundaries of the current window on the screen, an error
| |
| will be returned. [Note: this function is not implemented in Release
| |
| #9].
| |
|
| |
| 2.6. PROCESS CONTROL CALLS
| |
|
| |
| This section describes calls that are used to control the execution of
| |
| processes (active programs). From within one program, you can call for
| |
| the execution of another program, have it execute, and then return to
| |
| the calling program. Since only one program is allowed in memory at a
| |
| time, some special problems arise. Also, only rudimentary versions of
| |
| these system calls are implemented in Release #9 and I haven't decided
| |
| completely how they should work. So, this section is a bit tentative.
| |
|
| |
| NAME : exec
| |
| PURPOSE: execute external program as a child process
| |
| ARGS : (zp) = program name of executable
| |
| (zw) = start address of argument vector
| |
| .AY = number of arguments
| |
| [mp] = pointer to far memory volatile storage
| |
| RETURNS: .A = exit code
| |
| .X = number of bytes in "aceExitData" used
| |
| [mp] = pointer to far memory volatile storage
| |
| .CS = error occurred flag
| |
| ALTERS : .Y, errno
| |
|
| |
| Calling this routine will cause a new "frame" to be set up on the
| |
| "system stack" (lowering the available application area memory a
| |
| little), the specified program to be loaded into memory over top of the
| |
| current one, the new program to be executed, the old program to be
| |
| reloaded from whatever disk unit it came from originally upon exit of
| |
| the new program, and control to be returned to the old process with the
| |
| return values from the executed program. This is a complicated procedure
| |
| and many things can go wrong.
| |
|
| |
| The first thing that a process that wants to call another program must
| |
| do is set up the arguments to be passed in. All arguments must be
| |
| null-terminated strings. These arguments are to be put into high
| |
| memory, starting from one less than the location pointed to by
| |
| "aceMemTop" and working downward. It does not matter in which order the
| |
| strings are placed, as long as they are all grouped together. Then,
| |
| immediately below the strings comes the vector of two-byte RAM0 pointers
| |
| that point to the strings. This array must be in order, with the lowest
| |
| entry pointing to the first (zero subscript) string, etc., the second
| |
| highest entry pointing to the last string, and the highest entry
| |
| containing the value $0000. An asciigram follows:
| |
|
| |
| HIGHER ADDRESSES
| |
| | |
| |
| | | <--(aceMemTop)
| |
| +-----------+
| |
| | |
| |
| | string |
| |
| | | : collection of null-terminated strings
| |
| | contents |
| |
| | |
| |
| | |
| |
| +-----------+
| |
| | $0000 | : argv[N] : null argument pointer
| |
| +-----------+
| |
| | strptrN-1 | : argv[N-1]
| |
| +-----------+
| |
| | strptrN-2 | : argv[N-2]
| |
| +-----------+
| |
| . .
| |
| . .
| |
| +-----------+
| |
| | strptr 1 | : argv[1] : first actual argument
| |
| +-----------+
| |
| | strptr 0 | <--(zw) : argv[0] : filename of program to be executed
| |
| +-----------+
| |
| | |
| |
| LOWER ADDRESSES
| |
|
| |
| The first entry should indicate the filename or command name of the
| |
| program being executed, and the subsequent arguments are the actual
| |
| input arguments to the program being called. The address of the first
| |
| argument vector table entry is loaded into (zw), and the number of
| |
| arguments is loaded into .AY. Note that this value also includes the
| |
| command name, so if, for example, you were to call program "wc" to count
| |
| two filenames "hello" and "goodbye", then you would pass an argument
| |
| count of 3. The name pointed to by "argv[0]" does not actually have to
| |
| be the literal command name, but the one pointed to by (zp) does. If a
| |
| relative executable name is given in (zp), then the search path will be
| |
| used to locate the executable. Oh, don't screw up the organization of
| |
| the arguments or bad things will happen; there is no structure checking.
| |
|
| |
| After setting up the arguments, you'll want to set up any redirections
| |
| of stdin, stdout, or stderr you'll be needing. Because there is only
| |
| one open file table in the whole uni-tasking system, you'll have to
| |
| manipulate existing entries using the "fdswap" system call described
| |
| earlier. The open file table is inherited by the child process. Note
| |
| that if it closes any of the open files it inherited, then they are also
| |
| closed to your use also. If the child accidentally leaves open any
| |
| files it opened, they will be closed by the system before you are
| |
| reactivated.
| |
|
| |
| Finally, before the call is made, you have to save any volatile local
| |
| information into "far" memory. All application zeropage and application
| |
| area memory will be modified by the called program, so you must save
| |
| whatever you will need to continue after the return to be able to
| |
| continue. As mentioned earlier, all of the "far" memory that a parent
| |
| program owns will be safe, so you can save your volatile information
| |
| there, in any format you wish. All you have to do is save the pointer
| |
| to the far memory into the [mp] pointer. Upon return of the child
| |
| process, the value you put into [mp] will be restored, and you can then
| |
| restore your volatile information out of far storage. If you wish to
| |
| save no volatile information, then you can just leave garbage in the
| |
| [mp] value, since it will not be interpreted by the system.
| |
|
| |
| Alright, so now you call the "exec" primitive, the child program is
| |
| loaded, executed, and it returns.
| |
|
| |
| At this time, the parent program (that's you) is reloaded from wherever
| |
| it was loaded originally and you are returned to the instruction
| |
| immediately following the "jsr exec", with your processor stack intact
| |
| but the rest of your volatile storage invalid. Even if there is an
| |
| error return (carry flag set), your volatile storage will still need to
| |
| be restored, since the application area may have been overwritten before
| |
| the error was discovered. In the case of an error return, the child
| |
| process will not have been executed. If the system is unable to reload
| |
| the parent program (you), then an error return is given to your parent,
| |
| and so on, as far back as necessary. (This is a minor exception to the
| |
| rule that an error return indicates that a child didn't execute; in this
| |
| case, the child didn't complete).
| |
|
| |
| You are also returned an "exit code", which will have
| |
| application-specific meaning, although standard programs (e.g., shell
| |
| script) interpret the value as: 0==normal exit, anything else==error
| |
| exit. The X register is also set to indicate the amount of
| |
| "aceExitData" that is used, to allow for more complicated return values.
| |
|
| |
| [Note: This call is different in Release #9].
| |
|
| |
| NAME : execsub
| |
| PURPOSE: execute internal subroutine as a separate process
| |
| ARGS : (zp) = address of subroutine
| |
| (zw) = address of argument vector
| |
| RETURNS: .A = exit code
| |
| .X = number of bytes in "aceExitData" used
| |
| .CS = error occurred flag
| |
| ALTERS : .Y, errno
| |
|
| |
| This call is very similar to "exec", except that it calls an internal
| |
| subroutine rather than an external program. Thus, you don't have to
| |
| save or restore your volatile storage, or worry about loading the child
| |
| or reloading the parent. You do, however, set up the arguments and file
| |
| redirections as you would for a full "exec". [Note: this call is
| |
| different in Release #9].
| |
|
| |
| NAME : exit
| |
| PURPOSE: exit current program, return to parent
| |
| ARGS : .A = exit code
| |
| .X = number of bytes in "aceExitData" used
| |
| RETURNS: <there is no return, brah-ha-ha-ha-ha-ha!!!>
| |
| ALTERS : <don't bloody well matter>
| |
|
| |
| This call causes the current program to exit back to its parent. A
| |
| program that exits simply by returning to its environment will give back
| |
| an exit code of 0, which should be interpreted as a normal return. If
| |
| you wish to indicate a special return, you should use some exit code
| |
| other than zero. Many utilities will interpret non-zero error codes as
| |
| actual errors and may abort further operations because of this.
| |
|
| |
| You may set up a return data in "aceExitData", up to 255 bytes worth,
| |
| and load the number of bytes used into .X if you wish. It is
| |
| recommended that the first field of this data be a special identifier
| |
| code so programs that cannot interpret your data will not try. You
| |
| cannot give any far pointers in your return data, since all far memory
| |
| allocated to you will be freed by the system before returning to your
| |
| parent.
| |
|
| |
| NAME : memstat
| |
| PURPOSE: get "far" memory status plus process id
| |
| ARGS : <none>
| |
| RETURNS: .A = current process id
| |
| [sw+0]= amount of "far" memory free
| |
| [sw+4]= total amount of "far" memory
| |
| ALTERS : .X, .Y
| |
|
| |
| This call returns the current process id, the number of bytes of far
| |
| memory currently free, and the total amount of far memory.
| |
|
| |
| 2.7. MISCELLANEOUS CALLS
| |
|
| |
| NAME : utoa
| |
| PURPOSE: convert unsigned 32-bit number to a decimal PETSCII string
| |
| ARGS : .A = minimum length for return string
| |
| .X = zero-page address of 32-bit number
| |
| (sw+0)= pointer to string buffer to store string
| |
| RETURNS: .Y = length of string
| |
| ALTERS : .A, .X
| |
|
| |
| This is a utility call in the kernel. It is really not necessary for it
| |
| to be in the kernel, but so many programs make use of it that it makes
| |
| sense for it to be factored out. You give a pointer to a 32-bit
| |
| unsigned value in zero page memory, a pointer to a buffer to store that
| |
| string that is at least as long as necessary to store the value plus the
| |
| null-character terminator that will be put on the end of the string, and
| |
| a minimum length value for the string. If the number requires fewer
| |
| digits than the minimum length, the string will be padded with spaces on
| |
| the left. Since a 32-bit quantity can only contain an maximum of ten
| |
| decimal digits, the string buffer will only need to be a maximum of
| |
| eleven bytes in size.
| |
|
| |
| NAME : getdate
| |
| PURPOSE: get the current date and time
| |
| ARGS : (.AY) = address of buffer to put BCD-format date into
| |
| RETURNS: <none>
| |
| ALTERS : .A, .X, .Y
| |
|
| |
| Returns the current date and time in the BCD format described in the
| |
| paragraph on "aceDirentDate". It puts it into the at-least-eight-byte
| |
| storage area pointed to by (.AY).
| |
|
| |
| NAME : setdate
| |
| PURPOSE: set the current date and time
| |
| ARGS : (.AY) = address of date in BCD format
| |
| RETURNS: <none>
| |
| ALTERS : .A, .X, .Y
| |
|
| |
| Sets the current date and time in the system. (.AY) points to the BCD
| |
| date string whose format is discussed in the paragraph on
| |
| "aceDirentDate". No validity checking is performed on the date given.
| |
|
| |
| NAME : cmdopen
| |
| PURPOSE: open command channel to Commodore disk drives
| |
| ARGS : (zp) = device name
| |
| RETURNS: .A = file descriptor number
| |
| .CS = error occurred flag
| |
| ALTERS : .X, .Y, errno
| |
|
| |
| This "cmd" set of system calls really should not be present, but they
| |
| will be needed until the full complement of disk-utility system calls
| |
| are implemented. It is really not recommended that any application
| |
| program rely on these calls being around very long. This call opens the
| |
| command channel on the named device (standard ACE device name string)
| |
| and returns the file descriptor number to use thereafter.
| |
|
| |
| NAME : cmdclose
| |
| PURPOSE: close command channel to Commodore disk drives
| |
| ARGS : .A = file descriptor number
| |
| RETURNS: .CS = error occurred flag
| |
| ALTERS : .A, .X, .Y, errno
| |
|
| |
| This closes an opened command channel to a disk drive. Closing the
| |
| status will NOT affect any other open files on the disk unit at the
| |
| time.
| |
|
| |
| NAME : cmdsend
| |
| PURPOSE: send command over command channel to Commodore disk drives
| |
| ARGS : .X = file descriptor number
| |
| (.AY) = pointer to null-terminated command string
| |
| RETURNS: .CS = error occurred flag
| |
| ALTERS : .A, .X, .Y, errno
| |
|
| |
| This sends a command string to a disk drive. Since a null-terminated
| |
| string representation is used, not all Commodore/CMD-DOS commands can be
| |
| sent, but the important ones can be.
| |
|
| |
| NAME : cmdstatus
| |
| PURPOSE: receive current status from command channel of Commodore disk drives
| |
| ARGS : .X = file descriptor number
| |
| (.AY) = pointer to buffer for null-terminated status string
| |
| RETURNS: .A = status code in binary
| |
| .CS = error occurred
| |
| ALTERS : .X, .Y, errno
| |
|
| |
| This returns the status of a disk drive in a string as well as the
| |
| binary disk status number in the accumulator. The given status buffer
| |
| must be at least 50 or so characters long (whatever is the longest
| |
| possible disk status string).
| |
|
| |
| 3. USER PROGRAM ORGANIZATION
| |
|
| |
| The ACE system itself is written using the Buddy-128 assembler, so it is
| |
| recommended that applications be written in this also. User programs
| |
| for ACE have a very simple structure. Here is the standard "hello,
| |
| world" example program written in Buddy assembler for ACE:
| |
|
| |
| -----=-----
| |
| .seq acehead.s
| |
| .org aceAppAddress
| |
| .obj "@0:hello"
| |
|
| |
| jmp main
| |
| .byte aceID1,aceID2,aceID3
| |
|
| |
| main = *
| |
| lda #<helloMsg
| |
| ldy #>helloMsg
| |
| sta zp+0
| |
| sty zp+1
| |
| lda #<helloMsgEnd-helloMsg
| |
| ldy #>helloMsgEnd-helloMsg
| |
| ldx #stdout
| |
| jsr write
| |
| rts
| |
|
| |
| helloMsg = *
| |
| .asc "Hello, cruel world."
| |
| .byte 13
| |
| helloMsgEnd = *
| |
| -----=-----
| |
|
| |
| This would normally be put into a file called "hello.s". The ".s"
| |
| extension means that this is an assembler file (a la Unix). The first
| |
| thing this program does is include the "acehead.s" file. This is the
| |
| Buddy assembler file that contains the header information declarations
| |
| required to access the ACE system interface. The next line gives the
| |
| start address to start assembling to; it must be "aceAppAddress", which
| |
| is the address that ACE will load the program at. The next line is a
| |
| directive to the assembler to write the executable code to a
| |
| Commodore-DOS "PRG" file named "hello". This will be the command to
| |
| enter at the ACE shell prompt.
| |
|
| |
| The next six bytes of object code (which are the first six bytes of a
| |
| program) describe the header required by ACE programs. The first three
| |
| bytes must be a JMP to the main routine of the program. The next three
| |
| bytes must have the values "aceID1", "aceID2", and "aceID3",
| |
| respectively. And that's all there is to it. The rest of the program
| |
| can be organized however you want it to be.
| |
|
| |
| In this example, we set up the arguments for the "write" system call to
| |
| print the string "Hello, cruel world." plus a carriage return to
| |
| standard output. Note that this string does not need a terminating null
| |
| ($00) character since the write call takes a buffer length. The program
| |
| then returns to its calling environment via an RTS. This will cause an
| |
| implied "exit(0)" to be performed by the system, returning to the parent
| |
| program.
| |
|
| |
| Although this program does not take advantage of this, an application
| |
| program may use zero-page locations $0002 through $007f for storage
| |
| without fear of having the storage trodden upon by the system. Also,
| |
| the processor stack may be used from the point it was at upon entry to
| |
| your program all the way down to the bottom. I will be doing something
| |
| about ensuring there is always enough processor space for an application
| |
| to use in the future, but for now, all applications have to share the
| |
| single page of processor stack storage.
| |
|
| |
| Finally, an application program starts at location "aceAppAddress" (plus
| |
| six) and is allowed to use memory all the way up to one byte less than
| |
| the address pointed to by "aceMemTop" for its own purposes. Currently,
| |
| this amount of space is on the order of magnitude of about 24K. This
| |
| will be increased in the future.
| |
|
| |
| Application programs are not to access I/O features or even change the
| |
| current memory configuration during execution. All I/O and unusual
| |
| contortions must be performed by ACE system calls; otherwise, we could
| |
| end up in as bad a shape as MESS-DOS.
| |
|
| |
| 4. CONCLUSION
| |
|
| |
| Cool, eh?
| |
| =============================================================================
| |
| Looking Ahead: (Learned my lesson about "In The Next Issue" :-) (re: the
| |
| mouse article etc....) )
| |
|
| |
| Either a Multi-Tasking article or a look at the Internals of Ace.
| |
|
| |
| More graphics techniques.
| |
|
| |
| Answers to the Trivia in this issue.
| |
|
| |
| More articles and other information.
| |
|
| |
| (Sorry that this is a little bit more vague than last time - Just have some
| |
| authors actually finding real jobs, and others that forgot to include what
| |
| they were going to do for the next issue.)
| |
| </pre> | | </pre> |