@L}5 _$% l0$)$$Hȱ$ UhL" `e$$%`$%`  R@P!( L(1   Y I`  d  Ld M * @  $ % CC$$)%1 Udߥ$9%: !0 S$% DD˙`  }J)Lr d M * @  $ % CC$$)%1 Udߥ$9%: !0 S$%} DD˙`  }J)Lr J  ((  p L ()   J}L= ( L 0q A    IB JC;? D W } LL  ` W )LA!  ߰")-݆ p" } $G@LL 08`Q")<2Q0 -G$Ș݆ UL# ; p8(()(0ʥ)NQ` }$GȘ݆LU )L ݆ L GȘ ݆LL )W>Z   HH)H }p h  hyhy D L> L JJ    ! LA*` BF }7'8  M HN H` 8 Z  \LdJJ!"! GFE@F (!L }EE !E^ ^ E E7EȩEdE/EȩE  D } .L }  ;F d  ;?F7F? ( .   Z D LL d } . D  L    p  E` , d)  D L) 0BM݊L݉} ML  N݆ L NLML [ TEqEHȱEqEh 0Gȹ G} HLL GɛL  LFREE SECTORS G) *Gȩ GȽG GȌ*jj >G} C8jJ3j2CD( C202C ԠBX` N 1? l LlD:RAMDISK}.COMLu L1 L ;LHL  T`  `1  ɐ     `TU  } L ? .  t`GBJ ~DEHI B V0dV!}QDEHI VF9 ,0 ,0 s0hhL  L` H hDHEh"}DEL8HI4 0 HI,0 0  9 .G VLO#},0 L4*IJ`llD1:AUTORUN.SYSNEED MEM.SAV TO LOAD THIS FILE.D1:MEM.SAV J y08 B|DEHI$} V0 0`B;DEL`?<0LV`@ʆ v s? F0Ξ05: [ BDEHI%} VY8 B V  @  /DE `E:D1:DUP.SYSERROR-SAVING USER MEMORY ON DISKTYPE Y TO &}STILL RUN DOS B;DE J  (` 9 V⪍ ઍ  -'}LLu ÝDEHILV 9 .l 9 .l  `` s$B BH(}I|DE V BLV nB,DE JLV B V BLVDEIʩ BꭝLu  } 3E:}DISK OPERATING SYSTEM II VERSION COPYRIGHT 1984 ATARI CORP.A. DISK DIRECTORY I. FORMAT DISKB. RUN CARTRIDG*}E J. DUPLICATE DISKC. COPY FILE K. BINARY SAVED. DELETE FILE(S) L. BINARY LOADE. RENAME FILE M. RUN AT ADDRES+}SF. LOCK FILE N. CREATE MEM.SAVG. UNLOCK FILE O. DUPLICATE FILEH. WRITE DOS FILES P. FORMAT SINGLEL !N',}#"&))9(&*)/h)''-&؆莟R'S  vL/ˢ L }Insert DOS 2.0s, type Y Λx -}DEfHI 1莏#q! @ y0ɛ8A0,' ȅ 1 1ild! 1L!NO SUCH ITEMSELECT.} ITEM OR FOR MENU! 0 .z:*{}.|{ 1 0 0JB 18L%|DL/}%DIRECTORY--SEARCH SPEC,LIST FILE?[# 0 0 &|D3" 1L!NOT A DISK FILEN !B 1L!E# 1 !BD0}ED:}:1BJ|DE 1DEBHI 1 h0ߢ 0.1}  0?詛 1 y0YЛ 1 ;#L" ;#L! BL1TYPE "Y" TO DELETE...DELETE FILE SPEC2}COPY--FROM, TO?OPTION NOT ALLOWED736 FREE SECTORS COPYING---D1:DIRECK.COMl# 0|D .L/%#3}##JB|DE 1BHID#E 1#0: B 1L!#͑### B 1#c$0SY4}S1}:## # # .#Ƚ# # 𩛙## 1,#PD#ELJ- <.BJD#E 5}1 1HH 0hh|DL%1}:̳# L% #D#EL% 1 0 . .0O% 1L!WILD CARDS NOT A6}LLOWED IN DESTINATION 0 <.|K}N 2 FORMAT. t* 5) 1L!`) 0NΞ 0 L1) 1 L!BAD LOAD FILELOAD FROM WHAT FILE?) 0 ?}0#B 1L!WHAT FILE TO LOCK?) 0 0$B 1L!WHAT FILE TO UNLOCK?DUP DISK-SOURCE,DEST DRIVES?TYPE "Y" IF OK TO US@}E PROGRAM AREACAUTION: A "Y" INVALIDATES MEM.SAV.FE! +L1   `*  70 2 2A} 0.* 1 y0 0)INSERT BOTH DISKS, TYPE RETURN^, 1 y038逍 N, 1L! ,B}C, t*  Lx+, 0 ^, 1 y0 , ,0,0 ,L+ ,I0 ,Vǭ0C}Ξ, 0 }, 1 y0C,ШC, 0K'!" H H 'h h Lx+!EF 5L1L!D,I,HhD}` NOT ENOUGH ROOMINSERT SOURCE DISK,TYPE RETURNINSERT DESTINATION DISK,TYPE RETURNE}`  `8 rL1`-* 1P* 1 y0Y`hhL!NAME OF FILE TO MOVE?- 0 0|DL% <.F},^ 1 70 0 .@L# .BJ 1  DEHIB V L1 ,} 1 70,L.  G}JB|,#P#DE 1 HI BDEHHII 1 B 1 ,^ 1 70,0La- B V,#PH},^ 1 70 0L#L!-* 1P* 1 y0Yj383}mm ݭI}}`8}``|* ? ɛ,`|:-)| / 1L!`DESTINATION CANT BE DOJ}S.SYS0 0H{ 24Δ 28/L!/) 2 Π 2 0 ξK}hAΞB,0 J 1 BDEHI,HÝDE 1HIHIDELSAVE-GIVE L}FILE,START,END(,INIT,RUN)O S0 1`BDEPHI V` S0H 1 L!M}0 0 1L~0`PLEASE TYPE 1 LETTER,0`hhL! 70 1L0L<1 ,;ɛ7,"ɛ:ݦ1ݥN}A"D|ݤD|ȩ:|ȩ|ɛ,,(/+.ީ1 1,ɛ`轤{NAMEO} TOO LONG B VL!` L1I H1EΝDL1|mDiE` V0`8d/8 i:222 1 LP}!ERROR- 138ɛ+,' 20*.. өr2 1``2TOO MANY DIGITSINVALID HEXAQ}DECIMAL PARAMETER800 0 8 00`,0'D800 H,ɛh`2L1NEED D1 THRU D8uR} ECIMAL PARAMETER800 0 8 00`,0'D800 H,ɛh`2L1NEED D1 THRU D8uat2a atoi.cunsan atoi.cat2a fopen.cunsan fopen.cat2a isascii.cunsan isascii.cat2a ispunct.cunsan ispunct.cat2a itou.cT}unsan itou.cat2a reverse.cunsan reverse.cat2a xtoi.cunsan xtoi.cat2a atoib.cunsan atoib.cat2a fprintf.cunsan fprintfU}.cat2a isatty.cunsan isatty.cat2a isspace.cunsan isspace.cat2a itox.cunsan itox.cat2a startup.cunsan startup.cat2a dV}elete.cunsan delete.cat2a fputs.cunsan fputs.cat2a iscntrl.cunsan iscntrl.cat2a isupper.cunsan isupper.cat2a open.cuW}nsan open.cat2a strcat.cunsan strcat.cat2a dtoi.cunsan dtoi.cat2a fread.cunsan fread.cat2a iscons.cunsan iscons.cat2X}a isxdigit.cunsan isxdigit.cat2a otoi.cunsan otoi.cat2a strcmp.cunsan strcmp.cat2a fclose.cunsan fclose.cat2a fwrite.Y}cunsan fwrite.cat2a isgraph.cunsan isgraph.cat2a itoab.cunsan itoab.cat2a pmalloc.cunsan pmalloc.cat2a time.cunsan tZ}ime.cat2a fgets.cunsan fgets.cat2a gets.cunsan gets.cat2a islower.cunsan islower.cat2a itod.cunsan itod.cat2a readar[}gs.cunsan readargs.cat2a toascii.cunsan toascii.cat2a fname.cunsan fname.cat2a isalnum.cunsan isalnum.cat2a isprint.c\}unsan isprint.cat2a itoo.cunsan itoo.cat2a rename.cunsan rename.cat2a utoi.cunsan utoi.cat2a atari.m65unsan atari.m6]}5at2a close.m65unsan close.m65at2a getch.m65unsan getch.m65at2a isodigit.m65unsan isodigit.m65at2a runtime.m65unsan r^}untime.m65at2a toupper.m65unsan toupper.m65at2a bcopy.m65unsan bcopy.m65at2a closeall.m65unsan closeall.m65at2a global_}.m65unsan global.m65at2a iswhite.m65unsan iswhite.m65at2a rwcommon.m65unsan rwcommon.m65at2a tprintf.m65unsan tprintf.`}m65at2a bzero.m65unsan bzero.m65at2a cputc.m65unsan cputc.m65at2a heap.m65unsan heap.m65at2a itoa.m65unsan itoa.m65aa}t2a stdio.m65unsan stdio.m65at2a write.m65unsan write.m65at2a cgetc.m65unsan cgetc.m65at2a fdelete.m65unsan fdelete.m6b}5at2a isalpha.m65unsan isalpha.m65at2a parselin.m65unsan parselin.m65at2a strchr.m65unsan strchr.m65at2a cgets.m65unsc}an cgets.m65at2a frename.m65unsan frename.m65at2a isdigit.m65unsan isdigit.m65at2a read.m65unsan read.m65at2a tolower.d}m65unsan tolower.m65at2a ctype.hunsan ctype.hat2a file.hunsan file.hat2a stdio.hunsan stdio.hn read.m65at2a tolower.e;; Defs for Atari OS. These defs were stolen from ALBUG's SYSMAC.SML.; This file generates no code, just contains rom loca f}tions etc.;; VECTOR TABLEEDITRV =$E400 ;EDITORSCRENV =$E410 ;TELEVISION SCREENKEYBDV =$E420 ;KEYBOA g}RDPRINTV =$E430 ;PRINTERCASETV =$E440 ;CASSETTE; JUMP VECTOR TABLEDISKIV =$E450 ;DISK INITIALIZATION h}DSKINV =$E453 ;DISK INTERFACECIOV =$E456 ;CIO ROUTINESIOV =$E459 ;SIO ROUTINESETVBV =$E45C ;SET V i}ERTICAL BLANK VECTORSSYSVBV =$E45F ;SYSTEM VERTICAL BLANK ROUTINEXITVBV =$E462 ;EXIT VERTICAL BLANK ROUTINESIO j}INV =$E465 ;SIO INITSENDEV =$E468 ;SEND ENABLE ROUTINEINTINV =$E46B ;INTERRUPT HANDLER INITCIOINV =$E46 k}E ;CIO INITBLKBDV =$E471 ;BLACKBOARD MODEWARMSV =$E474 ;WARM START ENTRY POINTCOLDSV =$E477 ;COLD S l}TART ENTRY POINTRBLOKV =$E47D ;CASSETTE READ BLOCK VECTORDSOPIV =$E480 ;CASSETTE OPEN FOR INPUT VECTOR; SOME m} USEFUL INTERNAL ROUTINES;KGETCH =$F6E2 ;GET CHAR FROM KEYBOARD only on 800EOUTCH =$F6A4 ;OUTPUT CHAR TO SCREE n}NPUTLIN =$F385 ;OUTPUT LINE TO IOCB#0; COMMAND CODES FOR IOCBOPEN =$03 ;OPEN FOR INPUT/OUTPUTGETREC =$05 o} ;GET RECORD (TEXT)GETCHR =$07 ;GET CHARACTER(S)PUTREC =$09 ;PUT RECORD (TEXT)PUTCHR =$0B ;PUT CHARA p}CTER(S)CLOSE =$0C ;CLOSE DEVICESTATIS =$0D ;STATUS REQUESTSPECIL =$0E ;SPECIAL ENTRY COMMANDS; SPECIA q}L ENTRY COMMANDSDRAWLN =$11 ;DRAW LINEFILLIN =$12 ;DRAW LINE WITH RIGHT FILLRENAME =$20 ;RENAME DISK FI r}LEDELETE =$21 ;DELETE DISK FILEFORMAT =$22 ;FORMAT DISKLOCKFL =$23 ;LOCK FILE (READ ONLY)UNLOCK =$24 s} ;UNLOCK FILEPOINT =$25 ;POINT SECTORNOTE =$26 ;NOTE SECTORCCIO =$28 ;CONCURRENT I/O MODEIOCFRE = t}$FF ;IOCB "FREE"; AUX1 VALUES FOR OPENAPPEND =$01 ;OPEN FOR APPENDDIRECT =$02 ;OPEN FOR DIRECTORY ACCE u}SSOPNIN =$04 ;OPEN FOR INPUTOPNOT =$08 ;OPEN FOR OUTPUTOPNINO =OPNIN!OPNOT ;OPEN FOR INPUT/OUTPUTMXDMOD v}=$10 ;OPEN FOR MIXED MODEINSCLR =$20 ;OPEN WITHOUT CLEARING SCREEN; OS STATUS CODESSUCCES =$01 ;SUCCESS w}FUL OPERATIONBRKABT =$80 ;(128) BREAK KEY ABORTPRVOPN =$81 ;(129) IOCB ALREADY OPENNONDEV =$82 ;(130) NO x}N-EX DEVICEWRONLY =$83 ;(131) IOCB OPENED FOR WRITE ONLYNVALID =$84 ;(132) INVALID COMMANDNOTOPN =$85 ;( y}133) DEVICE OR FILE NOT OPENBADIOC =$86 ;(134) INVALID IOCB NUMBERRDONLY =$87 ;(135) IOCB OPENED FOR READ ONLY z}EOFERR =$88 ;(136) END OF FILETRNRCD =$89 ;(137) TRUNCATED RECORDTIMOUT =$8A ;(138) DEVICE TIMEOUTDNACK {} =$8B ;(139) DEVICE DOES NOT ACK COMMANDFRMERR =$8C ;(140) SERIAL BUS FRAMING ERRORCRSROR =$8D ;(141) CURS |}OR OUT OF RANGEOVRRUN =$8E ;(142) SERIAL BUS DATA OVERRUNCHKERR =$8F ;(143) SERIAL BUS CHECKSUM ERRORDERROR = }}$90 ;(144) DEVICE ERROR (OPERATION INCOMPLETE)BADMOD =$91 ;(145) BAD SCREEN MODE NUMBERFNCNOT =$92 ;(146) ~}FUNCTION NOT IN HANDLERSCRMEM =$93 ;(147) INSUFFICIENT MEMORY FOR SCREEN MODE; PAGE 0 LOCATIONSLINZBS =$00 };LINBUG STORAGE ; THESE LOCS ARE NOT CLEAREDCASINI =$02 ;CASSETTE INIT LOCRAMLO =$04 ;RAM POINTER FOR MEM T }ESTTRAMSZ =$06 ;TEMP LOC FOR RAM SIZETSTDAT =$07 ;RAM TEST DATA LOC; CLEARED ON COLDSTART ONLYWARMST =$08 } ;WARM START FLAGBOOTQ =$09 ;SUCCESSFUL BOOT FLAGDOSVEC =$0A ;DOS START VECTORDOSINI =$0C ;DOS INIT } ADDRESSAPPMHI =$0E ;APPLICATION MEM HI LIMIT; CLEARED ON COLD OR WARM STARTINTZBS =$10 ; START OF OS RAM C }LEAR LOC => $7FPOKMSK =$10 ;SYSTEM MASK FOR POKEY IRQ ENABLEBRKKEY =$11 ;BREAK KEY FLAGRTCLOK =$12 ;REAL } TIME CLOCK (60HZ OR 16.66666 MS) ; 3 bytes; hi order, medium, lowBUFADR =$15 ;INDIRECT BUFFER ADDRESS REGICC }OMT =$17 ;COMMAND FOR VECTOR HANDLERDSKFMS =$18 ;DISK FILE MANAGER POINTERDSKUTL =$1A ;DISK UTILITIES POI }NTERPTIMOT =$1C ;PRINTER TIME OUT REGISTERPBPNT =$1D ;PRINT BUFFER POINTERPBUFSZ =$1E ;PRINT BUFFER SIZE }PTEMP =$1F ;TEMP REGZIOCB =$20 ;PAGE 0 I/O CONTROL BLOCKIOCBSZ =16 ;NUMBER OF BYTES / IOCBMAXIOC =8*IO }CBSZ ;LENGTH OF IOCB AREAIOCBAS =ZIOCBICHIDZ =$20 ;HANDLER INDEX NUMBER ($FF := IOCB FREE)ICDNOZ =$21 ;DE }VICE NUMBER (DRIVE NUMBER)ICCOMZ =$22 ;COMMAND CODEICSTAZ =$23 ;STATUS OF LAST IOCB ACTIONICBALZ =$24 ;B }UFFER ADDRESS (LOW)ICBAHZ =$25 ; " " (HIGH)ICPTLZ =$26 ;PUT BYTE ROUTINE ADDRESS - 1ICPTHZ =$27ICBLLZ } =$28 ;BUFFER LENGTH (LOW)ICBLHZ =$29 ; " " (HIGH)ICAX1Z =$2A ;AUX INFOICAX2Z =$2BICSPRZ =$2C } ;SPARE BYTES (CIO LOCAL USE)ICIDNO =ICSPRZ+2 ;IOCB LUMBER * 16CIOCHR =ICSPRZ+3 ;CHARACTER BYTE FOR CURRENT OPER }ATIONOSSTATUS =$30 ;INTERNAL STATUS STORAGEOSCHKSUM =$31 ;CHECKSUM (SINGLE BYTE SUM WITH CARRY)BUNRLO =$32 } ;POINTER TO DATA BUFFER (LO BYTE)BUFRHI =$33 ;POINTER TO DATA BUFFER (HI BYTE)BFENLO =$34 ;NEXT BYTE PAST E }ND OF BUFFER (LO BYTE)BNENHI =$35 ;NEXT BYTE PAST END OF BUFFER (HI BYTE)CRETRY =$36 ;NUMBER OF COMMAND FRAM RE }TRIESDRETRY =$39 ;NUMBER OF DEVICE RETRIESBUFRFL =$38 ;DATA BUFFER FULL FLAGRECVDN =$39 ;RECEIVE DONE FL }AGXMTDON =$3A ;XMIT DONE FLAGCHKSNT =$3B ;CHECKSUM SENT FLAGNOCKSM =$3C ;NO CHECKSUM FOLLOWS DATA FLAG }BPTR =$3D ;BUFFER POINTER (CASSETTE)FTYPE =$3E ;FILE TYPE (SHORT IRG/LONG IRG)FEOF =$3F ;END OF FILE FLAG } (CASSETTE)FREQ =$40 ;FREQ COUNTER FOR CONSOLE SPEAKERSOUNDR =$41 ;NOISY I/O FLAG. (ZERO IS QUIET)CRITIC =$42 } ;CRITICAL CODE IF NON-ZERO)FMSZPG =$43 ;DISK FILE MANAGER SYSTEM STORAGE (7 BYTES)CKEY =$4A ;SET WHEN G }AME START PRESSEDCASSBT =$4B ;CASSETTE BOOT FLAGDSTAT =$4C ;DISPLAY STATUSATRACT =$4D ;ATTRACT MODE FLAG }DRKMSK =$4E ;DARK ATTRACT MASKCOLRSH =$4F ;ATTRACT COLOR SHIFTER (XOR'D WITH PLAYFIELD)TMPCHR =$50 ;TEM }P CHAR STORAGE (DISPLAY HANDLER)HOLD1 =$51 ;TEMP STG (DISPLAY HANDLER)LMARGN =$52 ;LEFT MARGINRMARGN =$53 } ;RIGHT MARGINROWCRS =$54 ;CURSOR COUNTERSCOLCRS =$55DINDEX =$57 ;DISPLAY INDEX (VARIOUS QUANTS)SAVMSC =$5 }8OLDROW =$5A ;PREVIOUS ROW/COLOLDCOL =$5BOLDCHR =$5D ;DATA UNDER CURSOROLDADR =$5ENEWROW =$60 ;POINT } DRAWS TO HERENEWCOL =$61LOGCOL =$63 ;POINTS AT COLUMN IN LOGICAL LINEADRESS =$64 ;INDIRECT POINTERMLTTMP = }$66 ;MULTIPLY TEMPOPNTMP =MLTTMP ;FIRST BYTE IS USED IN OPEN AS TEMPSAVADR =$68RAMTOP =$6A ;RAM SIZE DEF }INED BY POWER ON LOGICBUFCNT =$6B ;BUFFER COUNTBUFSTR =$6C ;EDITOR GETCH POINTERBITMSK =$6E ;BIT MASKSH }FAMT =$6F ;OUTCHR SHIFTROWAC =$70 ;USED BY "DRAW"COLAC =$72ENDPT =$74DELTAR =$76DELTAC =$77ROWINC =$7 }9COLINC =$7ASWPFLG =$7B ;NON-0 IF TXT AND RAM SWAPPEDHOLDCH =$7C ;CH BEFORE CNTL & SHFT PROCESSING IN KGETCH }INSDAT =$7D ;INSERT CHAR SAVECOUNTR =$7E ;DRAW COUNTER;;; $80 TO $FF ARE RESERVED FOR USER APPLICATIONS; P }AGE 2 LOCATIONSINTABS =$200 ;INTERRUPT TABLEVDSLST =$200 ;DISPLAY LIST NMI VECTORVPRCED =$202 ;PROCEED }LINE IRQ VECTORVINTER =$204 ;INTERRUPT LINE IRQ VECTORVBREAK =$206 ;"BRK" VECTORVKEYBD =$208 ;POKEY KEYB }OARD IRQ VECTORVSERIN =$20A ;POKEY SERIAL INPUT READYVSEROR =$20C ;POKEY SERIAL OUTPUT READYVSEROC =$20E } ;POKEY SERIAL OUTPUT DONEVTIMR1 =$210 ;POKEY TIMER 1 IRQVTIMR2 =$212 ;POKEY TIMER 2 IRQVTIMR4 =$214 ;PO }KEY TIMER 4 IRQ (DO NOT USE)VIMIRQ =$216 ;IMMEDIATE IRQ VECTORCDTMV1 =$218 ;COUNT DOWN TIMER 1CDTMV2 =$21A } ;COUNT DOWN TIMER 2CDTMV3 =$21C ;COUNT DOWN TIMER 3CDTMV4 =$21E ;COUNT DOWN TIMER 4CDTMV5 =$220 ;COUN }T DOWN TIMER 5VVBLKI =$222 ;IMMEDIATE VERTICAL BLANK NMI VECTORVVBLKD =$224 ;DEFERRED VERTICAL BLANK NMI VECTOR }CDTMA1 =$226 ;COUNT DOWN TIMER 1 JSR ADDRESSCDTMA2 =$228 ;COUNT DOWN TIMER 2 JSR ADDRESSCDTMF3 =$22A ;CO }UNT DOWN TIMER 3 FLAGSRTIMR =$22B ;SOFTWARE REPEAT TIMERCDTMF4 =$22C ;COUNT DOWN TIMER 4 FLAGINTEMP =$22D } ;IAN'S TEMP (???)CDTMF5 =$22E ;COUNT DOWN TIMER 5 FLAGSDMCTL =$22F ;SAVE DMACTL REGISTERDMACTL =$D400 }; the real DMA control regSDLSTL =$230 ;SAVE DISPLAY LIST (LOW)SDLSTH =$231 ;SAVE DISPLAY LIST (HIGH)SSKCTL = }$232 ;SKCTL REGISTER RAMLPENH =$234 ;LIGHT PEN HORIZ VALUELPENV =$235 ;LIGHT PEN VERT VALUE ; ($2 }36 - $239 SPARE)CDEVIC =$23A ;COMMAND FRAME BUFFER - DEVICECCOMND =$23B ;COMMANDCAUX1 =$23C ;COMMAND AUX } BYTE 1CAUX2 =$23D ;COMMAND AUX BYTE 2TEMP =$23E ;YESERRFLG =$23F ;ERROR FLAG - ANY DEVICE ERROR EXCEPT }TIMEOUTDFLAGS =$240 ;DISK FLAGS FROM SECTOR ONEDBSECT =$241 ;NUMBER OF DISK BOOT SECTORSBOOTAD =$242 ;A }DDRESS FOR DISK BOOT LOADERCOLDST =$244 ;COLDSTART FLAG (1 = DOING COLDSTART) ;($245 SPARE)DSKTIM =$246 } ;DISK TIME OUT REGLINBUF =$247 ;CHAR LINE BUFFER (40 BYTES)GPRIOR =$26F ;GLOBAL PRIORITY CELLPADDL0 =$270 } ;POT 0 SHADOWPADDL1 =$271 ;POT 1 SHADOWPADDL2 =$272 ;POT 2 SHADOWPADDL3 =$273 ;POT 3 SHADOWPADDL4 }=$274 ;POT 4 SHADOWPADDL5 =$275 ;POT 5 SHADOWPADDL6 =$276 ;POT 6 SHADOWPADDL7 =$277 ;POT 7 SHADOWS }TICK0 =$278 ;JOYSTICK 0 SHADOWSTICK1 =$279 ;JOYSTICK 1 SHADOWSTICK2 =$27A ;JOYSTICK 2 SHADOWSTICK3 =$27 }B ;JOYSTICK 3 SHADOWPTRIG0 =$27C ;PADDLE 0 TRIGGERPTRIG1 =$27D ;PADDLE 1 TRIGGERPTRIG2 =$27E ;PADDL }E 2 TRIGGERPTRIG3 =$27F ;PADDLE 3 TRIGGERPTRIG4 =$280 ;PADDLE 4 TRIGGERPTRIG5 =$281 ;PADDLE 5 TRIGGERPT }RIG6 =$282 ;PADDLE 6 TRIGGERPTRIG7 =$283 ;PADDLE 7 TRIGGERSTRIG0 =$284 ;JOYSTICK 0 TRIGGERSTRIG1 =$285 } ;JOYSTICK 1 TRIGGERSTRIG2 =$286 ;JOYSTICK 2 TRIGGERSTRIG3 =$287 ;JOYSTICK 3 TRIGGERCSTAT =$288 ;(U }NUSED)WMODE =$289 ;R/W FLAG FOR CASSETTEBLIM =$28A ;BUFFER LIMIT (CASSETTE) ;($28B - $28F SPARE)TXTROW } =$290 ;TEXT ROWCRSTXTCOL =$291 ;TEXT ROWCOLTINDEX =$293 ;TEXT INDEXTXTMSC =$294 ;FOOLS CONVRT INT }O NEW MSCTXTOLD =$296 ;OLDROW & OLDCOL FOR TEXT (AND THEN SOME)TMPX1 =$29CHOLD3 =$29DSUBTMP =$29EHOLD2 =$29FD }MASK =$2A0TMPLBT =$2A1OSESCFLG =$2A2 ;ESCAPE FLAGTABMAP =$2A3 ;TAB BUFFERLOGMAP =$2B2 ;LOGICAL LINE S }TART BIT MAPINVFLG =$2B6 ;INVERSE VIDEO FLAG (ATARI KEY)FILFLG =$2B7 ;RIGHT FILL FLAG FOR DRAWTMPROW =$2B8TM }PCOL =$2B9SCRFLG =$2BB ;SET IF SCROLL OCCURSHOLD4 =$2BC ;MORE DRAW TEMPSHOLD5 =$2BDSHFLOK =$2BE ;SHIF }T LOCK KEYBOTSCR =$2BF ;BOTTOM OF SCREEN (24 NORM, 4 SPLIT)PCOLR0 =$2C0 ;P0 COLORPCOLR1 =$2C1 ;P1 COLOR }PCOLR2 =$2C2 ;P2 COLORPCOLR3 =$2C3 ;P3 COLORCOLOR0 =$2C4 ;COLOR 0COLOR1 =$2C5COLOR2 =$2C6COLOR3 =$ }2C7COLOR4 =$2C8 ;BACKGROUND ;($2C9 - $2DF SPARE)GLBABS =$2E0 ;GLOBAL VARIABLES ;($2E0 - $2E3 SP }ARE)RAMSIZ =$2E4 ;RAM SIZE (HI BYTE ONLY)MEMTOP =$2E5 ;TOP OF AVAILABLE MEMORYMEMLO =$2E7 ;BOTTOM OF AVA }ILABLE MEMORY ;($2E9 SPARE)DVSTAT =$2EA ;STATUS BUFFERCBAUDL =$2EE ;CASSETTE BAUD RATE (LO BYTE)CBAUDH } =$2EF ; " " " (HI BYTE)CRSINH =$2F0 ;CURSOR INHIBIT (00 = CURSOR ON)KEYDEL =$2F1 ;KEY DELAY }CH1 =$2F2CHACT =$2F3 ;CHACTL REGISTER (SHADOW)CHBAS =$2F4 ;CHBAS REGISTER (SHADOW) ;($2F5 - $2F9 SPARE })OSCHAR =$2FAATACHR =$2FB ;ATASCII CHARACTERCH =$2FC ;GLOBAL VARIABLE FOR KEYBOARDFILDAT =$2FD ;RIGHT }FILL DATA (DRAW)DSPFLG =$2FE ;DISPLAY FLAG: DISP CONTROLS IF NON-ZEROSSFLAG =$2FF ;START/STOP FLAG (CNTL-1) FOR } PAGING; PAGE 3 LOCATIONSDCB =$300 ;DEVICE CONTROL BLOCKDDEVIC =$300 ;BUS I.D. NUMBERDUNIT =$301 ;UN }IT NUMBERDCOMND =$302 ;BUS COMMANDDSTATS =$303 ;COMMAND TYPE/STATUS RETURNDBUFLO =$304 ;DATA BUFFER POIN }TERDBUFHI =$305 ; ...DTIMLO =$306 ;DEVICE TIME OUT IN 1 SEC. UNITSDUNUSE =$307 ;UNUSEDDBYTLO =$308 } ;BYTE COUNTDBYTHI =$309 ; ...DAUX1 =$30A ;COMMAND AUXILLARY BYTESDAUX2 =$30B ; ...TIMER1 =$30C } ;INITIAL TIMER VALUEADDCOR =$30E ;ADDITION CORRECTIONCASFLG =$30F ;CASSETTE MODE WHEN SETTIMER2 =$310 ; }FINAL TIME VALUE (USED TO COMPUTE BAUD RATE)TEMP1 =$312 ;TEMP LOCATIONSTEMP2 =$314 ; ...TEMP3 =$315 ; .. }.SAVIO =$316 ;SAVE SERIAL IN DATA PORTTIMFLG =$317 ;TIME OUT FLAG FOR BAUD RATE CORRECTIONSTACKP =$318 ; }SIO STACK POINTER SAVE LOCTSTAT =$319 ;TEMP STATUS LOCHATABS =$31A ;HANDLER ADDRESS TABLE MAXDEV =$21 ; }MAXIMUM HANDLER ADDRESS INDEX; IOCB OFFSETS IOCB =$340 ;I/O CONTROL BLOCKSICHID =$340 ;HANDLER INDEX ($FF = } FREE)ICDNO =$341 ;DEVICE NUMBER (DRIVE NUMBER)ICCOM =$342 ;COMMAND CODEICSTA =$343 ;STATUSICBAL =$344 } ;BUFFER ADDRESSICBAH =$345 ; ...ICPTL =$346 ;PUT BYTE ROUTINE ADDRESS - 1ICPTH =$347 ; ...ICBLL }=$348 ;BUFFER LENGTHICBLH =$349 ; ...ICAX1 =$34A ;AUXILLARY INFOICAX2 =$34B ; ...ICSPR =$34C } ;4 SPARE BYTESPRNBUF =$3C0 ;PRINTER BUFFER ;($3EA - $3FC SPARE); PAGE 4 LOCATIONSCASBUF =$3FD ;CA }SSETTE BUFFER; USER AREA STARTS HERE AND GOES TO THE END OF PAGE 5USAREA =$480;; Other random stuff;CONSOL = $D01 }F ; console switches start, select, option;ATASCII CHARACTER DEFSATCLR =$7D ;CLEAR SCREEN CHARACTERATRUB =$7E } ;BACK SPACE (RUBOUT)ATTAB =$7F ;TABATEOL =$9B ;END-OF-LINEATDELL =$9C ; Delete lineATBEL =$FD } ;CONSOLE BELLATURW =$1C ;UP-ARROWATDRW =$1D ;DOWN-ARROWATLRW =$1E ;LEFT-ARROWATRRW =$1F ;RIGHT-A }RROW; USEFUL VALUESLEDGE =2 ;LMARGN'S INITIAL VALUEREDGE =39 ;RMARGN'S INITIAL VALUE;; End of SYSMAC.SML };----------------------------------------------------------------;; defs from sysequ.asm;;; EXECUTE FLAG DEFINES;EX }CYES = $80 ; EXECUTE IN PROGRESSEXCSCR = $40 ; ECHO EXCUTE INPUT TO SCREENEXCNEW = $10 ; EXECUTE START UP MODEEXC }SUP = $20 ; COLD START EXEC FLAG;; MISC ADDRESS EQUATES;CPALOC = $0A ; POINTER TO CP/AWARMST = $08 ; WARM START } (0=COLD)MEMLO = $2E7 ; AVAIL MEM (LOW) PTRMEMTOP = $2E5 ; AVAIL MEM (HIGH) PTRAPPMHI = $0E ; UPPER LIMIT OF APPL }ICATION MEMORYINITADR = $2E2 ; ATARI LOAD/INIT ADRGOADR = $2E0 ; ATARI LOAD/GO ADRCARTLOC = $BFFA ; CARTRIDGE RUN } LOCATIONCIO = $E456 ; CIO ENTRY ADREOL = $9B ; END OF LINE CHAR;;; CP/A FUNCTION AND VALUE DISPLACEMSNT; (I }NDIRECT THROUGH CPALOC); IE. (CPALOC),Y;CPGNFN = 3 ; GET NEXT FILE NAMECPDFDV = $07 ; DEFAULT DRIVE (3 BY }TES)CPBUFP = $0A ; CMD BUFF NEXT CHAR POINTR (1 BYTE)CPEXFL = $0B ; EXECUTE FLAGCPEXFN = $0C ; EXECUTE FILE NAME }(16 BYTES)CPEXNP = $1C ; EXECUTE NOTE/POINT VALUESCPFNAM = $21 ; FILENAME BUFFERRUNLOC = $3D ; CP/A LOAD/RUN ADR }CPCMDB = $3F ; COMMAND BUFFER (60 BYTES);CPCMDGO = -6 ; CP SUBROUTINE VECTOR;;------------------------------------- }---------------------------;; Floating point defs;fr0 = $D4 ; float reg 0fr1 = $E0 ; float reg 1flptr = $FC } ; pointer to a fp numinbuff = $F3 ; pointer to ascii numifp = $D9AA ; int in fr0 -> float in fr0fpi = $D9 }D2 ; float in fr0 -> int in fr0fasc = $D8E6 ; fr0 -> (inbuff)fmove = $DDB6 ; fr0 -> fr1fadd = $DA66 ; fr }0 + fr1 -> fr0fsub = $DA60 ; fr0 - fr1 -> fr0fmul = $DADB ; fr0 * fr1 -> fr0fdiv = $DB28 ; fr0 / fr1 -> fr0 }fld1r = $DD98 ; fr1 <- (XY); end of atari.m65ul = $DADB ; fr0 * fr1 -> fr0fdiv = $DB28 ; fr0 / fr1 -> fr0 6a2at atoi.csanitize atoi.ca2at fopen.csanitize fopen.ca2at isascii.csanitize isascii.ca2at ispunct.csanitize ispunct.c}a2at itou.csanitize itou.ca2at reverse.csanitize reverse.ca2at xtoi.csanitize xtoi.ca2at atoib.csanitize atoib.ca2at} fprintf.csanitize fprintf.ca2at isatty.csanitize isatty.ca2at isspace.csanitize isspace.ca2at itox.csanitize itox.ca}2at startup.csanitize startup.ca2at delete.csanitize delete.ca2at fputs.csanitize fputs.ca2at iscntrl.csanitize iscntr}l.ca2at isupper.csanitize isupper.ca2at open.csanitize open.ca2at strcat.csanitize strcat.ca2at dtoi.csanitize dtoi.c}a2at fread.csanitize fread.ca2at iscons.csanitize iscons.ca2at isxdigit.csanitize isxdigit.ca2at otoi.csanitize otoi.}ca2at strcmp.csanitize strcmp.ca2at fclose.csanitize fclose.ca2at fwrite.csanitize fwrite.ca2at isgraph.csanitize isg}raph.ca2at itoab.csanitize itoab.ca2at pmalloc.csanitize pmalloc.ca2at time.csanitize time.ca2at fgets.csanitize fget}s.ca2at gets.csanitize gets.ca2at islower.csanitize islower.ca2at itod.csanitize itod.ca2at readargs.csanitize readar}gs.ca2at toascii.csanitize toascii.ca2at fname.csanitize fname.ca2at isalnum.csanitize isalnum.ca2at isprint.csanitiz}e isprint.ca2at itoo.csanitize itoo.ca2at rename.csanitize rename.ca2at utoi.csanitize utoi.ca2at atari.m65sanitize a}tari.m65a2at close.m65sanitize close.m65a2at getch.m65sanitize getch.m65a2at isodigit.m65sanitize isodigit.m65a2at run}time.m65sanitize runtime.m65a2at toupper.m65sanitize toupper.m65a2at bcopy.m65sanitize bcopy.m65a2at closeall.m65sanit}ize closeall.m65a2at global.m65sanitize global.m65a2at iswhite.m65sanitize iswhite.m65a2at rwcommon.m65sanitize rwcommo}n.m65a2at tprintf.m65sanitize tprintf.m65a2at bzero.m65sanitize bzero.m65a2at cputc.m65sanitize cputc.m65a2at heap.m65}sanitize heap.m65a2at itoa.m65sanitize itoa.m65a2at stdio.m65sanitize stdio.m65a2at write.m65sanitize write.m65a2at c}getc.m65sanitize cgetc.m65a2at fdelete.m65sanitize fdelete.m65a2at isalpha.m65sanitize isalpha.m65a2at parselin.m65san}itize parselin.m65a2at strchr.m65sanitize strchr.m65a2at cgets.m65sanitize cgets.m65a2at frename.m65sanitize frename.m6}5a2at isdigit.m65sanitize isdigit.m65a2at read.m65sanitize read.m65a2at tolower.m65sanitize tolower.m65a2at ctype.hsa}nitize ctype.ha2at file.hsanitize file.ha2at stdio.hsanitize stdio.h2at tolower.m65sanitize tolower.m65a2at ctype.hsaI#define NOARGC /* no argument count passing */#define FIXARGC /* don't expect arg counts passed in *//*** atoi(s) - conve}rt s to integer.*/atoi(s) char *s; $( int sign, n; while(isspace(*s)) ++s; sign = 1; switch(*s) $( case }'-': sign = -1; case '+': ++s; $) n = 0; while(isdigit(*s)) n = 10 * n + *s++ - '0'; return (sign * n);$) |#define NOARGC /* no argument count passing */#define FIXARGC /* don't expect arg counts passed in *//*** atoib(s,b) - Co}nvert s to "unsigned" integer in base b.** NOTE: This is a non-standard function.*/atoib(s, b) char *s; int} b; $( int n, digit; n = 0; while(isspace(*s)) ++s; while((digit = (127 & *s++)) >= '0') $( if(digit >= 'a'}) digit -= 87; else if(digit >= 'A') digit -= 55; else digit -= '0'; if(digit >= b}) break; n = b * n + digit; $) return (n);$)t -= 55; else digit -= '0'; if(digit >= b9;; bcopy(p1, p2, nbytes); .globl _bcopy_bcopy: jsr popax ; get nbytes sta tmp1 stx tmp1+1 jsr popax ;} p2 sta ptr2 stx ptr2+1 jsr popax ; p1 sta ptr1 stx ptr1+1bc1: lda tmp1+1 ; nbytes^ beq bc3 ldy} #0 ; set up to move 256bc2: lda (ptr1),y ; get a byte sta (ptr2),y ; store it iny bne bc2 inc ptr1+1 } ; bump ptrs inc ptr2+1 dec tmp1+1 jmp bc1 ; do another blockbc3: ldy #0 ; set up for last section of < 25}6bc4: cpy tmp1 ; done yet? beq bc5 ; yup, exit lda (ptr1),y ; get a byte sta (ptr2),y ; store it iny  } bne bc4bc5: rts ; done!; beq bc5 ; yup, exit lda (ptr1),y ; get a byte sta (ptr2),y ; store it iny #;; bzero(ptr, nbytes); .globl _bzero_bzero: jsr popax ; get nbytes sta tmp1 stx tmp2 jsr popax ; get ! }ptr sta ptr1 stx ptr1+1 lda #0bz1: ldx tmp2 ; get nbytes^ beq bz3 ; zero, try lo ldy #0bz2: sta ! }(ptr1),y ; zap a byte iny bne bz2 inc ptr1+1 ; bump ptr^ dec tmp2 ; dec nbytes^ bne bz1 ; around agai! }nbz3: ldy tmp1 beq bz5 ldy #0bz4: sta (ptr1),y ; zap a byte iny cpy tmp1 ; done? bne bz4bz5: rts!}bz3: ldy tmp1 beq bz5 ldy #0bz4: sta (ptr1),y ; zap a byte iny cpy tmp1 ; done? bne bz4bz5: rts ;; cgetc(iocb); .globl _fgetc_fgetc: .globl _cgetc_cgetc: jsr popax ; get iocb tax lda #0 sta icbll,x%} sta icblh,x sta icbal,x sta icbah,x lda #getchr sta iccom,x jsr ciov bpl getc9 cpy #EOFERR ; EOF?%} beq getceof jmp ioreturn ; go return errorgetc9: ldx #0 ; return hi byte 0 rtsgetceof: lda #$FF tax %}rts; getceof jmp ioreturn ; go return errorgetc9: ldx #0 ; return hi byte 0 rtsgetceof: lda #$FF tax $;; simple version of fgets; cgets(str, size, iocb); char *str;; int size, iocb;; .globl _cgets_cgets: jsr popax )} ; get iocb sta tmp1 ; stash iocb here jsr popax ; get size stx tmp2 ; save x ldx tmp1 ; get iocb )}sta icbll,x ; store size lo lda tmp2 sta icblh,x ; store size hi jsr popax ; get buf addr stx ptr2+1 )} ; save x sta ptr2 ; and a, we'll return it if not eof ldx tmp1 ; get iocb sta icbal,x ; store size lo ld)}a tmp2 sta icbah,x ; store size hi lda #getrec ; get a line sta iccom,x jsr ciov cpy #0 bmi return0)} ldx ptr2+1 ; return the pointer lda ptr2 rtsreturn0: lda #0 ; return NULL tax rtsy #0 bmi return0(h;; close an iocb; .globl _cclose_cclose: .globl _close_close: jsr popax ; get iocb num tax lda #close -}sta iccom,x jsr ciov tya bmi *+5 ldx #0 rts ldx #$FF rtsr popax ; get iocb num tax lda #close ,L;; close all iocbs; .globl _closeall_closeall: ldx #$10 lda #close sta iccom,x jsr ciov txa clc adc 1}#$10 tax cpx #$80 bcc _closeall+2 rtsall: ldx #$10 lda #close sta iccom,x jsr ciov txa clc adc 00 This is the copyright notice for RA65, LINK65, LIBR65, and other Atari8-bit programs. Said programs areCopyright 19895}, by John R. Dunning.All rights reserved, with the follow-ing exceptions: Anyone may copy or redistributethese progra5}ms, provided that:1: You don't charge anything for the copy. It is permissable to charge a nominal fee for media,5 } etc.2: All source code and documentation for the programs is made available as part of the distribution.3: Thi5!}s copyright notice is preserved verbatim, and included in the distribution. You are allowed to modify theseprog5"}rams, and redistribute the mod-ified versions, provided that themodifications are clearly noted. There is NO WARRANTY 5#}with thissoftware, it comes as is, and is dis-tributed in the hope that it may beuseful. This copyright notice is bas5$}ed onthe one published by the Free SoftwareFoundation, sometimes known as the GNUproject. The idea is the same astheirs,5%} ie the software is free, andis intended to stay that way.Everybody has the right to copy,modify, and redistribute this so5&}ft-ware. Nobody has the right to preventanyone else from copying, modifying orredistributing it.and redistribute this so4e;; cputc(ch, iocb); .globl _fputc_fputc: .globl _cputc_cputc: jsr popax ; get iocb sta tmp1 jsr popax 9(} ; get char ldx tmp1 pha lda #0 sta icbll,x sta icblh,x sta icbal,x sta icbah,x lda #putchr sta ic9)}com,x pla jsr ciov bpl putc9 jmp ioreturn ; do common error stuffputc9: tya ldx #0 rts #putchr sta ic8k/* nothing here? */extern int iswhite();ioreturn ; do common error stuffputc9: tya ldx #0 rts #putchr sta ic<,/* delete a file */int delete(name)char * name;$( char buf[80]; fn_default(name, 0, buf); strcat(buf, "\n"); retA,}urn(fdelete(buf));$)t delete(name)char * name;$( char buf[80]; fn_default(name, 0, buf); strcat(buf, "\n"); ret@#define NOARGC /* no argument count passing */#define FIXARGC /* don't expect arg counts passed in */#include /*E.}** dtoi -- convert signed decimal string to integer nbr** returns field length, else ERR on error*/dtoi(decstr, nE/}br)char *decstr;int *nbr;$( int len, s; if((*decstr)=='-') $(s=1; ++decstr;$) else s=0; if((len=utoi(decstr, nbr))<0E0}) return ERR; if(*nbr<0) return ERR; if(s) $(*nbr = -*nbr; return ++len;$) else return len;$)((len=utoi(decstr, nbr))<0Dc#define NOARGC /* no argument count passing */#define FIXARGC /* don't expect arg counts passed in */#include /*I2}** Close fd ** Entry: fd = File descriptor for file to be closed.** Returns NULL for success, otherwise ERR*/fclose(fd)I3}int fd; $(/* if (close(fd) >= 0) return(NULL); else return(ERR); ... we can do better than that... */ retuI4}rn(close(fd) >= 0 ? NULL : ERR);$) return(NULL); else return(ERR); ... we can do better than that... */ retuH%;; delete file.; fdelete(str);;xcb: .byte 0 .globl _fdelete_fdelete: jsr findiocb ; find a free iocb stx xcM6}b ; save it jsr popax ; get the name string ldy xcb sta icbal,y ; store str\ txa sta icbah,y ; storM7}e str^ tya tax ; get iocb in x lda #delete ; get rename opcode sta iccom,x lda #0 sta icax1,x sta M8}icax2,x jsr ciov bpl del0 jmp ioreturn ; common error handling codedel0: tya ldx #0 rts; icax1,x sta Ll#define NOARGC /* no argument count passing */#define FIXARGC /* don't expect arg counts passed in */#include /*Q:}** Gets an entire string (including its newline** terminator) or size-1 characters, whichever comes** first. The input is Q;}terminated by a null character.** Entry: str = Pointer to destination buffer.** size = Size of the destination buffQ<}er.** fd = File descriptor of pertinent file.** Returns str on success, else NULL.*/fgets(str, size, fd)char * Q=} str;int size, fd;$( int ch; char * retval; retval = NULL; /* default */ for ( ; --size > 0 ; ) $( ch = fgeQ>}tc(fd); /* get one */ if (ch == EOF) break; if (!retval) retval = str; *str++ = ch; /* store it */ if (Q?}ch == '\n') break; /* stop at EOL */ $) *str = '\0'; return(retval);$) *str++ = ch; /* store it */ if (PV/* defs for file opening. these are the values passed to CIO in AUX1, when opening */#define O_RDONLY 0x04#define O_UA}WRONLY 0x08#define O_CREAT 0x08#define O_TRUNC 0x08to CIO in AUX1, when opening */#define O_RDONLY 0x04#define O_T8/* handy util for fixing up file names*/fn_default(name, ext, target)char * name;char * ext;char * target;$( chaYC}r buf[80]; /* temp storage *//* this is bummed for space, not speed; it'll copy the data around even when it doesn't YD}have to... */ if (!strchr(name, ':')) $( strcpy(buf, "D:"); strcat(buf, name); strcpy(target, buf);YE} $) else strcpy(target, name); if (ext) if (!strchr(target, '.')) $( strcat(target, ext); $)$)X}#define NOARGC /* no argument count passing */#define FIXARGC /* don't expect arg counts passed in */#include /*]G}** Open file indicated by fn.** Entry: fn = ASCIIZ file name.** May be prefixed by letter of drive.** ]H} mode = "a" - append** "r" - read** "w" - write** "u" - update** (some o]I}f those might not work on atari -- jrd)** Returns a file descriptor on success, else NULL.*/FILE * fopen(fn, mode)char * ]J}fn, * mode;$( int iocb; iocb = copen(fn, *mode); if (iocb < 0) $( errno = iocb; return(0); $) return(iocb]K}); /* just return it as a (FILE * ) */$)n, *mode); if (iocb < 0) $( errno = iocb; return(0); $) return(iocb\./* #define NOARGC /* no argument count passing *//*** Yes, that is correct. Although these functions use an** argument caM}ount, they do not call functions which need one.*/#include /*** fprintf(fd, ctlstring, arg, arg, ...) - FormatteaN}d print.** Operates as described by Kernighan & Ritchie.** b, c, d, o, s, u, and x specifications are supported.** Note: baO} (binary) is a non-standard extension.*/fprintf(argc)int argc; $( int dummy[1]; int * nxtarg;/* nxtarg = CCARGC() +aP} &argc; */ nxtarg = &argc + dummy[1] - 1; return(_pfguts(*nxtarg, --nxtarg));$)/*** printf(ctlstring, arg, arg, ...) aQ}- Formatted print.** Operates as described by Kernighan & Ritchie.** b, c, d, o, s, u, and x specifications are supported.aR}** Note: b (binary) is a non-standard extension.*/printf(args) int args; $( int dummy[1]; /* tprintf("printf: &argsaS}=%x &argc=%x argc=%d\n", &args, &dummy[1], dummy[1]); */ return(_pfguts(stdout, &args + dummy[1] - 1));$)/*** _pfguts(faT}d, ctlstring, arg, arg, ...)** Called by fprintf() and printf().*/_pfguts(fd, nxtarg)int fd;int *nxtarg; $( int arg,aU} left, pad, cc, len, maxchr, width; char *ctl, *sptr, str[17]; cc = 0; ctl = *aV}nxtarg--; while(*ctl) $( if(*ctl!='%') $( fputc(*ctl++, fd); ++cc; continue; $) elseaW} ++ctl; if(*ctl=='%') $( fputc(*ctl++, fd); ++cc; continue; $) if(*ctl=='-') $( left = 1; ++ctl; $) else aX} left = 0; if(*ctl=='0') pad = '0'; else pad = ' '; if(isdigit(*ctl)) $( width = atoi(aY}ctl++); while(isdigit(*ctl)) ++ctl; $) else width = 0; if(*ctl=='.') $( maxchr aZ}= atoi(++ctl); while(isdigit(*ctl)) ++ctl; $) else maxchr = 0; arg = *nxtarg--; sptr = str; swita[}ch(tolower(*ctl++)) $( case 'c': str[0] = arg; str[1] = NULL; break; case 's': sptr = arg; break; a\} case 'd': itoa(arg,str); break; case 'b': itoab(arg,str,2); break; case 'o': itoab(arg,str,8); break; a]} case 'u': itoab(arg,str,10); break; case 'x': itoab(arg,str,16); break; default: return (cc); $) a^}len = strlen(sptr);/* tprintf(" pf: str '%s' len %d wid %d\n", sptr, len, width); */ if(maxchr && maxchrlen) width = width - len; else width = 0; /* tprintf(" pf: str '%s' len %d wid %d iocb %x\n", sptr, len, a`}width, fd); */ if(!left) while(width--) $(/* tprintf(" pf: pad, iocb %x, %d remaining\n", fd, width); */ fputcaa}(pad,fd); ++cc;$) while(len--) $(fputc(*sptr++,fd); ++cc; $) if(left) while(width--) $(/* tprintf(" pf: fin, %d remaab}ining\n", width); */ fputc(pad,fd); ++cc;$) $) return(cc); $)idth--) $(/* tprintf(" pf: fin, %d rema`U#define NOARGC /* no arg count passing */#define FIXARGC /* don't expect arg counts passed in */#include /*** Wed}rite a string to fd. ** Entry: string = Pointer to null-terminated string.** fd = File descriptor of pertinent fee}ile.*/fputs(string,fd) char *string; int fd; $(/* we can do better than this ... while(*string) if(fputc(*string++,fdef})==EOF) return(EOF);*/ write(fd, string, strlen(string)); return(0);$)is ... while(*string) if(fputc(*string++,fddN#define NOARGC /* no arg count passing */#define FIXARGC /* don't expect arg counts passed in *//*** Item-stream read froiq}B%DOS SYSB*)DUP SYSBSASCII BATBeATARI M65BATASCII BATBATOI C BATOIB C BBCOPY M65B BZERO M65BCGETC M65BCGETS M65BCLOSE M65BCLOSEALLM65B COPYLEFTJRDB'CPUTC M65B*CTYPE H B+DELETE C B-DTOI C B1FCLOSE C B5FDELETE M65B9FGETS C B@FILE H BBFNAME C BFFOPEN C BLFPRINTF C BcFPUTS C BgFREAD C BtFRENAME M65ByFWRITE C B~GETCH M65BGETS C BGLOBAL M65BHEAP M65BISALNUM C BISALPHA M65BISASCII C BISATTY C BISCNTRL C BISCONS C BISDIGIT M65BISGRAPH C BISLOWER C BISODIGITM65BISPRINT C BISPUNCT C BISSPACE C BISUPPER C BISWHITE M65BISXDIGITC m fd.** Entry: buf = address of target buffer** sz = size of items in bytes** n = number of items to readir}** fd = file descriptor** Returns a count of the items actually read.** Use feof() and ferror() to determine file is}status.*/fread(buf, sz, n, fd) char * buf; int sz, n, fd; $( return (read(fd, buf, n * sz) / sz);$)o determine file hl;; rename file.; frename(str);; str is already in the form needed by ataridos, ie ; "d:foo.bar,baz.txt";xcb: .byte 0mu} .globl _frename_frename: jsr findiocb ; find a free iocb stx xcb ; save it jsr popax ; get the name strimv}ng ldy xcb sta icbal,y ; store str\ txa sta icbah,y ; store str^ tya tax ; get iocb in x lda #remw}name ; get rename opcode sta iccom,x lda #0 sta icax1,x sta icax2,x jsr ciov bpl ren0 jmp ioreturnremx}n0: tya ldx #0 rts; sta iccom,x lda #0 sta icax1,x sta icax2,x jsr ciov bpl ren0 jmp ioreturnrel#define NOARGC /* no arg count passing */#define FIXARGC /* don't expect arg counts passed in *//*** Item-stream write toqz} fd.** Entry: buf = address of source buffer** sz = size of items in bytes** n = number of items to writeq{}** fd = file descriptor** Returns a count of the items actually written or** zero if an error occurred.** May useq|} ferror(), as always, to detect errors.*/fwrite(buf, sz, n, fd) char * buf; int sz, n, fd; $( if (write(fd, buf, n*sz)q}} <= 0) return (0); return (n);$).*/fwrite(buf, sz, n, fd) char * buf; int sz, n, fd; $( if (write(fd, buf, n*sz)p&;; get a kbd char.; assemble with atari.m65; .globl _kbdchar_kbdchar: jsr k ; call the internal routine ldx #u}0 ; so we can zap X before cmp #0 ; (setting cond codes and) rts ; returningk: lda keybdv+5 pha ldu}a keybdv+4 pha rtsefore cmp #0 ; (setting cond codes and) rts ; returningk: lda keybdv+5 pha ldt#define NOARGC /* no arg count passing */#define FIXARGC /* don't expect arg counts passed in *//*** Gets an entire striny}g from stdin (excluding its newline** terminator) or size-1 characters, whichever comes** first. The input is terminated byy} a null character.** The user buffer must be large enough to hold the data.** Entry: str = Pointer to destination buffer.y}** Returns str on success, else NULL.*/#include gets(str)char *str; $( return (fgets(str, 32767, stdin));$)y}* Returns str on success, else NULL.*/#include gets(str)char *str; $( return (fgets(str, 32767, stdin));$)x;; this file must be assembled into all files that you expect to; use as parts of C programs. it defines common low level }}locations; like the stack ptr etc.;sp = $80 ; stack pointersreg = $82 ; secondary registerargcnt = $82 ; }}same slot; temp for vararg funcstmpptr = $84 ; pointer to random frobfntemp = $86 ; pointer to file namesvax = }} $88 ; slot to save/rest AX intoorigsp = $8A ; original system spptr1 = $8Cptr2 = $8Eptr3 = $90tmp1 = $9}}2tmp2 = $93tmp3 = $94tmp4 = $95; end global.m65ginal system spptr1 = $8Cptr2 = $8Eptr3 = $90tmp1 = $9|;;; heap defs for malloc and pmalloc;;; C variable (char * )_himem. contains pointer to next piece of; mem unallocated.}; .globl __himem__himem: .word __FREEMEM ; defined by linker, top of executable;; C variable (memblock * )_freels}t. contains head of linked list; of blocks of mem that have been freed; .globl __freelst__freelst: .word 0 ; nil} to start with;; that's all for here. see pmalloc.c and malloc.c for code that uses them;__freelst: .word 0 ; nil^#define NOARGC /* no arg count passing */#define FIXARGC /* don't expect arg counts passed in *//*** return 'true' if c i}s alphanumeric*/isalnum(c) int c; $( return ((c<='z' && c>='a') || (c<='Z' && c>='A') || (c<='9' && }c>='0'));$)c*/isalnum(c) int c; $( return ((c<='z' && c>='a') || (c<='Z' && c>='A') || (c<='9' && ;; return t if char is alpha; .globl _isalpha_isalpha: jsr popax ; get the char cmp #'A' bcc nope ; if l}ess than 'A', return 0 cmp #'Z+1 bcc yup cmp #'a bcc nope cmp #'z+1 bcs nopeyup: lda #1 rtsnope: l}da #0 rtsreturn 0 cmp #'Z+1 bcc yup cmp #'a bcc nope cmp #'z+1 bcs nopeyup: lda #1 rtsnope: l#define NOARGC /* no arg count passing */#define FIXARGC /* don't expect arg counts passed in *//*** return 'true' if c i}s an ASCII character (0-127)*/isascii(c) char * c; $( /* c is a simulated unsigned integer */ return (c <= 127);$)i|#define NOARGC /* no arg count passing */#define FIXARGC /* don't expect arg counts passed in */extern int Udevice[];/**}* Return "true" if fd is a device, else "false"*/isatty(fd) int fd; $( return (Udevice[fd]);$)ern int Udevice[];/**f#define NOARGC /* no arg count passing */#define FIXARGC /* don't expect arg counts passed in *//*** return 'true' if c i}s a control character** (0-31 or 127)*/iscntrl(c) char * c; $( /* c is a simulated unsigned integer */ return ((c <=} 31) || (c == 127));$) (0-31 or 127)*/iscntrl(c) char * c; $( /* c is a simulated unsigned integer */ return ((c <=#define NOARGC /* no arg count passing */#define FIXARGC /* don't expect arg counts passed in */#include /*** D}etermine if fd is the console.*/iscons(fd) int fd; $( return(fd == 0); /* kludge. need a way to tell what iocb is o}pen on */$)d is the console.*/iscons(fd) int fd; $( return(fd == 0); /* kludge. need a way to tell what iocb is o ; isdigit(c) -- decimal-p .globl _isdigit_isdigit: jsr popax ; get the char cmp #'0' ; < '0'? bcc ret0 }; less, return 0 cmp #'9'+1 ; >= '8'? bcs ret0 ; yes, return 0 lda #1 ; no, return a 1 rtsret0: txa }rtsss, return 0 cmp #'9'+1 ; >= '8'? bcs ret0 ; yes, return 0 lda #1 ; no, return a 1 rtsret0: txa #define NOARGC /* no arg count passing */#define FIXARGC /* don't expect arg counts passed in *//*** return 'true' if c i}s a graphic character** (33-126)*/isgraph(c) int c; $( return (c>=33 && c<=126);$)d in *//*** return 'true' if c i[#define NOARGC /* no arg count passing */#define FIXARGC /* don't expect arg counts passed in *//*** return 'true' if c i}s lower-case alphabetic*/islower(c) int c; $( return (c<='z' && c>='a');ounts passed in *//*** return 'true' if c iP; isodigit(c) -- octal-p .globl _isodigit_isodigit: jsr popax ; get the char cmp #'0' ; < '0'? bcc ret0 } ; less, return 0 cmp #'8' ; >= '8'? bcs ret0 ; yes, return 0 lda #1 ; no, return a 1 rtsret0: txa r}tsless, return 0 cmp #'8' ; >= '8'? bcs ret0 ; yes, return 0 lda #1 ; no, return a 1 rtsret0: txa r#define NOARGC /* no arg count passing */#define FIXARGC /* don't expect arg counts passed in *//*** return 'true' if c i}s a printable character** (32-126)*/isprint(c) int c; $( return (c>=32 && c<=126);$)in *//*** return 'true' if c i]#define NOARGC /* no arg count passing */#define FIXARGC /* don't expect arg counts passed in *//*** return 'true' if c i}s a punctuation character** (all but control and alphanumeric)*/ispunct(c) int c; $( return (!isalnum(c) && !iscntrl(c}));$)ctuation character** (all but control and alphanumeric)*/ispunct(c) int c; $( return (!isalnum(c) && !iscntrl(c#define NOARGC /* no arg count passing */#define FIXARGC /* don't expect arg counts passed in *//*** return 'true' if c i}s a white-space character*/isspace(c) int c; $( /* first check gives quick exit in most cases */ return(c<=' ' && (c=}=' ' || (c<=13 && c>=9)));$)space(c) int c; $( /* first check gives quick exit in most cases */ return(c<=' ' && (c=#define NOARGC /* no arg count passing */#define FIXARGC /* don't expect arg counts passed in *//*** return 'true' if c i}s upper-case alphabetic*/isupper(c) int c; $( return (c<='Z' && c>='A');$)nts passed in *//*** return 'true' if c iR; iswhite(c) -- whitespace-p .globl _iswhite_iswhite: jsr popax ; get the char and #$7F ; mask hi bit beq }ret0 cmp #$21 ; <= space? bcc ret1 ; less, return 1 cmp #$7F ; >= rubout? bcs ret1 ; yes, return 1re}t0: txa ; no, return a 0 rtsret1: lda #1 rtsn 1 cmp #$7F ; >= rubout? bcs ret1 ; yes, return 1re<#define NOARGC /* no arg count passing */#define FIXARGC /* don't expect arg counts passed in *//*** return 'true' if c i}s a hexadecimal digit** (0-9, A-F, or a-f)*/isxdigit(c) int c; $( return ((c<='f' && c>='a') || (c<='F' && c}>='A') || (c<='9' && c>='0'));$)*/isxdigit(c) int c; $( return ((c<='f' && c>='a') || (c<='F' && c,