User Tools

Site Tools



This shows you the differences between two versions of the page.

Link to this comparison view

magazines:chacking11 [2015-04-17 04:34] (current)
Line 1: Line 1:
 +                   ########​
 +             ##################​
 +         ###### ​           ######
 +      #####
 +    #####  ####  ####      ##       ##### ​  #### ​ ####  ####  ####  ####   #####
 +  #####    ##    ##      ####     ## ​  ## ​  ## ​ ###     ## ​   ####  ##   ## ​  ##
 + ##### ​   ######## ​    ## ​ ##    ##        #####       ## ​   ## ## ##   ##
 +#####    ##    ##    ######## ​  ## ​  ## ​  ## ​ ###     ## ​   ##  ####   ## ​  ##
 +#####  ####  ####  ####  ####   ##### ​  #### ​ ####  ####  ####  ####   ######​
 +#####                                                                     ##
 + ###### ​           ###### ​           Issue #11
 +   ################## ​              ​Version 1.0
 +       ######## ​                   December 1995
 +====== Table of Contents ======
 +   6. Speed up RAMLink transfers with the Double-DMA Technique
 +      (Reference: dbldma) ​                  by Doug Cotton and Mark Fellows ​
 +        RAMLink Designer Mark Fellows and Technical Editor Doug Cotton of 
 +        CMD describe a way of using a Commodore REU to increase transfer ​
 +        rates of the CMD RAMLink to one-half the speed of the REU transfer ​
 +        rate.
 +   8. The Graphics Toolbox by Stephen Judd
 +      (Reference: toolbox)
 +        To add another tool to our toolbox, Stephen details a new algorithm
 +        for drawing ellipses. ​ Some improvements to the circle routine in
 +        a previous column that will enable it to draw perfect circles of any
 +        radius is discussed, as well as details on using logarithms to 
 +        perform division.
 +  10. Design and Implementation of an Advanced Text Editor by Craig Bruce
 +      (Reference: zedace)
 +        Peer into the internal organization and implementation of an 
 +        advanced text editor/word processor for the ACE environment. ​
 +        Relevant data structure, global variables, display maintenance, ​
 +        text "​sloshing",​ and algorithms for many editing commands are 
 +        detailed.
 +   4. Hi Tech Trickery by George Taylor
 +      (Reference: trick)
 +        Don't let anyone ever tell you the SID chip is only capable of 4 bit 
 +        sample playback. ​ George Taylor explains using the digi dithering ​
 +        technique to increase the SID's resolution.
 +  12. Hacking Graphics by Rick Mosdell
 +      (Reference: gfx)
 +        Dig into this overview on how to set up the VIC-II to display Doodle
 +        and KOALA format pictures. ​ The two formats are detailed, and similar
 +        formats are referenced.
 +   1. The (cough,​cough) Hacking Editor
 +      (Reference: editor)
 +   2. Input/​Output
 +      (Reference: io)
 +   3. Newsfront
 +      (Reference: news)
 +   5. Hacking the Mags
 +      (Reference: mags)
 +   7. UseNuggets
 +      (Reference: usenet)
 +   9. Hack Surfing
 +      (Reference: surf)
 +  11. Commodore Trivia
 +      (Reference: trivia)
 +  13. ? DS, DS$: rem The Error Channel
 +      (Reference: error)
 +  14. The Next Hack
 +      (Reference: next)
 +====== Commodore Hacking Legal Notice ======
 +Commodore and the respective Commodore product names are trademarks or 
 +registered trademarks of ESCOM GmbH.  Commodore hacking is in no way 
 +affiliated with ESCOM GmbH, owners of said trademarks. ​ Commodore Hacking is 
 +published 4 times yearly by:
 +Brain Innovations Inc. 
 +602 N. Lemen 
 +Fenton MI  48430
 +The magazine is published on on-line networks free of charge, and a nominal ​
 +fee is charged for alternate mediums of transmission.  ​
 +Permission is granted to re-distribute this "​net-magazine"​ or "​e-zine"​ in its 
 +entirety for non-profit use.  A charge of no more than US$5.00 may be 
 +charged by redistribution parties to cover printed duplication and no more
 +than US$10.00 for other types of duplication to cover duplication and media
 +costs for this publication. ​ If this publications is included in a for-profit ​
 +compilation,​ this publication must be alternately available separately or as
 +part of a non-profit compilation.
 +This publication,​ in regards to its specific ordering and compilations of
 +various elements, is copyright(c) 1995 by Brain Innovations,​ Incorporated,​
 +unless otherwise noted. ​ Each work in this publication retains any and all 
 +copyrights pertaining to the individual work's contents. ​ For  ​
 +redistribution rights to individual works, please contact the author of said 
 +work or Brain Innovations,​ Inc.
 +Brain Innovations,​ Inc. assumes no responsibility for errors or omissions in 
 +editorial, article, or program listing content.  ​
 +====== Commodore Hacking Information ======
 +Commodore Hacking is published via the Internet 4 times yearly, and is 
 +presented in both ISO-8859-1 and HTML versions. ​ This and previous issues can 
 +be found at the Commodore Hacking Home Page 
 +(http://​​~brain/​chacking/​),​ as well as via FTP 
 +In addition, the Commodore Hacking mail server can be used to retrieve each 
 +issue. ​ To request a copy of an issue, please send the following electronic ​
 +mail message:
 +Subject: MAILSERV
 +Body of Message:
 +send c=hacking11.txt ​
 +To subscribe to the Commodore Hacking and receive new issues as 
 +they are published, add the following command to you MAILSERV message ​
 +prior to the quit command:
 +subscribe c=hacking Firstname Lastname msglen
 +(msglen is largest size of file in kilobytes you can receive in an email 
 +message. ​ When in doubt, choose 64)
 +subscribe c=hacking Jim Brain 100
 +Although no fee is charged for this magazine, donations are gladly accepted ​
 +from corporate and individual concerns. ​ All monies will be used to defray ​
 +any administrative costs, subscribe to publications for review, and 
 +compensate the individual authors contributing to this issue.
 +Any persons wishing to author articles for inclusion in Commodore Hacking are 
 +encouraged to view the submission guidelines on the WWW
 +(http://​​~brain/​pub/​c-hacking-submit.txt) or via the MAILSERV ​
 +server (send c-hacking-submit.txt).  ​
 +====== Reading C=Hacking ======
 +Starting with Issue 11 of Commodore Hacking, the new QuickFind indexing ​
 +system is utilized to aid readers of the text version in navigating the
 +magazine. ​ At the top  of each article or other important place in the
 +magazine, a word prefixed with a special string is present. ​ (See the
 +title of this article for an example. ​ Throughout the magazine, if an
 +article is mentioned, it will be followed by a reference string. ​ For
 +example, if we mentioned this article, we would add (Reference: rch) after
 +the name.  By using your favorite editor'​s search function and searching
 +for the string after the word "​Reference:",​ prefixed by the magic prefix
 +string, will move you directly to the article of choice. ​ To merely skip to
 +the next article in the magazine, search only for the magic prefix string.
 +Some handy indexing strings possibly not referenced anywhere are:
 +top      top of issue
 +bottom ​  ​bottom of issue
 +contents table of contents
 +legal    legal notice
 +For those with access to a UNIX system, the command "​what"​ can be
 +run on the issue, which will result in all the article titles being
 +A slightly different magic prefix string "#​(A)"​ is used to delimit
 +sub-topics or main heading in articles. ​ The text after the magic string
 +differs depending on article content. ​ For the Input/​Output column
 +(Reference: io), the text after the magic prefix will either be "​c"​ for 
 +comment, or "​r"​ for response. ​ In features and columns, a number after
 +the prefix indicates the ordinal of that heading or sub-topic in the
 +article. ​ If a specific sub-topic is referenced elsewhere in the article,
 +a sub-topic reference will be indicated. ​ A reference to "#​(A)r"​ would
 +be written as "​(SubRef:​ r)".
 +As time goes on, the role of this indexing system will be expanded and
 +changed to ease navigation of the text version, but minimize the clutter
 +added by these extra items.
 +====== The Hacking Editor ======
 +by Jim Brain (
 +Two new faces appear in this month'​s Commodore Hacking. ​ One is its new editor,
 +while the other is its new look.  I hope neither causes anyone to worry about 
 +the content of the magazine. ​ It's all still here.  C=Hacking will continue
 +to provide leading edge technical information about the Commodore computers
 +we all know and love.  The magazine will continue to cater to the Commodore
 +computer programmer, whether it be in the areas of sound, graphics, algorithms,
 +disk media access, or communications.  ​
 +However, the role of the magazine continues to expand. ​ It has been shown that
 +many people other than CBM programmers read the magazine, and programmers have
 +requested other information besides technical content be included in the
 +magazine. ​ To this end, Issue 11 contains many new features, including:
 +o  "​Hacking the Mags" (Reference: mags), which will summarize the other 
 +   ​Commodore magazines in the market place. ​ Not everyone can read or
 +   ​subscribe to all the quality CBM publications out there, so this column
 +   will alert readers to specific issues that may be of interest.
 +o  "​Newsfront"​ (Reference: news), which will bring the Commodore programmer ​
 +   and user up to date on developments in the Commodore community. ​ The
 +   ​Commodore world doesn'​t stand still, and every programmer should be aware
 +   of the newest technologies affecting the CBM line.
 +o  "The Error Channel"​ (Reference: error), which will formalize the process ​
 +   of fixing errors in earlier issues. ​ Hopefully, this will be unnecessary
 +   in most issues, but it will be here just in case.
 +o  "​Input/​Output"​ (Reference: io), which will allow C=Hacking readers space 
 +   for comments and concerns. ​ Many readers have sent me suggestions and
 +   ​comments,​ some C=Hacking can implement, and some C=Hacking cannot.  ​
 +   This spot will detail which is which and why.
 +o  Article separators. ​ As you can see above, each article or column in the
 +   ​magazine is delimited by the special key, followed by a short name
 +   of the article. ​ See "​Reading C=Hacking"​ (Reference: rch) in this issue.
 +o  Smaller size.  The last issue was over 400kB in size, which generated
 +   many complaints. ​ There is no need to create such a long issue, when 
 +   more issues can be published. ​ This issue should comfortably fit on
 +   two sides of a 1541 disk, a 1571 disk, or a 1581 disk.
 +o  Stable publication dates. ​ Circumstances (college, job hunt), made it 
 +   hard for the previous editor to maintain a schedule, so no blame is laid,
 +   but the magazine does need some stability. ​ Although possibly unrealistic,​
 +   I am striving to publish C=Hacking quarterly, with the following schedule:
 +      ​
 +      Publication Date        Submission Deadline
 +      March, 1996             ​February 10, 1996
 +      June, 1996              May 10, 1996
 +      September, 1996         ​Auguest 10, 1996
 +      December 1996           ​November 10, 1996
 +   If article submissions keep up, a switch to bi-monthly publication might
 +   be warranted, but I won't get too far ahead.
 +o  Fully HTML-ized version of the magazine. ​ Issue 11 contains many
 +   ​improvements designed to make the publication of an World Wide Web
 +   ​readable version of the magazine easier. ​ Look for the HTML version of
 +   this and older issue at URL: http://​​~brain/​chacking/​. ​  
 +Many people have compared Commodore Hacking to the defunct _Transactor_ ​
 +magazine, which is encouraging. ​ The new format will hopefully add to the
 +appeal of Commodore Hacking.
 +Although many of you know me or of me through previous Commodore work, this
 +is my first editorship, so please comment on the changes I have made and what
 +your opinions on each are.  As the magazine is for you, the reader, it is
 +always important to keep the reader happy.
 +Sadly, some things, like the WWW browser for C=Hacking, did not get done,
 +but there is always next time.
 +Enjoy YOUR magazine,
 +Jim Brain (
 +====== Input/Ouput ======
 +Obviously, Commodore Hacking depends on the comments and article submissions
 +from the Commodore community to flourish. ​ Everyone sees the articles, but
 +let's not forget those comments. ​ They are very helpful, and every attempt
 +is made to address concerns in them.  Address any comments, concerns, or
 +suggestions to:
 +Commodore Hacking
 +602 N. Lemen
 +Fenton, MI  48430 (Internet)
 +#(A)c: Need Samples of Samples  ​
 +From: "​Clifford \"​Paska\"​ Anderson"​ <​>​
 +Dear C=Hacking,
 +Hey.  Just writing to mention something I'd like to see in C=Hacking, if 
 +you can find someone to write about it.  I am interested in knowing more 
 +about how samples work on the 64, how to play, etc.
 + ​_ ​   _       _
 +Si vales, valeo
 +Your wish is granted. ​ Check out this issue'​s Hi Tech Trickery ​
 +(Reference: trick) by George Taylor for some insight into playing ​
 +#(A)c: You Index, I Index, We all Index
 +Dear C=Hacking,
 +I would like to offer an idea for the Chacking mag. Every now and then 
 +I'll come across a reference to an article in this or that Chacking Issue.
 +I run Zed and load that issue in (Thanks Mr Bruce) and start hunting for 
 +the start of the article. ​
 +This process would be made a lot easier if Chacking used a method of 
 +indexing I have seen used in several publications.
 +It involves the search function of most text editors. A 2/3/4 ? letter ​
 +code (with a delimiter char to prevent unintentional matches) that the 
 +reader uses to find the beginning of the article.
 +(Outline of suggestion deleted)
 +I would like to add a personal thanks for all your efforts on behalf of 
 +the C= community.
 +Al Anger
 +13841 SW 139 Ct.
 +Miami Fl. 33186
 +(305) 233-4689
 +Fire up that search function in your favorite editor. ​ Issue 11 now
 +contains the QuickFind indexing system that should fit your needs. ​ See 
 +"​Reading C=Hacking"​ (Reference: rch) for information on how to utilize the 
 +indexing system. ​ We would like to add that C=Hacking appreciates your 
 +personal thanks.
 +#(A)c: Are We Talking the Same Language?
 +From: Jack Vander White <​>​
 +Dear C=Hacking,
 +Noticed something that may be a potential problem and thought I would 
 +let you know.
 +  ​
 +Way back when hacking mag started I didn't have Internet access. the first
 +couple of issues were sent to me by fellows who had downloaded them and in
 +downloading had set their terms to translate them to PETSCII. This of 
 +course changed the coding in the uuencoding parts of the magazine and made
 +them decode improperly. ​
 +Since then I have my own access and have re-downloaded them and posted ​
 +them on my BBS in the original straight ASCII so that those who download
 +them can uudecode the relevant parts and then translate the text for 
 +  ​
 +Since different Terminal Programs are using different Translation tables
 +I can see all kinds of problems in this for the average user.
 +  ​
 +Any comment????
 +  ​
 +Jack VW
 +The HTML version of Commodore Hacking utilizes the ISO-8859-1 text
 +encoding standard, while the text version utilizes its 7-bit subset, ​
 +commonly called ASCII. ​ Normally, the encoding standard poses little
 +problem, as text uses but a nominal set of characters which can be
 +translated between PETSCII and ASCII. ​ However, as you point out, the
 +uucode format uses more characters, which may or may not be
 +translated correctly. ​ To circumvent this problem, which only occurs
 +in the text version, the files embedded in a Commodore Hacking issue 
 +should be uudecoded prior to converting the file to anoy alternate
 +====== Newsfront ======
 +*  Although not new news, Some still may not know that Creative Micro Designs,
 +   Inc., is currently designing the Super64CPU accelerator. ​ This external
 +   ​3"​ tall by 6" wide by 2" deep cartridge will allow Commodore computers
 +   to execute programs at either 10MHz or 20MHz  (actually, 9 and 18 MHz, 
 +   ​realistically). ​ The unit uses the Western Design Center'​s 65C816S CPU,
 +   which is object code compatible with the 6502/​6510/​8502. ​ The CPU, used
 +   in the Super Nintendo Entertainment System as well as other products, can
 +   be switched between 6502 emulation mode and "​native"​ mode, which allows
 +   the following:
 +   ​o ​ access to 16 MB of RAM without bank switching.
 +   ​o ​ 64kB stack.
 +   ​o ​ 64kB zero page (now called "​direct access"​).
 +   ​o ​ 16 bit registers.
 +   ​o ​ Support for virtual memory systems.
 +   The unit is scheduled for production in February, 1996, and will cost 
 +   ​~US$149.00 for the 10MHz unit and US$199.00 for the 20MHz unit.  ​
 +*  The following information was relayed to the USENET newsgroup comp.sys.cbm
 +   by Jack Vanderhite, editor and publisher of COMMODORE CEE disk magazine:
 +      Rather than reply to all the messages asking about DIEHARD I will tell
 +      all what has been happening over the last few days. 
 +      Brian Crosthwaite,​ Publisher of Diehard, contacted CMD, Loadstar, and
 +      Commodore CEE this week with the following form letter faxed to each of
 +      us:
 +      -----------
 +      ​
 +      Diehard, the Flyer for commodore 8bitters is planning to cease 
 +      publication and we are looking to transfer our subscription fulfillment.
 +      Our number of outstanding subscribers is approximately 8,400 and I 
 +      would be willing to throw in the balance of the list, totaling ​
 +      approximately 12,000.
 +      Please call me at (xxx)xxx-xxxx if you are interested in acquiring these
 +      readers and names.
 +      ​
 +      Sincerely, ​
 +      ​
 +      Brian L. Crosthwaite
 +      Publisher
 +      ​
 +      ----------
 +      ​
 +      Each of us did contact Brian for further details. They are bleak. The
 +      total number of paper issues due to subscribers is approximately 64,000.
 +      This does not count the approximately 1,200 spinner subscribers which
 +      would make approximately 10,000 disks due. 
 +      ​
 +      The cost of publishing alone would amount to approximately $100,000 for
 +      printing, layout, disks, ,mail cost, etc. Not taking into account the
 +      cost of articles, etc.
 +      ​
 +      when asked about money Brian'​s only comment was "There is none. It'​s ​
 +      gone."
 +      a further complication is that Tom Netsel told me last week that General
 +      Media says that Brian has assumed the obligation to deliver the balance
 +      of the Gazette subscriptions. I questioned Brian about this. Brian says 
 +      that general media faxed him the terms of transference of the 
 +      obligation and that he faxed back an acceptance of the terms. ​ While I 
 +      have not seen the actual faxes involved it does sound like offer and 
 +      acceptance of a binding contract from here.
 +      ​
 +      Obviously, all of us have rejected this offer. I have been told that 
 +      there is an issue of Diehard at the printers, probably printed. ​
 +      However, the printing bill alone is over $8,000 plus the cost 
 +      of mailing. Since there is no money it sits there. ​  
 +      ​
 +      If anyone were willing to assume the total obligations they would have 
 +      to assume a liability of well over $100,000 over the next year before ​
 +      any returns from renewals would even make a dent in this huge 
 +      obligation.
 +      ​
 +      Please Note: I am putting this out as a public message. This is ALL I 
 +      know.
 +      Please do not come back at me asking questions. I have nothing more I can
 +      add to this.   
 +      ​
 +      Jack VW
 +    ​
 +   So, if you have outstanding issues of dieHard due you, as the editor ​
 +   ​does, ​ the fears have been confirmed. ​ However, for those who purchased ​
 +   the dieHard "​Spinner"​ disk, read on for the encouraging news.
 +*  The LOADSTAR disk magazine has been recently purchased from Softdisk ​
 +   ​Publishing by LOADSTAR principles Fender Tucker and Julie Mangham. ​ Now 
 +   owned by J and F Publishing, a corporation founded by Mr. Tucker and Mrs.
 +   ​Mangham,​ provide the magazine with even more flexibility ​  ​Tucker ​
 +   ​states that now LOADSTAR is "more solvent then ever before"​. ​ Existing ​
 +   ​subscribers will see no difference with this change, as Softdisk and 
 +   ​LOADSTAR will continue to maintain a close relationship,​ with Softdisk ​
 +   ​continuing to handle subscriptions,​ in addition to other tasks.  ​
 +   In related news, J and F Publishing has agreed to fulfill the remainder ​
 +   of the outstading dieHard "​Spinner"​ subscriptions. ​ Although ​
 +   ​unfortunate that dieHard left its subscribers out in the cold, it 
 +   is commendable that these subscriptions will be fulfilled with 
 +   ​LOADSTAR issues. ​ The agreement will provide one issue of LOADSTAR ​
 +   for every two issues of the Spinner, as the Spinner was a single ​
 +   disk, whereas LOADSTAR is double that.  No word has been heard yet on 
 +   the fate of dieHard paper subscriptions. ​ All 1200 Spinner ​
 +   ​subscribers should be receiving information about the 
 +   ​subscription fulfillment soon.
 +*  For those people wishing to use the Internet with their Commodore 64, 
 +   only to find out that the local Internet Service Provider (ISP) only 
 +   ​provides Serial Line Internet Protocol (SLIP) service with no shell 
 +   ​account service, help is coming. ​ A prototype Transmissions Control ​
 +   ​Protocol/​Internet Protocol (TCP/IP) protocol stack with SLIP support has 
 +   been developed by Daniel Dallmann ​
 +   ​( of Germany. ​ Available now 
 +   via the Internet (ftp://​​pub/​c64),​ the package is by no 
 +   means complete, but does include the basic TCP/IP stack, the SLIP driver, ​
 +   and a rudimentary Telnet application.  ​
 +*  Another Commodore hardware/​software supplier has announced its online
 +   ​presence:​ Performance Peripherals Incorporated. ​ Maker of the RAMDrive
 +   and BB units (BBGRAM, BBRTC, and BBGRam), PPI published an online catalog ​
 +   that users can retrieve via the C=Hacking WWW Site 
 +   ​(http://​​~brain/​pub/​PPI_catalog.11.95.txt) and the 
 +   ​C=Hacking MAILSERV server. (send PPI_catalog.11.95.txt). ​ In addition to
 +   ​importing FLASH8 (the 8MHz accelerator cartridge from Germany), PPI 
 +   ​manufactures CommPort, which is a 6551 UART cartridge (ala Swiftlink) ​
 +   which has the basic 6551 functionality with the addition of switch ​
 +   ​selectable NMI or IRQ interrupt triggering and switch-selectable ​
 +   ​$de00/​$df00 addressing.  ​
 +*  PPI has one more trick up its sleeve. ​ PPI will be carrying Novaterm 9.6,
 +   the newest version of Nick Rossi'​s oft-used terminal program for the 
 +   ​C64. ​ The blurb follows:
 +      Novaterm 9.6 is a complete terminal emulation program on cartridge for 
 +      the C64. Novaterm has several features such as 80 column ANSI on a stock 
 +      C64, and compatibility with CommPort, RAMDrive, BBGRam, and many other 
 +      hardware devices. Just connect a BBGRam, and Novaterm can use it as a
 +      "​buffer"​ for storing text or as a "​virtual disk" for quickly and easily
 +      downloading files. Definately the perfect setup for Internet usage. And 
 +      since Novaterm is in cartridge form, the program loads in seconds, not 
 +      minutes. Novaterm 9.6 is the latest version programmed by NICK ROSSI. ​
 +      Includes autoboot switch.
 +====== Hi Tech Trickery: Sample Dither ======
 +by George Taylor (
 +#(A): Introduction
 +You may know of dithering in graphics. ​ It is when a limited number of
 +colors are used to simulate more.  This is done by randomly arranging the
 +pixels so they blend at a distance, creating an average of the shades.
 +Here, screen space is being averaged, and more shades are being produced.
 +In playing samples, time is being averaged, and more bits are being produced.
 +#(A): Dithering Sound
 +Let's say we do the following:
 +                lda #8
 +                sta $d418       This code toggles the low bit of the output.
 +                lda #9
 +                sta $d418
 +Over an average of time, this is the same as:
 +                lda #8.5        But we can't really do this.
 +                sta $d418
 +This idea can be used to easily do 5 bit sound. ​ Basically, we take a
 +5 bit sample, shift right, then add 0.  If bit 0 was high,
 +it will increment the 4 bit number. ​ Then as this adding takes place,
 +toggling bit 0, it will average out to give half a bit.
 +#(A): Is There a Catch?
 +There is one drawback though. ​ This toggling can be heard as the high
 +frequency square wave it resembles. ​ You must use a high enough sample
 +rate so this can't be heard. ​ Also it takes two bit toggles to create the
 +5th bit, so you must double the sample rate.  In order to play 8.5, for
 +example, you must play 8 and then 9, so the 8 and 9 must take half the normal
 +time, or your sample will play too slow.
 +One other problem is that there is the possibility of overflow. ​ In this
 +case you can use hard clipping on the signal. ​ In other words, the 5 bit
 +sample 31 will be played at 16, so instead play 15.
 +This is actually called pulse width modulation. ​ It is a good example for
 +illustrating sample dithering. ​ For example, you can play TRUE 16 bit sound,
 +even with one bit. To do this, take the 16 bit sample, add a 12 bit random
 +number, then play the high 4 bits of this result. ​ Also remember the clipping
 +problem as mentioned above.
 +@(A): How Is This Like Pulse Width Modulation?
 +The random number range is proportional to the 16 bit sample. ​ If the 16 bit
 +number is high, then it is very likely the 0 bit (toggle bit) is high.  It is
 +the random number which allows the toggle bit to change. ​ So now we have 16
 +bit sound with 16db signal to noise ratio.
 +There are some more advanced technical issues to this.  The kind of random
 +number you choose affects the results. ​ You need a triangle density function
 +for perfect linearity (ie., for no distortion). ​ This is the relationship
 +of random numbers in the sequence, and does not affect the probability
 +distribution,​ which should be equal. ​ The choice of density function is a
 +tradeoff between added noise and linearity. ​ I used pulse density function
 +in my demo, which is non-filtered random numbers, and it's ok but I can
 +still hear some noise pumping.
 +#(A): Conclusion
 +Enjoy the ditherdigi!
 +#(A)5bit: Listing One:  5 bit play routine
 +Memory map:
 +3:     start page of sample
 +4:     end page of sample
 +5:     ​sample period (remmber to play twice normal speed)
 +fb,fc: pointer to sample
 +start lda 3
 +      sta $fc
 +      lda #0
 +      sta $fb           ; initialize sample pointer
 +      lda #$b
 +      sta $d011         ; blank screen for better timing
 +      sei               ; disable interrupts for better timing
 +play  lda ($fb),y
 +      lsr
 +      sta $d418         ; push sample
 +      ldx 5
 +d     dex
 +      bne d
 +      pha
 +      nop
 +      adc #0
 +      cmp #$10
 +      beq s1
 +      sta $d418
 +      bpl s
 +s1    nop
 +      nop
 +      nop
 +s     pla
 +      ldx 5
 +d1    dex
 +      bne d1
 +      iny
 +      bne play
 +      inc fc
 +      lda fc
 +      cmp 4
 +      bne play
 +      lda #$1b
 +      sta $d011
 +      cli
 +end   rts
 +#(A): References
 +Consult the proceedings of the ACM for further info on digi dithering.
 +====== Hacking the Mags ======
 +Not everything good and/or technical comes from Commodore Hacking, which is
 +as it should be.  (I still think we have the most, though...) ​ Thus, let's
 +spotlight some good and/or technical reading from the other Commodore ​
 +If you know of a magazine that you would like to see summarized here, let 
 +C=Hacking know about it.  These summaries are only limited by Commodore ​
 +Hacking'​s inability to purchase subscriptions to all the Commodore ​
 +publications available. ​ We are very grateful to those publications that send
 +complimentary copies of their publications for review.
 +   ​Volume 1, Issues 1 and 2 came all packaged as one "​mega-issue"​. This
 +   ​particular double issue should be renamed the memory map issue, with 
 +   I/O and/or memory maps for the VIC, 64, 128, and PET computers.  ​
 +   ​Information on 6522 bugs and on the 6526 CIA chips that was cut from the 
 +   final compilation of the Commodore 64 Prorammer'​s Reference Guide is
 +   of interest to Commodore Haking readers. ​ Some of the information is
 +   ​culled from the Internet: the 64 memory maps, the info on the 6522, and a 
 +   list of all the CSG produced IC numbers with descriptions. ​ Of course, these
 +   files are also available on the Internet, if you have access. ​ Howver, for 
 +   those who don't know where to look or for those without access, the 
 +   ​information is welcome. Issue 3 has a PCX to GEOPaint converter, much like
 +   ​_LOADSTAR_,​ and Issue 4 will begin a column on PAL to NTSC program ​
 +   ​conversions. ​ One thing we'd like to see at Commodore Hacking is a better
 +   menu program, as the current one is somewhat hard to navigate.
 +#(A): Commodore World
 +   Issue 10 just arrived at the computer room, with a snazzy front cover.  ​
 +   Slick paper aside, the picture of Al Anger'​s Tower 128 was a masterpiece. ​
 +   ​Editor Doug Cotton spews about the hype of Windows 95, and the first ads 
 +   for the Super 64 CPU accelerator are present. ​ If you're into hardware ​
 +   mods, you can't miss page 4, which shows some other Al Anger hacked ​
 +   ​Commodore creations. ​ Jim Butterfield'​s 4 page 65XX ML reference is 
 +   ​useful for the newer programmers,​ and Doug Cotton'​s Assembly Line topic of 
 +   ​serial routines will help those disk I/O challenged in the crowd. ​ This 
 +   issue details the high level routines, while #11 will tackle the low level 
 +   disk I/O.  Maurice Randall goes over event handling in GEOS, while Al Anger
 +   ​details how to disable the internal 1571D in the C128D. ​ Gaelyne Moranec
 +   ​touches on the Internet nitty-gritty of learning UNIX commands and 
 +   ​includes a table of UNIX-like commands found in ACE and LUnix. ​ At the end,
 +   ​though,​ C=Hacking'​s burning question is:  What hangup does Doug have with 
 +   those abstract graphics sprinkled throughout the mag?  There'​s nothing ​
 +   wrong with them, but some look like those psycho-analyst inkblot test 
 +   ​cards. ​  
 +#(A): Driven
 +   ​Driven 9 contains a rundown on USENET (written by Jim Brain), which will
 +   help those Internet "​newbies"​. ​ For those doing cross development,​ the
 +   ​review of the PC<​->​C64/​C128 networking system called 64NET by Paul Gardner-
 +   ​Stephen might help some get object code from the PC to the 64/​128. ​ Eddie
 +   ​Bourdon has some info on GEnie, including what Commodore support is
 +   ​available.  ​
 +   ​Driven 10 presents some useful WWW addresses, while XMikeX and Pegasus
 +   ​tackle the issues of apathy and pessimism in the Commodore community. ​ Both
 +   make for good reading, but the best (in our opinion) was the pessimism
 +   ​piece. ​ How many times have YOU been laughed out of CompUSA for mentioning
 +   that modem or SCSI drive was for a Commodore?
 +   Issue 138 just finished loading on the 1581 disk drive, and the disk is
 +   ​packed with information. ​ Fender Tucker goes into much detail on the
 +   ​recent changes at LOADSTAR and its new Publishing company, J and F
 +   ​Publishing. ​ Of interest to programmers is the PCX to GEOPaint converter
 +   ​program,​ written by Fender Tucker and Doreen Horne. ​ Some details on Al
 +   ​Angers machines that are shown in Commodore World are related. ​ Jeff Jones
 +   ​presents a simple program pause routine, which fiddles with the NMI 
 +   ​interrupt,​ and gives out source code as well.  The Internet 101 series takes
 +   a month off from the LOADSTAR letter in #28, but is expected back next
 +   ​month. ​ Lastly, Dave Moorman presents his fractal generator called FRACTAL
 +   ​MOUNTAINS. ​ C=Hacking couldn'​t get it to work, but we think it's user error.
 +#(A): LOADSTAR 128
 +   In Issue 29, Fender apologizes for not paying enough attention to the 800
 +   ​LOADSTAR 128 subscribers. ​ Of interest to programmers is the program listing
 +   pause program on the issue, but the rest is pretty light stuff, not to knock
 +   ​LOADSTAR. ​ Different audiences need different material.
 +#(A): Vision
 +   In Issue 7, Rick Mosdell has an article on graphics formats, updated and
 +   ​reproduced in this issue (Reference: gfx).  There is some information from
 +   ​USENET reproduced, and a list of FTP sites as posted to USENET is
 +   also presented. ​ Not much technical content in here, but C=Hacking was
 +   ​impressed with the graphics, music, and stories in the mag.  Besides, ​
 +   ​everyone needs some time to enjoy the machine. ​
 +Other magazines not covered in this rundown include _The Underground_, ​
 +_Gatekeeper_,​ _Commodore Network_, _64'​er_,​ _Atta Bitar_ (_8 bitter_), as well
 +as those C=Hacking is simply not aware of.  As soon as we can snag a copy of 
 +any of these, or get the foreign language ones in English :-), we will give 
 +you the scoop on them.  ​
 +====== Speed up RAMLink transfers with the Double-DMA Technique ======
 +by Doug Cotton ( and Mark Fellows ​
 +#(A): Introduction
 +When CMD designed the RAMLink, we tried to make the system as fast as possible,
 +but costs and complexity prohibited us from duplicating the operation of the 
 +DMA operation found in the Commodore RAM Expansion Unit (REU), ​ The 8726 DMA
 +controller found in the REU is a very complex item that allows the REU to
 +transfer one byte per 1 MHz CPU clock cycle (1 microsecond). ​ On the other 
 +hand, the RAMLink uses the 6510/8502 CPU load and store operations to transfer
 +memory from the RAMLink memory to main memory. ​ For the user who uses RL-DOS
 +and RAMDOS, the difference is not noticeable, because although the RAMLink
 +transfer is slower, RAMDOS continually pages its code in and out of main 
 +memory, effectively slowing its effective transfer speed down significantly.  ​
 +But, what if the programmer isn't using RAMDOS? ​ Then, the speed of the RAMLink
 +becomes an issue. ​ The RAMLink takes about 8 cycles to perform a transfer
 +of a byte, while the REU does it in 1.  This is significant. ​ However, if a
 +user owns both a RAMLink and an REU, there is a way to boost the transfer rate
 +of the RAMLink via software. ​ The method is called Double-DMA.  ​
 +#(A): Double-DMA Description
 +Basically, the process is quite simple. ​ Since the REU has the ability to
 +transfe memory at 1 byte/​microsecond,​ you can use the REU DMA to transfer
 +memory from the RAMLink to main memory. ​ To understand how we can do this,
 +remember that the normal RL-DOS transfer routines use the CPU to perform the
 +memory transfer. ​ Well, to do that, at least some of the RAMLink RAM must be
 +mapped into main memory. ​ To be exact, 256 bytes is mapped in.  So, to 
 +utilize the Double-DMA technique, the programmer simply makes the 
 +appropriate 256 bytes of RAMLink memory to be transferred visible in the 
 +main memory map, uses the REU to transfer that 256 bytes to the REU, and then
 +uses the REU to transfer the 256 bytes in the REU to its destination in the
 +main memory map. Thus, the Double-DMA technique will allow the RAMLink to
 +transfer data at rouyghly 1/2 the speed of the REU, or 3-4 times faster than
 +using the CPU to perform transfers.
 +#(A): The RAMLink memory map
 +To achieve this transfer speed gain, the programmer must forego RL-DOS
 +usage and write specialized transfer routines. ​ To do that, we need to
 +discuss how the RAMLink maps itself into main memory and detail the various
 +RAMLink registers needed to make this feat possible:
 +Address Description
 +------- -----------
 +$de00   256 bytes of data (See $dfc0-$dfc3 for more information)
 +$df7e   write to this location to activate the RAMLink hardware
 +$df7f   write to this location to deactivate the RAMLink hardware.
 +$dfa0   lo byte of requested RAMCard memory page
 +$dfa1   hi byte of requested RAMCard memory page
 +$dfc0   write to this location to show RL variable RAM at $de00 (default)
 +$dfc1   write to this location to show RAMCard memory at $de00
 +$dfc2   write to this location to show the RAM Port device $de00 page at $de00
 +$dfc0   write to this location to show Pass-Thru Port dev. $de00 page at $de00
 +For all locations that have the description "write to this address...",​ the
 +program can safely write any byte to those locations, as the RAMLink hardware
 +simply waits for an access, not any particular byte to be written.
 +#(A): Order of Operations
 +Although the Double-DMA technique relies on use of the REU, it is beyond the
 +scope of this article to detail how to access the REU RAM under programmatic
 +control. ​ For more information on transferring data from the Commodore 128/64
 +and the 17XX REU, refer to the back of a REU owner'​s manual.  ​
 +The following steps will realize the Double-DMA method:
 +Notes: ​ P = PAGE in RAMCard RAM to be transferred to/from
 +        A = PAGE of RAM in main memory to be transferred to/from
 +        X = single page of memory in REU used as temp RAM
 + ​1) ​ if computer = 128, set up correct RAM bank
 + ​2) ​ make I/O visible in main memory
 + ​3) ​ sei
 + ​4) ​ sta $df7e - activate RAMLink
 + ​5) ​ lda #<P
 + ​6) ​ sta $dfa0
 + ​7) ​ lda #>P
 + ​8) ​ sta $dfa1
 + ​9) ​ sta $dfc1 - make $de00 show PAGE of RAM on RAMCard
 +Now, with the RAMLink hardware enabled in this way, the REU registers are
 +also visible, so one can do a double DMA transfer at this point. ​ There
 +are two choices:
 +Transfer A->P:
 +10)  set up REU for A->X transfer
 +11)  initiate REU DMA transfer
 +12)  set up REU for X->$de00 transfer
 +13)  initiate REU DMA transfer
 +Transfer P->A
 +10)  set up REU for X->$de00 transfer
 +11)  initiate REU DMA transfer
 +12)  set up REU for A->X transfer
 +13)  initiate REU DMA transfer
 +Now, to go on:
 +14)  If more byte need transferrring,​ A=A+1, P=P+1, goto 5
 +15)  sta $dfc1 - restore contents of $de00
 +15)  sta $df7f - deactivate RAMLink hardware
 +16)  if computer = 128, restore bank
 +17)  restore I/O visibility if needed
 +18)  cli
 +#(A): Address Translation
 +To effectively use the Double-DMA technique, a programmer will want to
 +set up a DACC partition in the RAMLink for use as external RAM.  The
 +programmer will need to determine the start address of the partition with the
 +RL-DOS G-P command (or its sister command, G-[shift]P) ​ This command will
 +return the address of the DACC partition, or will it?
 +The answer is: Maybe. ​ If a user has inserted an REU into the RAMLink RAM
 +port and has the Normal/​Direct swittch set to Normal, RL-DOS uses REU memory ​
 +as the lowest RAM in the RAMLink memory map. However, when directly accessing ​
 +the RAMLink and bypassing RL-DOS, the REU is not mapped into the RAMLink ​
 +memory map. So, for such a condition, the code that determines the start of 
 +the DACC partition must SUBTRACT the size of the REU from the address returned
 +by the G-P command. ​ It's non-utopian,​ but the program need only do this once.
 +However, for such an REU configuration,​ one must take care to ensure that at 
 +least 256 bytes of REU RAM is available and not already in use before ​
 +utilizing the Double-DMA technique.
 +#(A): Performance
 +Craig Bruce, who has implemented this technique in his ACE operating system,
 +provides the following performance figures for different access techniques:
 +Type            Bandwidth ​  ​Latency Notes
 +                (bytes/sec) (~usec)
 +------------- ​  ​--------- ​  ​------- -----
 +REU             ​1,​007,​641 ​     65.8 REU in Direct mode
 +REU thru RL     ​1,​007,​641 ​     77.8 REU in RAM Port in Normal mode
 +RAMLink ​          ​105,​792 ​    199.2 Regular RAMLink access
 +RL with REU       ​372,​827 ​    319.8 Double-DMA
 +Internal RAM0     ​120,​181 ​     44.2 Zero-page
 +Internal RAM1      80,​283 ​     56.3 All main memory except zero-page
 +So, using this technique in ACE results in a 3.7x increase in transfer speed.
 +For some applications,​ that is well worth the trouble.
 +#(A): Conclusion
 +Obviously, CMD recommends that the RL-DOS be used for most operations, but
 +we realize that some programmers simply need faster transfer rates. ​ The
 +Double-DMA technique should provide the speed needed from the RAMLink. ​
 +Obviously, since this technique bypasses RL-DOS, code using it can
 +potentially corrupt RAMLink memory if errors occur or if the technique is
 +improperly used. When using the technique, we recommend extensive testing
 +using various DACC partitions and different REU configurations to ensure
 +proper operation.  ​
 +#(A)ddcode: Double-DMA Code
 +Following is a set of functions that will perform transfers using Double-DMA.
 +They are copied from the routines used in Craig Bruce'​s ACE operating system,
 +Release 14, which incorporates the Double-DMA method. ​ We thank Craig for
 +the code below:
 +; Name:        Double-DMA memory transfer
 +; Author: ​     Craig Bruce
 +; Date:        1995-12-4
 +; Description:​ The following routines use the Double-DMA technique to transfer
 +;              memory to/from main RAM and the RAMLink. ​ If no RL is present,
 +;              normal CPU transfer methods are utilized.
 +; Variables: ​  [mp] holds the address of RAMCard memory to transfer
 +;              ramlinkNearPtr hold the address of main memory to transfer
 +;              ramlinkLength is length of data to transfer
 +;              ramlinkOpcode = $90: main memory -> RL
 +;                            = $91: RL -> main memory ​
 +reu = $df00
 +rlActivate ​  = $df7e
 +rlDeactivate = $df7f
 +rlSram ​      = $dfc0
 +rlPageSelect = $dfa0
 +rlPageActivate = $dfc1
 +rlPageData ​  = $de00
 +ramlinkOpcode .buf 1
 +ramlinkLength .buf 2
 +ramlinkNearPtr .buf 2
 +ramlinkMpSave .buf 3
 +ramlinkZpSave .buf 2
 +ramlinkOp = *  ;( [mp]=farPtr,​ ramlinkNearPtr,​ ramlinkLength,​ ramlinkOpcode )
 +   lda mp+0
 +   ldy mp+1
 +   ldx mp+2
 +   sta ramlinkMpSave+0
 +   sty ramlinkMpSave+1
 +   stx ramlinkMpSave+2
 +   lda zp+0
 +   ldy zp+1
 +   sta ramlinkZpSave+0
 +   sty ramlinkZpSave+1
 +   lda ramlinkNearPtr+0
 +   ldy ramlinkNearPtr+1
 +   sta zp+0
 +   sty zp+1
 +   clc
 +   lda mp+1
 +   adc aceRamlinkStart+0
 +   sta mp+1
 +   lda mp+2
 +   adc aceRamlinkStart+1
 +   sta mp+2
 +-  lda ramlinkLength+0
 +   ora ramlinkLength+1
 +   beq +
 +   jsr rlTransferChunk
 +   jmp -
 ++  lda ramlinkMpSave+0
 +   ldy ramlinkMpSave+1
 +   ldx ramlinkMpSave+2
 +   sta mp+0
 +   sty mp+1
 +   stx mp+2
 +   lda ramlinkZpSave+0
 +   ldy ramlinkZpSave+1
 +   sta zp+0
 +   sty zp+1
 +   clc
 +   rts
 +   ​rlTrSize .buf 1
 +   ​rlTransferChunk = *  ;( [mp]=rlmem, (zp)=nearmem,​ rlLength, rlOpcode )
 +   ;** figure maximum page operation
 +   lda ramlinkLength+1
 +   beq +
 +   lda #0
 +   ldx mp+0
 +   beq rlTrDo
 +   sec
 +   sbc mp+0
 +   jmp rlTrDo
 ++  lda mp+0
 +   beq +
 +   lda #0
 +   sec
 +   sbc mp+0
 +   cmp ramlinkLength+0
 +   bcc rlTrDo
 ++  lda ramlinkLength+0
 +   ;** do the transfer
 +   ​rlTrDo = *
 +   tay
 +   sty rlTrSize
 +   jsr rlPageOp
 +   ;** update the pointers and remaining length
 +   clc
 +   lda rlTrSize
 +   bne +
 +   inc mp+1
 +   inc zp+1
 +   dec ramlinkLength+1
 +   rts
 ++  adc mp+0
 +   sta mp+0
 +   bcc +
 +   inc mp+1
 ++  clc
 +   lda zp+0
 +   adc rlTrSize
 +   sta zp+0
 +   bcc +
 +   inc zp+1
 ++  sec
 +   lda ramlinkLength+0
 +   sbc rlTrSize
 +   sta ramlinkLength+0
 +   bcs +
 +   dec ramlinkLength+1
 ++  rts
 +   ​rlPageOp = *  ;( [mp]=rlmem, (zp)=nearmem,​ .Y=bytes, ramlinkOpcode )
 +   php
 +   sei
 +   sta rlActivate
 +   lda mp+1
 +   sta rlPageSelect+0
 +   lda mp+2
 +   sta rlPageSelect+1
 +   sta rlPageActivate
 +   lda aceReuRlSpeedPage+3
 +   bne rlPageOpReu ​ ;xxx dependency on aceMemNull==0
 +   ​rlPageOpNonReu = *
 +   tya
 +   clc
 +   adc mp+0
 +   tax
 +   lda ramlinkOpcode
 +   cmp #$91
 +   bne rlPageOpWrite
 +   dex
 +   dey
 +   beq +
 +-  lda rlPageData,​x
 +   sta (zp),y
 +   dex
 +   dey
 +   bne -
 ++  lda rlPageData,​x
 +   sta (zp),y
 +   jmp rlPageOpContinue
 +   ​rlPageOpWrite = *
 +   dex
 +   dey
 +   beq +
 +-  lda (zp),y
 +   sta rlPageData,​x
 +   dex
 +   dey
 +   bne -
 ++  lda (zp),y
 +   sta rlPageData,​x
 +   ​rlPageOpContinue = *
 +   sta rlSram
 +   sta rlDeactivate
 +   plp
 +   rts
 +   ​rlPageOpReu = * ;( [mp]=rlmem, (zp)=nearmem,​ .Y=bytes, ramlinkOpcode )
 +   ;** ramlink hardware already switched in
 +   ldx #1
 +   tya
 +   beq +
 +   ldx #0
 +   cmp #0  ;xx cut-off value
 +   bcc rlPageOpNonReu
 ++  ldy ramlinkOpcode
 +   cpy #$90
 +   beq +
 +   ldy #$90            ;​rl->​reu->​intern
 +   jsr rlPageOpReuRl
 +   ldy #$91
 +   jsr rlPageOpReuIntern
 +   jmp ++
 ++  ldy #$90            ;​intern->​reu->​rl
 +   jsr rlPageOpReuIntern
 +   ldy #$91
 +   jsr rlPageOpReuRl
 ++  sta rlSram
 +   sta rlDeactivate
 +   plp
 +   rts
 +   ​rlPageOpReuIntern = *  ;( .AX=bytes, .Y=op )
 +   sta reu+7  ;len
 +   stx reu+8
 +   sty temp1
 +   pha
 +   lda zp+0
 +   ldy zp+1
 +   sta reu+2
 +   sty reu+3
 +   lda aceReuRlSpeedPage+0
 +   ldy aceReuRlSpeedPage+1
 +   sta reu+4
 +   sty reu+5
 +   lda aceReuRlSpeedPage+2
 +   sta reu+6
 +.if computer-64
 +   ldy vic+$30
 +   lda #0
 +   sta vic+$30
 +   lda temp1
 +   sta reu+1
 +.if computer-64
 +   sty vic+$30
 +   pla
 +   rts
 +   ​rlPageOpReuRl = *  ;( .AX=bytes, .Y=op )
 +   sta reu+7  ;len
 +   stx reu+8
 +   sty temp1
 +   pha
 +   lda mp+0
 +   ldy #>​rlPageData
 +   sta reu+2
 +   sty reu+3
 +   lda aceReuRlSpeedPage+0
 +   ldy aceReuRlSpeedPage+1
 +   sta reu+4
 +   sty reu+5
 +   lda aceReuRlSpeedPage+2
 +   sta reu+6
 +.if computer-64
 +   ldy vic+$30
 +   lda #0
 +   sta vic+$30
 +   lda temp1
 +   sta reu+1
 +.if computer-64
 +   sty vic+$30
 +   pla
 +   rts
 +====== UseNuggets ======
 +COMP.SYS.CBM: ​ The breeding ground of programmers and users alike. ​ Let's
 +see what topics are showing up this month:
 +#(A): We Want More Power!
 +   ​CMD'​s announcement of the Super64 CPU accelerator got things stirred up
 +   in the newsgroup. ​ When it was announced that the initial product would run
 +   on a C64 or on a C128 in 64 mode only, some angry C128 128 mode users
 +   ​vented all over the place. ​ Everything from people wondering aloud what
 +   extra work the 128 version would require to threats of non-purchase of
 +   the unit ensued. ​ Then, just as the first wave of fighting subsided, the
 +   next wave started, programmers worried about RAM transfer speed bottlenecks
 +   ​questioned CMD's decision not to include a DMA device on the unit to
 +   speed data transfers. ​ CMD's response:
 +      From: Doug Cotton <​>​
 +      Newsgroups: comp.sys.cbm
 +      Subject: Re: Power Users!
 +      Date: 28 Nov 1995 00:59:26 GMT
 +      Organization:​ Creative Micro Designs, Inc.
 +      ​
 +      There were some earlier questions about how fast memory transfers ​
 +      could be accomplished with the accelerator,​ and at least one 
 +      individual emailed me over the lack of a DMA controller. I obtained ​
 +      some figures from Mark concerning this. Presently, the DMA transfers
 +      using an REU transfers a byte in 1 microsecond. The accelerator can 
 +      achieve this same speed when transferring data from either ​
 +      on-board static RAM, or from expansion memory (slower DRAM) to the 
 +      host computer RAM. Transfers internally (from static RAM to static ​
 +      RAM) will take .35 microseconds per byte (350 nanoseconds). ​
 +      Transfers from RAMLink RAMCard RAM (direct style) to the host 
 +      computer RAM will take about 2 microseconds per byte. The only figures ​
 +      I don't have yet are for transfers between on-board static RAM 
 +      and expansion DRAM, but this will be governed by the speed of the 
 +      DRAM itself, and the number of wait-states required. It definately ​
 +      will be faster than 1 byte per microsecond though. So the only 
 +      thing slower than a current DMA operation is transferring to and 
 +      from RAMLink RAMCard memory, which is still pretty impressive at 
 +      half the speed of present DMA transfers. ​  
 +      ​
 +      Given these speeds, the cost of high-speed DMA controllers ($$$$), and 
 +      a real lack of anywhere to put one on the main board, I think 
 +      going without a DMA controller is reasonable. If you really want 
 +      one, though, there'​s always the high-speed expansion port, and 
 +      a do-it-yourself project.
 +      ​
 +      Doug Cotton
 +      ​
 +   ​Notice the tiny "high speed expansion port" mention at the end.  Reports
 +   ​indicate that such a port or ports will definitely appear on the unit,
 +   but it is still undetermined whether a single connector or a small 
 +   ​expansion bus will be utilized. ​ Commodore Hacking recommends the latter,
 +   as more options for hardware mods are available.
 +#(A): Let's all design the Commodore 64 Laptop!
 +   Yes, the dreamers are at it once again. ​ Starting in late October, the
 +   net was abuzz with thoughts on what should be included on a Commodore
 +   ​Laptop. The designs were flying fast and furious, with many different
 +   ​features discussed. ​ It was agreed that the laptop would need to be
 +   a power sipper and have an LCD screen and a keyboard. ​ However, that
 +   was where agreement ended. ​ Some of following items were bantered about:
 +   CPU:
 +   ​o ​ "​really fast" 6510
 +   ​o ​ 65C816S
 +   Disk:
 +   ​o ​ FLASH RAM cards.
 +   ​o ​ built in hard drive
 +   ​o ​ low power 1581 or CMD FD2000/4000
 +   RAM
 +   ​o ​ definitely more than 64kB, but disagreement as to how much more.
 +   Video
 +   ​o ​ VIC-II compatibility with more modes.
 +   ​o ​ VIC-III as found in Commodore 65
 +   Sound
 +   ​o ​ Built in stereo SIDs
 +   ​o ​ Quad SIDs
 +   So, on and on it went.  Some got down to the nitty gritty of planning
 +   ​designs for chips. ​ Some wanted to put the SIDs into one chip, while 
 +   ​others wanted a SID/VIC/CPU single chip solution.  ​
 +   ​It'​s December, and the thread is still going strong, but a few great
 +   ​things have surfaced, which is why you can't just discount this type of
 +   ​dreaming:​
 +   ​o ​ Someone posted the procedure for modifying the C64 to run on
 +      battery power.
 +   ​o ​ A few people started looking into how much money such designing would
 +      require.
 +   ​o ​ Most people who thought disk media should be included agreed that the 
 +      CMD FD drive could/​should be used.  ​
 +   ​o ​ Everyone woke up and noticed that the NMOS CPU process used for the
 +      fabbibng of the CBM chips was power hungry and ill-suited to battery
 +      operation.
 +   ​C=Hacking encourages users to answer the quetion: My dream Commodore
 +   ​laptop computer would include.... ​ Send you entries to Commodore
 +   ​Hacking ( with the subject "​LAPTOP"​. ​ We'll print
 +   the best entries next issue.
 +   ​Everyone seems to think that CMD is going to have one in development ​
 +   ​before long.  Dunno. ​ Commodore Hacking has heard rumors of what is going
 +   on at CMD, but we haven'​t heard about the laptop project. ​ Of course, ​
 +   ​we'​re not SPECIAL or anything.... :-)
 +#(A): The Tower of Power
 +   It seems Al Anger'​s ( Tower 128 picture on Commodore World'​s
 +   Issue 10 cover got everyone excited. ​ A couple of people were sending Al
 +   email about it, Commodore Hacking asked some questions, and some USENETters
 +   were deciding how to do it themselves. ​ Al states that $2000 would just
 +   about cover it, which turned a few enquiring minds away, we're sure.
 +   ​Still,​ the reasons given for wanting a tower were solid. ​ Commodore users
 +   are getting tired of all the clutter and mess cables, power cords,
 +   ​expansion extenders, Swiftlink cartridges, etc. make in the computer room.
 +   ​C=Hacking notes that at least one manufacturer produces tower 64 systems,
 +   but the cost is evidently more than what most folks are willing to fork
 +   over (~US$300 - US$550). ​ So, everyone is waiting for the cost to come 
 +   ​down.... ​
 +#(A): Dave Letterman, Eat Your Heart Out!
 +   The latest thread is the top ten list of games. ​ Everyone is submitting
 +   their 10 most favorite games for the CBM machines. ​ (Is anyone compiling
 +   ​these?​) ​ Anyway, it turns out this thread has a nice side effect. ​ People
 +   are reminiscing about the old games, and the Commodore users are noting
 +   that the new games "just aren't as good"​. ​ Here, here!
 +So, that wraps up the USENET this time.  We try to keep an eye out for 
 +stuff of interest, but drop us a line if you think we might miss an IMPORTANT
 +====== The Graphics Toolbox: Ellipses ======
 +by Stephen L. Judd (
 +#(A): Introduction
 +After a much needed break from Commodore 64 programming,​ I thought it
 +would be nice to construct another algorithm for the 2D graphics toolbox.
 +Since we did circles last time, a natural successor would be an algorithm
 +to draw eclipses. ​ We will first review the circle algorithm, and then build
 +upon it to draw eclipses. ​ You may recall that the algorithm had problems
 +with small-radius circles. ​ There is a very easy way to fix this, so we will
 +cover that issue as well.
 +#(A): Circles
 +   ​Recall that the equation for a circle is
 +         x^2 + y^2 = r^2
 +After taking differentials of both sides, we find that
 +         dy = -x/y dx
 +That is, if we take a step of size dx in the x-direction,​ we in principle
 +want to take a step of size dy in the y-direction.  ​
 +Next we start at the top of the circle, so that y=r and x=0.  We
 +start increasing x in step sizes of one.  We only care about step sizes
 +of one, since our basic unit is now a pixel. ​ The y-coordinate is going to
 +start piling up these dy's, and at some point the integer part of y will 
 +increase, and we get a new y-coordinate for the pixel. ​ The idea, then, is to
 +keep adding the dy's together, and once their sum is greater than one, we
 +decrease y (remember that y starts at the top of the circle).
 +The sneaky way to do this is to treat y as an integer "​constant"​. ​ Then
 +it is very easy to add the dy's together, since they have a common denominator
 +equal to y. So really all we need to do is start adding x-coordinates together,
 +and once their sum is larger than y, we decrease y and hang on to the
 +remaining fractional part of dy.  The algorithm then looks like:
 +      y=r
 +      x=0
 +      a=r
 +loop: x=x+1
 +      a=a-r
 +      if a<=0 then a=a+y:y=y-1
 +      plot (x,y)
 +      if x<y then loop:
 +Now, Chris McBride pointed something out to me.  As you may recall,
 +the algorithm breaks down for small r.  Chris said that if a is initially
 +set to r/2 instead of r, the algorithm works perfectly. ​ Why is that?
 +Recall that we add dy to itself until it is greater than one.  Wouldn'​t
 +it make more sense to add dy to itself until it is greater than 0.5?
 +That would have the effect of rounding things up.  Thus, starting at r/2
 +is like adding 0.5 to the fractional part of y -- it is the difference
 +between INT(y) and INT(y+0.5).
 +Thus, the above line
 +   a=r
 +should be changed to
 +   a=r/2
 +for a perfect circle every time.  Thus, this corresponds to adding an LSR
 +to the machine code.  Incidentally,​ this fix appeared in an earlier C=Hacking,
 +but it was placed in such a crazy place that you probably never saw it.
 +#(A): Ellipses, HO!
 +Now we can move on to eclipses. ​ Since ellipses are simply a
 +squashed circle, it seems reasonable that we could modify the above circle
 +algorithm. ​ So, let's get to it!
 +Everyone knows the equation of an eclipse:
 +   ​x^2/​a^2 + y^2/b^2 = 1
 +Upon taking differentials of both sides we have,
 +   ​2*x*dx/​a^2 + 2*y*dy/b^2 = 0
 +or, equivalently,​
 +   dy = -b^2/a^2 * x/y * dx
 +As you can see, life becomes suddenly becomes more complicated by a factor of
 +b^2/​a^2. ​ Furthermore,​ with an eclipse we only have reflection symmetries
 +through the x- and y-axis. ​ In the circle algorithm we could get away with
 +just drawing an eighth of the circle, but now we have to draw a full quarter
 +of the eclipse.
 +We will start drawing the eclipse at x=0, y=b, so that initially x
 +will increase by one at each step, and y will wait a few steps to increase.
 +At some point, though, we will want y to increase by one at each step, and
 +x to wait a few steps before increasing; in the circle algorithm we just quit
 +once we reached this point, but now we are going to need an equation for dx:
 +   dx = -a^2/b^2 * y/x * dy
 +In the circle algorithm, we used a single variable to count up and
 +tell us when it was time to increase y.  Perhaps your intuition suggests
 +that we can do an eclipse with _two_ variables; mine said the same thing,
 +so that is exactly what we will do.
 +First, let us assume we have a way of calculating b^2/a^2:
 +   E = b^2/a^2
 +I will suggest a way to perform this calculation later. ​ Let's write out
 +the first few terms in the dy summation, starting at x=0, y=b:
 +   dy1 + dy2 + ... = -E * (x0 + x1 + x2 + x3 + ...)/y
 +                   = -E * (0 + 1 + 2 + 3 + ...)/b
 +                   = - (0 + E + 2E + 3E + ...)/b
 +So, the basic structure of the algorithm is: add up 0, E, 2E, etc. until
 +the sum is larger than y.  At that point, reset the counter, keeping the
 +remainder, and decrease y.  This is where the two variables come in:
 +   X=X+1
 +   ​T2=T2+E
 +   ​T1=T1+T2
 +   IF T1>=Y THEN T1=T1-Y:​Y=Y-1
 +Do you see how it works? ​ T2 simply takes on the values 0, E, 2E, 3E, etc.,
 +and T1 is the counter. ​ Furthermore,​ you can see that once T2 is larger
 +than Y, dy will be larger than one at each step.  We need a new algorithm
 +to continue the calculation,​ and it turns out to be quite simple.
 +Look at the expression for dx above. ​ We could calculate a^2/b^2,
 +but somehow that goes against the spirit of the calculation so far.  Let's
 +instead rewrite dx slightly:
 +   dx = - y/(E*x) * dy
 +Here we have simply written a^2/b^2 as 1/(b^2/a^2) = 1/E.  But E*x is
 +exactly the variable T2 above, so we can continue the calcuation without
 +even stopping for breath:
 +   Y=Y-1
 +   ​T1=T1+Y
 +   IF T1>=T2 THEN T1=T1-T2:​X=X+1:​T2=T2+E
 +(remember that T1 keeps track of the fractional part of y).  So, we now
 +have a complete algorithm for drawing an eclipse:
 +   10 A=150:​B=16:​E=B*B/​(A*A)
 +   20 X=0:​Y=B:​T1=0:​T2=0.5
 +   30 GRAPHIC1,​1:​SLOW:​X0=160:​Y0=100:​DRAW1,​X0+A,​Y0:​DRAW1,​X0,​Y0-B
 +   40 X=X+1:​T2=T2+E
 +   50 T1=T1+T2
 +   60 IF T1>=Y THEN T1=T1-Y:​Y=Y-1
 +   70 DRAW1,​X0+X,​Y0-Y
 +   80 IF T2<Y THEN 40
 +   90 Y=Y-1
 +   100 T1=T1+Y
 +   110 IF T1>=T2 THEN T1=T1-T2:​X=X+1:​T2=T2+E
 +   120 DRAW1,​X0+X,​Y0-Y
 +   130 IF Y>0 THEN 90
 +Lines 40-80 are the top part of the eclipse, and lines 90-130 handle the
 +bottom part.  Note that T2 starts at 0.5, to round off the calculation in the
 +same spirit as we did in the circle algorithm.
 +Naturally, this algorithm has a few limitations. ​ In line 30 the start
 +and end points are plotted, so you can see how close the algorithm really is.
 +In my experiments it occasionally missed the endpoint by a pixel or two.  As 
 +usual, I was a little too lazy to investigate possible ways to get around this.
 +If you require a perfect eclipse, you need to start the calculation at x=0, y=b
 +and run it forwards (e.g. lines 40-80 above), and then do another, similar
 +calcuation, starting at x=a, y=0, and running backwards. ​ That is, for the
 +second calculation,​ calculate E2=a^2/b^2, and then run the algorithm just like
 +lines 40-80, interchanging X and Y.
 +Now we need to translate this algorithm into assembly. ​ I am going
 +to make a few assumptions:​ first, that everything fits in a byte.  In
 +particular, I require that b^2/a < 256.  This insures that b^2/a^2 < 256,
 +and also insures that T2 will not overflow (note that when x=a, T2=E*a,
 +e.g. T2=b^2/​a). ​ What this means is that eclipses can't be too squashed.
 +Next, we need to deal with the fraction E=b^2/​a^2. ​ Any number
 +like this consists of two parts, an integer part plus a fractional part
 +(e.g. a number and a decimal). ​ So, let's split E into two parts, EL and EH,
 +where EL represents the decimal part and EH the integer. ​ Now our addition
 +consists of adding together the fractional parts, and if there is an overflow,
 +increasing the integer part.  For example, if E=1.62, then EH=1 and EL=0.62.
 +We add EL to our number, and if it is greater than one, we carry the one to
 +when we add EH to our number.
 +The best thing to do is to represent EL as a fractional part of 256.
 +That is, our EL above should really be 0.62*256. ​ This way, carries and
 +overflows will be handled automatically (this will become clear in a moment).
 +Let me give some pseudo-assembly code and we'll push off the
 +explanation until later:
 +   35 GOTO 200
 +   190 REM ***********************
 +   200 XM=0:​YM=B:​X=128:​Y=0:​EH%=INT(E):​EL%=INT((E-EH%)*256+0.5)
 +   210 XM=XM+1
 +   220 C=0:​A=X:​A=A+EL%:​IF A>255 THEN A=A-256:C=1
 +   230 X=A:​A=Y:​A=A+EH%+C:​Y=A
 +   235 A=A+T1
 +   240 IF A>=YM THEN A=A-YM:​YM=YM-1
 +   250 T1=A:DRAW1, X0+XM, Y0-YM
 +   260 IF Y<=YM THEN 210
 +   265 T2=Y:A=T1
 +   270 YM=YM-1
 +   280 A=A+YM:IF A<T2 THEN 300
 +   290 A=A-T2:​T1=A:​XM=XM+1:​A=X:​C=0:​A=A+EL%:​IF A>255 THEN A=A-256:C=1
 +   295 X=A:​A=T2:​A=A+EH%+C:​T2=A:​A=T1
 +   300 DRAW1, X0+XM, Y0-YM
 +   310 YM=YM-1:IF YM>=0 THEN 280
 +XM and YM are the x and y coordinates of the point to be plotted. ​ Note
 +that in line 200 X starts at 128, and this again is to round up all our
 +calculations;​ compare to line 20, where we started T2 at 0.5.  In the
 +above code I store T2 in the X and Y registers for the first part of the
 +code.  Note that in lines 220 and 290 there is some extraneous code to
 +simulate things that in assembly are taken care of by the 6502.  Note
 +also that the comparison in line 260 has been changed from < to <​=. ​ This
 +makes the branch easier, and I'm not sure how it affects the calculation
 +(I didn't notice any difference in the few runs I tried it on).
 +Moving through the code, we increase x, and then add the decimal
 +part of E to the counter. ​ Then we add the integer part of E to the counter,
 +along with any carries. ​ If the integer part of the counter is greater than
 +y, it is time to decrease y and reset the counter.
 +Moving to the second part of the code, we do a little rearranging
 +in line 265.  Really a better thing to do would be to let A=T1-T2, so that
 +the compare in line 280 becomes simpler. ​ Anyways, note that the Y register
 +becomes freed up at this point. ​ From here on, it is pretty much the same
 +thing as before.
 +The full assembly code is then:
 +   ;​Ellipse SLJ 11/3/95 Assumptions:​
 +   ;​0->​XM B->YM, x- and y-coordinates
 +   ;​0->​T1
 +   ;EL and EH contain remainder and integer parts of E, resp.
 +   LDX #128
 +   LDY #00
 +   CLC
 +   TXA
 +   ADC EL
 +   TAX
 +   TYA
 +   ADC EH
 +   TAY
 +   ADC T1
 +   CMP YM
 +   BCC :CONT1
 +   SBC YM
 +   DEC YM
 +:​CONT1 ​  STA T1
 +   CPY YM
 +   BCC L1
 +   STY T2
 +   LDA T1
 +   SBC T2
 +   DEC YM
 +   BCC :CONT2
 +   SBC T2
 +   STA T1
 +   INC XM
 +   TXA
 +   ADC EL
 +   TAX
 +   LDA T2
 +   ADC EH
 +   STA T2
 +   LDA T1
 +   DEC YM
 +   BPL L2      ;Assuming y<128
 +#(A): Logarithms
 +Finally, we need a way of calculating b^2/​a^2. ​ I suggest using
 +logarithms for this.  I do believe I discussed this concept in an earlier
 +issue of C=Hacking. ​ Nevertheless,​ the idea is that if
 +   x = b^2/a^2
 +   ​log(x) = 2*log(b) - 2*log(a)
 +so that
 +   x = exp(2*(log(b) - log(a))
 +Thus, three tables need to be created: one for log(x), and one each for
 +the integer and remainder parts of e^(2*x). ​ Now, to improve accuracy,
 +the first table might be a table of f(x)=222/​log(128) * log(x/​2). ​ This
 +constant is chosen so that f(255) is roughly 255.  222 was chosen because
 +the inversion (i.e. the e^x part) works best at that value. ​ This pretty
 +much assumes that x is not zero or one, either. ​ You can of course use
 +more tables for somewhat better accuracy.
 +One really nice thing about this is that you don't have to worry
 +about squaring things, since that part can be taken care of automatically
 +in logarithm space. ​ On the downside, we are restricted even further by
 +the types of numbers we can divide (e.g. log(a)-log(b) can't be larger
 +than 127 or so).
 +Division then consists of a table lookup, subtraction of another
 +table lookup, and two more table lookups. ​ Here is a short program to
 +demonstrate the use of logs in this sort of division, and a very rough
 +feel for the type of accuracy to expect -- note that it doesn'​t compare
 +decimal parts, or convert the decimal parts into fractions of 256, etc.:
 +   1 FAST:​PRINT"​[CLR]"​
 +   10 DIM L(256),​EI(256),​ER(256):​FC=222/​LOG(128)
 +   20 FOR I=1 TO 256
 +   25 PRINT "​[HOME]"​I
 +   30 L(I)= INT(FC*LOG(I/​2)+0.5):​IF I=1 THEN L(I)=0
 +   40 S=I:IF I>127 THEN S=I-256
 +   50 EX=EXP(2*S/​FC):​IF EX>256 THEN PRINT"​WHOOPS! EX="​EX"​I="​I
 +   60 EI(I)=INT(EX+0.5)
 +   70 ER(I)=EX-EI(I)
 +   80 NEXT I
 +   90 EI(0)=1:​ER(0)=0
 +   100 FOR A=2 TO 250
 +   110 FOR B=2 TO 250
 +   120 X=L(B)-L(A)
 +   123 IF X>127 THEN PRINT"​OOPS:​A="​A"​B="​B"​X="​X
 +   126 IF X<0 THEN X=X+256
 +   130 A1=EI(X)+ER(X):​A2=B*B/​(A*A):​IF A2>255 THEN B=600
 +   135 BL=INT(A2+0.5)-INT(A1+0.5)
 +   140 PRINT A;​B,​A1;​A2,"​ERR="​INT(A2+0.5)-INT(A1+0.5)
 +   150 NEXT:NEXT
 +#(A): Conclusion
 +Sorry, no 3D graphics this time around. ​ Watch for a full-screen,​ hires
 +bitmapped solid 3D virtual world sometime in the not too distant future.
 +Otherwise, may your ellipses never be square :).
 +====== Hack Surfing ======
 +For those who can access that great expanse of area called the World Wide
 +Web, here is some new places to visit that are of interest to the Commodore
 +community. ​ In early 1994, when the US Commodore WWW Site started, the number
 +of sites online that catered to Commodore numbered in the 10'​s. ​ Now, the
 +number is in the 100'​s. ​ What a change.
 +If you know of a site that is not listed here, please feel free to send it
 +to the magazine. ​ The following links have been gleaned from those recently
 +changed or added to the US Commodore WWW Site Links page 
 +(http://​​~brain/​cbmlinks.html).  ​
 +To encourage these sites to strive to continually enhance their creations,
 +and because we like to gripe :-), we'll point out an improvements that 
 +could be made at each site. 
 +#(A): Companies
 +o  http://​
 +   ESCOM Interactive,​ Inc. The new home of Commodore has links to many of
 +   its offices and some general information. ​ The pages are still under 
 +   ​construction,​ but you should probably save this address. ​ C=Hacking gripe:
 +   No Commodore 8-bit inforation yet.
 +o  http://​​~brain/​guest/​cmd/​
 +   ​Creative Micro Designs. ​ Stay tuned to this site for information on
 +   the accelerator,​ and keep up to date on the latests prices on CMD
 +   ​peripherals and software. ​ C=Hacking gripe: For a comapny wanting having
 +   just announced the Super64CPU, no mention of it is to found anywhere on
 +   the WWW site.  Bummer.
 +#(A): Publications
 +o  http://​​about/​c64.html
 +   ​LOADSTAR and LOADSTAR 128.  If you are interested in LOADSTAR, check 'em
 +   out here.  Some Commodore links are included, and the and a few magazine ​
 +   ​teasers are present. ​ In addition, details on how to ordr LOADSTAR or any
 +   of its related software titles is provided. ​ C=Hacking gripe: ​ the 
 +   ​background color. ​ Yellow is hard on our eyes... ​ Oh well.
 +o  http://​​~dat95pkn/​8bitar/​
 +   Atta Bitar (8 Bitter) magazine. ​ Full indexes for the past 3 years, as well
 +   as information on how to subscribe. ​ We'd tell you more, but none of us
 +   read German (At least we THINK it's German), and the English transmation ​
 +   page isn't done yet.  Anyway, if you would like to subscribe or need to 
 +   ​search the index of the magazine, here's the place to go.  ​
 +   C=H gripe: Yes, we know this is English-centric,​ but we just wish we could
 +   ​actually read all the great info on this site.
 +#(A): User's Groups
 +o  http://​​
 +   ​Champaign-Urbana Commodore User's Group. ​ Home of the Universtity of
 +   ​Illinois (the editor'​s alma mater!) ​ Meeting dates and time, along with 
 +   ​newsletters and a user group listing are presented. ​ C=H gripe: No 
 +   ​mention of what local CBM 8-bit users are doing. ​ This site recently ​
 +   ​changed addresses, so change all your links...
 +o  http://​​~eberger/​pcg/​
 +   ​Pittsburgh Commodore Group. ​ Local news, meeting dates and time, and 
 +   some newsletters are present. ​ This site has also recently relocated
 +   to this new address. ​ C=H gripe: Same as for CUCUG. ​ We want to know
 +   what the CBM 8-bitters are doing in Pittsburgh.
 +o  http://​​~rtrissel/​
 +   The Central Coast Commodore User's Group. ​ Those in the Santa Maria
 +   CA area will be glad to know that CCCUG is there for them.  Past
 +   ​newsletter are available, and some links to other information of 
 +   ​interest is present. ​ C=H gripe: Meeting dates and times need to be
 +   ​present in some easy place. ​ C=H plug:  It sounds like this club might
 +   need a little help, as it is down on members. ​ If you are in the Santa
 +   Maria area, consider joining...
 +#(A): Miscellaneous
 +o  http://​​art/​9408/​sec14/​art1.htm
 +   Byte Magazine'​s Commodore obituary, by Tom Halfhill. ​ Tom spells out many
 +   of the things that Commodore DID do right in its lifetime, and reflects
 +   on the blunders CBM made.  The article makes for very good reading, but 
 +   will depress some.  C=H gripe: The pictures in the real article aren't
 +   ​reproduced in the WWW page.
 +o  http://​​~e9426444/​geoswarp/​index.html
 +   GEOS Warp 1.0.  For the Mac user who needs or wants to run GEOS, this
 +   ​program,​ run on a Macintosh, will allow GEOS programs to operate on
 +   the Mac.  The system looks very impressive, to the point of us not asking,
 +   ​Why? ​ C=H gripe: ​ Not really with the page, but the writer laments that
 +   ​progress is slow owing to no agreement with GEOWorks. ​ Such things may
 +   doom the project to failure.
 +o  http://​​~danf/​cbm/​
 +   Dan Fandrich'​s WWW Site.  For those who develop on alternate platforms or
 +   use multiple programming languages with the C64/128, bookmark this page.  ​
 +   Very current info, and lots of it is presented. ​ Some defunct Commodore ​
 +   mags are indexed, and pointers are provided to many of the current crop of 
 +   ​magazines,​ including this one.  C=H gripe: ​ the page needs a little bit 
 +   more organization to make it easier to get at juicy info.
 +o  http://​​~scatt/​commodore.htm
 +   ​Scatt'​s WWW Site. For those just moving into assembly language programming
 +   from BASIC or something else, this page has a beginner'​s tutorial you
 +   might find useful. ​ C=H gripe: A little low on content, but we are glad 
 +   what there is is available.
 +o  http://​​~pbgonz/​progc64.html
 +   Pete Gonzalez'​s WWW Site.  Small page, but worth viewing. ​ Pete shows some
 +   ​screen shots of a new game he is developing, and offers copies of his 
 +   in progress cross assembler for the PC.  C=H gripe: When's the game coming
 +   out again? :-)
 +o  http://​​~yak/​cccc/​
 +   The Commodore Computer Cult Corner. ​ Some people play games, and then some
 +   ​people PLAY games. ​ Jonas Hulten has pictures of his game design, ​
 +   ​implementation,​ and programming heoes. ​ You can read about each one, and
 +   even light a "​candle"​ for them.  This site has a CBM links page, which 
 +   ​anyone can add their link to automatically. ​ C=H gripe: We can add our home
 +   page automatically,​ but not our hero.  ​
 +o  http://​​~jwilbur/​
 +   John Wilbur'​s WWW Site.  Basically, just a links page right now, but we'll
 +   check back.  C=H gripe: We'd like to see a little more about John as it
 +   ​relates to Commodore.
 +o  http://​​~supermjk/​
 +   ​Marc-Jano Knopp'​s WWW Site.  Mainly a large links page for Commodore
 +   ​information,​ this site does give a glimpse of the never produced Commodore
 +   LCD laptop computer. ​ C=H gripe: ​ As above, we love to see a little more
 +   about Marc-Jano as it relates to Commodore.
 +====== Design and Implementation of an Advanced Text Editor ======
 +by Craig Bruce (
 +Note: Due to the size of the article, no executable or source code 
 +      is included, but both will be included in ACE Release #15 
 +      (ftp://​​pub/​cbm/​os/​ace/​).
 +This article discusses the design and implementation of the ZED text editor
 +for the ACE operating system (Release #15 and higher). ​ The program and full
 +source code will be freely available when they are ready. ​ ZED is written
 +entirely in assembly language (ACEassembler) and makes heavy use of the
 +full-screen control capabilities of ACE.  However, part of the genius of the
 +design of the ACE interface is that its facilities could be replicated into
 +a standalone environment and a new ZED could be made into a one-part program
 +(for greater convenience,​ with less flexibility).
 +There was a previous version of ZED, which WAS a standalone program. ​ It was
 +written entirely in _machine_ language (as opposed to assembly language;
 +y'​know,​ hexadecimal and stuff, with a machine-language monitor). ​ Needless
 +to say, upgrading and maintaining the program was a real problem, even
 +though it was only 17K in size.  The program also had a couple of
 +limitations,​ the most serious of which being that all lines were limited to
 +a maximum of 80 characters (plus a carriage return), or they would be split
 +into two physical lines internally. ​ It would also work only on the
 +80-column C128.
 +Still, the standalone version had a number of outstanding capabilities,​
 +including the ability to edit EXTREMELY large files with an REU and dynamic
 +data structures, the ability to use "burst mode" on devices that supported
 +it, TAB and character-set translation on loading and saving, global search
 +and replace, range delete and recall, and a paragraph "​juggling"​ feature.
 +It is truly an outstanding program (if I do say so myself), and it is my
 +pleasure to use it every day.  (I also use Unix's "​vi"​ every day, and I am
 +getting tired of its clumsy user interface... I may just have to port ZED to
 +the Unix environment one of these days).
 +The ACE version has/will have all of these features and then some.  The ACE
 +version supports even larger files by using the ACE dynamic memory
 +management system (see C= Hacking #7 or a newer ACE Programmer'​s Reference
 +Guide) in addition to its own byte-oriented memory management (see C=
 +Hacking #2) with internal memory (up to 512K on a C128), REUs up to 16 Megs,
 +and RAMLink DACC memory up to 16 Megs.  Burst-mode support isn't currently
 +available in ACE (see C= Hacking #3), nor does the ACE version of ZED
 +currently implement the other outstanding editing features of the original
 +ZED mentioned above. ​ (For another C= Hacking reference, ACE does support a
 +three-key rollover for typing convenience (see C= Hacking #6)).
 +However, the ACE version supports extremely long physical lines (paragraphs)
 +by providing automatic word wrapping and "soft returns"​ with automatic "text
 +sloshing"​ (a dynamic form of "​juggling"​),​ and it therefore has/will have the
 +functionality of a word processor. ​ The new version also works in all video
 +modes that ACE supports on both the C128 and C64.
 +Now we start talking about the implementation of ZED.  What a text editor
 +is, basically, is a program that holds a text document in memory that allows
 +you to use certain commands to alter tiny pieces or large-scale chunks of
 +the document and then to save the changed document permanently back to
 +disk.  The way in which the document is held in memory is the content of
 +this section.
 +ZED uses a bi-directionally linked list to hold the text document in
 +memory. ​ A special "​trailer"​ line is used (which is displayed with a little
 +"​house"​ character on it) to make modifications to the linked list and the
 +whole list is in the form of a big ring (the links run around in circles).
 +Here is an asciigram of a document with two data lines:
 +  /​-------------------\
 +  |   /​----------\ ​   |
 +  |   ​| ​         V    |
 +  |   ​| ​       +-------------------------------------
 +  |   ​| ​       |next|prev| ​ data for line #1...
 +  |   ​| ​       +-------------------------------------
 +  |   ​| ​         |    ^
 +  |   ​| ​         V    |
 +  |   ​| ​       +-------------------------------------
 +  |   ​| ​       |next|prev| ​ data for line #2...
 +  |   ​| ​       +-------------------------------------
 +  |   ​| ​         |    ^
 +  |   ​| ​         V    |
 +  |   ​| ​       +-------------------------------------
 +  |   ​| ​       |next|prev| ​ special trailer line...
 +  |   ​| ​       +-------------------------------------
 +  |   ​| ​         |    ^
 +  |   ​\----------/ ​   |
 +  \-------------------/​
 +I should mention that all pointers are 32-bit values, so that they can point
 +to anywhere in ACE's "​far"​ memory. ​ (In fact, many of the control variables
 +for ZED are 32 bits in size, to avoid all arbitrary restrictions on the
 +magnitudes of various things). ​ And, despite where the arrows point in the
 +diagram, the value that is stored for the pointer is the address of the
 +starting byte of the record that is being pointed to.
 +I should also mention that lines are stored as they are displayed. ​ If one
 +physical line (terminated by a carriage return) has to be split (using "soft
 +returns"​) over multiple display lines, then each _display_ line takes up one
 +linked-record position in the document data structure.
 +Using a bi-directionally (doubly) linked list (instead of a uni-directionaly
 +(singly) linked list is a practical necessity in this environment for two
 +reasons. ​ First, the linking represents the natural way that the user
 +accesses the document: he normally moves cursor up and down, page up and
 +down.  It would take a lot of time to move the cursor up using a singly
 +linked list.  Second, using a double linked list makes it easier to insert
 +or delete a line from the document. ​ You need to modify the previous record
 +to point beyond the record being deleted, but the previous record is
 +difficult to locate in a singly linked list; you must keep and manage a
 +pointer to it (and if the user moves the cursor up, you lose what you've got
 +for it).  I prefer doubly liked lists for any job anyway, even if the
 +ability to go backwards isn't needed, because they are easier to work with
 +(and to construct reusable library routines for).
 +Using a large block of memory for the data isn't really an option either.
 +Anyone who has used SpeedScript knows what happens when you try to insert
 +text near the beginning of a long document: it takes a lot of time to insert
 +one space in the document memory, and the delay is annoying. ​ Imagine this
 +played out for a document that is N megabytes in size.  (Some auxiliary data
 +structure would be needed in this case anyway, to break the 64K barrier).
 +I'm guessing that most other word processors/​text editors for Commodore
 +computers use this data structure (a "​large"​ block of memory).
 +The decision to store each display line in a single record is really one of
 +convenience and efficiency. ​ Most of the time, the use will be positioning
 +the cursor and whizzing between display pages, so we don't want to be
 +wasting any time uselessly re-formatting the text while he (sic) is doing
 +this.  We only want to re-format the text when an actual modification is
 +made to the document. ​ This organization does have the ugly implication that
 +physical and logical line numbers may not always match up, but if the
 +"​target"​ line length (the maximum length that a single display line can be)
 +is set to be longer than the maximum physical-line length of a file (often
 +80 characters),​ then the two will match up.
 +Accessing the document is fairly simple. ​ All that we need to locate the
 +entire document is the address of the special trailer line.  With this, we
 +know directly where the bottom line is, so we can instantly go to the bottom
 +of the document (Commodore-DOWN) and then follow the links backward to
 +access preceeding lines. ​ Finding the top of the document is also quite easy
 +since the document is in a ring.  We just locate the trailer line and then
 +follow the "​next"​ link, and we arrive at the first line (Commodore-UP). ​ It
 +should be no surprise that a pointer is kept to the trailer line in ZED in
 +order to locate a document. ​ The design allows for many documents to be held
 +in memory at the same time, including the "kill buffer"​ (which is logically
 +a complete and independent document). ​ To make management even simpler, it
 +should be noted that this trailer line never changes (therefore, we never
 +have to update the pointer to the trailer line of a document).
 +The format of each individual display line within a document held in the
 +linked-list structure described above is as follows:
 +OFF   ​SIZ ​  DESC
 +---   ​--- ​  -----
 +  0     ​4 ​  ​pointer to the next line
 +  4     ​4 ​  ​pointer to the previous line
 +  8     ​1 ​  flags for the line, including $80=hard-return,​ $40=trailer line
 +  9     ​1 ​  ​number of characters on the line 
 + ​10 ​    ​n ​  the displayable characters of the line
 +n+10    -   SIZE
 +The two 32-bit pointers have already been mentioned. ​ The "​flags"​ field
 +tells whether the line ends in a "hard return"​ or a "soft return"​. ​ A hard
 +return (indicated by the $80 bit being set) is recorded for every place in
 +the text file where a carriage-return character is present. ​ A soft return
 +(indicated by the $80 bit being clear) is formatted into the document every
 +place where a line must be broken in order to avoid it exceeding the target
 +line length. ​ If you modify the document, then words can be wrapped and
 +pulled back around a soft return in order to insure that display lines are
 +as full as possible (whereas they cannot be wrapped around a hard return).
 +When a file is being written back to disk, lines that have a hard return
 +flag will be written with a trailing carriage-return character, whereas
 +lines ending with a soft return will be written with only the characters
 +displayed on the line (no CR), and, as such, they will be logically
 +concatenated together into the same physical line (again) in the output
 +file.  The "​trailer line" flag indicates whether the current line is the
 +special trailer line of the document or not.  We need a convenient way to
 +check for running into the trailer line, and we cannot use null pointers
 +since the document is in a ring (note that there won't be any null pointers
 +even if the document contains zero data lines; the trailer line will point
 +to itself).
 +The lower six bits of the flags field are currently unused, but they could
 +be used, for example, to record the number of leading spaces that a
 +line has before the first non-blank character. ​ This would allow us to
 +hold a file with a lot of indentation (a program, for example) using less
 +memory per line.  This feature is not currently implemented.
 +The next field tells the number of displayable characters that are on the
 +line and then the next field stores the actual characters in a simple
 +string. ​ If the line ends in a hard return, then the carriage-return
 +character is NOT stored in the line data, since its presence is already
 +indicated in the line header. ​ When records are allocated in the
 +dynamic-memory space, only the number of bytes that are actually needed are
 +allocated. ​ This is the number of bytes on the line plus ten bytes for the
 +line header. ​ Actually, the number of bytes reserved for an allocation is
 +the number of bytes requested rounded up to the nearest multiple of eight
 +bytes, for technical reasons discussed in C= Hacking #2.  A single display
 +line can contain up to 240 characters (not counting the CR).
 +Every time that a line needs to be accessed, it must be fetched from far
 +memory into a buffer in the program space. ​ There is a slight efficiency
 +problem in accessing a line that there isn't when allocating and storing a
 +line.  When going to read the line, you don't know how big it is, since you
 +know nothing about it other than its far location. ​ The conservative thing
 +to do would be to read the first ten bytes of the line record (the header
 +information) and then use the value in the line-length field to figure out
 +how many more bytes you need to fetch. ​ I kind of took a wild stab and made
 +it so that I read the first twenty bytes of a line and then see if the line
 +has ten or fewer displayable characters on it.  If so, then I have
 +successfully fetched the whole line and I am done in one access. ​ (Note that
 +there is no problem with fetching far memory beyond one record'​s allocation
 +(although there certainly would be a problem with stashing)). ​ If not, then
 +I fetch the remaining characters and I am done in two fetches (actually, I
 +fetch all of the characters for simplicity).
 +However, often times I don't actually have to fetch the data of a line at
 +all and I only need to access its header information (to follow or change
 +its linkage, for example). ​ In this case, I only have to access the header
 +of the line and I only need one access to get it since I already know how
 +long the header is (ten bytes). ​ I can also write back a modified header in
 +place since it is of fixed length. ​ If I were to, for example, add
 +characters to a line, then I would have to re-allocate a larger line record
 +for it, free the old line-record storage, and link the new line record in
 +with the rest of the document (by updating the previous record'​s "​next"​
 +pointer and updating the next record'​s "​prev"​ pointer and by updating any
 +necessary global variables... quite a bit or work).
 +#(A)2.3: 2.3. GLOBAL VARIABLES
 +This section describes all of the global variables that ZED keeps in order
 +to edit a document. ​ First, I have three separate temporary-storage work
 +work1 = $02 ;(16)  ;used by malloc
 +work2 = $12 ;(16)  ;used by file-load
 +work3 = $22 ;(14)
 +Each work area is used by successively higher levels of software in order to
 +avoid conflicts between layers. ​ For example, "​work1"​ is used by the
 +dynamic-memory routines and "​work2"​ gets modified when loading a file.  The
 +process of loading a file involves a lot of memory-allocation work, so it is
 +good that they use separate working storage and don't clobber each other.
 +The following variables are used for managing the screen and the current
 +cursor column:
 +scrTopAddr ​     = $30 ;(2)  ;screen address of the top line on the display
 +scrRow ​         = $34 ;(1)  ;row number of the current line on the display
 +scrCol ​         = $35 ;(1)  ;virtual screen column number of cursor position
 +scrRows ​        = $36 ;(1)  ;number of rows on the display
 +scrCols ​        = $37 ;(1)  ;number of columns on the display
 +scrStartRow: ​   .buf 1      ;starting row on the display
 +scrStartCol: ​   .buf 1      ;starting column on the display
 +scrRowInc ​      = $38 ;(1)  ;row increment for the display
 +scrLeftMargin ​  = $39 ;(1)  ;left margin for displaying lines
 +statusMargin: ​  .buf 1      ;left margin of the status line on the display
 +conColor: ​      .buf 8      ;color palette
 +Most of these fields are used for interfacing with ACE's direct-access
 +full-screen-control calls. ​ The ones that are used most often are allocated
 +to zero-page locations (to reduce code size and to increase performance) and
 +the others are allocated to absolute memory. ​ ACE allows application
 +programs to use zero-page locations $02 to $7F for their own purposes.
 +The current displayed cursor location is stored in "​scrRow"​ and "​scrCol"​.
 +"​scrRow"​ is the current physical display row of the current document line
 +(where display rows start at 2 since the control and separator lines take up
 +rows 0 and 1), and "​scrCol"​ tells the current position on the current line,
 +from 0 up to the length of the line.  Since this version of ZED features
 +horizontal scrolling to handle really long display lines, "​scrLeftMargin"​ is
 +also maintained to tell what the column number of the left margin of the
 +display is.  When we refresh the screen, we will display all lines starting
 +from this character position. ​ Note that internally, column numbers start
 +from 0 whereas they are numbered starting from 1 in all dialogue with the
 +ape at the keyboard. ​ Every time that the cursor could possibly move off the
 +right or left edge of the screen, a check is made and if this happens, then
 +the "​scrLeftMargin"​ is adjusted and the screen is re-painted (effectively
 +giving us horizontal scrolling).
 +The following variables are used to keep track of various parameters:
 +targetLen ​      = $3a ;(1)  ;length to display lines
 +wrapFlag ​       = $3b ;(1)  ;​$80=wrap,​$40=showCR
 +modified ​       = $3c ;(1)  ;$00=no, $ff=modified
 +modeFlags ​      = $3d ;(1)  ;​$80=insert,​ $40=indent
 +statusUpdate ​   = $3e ;(1) ;​128=line,​64=col,​32=mod,​16=ins,​8=byt,​4=fre,​2=nm,​1=msg
 +markedLinePtr: ​ .buf 4      ;line that is marked, NULL of none
 +markedLineNum: ​ .buf 4      ;line number that is marked
 +markedCol: ​     .buf 1      ;column of marked logical line
 +"​targetLen"​ is the length that ZED tries to keep wrappable lines as close to
 +without exceeding. ​ By default, it will be set to the physical display width
 +of the screen, but it can be set to 240 characters by the "​-l"​ option and it
 +will eventually be manually settable to any value you want (10<​=l<​=240).
 +The "​wrapFlag"​ tells, first, whether word wrapping should be used ($80 set)
 +or whether lines should just be broken at the target length regardless of
 +whether it gets broken in the middle of a word or not ($80 clear), and
 +second, tells whether carriage-return characters should be displayed to the
 +user ($40 set) or not ($40 clear). ​ (Actually, a suitable character to
 +represent the carriage return is displayed, taken from the graphical palette
 +of the current character set).  You will normally want carriage returns
 +displayed when you are using ZED as a word processor, and you will normally
 +want them not displayed when using ZED as a text editor.
 +The "​modeFlags"​ tell, first, whether auto-insert ($80 bit set) or over-type
 +($80 clear) mode is in effect, and second, whether auto-indent ($40 set) or
 +no-indent ($40 clear) mode is in effect. ​ Insert/​overtype is currently
 +supported and auto-indent is not.  Auto-indent is intended to eventually
 +make programming easier by not requiring you to type a bunch of spaces to
 +indent a new line of a source file that should be at the same nesting level
 +as the previous line.
 +The "​statusUpdate"​ variable is used to reduce the amount of work the needs
 +to be done in order to keep the status line at the top of the screen up to
 +date.  If any of the variables that control the values displayed on the
 +status line change, then the corresponding bit in this variable should be
 +set.  After processing a keystroke but before waiting for the next
 +keystroke, ZED will update all of the fields that have a '​1'​ bit in this
 +variable. ​ The "​msg"​ bit is special, since it tells whether a dialogue
 +message is currently being displayed on the separator line (between the
 +status line and the first document line), and if there is, then the message
 +should be erased (overwritten by the separator characters) _after_ the user
 +presses the next key (since it wouldn'​t be much fun if the user had only a
 +couple of milliseconds to read the message).
 +The "​marked*"​ fields tell where the "​mark"​ is currently set for range
 +commands (like delete). ​ Like in the stand-alone ZED, I will be making this
 +version clear the mark after every modification to the file.  The main
 +reason for this is that it would be a pain in the but to keep track of the
 +mark in some cases like when the line that is marked gets deleted or
 +updated, and that having set-mark/​do-operation clear the mark prevents the
 +ape at the keyboard from accidentally hitting a range-destroy key and wiping
 +out his document (he will get a "range not set" error message instead).
 +The following variables are used to keep track of the current position in
 +the document:
 +linePtr ​        = $40 ;(4)  ;pointer to current line
 +lineNum ​        = $44 ;(4)  ;number of current physical line
 +headLinePtr ​    = $4c ;(4)  ;pointer to the special header/​trailer line
 +lineCount ​      = $50 ;(4)  ;number of display lines in buffer
 +byteCount ​      = $54 ;(4)  ;number of bytes in buffer
 +"​linePtr"​ always points to the line record that the cursor is logically on.
 +This is probably the most important global variable. ​ This variable is
 +needed so that we know what line to modify/etc. if the user enteres a
 +letter/​etc. ​ "​lineNum"​ gives the line number of the "​linePtr"​ line, where
 +line numbers start from 1.  This needs to be maintained in order to tell the
 +ape at the keyboard where in the document he is.  These two fields are
 +sequentially updated as the user moves from line to line in the document.
 +"​headLinePtr"​ is a bit of a misnomer since it actually points to the special
 +trailer line.  As explained above, it is used to find the top and the bottom
 +of the document. ​ "​lineCount"​ keeps track of the total number of display
 +lines in the current document, and "​byteCount",​ the total number of bytes.
 +Each carriage-return character counts as one byte.  Keeping track of line
 +and byte counts is for convenience rather than necessity.
 +The following variables manage the "kill buffer",​ where text goes after it's
 +been deleted but before it's completely discarded (a sort of purgatory):
 +killBufHeadPtr:​ .buf 4      ;pointer to special header/​trailer line of kill buf
 +killLineCount: ​ .buf 4      ;number of lines in kill buffer
 +killByteCount: ​ .buf 4      ;number of bytes in the kill buffer
 +The kill buffer is maintained in exactly the same structure that the main
 +document is: a ring of doubly linked line records. ​ The three fields shown
 +store the pointer to the special trailer line, the number of data lines in
 +the kill buffer, and the number of data bytes in the kill buffer,
 +In addition to the kill buffer, there is also a "rub buffer":​
 +rubBufPtr: ​ .buf 1
 +rubBufSize: .buf 1
 +rubBuffer: ​ .bss RUB_BUFFER_SIZE
 +It is used to hold the fifty single characters that have most recently been
 +deleted by using either the DEL or Commodore-DEL (Rub). ​ I found that when
 +using the old version of ZED, I would sometimes unintentionally delete a
 +single character and then want it back, and I had to expend mental effort to
 +figure out what it was.  This mechanism takes the effort out of that job by
 +maintaining a LIFO (Last In First Out) (circular) buffer controlled by the
 +variables given above (note that "​RUB_BUFFER_SIZE"​ is a constant which can
 +be easily changed up to 255 in the source code). ​ The "​rubBuffer"​ is
 +actually contained in the uninitialized-storage section of the program
 +("​bss"​ in Unix terminology). ​ (The "​.bss"​ directive is not currently
 +implemented in the ACEassembler,​ but I used it here as a shorthand for the
 +equates that replace it).
 +The Shift-Ctrl-R (rub recall) keystroke is used to recall the previous
 +character (as if you had typed it in) and has the effect of resetting the
 +"​rubBufPtr"​. ​ Then, each additional time that you type Shift-Ctrl-R in a
 +row, the "​rubBufPtr"​ is advanced backward to the character previous to
 +the one just recalled. ​ Pressing anything other than Shift-Ctrl-R resets
 +the "​rubBufPtr",​ so that you could recall the characters again, if you want.
 +You can recall as few characters as you wish.
 +Interpreting command keys is done with the following global variables:
 +keychar ​      = $58 ;(1)
 +keyshift ​     = $59 ;(1)
 +sameKeyCount:​ .buf 1
 +sameKeyChar: ​ .byte $00
 +sameKeyShift:​ .byte $ff
 +ACE returns both a shift pattern and a key character code, so both are
 +stored. ​ The shift pattern allows us to take different actions for commands
 +like Ctrl-R and Shift-Ctrl-R. ​ The "​same*"​ fields store the previous
 +keystroke and the number of times that the exact keystroke has been made, so
 +that slightly different actions can be taken when the same keystroke is made
 +multiple times, such as with Shift-Ctrl-R (or maybe HOME).
 +The following global variables are also maintained for various purposes:
 +exitFlag: ​    .buf 1
 +arg:          .buf 2
 +temp:         .buf 4
 +stringbuf: ​   .bss 256
 +filebuf: ​     .bss 256
 +tpaFreemap: ​  .bss 256
 +linebuf: ​     .bss 256
 +line          = linebuf+headLength ;(241)
 +headBuffer ​   = $70 ;(10) ;buffer for holding the head of the current line
 +headNext ​     = $70 ;(4)  ;pointer to the next line in a document
 +headPrev ​     = $74 ;(4)  ;pointer to the prev line in a document
 +headLineLe ​   = $78 ;(1)  ;length of the text line
 +headFlags ​    = $79 ;(1)  ;​$80=CR-end,​ $40=headerLine,​ &​$3F=indent
 +headLength ​   = 10        ;length of the line header
 +documentBuf: ​ .bss 256
 + ​docbufNext ​  = documentBuf+0 ​  ;(4)
 + ​docbufPrev ​  = documentBuf+4 ​  ;(4)
 + ​docbufInfo ​  = documentBuf+8 ​  ;(23)
 + ​docbufFilenameLen = documentBuf+31 ;(1)
 + ​docbufFilename= documentBuf+32 ​ ;(224)
 +"​exitFlag"​ is set to tell the main loop to bail out and exit back to the
 +calling program. ​ "​arg"​ is used for scanning the command-line arguments.
 +"​temp"​ is used miscellaneously. ​ "​stringbuf"​ is used for miscellaneous
 +string processing, and "​filebuf"​ is used for miscellaneous file/string
 +processing. ​ "​tpaFreemap"​ is used by the dynamic-memory-management code as a
 +free-memory-page map for making allocations out of the application program
 +area (or TPA, Transient Program Area). ​ The ACE kernel doesn'​t dynamically
 +allocate pages in the application space (since this cannot normally be done
 +reliably), so a mechanism is needed inside of ZED to make use of this
 +"​linebuf"​ is the place where the current line is fetched to/stashed from
 +when it is being accessed or modified. ​ "​line"​ is the sub-field of "​linebuf"​
 +where the actual line data is stored. ​ The "​head*"​ variables are allocated
 +in zeropage and the record-header information from "​linebuf"​ is copied to
 +these variables whenever a line is fetched and copied from these variables
 +when a line is stashed to far memory. ​ Zero page is used for these variables
 +since they are manipulated all of the time.
 +Finally, "​documentBuf"​ stores all of the information about the current main
 +document. ​ There is currently support for only one main document
 +implemented,​ but the design includes the concept of the user being able to
 +switch between an arbitrary number of documents held in memory at any time.
 +When ZED is first started up, its usual first job is to load in the document
 +that was named on the command line (plus you can load a file at any time
 +with Ctrl-L). ​ ZED uses the standard ACE "​open",​ "​read",​ and "​close"​ system
 +calls to do this, although there is a bit of business that has to happen to
 +get the data into the internal form that ZED uses.  The job is split into a
 +number of routines to make it easier to program.
 +The main routine opens the file for reading and initializes that variables
 +that the load routine uses.  Among other things, the load routine counts up
 +the number of display lines and physical bytes in the file and must wrap
 +physical lines into display lines while reading. ​ Later, this routine will
 +perform on-the-fly translation from other file formats to PETSCII and will
 +perform TAB expansion if requested.
 +The main routine repeatedly calls subroutines to read a line into the line
 +buffer, wrap it, and store it to memory. ​ For the purpose of the following
 +discussion, we will assume that the "​target"​ line length is 80 characters,
 +although it can be set to anything that you want.  The Read routine copies
 +characters from the "​filebuf"​ to the line buffer, with the filebuf being
 +re-filled with file-data characters as necessary in 254-byte chunks (the
 +natural size of Commodore data sectors, for efficiency). ​ Data bytes are
 +copied until either a carriage-return (CR) character is encountered or we
 +reach the 81st character (target+1). ​ We have to check the 81st character
 +because it may be a CR, and if we are in the normal text-editor mode, we can
 +store a full 80 data characters on a display line, even if it ends in a CR
 +(some editors, quite annoyingly, cannot do this). ​ However, if the user
 +selects the mode where CRs are visibly displayed on the screen, then we stop
 +scanning the current display line at a maximum of 80 characters if a CR
 +isn't encountered.
 +After the characters of the display line have been put into the line buffer
 +in the above step, it may be the case that the word at the end of the line
 +has been abruptly broken in the middle. ​ If the line ended in a CR, then
 +this doesn'​t need to be checked. ​ If the line didn't end in a CR and if the
 +"​wrap"​ mode is currently on, then an abruptly cut word will have to be
 +wrapped to the next line.  To do this, we scan from the end of the line back
 +until we encounter the last space character on the line.  Then, we cut the
 +line immediately after that space, and remember where we cut it so that we
 +can later process the overflown characters. ​ If there is no space on the
 +line (i.e., the first and only word on the line is longer than the target
 +length), then we keep it as-is and end up breaking the word abruptly. ​ Note
 +that we break the line with a "soft return",​ so there is no damage done to
 +the data by word wrapping.
 +After the fat (if any) has been trimmed off the current display line, we
 +want to store it into far memory, into the doubly linked ring structure
 +discussed above. ​ To do this, we first, set the pointer to the previous line
 +to the address of the previous line record (we keep track of this) and set
 +the pointer to the next line to Null (for now).  Then we we allocate memory
 +for the current line and Stash it out.  But we're not done yet; we need to
 +set the "​next"​ pointer on the previous line record to point to our newly
 +allocated line.  This can be done by simply writing the 32-bit pointer value
 +to the start address of the previous line (there is no need to re-fetch the
 +previous-line contents or header).
 +And after stashing out the line, we recall where we wrapped it (if we did)
 +and copy the characters that were cut off to the beginning of the line
 +buffer and we pretend that we have fetched these from the file as if in the
 +Load Line step above. ​ Then we go back to the Load Line step and continue.
 +When loading is finished (after we hit End-Of-File (EOF) on the file being
 +read), we flush the last incomplete line segment, if there was one (a file
 +is not required to end in a CR) and then we cap things off with the special
 +trailer line.  This trailer line is allocated before we start loading the
 +file (although I didn't mention it above), and now we set up its links so
 +that our entire file is the nice doubly linked ring that we like so much.
 +Now we are finished, and we return the trailer-line pointer, the number of
 +display lines read in, and the number of physical bytes read in to whomever
 +called us (it could be the command-line parser, the Ctrl-L (Load) command,
 +or the Ctrl-I (Insert) command).
 +There are three reasons why I like having this special trailer line around.
 +(1) It allows us to not have to worry about Null pointers. ​ For example, you
 +will notice that while stashing a loaded line, I allocated the trailer line
 +first so that we would always have a "​previous"​ line to link with.  (2) It
 +allows the user to move the cursor beyond the physical end of the document
 +to do operations like recall (Ctrl-R) a block of text.  This was a problem
 +with the original ZED; you had to go the the end of the file, press RETURN
 +to open up a blank line, recall the text, and then delete the bogus blank
 +line.  (3) It allows a document to have zero characters in it in a
 +consistent fashion.
 +There is also a subtle but complicated issue dealing with dynamic memory
 +allocation that I haven'​t discussed yet: what if it fails? ​ (I.e., what if
 +we run out of memory?​). ​ In this case, we must handle the failure
 +gracefully, maintain the integrity of the document as best we can, and
 +inform the user.  In some cases, maintaining the integrity will involve
 +un-doing committed changes to the document, which is a real pain in the
 +butt, but which is still very important. ​ It would be kind of annoying if
 +you just made the last keystroke on five hours of editing work and the
 +program aborted on an "out of memory"​ error, sending all of your work to the
 +great bit bucket in the sky.
 +This section discusses the operations that have to do with maintaining the
 +current secion of the document on the display and moving the cursor around
 +within the document.
 +This is the essential operation that keeps the screen up to date with the
 +docment in memory. ​ ZED has a single function that does this operation, and
 +it is called with the arguments: a pointer to the starting line to display,
 +the starting screen line number to start painting at, and the ending screen
 +line number to end painting at, plus one (lots of endings are 'plus one'
 +since this allows me to use the BCC instruction). ​ Some implied arguments
 +include general information about the screen for use with the "​aceWin*"​
 +kernel functions and the left margin for displaying lines.
 +This subroutine simply goes through the display lines one by one, displays
 +the line contents, and advances the line pointer. ​ To display a single line,
 +the line is fetched into the line buffer from far memory and the number of
 +displayable characters is calculated according to the line length and the
 +left-hand display margin. ​ The displayable characters (possibly zero) are
 +written to the screen memory and if the line isn't completely full, then the
 +remainder of the line is filled in with space characters. ​ The displaying is
 +completely performed by the "​aceWinPut"​ system call.  One oddity that needs
 +to be handled is running out of document lines before filling the screen
 +range. ​ In this case, each remaining screen line is cleared.
 +Attributes (colors) are not used for this operation, since they are not
 +needed and using them would only slow us down.  They display-area color
 +cells are initialized when ZED starts (as are the status-line and
 +separator-line color cells) and don't change during operation. ​ The colors
 +come from the ACE palette (which the user can configure to his own liking).
 +This subroutine is used to both repaint the entire screen (when necessary)
 +and to repaint only one line or a few lines (when I can get away with
 +this). ​ Repainting takes time, so we want to repaint only what has changed.
 +However, repainting isn't too slow, especially when compared to serial-line
 +speeds, since screen updates are written directly to screen memory, although
 +the C64's soft-80 screen is significantly slower than the other screen types
 +since so much more processor work needs to be done just to make a single
 +character appear.
 +In the future, it may be useful to allow this function to abort in the
 +middle of this operation if the user presses a key before the repainting is
 +finished, in order to allow the user to work faster. ​ For example, if you
 +hold down the Page-Down keystroke, the speed that you go forward in the
 +document is limited by how fast the screen can be repainted. ​ If the repaint
 +operation were abortable, then you could always go forward as fast as the
 +key repeates, and when you get to where you are going and release the
 +Page-Down key, the screen would repaint one final time and everything would
 +be consistent. ​ A flag would need to be kept to tell whether the screen is
 +consistent or not, in order to make this work.
 +There is also a function that displays a message in the separator line on
 +the screen. ​ It also needs to store the displayed message in order to allow
 +the user to scroll through it if the screen is not wide enough to display it
 +in its entirety. ​ When the message is no longer needed, it is erased by
 +overwriting it with separator characters. ​ And, there is also a function
 +that updates all of the fields that have changed on the status line.
 +#(A)3.2: 3.2. MAIN CONTROL
 +Before I start talking about the implementations of the individual commands,
 +I should say something about the main control for the program. ​ After ZED
 +initializes and loads the initial document (even if you don't specify one,
 +ZED will default to the name "​noname"​ and try to load it), control is passed
 +to a small main loop of simply displaying the cursor, waiting for a
 +keystroke, undisplaying the cursor, calling the subroutine associated with
 +the keystroke, and repeating.
 +#(A)3.3: 3.3. END UP, DOWN, LEFT, RIGHT
 +Moving the current line to the top and bottom of the document is straight
 +forward, because of the organization that was discussed in the data-
 +structure secion above. ​ To go to the top of the document, copy the
 +trailer-line pointer to the current line pointer and then fetch the next
 +pointer from the trailer line's header; this will give a pointer to the top
 +line.  Then we set the current line number to one and a couple of other
 +variables and call the subroutine discussed above to repaint the screen.
 +Going to the bottom of the document would be just as easy as going to the
 +top, except that we want the last line (the trailer line) to be displayed on
 +the bottom of the screen in order to present as much useful document content
 +to the user as possible. ​ If there are fewer lines in the file than will
 +fill a screen, then we cannot, of course, display an entire screen.
 +To make this business easier, a subroutine is provided that, given a
 +starting line pointer and a count, will scan until it either hits the
 +count-th line previous to the given one or it hits the top line of the
 +document. ​ It returns the number of lines that were actually scanned upwards
 +(possibly zero), the pointer to the line that it stopped scanning at, and a
 +flag indicating whether it stopped because it hit the top of the document or
 +not.  This subroutine is quite generally useful. ​ There is a similar
 +subroutine that scans downward.
 +So, after locating the bottom line of the document and setting the line
 +number, the scan-upwards subroutine is called to scan upwards the number of
 +displayable lines on the screen. ​ The screen is then repainted in its
 +entirety from the line that was scanned up to, and the new cursor-display
 +location is computed from the count of the lines that were scanned over.
 +This works equally well for a long document, a document shorter than the
 +height of the screen, and an empty document.
 +The End-Left and End-Right commands are very simple in that they don't even
 +have to change the current line pointer, but they do have to check if the
 +cursor has moved off either the left or right edge (margin) of the screen.
 +The visible columns go from the column number of the left margin, up to that
 +plus the width of the screen. ​ If the cursor goes off an edge of the screen,
 +then the new left margin will have to be computed and the entire display
 +will need to be repainted.
 +This repainting effectively achieves horizontal scrolling. ​ Lines in ZED, of
 +course, can be up to 240 characters across (241 if you count the carriage-
 +return character), but the widest screen that ACE supports is 80 columns.
 +Arguably, the horizontal scrolling could be done more efficiently by moving
 +the contents of the display left or right by the requred number of columns
 +and then filling in the opened spaces with the data from the correct columns
 +of the display lines in memory. ​ However, the additional complexity is
 +non-trivial and the speedup may not be all that great except for the soft-80
 +screen of the C64.  A better approach might be to go with the interruptable-
 +repainting idea that I spoke of earlier, if the current line were updated
 +first (so that you can see what you're doing) and the rest of the lines
 +All of these functions follow quite naturally from what is above. ​ For Page-
 +Up and Down, the scan-up or scan-down subroutines already described are
 +called to find the new current line for the cursor and then the entire
 +screen is repainted, effectively paging up or down.
 +For cursor up and down, we just go up or down to the next line in the
 +document and adjust adjust the cursor location on the screen. ​ If the cursor
 +goes off the top or bottom of the screen, then we scroll the screen up or
 +down as appropriate (ACE can scroll the screen up or down and will
 +eventually be able to scroll it left and right (although this will be a bit
 +painful for the soft-80 screen since it may mean scrolling left and right
 +nybbles)). ​ Then, we display the current line at either the top or bottom of
 +the screen to fill in the blank line that we just opened up.  Because we use
 +scrolling and painting only a single line, we can scroll the screen fairly
 +quickly, easily keeping up with the cursor repeat rate, except on the
 +soft-80 screen.
 +For cursor left and right, we advance the cursor one position on the line
 +and see if it has gone over the edge.  If not, then we are done; nothing
 +needs to be redisplayed. ​ If we have gone off the edge, then we call the
 +cursor-up or cursor-down routines to go to the previous/​next line and we
 +position the cursor to either the end or start of the new line.
 +The word left/right functions are similar to the cursor left/right
 +functions, except that we keep scanning until we run into the start of the
 +next word.  For word left, this is defined as running into a non-whitespace
 +character that is preceeded by a whitespace character. ​ A whitespace
 +character is defined as either a space, a TAB, a hard return, or the
 +beginning or ending of the document. ​ For word right, the start of the next
 +word is defined as a non-whitespace character that is preceeded by a
 +whitespace character, where we start searching from one position to the
 +right of the current cursor position. ​ If we run into the beginning or end
 +of the document, then we stop there.
 +BTW, all of these moving-around functions check the cursor position against
 +the display bounds and "​scroll"​ the display left or right if the cursor has
 +gone off the screen. ​ Well, actually, there is one exception to this rule.
 +If the current line is the target-length number of characters long, and the
 +target length equals the screen width, and carriage returns are selected not
 +to be displayed, and the left margin of the display is column one
 +(external), and the cursor is in the target-length-plus-one position of the
 +line, then the screen is NOT scrolled right. ​ Instead, the cursor is
 +displayed on the last position of the line and is made to blink fast (an ACE
 +feature). ​ This is done to avoid the annoyance of having the screen scroll
 +right when you are editing a text file on, say, an 80-column screen that has
 +up to 80-character lines in it.  The standalone ACE does this too, when you
 +logically hit the 81st column.
 +So far, we can load up a document and whiz around inside of it, but we can't
 +actually change anything. ​ This section describes the single-character
 +modification operations of character input, rub, and delete, and the text
 +"​sloshing"​ algorithm that is needed to make sure that lines are always as
 +full as they can be without going over the target length ("Come on down!"​).
 +#(A)4.1: 4.1. TEXT INPUT, DELETION
 +Adding a single character to a document isn't really very difficult. There
 +are two modes for single-character inputting: insert and overtype. ​ Insert
 +mode is generally more useful and more often used, but overtyping can be
 +very useful when dealing with tabular or specially formatted text.
 +Therefore, we must support both modes. ​ In some other text editors, overtype
 +mode is the natural mode because the cost of inserting a character can be
 +so high, but not here.
 +Actually, there isn't a whole lot of difference in the implementations of
 +the two modes. ​ For overtype mode, you just fetch the current line, take the
 +inputted character and store it into the line buffer at the current
 +position, stash the line back into memory, and repaint the line.  For insert
 +mode, we do the same thing, except that we copy the line from the cursor to
 +the end to one position beyond the cursor (backwards) and bump its length up
 +by one before storing the new character on the line.
 +Rubbing out a character (Commodore-DEL) is done in quite the same way,
 +except that we copy the rest of the line back one space and decrement the
 +length. ​ Oh, and when the length of the new line is different from the
 +length of the old line, we have to deallocate the old line and allocate new
 +memory for the new line, and surgically link it in with the rest of the
 +document. ​ I have a subroutine that does this.
 +The DEL key is handled as if you had typed Cursor Left then RUB, except when
 +you press DEL on the first column of a line and the previous line ends with
 +a hard return, the hard return of the previous line is removed instead. ​ I
 +decided to make the RUB (Co-DEL) key return an error instead of joining
 +lines together like DEL, because sometimes it is convenient to just lean on
 +the RUB key to delete to the end of a line.
 +#(A)4.2: 4.2. TEXT SLOSHING
 +But, we're not done with text modifications yet.  If we just left the
 +modifications as described in the previous sections, we would be end up with
 +lines that are longer than the target length, with ragged lines, and with
 +lines that don't join together like they should after pressing DEL in the
 +first column.
 +After each of the modifications,​ the text-sloshing routine is called to
 +straighten everything up and figure out how to redisplay the screen. ​ Often,
 +only one line needs to change, but sometimes, many lines or even the whole
 +screen will have to be updated, as sloshing text can continue for many lines
 +as line overflows and underflows cascade forward from the line that has just
 +been modified. ​ In fact, the text-sloshing routine is enormously complicated
 +and has many, many special cases. (Although, for all of its complexity, it
 +is only 400 lines long, although it still needs a few more features).
 +There are many more cases that could cause sloshing than you might think.
 +There are the obvious inserting/​deleting one-too-many characters in the
 +current line, but there is also the case that an insertion or deletion
 +causes a space character to move to the right position on a line to allow
 +the line to be sloshed backward, or maybe you remove a space from the end of
 +a line that creates a word that would be too long to be contained on one
 +line and therefore needs to be sloshed forward.
 +The sloshing algorithm doesn'​t introduce or take away any characters from
 +the body of the document; it just reorganizes the existing characters. ​ All
 +of the spaces are retained at the ends of wrapped lines. ​ We don't want to
 +delete spaces, since it is difficult to reconstruct them, since two spaces
 +are normally between two sentences in text, but it is difficult for a
 +computer to figure out where a sentence ends.  In fact, keeping these spaces
 +can sometimes cause an anomaly: if all of the spaces won't fit on the end of
 +one line, then they will be displayed at the beginning of the next line.
 +The variables that are maintained by the algorithm are as follows:
 +sloshLinesAltered ​ = work2+0 ;(1) ;a simple count
 +sloshRedisplayAll ​ = work2+1 ;(1) ;​$80=redisplay to bottom, $ff=force all
 +sloshRedisplayPrev = work2+2 ;(1) ;whether previous line needs to be repainted
 +sloshMaxChars ​     = work2+3 ;(1) ;number of chars that can be sloshed
 +sloshTailChar ​     = work2+4 ;(1) ;the last char of prev line
 +sloshTheCr ​        = work2+5 ;(1) ;whether a CR should be sloshed
 +sloshLinesInserted = work2+6 ;(1) ;number of new line records created
 +sloshLinesDeleted ​ = work2+7 ;(1) ;number of existing line records deleted
 +sloshCurAltered ​   = work2+8 ;(1) ;whether the current line has been altered
 +sloshTerminate ​    = work2+9 ;(1) ;flag to terminate (hit a hard return)
 +sloshCurTailChar ​  = work2+10 ;(1);last char of current line
 +The algorithm has a main loop that is repeated for each line that can be
 +sloshed. ​ The loop exits when we either run into a hard return or we run
 +into a line that does not need to be sloshed. ​ We start scanning from the
 +cursor line of the main document.
 +We first look at the previous line and see how many more characters it can
 +accommodate before being full.  Then, we scan the current line from this
 +point (the number of characters that could potentially be sloshed backwards)
 +back to the start of the line searching for spaces. ​ If there are no spaces,
 +then the current line cannot be sloshed back onto the previous line.  If we
 +do run into a space, then we stop searching and know that we can (and must)
 +slosh back the current line.  So, we remove the characters from the current
 +line and write it back (maintaining links as appropriate) and then go back
 +to the previous line and append these characters to it.
 +If the cursor happened to be on the line in a position that got sloshed
 +back, then we must adjust the cursor position and move it back to the
 +previous line.  If the previous line is before the start of the screen,
 +we must set the flag to redisplay the entire screen later. ​ If the current
 +line is the first line of the slosh area but the cursor didn't get moved
 +back to the previous line, then we must set the flag to indicate that
 +we must redisplay the previous line too when we repaint the screen.
 +If it turns out that we have sloshed back ALL of the characters on the
 +current line, then we must remove the empty line record of the current line
 +from the document and adjust the global line count. ​ We also have to worry
 +about sloshing back a hard return, and if we do, then we bail out of the
 +algorithm since we are done.  Oh, and we have to keep in mind whether we are
 +displaying carriage returns or not in calculating line lengths.
 +After shoshing backward, we check if the current line needs to be sloshed
 +forward. ​ It needs to be sloshed forward if it is either longer than the
 +target length or it ends in a non-space character and the first
 +word on the next line cannot be sloshed back.  The latter is a special case
 +and needs to be checked for specially, even thought the functionality
 +for doing so is redundant.
 +If we do need to slosh forward, we start scanning the current line at the
 +target-line-length point and scan backwards until we hit the first space.
 +If there is no space, then the current word is longer than the target length
 +and must remain abruptly broken over two (or more) lines. ​ We wrap it at the
 +target length. ​ If we do find a space earlier on the line, then we wrap the
 +line right after that space. ​ Oh, I forgot to mention: we need to do
 +something special for lines that end with non-spaces for backward sloshing
 +too.  If the previous line ends in a non-space (presumably because it
 +contains a single very long word), then we don't find any spaces to slosh
 +back to the end of the word, then we slosh back as many characters as will
 +fit, since the word is broken anyway, and we want it to have as many
 +characters as possible on a single line.
 +To wrap the line, we set the length of the current line to the new length
 +and replace the old version of the line in memory. ​ Then, we create a new
 +line record and store the characters that were wrapped in it and link this
 +line record in with the rest of the document. ​ And this is all that we do
 +here; we don't actually insert the wrapped characters into the next line,
 +since that would be more complicated,​ and since it might cause that line to
 +overflow. ​ If we just leave the wrapped characters, they will be joined with
 +the next line (if necessary) on the next iteration of the main sloshing loop
 +in a slosh-back operation. ​ We must adjust the cursor location, like before,
 +if the cursor was on the part of the line that got wrapped around.
 +At the end of a loop, we check to see if we have passed a hard return in
 +the document, in which case, we exit.  Otherwise, if either the current
 +line has been modified or if the current line is the first line to
 +be sloshed, then we go on to the next line and repeat the above
 +On our way out, we do a little fine tuning of the "​sloshLinesAltered",​
 +"​sloshRedisplayAll",​ and "​sloshRedisplayPrev"​ variables, which were
 +described earlier. ​ These variables will be used to repaint the changed
 +portions of the screen display. ​ Part of the fine adjustment includes
 +comparing the number of lines that have been inserted and deleted from the
 +document. ​ If these two numbers match, then the bottom portion of the screen
 +doesn'​t have to be repainted, only the altered lines themselves; otherwise,
 +we need to repaint from the current line all the way to the bottom of the
 +The sloshing algorithm currently does not handle non-wrap mode; lines will
 +always be word wrapped. ​ Later, all lines will be broken at the N-th column
 +if you are not in word-wrap mode.  Also, the algorithm can produce an
 +anomalous wrapping in one case involving lines that end with non-spaces that
 +I can't seem to remember that this algorithm will fail in (but, the document
 +will still be interally consistent). ​ And finally, if you change the target
 +line length while editing a document (which you can't currently do), then
 +the algorithm may not be able to give optimal word wrapping in all cases
 +(though, again, the document will always be interally consistent).
 +This secion discusses the other features of the editor that have not been
 +described yet.  In general, the operation of this version follows closely
 +from the standalone version, so you can read its documentation for more
 +details. ​ First, I will give a summary of all of the implemented and planned
 +commands, and then I will discuss the operation of a few selected commands.
 +#(A)5.1: 5.1. COMMAND SUMMARY
 +Here is a command summary. ​ The "​I"​ column in this list tells whether the
 +feature is currently implemented or not.  A blank means "​no",​ and an
 +asterisk means "​yes"​. ​ Note that "​currently"​ means "by the time that you
 +read this" (which will be a couple of weeks after I have written this). ​ The
 +"​CODE"​ column tells the internal ACE-PETSCII code for the key.  A plus
 +symbol following it means that the shift status of the key is checked to
 +distinguish this key.  The "​KEY"​ column tells what keystroke you must make
 +("​CT-"​ means Ctrl, "​CO-"​ means Commodore, "​SH-"​ means Shift, and "​AL-"​ means
 +Alt).  The "​ACTION"​ column tells you what happens.
 +- ----  ------- ​ -------
 +  $e0   ​CT-@ ​    ​Exchange cursor position with mark position
 +* $e1   ​CT-A ​    Alter case of letter under cursor
 +  $e2   ​CT-B ​    Go on to next document buffer
 +  $e2+  SH-CT-B ​ Go on to previous document buffer
 +  $e3   ​CT-C ​    Copy range
 +* $e4   ​CT-D ​    ​Delete range
 +* $e5   ​CT-E ​    Exit with save
 +* $e6   ​CT-F ​    Find next occurrence of hunt string
 +  $e6+  SH-CT-F ​ Find previous occurrence of hunt string
 +  $e7   ​CT-G ​    Go to given line number
 +  $e7+  SH-CT-G ​ Go to given _physical_ line number
 +* $e8   ​CT-H ​    Set Hunt string
 +* $e9   ​CT-I ​    ​Insert new file into current one
 +  $ea   ​CT-J ​    ​Juggle the lines of paragraphs, keep separate
 +  $eb   ​CT-K ​    Kill current line
 +* $ec   ​CT-L ​    Load file
 +  $ed   ​CT-M ​    Set Mark for range operations
 +* $ee   ​CT-N ​    Set Name of current file
 +  $ef   ​CT-O ​    Set Options: input/​output translation/​tab-expansion,​ etc.
 +  $f0   ​CT-P ​    Print current file
 +* $f1   ​CT-Q ​    Quit without save
 +* $f2   ​CT-R ​    ​Recall text from the Kill buffer
 +* $f2+  SH-CT-R ​ Recall text from the Rub buffer
 +* $f3   ​CT-S ​    Save file
 +  $f4   ​CT-T ​    Tie together multiple lines into one big line (paragraph)
 +  $f5   ​CT-U ​    Undo the last change made to the document
 +  $f6   ​CT-V ​    ​Verify file
 +  $f7   ​CT-W ​    Write range with new name
 +  $f8   ​CT-X ​    ​Extract the individual lines from a paragraph
 +  $f9   ​CT-Y ​    ​Replace (all the other letters were taken!)
 +* $fa   ​CT-Z ​    Goto bottom of screen
 +* $fb   ​CT-[ ​    ​Toggle insert mode
 +* $fc   ​CT-\ ​    ​Toggle modified flag
 +* $fd   ​CT-] ​    ​Toggle indent mode
 +  $fe   ​CT-^ ​    ​Change the current working directory
 +  $ff   ​CT-_ ​    ​Compose ISO-8859-1 character
 +I CODE  KEY          ACTION
 +- ----  ---          ------
 +* $91   ​UP ​          ​Cursor up
 +* $11   ​DOWN ​        ​Cursor down
 +* $9d   ​LEFT ​        ​Cursor left
 +* $1d   ​RIGHT ​       Cursor right
 +* $06   ​SH-LEFT ​     Word left
 +* $0b   ​SH-RIGHT ​    Word right
 +* $16   ​CT-UP ​       Page up
 +* $17   ​CT-DOWN ​     Page down
 +* $19   ​CT-LEFT ​     Page left
 +* $1a   ​CT-RIGHT ​    Page right
 +* $0c   ​CO-UP ​       Goto top of document
 +* $0f   ​CO-DOWN ​     Goto bottom of document
 +* $10   ​CO-LEFT ​     Goto beginning of line
 +* $15   ​CO-RIGHT ​    Goto end of line
 +* $0d   ​RETURN ​      Split current line (indent not yet implemented)
 +  $8d   ​SH-RETURN ​   Go to next paragraph
 +  $01   ​CT-RETURN ​   Go up one paragraph
 +  $09   ​TAB ​         Tab
 +  $02   ​SH-TAB ​      ​Backtab
 +  $18   ​CT-TAB ​      ​Insert to next tab stop
 +* $14   ​DEL ​         Delete character
 +* $08   ​CO-DEL ​      ​Rubout
 +* $94   ​INST ​        ​Insert one space
 +* $13   ​HOME ​        <​nothing>​
 +* $93   ​CLR ​         Cursor home
 +  $04   ​HELP ​        Bring up help window
 +  $84   ​SH-HELP ​     Display help screen
 +* $0a   ​LINEFEED ​    <​nothing>​
 +* $07   ​SH-LINEFEED ​ <​nothing>​
 +* $1b   ​ESCAPE ​      ​Redisplay screen
 +* $0e   ​SH-ESCAPE ​   <​nothing>​
 +* $03   ​STOP ​        <​stop some operations>​
 +* $83   ​RUN ​         <​nothing>​
 +  $90   ​CT-1 ​        Clear document
 +  $05   ​CT-2 ​        Clear buffer
 +  $1c   ​CT-3 ​        Enter hexadecimal PETSCII character code
 +  $9f   ​CT-4 ​        ​Display directory
 +  $9c   ​CT-5 ​        ​Destroy current document buffer
 +  $1e   ​CT-6 ​        ​Create new document buffer
 +  $1f   ​CT-7 ​        ​Display PETSCII code of current character
 +* $9e   ​CT-8 ​        ​Scroll left margin of status line
 +* $12   ​CT-9 ​        ​Reverse screen on
 +* $92   ​CT-0 ​        ​Screen reverse off
 +  $81   ​CO-1 ​        Set display to show single buffer
 +  $95   ​CO-2 ​        Set display to show two buffers
 +  $96   ​CO-3 ​        Set display to show three buffers
 +  $97   ​CO-4 ​        Set display to 40 columns, default rows
 +  $98   ​CO-5 ​        Set display to take full screen
 +  $99   ​CO-6 ​        Set display to default number of rows
 +  $9a   ​CO-7 ​        Set display to maximum number of rows
 +  $9b   ​CO-8 ​        Set display to 80 columns, default rows
 +  $85   ​F1 ​          ​Function key 1  : user-defined string
 +  $89   ​SH-F1 ​       Function key 2  : user-defined string
 +  $86   ​F3 ​          ​Function key 3  : user-defined string
 +  $8a   ​SH-F3 ​       Function key 4  : user-defined string
 +  $87   ​F5 ​          ​Function key 5  : user-defined string
 +  $8b   ​SH-F5 ​       Function key 6  : user-defined string
 +  $88   ​F7 ​          ​Function key 7  : user-defined string
 +  $8c   ​SH-F7 ​       Function key 8  : user-defined string
 +  $80   ​CT-F1 ​       Function key 9  : user-defined string
 +  $82   ​CT-F3 ​       Function key 10 : user-defined string
 +  $8e   ​CT-F5 ​       Function key 11 : user-defined string
 +  $8f   ​CT-F7 ​       Function key 12 : user-defined string
 +#(A)5.2: 5.2. TEXT SAVE
 +This function is, of course, implemented,​ since the text-modification
 +functions of the editor would be useless without it.  It is really quite
 +simple, because of the data structure of the document. ​ First, we try to
 +open the file for writing. ​ If not successful and we get a "file exists"​
 +error, then we scratch the old file.  Then, we re-open for writing.
 +To save the file contents, we start at the top line, and fetch each line in
 +turn until we hit the trailer line of the document, at which point we are
 +finished. ​ After fetching the line, we check if it ends with a hard return,
 +and if so, we append the line buffer with a carriage return character and
 +bump up the line length. ​ We then call the ACE "​write"​ primitive with the
 +line buffer as the argument to write out the line.  Writing in this size of
 +chunk rather than in single bytes gives ACE the opportunity to carry out
 +this operation as efficiently as it can.
 +We then close the file and we are done.  We display status information to
 +the user during all phases of this operation, and we certainly tell him if
 +anything goes wrong.
 +Range delete and recall are implemented,​ since they are very useful for
 +general editing. ​ What will normally happen is that the user will set the
 +mark with Ctrl-M (mark) to one end of the range to be deleted, and then move
 +the cursor to the other end of the range and press Ctrl-D (delete). ​ The
 +text then disappears into the kill buffer and can be recalled any number of
 +times at any point in the document using the Ctrl-R (recall).
 +One difference between this ZED and the operations mentioned here are
 +"​character oriented"​ rather than "line oriented"​. ​ So, you can now delete
 +only portions of lines rather than entire lines. ​ You just have to keep in
 +mind that the cursor is logically located "​between"​ the previous character
 +and the character that the cursor is currently over.  For example, if the
 +cursor was on the "​y"​ in "​xyz",​ then the mark would be set to between the
 +"​x"​ and "​y"​ if you pressed Ctrl-M at that point. ​ This also means that if
 +you wanted to delete an entire line (that ended with a hard return), then
 +you would move the cursor to the first character of the line and press
 +Ctrl-M and then move the cursor to the first character of the NEXT line and
 +press Ctrl-D. ​ (The Hard Return itself won't be included in the delete
 +operation if you move the cursor to the end of the line to be deleted--this
 +is one of the reasons for having a displayable trailer line).
 +To implement the delete operation, all of the lines in the operation are
 +unlinked from the main document and are linked into the kill buffer. ​ If
 +there already was something in the kill buffer, then it is deallocated and
 +the kill buffer is cleared. ​ A trailer line is permanently allocated to the
 +kill buffer, to make it work consistently with the main document. ​ Partial
 +lines (potentially,​ the first and last lines of the range) are a bit of a
 +pain and have to be split into two lines at the point of the mark/​cursor,​
 +where one of the broken lines stays with the document and the other goes
 +into the kill buffer. ​ After extracting the range, the lines around the
 +extracted region are sewn back together ("​sponge,​ nurse!"​) and text is
 +"​sloshed"​ about the stitch point (if necessary). ​ The number of bytes and
 +lines involved are counted up and are subtracted from the global counts
 +for the main document.
 +Ctrl-C (copy) is very similar to the delete operation, except that the data
 +to be deleted is actually copied to the kill buffer and the document is left
 +unmodified. ​ Range copy is not currently implemented,​ since its operation
 +can be emulated with a Ctrl-D followed immediately by a Ctrl-R.
 +To implement the recall operation, the kill buffer is replicated into a
 +temporary document and the current line of the main document is broken into
 +two lines at the recall point (if necessary). ​ Then, the temporary document
 +is linked into the main document at the recall point and the text is
 +"​sloshed"​ about the two stitch points. ​ The line and byte counts are
 +adjusted, and we are done.
 +#(A)5.4: 5.4. TEXT SEARCHING
 +Forward text searching is implemented,​ since it is very useful for both
 +finding things and for moving quickly around in a document. ​ (Reverse search
 +and Range search and replace are not currently implemented,​ since they are
 +less useful).
 +The implementation is quite straightforward. ​ The user will first use Ctrl-H
 +(hunt-string) to set the string to search for.  The user will input this on
 +the top line of the screen, and we don't have to do much work for inputting
 +the string, since ACE already provides a console-input routine complete with
 +left/right cursor movement and a scroll-back buffer (although it is a bit
 +hard to use if the input line is longer than the input window on the
 +After the search string is set, the user will press Ctrl-F (find) to find
 +the next occurrence of the string. ​ So, we just search for that string,
 +starting at the cursor position to the right of the current position. ​ A
 +simple algorithm of keeping a pointer to the current scan position in the
 +hunt string and pointers to both the current position in the document and to
 +the position in the document corresponding to the start of the string is
 +If the current document character matches the current hunt-string character,
 +then both the document and hunt-string pointers are advanced. ​ If the hunt
 +string is exhausted by this, then we have found a match and can stop
 +searching. ​ We move the cursor to the saved document position of the start
 +of the hunt string and exit.  If the characters don't match, then we move
 +the current document pointer back to the postition corresponding to the
 +start of the hunt string, advance it by one, save it, and start searching
 +again. ​ Our algorithm needs to be able to wrap around soft returns in the
 +main document.
 +#(A)6: 6. CONCLUSION
 +So, here we finally have the basic ACE version of the ZED text editor that I
 +have been promising for a very long time.  The new version doesn'​t contain
 +all of the features of the standalone version, but I am working on it.  The
 +new version does, however, include a few features that the old version does
 +not, like long lines, horizontal scrolling, text "​sloshing",​ the ability to
 +use additional memory types for storage, the ability to work on the C64,
 +integration with a command-line environment,​ and full assembler-code
 +availability (Real Soon Now(TM)).
 +In order to make ZED operational as a word processor, some means of giving
 +embedded commands and for formatting and printing these commands must be
 +provided. ​ I was originally thinking that an EasyScript or SpeedScript kind
 +of embedded-command structure, and then I was thinking abouta LaTeX kind of
 +structure (the LaTeX structure is superior), but I am now thinking that an
 +HTML type of format-command structure might be rather apropos. ​ Why then I
 +would need to create a print formatter and previewer that might be usable
 +for other purposes, too.
 +====== Commodore Trivia ======
 +by Jim Brain (
 +          ​
 +#(A): Introduction
 +Well, the cold has moved in on us in Michigan, but the Commodore information
 +coming into the house is keeping us warm.  Some orphan computers have showed
 +up, including a Commodore 65 and C116, as well as a couple of Commodore B-128
 +computers with all the fixin'​s. ​ So, armed with the hardware, I have come up
 +with some brain ticklers for the Commodore know-it-all.
 +As some may know, these questions are part of a contest held each month on
 +the Internet, in which the winner receives a donated prize. ​ I encourage
 +those who can received the newest editions of trivia to enter the contest.
 +This article contains the questions and answers for trivia editions #19-22,
 +with questions for the current contest, #​23.  ​
 +If you wish, you can subscribe to the trivia mailing list and receive the
 +newest editions of the trivia via Internet email. ​ To add your name to the
 +list, please mail a message:
 +Subject: MAILSERV
 +subscribe trivia Firstname Lastname
 +#(A): Trivia Questions
 +Q $120) What is the model number of the assembler/​monitor for the KIM-1?
 +A $120) The KIM-5 was the model number of the editor/​assembler product.
 +Q $121) How many LEDs are on the KIM-1?
 +A $121) The basic unit contains 6 7-segment LED displays, or 42 LEDs if
 +        you count each LED in a segment.
 +Q $122) What is the model number of the REC chip used in the REU?
 +A $122) MOS 8726.
 +Q $123) At least two versions of the above chip exist. ​ What is the main
 +        physical difference between the versions?
 +A $123) The eraly versio of the chip (8726-R1) exists in DIP form, while the
 +        8726-r4-r8 exists as a "​J-lead"​ square surface mount unit.
 +Q $124) Why couldn'​t regular Atari(tm) style joystcks be used with the
 +        Commodore Plus/4 series?
 +A $124) Instead of using the de-facto 9 pin D-subminuture connector for the
 +        joysticks, the Plus/4 series used small mini-DIN connectors. ​ Some
 +        sources claim the older connectors were leaking a fair bit of
 +        radio interference and were preventing the units from attaining
 +        FCC approval, so the connectors were changed to the better-shielded
 +        mini-DIN types.
 +Q $125) What was the first joystick model Commodore produced that would
 +        function with the Plus/4 computer line?
 +A $125) The Commodore T-1341 Joystick, which had the special mini-DIN ​
 +        connector
 +Q $126) How many computer models are included in the Plus/4 line?
 +A $126) At last count, 3 models in the Plus/4 series were produced:
 +        The Commodore Plus/4
 +        The Commodore 16
 +        The Commodore 116
 +        Some Commodore 264 models are known to exist, but are not counted, ​
 +        since the 264 was the prototype model of the Plus/​4. ​ Also, a V364
 +        model was planned, but only one unit is known to exist.
 +Q $127) In a normal Commodore disk drive Directory Entry, what relative
 +        offset denotes the start of the program name?
 +A $127) The filename starts at the 4th byte in the directory entry.
 +Q $128) How many tracks in a 1541 or 4040 are normally available for use as
 +        storage?
 +A $128) 35 tracks.
 +Q $129) How many bytes comprise a single disk drive directory entry?
 +A $129) 30 bytes.  ​
 +Q $12A) What is the model number of the Commodore dual drive with a total
 +        capacity per unit of 2.12MB?
 +A $12A) The Commodore 8250 or 8250LP dual disk drive.
 +Q $12B) On the drive denoted in $12A, how large could a single sequential
 +        file be?
 +A $12B) 1.025 megabytes.
 +Q $12C) At least two version of the Commodore 64C keyboard exist. ​ What is
 +        the difference between them?  Extra Credit: Why?
 +A $12C) One one keyboard style, the Commodore graphics are printed on the
 +        front of the keys, while they appear above the letters on the keys
 +        in the second type of keyboard. ​ I can't answer the extra credit
 +        part except to say that Commodore was always seeking the best deal.
 +        aybe a new keyboard manufacturer got the bid and changed the layout.
 +Q $12D) On the Commodore 64, what area of memory is swapped out when using an
 +        REU with RamDos?
 +A $12D) $6000 - $7fff is swapped out when a RAMDOS command is executing.
 +Q $12E) Commodore manufactured two different versions of the 1541-II drive.  ​
 +        What is the difference between them?
 +A $12E) The drive mechanisms differ in the two drives. ​ You can tell which you
 +        have by the appearance of the front of the drive. ​ If the lever hits
 +        a rest in the release position, you have the direct drive model. ​ If 
 +        the lever has no such rest visible, the drive cotains the belt drive
 +        mechanism.
 +Q $12F) How many colors could the Commodore 1520 plotter plot in?
 +A $12F) 4.  red, black, blue, and green.
 +Q $130) The Commodore Plus/4 was referred to as the "​___________ Machine"​.
 +A $130) Productivity.
 +Q $131) Although the Commodore 16 and 116 were functionally equivalent, what
 +        two physical characteristics distinguished one from another?
 +A $131) Case style and keyboard. ​ The C16 is enclosed in a VIC20/C64 style
 +        case with keyboard, while the C116 sports a scaled down Plus/4
 +        style case and "​chicklet"​ keyboard.
 +Q $132) How many pins are there on the Commodore plus/4 expansion port
 +        connector?
 +A $132) 50 pins.
 +Q $133) On which side of the Commodore 65 (as it is facing you) did Commodore
 +        place the power switch on?
 +A $133) The left side.  Since the disk drive fills the entire right side, the
 +        left side is an obvious choice, as the swith would require cabling if
 +        installed on the right side.
 +Q $134) How many keys are on a standard Commodore 128 keyboard?
 +A $134) 92 keys.
 +Q $135) What color are the drive LEDs on the SX64 drive?
 +A $135) There is only one LED, a red in-use LED.
 +Q $136) True or False? ​ The Commodore 64 and VIC-20 keyboards are
 +        interchangeable.
 +A $136) True.
 +Q $137) On a 1526/MPS 802 printer, how many redefinable characters
 +        were available for use per line of text?
 +A $137) 1.  True fact:  In order to print a line of graphics, one must
 +        print a GFX char, do a returb without linefeed (resets the graphic
 +        character, evidently), the tab over and repeat the cycle until 80
 +        characters were printed. ​ I had one, and it took me 7 hours to 
 +        print 21 pages of GEOWrite text!
 +Q $138) To set up a redefinable character on the MPS 802/1526 printer, what
 +        secondary address must be opened?
 +A $138) Secondary address #5.
 +Q $139) How many pins are in each Euro-DIN plug used on the Plus/4-C16
 +        joysticks?
 +A $139) 8 pins.
 +Q $13A) How many pins are on a regular Commodore VIC-20/C64 joystick
 +        connector?
 +A $13A) 9 pins.
 +Q $13B) What BASIC command is used to change from C128 mode to C64 mode on a 
 +        C128?
 +A $13B) go 64.  It will ask for confirmation.
 +Q $13C) What were the four integrated programs included in the infamous
 +        "​3+1"​ software in the Plus/4?
 +A $13C) A word processor, spreadsheet,​ graphics software, and a data management
 +        program.
 +Q $13D) Which Commodore serial printer(s) had a small switch that allowed it
 +        to be addressed as either device 4 or device 5?
 +A $13D) The 1525, MPS 801, and MPS 803 had such a switch. ​ Although I cannot ​
 +        confirm this, I believe the 1515, the precursor to the 1525, also 
 +        had the 4/5 switch.
 +Q $13E) How many addressable registers does the Commodore VIC-II IC have?
 +A $13E) There are 47 control registers in the Commodore VIC-II chip.
 +Q $13F) On a Commodore PET machine, what output appears on the screen after
 +        typing in SAVE "",​2?​
 +Q $140) What was the model number of the microprocessor used in the
 +        first of the Commodore 264 Series?
 +A $140) The early Plus/4 units contained a 7501 microprocessor,​ and the
 +        later units featured a 8501 microprocessor. ​ The only differences
 +        between the two units is the manufacturing process and die size.
 +Q $141) How fast could the microprocessor in the Commodore 264 Series
 +        theoretically run at?
 +A $141) 1.76 MHz.
 +Q $142) How many colors can a Commodore Plus/4 display at once?
 +A $142) 8 shades each of 16 colors, but the 8 shades of black are still
 +        still black, so a total of 121 colors are possible.
 +Q $143) What anomaly exists in the numbering of the BASIC interpreter
 +        in the Plus/4 as 3.5?
 +A $143) This version contained almost all of the commands in Version 4.0, 
 +        plus some new commands for graphics and sound.
 +Q $144) After the very first 1581 disk drives were introduced, Commodore
 +        found that the WD1770 disk controller chip in the drive could corrupt
 +        the disk in some situations. ​ So, Commodore offered a replacement
 +        IC to fix the problem. ​ What was the number of the replacement IC?
 +A $144) The Western Digital WD1772 IC.
 +Q $145) On some very early CBM 1541 drives, what would happen if the serial
 +        bus CLOCK and DATA lines were high upon startup?
 +A $145) On the very first 1541 drives (I suspect the feature was also on the
 +        1540 as well), On power-up, the drive would jump to a subroutine at
 +        $E780 after performing the reset routine. ​ The code there would check
 +        for the high state of CLOCK and DATA.  If found, the code would wait
 +        until both go low and then store '​*'​ into the filename buffer, sets the
 +        filename length to 1, and then jumps to the & command, which loads
 +        a USR file and executes it.
 +        Since the Commodore computer never used this feature, and some machines
 +        would boot with these lines randomly high, Commodore removed the
 +        feature.
 +Q $146) In question $0F8, we learned that one must DIMension an array in
 +        BASIC if it will have more than 11 elements. ​ Which Commodore
 +        produced reference book ncorrectly claims the need to DIMension ​
 +        arrays for more than 10 elements.
 +A $146) The Commodore 128 Programmer'​s Reference Guide. ​ Page 17.
 +Q $147) Why should serial device number 31 not be used? 
 +A $147) While it is specified as a valid serial bus address, when "​or"​ed with
 +        certain commands, it results in a bad command, hanging the bus and
 +        the serial drivers.
 +Q $148) On most VIC game cartridges from VIC-1910 up, toggling interlaced
 +        screen display can be done with a keypress. ​ Which key?
 +A $148) Press the F7 function key.
 +Q $149) Which cartidge fitting the criteria in $148 does not toggle interlace
 +        display with the same keypress as the others? ​ How is it toggled
 +        on this cartridge?
 +A $149) Gorf, VIC-1923. ​ Pushing the joystick up toggles interlace mode.
 +Q $14A) The Commodore 64 KERNAL and BASIC code use every opcode in the 6510
 +        CPU except three. ​ Which three?
 +A $14A) BRK, CLV, and SED.
 +Q $14B) For what purpose does the BASIC interpreter in a Commodore 64 
 +        require the Complex Interface Adaptor (CIA) IC? 
 +A $14B) In order to calculate random values for the BASIC function RND(0),
 +        the first 4 registers of the CIA whose address is provided by the
 +        IOBASE KERNAL routine are read.
 +Q $14C) On the Commodore 128, the 80 column output is output by the VDC
 +        chip.  What does VDC stand for?
 +A $14C) Video Display Controller.
 +Q $14D) By now, most people know about the ill-fated Commodore 65.  What
 +        were the specifications on the original Commodore 65 idea?
 +A $14D) A Commodore C64C with a built-in 1581.
 +Q $14E) When referring to the Commodore 4032, one usually states that
 +        one has a "thin 40" or a "fat 40"​. ​ What does "​thin"​ and "​fat"​
 +        signify?
 +A $14E) A "thin 40" had a 9" screen and could not be upgraded. ​ The
 +        "fat 40" had a 12" screen, and could be upgraded to a 8000 series
 +        machine with some upgrade chips.
 +Q $14F) If you own a Commodore 4032, how can you tell which kind (thin
 +        or fat) you have?
 +A $14F) If you hold down the cursor key and it repeats, you have a "fat 40".
 +        (Of course, inspection could also be used, as the "​thin"​ unit had a
 +         ​smaller screen)
 +Q $150) How nmany keys are on a standard Commodore B-128 keyboard?
 +A $150) 94 keys.
 +Q $151) How many revisions of the 1541 printed circuit board are
 +        known to exist?
 +A $151) For the 1541:
 +        PCB# 1540001 ​   The "long board",​ as used in the 1540.
 +        PCB# 1540008-01 Minor revisions to the 1540001 board.
 +        PCB# 1540048 ​   The "short board"​.
 +        PCB# 1540050 ​   Minor revisions to the 1540048 board.
 +                        -01   ALPS mechanism
 +                        -03   ​Newtronics mechanism
 +        PCB# 250442-01 ​ A revision of the short board. 1541 A board
 +        PCB# 250446-01 ​ Minor revisions to the #250442 board, 1541 A-2 board
 +        PCB# 250446-03 ​ Cost reduced 250442-03 board. ​ the 1541A C/R.
 +        ​
 +        For the 1541C:
 +        PCB# 250448-01 ​ Contains the track 1 sensor logic. ​ the 1541B board.
 +        ​
 +        For the 1541-II:
 +        ​
 +        PCB# 340503 ​    Cost reduced board. Termed the 1541-II board. ​
 +        ​
 +        There might be others, but these we can confirm. ​ There are 9
 +        if you count the 1541-II board as a 1541 board, 8 if not.
 +Q $152) The Commodore 6510 CPU has two internal I/O registers. ​ Where in the
 +        Commodore 64 are these two registers located at?
 +A $152) Location $0000 and $0001
 +Q $153) The Commodore 64 cotains 64kB of memory. ​ How many bytes is in
 +        64kB?
 +A $153) 65536 bytes
 +Q $154) What is the name of the Commodore employee responsible for much of
 +        the Commodore 128 and 65 software development,​ among other 
 +        accomplishments? ​ (hint: initials are FB)
 +A $154) Fred Bowen.
 +Q $155) In question $13F, we found out the message that was displayed after
 +        typing SAVE "",​2. ​ Why did Commodore change that message on the
 +        VIC-20?
 +A $155) The original message, as detailed in Q $13F was:
 +        Commodore found that people were pressing the play buttopn BEFORE the
 +        record button, which would prevent the record button from functioning
 +        in some cases. ​ So, Commodore changed the message to:
 +        To circumvent the problem. ​ Note that the VIC did not have 2 tape
 +        interfaces, so no cassette number was needed.
 +Q $156) What was the number of Commodore 64 machines sold, within 4 million?
 +A $156) 17 million ​ (This information came from Dave Haynie)
 +Q $157) What was the number of Commodore 128 machines sold, within 1 million?
 +A $157) 4.5 million (This information came from Dave Haynie)
 +Q $158) In 1985, Commodore previewed the Commodore LCD Laptop computer at the
 +        January CES show.  How many software packages were to be built-in?
 +A $158) 8:
 +        ​
 +        Word Processor
 +        File Manager
 +        Spreadsheet
 +        Address Book
 +        Scheduler
 +        Calculator
 +        Memo Pad
 +        Telecommunications Package
 +Q $159) In the Commodore LCD unit, what were the text screen dimensions?
 +A $159) 80 coumns by 16 rows.  1200 characters on screen.
 +Q $15A) What is the version number of the only known "​bug-free"​ VIC-II
 +        IC?
 +A $15A) 6569-R5. ​ What's funny is that this chip was manufactured after
 +        the Commodore 128 was introduced, so they used the 6569-R3 for the
 +        development of the Vic-IIe chip (8563 series), which is buggy.
 +        So, the newest PAL 64s have a better VIC than the C128.
 +Q $15B) Machine language programmer typically use the .X register to index 
 +        into small arrays. ​ What is the largest byte-array size that can be
 +        handled in this way?
 +A $15B) 256 bytes.
 +Q $15C) In the mid-1980'​s,​ Commodore started manufacturing IBM clone PCs.
 +        One of the models had a name which was a type of horse. ​ Name the term.
 +A $15C) The Commodore "​Colt"​ PC.
 +Q $15D) What is the model number of the first mouse introduced for the
 +        Commodore 64?
 +A $15D) The 1350.  ​
 +Q $15E) What was the problem with the mouse in question $15D?
 +A $15E) As Commodore was either still developing the (now more 
 +        popular) 1351 mouse or the 1350 was designed as a lower cost 
 +        alternative,​ this mouse could only emulate a joystick. ​ When you
 +        rolled it up, the joystick "​UP"​ pin was triggered. ​ Likewise for the
 +        other directions.
 +Q $15F) If you hold down the cursor key on the CBM 4000 series machine and it
 +        does not repeat, what fact about the machine do you now know?
 +        (other than the key doesn'​t repeat)
 +A $15F) It is a thin 40XX machine, meaning it could not be upgraded to an
 +        80XX machine via chip swaps.
 +------- A publication describing BASIC on the Commodore makes the claim that
 +        BASIC variables are limited to 5 characters, with the first two being
 +        significant. ​ The example to prove this point in the book is given as:
 +        ABCDE=5 ​  ​works,​ while
 +        ABCDEF=6 ​ does not.
 +        The following questions refer to this claim:
 +Q $160) What is wrong with the above statement?
 +Q $161) What causes the variable ABCDEF to fail?
 +Q $162) How long can variable names really be?
 +        Extra Credit: ​ Who was the book publisher?
 +------- The Commodore LCD Computer system, much like the Commodore 65,
 +        was a product that never reached the market. ​ Do you remember this
 +        pint-size CBM machine?
 +Q $163) How many keys were on the CLCD keyboard?
 +Q $164) What does LCD in the Commodore LCD stand for?
 +Q $165) Was an internal modem to be includes?
 +Q $166) Like the Plus/4 the CLCD unit had integrated software. ​ What programs
 +        were included?
 +Q $167) How many batteries of what type did the CLCD use for power?
 +Q $168) Approximately how much did the CLCD unit weigh?
 +Q $169) What version of BASIC was to be included with the CLCD computer?
 +Q $16A) The CLCD unit contained a port that could be used with a 
 +        Hewlett-Packard device. ​ What did the device do?
 +Q $16B) What microprocessor did the CLCD unit utilize?
 +Q $16C) In addition to the usual inclusion of standard Commodore ports,
 +        what two industry standard ports were included on the CLCD?
 +Q $16D) How much RAM did the CLCD computer include?
 +Q $16E) How many pixels are on the LCD screen on the CLCD machine?
 +Q $16F) How much ROM did the CLCD computer contain?
 +====== Hacking Graphics: Let's Get Graphical ======
 +by Rick Mosdell (
 +(c) September 1995 (used by permission)
 +#(A): Introduction
 +High resolution graphics on the C64 is not all that complicated. How to set 
 +up the VIC-chip to see your bitmap and colors IS, so this will not become ​
 +a discussion on which bits to flip or where to put your blocks of data 
 +inside a computer already renowned for its lack of space. Instead, I 
 +am interested in the internal data formats of the only two graphics formats. ​
 +#(A): Definitions
 +nybble ​       the first (lowest) or last(highest) group of 4 bits found in a:
 +byte          the fundamental 8 bit unit of our C64: an 8-bit computer.
 +word          two bytes side by side and related, ie. 16 bits. c64 pointers
 +              into RAM are lo/hi byte style.
 +bitmap ​       a contiguous block of data where a shape is defined when some
 +              bits or bit-pairs take a fore-ground color and others take on
 +              a background color.
 +color-ram ​    a block of data which defines the colors for the bitmap, ​
 +              thus completing the picture. ​  
 +color nybble ​ since the C64 has a maximum of nybble 16 colors, to conserve ​
 +              space 2 colors fit into 1 byte.
 +LORES         ​important! This would refer to pictures created by using the
 +              normal 256-byte character set. Extensive use of the graphics ​
 +              characters in lowercase plus RVSon/​RVSoff here. These are NOT 
 +              graphic files and are text files stored in SEQ format.
 +MEDRES ​       this refers to Koala Paint files and related formats.
 +HIRES         this refers to Doodle files and their derivatives.
 +#(A): Doodle!
 +This graphics format is the simplest of all! Here the screen is 
 +divided into 64000 pixels of light (320x200) and is truly HIRES. Neither ​
 +the text color-ram at $D800 nor the 4 background colors at $D021 apply at 
 +all.  The downside is that only 2 colors can be displayed at one time in an 
 +8x8 pixel block. This is the format geoPaint uses (but allows for a whole 
 +page displayed a screenful at a time). These files are prefixed with 
 +"​dd..."​ that when compressed become "​jj..."​. They are PRG files that load 
 +at $5C00. Internally, the 1K of color (1024 bytes) is first followed by 8K 
 +of bitmap (8192 bytes). The "​dd..."​ files are invariably 37 blocks long, 
 +which makes sense since they are 9K long (36+ disk sectors each 254 
 +bytes). ​ The "​1"​ bit of the bitmap uses the low nybble value of the 
 +color-ram while the "​0"​ bit displays the high nybble color. ​
 +Simple, straight-forward and direct! Some artists might find this 
 +color restriction too hazardous to their health. Since our screen is 
 +320x200 pixels (64000 total remember?) dividing by 8 will give us only 
 +8000 bytes needed for the bitmap and only 1000 bytes necessary for 
 +the color-ram. So this format actually wastes 216 bytes! Careful placement ​
 +of colors can result in spectacular HIRES pictures though: look for 
 +the "​Lobster"​ pic in geoPaint and the Doodle files "​Middle Earth" ​
 +and "​Pagoda"​. Other related formats are (refer to the program "​Autograph+" ​
 +by Fuzzy Fox):
 +*  OCP Art Studio
 +*  RUN Paint HIRES
 +*  (geoPaint)
 +#(A): Koala Paint
 +Koala is certainly the most colorful and interesting format. Here 
 +the screen is MEDRES, resulting in dots double pixel width for a resolution ​
 +of 32000 elements (160x200). The loss of resol- ution is compensated by 
 +the ability to display 4 colors at once in each 8x8 pixel block. Here you 
 +have 2 blocks of color-ram, one wherever you put it AND the normal ​
 +color-ram at $D800. Your picture is also effected screen-wide by 
 +the background color at $D021. These files, prefixed by  "​[cbm-1]pic...",​ are
 +PRG files that load at $6000. The same files, when compressed, are prefixed ​
 +by "​gg..."​. ​ That first character in the filename of the raw format means that 
 +you cannot delete these files normally. It is made by pressing CBM-1 
 +(orange) and is hex $81 (decimal 129). The only way I know to scratch ​
 +these files is by typing:
 +   ​OPEN15,​DV,​15,"​s0:​[cbm-1]pic...":​close15
 +Where DV is your current device. Here the creators of Koala were smart 
 +and wasted NO space. Internally the file contains 8000 bytes for the 
 +bitmap(not 8192 bytes), 1000 bytes (not 1024) for the movable color-ram, ​
 +1000 bytes for the color-ram at $D800, and (this IS important) ONE more 
 +byte for the background color. The length ends up at 41 blocks which is 
 +ok considering it is about 10K long. These double width dots are called ​
 +bit-pairs and they draw their colors from various sources:
 +%00 from the background color at $D021
 +%01 from the high nybble of the movable color-ram ​
 +%10 from the low nybble of the movable color-ram ​
 +%11 from the low nybble of the normal color-ram at $D800.
 +Interesting eh? There'​s your 4 colors and where they come from! Related
 +formats would be:
 +*  Advanced OCP Art Studio
 +*  Artist64
 +*  Blazing Paddles
 +*  RUN Paint MEDRES
 +*  SID/PIC multi-color
 +#(A): Conclusion
 +Although I am not an expert on graphics screens (not am I claiming to be),
 +I think programmers should be aware of these two poular formats for
 +storing and displaying graphics on the Commodore 64/​128.  ​
 +          ​
 +====== ? DS, DS$: rem The Error Channel ======
 +In Commodore Hacking Issue #10, the end of the "​Second SID Chip Installation"​
 +article was omitted. ​ The omitted section is included below. (SubRef: sid)
 +Certain early revisions of C=Hacking #10 are missing the end of the article
 +by Alan Jones entitled "​Solving Large Systems of Linear Equations on a
 +C64 Without Memory"​. ​ The omitted text is included below. (SubRef: linear)
 +#(A)sid: Second SID Chip Installation (Line 137 on)
 +         (c) 1987 Mark A. Dickenson
 +Here comes the difficult part to explain. ​ This is the coupling
 +circuit for the audio output. ​ Here is a rough schematic.
 +Pin 27 on             ​12volts dc
 +SID chip   ​resistor ​   !
 +--.          10k ohm   ​!collector
 +27!----.--/​!/​!/​--.-----O 2n2222
 +--' ​   !         ​! ​    ​!emitter
 +       ​! ​        ​! ​    !
 +       <​resistor !     !
 +       >​1k ​      ​! ​    ! +
 +       <​ohm ​     !     :​--!]---to RCA
 +       ​! ​        ​! ​    ​! ​ 10 uf
 +       ​! ​        ​! ​    ​!electrol cap
 +       ​! ​        ​! ​    !
 +ground--- ​       !     !
 +       ​- ​        ​! ​    <​resistor
 +                 ​! ​    >​1k
 +                 ​! ​    <​ohm
 +                 ​! ​    !
 +                 ​! ​    !
 +                 ​! ​    !
 +                 ​! ​   ---ground
 +                 ​! ​    -
 +                 !
 +                === 1000 pf (.001mf)
 +                 ​! ​ capacitor
 +                 !
 +                ---ground
 +                 -
 +You can get the 12 volts you need for the transistor directly from pin #28 of
 +the SID chip.
 +If you need any help on constructing this circuit check out any of the
 +many books that have schematics on the C-64.  This is similar to the one
 +already inside the C-64.
 +The ground wire from the RCA plug can be soldered to the main grounding
 +strip between the serial and video ports. ​ The center wire will be
 +connected to the negative side of the 10uf electrolitic capacitor.
 +I still think you should have someone familier with electronics install
 +this circuit for you.
 +If you have a problem with some cartridges, you will have to install
 +a switch between pin #25 of BOTH SID chips. ​ This will CUT the power to the
 +extra SID chip, effectivly turning it off.  I would suggest that you turn
 +OFF the computer before you turn the extra SID chip ON or OFF with this
 +A good place to mount the switch and RCA plug is on the back of the
 +computer and above the monitor jack on the 64.  I still haven'​t found a GOOD
 +place on the 128.  A suggestion was made that if you are not going to use
 +the RF output on the computer, you can cut the wire going to that RCA plug.
 +Then connect your audio output wire to the center connector of the plug.  This
 +does work but BE CAREFUL!
 +Good luck on the construction.
 +Mark A. Dickenson
 +            by Alan Jones  ( WITHOUT MEMORY (Line 239 on)
 +PROC slv(n#,​nr#,​i#,​REF a(),REF c(),REF b(,​),​sdb#,​REF sw#(),REF fail#) CL
 +  // This routine solves a system of equations using the quartersolve
 +  // algorithm with partial pivoting.
 +  // It is called a "line at a time" and uses only
 +  // 0.25*nn memory locations which enables larger problems to be solved
 +Slv calls the swap'​real and swap'​integer proocedures from the strings
 +package. ​ The strings package is a ROMMED package on the Super Chip ROM.
 +It does exactly what it says, e.g.  swap'​real(a,​b) is the same as:
 +t:=a; a:=b; b:=t.
 +Slv calls the sdot, isamax#, sswap, sscal, saxpy, and scopy routines
 +from the blas package. ​ The blas package is LINKed to the program, but
 +it could, and should, be placed on EPROM.
 +Basic Linear Algebra Subroutines,​ BLAS
 +The BLAS were originally written for the Fortran language to speed
 +execution and streamline code used for solving linear algebra and other
 +matrix problems. ​ The LINPACK routines, Ref. 3, use the BLAS and are
 +perhaps the best known. ​ The idea is that the BLAS routines will be
 +highly optimized for a particular computer, coded in ML or a High Order
 +Language. ​ Some operating systems even include BLAS like routines.
 +Writing fast efficient programs is then a simple matter of selecting the
 +best solution algorithm and coding it in a manner that makes best use of
 +the blas routines. ​ There are blas routines for single precision, double
 +precision, and complex numbers. ​ The level 1 BLAS perform operations on
 +rows or columns of an array and typicaly do n scalar operations
 +replacing the inner most loop of code.  There are also level 2 BLAS that
 +perform n*n operations and Level 3 BLAS that perform n*n*n operations.
 +Nicholas Higham has coded most of the single precision level 1 blas
 +routines and put them in a Comal 2.0 package. ​ The Comal blas package is
 +included on the Packages Library Volume 2 disk.  I am not aware of ML
 +blas routines coded for any other C64/128 languages although this is
 +certainly possible and recommended.
 +The Comal blas routines behave exactly the same way that the Fortran
 +blas routines do except that Fortran can pass the starting address of an
 +array with just "​a",​ while Comal requires "​a(1)"​. ​ The Comal blas will
 +allow you pass an array, by reference, of single or multiple dimensions
 +and start from any position in the array. ​ If you code the blas routines
 +as ordinary Comal routines you have to pass additional parameters and
 +have separate routines for single dimensioned arrays and two dimensional
 +arrays. ​ Note also that Fortran stores two dimensional arrays by
 +columns, and Comal (like many other languages) stores two dimensional
 +arrays by rows.  If you translate code between Fortran and Comal using
 +blas routines you will have to change the increment variables.
 +            Fortran ​                         Comal
 +    dimension c(n), a(ilda,​isda) ​    DIM c(n#), a(lda#,​sda#​)
 +    scopy(n,​c,​1,​a(i,​1),​ilda) ​        ​scopy(n#,​c(1),​1,​a(i#,​1),​1)
 +    scopy(n,​c,​1,​a(1,​j),​1) ​           scopy(n#,​c(1),​1,​a(1,​j#​),​sda#​)
 +The first scopy copies array c into the ith row of array a.  The second
 +scopy copies array c into the jth column of array a.
 +This is what scopy does in Fortran:
 +    subroutine scopy(n,​sx,​incx,​sy,​incy)
 +    real sx(1),sy(1)
 +    ix=1
 +    iy=1
 +    do 10 i = 1,n
 +      sy(iy) = sx(ix)
 +      ix = ix + incx
 +      iy = iy + incy
 + 10 continue
 +    return
 +    end
 +The Comal BLAS does exactly the same thing. ​ If coded entirely in COMAL
 +rather than as a package it would have to be different. ​ The call would
 +scopy(n#,​c(1),​1,​a(1,​j#​),​sda#​) would have to become,
 +scopy(n#,​c(),​1,​1,​a(,​),​1,​j#,​sda#,​sda#​) and the Comal procedure might be:
 +PROC scopy(n#, REF x(), ix#, incx#, REF y(,), iy#, jy#, sdy#, incy#) CLOSED
 +  iyinc#:​=incy#​ DIV sdy#  //assuming y is dimensioned y(?,sdy#)
 +  jyinc#:​=incy#​ MOD sdy#
 +  FOR i#=1 TO n# DO
 +    y(iy#,​jy#​):​=x(ix#​)
 +    ix#:+incx#; iy#:​+iyinc#;​ jy#:+jyinc#
 +ENDPROC scopy
 +Note that more information has to be passed to the procedure and used
 +that the ML blas picks up automatically. ​ Also we would need separate
 +procedures to handle every combination of single and multi dimensional
 +arrays. ​ The Comal ML blas are indeed wonderful. ​ For speed
 +considerations this should also be left as an open procedure or better
 +yet just use in line code.
 +Here is a very simplified description of what each of the routines in
 +the Comal BLAS package does.
 +sum:​=sasum(n#,​x(1),​1) ​ Returns sum of absolute values in x().
 +  sum:=0
 +  FOR i#:=1 TO n# DO sum:​+ABS(x(i#​))
 +saxpy(n#,​sa,​x(1),​1,​y(1),​1) ​ Add a multiple of x() to y().
 +  FOR i#:=1 TO n# DO y(i#​):​+sa*x(i#​)
 +prod:​=sdot(n#,​x(1),​1,​y(1),​1) ​ Returns dot product of x() and y().
 +  prod:=0
 +  FOR i#:=1 TO n# DO prod:​+x(i#​)*y(i#​)
 +sswap(n#,​x(1),​1,​y(1),​1) ​ Swaps x() and y().
 +  FOR i#:=1 TO n# DO t:=x(i#); x(i#​):​=y(i#​);​ y(i#):=t
 +scopy(n#,​x(1),​1,​y(1),​1) ​ Copy x() to y().
 +  For i#:=1 TO n# DO y(i#​):​=x(i#​)
 +max#:​=isamax#​(n,​x(1),​1) ​ Returns index of the element of x() with the
 +                         ​largest absolute value.
 +  t:=0; max#:=1
 +  FOR i#:=1 TO n#
 +    IF ABS(x(i#​))>​t THEN t:​=ABS(x(i#​));​ max#:=i#
 +  ENDFOR i#
 +sscal(n#,​sa,​x(1),​1) ​ Scale x() by a constant sa.
 +  FOR i#:=1 TO n# DO x(i#​):​=sa*x(i#​)
 +snrm2(n#,​x(1),​1) ​ Returns the 2 norm of x().
 +  norm2:=0
 +  FOR i#:=1 TO n# DO norm2:​+x(i#​)*x(i#​)
 +  norm2:​=SQR(norm2)
 +srot(n#,​x(1),​1,​y(1),​1,​c,​s) ​ Apply Givens rotation.
 +  FOR i#:=1 TO n# DO
 +    t:=c*x(i#) + s*y(i#)
 +    y(i#​):​=s*x(i#​) + c*y(i#)
 +    x(i#):=t
 +  ENDFOR i#
 +Bear in mind that each of these simple examples can be more complex as
 +was given for scopy. ​ You now have enough information to write your own
 +BLAS routines in ML or the programming language of your choice, or to
 +expand the BLAS routine calls in slv to ordinary in line code.
 +You can also apply the BLAS routines in creative ways besides just
 +operating on rows or columns. ​ For example you could create the identity
 +matrix with:
 +  DIM a(n#,n#)
 +  a(1,1):=1; a(1,2):=0
 +  scopy(n#​*n#​-2,​a(1,​2),​0,​a(1,​3),​1) // zero the rest of the matrix
 +  scopy(n#​-1,​a(1,​1),​0,​a(2,​2),​n#​+1) // copy ones to the diagonal.
 +1.  Zambardino, R. A., "​Solutions of Systems of Linear Equations with
 +Partial Pivoting and Reduced Storage Requirements",​ The Computer Journal
 +Vol. 17, No. 4, 1974, pp. 377-378.
 +2.  Orden A., "​Matrix Inversion and Related Topics by Direct Methods",​
 +in Mathematical Methods for Digital Computers, Vol. 1, Edited by A.
 +Ralston and H. Wilf, John Wiley and Sons Inc.,  1960.
 +3.  Dongarra, J. J., Moeler, C. B., Bunch, J. R., Stewart, G. W.,
 +Linpack Users' Guide, SIAM Press, Philadelphia,​ 1979.
 +====== The Next Hack ======
 +"But wait, there'​s more!" ​ Actually, there is, but you'll have to wait
 +until next issue for it.  Here's a little appetizer of what's ahead in
 +Commodore Hacking issue #12
 +o  All you cross-development folks, listen up!  Issue #12 will enter the
 +   realm of cross-compilers with Craig Bruce as he details the construction
 +   of a high level language cross compiler. ​ It'll be written in C and will
 +   ​compile a a simplified but structured custom language including concepts
 +   from BASIC, C, and Pascal. Concepts like declaration handling, expression ​
 +   ​interpretion and optimization,​ and structure control definitions will be
 +   ​discussed
 +o  Gearing up for the 65C816S. ​ C=Hacking will detail the new opcodes
 +   ​available to programmers,​ show how to detect CPU clock speed on any
 +   C64, accelerated or not, discuss pitfalls in code migration, and 
 +   ​possibly give a rundown on a prototype accelerator unit from CMD.
 +o  SLIP, Sliding away.... ​ C=Hacking will take an in-depth look at Daniel
 +   ​Dallmann'​s SLIP-DEMO program and go over the SLIP and TCP/​IP ​
 +   ​protocols in detail as they relate to the Commodore.
 +o  Here Boy, here Boy! Good Dog.  The "​FIDO'​s Nuggets"​ column will bring
 +   ​readers up to date on the discussions in the FIDO CBM echo.
 +o  The RumorMonger. ​ The best rumors we've heard so far.  Your mileage
 +   may vary...
 +o  All that and C=Hacking'​s regular columns.  ​
 +So, set aside a place on that disk drive for the next issue now, because you 
 +won't want to miss it...
magazines/chacking11.txt ยท Last modified: 2015-04-17 04:34 (external edit)