magazines:chacking7
no way to compare when less than two revisions
Differences
This shows you the differences between two versions of the page.
— | magazines:chacking7 [2015-04-17 04:34] (current) – created - external edit 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | < | ||
+ | ######## | ||
+ | ################## | ||
+ | ###### | ||
+ | ##### | ||
+ | ##### #### #### ## ##### #### | ||
+ | ##### ## ## #### ## ## | ||
+ | ##### | ||
+ | ##### ## ## ######## | ||
+ | ##### #### #### #### #### ##### #### | ||
+ | ##### ## | ||
+ | ###### | ||
+ | ################## | ||
+ | ######## | ||
+ | ----------------------------------------------------------------------------- | ||
+ | Editor' | ||
+ | by Craig Taylor (duck@pembvax1.pembroke.edu) | ||
+ | |||
+ | This net-magazine is still alive after over two years suprising even | ||
+ | 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 | ||
+ | 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, | ||
+ | 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, | ||
+ | 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 " | ||
+ | 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/ | ||
+ | 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/ | ||
+ | and via a mailserver which documentation can be obtained by sending | ||
+ | mail to " | ||
+ | " | ||
+ | |||
+ | ============================================================================= | ||
+ | |||
+ | NOTICE: Permission is granted to re-distribute this " | ||
+ | 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 | ||
+ | " | ||
+ | |||
+ | ============================================================================= | ||
+ | </ | ||
+ | ====== 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' | ||
+ | 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' | ||
+ | |||
+ | 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' | ||
+ | |||
+ | This article explains the complete system interface for the ACE-128/64 | ||
+ | computing environment. | ||
+ | developing software to run on top of the ACE kernel. | ||
+ | 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. | ||
+ | 1982, a brand new Vic-20 with some game cartridges. | ||
+ | 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. | ||
+ | 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. | ||
+ | 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. | ||
+ | an installment of Commodore Trivia. | ||
+ | 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' | ||
+ | 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. | ||
+ | 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' | ||
+ | implemented, | ||
+ | |||
+ | 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' | ||
+ | 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. | ||
+ | nonetheless, | ||
+ | |||
+ | A $000) Personal Electronic Transactor | ||
+ | Since the acronym was made up before the expansion, the following | ||
+ | are also valid: | ||
+ | | ||
+ | Personal Electronic Translator | ||
+ | Peddle' | ||
+ | | ||
+ | Q $001) Commodore planned to manufacture a successor series to the | ||
+ | successful Commodore 64 home computer. | ||
+ | be Business machines. | ||
+ | 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, | ||
+ | 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' | ||
+ | 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. | ||
+ | number. | ||
+ | | ||
+ | Q $01E) Some formats of CP/M write disks using the MFM format. | ||
+ | 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. | ||
+ | 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. | ||
+ | go, and you'll be locked into Cyberspace. | ||
+ | |||
+ | 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 " | ||
+ | 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 " | ||
+ | |||
+ | 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?" | ||
+ | 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' | ||
+ | (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 " | ||
+ | |||
+ | 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, " | ||
+ | (currently going to Pembroke State University) hence | ||
+ | " | ||
+ | computer needs to use to know how to seperate the computer name and the | ||
+ | user name is " | ||
+ | |||
+ | 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' | ||
+ | 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" | ||
+ | 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: | ||
+ | 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 | ||
+ | " | ||
+ | |||
+ | 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 | ||
+ | " | ||
+ | second group of letters stand for the type of newsgroup "sys for system, | ||
+ | binaries for binaries etc..." | ||
+ | " | ||
+ | |||
+ | 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 | ||
+ | " | ||
+ | programs available that will let you take the " | ||
+ | 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' | ||
+ | many people chatter or " | ||
+ | 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, | ||
+ | in shareware and public-domain software, know the " | ||
+ | before they exist all for free? (Or at least, only for what your | ||
+ | " | ||
+ | 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' | ||
+ | numerous FTP sites out there in InterNet land - one of the best | ||
+ | currently available for the Commodore computers is that of R.Knop' | ||
+ | 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. | ||
+ | me know and it will be deleted. | ||
+ | tell me so that it can be added. | ||
+ | ----- | ||
+ | |||
+ | To use this list on a UNIX system, just type 'ftp < | ||
+ | < | ||
+ | your login, and your E-mail address for the password. | ||
+ | and list directories with ' | ||
+ | files to your system using ' | ||
+ | if you are getting a program, or ' | ||
+ | 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. | ||
+ | |||
+ | Enjoy! | ||
+ | ----- | ||
+ | |||
+ | Host sol.cs.ruu.nl | ||
+ | Last updated 00:39 4 Sep 1993 | ||
+ | Location: / | ||
+ | DIRECTORY rwxr-xr-x | ||
+ | Location: / | ||
+ | FILE rw-r--r-- | ||
+ | |||
+ | Host uceng.uc.edu | ||
+ | Last updated 04:38 6 Sep 1993 | ||
+ | Location: / | ||
+ | FILE rw-r--r-- | ||
+ | Location: / | ||
+ | FILE rw-r--r-- | ||
+ | FILE rw-r--r-- | ||
+ | FILE rw-r--r-- | ||
+ | FILE rw-r--r-- | ||
+ | FILE rw-r--r-- | ||
+ | Location: / | ||
+ | FILE r--r--r-- | ||
+ | |||
+ | Host aix370.rrz.uni-koeln.de | ||
+ | Location: / | ||
+ | DIRECTORY rwxrwxr-x | ||
+ | |||
+ | Host ftp.csv.warwick.ac.uk | ||
+ | Last updated 00:00 18 Jan 1994 | ||
+ | Location: /pub/c64 | ||
+ | FILE rw-r--r-- | ||
+ | FILE rw-r--r-- | ||
+ | FILE rw-r--r-- | ||
+ | FILE rw-r--r-- | ||
+ | FILE rw-r--r-- | ||
+ | FILE rw-r--r-- | ||
+ | FILE rw-r--r-- | ||
+ | Descriptions: | ||
+ | ============ | ||
+ | backgamm - Backgammon board game | ||
+ | chequebo - Cheque Book Organiser, written in basic with UK pound sign as | ||
+ | | ||
+ | countdow - LOAD" | ||
+ | draughts - Draughts board game. | ||
+ | loader | ||
+ | whitewas - Colour squares board game. | ||
+ | Location: /tmp/c64 | ||
+ | > | ||
+ | > | ||
+ | |||
+ | Host clover.csv.warwick.ac.uk | ||
+ | Last updated 13:29 27 Sep 1993 | ||
+ | Location: /pub/c64 | ||
+ | FILE rw-r--r-- | ||
+ | FILE rw-r--r-- | ||
+ | |||
+ | Host nexus.yorku.ca | ||
+ | Last updated 00:00 21 Dec 1993 | ||
+ | Location: / | ||
+ | FILE rw-r--r-- | ||
+ | > | ||
+ | |||
+ | Host rigel.acs.oakland.edu | ||
+ | Last updated 01:42 3 Sep 1993 | ||
+ | Location: /pub2/cpm | ||
+ | DIRECTORY rwxr-xr-x | ||
+ | DIRECTORY rwxr-xr-x | ||
+ | Location: / | ||
+ | FILE rw-r--r-- | ||
+ | FILE rw-r--r-- | ||
+ | FILE rw-r--r-- | ||
+ | FILE rw-r--r-- | ||
+ | FILE rw-r--r-- | ||
+ | |||
+ | Host oak.oakland.edu | ||
+ | Last updated 00:00 18 Dec 1993 | ||
+ | Location: /pub2/cpm | ||
+ | > | ||
+ | |||
+ | Host src.doc.ic.ac.uk | ||
+ | Location: / | ||
+ | DIRECTORY rwxr-xr-x | ||
+ | Location: / | ||
+ | DIRECTORY rwxr-xr-x | ||
+ | DIRECTORY rwxr-xr-x | ||
+ | Location: / | ||
+ | DIRECTORY rwxr-xr-x | ||
+ | Location: / | ||
+ | DIRECTORY rwxr-xr-x | ||
+ | |||
+ | Host tupac-amaru.informatik.rwth-aachen.de | ||
+ | Last updated 04:59 7 Oct 1992 | ||
+ | Location: / | ||
+ | DIRECTORY rwxr-xr-x | ||
+ | DIRECTORY rwxr-xr-x | ||
+ | |||
+ | Host wuarchive.wustl.edu | ||
+ | Last updated 02:40 23 May 1993 | ||
+ | Location: / | ||
+ | FILE rw-rw-r-- | ||
+ | FILE rw-rw-r-- | ||
+ | Location: / | ||
+ | DIRECTORY rwxr-xr-x | ||
+ | DIRECTORY rwxr-xr-x | ||
+ | |||
+ | Host watsun.cc.columbia.edu | ||
+ | Last updated 02:07 8 Sep 1993 | ||
+ | Location: / | ||
+ | DIRECTORY rwxrwxr-x | ||
+ | Location: /kermit/bin | ||
+ | |||
+ | Host cs.columbia.edu | ||
+ | Last updated 01:29 12 Sep 1993 | ||
+ | Location: / | ||
+ | FILE rw-rw-r-- | ||
+ | FILE rw-rw-r-- | ||
+ | FILE rw-rw-r-- | ||
+ | FILE rw-rw-r-- | ||
+ | FILE rw-rw-r-- | ||
+ | FILE rw-rw-r-- | ||
+ | FILE rw-rw-r-- | ||
+ | |||
+ | Host plaza.aarnet.edu.au | ||
+ | Last updated 00:00 28 Dec 1993 | ||
+ | Location: / | ||
+ | FILE r--r--r-- | ||
+ | FILE r--r--r-- | ||
+ | FILE r--r--r-- | ||
+ | FILE r--r--r-- | ||
+ | FILE r--r--r-- | ||
+ | > | ||
+ | > | ||
+ | |||
+ | Host flubber.cs.umd.edu | ||
+ | Last updated 00:00 03 Jan 1994 | ||
+ | Location: / | ||
+ | FILE rw-r--r-- | ||
+ | -------------------------------- | ||
+ | |||
+ | Host f.ms.uky.edu (128.163.128.6) | ||
+ | Last updated 00:00 28 Dec 1993 | ||
+ | Location: / | ||
+ | |||
+ | Host ftp.funet.fi (128.214.6.100) | ||
+ | Last updated 06:11 22 Mar 1993 | ||
+ | Location: / | ||
+ | DIRECTORY rwxrwxr-x | ||
+ | Location: /pub/misc | ||
+ | DIRECTORY rwxrwxr-x | ||
+ | Location: /pub/kermit | ||
+ | DIRECTORY rwxrwxr-x | ||
+ | Location: / | ||
+ | FILE rw-rw-r-- | ||
+ | FILE rw-rw-r-- | ||
+ | /pub/cbm | ||
+ | |||
+ | Host nic.switch.ch | ||
+ | Last updated 00:39 31 Aug 1993 | ||
+ | Location: / | ||
+ | |||
+ | Host gmdzi.gmd.de | ||
+ | Last updated 01:08 1 Aug 1993 | ||
+ | Location: / | ||
+ | FILE rw-rw-r-- | ||
+ | |||
+ | Host micros.hensa.ac.uk | ||
+ | Location /kermit | ||
+ | DIRECTORY rwxr-x--- | ||
+ | |||
+ | Host wilbur.stanford.edu | ||
+ | Location / | ||
+ | DIRECTORY rwxr-xr-x | ||
+ | |||
+ | Host syrinx.umd.edu (128.8.2.114) | ||
+ | Last updated 00:00 28 Dec 1993 | ||
+ | Location: / | ||
+ | |||
+ | Host tolsun.oulu.fi (130.231.96.16) | ||
+ | Last updated 01:53 6 Sep 1993 | ||
+ | Location: /pub | ||
+ | DIRECTORY rwxr-xr-x | ||
+ | Location: /incoming | ||
+ | DIRECTORY --------- | ||
+ | / | ||
+ | /pub/c64 | ||
+ | > | ||
+ | > | ||
+ | > | ||
+ | >/ | ||
+ | |||
+ | Host ccosun.caltech.edu (131.215.139.2) | ||
+ | Last updated 00:00 31 JAN 1994 | ||
+ | Location: /pub/rknop | ||
+ | Location: / | ||
+ | > 64/128 programs can be found within directories according to | ||
+ | > function. | ||
+ | |||
+ | Host ucsd.edu (128.54.16.1) | ||
+ | Last updated 04:46 6 Sep 1993 | ||
+ | Location: / | ||
+ | DIRECTORY rwxr-xr-x | ||
+ | |||
+ | Host cs.dal.ca | ||
+ | Last updated 01:36 12 Sep 1993 | ||
+ | Location: / | ||
+ | DIRECTORY rwxrwxr-x | ||
+ | | ||
+ | |||
+ | Host ccnga.uwaterloo.ca | ||
+ | Last updated 00:00 01 Jan 1994 | ||
+ | Location: / | ||
+ | > 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/ | ||
+ | |||
+ | 72560.3467@CompuServe.COM | ||
+ | ============================================================================= | ||
+ | </ | ||
+ | ====== Hiding kilobytes ====== | ||
+ | < | ||
+ | by Marko M" | ||
+ | |||
+ | 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. | ||
+ | |||
+ | |||
+ | _Memory management_ | ||
+ | |||
+ | The Commodore 64 has access to more memory than its processor can | ||
+ | directly handle. This is possible by banking the memory. There are | ||
+ | five user configurable inputs that affect the banking. Three of them | ||
+ | can be controlled by program, and the rest two serve as control lines | ||
+ | on the memory expansion port. | ||
+ | |||
+ | The 6510 MPU has an integrated I/O port with six I/O lines. This | ||
+ | port is accessed through the memory locations 0 and 1. The location 0 | ||
+ | is the Data Direction Register for the Peripheral data Register, which | ||
+ | is mapped to the other location. When a bit in the DDR is set, the | ||
+ | corresponding PR bit controls the state of a corresponding Peripheral | ||
+ | line as an output. When it is clear, the state of the Peripheral line | ||
+ | is reflected by the Peripheral register. The Peripheral lines are | ||
+ | numbered from 0 to 5, and they are mapped to the DDR and PR bits 0 - 5, | ||
+ | respectively. The 8502 processor, which is used in the Commodore 128, | ||
+ | has seven Peripheral lines in its I/O port. The seventh line is connected | ||
+ | to the Caps lock or ASC/CC key. | ||
+ | |||
+ | The I/O lines have the following functions: | ||
+ | |||
+ | | ||
+ | | ||
+ | out P5 | ||
+ | in | ||
+ | out P3 | ||
+ | out P2 | ||
+ | out P1 HIRAM | ||
+ | out P0 LORAM | ||
+ | |||
+ | The default value of the DDR register is $2F, so all lines except | ||
+ | Cassette sense are outputs. The default PR value is $37 (Datassette | ||
+ | motor stopped, and all three memory management lines high). | ||
+ | |||
+ | Like most chips in the Commodore 64, the 6510 MPU uses the NMOS | ||
+ | (N-channel metal oxide semiconductor) technology. The NMOS switches | ||
+ | produce strong logical ' | ||
+ | is the PMOS (P-channel metal oxide semiconductor) technology, which | ||
+ | cannot pull strong signals low, but is able to drive them high. The CMOS | ||
+ | technology (complementary metal oxide semiconductor), | ||
+ | these two technologies, | ||
+ | |||
+ | Because most integrated circuits in the C64 use the NMOS technology, | ||
+ | all hardware lines that are not outputs are driven to +5 volts with a | ||
+ | weak current. This is usually accomplished by pull-up resistors, large | ||
+ | resistances between the hardware lines and the +5 volt power supply | ||
+ | line. The resistors can be inside a chip or on the printed circuit | ||
+ | board. This allows any NMOS or CMOS chip to drive the line to the | ||
+ | desired state (low or high voltage level). | ||
+ | |||
+ | The difference between an input and an output is that an output uses | ||
+ | more current to drive the signal to the desired level. An input and an | ||
+ | output outputting logical ' | ||
+ | chip. But if a chip is trying to drive a signal to ground level, it | ||
+ | needs more current to sink an output than an input. You can even use | ||
+ | outputs as inputs, i.e. read them in your program. | ||
+ | |||
+ | You can use this feature to distinquish between the left | ||
+ | shift and the shift lock keys, although they are connected | ||
+ | to same hardware lines. The shift lock key has smaller | ||
+ | resistance than the left shift. If you make both CIA 1 | ||
+ | ports to outputs (write $FF to $DC03 and $DC01) prior | ||
+ | reading the left shift key, only shift lock can change the | ||
+ | values you read from CIA 1 port B ($DC01).) | ||
+ | |||
+ | So, if you turn any memory management line to input, the external | ||
+ | pull-up resistors will make it look like it is outputting logical | ||
+ | ' | ||
+ | upon startup: Pulling the -RESET line low resets all Peripheral lines | ||
+ | to inputs, thus driving all three processor-driven memory management | ||
+ | lines high. | ||
+ | |||
+ | The two remaining memory management lines are -EXROM and -GAME on | ||
+ | the cartridge port. Each line has a pull-up resistor, so the lines are | ||
+ | ' | ||
+ | two lines prior to selecting the C64 mode, provided that you write the | ||
+ | mode switch routine yourself.) | ||
+ | |||
+ | Even though the memory banking has been implemented with a 82S100 | ||
+ | Programmable _Logic_ Array, there is only one control line that seems | ||
+ | to behave logically at first sight, the -CHAREN line. It is mostly | ||
+ | used to choose between I/O address space and the character generator | ||
+ | ROM. The following memory map introduces the oddities of -CHAREN and | ||
+ | the other memory management lines. It is based on the memory maps in | ||
+ | the Commodore 64 Programmer' | ||
+ | errors and inaccuracies have been corrected. | ||
+ | |||
+ | The leftmost column of the table contains addresses in hexadecimal | ||
+ | notation. The columns aside it introduce all possible memory | ||
+ | configurations. The default mode is on the left, and the absolutely | ||
+ | most rarely used Ultimax game console configuration is on the right. | ||
+ | (There have been at least two Ultimax cartridges on the market.) Each | ||
+ | memory configuration column has one or more four-digit binary numbers | ||
+ | as a title. The bits, from left to right, represent the state of the | ||
+ | -LORAM, -HIRAM, -GAME and -EXROM lines, respectively. The bits whose | ||
+ | state does not matter are marked with " | ||
+ | Ultimax video game configuration is active (the -GAME line is shorted | ||
+ | to ground, -EXROM kept high), the -LORAM and -HIRAM lines have no effect. | ||
+ | |||
+ | |||
+ | default | ||
+ | 1111 101x 1000 011x 001x 1110 0100 1100 xx01 | ||
+ | 00x0 | ||
+ | 10000 | ||
+ | ----------------------------------------------------------------------------- | ||
+ | F000 | ||
+ | Kernal | ||
+ | E000 | ||
+ | ----------------------------------------------------------------------------- | ||
+ | | ||
+ | ----------------------------------------------------------------------------- | ||
+ | | ||
+ | ----------------------------------------------------------------------------- | ||
+ | B000 | ||
+ | BASIC | ||
+ | A000 | ||
+ | ----------------------------------------------------------------------------- | ||
+ | 9000 | ||
+ | RAM | ||
+ | 8000 | ||
+ | ----------------------------------------------------------------------------- | ||
+ | 7000 | ||
+ | |||
+ | 6000 | ||
+ | RAM | ||
+ | 5000 | ||
+ | |||
+ | 4000 | ||
+ | ----------------------------------------------------------------------------- | ||
+ | | ||
+ | |||
+ | | ||
+ | |||
+ | 1000 | ||
+ | ----------------------------------------------------------------------------- | ||
+ | | ||
+ | ----------------------------------------------------------------------------- | ||
+ | |||
+ | *) Internal memory does not respond to write accesses to these areas. | ||
+ | |||
+ | |||
+ | Legend: Kernal | ||
+ | |||
+ | IO/C D000-DFFF | ||
+ | generator ROM, selected by -CHAREN. | ||
+ | If the CHAREN bit is clear, | ||
+ | the character generator ROM is | ||
+ | chosen. If it is set, the | ||
+ | I/O chips are accessible. | ||
+ | |||
+ | IO/ | ||
+ | selected by -CHAREN. | ||
+ | If the CHAREN bit is clear, | ||
+ | the character generator ROM is | ||
+ | chosen. If it is set, the | ||
+ | internal RAM is accessible. | ||
+ | |||
+ | I/O | ||
+ | The -CHAREN line has no effect. | ||
+ | |||
+ | BASIC | ||
+ | |||
+ | ROMH A000-BFFF or External ROM with the -ROMH line | ||
+ | E000-FFFF | ||
+ | |||
+ | ROML 8000-9FFF | ||
+ | connected to its -CS line. | ||
+ | |||
+ | RAM | ||
+ | |||
+ | - | ||
+ | A000-CFFF | ||
+ | do not detect any memory accesses | ||
+ | to this area except the VIC-II' | ||
+ | DMA and memory refreshes. | ||
+ | |||
+ | NOTE: | ||
+ | (Kernal, BASIC, CHAROM, ROML, ROMH), the data will get | ||
+ | " | ||
+ | |||
+ | For this reason, you can easily copy data from ROM to RAM, | ||
+ | without any bank switching. But implementing external | ||
+ | memory expansions without DMA is very hard, as you have to | ||
+ | use the Ultimax memory configuration, | ||
+ | written both to internal and external RAM. | ||
+ | |||
+ | However, this is not true for the Ultimax game | ||
+ | configuration. In that mode, the internal RAM ignores all | ||
+ | memory accesses outside the area $0000-$0FFF, | ||
+ | performed by the VIC, and you can write to external memory | ||
+ | at $1000-$CFFF and $E000-$FFFF, | ||
+ | the contents of the internal RAM. | ||
+ | |||
+ | |||
+ | _A note concerning the I/O area_ | ||
+ | |||
+ | The I/O area is divided as follows: | ||
+ | |||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | As you can see, the address ranges for the chips are much larger | ||
+ | than required. Because of this, you can access the chips through | ||
+ | multiple memory areas. The VIC-II appears in its window every $40 | ||
+ | addresses. For instance, the addresses $D040 and $D080 are both mapped | ||
+ | to the Sprite 0 X co-ordinate register. The SID has one register | ||
+ | selection line less, thus it appears at every $20 bytes. The CIA | ||
+ | chips have only 16 registers, so there are 16 copies of each in their | ||
+ | memory area. | ||
+ | |||
+ | However, you should not use other addresses than those specified by | ||
+ | Commodore. For instance, the Commodore 128 mapped its additional I/O | ||
+ | chips to this same memory area, and the SID responds only to the | ||
+ | addresses D400-D4FF, also when in C64 mode. And the Commodore 65, | ||
+ | which unfortunately did not make its way to the market, could narrow | ||
+ | the memory window reserved for the MOS 6569/6567 VIC-II (or CSG 4567 | ||
+ | VIC-III in that machine). | ||
+ | |||
+ | |||
+ | _The video chip_ | ||
+ | |||
+ | The MOS 6567/6569 VIC-II Video Interface Controller has access to | ||
+ | only 16 kilobytes at a time. To enable the VIC-II to access the whole | ||
+ | 64 kB memory space, the main memory is divided to four banks of 16 kB | ||
+ | each. The lines PA0 and PA1 of the second CIA are the inverse of the | ||
+ | virtual VIC-II address lines VA14 and VA15, respectively. To select a | ||
+ | VIC-II bank other than the default, you must program the CIA lines to | ||
+ | output the desired bit pair. For instance, the following code selects | ||
+ | the memory area $4000-$7FFF (bank 1) for the video controller: | ||
+ | |||
+ | LDA $DD02 ; Data Direction Register A | ||
+ | ORA #$03 ; Set pins PA0 and PA1 to outputs | ||
+ | STA $DD02 | ||
+ | LDA $DD00 | ||
+ | AND #$FC ; Mask the lowmost bit pair off | ||
+ | ORA #$02 ; Select VIC-II bank 1 (the inverse of binary 01 is 10) | ||
+ | STA $DD00 | ||
+ | |||
+ | Why should you set the pins to outputs? Hardware RESET resets all | ||
+ | I/O lines to inputs, and thanks to the CIA's internal pull-up | ||
+ | resistors, the inputs actually output logical high voltage level. So, | ||
+ | upon -RESET, the video bank 0 is selected automatically, | ||
+ | Kernals could leave it uninitialized. | ||
+ | |||
+ | Note that the VIC-II always fetches its information from the | ||
+ | internal RAM, totally ignoring the memory configuration lines. There | ||
+ | is only one exception to this rule: The character generator ROM. | ||
+ | Unless the Ultimax mode is selected, VIC-II " | ||
+ | ROM in the memory areas 1000-1FFF and 9000-9FFF. If the Ultimax | ||
+ | configuration is active, the VIC-II will fetch all data from the | ||
+ | internal RAM. | ||
+ | |||
+ | |||
+ | _An application: | ||
+ | |||
+ | If you are making a memory resident program and want to make it as | ||
+ | invisible to the system as possible, probably the best method is | ||
+ | keeping most of your code under the I/O area (in the RAM at | ||
+ | $D000-$DFFF). This area is very safe, since programs utilizing it are | ||
+ | rare, since they are very difficult to implement and to debug. You | ||
+ | need only a short routine in the normally visible RAM that pushes the | ||
+ | current value of the processor' | ||
+ | RAM on to $D000-$DFFF and jumps to this area. Returning from the | ||
+ | $D000-$DFFF area is possible even without any routine in the normally | ||
+ | visible RAM area. Just write an RTS or an RTI to an I/O register and | ||
+ | return through it. | ||
+ | |||
+ | But what if your program needs to use I/O? And how can you write the | ||
+ | return instruction to an I/O register while the I/O area is switched | ||
+ | off? You need a swap area for your program in normally visible memory. | ||
+ | The first thing your routine at $D000-$DFFF does is copying the I/O | ||
+ | routines (or the whole program) to normally visible memory, swapping | ||
+ | the bytes. For instance, if your I/O routines are initially being | ||
+ | stored at $D200-$D3FF, | ||
+ | contents of $C000-$C1FF. Now you can call the I/O routines from your | ||
+ | routine at $D000-$DFFF, | ||
+ | temporarily on to access the I/O chips. And right before exiting your | ||
+ | program at $D000-$DFFF swaps the old contents of that I/O routine area | ||
+ | in, e.g. exchanges the memory areas $D200-$D3FF and $C000-$C1FF | ||
+ | again. | ||
+ | |||
+ | What I/O registers can you use for the return instruction? | ||
+ | basically two alternatives: | ||
+ | serial port register. The VIC registers are easiest to use, as they | ||
+ | act precisely like memory places: you can easily write the desired | ||
+ | value to a register. But the CIA register is usually better, as | ||
+ | changing the VIC registers might change the screen layout. | ||
+ | |||
+ | However, also the SP register has some drawbacks: If the machine' | ||
+ | CNT1 and CNT2 lines are connected to a frequency source, you must stop | ||
+ | either CIA's Timer A to use the SP register method. Normally the 1st | ||
+ | CIA's Timer A is the main hardware interrupt source. And if you use | ||
+ | the Kernal' | ||
+ | if you don't want to lose any CIA interrupts, you might want to know | ||
+ | that executing the RTS or RTI at SP register has the side effect of | ||
+ | reading the Interrupt Control Register, thus acknowledging an interrupt | ||
+ | that might have been waiting. | ||
+ | |||
+ | If you can't use either method, you can use either CIA's ToD seconds | ||
+ | or minutes or ToD alarm time for storing an RTI. Or, if you don't want | ||
+ | to alter any registers, use the VIC-II' | ||
+ | exiting, wait for appropriate raster line and trig the light pen latch | ||
+ | with CIA1's PB4 bit. However, this method assumes that the control | ||
+ | port 1's button/ | ||
+ | trigging the light pen, causing the light pen Y co-ordinate register | ||
+ | ($D014) to be $40 or $60, you have more than half a frame time to | ||
+ | restore the state of the I/O chips and return through the register. | ||
+ | |||
+ | You can also use the SID to store an RTI or RTS command. How is this | ||
+ | possible, you might ask. After all, the chip consists of read only or | ||
+ | write only registers. However, there are two registers that can be | ||
+ | controlled by program, the envelope generator and oscillator outputs | ||
+ | of the third voice. This method requires you to change the frequency | ||
+ | of voice 3 and to select a waveform for it. This will affect on the | ||
+ | voice output by turning the voice 3 off, but who would keep the voice | ||
+ | 3 producing a tone while calling an operating system routine? | ||
+ | |||
+ | Also keep in mind that the user could press RESTORE while the Kernal | ||
+ | ROM and I/O areas are disabled. You could write your own non-maskable | ||
+ | interrupt (NMI) handler (using the NMI vector at $FFFA), but a fast | ||
+ | loader that uses very tight timing would still stop working if the | ||
+ | user pressed RESTORE in the middle of a data block transfer. So, to | ||
+ | make a robust program, you have to disable NMI interrupts. But how is | ||
+ | this possible? They are Non-Maskable after all. The NMI interrupt is | ||
+ | edge-sensitive, | ||
+ | line drops from +5V to ground. To disable the interrupt, simply cause | ||
+ | an NMI with CIA2's timer, but don't read the Interrupt Control | ||
+ | register. If you need to read $DD0D in your program, you must add a | ||
+ | NMI handler just in case the user presses RESTORE. And don't forget to | ||
+ | raise the -NMI line upon exiting the program. | ||
+ | key does not work until the user issues a -RESET or reads the ICR | ||
+ | register explicitly. (The Kernal does not read $DD0D, unless it is | ||
+ | handling an interrupt.) This can be done automatically by the two | ||
+ | following SP register examples due to one of the 6510's undocumented | ||
+ | features (refer to the descriptions of RTS and RTI below). | ||
+ | |||
+ | ; Returning via VIC sprite 7 X co-ordinate register | ||
+ | |||
+ | Initialization: | ||
+ | LDA #$60 | ||
+ | STA $D015 ; Write RTS to VIC register $15. | ||
+ | |||
+ | Exiting: | ||
+ | ; $12. You have multiple alternatives, | ||
+ | ; appears in memory at $D000+$40*n, | ||
+ | |||
+ | PLA ; Pull the saved 6510 I/O register state from stack | ||
+ | STA $01 ; Restore original memory bank configuration | ||
+ | ; Now the processor fetches the RTS command from the | ||
+ | ; VIC register $15. | ||
+ | |||
+ | |||
+ | ; Returning via CIA 2's ToD or ToD alarm seconds register | ||
+ | |||
+ | Initialization: | ||
+ | LDA # | ||
+ | STA $DD08 ; Set ToD tenths of seconds | ||
+ | ; (clear it so that the seconds register | ||
+ | ; would not overflow) | ||
+ | ; If ToD alarm register is selected, this | ||
+ | ; instruction will be unnecessary. | ||
+ | STA $DD09 ; Set ToD seconds | ||
+ | LDA $DD0B ; Read ToD hours (freeze ToD display) | ||
+ | |||
+ | Exiting: | ||
+ | ; $6. As the CIA 2 appears in memory at $DD00+$10*n, | ||
+ | ; where 0< | ||
+ | PLA | ||
+ | STA $01 ; Restore original memory bank configuration | ||
+ | ; Now the processor fetches the RTS command from | ||
+ | ; the CIA 2 register $9. | ||
+ | |||
+ | |||
+ | ; Returning via CIA 2's SP register (assuming that CNT2 is stable) | ||
+ | |||
+ | Initialization: | ||
+ | LDA $DD0E ; CIA 2's Control Register A | ||
+ | AND #$BF ; Set Serial Port to input | ||
+ | STA $DD0E ; (make the SP register to act as a memory place) | ||
+ | LDA #$60 | ||
+ | STA $DD0C ; Write RTS to CIA 2 register $C. | ||
+ | |||
+ | Exiting: | ||
+ | ; $9. As the CIA 2 appears in memory at $DD00+$10*n, | ||
+ | ; where 0< | ||
+ | PLA | ||
+ | STA $01 ; Restore original memory bank configuration | ||
+ | ; Now the processor fetches the RTS command from | ||
+ | ; the CIA 2 register $C. | ||
+ | |||
+ | |||
+ | ; Returning via CIA 2's SP register, stopping the Timer A | ||
+ | ; and forcing SP2 and CNT2 to output | ||
+ | |||
+ | Initialization: | ||
+ | LDA $DD0E ; CIA 2's Control Register A | ||
+ | AND #$FE ; Stop Timer A | ||
+ | ORA #$40 ; Set Serial Port to output | ||
+ | STA $DD0E ; (make the SP register to act as a memory place) | ||
+ | LDA #$60 | ||
+ | STA $DD0C ; Write RTS to CIA register $C. | ||
+ | |||
+ | Exiting: | ||
+ | ; $9. As the CIA 2 appears in memory at $DD00+$10*n, | ||
+ | ; where 0< | ||
+ | PLA | ||
+ | STA $01 ; Restore original memory bank configuration | ||
+ | ; Now the processor fetches the RTS command from | ||
+ | ; the CIA 2 register $C. | ||
+ | |||
+ | ; Returning via SID oscillator 3 output register | ||
+ | |||
+ | Initialization: | ||
+ | LDA #$20 ; Select sawtooth waveform | ||
+ | STA $D412 ; but do not enable the sound | ||
+ | LDY #$00 ; Select frequency | ||
+ | STY $D40E ; (system clock)/ | ||
+ | LDA #$FF ; causing the OSC3 output to increment by one | ||
+ | STY $D40F ; every $10000/ | ||
+ | |||
+ | LDA #$0E | ||
+ | LDX #$60 | ||
+ | |||
+ | BIT $D41B ; Wait for the oscillator 3 output | ||
+ | BMI *-3 ; to be in the range | ||
+ | BVS *-5 ; $00-$3F. | ||
+ | BIT $D41B ; Wait for the oscillator 3 output | ||
+ | BVC *-3 ; to be at least $40. | ||
+ | |||
+ | STA $D40F ; Slow down the frequency to (system clock)/ | ||
+ | CPX $D41B ; Wait for the oscillator 3 | ||
+ | BNE *-3 ; output to reach $60 (RTS) | ||
+ | |||
+ | STY $D40F ; Reset the frequency of voice 3 | ||
+ | ; (stop the OSC3 register from increasing) | ||
+ | |||
+ | Exiting: | ||
+ | ; $18. As the SID appears in memory at $D400+$20*n, | ||
+ | ; where 0< | ||
+ | ; However, in C128 there are only eight alternatives, | ||
+ | ; as the SID is only at $D400-$D4FF. | ||
+ | |||
+ | PLA | ||
+ | STA $01 ; Restore original memory bank configuration | ||
+ | ; Now the processor fetches the RTS command from | ||
+ | ; the SID register $1B. | ||
+ | |||
+ | |||
+ | For instance, if you want to make a highly compatible fast loader, | ||
+ | make the ILOAD vector ($0330) point to the beginning of the stack | ||
+ | area. Remember that the BASIC interpreter uses the first bytes of | ||
+ | stack while converting numbers to text. A good address is $0120. | ||
+ | Robust programs practically never use so much stack that it could | ||
+ | corrupt this routine. Usually only crunched programs (demos and alike) | ||
+ | use all stack in the decompression phase. They also make use of the | ||
+ | $D000-$DFFF area. | ||
+ | |||
+ | This stack routine will jump to your routine at $D000-$DFFF, | ||
+ | described above. For performance' | ||
+ | loop to the swap area, e.g. $C000-$C1FF, | ||
+ | after doing the preliminary work. But what about files that load over | ||
+ | $C000-$C1FF? | ||
+ | machine? Not necessarily. If you copy those bytes to your swap area at | ||
+ | $D000-$DFFF, | ||
+ | the original $C000-$C1FF area. | ||
+ | |||
+ | If you want to make your program user-friendly, | ||
+ | initialization routine to the stack area as well, so that the user can | ||
+ | restore the fast loader by issuing a SYS command, rather than loading | ||
+ | it each time he has pressed RESET. | ||
+ | |||
+ | |||
+ | _An example: A "hello world" program_ | ||
+ | |||
+ | To help you in getting started, I have written a small example | ||
+ | program that echoes the famous message " | ||
+ | output (normally screen) using the Kernal' | ||
+ | the initialization routine has been run, the program can be started by | ||
+ | commanding SYS 300. I used the Commodore 128's machine language | ||
+ | monitor to put it up, but it was still pretty difficult to debug the | ||
+ | program. Here it is in uuencoded format: | ||
+ | |||
+ | begin 644 hello | ||
+ | M`0@+", | ||
+ | MA0%88*4!JBGX" | ||
+ | M8*4!2`D# | ||
+ | M2*D6C? | ||
+ | 5A`& | ||
+ | ` | ||
+ | end | ||
+ | |||
+ | In order to fully understand the operation of this program, you need | ||
+ | to know how the instructions RTI, RTS and PHA work. There is some work | ||
+ | going on to reverse engineer the NMOS 6502 microprocessor to large | ||
+ | extent, and it is now known for most instructions what memory places | ||
+ | they access during their execution and for what purpose. The internal | ||
+ | procedures haven' | ||
+ | descriptions should be easier to read anyway. | ||
+ | |||
+ | For curiosity, I quote here the description of all instructions that | ||
+ | use the stack. The descriptions of internal operations are yet | ||
+ | inaccurate, but the memory accesses have been verified with an | ||
+ | oscilloscope. I will mail copies the whole document upon request. When | ||
+ | finished, the document will be put on an FTP site. | ||
+ | |||
+ | JSR | ||
+ | |||
+ | # address R/W description | ||
+ | --- ------- --- ------------------------------------------------- | ||
+ | 1 PC | ||
+ | 2 PC | ||
+ | 3 $0100, | ||
+ | 4 $0100, | ||
+ | 5 $0100, | ||
+ | 6 PC | ||
+ | | ||
+ | |||
+ | |||
+ | RTS | ||
+ | |||
+ | # address R/W description | ||
+ | --- ------- --- ----------------------------------------------- | ||
+ | 1 PC | ||
+ | 2 PC | ||
+ | | ||
+ | 3 $0100, | ||
+ | 4 $0100, | ||
+ | 5 $0100, | ||
+ | 6 PC | ||
+ | |||
+ | |||
+ | BRK | ||
+ | |||
+ | # address R/W description | ||
+ | --- ------- --- ----------------------------------------------- | ||
+ | 1 PC | ||
+ | 2 PC | ||
+ | | ||
+ | 3 $0100, | ||
+ | 4 $0100, | ||
+ | 5 $0100, | ||
+ | set I flag | ||
+ | 6 | ||
+ | 7 | ||
+ | |||
+ | |||
+ | RTI | ||
+ | |||
+ | # address R/W description | ||
+ | --- ------- --- ----------------------------------------------- | ||
+ | 1 PC | ||
+ | 2 PC | ||
+ | | ||
+ | 3 $0100, | ||
+ | 4 $0100, | ||
+ | 5 $0100, | ||
+ | 6 $0100, | ||
+ | |||
+ | |||
+ | PHA, PHP | ||
+ | |||
+ | # address R/W description | ||
+ | --- ------- --- ----------------------------------------------- | ||
+ | 1 PC | ||
+ | 2 PC | ||
+ | | ||
+ | 3 $0100, | ||
+ | |||
+ | |||
+ | PLA, PLP | ||
+ | |||
+ | # address R/W description | ||
+ | --- ------- --- ----------------------------------------------- | ||
+ | 1 PC | ||
+ | 2 PC | ||
+ | | ||
+ | 3 $0100, | ||
+ | 4 $0100, | ||
+ | |||
+ | |||
+ | The example program consists of three parts. The first part | ||
+ | transfers the other parts to appropriate memory areas. The second part | ||
+ | is located in stack area (300-312), and it invokes the third part, the | ||
+ | main module. | ||
+ | |||
+ | The loader part ($0801-$08C7) is as follows: | ||
+ | |||
+ | 1993 SYS2061 | ||
+ | |||
+ | 080D SEI Disable interrupts. | ||
+ | 080E LDA $01 | ||
+ | 0810 PHA Store the state of the processor' | ||
+ | 0811 AND #$F8 | ||
+ | 0813 STA $01 Select 64 kB RAM memory configuration. | ||
+ | |||
+ | 0815 LDX #$0C Copy the invoking part to 300-312. | ||
+ | 0817 LDA $0830,X | ||
+ | 081A STA $012C,X | ||
+ | 081D DEX | ||
+ | 081E BPL $0817 | ||
+ | |||
+ | 0820 LDX #$8B Copy the main part to $DD64-$DDEE. | ||
+ | 0822 LDA $083C,X | ||
+ | 0825 STA $DD63,X | ||
+ | 0828 DEX | ||
+ | 0829 BNE $0822 | ||
+ | |||
+ | 082B PLA Restore original memory configuration. | ||
+ | 082C STA $01 | ||
+ | 082E CLI Enable interrupts. | ||
+ | 082F RTS Return. | ||
+ | |||
+ | The user invokes the following part by issuing SYS 300. This part | ||
+ | changes the memory configuration and jumps to the main part. | ||
+ | |||
+ | 012C LDA $01 | ||
+ | 012E TAX Store original memory configuration to X register. | ||
+ | 012F AND #$F8 | ||
+ | 0131 ORA #$04 | ||
+ | 0133 SEI Disable interrupts. | ||
+ | 0134 STA $01 Select 64 kB RAM memory configuration. | ||
+ | 0136 JMP $DDA4 Jump to the main part. | ||
+ | |||
+ | The main part actually consists of two parts. It may be a bit | ||
+ | complicated, | ||
+ | |||
+ | DDA4 TXA | ||
+ | DDA5 PHA Push original memory configuration on stack. | ||
+ | DDA6 LDA $FFFA | ||
+ | DDA9 PHA | ||
+ | DDAA LDA $FFFB | ||
+ | DDAD PHA Store the original values of $FFFA and $FFFB. | ||
+ | DDAE LDA #$16 | ||
+ | DDB0 STA $FFFA Set ($FFFA) to point to RTI. | ||
+ | DDB3 LDA #$C0 | ||
+ | DDB5 STA $FFFB | ||
+ | DDB8 JSR $DDDC Swap the auxiliary routines in. | ||
+ | DDBB JSR $C000 Disable NMI's and initialize CIA2. | ||
+ | DDBE PLA | ||
+ | DDBF STA $FFFB Restore original values to $FFFA and $FFFB. | ||
+ | DDC2 PLA | ||
+ | DDC3 STA $FFFA | ||
+ | DDC6 JSR $C01D Print the message. | ||
+ | DDC9 JSR $DDDC Swap the auxiliary routines out. | ||
+ | DDCC PLA | ||
+ | DDCD TAY Load original memory configuration to Y register. | ||
+ | DDCE LDA #$00 Push desired stack register value on stack | ||
+ | DDD0 PHA (clear all flags, especially the I flag). | ||
+ | DDD1 TSX | ||
+ | DDD2 INC $0102, | ||
+ | DDD5 BNE $DDDA (RTS preincrements it, but RTI does not.) | ||
+ | DDD7 INC $0103,X | ||
+ | DDDA STY $01 Restore original memory configuration. | ||
+ | |||
+ | (The 6510 fetches the next instruction from $DDDC, which is now | ||
+ | connected to the CIA2's register $C, the Serial Port register. | ||
+ | The initialization routine wrote an RTI to it. The processor also | ||
+ | reads from $DDDD as a side effect of the instruction fetch, | ||
+ | thus re-enabling NMI' | ||
+ | |||
+ | DDDC LDY #$3F | ||
+ | DDDE LDX $C000, | ||
+ | DDE1 LDA $DD64,Y | ||
+ | DDE4 STA $C000,Y | ||
+ | DDE7 TXA | ||
+ | DDE8 STA $DD64,Y | ||
+ | DDEB DEY | ||
+ | DDEC BPL $DDDE | ||
+ | DDEE RTS | ||
+ | |||
+ | C000 INC $01 Enable the I/O area. | ||
+ | C002 LDX #$81 | ||
+ | C004 STX $DD0D Enable Timer A interrupts of CIA2. | ||
+ | C007 LDX #$00 | ||
+ | C009 STX $DD05 | ||
+ | C00C INX | ||
+ | C00D STX $DD04 Prepare Timer A to count from 1 to 0. | ||
+ | C010 LDX #$DD | ||
+ | C012 STX $DD0E Cause an interrupt. | ||
+ | |||
+ | (The instruction sets SP to output, makes Timer A to count | ||
+ | system clock pulses, forces the CIA to load the initial value | ||
+ | to the counter, selects one-shot counting and starts the timer.) | ||
+ | |||
+ | C015 LDX #$40 | ||
+ | |||
+ | (The processor now jumps to the NMI handler ($C016), and | ||
+ | the SP register starts to act as a memory place.) | ||
+ | |||
+ | C017 STX $DD0C Write an RTI to Serial Port register. | ||
+ | C01A DEC $01 Disable the I/O area. | ||
+ | C01C RTS Return. | ||
+ | |||
+ | C01D LDA $01 | ||
+ | C01F PHA | ||
+ | C020 ORA #$03 | ||
+ | C022 STA $01 | ||
+ | C024 LDY #$0C Print the message. | ||
+ | C026 LDA $C033,Y | ||
+ | C029 JSR $FFD2 | ||
+ | C02C DEY | ||
+ | C02D BPL $C026 | ||
+ | C02F PLA | ||
+ | C030 STA $01 Restore the 64 kB memory configuration. | ||
+ | C032 RTS | ||
+ | |||
+ | C033 " | ||
+ | |||
+ | (The string is backwards in memory, since I don't want to | ||
+ | waste cycles in explicit comparisons. This method results in | ||
+ | more readable code than doing a forward loop with an index | ||
+ | value $100-(number of characters).) | ||
+ | |||
+ | This program is not excellent. It has the following bugs: | ||
+ | |||
+ | o The 6510's memory management lines P0 and P1 (LORAM and HIRAM, | ||
+ | | ||
+ | | ||
+ | This could be easily corrected by setting the P0 and P1 lines | ||
+ | to output in the beginning of the interfacing routine (300 - 312): | ||
+ | |||
+ | LDA $00 | ||
+ | ORA #$02 | ||
+ | STA $00 | ||
+ | |||
+ | o The program does not restore the original state of the CIA2 | ||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | o If the user redirected output to cassette or RS-232, interrupts | ||
+ | would be required. However, they are completely disabled. | ||
+ | |||
+ | o If a non-maskable interrupt occurs while the loader part is being | ||
+ | | ||
+ | main part, if an NMI is issued after disabling ROMs and I/O in | ||
+ | $0134 but before exchanging the contents of the memory places | ||
+ | $C016 and $DD7A. | ||
+ | |||
+ | |||
+ | _Freezer cartridges_ | ||
+ | |||
+ | There are many cartridges that let you to stop almost any program for | ||
+ | " | ||
+ | cartridges is the Action Replay VI made by Datel Electronics back in | ||
+ | 1989. The cartridge has 8 kilobytes RAM and 32 kilobytes ROM on board, | ||
+ | and it has a custom chip for fiddling with the C64 cartridge port | ||
+ | lines -EXROM, -GAME, -IRQ, -NMI and BA. | ||
+ | |||
+ | If the -NMI line is not asserted (the NMI interrupts are enabled), all | ||
+ | freezer cartridges should be able to halt any program. When the user | ||
+ | presses the " | ||
+ | dropping the BA line low. Then they switch some of their own ROM to | ||
+ | the $E000 - $FFFF block by selecting the UltiMax configuration with | ||
+ | the -EXROM and -GAME lines. After this, they assert the -NMI line and | ||
+ | release the BA line. After completing the current instruction, | ||
+ | processor will take the NMI interrupt and load the program counter | ||
+ | from the vector at $FFFA, provided that the NMI line was not asserted | ||
+ | already. | ||
+ | |||
+ | This approach is prone to many flaws. Firstly, if the processor is | ||
+ | executing a write instruction when the program is being halted, and if | ||
+ | the write occurred outside the area $0000 - $0FFF, the data would get | ||
+ | lost, if the UltiMax configuration was asserted too early. This can be | ||
+ | corrected to some extent by waiting at least two cycles after | ||
+ | asserting the BA line, as the processor will not stop during write | ||
+ | cycles. However, this is of no help if the processor has not gotten to | ||
+ | the write stage yet. | ||
+ | |||
+ | Secondly, if the instruction being executed is outside the area | ||
+ | $0000 - $0FFF, or if it accesses any data outside that area, the | ||
+ | processor will fetch either wrong parameters or incorrect data, or | ||
+ | both. If the instruction does not write anything, will only corrupt | ||
+ | one processor register. | ||
+ | |||
+ | Thirdly, if the NMI interrupts are disabled, pressing the " | ||
+ | button does not have any other immediate effect than leaving the | ||
+ | UltiMax mode asserted, which makes any system RAM outside the area | ||
+ | $0000 - $0FFF unavailable. It also forces the I/O area ($D000 - $DFFF) | ||
+ | on. If the program has any instructions or data outside the lowmost | ||
+ | four kilobytes, it will eventually jam, as that data will be something | ||
+ | else than the program expects. | ||
+ | |||
+ | One might except that reading from open address space should return | ||
+ | random bytes. But, in at least two C64's, the bytes read are mostly | ||
+ | $BD, which is the opcode for LDA absolute,X. So, if the processor has | ||
+ | a "good luck", it will happily execute only LDA $BDBD,X commands, and | ||
+ | it might survive to the cartridge ROM area without jamming. Or it | ||
+ | could eventually fetch a BRK and jump to the cartridge ROM via the | ||
+ | IRQ/BRK vector at $FFFE. The Action Replay VI has the familiar | ||
+ | autostart data in the beginning of both the ROML and ROMH blocks by | ||
+ | default, and that data could be interpreted as sensible commands. The | ||
+ | Action Replay VI was indeed able to freeze my test program, even | ||
+ | though I had covered its -RESET, -IRQ and -NMI lines with a piece of | ||
+ | tape, until I relocated the program to the first 4 kilobyte block. | ||
+ | |||
+ | |||
+ | _Building an unbeatable freezer circuit_ | ||
+ | |||
+ | As you can see, it is totally impossible to design a freezer cartridge | ||
+ | that freezes any program. If the program to be freezed has disabled | ||
+ | the NMI interrupts, and if its code runs mostly at $0000 - $0FFF or | ||
+ | $D000 - $DFFF, the computer will more probably hang than succeed in | ||
+ | freezing the program. | ||
+ | |||
+ | However, it is possible to make some internal modifications to a C64, | ||
+ | so that it can freeze literally any program. You need to expand your | ||
+ | machine to 256 kilobytes following the documents on ftp.funet.fi in | ||
+ | the / | ||
+ | computer so that all of the 64 kilobytes the previous program used, | ||
+ | will remain intact. If you add a switch to one of the memory expansion | ||
+ | controller' | ||
+ | have no way to screw the machine up, as the additional memory management | ||
+ | registers will not be available. | ||
+ | |||
+ | A few enhancements to this circuit are required so that you can freeze | ||
+ | the programs without losing the state of the I/O chips. You will also | ||
+ | need to replace the Kernal ROM chip with your own code, if you do not | ||
+ | want to lose the state of the A, X, P and S registers. Unfortunately | ||
+ | this circuit will not preserve the state of the processor' | ||
+ | lines (its built-in I/O port mapped to the memory addresses 0 and 1), | ||
+ | nor does it record the program counter (PC). I have a partial solution | ||
+ | to the PC problem, though. | ||
+ | |||
+ | If you are interested in this project, contact me. I will design the | ||
+ | additional hardware, and I will program the startup routines, but I | ||
+ | certainly do not have the time to program all of the freezer software. | ||
+ | Most of the freezer software could be in RAM, so it would be very easy | ||
+ | to develop it, and you could even use existing tools by patching them | ||
+ | slightly. | ||
+ | |||
+ | ============================================================================= | ||
+ | </ | ||
+ | |||
+ | ====== FLD - Scrolling the screen ====== | ||
+ | by Marek Klampar (klampar@elf.stuba.sk) | ||
+ | |||
+ | Scrolling the screen((downwards /Oswald)) | ||
+ | |||
+ | [inspirated by Pasi Ojala article ' | ||
+ | |||
+ | From Pasi ' | ||
+ | |||
+ | ===== 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((the lowest 3 bits of $d011 /Oswald)) 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' | ||
+ | |||
+ | 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 | ||
+ | replace LDX OFSET | ||
+ | by LDX #$ff | ||
+ | </ | ||
+ | and enjoy =) | ||
+ | |||
+ | |||
+ | The demonstration 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 #< | ||
+ | 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 ' | ||
+ | Written on 16-May-91 | ||
+ | |||
+ | (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, | ||
+ | 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/ | ||
+ | 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, | ||
+ | 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, | ||
+ | change the sprite image pointers. There is multiple sprite pictures, | ||
+ | where the graphics is shifted horizontally, | ||
+ | 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= | ||
+ | ZP= | ||
+ | START= | ||
+ | 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= | ||
+ | SPEED= | ||
+ | |||
+ | *= $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), | ||
+ | INY | ||
+ | BNE LOOP0 | ||
+ | INC ZP+1 | ||
+ | BPL LOOP0 | ||
+ | |||
+ | LDA #>START | ||
+ | STA ZP+1 | ||
+ | LDA #$32 ; Character ROM to address space ($D000-) | ||
+ | STA $01 | ||
+ | LOOP1 | ||
+ | LSR | ||
+ | LSR | ||
+ | LSR | ||
+ | TAX | ||
+ | LDA TEXT, | ||
+ | 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, | ||
+ | STA START+2056, | ||
+ | STA START+4112, | ||
+ | STA START+6168, | ||
+ | STA START+8224, | ||
+ | STA START+10280, | ||
+ | STA START+12336, | ||
+ | STA START+14392, | ||
+ | INY | ||
+ | BNE LOOP3 | ||
+ | LDA #0 ; Clear the pointer, value and speed | ||
+ | STA POINTER | ||
+ | STA VALUE | ||
+ | STA SPEED | ||
+ | |||
+ | LOOP4 | ||
+ | ORA #$80 ; Use the inverted chars | ||
+ | STA SCREEN, | ||
+ | STA SCREEN+40,Y | ||
+ | STA SCREEN+80,Y | ||
+ | STA SCREEN+120, | ||
+ | STA SCREEN+160, | ||
+ | STA SCREEN+200, | ||
+ | STA SCREEN+240, | ||
+ | STA SCREEN+280, | ||
+ | LDA #239 ; leave the last line empty | ||
+ | STA SCREEN+320, | ||
+ | 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 | ||
+ | JMP BAD ; next line is a bad line | ||
+ | LOOP5 NOP | ||
+ | LOOP6 LDA SHIFTL, | ||
+ | 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, | ||
+ | STA $D016 | ||
+ | LDA SHIFTH,Y | ||
+ | STA $D018 | ||
+ | INY | ||
+ | LDX #7 ; New bad line coming up | ||
+ | JMP LOOP6 | ||
+ | |||
+ | OVER LDA #$97 ; Video bank to ' | ||
+ | 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 ; | ||
+ | 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> | ||
+ | 3 CH=0: | ||
+ | 4 FORF=0TO31: | ||
+ | 5 CH=CH+Q: | ||
+ | 6 PRINT" | ||
+ | 100 DATA 78A97F8D0DDCA9818D1AD0A9AD8D1403A9C08D1503A9318D12D0A91B8D11D0A0, | ||
+ | 101 DATA 00A24086FC84FB9891FBC8D0FBE6FC10F7A94485FCA9328501984A4A4AAABD5E, | ||
+ | 102 DATA C10A0A0AAAA9D069008D4EC0BD00D091FBE8C88A2907D0F4C000D0DDA9378501, | ||
+ | 103 DATA B9004499084C99105499185C99206499286C99307499387CC8D0E5A9008D3C03, | ||
+ | 104 DATA 8D3D038D3E0398098099004099284099504099784099A04099C84099F0409918, | ||
+ | 105 DATA 41A9EF994041C8C028D0DB5860A9968D00DDEAEAAC3C034CE1C0EAB900CF8D16, | ||
+ | 106 DATA D0B900CE8D18D0EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAAD12D0C9781016C8CAD0, | ||
+ | 107 DATA D9B900CF8D16D0B900CE8D18D0C8A2074CBBC0A9978D00DDA9168D18D0A9088D, | ||
+ | 108 DATA 16D0AD00DC2D01DCAAAC3E032908D008C8C00410038C3E038A2904D00888C0FC, | ||
+ | 109 DATA 30038C3E03AD3D03186D3E03100EAD3E0349FF1869018D3E03AD3D038D3D034A, | ||
+ | 110 DATA AA29070908AC3C039900CF8A4A4A4A0A9900CECE3C03A9018D19D04C31EA1408, | ||
+ | 111 DATA 091320091320140503082D1405030820060F1220033D3634200219200D050F12, | ||
+ | 200 DATA END,0 | ||
+ | |||
+ | -------------------------------------------------------------------------- | ||
+ | Uuencoded C64 executable version of the demo program (PAL) | ||
+ | |||
+ | begin 644 tech.64 | ||
+ | M`0@-" | ||
+ | MLC`ZAT$D+$$ZF4$D.HM!)+(B14Y$(J> | ||
+ | M.H``DP@$`(%& | ||
+ | M*$$D+$: | ||
+ | M`, | ||
+ | M.# | ||
+ | M, | ||
+ | M-D9#, | ||
+ | M" | ||
+ | M, | ||
+ | M,# | ||
+ | M-4$Y,# | ||
+ | M,# | ||
+ | M, | ||
+ | M1$1%045!04, | ||
+ | M0CDP, | ||
+ | M, | ||
+ | M.3`P0T4X1# | ||
+ | M,# | ||
+ | M1# | ||
+ | M; | ||
+ | M.3`Q.$0S13`S040S1# | ||
+ | M.$%#, | ||
+ | M-$, | ||
+ | M, | ||
+ | 4-3(`< | ||
+ | `` | ||
+ | end | ||
+ | |||
+ | ============================================================================= | ||
+ | </ | ||
+ | ====== ACE-128/64 PROGRAMMER' | ||
+ | < | ||
+ | by Craig Bruce < | ||
+ | |||
+ | 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, " | ||
+ | the 128/64). | ||
+ | |||
+ | So what is ACE all about? | ||
+ | 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. | ||
+ | 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. | ||
+ | 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. | ||
+ | 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. | ||
+ | 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. | ||
+ | device drivers it provided. | ||
+ | also, although more custom device drivers are needed. | ||
+ | the capability of making programs work together, rather than having | ||
+ | programs that are totally incompatible. | ||
+ | under construction. | ||
+ | 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. | ||
+ | slowly. | ||
+ | the C64 and C128, and they do. | ||
+ | |||
+ | This documentation refers to ACE release #10, which has not been | ||
+ | released yet (or even programmed). | ||
+ | Release #10 will be spruced up from the inside out to support the system | ||
+ | interface described in this document. | ||
+ | described, because some of its features are not the best they could | ||
+ | possibly be. Note, however, that the basic features, like " | ||
+ | " | ||
+ | version number of this " | ||
+ | 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, | ||
+ | terms of symbolic assembler labels. | ||
+ | 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. | ||
+ | |||
+ | SYMBOL | ||
+ | ------- | ||
+ | zp | ||
+ | zw | ||
+ | mp | ||
+ | syswork | ||
+ | |||
+ | The first two, " | ||
+ | 16-bit values; " | ||
+ | The " | ||
+ | passing far memory pointers for use with the far memory routines. | ||
+ | three of these variables will remain unchanged inside of system call | ||
+ | unless they will contain a return value. | ||
+ | used mainly when there are too many arguments for other variables to | ||
+ | hold, and all non-input and non-output bytes of " | ||
+ | change by the kernel. | ||
+ | locations will be preserved unless otherwise indicated. [Note: In | ||
+ | Release #9, " | ||
+ | |||
+ | 2.2. SYSTEM VARIABLES | ||
+ | |||
+ | There are several non-zeropage variables for storing system status and | ||
+ | return values: | ||
+ | |||
+ | SYMBOL | ||
+ | ---------- | ||
+ | errno | ||
+ | aceID | ||
+ | aceArgc | ||
+ | aceArgv | ||
+ | aceMemTop | ||
+ | aceShellPath | ||
+ | aceShellAlias | ||
+ | aceCurDirName | ||
+ | aceExitData | ||
+ | aceDirentBuffer < | ||
+ | aceDirentLength | ||
+ | aceDirentBytes | ||
+ | aceDirentDate | ||
+ | aceDirentType | ||
+ | aceDirentFlags | ||
+ | aceDirentNameLen | ||
+ | aceDirentName | ||
+ | |||
+ | ERRNO: " | ||
+ | system call ends in error, it sets the carry flag to " | ||
+ | code in " | ||
+ | system work completed at the time the error is encountered and aborting | ||
+ | the operation. | ||
+ | single-byte " | ||
+ | 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: " | ||
+ | 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 " | ||
+ | and the high, " | ||
+ | users that they cannot simply BOOT the program from BASIC, but rather | ||
+ | they must run ACE first. | ||
+ | |||
+ | ARGC: " | ||
+ | arguments passed to the application by the program (usually the command | ||
+ | shell) that called the application. | ||
+ | name of the application program, so the count will always be at least | ||
+ | one. Other arguments are optional. | ||
+ | |||
+ | ARGV: " | ||
+ | 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. | ||
+ | that ends with a zero byte). | ||
+ | to an application, | ||
+ | that, and fetch the pointer from that address. | ||
+ | ever-present application name is the 0-th argument. | ||
+ | element of the argument vector will always contain a value of $0000, a | ||
+ | null pointer. | ||
+ | |||
+ | MEM-TOP: " | ||
+ | byte past the highest byte that the application program is allowed to | ||
+ | use. All application programs are loaded into memory at address | ||
+ | " | ||
+ | progam code and " | ||
+ | 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, | ||
+ | available memory for a file buffer, but other programs, such as a file | ||
+ | compressor, may have much greater demand for " | ||
+ | variable has a different name in Release #9]. | ||
+ | |||
+ | SHELL-PATH: " | ||
+ | the page of memory that stores the pathnames of directories to search | ||
+ | through in order to find executable files. | ||
+ | null-terminated string, and the list is terminated by an empty string | ||
+ | (containing only the zero character). | ||
+ | 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 " | ||
+ | system call. This mechanism for reading/ | ||
+ | path may be changed in the future. | ||
+ | |||
+ | SHELL-ALIAS: | ||
+ | the page of memory that stores the aliases to be used with the command | ||
+ | shell. | ||
+ | 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 " | ||
+ | -l" | ||
+ | equals character (" | ||
+ | by a zero. The alias list is terminated by an empty string. | ||
+ | mechanism may be extended in the future to allow multiple pages of | ||
+ | aliases, or may be changed completely. | ||
+ | |||
+ | CUR-DIR-NAME: | ||
+ | the null-terminated string indicating the current directory. | ||
+ | is not supposed to modify this value, and the value will not always give | ||
+ | a full pathname. | ||
+ | in future versions of ACE. | ||
+ | |||
+ | ACE-EXIT-DATA: | ||
+ | the 256-byte buffer allocated for user programs to give detailed return | ||
+ | information upon exiting back to their parent program. | ||
+ | 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. | ||
+ | this feature may need to change in future versions of ACE. | ||
+ | |||
+ | DIRENT-BUFFER: | ||
+ | information read with the " | ||
+ | " | ||
+ | (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 " | ||
+ | |||
+ | DIRENT-BYTES: | ||
+ | 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. | ||
+ | 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: | ||
+ | decimal values, stored from most significant digits to least | ||
+ | significant. | ||
+ | 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. | ||
+ | Saturday 7, and a code of 0 means " | ||
+ | format for all dates used in ACE. This format is abstracted as | ||
+ | " | ||
+ | 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: | ||
+ | null-terminated string. | ||
+ | lowercase PETSCII. | ||
+ | returned, as well and other possibilities for custom device drivers. | ||
+ | |||
+ | DIRENT-FLAGS: | ||
+ | as consisting of eight independent one-bit fields. | ||
+ | the fields is " | ||
+ | (otherwise it is a regular file), " | ||
+ | means the item is writable, and " | ||
+ | " | ||
+ | improperly closed (a " | ||
+ | " | ||
+ | " | ||
+ | be interpreted as being a " | ||
+ | binary or unknown). | ||
+ | means true, " | ||
+ | |||
+ | DIRENT-NAME-LEN: | ||
+ | number of characters in the filename. | ||
+ | |||
+ | DIRENT-NAME: | ||
+ | character string field. | ||
+ | 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 | ||
+ | ------------------- | ||
+ | aceAppAddress | ||
+ | aceID1 | ||
+ | aceID2 | ||
+ | aceID3 | ||
+ | aceMemNull | ||
+ | aceMemREU | ||
+ | aceMemInternal | ||
+ | aceMemRLREU | ||
+ | aceMemRL | ||
+ | aceErrStopped | ||
+ | aceErrTooManyFiles | ||
+ | aceErrFileOpen | ||
+ | aceErrFileNotOpen | ||
+ | aceErrFileNotFound | ||
+ | aceErrDeviceNotPresent | ||
+ | aceErrFileNotInput | ||
+ | aceErrFileNotOutput | ||
+ | aceErrMissingFilename | ||
+ | aceErrIllegalDevice | ||
+ | aceErrWriteProtect | ||
+ | aceErrFileExists | ||
+ | aceErrFileTypeMismatch | ||
+ | aceErrNoChannel | ||
+ | aceErrInsufficientMemory err: ACE could not allocate the memory you requested | ||
+ | aceErrOpenDirectory | ||
+ | aceErrDiskOnlyOperation | ||
+ | aceErrNullPointer | ||
+ | aceErrInvalidFreeParms | ||
+ | aceErrFreeNotOwned | ||
+ | stdin file descriptor reserved for stdin input stream | ||
+ | stdout | ||
+ | stderr | ||
+ | |||
+ | " | ||
+ | programs are loaded into memory at. They must, of course, be compiled | ||
+ | to execute starting at this address. | ||
+ | |||
+ | The " | ||
+ | call, except for " | ||
+ | for indicating null far pointers. | ||
+ | specify what types of memory you are willing to accept. | ||
+ | important because the difference types of memory have different | ||
+ | performance characteristics. | ||
+ | memory that is available. | ||
+ | byte-transfer times of about 60 us (microseconds) and 1 us, | ||
+ | respectively. | ||
+ | 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+). | ||
+ | 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 " | ||
+ | error codes are returned in the " | ||
+ | error codes from Commodore disk drives are covered, but the important | ||
+ | ones are. Finally, the " | ||
+ | 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 : | ||
+ | PURPOSE: | ||
+ | ARGS : | ||
+ | .A = file mode (" | ||
+ | RETURNS: | ||
+ | .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. | ||
+ | character. | ||
+ | the file for writing, and " | ||
+ | (writing, starting at the end of the file). | ||
+ | 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. | ||
+ | " | ||
+ | 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. | ||
+ | stdout, and stderr, respectively. | ||
+ | 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 " | ||
+ | |||
+ | Restrictions: | ||
+ | device, and there is a system maximum of open files. | ||
+ | "too many files" error if you ever exceed this limit. | ||
+ | the nature of Commodore-DOS, | ||
+ | the number of files that can be simultaneously open on a single disk | ||
+ | device, resulting in a "no channel" | ||
+ | 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 " | ||
+ | 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 : | ||
+ | PURPOSE: | ||
+ | ARGS : | ||
+ | RETURNS: | ||
+ | ALTERS : .A, .X, .Y, errno | ||
+ | |||
+ | Closes an open file. Not much to say about this one. | ||
+ | |||
+ | NAME : | ||
+ | PURPOSE: | ||
+ | ARGS : | ||
+ | (zp) = pointer to buffer to store data into | ||
+ | .AY = maximum number of bytes to read | ||
+ | RETURNS: | ||
+ | .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' | ||
+ | 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. | ||
+ | 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. | ||
+ | number of bytes read are returned only in the .AY registers, not in | ||
+ | (zw).] | ||
+ | been reached. | ||
+ | give another EOF return. | ||
+ | the processor. | ||
+ | |||
+ | NAME : | ||
+ | PURPOSE: | ||
+ | ARGS : | ||
+ | (zp) = pointer to data to be written | ||
+ | .AY = length of data to be written in bytes | ||
+ | RETURNS: | ||
+ | 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. | ||
+ | will be corrected.] | ||
+ | |||
+ | NAME : | ||
+ | PURPOSE: | ||
+ | ARGS : | ||
+ | .A = file mode (must be " | ||
+ | RETURNS: | ||
+ | .CS = error occurred flag | ||
+ | ALTERS : .X, .Y, errno | ||
+ | |||
+ | This performs the same function as the regular " | ||
+ | style of file accessing will allow files to be read much faster than the | ||
+ | other. | ||
+ | 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 " | ||
+ | devices, except for output to the console. | ||
+ | just not accessed. | ||
+ | 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 " | ||
+ | make it easy to switch from using one to the other. | ||
+ | calls do not exist in Release #9]. | ||
+ | |||
+ | NAME : | ||
+ | PURPOSE: | ||
+ | ARGS : | ||
+ | RETURNS: | ||
+ | ALTERS : .A, .X, .Y, errno | ||
+ | |||
+ | Closes the file that was opened for fast reading. | ||
+ | |||
+ | NAME : | ||
+ | PURPOSE: | ||
+ | ARGS : | ||
+ | (zp) = pointer to buffer to store data into | ||
+ | .AY = maximum number of bytes to read | ||
+ | RETURNS: | ||
+ | .CS = error occurred flag | ||
+ | .ZS = EOF reached flag | ||
+ | ALTERS : .X, errno | ||
+ | |||
+ | Read data from the (one) file that is currently opened for " | ||
+ | reading. The arguments and semantics are equivalent to the regular | ||
+ | " | ||
+ | |||
+ | NAME : | ||
+ | PURPOSE: | ||
+ | ARGS : | ||
+ | .AY = address to load file | ||
+ | (zw) = highest address that file may occupy, plus one | ||
+ | RETURNS: | ||
+ | .CS = error occurred flag | ||
+ | ALTERS : .X, errno | ||
+ | |||
+ | Binary-load a file directly into memory. | ||
+ | the specified space, an error will be returned and the load truncated if | ||
+ | the device supports truncation; otherwise, important data may be | ||
+ | overwritten. | ||
+ | |||
+ | NAME : | ||
+ | PURPOSE: | ||
+ | ARGS : | ||
+ | RETURNS: | ||
+ | ALTERS : .A, .X, .Y, errno | ||
+ | |||
+ | Delete the named file. | ||
+ | |||
+ | NAME : | ||
+ | PURPOSE: | ||
+ | ARGS : | ||
+ | (zw) = new filename | ||
+ | RETURNS: | ||
+ | ALTERS : .A, .X, .Y, errno | ||
+ | |||
+ | Renames a file or directory. | ||
+ | exists, then the operation will be aborted and a "file exists" | ||
+ | will be returned. | ||
+ | the current directory and the new name may not include any path, just a | ||
+ | filename. | ||
+ | |||
+ | NAME : | ||
+ | PURPOSE: | ||
+ | ARGS : | ||
+ | RETURNS: | ||
+ | .X = number of columns on device | ||
+ | .Y = number of rows per " | ||
+ | .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. | ||
+ | and columns per " | ||
+ | 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 : | ||
+ | PURPOSE: | ||
+ | ARGS : | ||
+ | .Y = second file descriptor number | ||
+ | RETURNS: | ||
+ | ALTERS : .A, .X, .Y, errno | ||
+ | |||
+ | This call swaps meanings of two file descriptor numbers. | ||
+ | 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. | ||
+ | example, stdout, and swap the file descriptor number returned from the | ||
+ | open with file descriptor number 1 (stdout). | ||
+ | subroutine or external program, and on return, swap the two file | ||
+ | descriptors back, and close the redirection file. | ||
+ | |||
+ | 2.2. DIRECTORY CALLS | ||
+ | |||
+ | NAME : | ||
+ | PURPOSE: | ||
+ | ARGS : | ||
+ | RETURNS: | ||
+ | .CS = error occurred flag | ||
+ | ALTERS : .X, .Y, errno | ||
+ | |||
+ | This call opens a directory for reading its entries. | ||
+ | " | ||
+ | entires with the " | ||
+ | call must be a proper directory name like " | ||
+ | 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. | ||
+ | wildcards to this call; you will receive the entire directory listing. | ||
+ | |||
+ | NAME : | ||
+ | PURPOSE: | ||
+ | ARGS : | ||
+ | RETURNS: | ||
+ | ALTERS : .A, .X, .Y, errno | ||
+ | |||
+ | Closes a directory that is open for reading. | ||
+ | any point while scanning a directory; you do not have to finish scanning | ||
+ | an entire directory first. | ||
+ | |||
+ | NAME : | ||
+ | PURPOSE: | ||
+ | ARGS : | ||
+ | RETURNS: | ||
+ | .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 " | ||
+ | earlier. | ||
+ | this routine, you will receive the name of the disk (or directory). | ||
+ | " | ||
+ | will contain information; | ||
+ | |||
+ | Each subsequent call to this routine will return the next directory | ||
+ | entry in the directory. | ||
+ | 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 " | ||
+ | listing. | ||
+ | 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 : | ||
+ | PURPOSE: | ||
+ | ARGS : | ||
+ | RETURNS: | ||
+ | .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. | ||
+ | for false. | ||
+ | " | ||
+ | whether the file/ | ||
+ | |||
+ | NAME : | ||
+ | PURPOSE: | ||
+ | ARGS : | ||
+ | RETURNS: | ||
+ | ALTERS : .A, .X, .Y, errno | ||
+ | |||
+ | Changes the current working directory to the named directory. | ||
+ | the Commodore Kernal doesn' | ||
+ | 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 : | ||
+ | PURPOSE: | ||
+ | ARGS : | ||
+ | RETURNS: | ||
+ | ALTERS : .A, .X, .Y, errno | ||
+ | |||
+ | Changes the current working directory back to the " | ||
+ | is defined in the " | ||
+ | |||
+ | NAME : | ||
+ | PURPOSE: | ||
+ | ARGS : | ||
+ | RETURNS: | ||
+ | ALTERS : .A, .X, .Y, errno | ||
+ | |||
+ | Creates a new directory. | ||
+ | directory has to be the parent directory of the directory you want to | ||
+ | create. | ||
+ | common denominator for directory support. | ||
+ | implemented in Release #9]. | ||
+ | |||
+ | NAME : | ||
+ | PURPOSE: | ||
+ | ARGS : | ||
+ | RETURNS: | ||
+ | ALTERS : .A, .X, .Y, errno | ||
+ | |||
+ | Deletes an existing directory. | ||
+ | directory entries) in order for this command to succeed. | ||
+ | pretty sure that you have to be " | ||
+ | be deleted, since this is probably required by CMD devices. | ||
+ | call is not implemented in Release #9]. | ||
+ | |||
+ | 2.3. MEMORY CALLS | ||
+ | |||
+ | The calls given in this section are to be used for accessing " | ||
+ | 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 " | ||
+ | the practice of bypassing the operating system would undoubtedly lead to | ||
+ | problems (can you say " | ||
+ | |||
+ | All of these calls use a 32-bit pointer that is stored in the zero-page | ||
+ | argument field " | ||
+ | as consisting of low and high words. | ||
+ | first, is the offset into the memory " | ||
+ | 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. | ||
+ | make any interpretation of the bank word. An application should only | ||
+ | access far memory that it has allocated for itself via the " | ||
+ | call. | ||
+ | |||
+ | NAME : | ||
+ | ARGS : | ||
+ | .X = destination zero-page address | ||
+ | .Y = transfer length | ||
+ | RETURNS: | ||
+ | ALTERS : .A, .X, .Y, errno | ||
+ | |||
+ | Load zero-page locations with the contents of far memory. | ||
+ | course, gives the address of the first byte of far memory to be | ||
+ | retrieved. | ||
+ | storage space for the data on zero page. It must be in the application | ||
+ | zero-page space. | ||
+ | transferred, | ||
+ | application zero-page storage, must be 126 bytes or less. This routine | ||
+ | will return a " | ||
+ | pointer. | ||
+ | |||
+ | NAME : | ||
+ | ARGS : | ||
+ | [mp] = destination far memory pointer | ||
+ | .Y = transfer length | ||
+ | RETURNS: | ||
+ | ALTERS : .A, .X, .Y, errno | ||
+ | |||
+ | This routine is the complement of " | ||
+ | zero page to far memory. | ||
+ | " | ||
+ | |||
+ | NAME : | ||
+ | ARGS : | ||
+ | (zp) = destination RAM0 pointer | ||
+ | .AY = transfer length | ||
+ | RETURNS: | ||
+ | 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. | ||
+ | arguments should mostly speak for themselves. | ||
+ | RAM0 memory that is not specifically allocated to the application. | ||
+ | will get an error if you try to use a null far pointer. | ||
+ | |||
+ | NAME : | ||
+ | ARGS : | ||
+ | [mp] = destination far memory pointer | ||
+ | .AY = transfer length | ||
+ | RETURNS: | ||
+ | ALTERS : .A, .X, .Y, errno | ||
+ | |||
+ | This is the complement of " | ||
+ | it transfers data from RAM0 to far memory. | ||
+ | |||
+ | NAME : | ||
+ | ARGS : | ||
+ | .X = starting " | ||
+ | .Y = ending " | ||
+ | RETURNS: | ||
+ | .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, | ||
+ | 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 " | ||
+ | search for the required allocation. | ||
+ | the System Constants section. | ||
+ | constants are arranged in order of accessing speed. | ||
+ | application has speed requirements that dictate, for example, that | ||
+ | RAMLink memory should not be used, then you would call " | ||
+ | a search range of .X=0 to .Y=aceMemInternal. | ||
+ | are willing to accept any memory the system can give to you, you would | ||
+ | specify .X=0 to .Y=255. | ||
+ | the fastest and slowest memory available. | ||
+ | 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 " | ||
+ | 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. | ||
+ | return a " | ||
+ | error may occur if there is actually the correct amount of memory free | ||
+ | but just not in a big enough contiguous chunk. | ||
+ | routine will return in " | ||
+ | page of the allocated memory. | ||
+ | |||
+ | If you call a subprogram with the " | ||
+ | is holding far memory, that far memory will be kept allocated to your | ||
+ | program and will be safe while the child program is executing. | ||
+ | don't deallocate the memory with " | ||
+ | parent program, then the system will automatically deallocate all memory | ||
+ | allocated to you. So, have no fear about calling " | ||
+ | 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 | ||
+ | " | ||
+ | that manage page allocation and deallocation requests to the near | ||
+ | memory, and calls the " | ||
+ | far memory. | ||
+ | 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. | ||
+ | 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. | ||
+ | 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 : | ||
+ | ARGS : | ||
+ | .A = number of pages to be freed | ||
+ | RETURNS: | ||
+ | ALTERS : .A, .X, .Y, errno | ||
+ | |||
+ | This deallocates memory that was allocated to a process by using the | ||
+ | " | ||
+ | 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. | ||
+ | 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). | ||
+ | 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. | ||
+ | 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. | ||
+ | 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 " | ||
+ | values refer to the " | ||
+ | " | ||
+ | parts of a screen location will be modified. | ||
+ | to each screen location: the character code, the color code, and the | ||
+ | high-attributes. | ||
+ | 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. | ||
+ | follows: | ||
+ | |||
+ | CODES (hex) | ||
+ | ----------- | ||
+ | $00-$1f | ||
+ | $20-$3f | ||
+ | $40-$5f | ||
+ | $60-$7f | ||
+ | $80-$9f | ||
+ | $a0-$bf | ||
+ | $c0-$df | ||
+ | $e0-$ef | ||
+ | |||
+ | There are sixteen color codes, occupying the lower four bits of the color | ||
+ | value. | ||
+ | |||
+ | CODE(dec) | ||
+ | --------- | ||
+ | 0 $0 | ||
+ | 1 $1 | ||
+ | 2 $2 | ||
+ | 3 $3 | ||
+ | 4 $4 | ||
+ | 5 $5 | ||
+ | 6 $6 | ||
+ | 7 $7 | ||
+ | 8 $8 | ||
+ | 9 $9 | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | Finally, there are the high-attribute bits. These occupy the four most | ||
+ | significant bits of the color value. | ||
+ | (VIC text, VDC text, or VIC/VDC bitmap), these bits have one of three | ||
+ | meanings: character attributes, background character color, or no | ||
+ | effect. | ||
+ | different effects on different displays. | ||
+ | are the same as the foreground character codes listed above. | ||
+ | character attributes have the following meanings: | ||
+ | |||
+ | BIT VALUE | ||
+ | -avub---- | ||
+ | %10000000 | ||
+ | %01000000 | ||
+ | %00100000 | ||
+ | %00010000 | ||
+ | |||
+ | These values are additive (or, should I say, " | ||
+ | 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). | ||
+ | have changed, set bits in the " | ||
+ | system calls. | ||
+ | as well: | ||
+ | |||
+ | BIT VALUE | ||
+ | -cah----- | ||
+ | %10000000 | ||
+ | %01000000 | ||
+ | %00100000 | ||
+ | |||
+ | The screen calls that deal with placing characters on the screen refer | ||
+ | to screen locations using absolute addresses of locations in screen | ||
+ | memory. | ||
+ | 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, | ||
+ | numbers and return the corresponding absolute screen address. | ||
+ | |||
+ | The screen-control system calls are as follows: | ||
+ | |||
+ | NAME : | ||
+ | ARGS : | ||
+ | RETURNS: | ||
+ | ALTERS : .A, .X, .Y | ||
+ | |||
+ | Sets the current window to cover the entire screen. | ||
+ | |||
+ | NAME : | ||
+ | ARGS : | ||
+ | .X = character fill value | ||
+ | .Y = color fill value | ||
+ | RETURNS: | ||
+ | ALTERS : .A, .X, .Y | ||
+ | |||
+ | This call " | ||
+ | character/ | ||
+ | limit what gets cleared. [Note: The arguments for this call are slightly | ||
+ | different in Release #9]. | ||
+ | |||
+ | NAME : | ||
+ | ARGS : | ||
+ | .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: | ||
+ | ALTERS : .A, .X, .Y, errno | ||
+ | |||
+ | Sets the current window to the size you specify. | ||
+ | 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 : | ||
+ | ARGS : | ||
+ | RETURNS: | ||
+ | .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 | ||
+ | | ||
+ | | ||
+ | ALTERS : < | ||
+ | |||
+ | Returns information about the current window. [Note: the arguments are | ||
+ | slightly different in Release #9]. | ||
+ | |||
+ | NAME : | ||
+ | ARGS : (sw+0)= absolute screen address to start putting data at | ||
+ | | ||
+ | .X = length of character string | ||
+ | .Y = color | ||
+ | .A = char/ | ||
+ | sw+4 = fill character | ||
+ | sw+5 = total field length | ||
+ | RETURNS: | ||
+ | ALTERS : .A, .X, .Y | ||
+ | |||
+ | Puts text onto the screen. | ||
+ | starting screen address and the total field length. | ||
+ | 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. | ||
+ | ignored; they are poked literally onto the screen, including the null | ||
+ | character. | ||
+ | equal to the total length of the field. | ||
+ | will be filled in with the "fill character" | ||
+ | |||
+ | The color of the total field length will be filled in with " | ||
+ | can use the " | ||
+ | to be changed. | ||
+ | the field are not to be changed, then the call would execute faster. | ||
+ | |||
+ | NAME : | ||
+ | ARGS : | ||
+ | .Y = new RGBI border color | ||
+ | .A = which colors to change ($80=screen + $40=border) | ||
+ | RETURNS: | ||
+ | .Y = resulting RGBI border color | ||
+ | ALTERS : .A | ||
+ | |||
+ | Sets the color of the screen and border. | ||
+ | the other, both, or neither. | ||
+ | and the existing colors for colors unchaned will be returned. | ||
+ | not all screens have an adjustable color, so the border argument may be | ||
+ | ignored. | ||
+ | |||
+ | NAME : | ||
+ | ARGS : | ||
+ | .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. | ||
+ | returned, so garbage in, garbage out. | ||
+ | |||
+ | NAME : | ||
+ | ARGS : (sw+0)= screen address to place cursor | ||
+ | .A = enable flag ($ff=cursor-on / $00=cursor-off) | ||
+ | .Y = color to show cursor in | ||
+ | RETURNS: | ||
+ | ALTERS : .A, .X, .Y | ||
+ | |||
+ | Displays or undisplays the cursor at the given screen address. | ||
+ | call returns immediately in either case. No errors are returned. | ||
+ | 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. | ||
+ | give the same address when undisplaying the cursor as you did when | ||
+ | displaying the cursor. | ||
+ | its undisplayed state (duh!). | ||
+ | want the cursor to be shown in. The high-attribute bits of this color | ||
+ | are ignored. | ||
+ | |||
+ | NAME : | ||
+ | ARGS : | ||
+ | .X = number of rows to scroll up/down | ||
+ | sw+4 = fill character | ||
+ | .Y = fill color | ||
+ | RETURNS: | ||
+ | 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. | ||
+ | the characters and/or colors are to be scrolled by using the " | ||
+ | byte in the usual way. Scrolling only the characters, for example, will | ||
+ | be twice as fast as scrolling both characters and attributes. | ||
+ | to scroll up or down is specified also using bits in the " | ||
+ | as indicated in the input arguments above. | ||
+ | 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 " | ||
+ | the screen and keyboard. | ||
+ | than the calls in the previous section. | ||
+ | |||
+ | NAME : | ||
+ | ARGS : | ||
+ | RETURNS: | ||
+ | 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 : | ||
+ | ARGS : | ||
+ | RETURNS: | ||
+ | ALTERS : .X, .Y | ||
+ | |||
+ | Waits for the user to type a key (or takes a previous keystroke from the | ||
+ | keyboard buffer). | ||
+ | PETSCII codes, but there are many special control keystrokes. | ||
+ | not listed here (yet) because I haven' | ||
+ | special codes should be, but all 256 possible character values will be | ||
+ | covered. | ||
+ | standardizing control keystrokes for applications. | ||
+ | returned in the accumulator. | ||
+ | |||
+ | NAME : | ||
+ | ARGS : | ||
+ | + $80=modify high-attributes of colors | ||
+ | .X = new RGBI character color | ||
+ | .Y = new RGBI cursor color | ||
+ | RETURNS: | ||
+ | .Y = resulting cursor color | ||
+ | ALTERS : .A | ||
+ | |||
+ | Sets the character and cursor colors to be used by the console for the | ||
+ | " | ||
+ | console device. You can use the flags argument to limit what gets | ||
+ | changed. [Note: flags argument is slightly different in Release #9]. | ||
+ | |||
+ | NAME : | ||
+ | ARGS : | ||
+ | RETURNS: | ||
+ | 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, | ||
+ | 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. | ||
+ | interpret their meaning according to the application. The suggested | ||
+ | usages are given in the return arguments listed above. | ||
+ | |||
+ | NAME : | ||
+ | ARGS : | ||
+ | .X = number of text columns required, minimum | ||
+ | RETURNS: | ||
+ | .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. | ||
+ | the system cannot match your minimum requirements, | ||
+ | returned, and the current screen will be unchanged. | ||
+ | the processor will be changed to match the screen selected, if | ||
+ | appropriate. | ||
+ | |||
+ | NAME : | ||
+ | ARGS : | ||
+ | .X = column | ||
+ | RETURNS: | ||
+ | ALTERS : .A, .X, .Y | ||
+ | |||
+ | This call will set the screen location that the next console " | ||
+ | " | ||
+ | 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). | ||
+ | the execution of another program, have it execute, and then return to | ||
+ | the calling program. | ||
+ | time, some special problems arise. | ||
+ | these system calls are implemented in Release #9 and I haven' | ||
+ | completely how they should work. So, this section is a bit tentative. | ||
+ | |||
+ | NAME : | ||
+ | PURPOSE: | ||
+ | ARGS : | ||
+ | (zw) = start address of argument vector | ||
+ | .AY = number of arguments | ||
+ | [mp] = pointer to far memory volatile storage | ||
+ | RETURNS: | ||
+ | .X = number of bytes in " | ||
+ | [mp] = pointer to far memory volatile storage | ||
+ | .CS = error occurred flag | ||
+ | ALTERS : .Y, errno | ||
+ | |||
+ | Calling this routine will cause a new " | ||
+ | " | ||
+ | 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. | ||
+ | memory, starting from one less than the location pointed to by | ||
+ | " | ||
+ | strings are placed, as long as they are all grouped together. | ||
+ | immediately below the strings comes the vector of two-byte RAM0 pointers | ||
+ | that point to the strings. | ||
+ | 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. | ||
+ | |||
+ | HIGHER ADDRESSES | ||
+ | | | | ||
+ | | | < | ||
+ | +-----------+ | ||
+ | | | | ||
+ | | string | ||
+ | | | ||
+ | | contents | | ||
+ | | | | ||
+ | | | | ||
+ | +-----------+ | ||
+ | | | ||
+ | +-----------+ | ||
+ | | 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. | ||
+ | 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 " | ||
+ | two filenames " | ||
+ | count of 3. The name pointed to by " | ||
+ | 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. | ||
+ | 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. | ||
+ | one open file table in the whole uni-tasking system, you'll have to | ||
+ | manipulate existing entries using the " | ||
+ | earlier. | ||
+ | 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 " | ||
+ | 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. | ||
+ | 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. | ||
+ | process, the value you put into [mp] will be restored, and you can then | ||
+ | restore your volatile information out of far storage. | ||
+ | save no volatile information, | ||
+ | [mp] value, since it will not be interpreted by the system. | ||
+ | |||
+ | Alright, so now you call the " | ||
+ | loaded, executed, and it returns. | ||
+ | |||
+ | At this time, the parent program (that' | ||
+ | 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. | ||
+ | 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. | ||
+ | process will not have been executed. | ||
+ | the parent program (you), then an error return is given to your parent, | ||
+ | and so on, as far back as necessary. | ||
+ | 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 | ||
+ | " | ||
+ | |||
+ | [Note: This call is different in Release #9]. | ||
+ | |||
+ | NAME : | ||
+ | PURPOSE: | ||
+ | ARGS : | ||
+ | (zw) = address of argument vector | ||
+ | RETURNS: | ||
+ | .X = number of bytes in " | ||
+ | .CS = error occurred flag | ||
+ | ALTERS : .Y, errno | ||
+ | |||
+ | This call is very similar to " | ||
+ | subroutine rather than an external program. | ||
+ | save or restore your volatile storage, or worry about loading the child | ||
+ | or reloading the parent. | ||
+ | redirections as you would for a full " | ||
+ | different in Release #9]. | ||
+ | |||
+ | NAME : | ||
+ | PURPOSE: | ||
+ | ARGS : | ||
+ | .X = number of bytes in " | ||
+ | RETURNS: | ||
+ | ALTERS : < | ||
+ | |||
+ | 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. | ||
+ | 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 " | ||
+ | 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 : | ||
+ | PURPOSE: | ||
+ | ARGS : | ||
+ | RETURNS: | ||
+ | | ||
+ | | ||
+ | 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 : | ||
+ | PURPOSE: | ||
+ | ARGS : | ||
+ | .X = zero-page address of 32-bit number | ||
+ | | ||
+ | RETURNS: | ||
+ | ALTERS : .A, .X | ||
+ | |||
+ | This is a utility call in the kernel. | ||
+ | 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. | ||
+ | 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 : | ||
+ | PURPOSE: | ||
+ | ARGS : (.AY) = address of buffer to put BCD-format date into | ||
+ | RETURNS: | ||
+ | ALTERS : .A, .X, .Y | ||
+ | |||
+ | Returns the current date and time in the BCD format described in the | ||
+ | paragraph on " | ||
+ | storage area pointed to by (.AY). | ||
+ | |||
+ | NAME : | ||
+ | PURPOSE: | ||
+ | ARGS : (.AY) = address of date in BCD format | ||
+ | RETURNS: | ||
+ | ALTERS : .A, .X, .Y | ||
+ | |||
+ | Sets the current date and time in the system. | ||
+ | date string whose format is discussed in the paragraph on | ||
+ | " | ||
+ | |||
+ | NAME : | ||
+ | PURPOSE: | ||
+ | ARGS : | ||
+ | RETURNS: | ||
+ | .CS = error occurred flag | ||
+ | ALTERS : .X, .Y, errno | ||
+ | |||
+ | This " | ||
+ | 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 : | ||
+ | PURPOSE: | ||
+ | ARGS : | ||
+ | RETURNS: | ||
+ | ALTERS : .A, .X, .Y, errno | ||
+ | |||
+ | This closes an opened command channel to a disk drive. | ||
+ | status will NOT affect any other open files on the disk unit at the | ||
+ | time. | ||
+ | |||
+ | NAME : | ||
+ | PURPOSE: | ||
+ | ARGS : | ||
+ | (.AY) = pointer to null-terminated command string | ||
+ | RETURNS: | ||
+ | ALTERS : .A, .X, .Y, errno | ||
+ | |||
+ | This sends a command string to a disk drive. | ||
+ | string representation is used, not all Commodore/ | ||
+ | sent, but the important ones can be. | ||
+ | |||
+ | NAME : | ||
+ | PURPOSE: | ||
+ | ARGS : | ||
+ | (.AY) = pointer to buffer for null-terminated status string | ||
+ | RETURNS: | ||
+ | .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. | ||
+ | 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. | ||
+ | world" example program written in Buddy assembler for ACE: | ||
+ | |||
+ | -----=----- | ||
+ | .seq acehead.s | ||
+ | .org aceAppAddress | ||
+ | .obj " | ||
+ | |||
+ | jmp main | ||
+ | .byte aceID1, | ||
+ | |||
+ | main = * | ||
+ | lda #< | ||
+ | ldy #> | ||
+ | sta zp+0 | ||
+ | sty zp+1 | ||
+ | lda #< | ||
+ | ldy #> | ||
+ | ldx #stdout | ||
+ | jsr write | ||
+ | rts | ||
+ | |||
+ | helloMsg = * | ||
+ | .asc " | ||
+ | .byte 13 | ||
+ | helloMsgEnd = * | ||
+ | -----=----- | ||
+ | |||
+ | This would normally be put into a file called " | ||
+ | extension means that this is an assembler file (a la Unix). | ||
+ | thing this program does is include the " | ||
+ | Buddy assembler file that contains the header information declarations | ||
+ | required to access the ACE system interface. | ||
+ | start address to start assembling to; it must be " | ||
+ | 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 " | ||
+ | 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. | ||
+ | bytes must be a JMP to the main routine of the program. | ||
+ | bytes must have the values " | ||
+ | respectively. | ||
+ | can be organized however you want it to be. | ||
+ | |||
+ | In this example, we set up the arguments for the " | ||
+ | print the string " | ||
+ | standard output. | ||
+ | ($00) character since the write call takes a buffer length. | ||
+ | then returns to its calling environment via an RTS. This will cause an | ||
+ | implied " | ||
+ | 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. | ||
+ | the processor stack may be used from the point it was at upon entry to | ||
+ | your program all the way down to the bottom. | ||
+ | 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 " | ||
+ | six) and is allowed to use memory all the way up to one byte less than | ||
+ | the address pointed to by " | ||
+ | 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. | ||
+ | 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 | ||
+ | | ||
+ | they were going to do for the next issue.) | ||
+ | </ |
magazines/chacking7.txt · Last modified: 2015-04-17 04:34 by 127.0.0.1