@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`  `8  ɐ     `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.D8:MEM.SAV J y08 B|DEHI$} V0 0`B;DEL`?<0LV`@ʆ v s? F0Ξ05: [ BDEHI%} VY8 B V  @  /DE `E:D8: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 ALLOWED 039 FREE SECTORS COPYING---D2:UTILITYS.DOCl# 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- 170ɛ+,' 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 D8uLRS:H` B V`BDEhK)I JLVUVT`H 2` BHIhLV }}~ɛ  ;} 2T} ` RUN"D:MENU*.*"  \`bU}b U*.*"  \`b{ [ +'0@@A0@@[0@@2'!(} W}Π$('(POL(DThis Disk is full of ACTION! files marked with the Extender .O(ZHE(=Note: ACTION! is re X}quired to access these disk files.H(d--(%Also, there are several documentationna^(Vfiles marked with the Exten Y}der that you will want to read and/or print out.a(x,,($So... get out your ACTION! cartridge((( and start t Z}o examine these greatRO(Groutines so that you can begin to use them in your own programming.R(-*("Type to be [}gin using this disk!-(D:MENUso that you can begin to use them in your own programming.R(-*("Type to be & ACTION! 3.5 NOTES/BUGS (rev. 5/24/84: see items 5 & 6)-----------------------------------1. The Monitor Run co]}mmand will NOTrun a compiled program written to afile, only a source program.2. The compiled program has thestarting add^}ress in the DOS Init,not the DOS Run, vector. This meansthat IOCB #1 is still open to theLoad file. It also means that aR_}ETURN to DOS will fail if IOCB #1is used for some other purpose bythe ACTION! program. It DOES,however, make it easy toco`}ncatenate more than one ACTION!program into a single Load file.(Of course, the vector can bechanged to DOS Run.)3. If a a}Monitor write command fails(like with a disk full ERROR 162),the IOCB is NOT immediately closed.If the disk is changed befb}ore theIOCB is next used, the VTOC andDirectory of the new disk will beclobbered!4. Initial values for variables aresetc} only at compile time, and notat PROCedure/FUNCtion invocationtime (like some other languages).5. The integer division opd}erator(/) gives incorrect results for aCARD dividend and/or divisor >=$8000.6. The MOD operator gives incorrectresults e}for a CARD dividend >=$8000, and where the signs of thedividend and divisor are opposite.Note that MOD always returns apof}sitive value, regardless of thesign of the dividend.7. There may be only ONE FUNCtioncall in an expression.8. Constant g}expressions with a CHAR(') constant operand (which areevaluated at compile time) will becomputed MOD $8000 (i.e. giveincoh}rrect results for CARDs >=$8000). [Example: $E000+'X]9. Implied non-zero conditionaltests should not be used in acomplexi} relational expression. [IFA AND B THEN ... FI may giveunexpected results; use IF A#0 ANDB#0 THEN ... FI instead. IF A ANDj}B=3 THEN ... FI won't compile.]10. Shorthand "==" assignment givesincorrect results if the expressioncontains a FUNCtionk} that has anexpression for an operand.[X==+READBLOCK(1,P,R) is ok, butX==+READBLOCK(1,P+X,R-X) won'twork.]11. A PROCedul}re/FUNCtion name isreally a POINTER which may bechanged with an assignmentstatement. (This can be used forbackward referem}nces or dynamicbranching.)12. If "PROC identifier=addr" formis used, no local storage ofparameters will be generated(usn}eful for machine languageroutines). Note that PROCedureidentifier=* is valid.13. CARD or INT record fields maynot be theo} first or second argumentto a PROCedure/FUNCtion. ACTION! 3.5 Notes/Bugs (rev. 5/24/84), page 2 -----p}-----------------14. Hex constants to set the sizeof an ARRAY give incorrect results;use decimal constants instead [i.e.q}BUF(1024) instead of BUF($400)].15. The first global CARD ARRARYencountered by the compiler will belocated at the end ofr} the program(useful for finding the beginningaddress of free RAM above theProgram).16. An undimensioned ARRAY isstored s}out of line so that the namemay be used as a POINTER.17. For a RETURN from a FUNCtion,the first byte is stored at $A0 andt}the second byte (if any) is storedat $A1; registers are not used.18. SET statements to control theorigin of your compileu}d code mustbe at the beginning of yourprogram, not given to the Monitor.19. PrintE and PrintDE libraryPROCedures use thev} OS Put Recordcommand, so an embedded EOL willstop transmission. However, PrintFWILL completely transmit a controlstring,w} embedded EOL's and all.20. PutDE (like PutE) libraryPROCedure outputs only an EOL (andnot a character).21. All Numericx} Input libraryFUNCtions process an entire record(delimited by an EOL) on each call(no multiple numbers per record).22. Fy}or String Input libraryFUNCtions (InputS, InputSD andInputMD), there must be room in thestring for the terminating EOL,evz}en though the resulting stringlength will not include it.23. The filestring argument for theXIO library PROCedure MUST ha{}ve adelimiter after the filespecification. (It often will,especially with an in-line constantor string which has been Inp|}ut, butit's safer to put something like ablank at the end of the filespecification.) This is not neededfor OPEN/CLOSE.2}}4. The library BYTE ARRAY EOF(8)should not be tested for a value of1, only for zero/non-zero. (Don'tuse IF EOF(1)=EOF(2) T~}HEN ... FI;instead use IF EOF(1)#0 ANDEOF(2)#0 THEN ... FI. ReadBlock inthe XA does not give 1 for end offile.)25. Opti}mization Techniques:25.1. Zero page variables [likeBYTE X=$A2]. See note below.25.2. Shorthand (==) assignment,especial}ly with simple expressions[like X==+1 and X==LSH 4].25.3. Successive zero assignments[like X=0 Y=0].25.4. Comparisons t}o zero [like X=0AND Y#0]. ACTION! 3.5 Notes/Bugs (rev. 5/24/84), page 3 ----------------------25.5. B}YTE ARRAY references withconstant expressions [like X(3)]where the ARRAY is 256 bytes orless.25.6. Constant expressions }areevaluated at compile time [like1+2].26. Note: Zero page $A0-$AF is usedfor parameter storage from thebottom up and a}lso for expressiontemporary storage from the topdown. It's usually safe to use afew locations starting with $A0(except wa}tch out for FUNCtionRETURN being stored in $A0-A1) aslong as no FUNCtion/PROCedure callsare made.ting with $A0(except waeAdditions/comments on ANOTE.DOCPlease note that all of thesecomments refer to version 3.5 ofACTION! cartridge. If you d}o notknow which version you have, youcan find out by going to theMonitor and enter: ? $B000it will print a line som}ething likethe following: 45056,$B000 = 5 $1035 53 4149The number following the equal signshould be 5 for version 3.}5 (1 forversion 3.1, 2 for version 3.2,etc.)If you don't have version 3.5, youmight want to contact O.S.S. andarrange t}o get an upgrade. Theyshould be coming out with version3.6 shortly, so you might want towait for that version. The(noti}cable) differences between thetwo versions are (see ANOTE.DOC andcomments below): a) SndRst clears two tone bit ofSKCT}L($D20F, shadow SSKCTL=$232). This bit must be cleared for soundchannels 3 & 4 to work properly. b) Record fields are h}andledproperly for arguments in PROC andFUNC calls. c) SAssign now works properlywhen the source string is zerolength}. d) Paddle function now referencesshadow registers (= works).Now that you know which version youhave. A few commen}ts aboutANOTE.DOC a) In conditional expressions,the operation of AND and OR dependon their context. If the operandsa}re arithmatic (numericexpressions, i.e IF a AND b ...),then the operation is arithmatic(bit-wise). If the operands arelo}gical (relational expressions,i.e IF a#0 AND b#0 ...), then theoperation is logical. The compilerdoesn't allow mixed mode} conditionalexpressions. That is why you getan error for: IF a AND b=0.NOTE: As stated in the manual, thisfeature is n}ot guaranteed to besupported in future versions. Ifyou want arithmatic operations use&, % and %. b) Expressions are t}reated as TRUEin simple relational expressions ifthey are non-zero. Otherwise, theyare treated as FALSE. Thus: IF }a THENis equivalent to: IF a#0 THENThis is intended to make code morereadable. c) x==+1 and x==LSH 4 generate}the same code as x=x+1 and x=x LSH4. The == operator does generate bettercode though for POINTER and ARRAYreferences suc}h as: a(i) ==+ 1 andp^ ==RSH 4.The memory map in the manual isincorrect. $CA is used by thecompiler, so only $CB to $}CD arenever referenced by the compiler.If you are not using a big symboltable (see BIGST.ACT), then $CE and$CF are never }referenced either.Finally, PROC/FUNC declarations withrecord pointers other than the firstargument don't compile correctl}y. If you try to compile: TYPE REC=[ ... ] . . PROC T(BYTE x, REC POINTER p)you'll get an Error 7 (in}validargument list). This bug can behandled by omitting the comma as in: PROC T(BYTE x REC POINTER p) Please note }that this is just atemporary fix and most likely willnot work in future versions (but thecorrect declaration will).Happ}y programming to all you ACTION!owners. If you have any questions,please feel free to ask. - Clinton Parker [70435,62}5] Action Computer Servicesowners. If you have any questions,please feel free to ask. - Clinton Parker [70435,62!A BIT OF THIS AND THAT...------------------------- #: 60714 Sec. 5 - Beyond BASIC...Sb: #60705-#ACTION16-Jul-84 2}2:31:41Fm: RICHARD E. ERNEST 73506,1720To: SYSOP*R.Brudzynski 74035,1550(X)DICK, THE PROGRAM IS ON PAGES130-132 TH}E EXAMPLE NUMBER 4. ISURE HOPE THAT YOUR RIGHT, AND AMGLAD TO KNOW THAT THE MANUAL ISNTALWAYS RIGHT. I KNOW WHAT THEPROB}LEM IS, BUT AM NOT FAR ENOUGHALONG TO CORRECT IT.THANKS, EDDIE ERNEST* Reply: 60763(UA RE T) (D=del}ete): rr #: 60763 Sec. 5 - Beyond BASIC...Sb: #60714-#ACTION 17-Jul-84 02:25:07Fm: Clinton Parker 70435,625To: RI}CHARD E. ERNEST 73506,1720(X)I have never tried that one myself(look, OSS dreamed up all of thoseexamples), but I do kn}ow that atleast: mode=InputB() ; read mode IF mode='A OR mode='a THEN;anything but A or ais wrong and should} read: mode=GetD(7) IF mode='X OR mode='x THEN ;expand listHopes this helps some. Also, whileI'm on it:pg. 6}3 should say that * and / areINT only operators.pg. 123: ex. #1 is wrong, but sorrydon't remember what is wrong offthe t}op of my head. Comma afterlevel in TYPE dcl. shouldn't bethere fer surr. I think there aqreother problems as well.pg. 1}58 should state that PrintEdoesn't handle embedded EOL instrings.pg. 163: PutDE is like PutE and does not take the secon}d argumentcharacter as described, onlychannel.pg. 166: in InputMD, should be at least max+2 in sizesince and a}dditional byte is neededfor the size (first byte) and forthe EOL that CIO puts at the end ofthe string but which is notin}cluded in the size of the stringby ACTION!.I know that there are more typos,but I gave my list of them alongwith my mark}ed up manual to OSS. These are ones I found since thenand I hope that they will becorrect in the next printing.- Clint}* Reply: 60765* RR 60714 + (UA RE T): rr #: 60765 Sec. 5 - BeyondBASIC...Sb: #60763-ACTION 17-Jul-84 02:50:}37Fm: RICHARD E. ERNEST 73506,1720To: Clinton Parker 70435,625CLINT, THANKS FOR POINTING OUT ALLTHOSE ERRORS. I WOUL}D HAVE GONEMADD IF I USED THOSE AND THEY NOTWORK. EDDIE ERNESTTHANKS FOR POINTING OUT ALLTHOSE ERRORS. I WOULM; BIGST.ACT; copyright (c) 1984; by Action Computer Services; All Rights Reserved; This program will create a big}; global symbol table (max 510; entries, normally 255) when run.; It will boot the cartridge as well,; so you must not ha}ve anything in; the Editor that you want. It does; not increase the space used to; store variable names. If you want; t}o increase this as well, you will; have to 'SET $495 = #' in the; monitor after running this program.; # is the number of }pages you want; to be used for name storage (each; page is 256 bytes, default is 8).; You must use the correct version of}; Cold below:; version 3.0 ACTION! ROM;PROC Cold=$A323()[]; version s 3.1 to 3.6 ACTION! ROMsPROC Cold=$A326()[]PRO}C BigSymbolTable() CHAR bigST=$4C4 BYTE EBank=$D503 Zero($480, 255); following statement causes all; variables star}ting with uppercase; letters to go into one half of the; global symbol table and variables; starting with lowercase letter}s to; go into other half (255 entries in; each half). If you use mostly; uppercase variable (this includes; PROC/FUNC na}mes) use 'M. If you; use mostly lowercase variables then; use 'm. bigST = 'a; boot cartridge with big S.T. ; Will n}ot return. EBank = 0 Cold()RETURNse variables then; use 'm. bigST = 'a; boot cartridge with big S.T. ; Will n) Using ST.ACT is very simple. Allyou need to do is:1) boot ACTION! using Boot command in monitor.2) RUN "ST.ACT" f }rom monitor3) make sure you have the printer on before you compile another program.The symbol table listing will b }e sent to the device specified in theOpen routine in SPLEnd in ST.ACT.This is initially the printer putyou can change it }to another deviceif you want to.NOTE that addresses given for TYPEdeclarations are the size of thattype in bytes. The a }ddress fieldfor type fields is the byte offsetwithin that type.YPEdeclarations are the size of thattype in bytes. The a B; BIGST.ACT; copyright (c) 1984; by Action Computer Services; All Rights Reserved; This program will create a big$}; global symbol table (max 510; entries, normally 255) when run.; It will boot the cartridge as well,; so you must not ha$}ve anything in; the Editor that you want. It does; not increase the space used to; store variable names. If you want; t$}o increase this as well, you will; have to 'SET $495 = #' in the; monitor after running this program.; # is the number of $}pages you want; to be used for name storage (each; page is 256 bytes, default is 8).; You must use the correct version of$}; Cold below:; version 3.0 ACTION! ROM;PROC Cold=$A323()[]; version s 3.1 to 3.6 ACTION! ROMsPROC Cold=$A326()[]PRO$}C BigSymbolTable() CHAR bigST=$4C4 BYTE EBank=$D503 Zero($480, 255); following statement causes all; variables star$}ting with uppercase; letters to go into one half of the; global symbol table and variables; starting with lowercase letter$}s to; go into other half (255 entries in; each half). If you use mostly; uppercase variable (this includes; PROC/FUNC na$}mes) use 'M. If you; use mostly lowercase variables then; use 'm. bigST = 'a; boot cartridge with big S.T. ; Will n$}ot return. EBank = 0 Cold()RETURNe with big S.T. ; Will n$c; FIRST.ACT -- a few odd PROCs/FUNCs; LegalDrive - allows determining if the specified drive number is re(}cognized by DOS; MaskInput - uses underlines as input masking for user responses; UnMask - cleans off excess m(}asking that the editor picks up; Find - returns the position in a CHAR ARRAY (string) where the sub-(}string was found, returns 0 if not found - search begins at the position specified by start ; --------(}---------------------------- BYTE FUNC LegalDrive(BYTE drive_num)BYTE drvbyt=$070A, bit, iBYTE ARRAY mask=[1 2 4 8 (}16 32 64 128], drive(8) FOR bit=0 TO 7 DO drive(bit)=(drvbyt&mask(bit)) RSH bit ODRETURN(drive(drive_num-1))PROC(} MaskInput(BYTE width)BYTE i FOR i=1 TO width DO Put('_) OD FOR i=1 TO width DO Put(') ODRETURNPROC (}UnMask(CHAR ARRAY source,destination)BYTE i FOR i=1 TO source(0) DO IF source(i)<>'_ THEN destination(i)=sourc(}e(i) ELSE EXIT FI OD destination(0)=i-1RETURNBYTE FUNC Find(CHAR ARRAY str,sub BYTE start)BYTE i, jCHA(}R ARRAY tmp FOR i=start TO str(0) DO IF sub(1)=str(i) THEN tmp(0)=sub(0) FOR j=1 TO sub(0) DO (} tmp(j)=str(j+i-1) OD IF SCompare(tmp,sub)=0 THEN RETURN(i) FI FI ODRETURN(0) DO (rMODULE ; BLKIO.ACT; Copyright (c) 1983, 1984, 1985; by Action Computer Services (ACS);; This software may be incorporat,}ed in; other software packages providing; that this copyright notice is also; incorporated as well.; version 1.1; last ,}modified May 8, 1985BYTE CIO_statusCHAR FUNC CIO=*(BYTE dev, CARD addr, size, BYTE cmd, aux1, aux2); see hard,}ware manual for description; of CIOV.; IOCB# = dev; ICCOM = cmd; ICBA = addr; ICBL = size; ICAX1 = aux1; ,} ICAX2 = aux2; ICAX1 and ICAX2 are not set if aux1=0; The first byte of addr is passed to; CIO in the A register. The sta,}tus; on return from CIO is stored in; CIO_status. If status=$88 then; EOF(dev) is set to a non-zero value.; No other err,}or checking is performed; and the result of the CIOV call is; returned as the result of this FUNC.[$29$F$85$A0$86$A1$A$A$A,}$A$AA$A5$A5$9D$342$A5$A3$9D$348$A5$A4$9D$349$A5$A6$F0$8$9D$34A$A5$A7$9D$34B$98$9D$345$A5$A1$9D$344$20$E456$8C CIO_status$,}C0$88$D0$6$98$A4$A0$99 EOF$A085$60]CARD FUNC ReadBlock=*(BYTE dev, CARD addr, size); Reads size byte,}s from dev into addr.; Returns number of bytes read (may; be < size if EOF). Set EOF flag if; EOF is encountered. Status,} is ; saved in CIO_status.[$48$A9$7$85$A5$A9$0$85$A6$A5$A3$5$A4$D0$6$85$A0$85$A1$68$60$68$20 CIO$BD$348$85$A0$BD$349$85$,}A1$60]PROC WriteBlock=*(BYTE dev, CARD addr, size); Writes size bytes from addr to dev.; Status is s,}aved in CIO_status.[$48$A9$B$85$A5$A9$0$85$A6$A5$A3$5$A4$D0$2$68$60$68$4C CIO]PROC PutCD=*(BYTE chan, CARD n) BYTE c=$,}AA, lo=$AB, hi=$AC; save args [ $85 c $86 lo $84 hi ]; PutD(c, lo); PutD(c, hi) CIO(c,lo,0,11,0) CIO,}(c,hi,0,11,0)RETURNCARD FUNC GetCD(BYTE chan) CARD out BYTE lo=out, hi=out+1; lo = GetD(chan); hi = GetD(chan) l,}o = CIO(chan,0,0,7,0) hi = CIO(chan,0,0,7,0)RETURN(out)MODULE ; for usert+1; lo = GetD(chan); hi = GetD(chan) l,Q;; AUTO.ACT;; Copyright 1984 by Action Computer Services; All Rights Reserved;; last modified January 11, 19840}DEFINE STRING = "CHAR ARRAY"DEFINE JMP = "$4C" ; JMP addr16TYPE INSTR=[BYTE op CARD addr]INSTR mvec=$4F2BYTE linemax=$40}CFBYTE COLCRS=$55, LMARGIN=$52STRING buf(0)=$9B^; version 3.0 ROM:;PROC CSRet=$A4A6()[];PROC Back=$AA24()[]; version 0}3.1 to 3.6 ROM:PROC CSRet=$A4A9()[]PROC Back=$AA2E()[]PROC InsertCh() ; actual address filled; in Init below.PROC Aut0}o() CHAR c BYTE i, j BYTE indent=$9A, choff=$8D, sp=$8C InsertCh() IF sp>=linemax THEN i = buf(0) IF buf(0}i)=' THEN c = buf(i-1) IF c='. OR c='? OR c=': OR c='! OR c='; THEN i = i - 2 FI FI 0} WHILE buf(i)#' AND i#0 DO i = i - 1 OD IF i>1 THEN FOR j = i TO buf(0)-1 DO buf(j) = buf(j+1)0} OD buf(0) ==- 1 i = i - 1 choff = i+LMARGIN-COLCRS-indent FI CSRet() Back() FIRETURN0}; only code generated before Init is; allocated space. Init will be; garbage collected (well kind of).; Rest of code is 0}safe as long as; cartridge is not booted (cold start).PROC Init() CARD codeBlock, bsize, csize, nBlock CARD POINTER cu0}r, next CARD ARRAY codeBase=$491; find code block entry in free list codeBlock = codeBase^ - 4 next = $80 ; AFbase 0}DO cur = next next = next^ IF next=0 THEN ; can't find block PutE() PrintE("I can't allocate space f0}or your code") PrintE("You better Boot and try again!") RETURN FI UNTIL next=codeBlock OD; setup screen 0} LMARGIN = 0 linemax = 40; link in our routine InsertCh = mvec.addr mvec.op = JMP mvec.addr = Auto; actually rese0}rve space for routines; assume we can split block csize = @codeBlock-codeBlock nBlock = next^ bsize = next(1) - csize0} next = @codeBlock cur^ = next next^ = nBlock next(1) = bsize codeBase^ = @codeBlockRETURNsize = next(1) - csize0f;; FREE.ACT;; Free Memory in Editor;; Copyright 1984 by Action Computer Services; All Rights Reserved;; last mo4}dified March 8, 1984; Adds command [CS]? to editor.; This command will print out how; much memory is left in the editor's4}; command line.DEFINE STRING = "CHAR ARRAY"DEFINE JMP = "$4C" ; JMP addr16TYPE INSTR=[BYTE op CARD addr]INSTR nextCmd,4} mvec=$4F5PROC CToStr=$B10F(CARD n); version 3.0 ROM:;PROC CmdMsg=$A929(STRING msg); version 3.1 ROM:;PROC CmdMsg=$A4}932(STRING msg); version 3.2-3.6 ROM:PROC CmdMsg=$A938(STRING msg)PROC Free() CHAR curCh=$4A2 CARD count STRING n4}umbuf(0)=$550 CARD ARRAY next IF curCh#$E6 THEN ; not [CS]? [JMP nextCmd] FI count = 0 next = $80 ; AFbase 4}DO next = next^ IF next=0 THEN EXIT FI count = count + next(1) OD CToStr(count) CmdMsg(numbuf)RETURN; on4}ly code generated before Init is; allocated space. Init will be; garbage collected (well kind of).PROC Init() CARD cod4}eBlock, bsize, csize, nBlock CARD POINTER cur, next CARD ARRAY codeBase=$491; link in our routine nextCmd.op = mvec.o5}p nextCmd.addr = mvec.addr mvec.op = JMP mvec.addr = Free; allocate our routine so it won't; go away. codeBlock = 5}codeBase^ - 4 next = $80 ; AFbase DO cur = next next = next^ UNTIL next=0 OR next=codeBlock OD IF next=0 THE5}N PutE() PrintE("I can't allocate space for your code") PrintE("You better Boot and try again!") RETURN FI5}; assume we can split block csize = @codeBlock-codeBlock nBlock = next^ bsize = next(1) - csize next = @codeBlock 5} cur^ = next next^ = nBlock next(1) = bsize codeBase^ = @codeBlockRETURNsize = next(1) - csize next = @codeBlock 4Q;;;Another Graphics 10 demo;; By. Rich Gortatowsky;;; 10/23/84;;;;E - Exits back to ACTION!;;(This one t9}urned out better!); (p.s. Kills video DMA);PROC INITCOLOR() BYTE CLR CARD IDX FOR IDX=0 TO 7 DO CLR=(IDX+1)*16+9}8 POKE(705+IDX,CLR) ODRETURNPROC MAIN() BYTE I,C,Q CARD IDX GRAPHICS(10) INITCOLOR() POKE(559,0) FOR I=1 TO 649} DO IF C<8 THEN C==+1 ELSE C=1 FI COLOR=C PLOT(I,I) DRAWTO(I,191-I) DRAWTO(79-I,191-I) DRAWTO(79-I,I) 9 }DRAWTO(I,I) OD POKE(559,34) POKE(764,255) DO Q=PEEK(764) I=PEEK(705) FOR IDX=705 TO 711 DO C=PEEK(IDX+19 }) POKE (IDX,C) OD POKE(712,I) IF Q=42 THEN RETURN FI FOR IDX=1 TO 4000 DO OD OD RETURNPEEK(IDX+18s;;Floating Point Routines for ACTION!;DEFINE REAL="BYTE ARRAY";; Allows declarations like REAL X(6);;; OS Equates fol= }low;BYTE CIX=$00F2BYTE POINTER FR0=$D4,FR1=$E0PROC AFP =$D800 () ;OS Ascii--> Fltpt routinePROC FASC=$D8E6 ();OS Fltpt-= }-> ASCII routinePROC FPI =$D9D2 ();OS Fltpt--> IntegerPROC IFP =$D9AA ();OS Integer-->FltptPROC FADD=$DA66 ();OS Fltpt ADD=}PROC FSUB=$DA60 ()PROC FMUL=$DADB ()PROC FDIV=$DB28 ()PROC FLOG=$DECD ()PROC FLOG10=$DED1()PROC FEXP=$DDC0 ();OS e**XP=}ROC FEXP10=$DDCC();OS 10**X;; Routines to INPUT Real Numbers;PROC InputR(REAL NUM)InputS($580) POKEC($F3,$581)CIX=}=0 AFP() MoveBlock(NUM,FR0,6) RETURNPROC InputRD(BYTE channel, REAL NUM)BYTE defaultdefault=devicedevice=cha=}nnelInputR(NUM)device=defaultRETURN;; Routines to PRINT Real Numbers;PROC PrintR(REAL NUM)BYTE POINTER INBUFFMove=}Block(FR0,NUM,6)FASC()INBUFF=PEEKC($00F3)WHILE INBUFF^<128 DO Put(INBUFF^) INBUFF==+1 ODPut(INBUFF^&127)RETURNPROC Pr=}intRE(REAL NUM)PrintR(NUM)PutE()RETURNPROC PrintRD(BYTE channel, REAL NUM)BYTE defaultdefault=devicedevice=channelPr=}intR(NUM)device=defaultRETURNPROC PrintRDE(BYTE channel, REAL NUM)BYTE defaultdefault=devicedevice=channelPrintRE(NUM=})device=defaultRETURN;; Routine used to make OS calls;PROC RealOPS(BYTE Operator,REAL Destination,N1,N2)MoveBlock(F=}R0,N1,6)MoveBlock(FR1,N2,6)IF Operator=1 THEN FADD() ELSEIF Operator=2 THEN FSUB() ELSEIF Operator=3 THEN FMUL() ELSE=}IF Operator=4 THEN FDIV() ELSEIF Operator=5 THEN FLOG() ELSEIF Operator=6 THEN FLOG10() ELSEIF Operator=7 THEN=} FEXP() ELSEIF Operator=8 THEN FEXP10()FIMoveBlock(Destination,FR0,6)RETURN;; Routines called by user to do; F=}loating Point operations;; PROC RealADD(REAL Destination,N1,N2)RealOPS(1,Destination,N1,N2)RETURNPROC RealSUB(REAL De=}stination,N1,N2)RealOPS(2,Destination,N1,N2)RETURNPROC RealMUL(REAL Destination,N1,N2)RealOPS(3,Destination,N1,N2)RETUR=}NPROC RealDIV(REAL Destination,N1,N2)RealOPS(4,Destination,N1,N2)RETURNPROC LOG(REAL Destination,NUM)RealOPS(5,Destina=}tion,NUM)RETURNPROC LOG10(REAL Destination,NUM)RealOPS(6,Destination,NUM)RETURNPROC EXP(REAL Destination,NUM)RealOPS(=}7,Destination,NUM)RETURNPROC EXP10(REAL Destination,NUM)RealOPS(8,Destination,NUM)RETURN;; Routine to do Real-to-Inte=}ger Conversion;; =ROUND();CARD FUNC ROUND(REAL NUM)MoveBlock(FR0,NUM,6)FPI()RETURN (FR0^)=};; Routine to do Integer-to-Real Conversion;PROC Float(CARD Integer, REAL Result)CARD POINTER PP=FR0P^=IntegerIFP()= }MoveBlock(Result,FR0,6)RETURNPROC Float(CARD Integer, REAL Result)CARD POINTER PP=FR0P^=IntegerIFP()<1 FLOATING POINT ROUTINES for ACTION!(tm) -----------------------The purpose of these routines is toaA"}dd an elementary floating pointcapability to the ACTION! languageby providing ACTION! syntax formaking calls to the floatiA#}ng pointROM on the Atari OS board.These routines should be INCLUDEDin any program needing access tofloating point arithmA$}etic. PROC'sare provided for the Input andOutput of floating point numbers,for conversion between floatingpoint and integA%}er (CARD)representations, and for thearithmetic operations provided inthe Atari OS ROM.The REAL data type:REAL numbersA&} are stored in BYTEARRAYs of length 6. The word REALhas been DEFINEd to mean "BYTEARRAY". This means floating pointvariabA'}les can be declared using thefollowing syntax: REAL X(6) REAL Y(6),Z(6) ; PROC procname(REAL parameter) ; etc.A(}Input:Two PROC's are provided. Theirusage is similar to the libraryPROC "InputS" used for characterstrings. PROC InpA)}utR() and PROC InputRD(BYTE channel,) Example: REAL X(6) InputR(X)Output:Four PROC's arA*}e provided. Theirusage is similar to the libraryPROC's used for output of strings. PROC PrintR() and A+} PROC PrintRE() and PROC PrintRD(BYTE channel,) and PROC PrintRDE(BYTE channel,A,}) Example: REAL X(6) PrintR(X)Conversion:One PROC and one FUNC are provided.PROC FLOAT(,) uses A-}theOS IFP routine. On return, the parameter will be set to thefloating point representation ofthe CARD parameter.A.}CARD FUNC ROUND() uses the OSFPI routine. The function returnsthe CARD representation of theROUNDED (not truncated) A/}floatingpoint parameter.Example: CARD X REAL Y(6) FLOAT(X,Y) X=ROUND(Y)Arithmetic:Eight PRA0}OC's are provided. Allrequire a REAL Destination toreceive the result, plus at leastone other REAL parameter. PROC RealAA1}DD(,,) PROC RealSUB(,,) PROC RealMUL(,,) PROC RealDIV(,,A2}) PROC LOG(,) PROC LOG10(,) PROC EXP(,) PROC EXP10(,)Examples: CAA3}RD I,J REAL X,Y,Z ;Compute 355/113=3.14159 I=355 J=113 FLOAT(I,X) ;X=355.0A4} FLOAT(J,Y) ;Y=113.0 RealDIV(Z,X,Y) ;Z=X/Y PrintR(Z) ;will print 3.14159292 A5} ; ; Input 2 numbers, print sum ; InputR(X) InputR(Y) A6}RealADD(X,X,Y) ;X is destination as well as addend PrintR(X) ;will print A7} sum X+Y ---------- destination as well as addend PrintR(X) ;will print @ ; LOaDPT 9/84-1/17/85, A. B. Langdon; Read executable file to see where ; its segments load and its entry point(s).SET $E9}491=$4000 SET 14=$491^PROC go=*()[$6C $2E2] MODULE; try Long's fix instead of BYTE rts=[$60];INCLUDE "D:SYSLIB.ACT";INCLUDE:}E "D:SYSIO.ACT"; Close using channel 1 caused "system error" with DOS 2.1 but not DOS XL.; ACS bbs has a block read (BLKIOE;}.ACT) in machine code segments that is; smaller and has a general purpose call to CIO. Here, I'll leave mine; as it illustrE<}ates use of the language and is just as fast.; First global CARD ARRAY will be placed AFTER rest of program.CARD ARRAY bufE=}fer(1) ; locate the buffer.CARD FLen, ; File length up to 64K i, CSum0, CSum1BYTE OpOKBYTE CIO_status ; global foE>}r CIO return value (per ACS convention)CARD FUNC GetAD(BYTE chan CARD addr, len) ; Block read TYPE IOCB=[BYTE hid,dno,comE?},sta CARD badr,put,blen BYTE aux1,aux2,aux3,aux4,aux5,aux6] IOCB POINTER ic BYTE chan16 BYTE@}E POINTER b chan16 = (chan&$07) LSH 4 ic = $340+chan16 ic.com = 7 ; read ic.blen = len ic.badr = addr [$AE chan16EA} $20 $E456 $8C CIO_status] ; LDX chan, JSR CIO; STY CIO_status IF CIO_status = $88 THEN EOF(chan)=1 FI FLen ==+ ic.blen EB}; this to RETURN is special to this application. b = addr FOR i = 1 TO ic.blen DO ; note CSum1 is affected by trailing EC}zeroes (OS/A v.4). CSum0 ==+ b^ CSum1 ==+ CSum0 b ==+ 1 ODRETURN (ic.blen)CARD FUNC GetCD(BYTE chan) ; Read ED}a word CARD c GetAD(chan,@c,2)RETURN (c)PROC FixFlSp(BYTE ARRAY FileSpec) IF FileSpec(2)<>': AND FileSpec(3)<>': THEEE}N ; prefix "D:" to file name FileSpec^==+2 i=FileSpec^ WHILE i>2 DO FileSpec(i)=FileSpec(i-2) i==-1 EF} OD FileSpec(1)='D FileSpec(2)=': FI; Could also convert to upper case: if >$60 then subtract $20.RETURNPROC SysEG}Err(BYTE errno)PROC MyError(BYTE errno) IF errno=$80 THEN Error=SysErr Error(errno) FI PrintF("error %I. Try again%E",eEH}rrno) OpOK=0RETURNPROC End=*() [$68$AA$68$CD$2E8$90$5$CD$2E6$90$F3 $48$8A$48$60]; entry: PLA; TAX; PLA; CMP MEMLO+1; BCEI}C lab; CMP MEMTOP+1; BCC entry;; lab: PHA; TXA; PHA; RTS; Trace back thru RTS's and return to cartridge or DOS.; From ACS EJ}bulletin board.PROC LoadPt() CHAR ARRAY FileSpec(20) BYTE b CARD fwa, lwa, BufLen, MEMTOP=$2E5, MEMLO=$2EK}E7 BufLen=MEMTOP-$80-buffer SysErr=Error DO Print("File Spec=") InputS(FileSpec) IF FileSpec^=0 THEN END() EL}FI FixFlSp(FileSpec) Close(2) OpOK=1 Error=MyError Open(2,FileSpec,4,0) UNTIL OpOK OD Error=SysErr FLen=0 CEM}Sum0=0 CSum1=0 i=GetCD(2) IF i<>$FFFF THEN ; is it a LOAD file? PrintF("Bad load file header=%H%E",i) Close(2)EN} RETURN FI DO; Code block DO fwa=GetCD(2) IF fwa=0 OR EOF(2)<>0 THEN ; may get 0 before EOF in DOEO}S 4. PrintF("End of file. %H bytes%E",FLen) PrintF(" checksum=%H%H%E",CSum0,CSum1) Close(2) REP}ETURN FI UNTIL fwa<>$FFFF OD; Skip embedded $FFFF lwa=GetCD(2) IF (fwa=$2E2 OR fwa=$2E0) AND lwa=fwa+1 THENEQ} IF fwa=$2E0 THEN Print("INIT") FI IF fwa=$2E2 THEN Print("RUN") FI i=GetCD(2) PrintF(" at %H%E",i) ER} fwa==+2 ELSE PrintF("fwa, lwa %H %H%E",fwa,lwa) IF fwa=fwa DO ; just pass over these bytes i=lwa-fwa+1 IF i>100ET}0 THEN i=1000 FI i=GetAD(2,buffer,i) fwa==+i OD OD Close(2)RETURNPROC Main() device=0 ; in case MEU}AC/65 has been here DO LoadPt() PrintE(" (RETURN to end)") ODRETURNRETURNPROC Main() device=0 ; in case MDR; This fragment loads an Action!; program and executes it; (thru INITAD). This fragment can be; easily modified to supIW}port any type; of binary load file by checking the; status of INITAD and RUNAD after; each block of code has been loadeIX}d.; If you want this fragment to remain; resident, you must compile to a; specific location (outside your own; programIY}, obviously) using either the; SET $E/SET $491 method or using; SET $B5 to set a compilation offset; (Note: due to a buIZ}g in the Action!; compiler offset routine, you can; only specify a positive offset); Once the program is compiled, type:I[}; ?Load; from the monitor to obtain the; runtime address. In your own source; that calls Load, you must insert tI\}he; following line before its use:; PROC Load=$xxxx(CHAR ARRAY str); where "$xxxx" is the address you; found abovI]}e, and where the CHAR; ARRAY "str" is the complete filespec; of the program you want to load.MODULE ;LOAD.ACTBYTE I^}CIO_statusCARD start, len; NOTE: CIO and ReadBlock are; copyrighted routines of; Action! computer services; CreI_}dit such as this of their origin; must be given if used in your own; program sourceCHAR FUNC CIO=*(BYTE dev, CARD addr,sI`}ize, BYTE cmd,aux1,aux2) [$29$F$85$A0$86$A1$A$A$A$A$AA$A5$A5$9D$342$A5$A3$9D$348$A5$A4$9D$349$A5$A6$F0$8$9D$34A$A5$A7$9D$34BIa}$98$9D$345 $A5$A1$9D$344$20$E456$8C CIO_status$C0$88$D0$6$98$A4$A0$99 EOF$60]CARD FUNC ReadBlock=*(BYTE dev, CARD addr, siIb}ze) [$48$A9$7$85$A5$A9$0$85$A6$A5$A3$5$A4$D0$6$85$A0$85$A1$68$60$68$20 CIO$BD$348$85$A0$BD$349$85$A1$60]; MAINLINE ******Ic}**********************CARD FUNC GetOne()BYTE cLowCARD cHigh DO cLow=GetD(1) cHigh=GetD(1) cHigh== LSH 8 % Id}cLow UNTIL cHigh#$FFFF ODRETURN(cHigh)PROC GetAddrs=*() start=GetOne() len=GetOne()-start+1RETURNPROC Load(CHARIe} ARRAY filespec)CARD INITAD=$2E2 Close(1) Open(1,filespec,4,0) WHILE start#$2E2 DO GetAddrs() ReadBlock(1,If}start,len) OD Close(1) [$6C INITAD] DO GetAddrs() ReadBlock(1,HZMODULE ; INITBAD6.ACT ; written by Ed Seward III; last modified 17 July 1984;;---------------------------------------Mq}b%DOS SYSb*)DUP SYSbSAUTORUN SYSbVMENU b*\ANOTE1 DOCbANOTE2 DOCbACTMANALDOCb ST ACTbST DOCb BIGST ACTb FIRST ACTbBLKIO58 ACTbAUTO ACTbFREE ACTbESCAPE ACTb REALS ACTb!REALS DOCb8LODPT ACTbVLOAD ACTbgSIODISK ACTb SORT ACTb(SORT DOCbASSEM ACTbAASSEM DOCb CATCH ACTbEND ACTbRUBINGENDOCb,8RUBINGENACTb)dRELGEN2 ACTb RELOC2 ACTbGRTONE ACT----------; This module is to provide access to specific; sectors through the Resident Diskette Handler.;---------------Mr}----------------------------------;; The values of the SIO status byte ($0303); are provided here for those that may wanMs}t to add; some error handling.;; 1 -NO ERRORS; $8A -device doesn't respond; $8B -device nak; $8C -serMt}ial bus framing error; $8E -serial bus overrun error; $8F -serial bus checksum error; $90 -device done error;Mu}; The above list of values of DSTATS is from ; The Atari Technical Reference Notes.;--------------------------------------Mv}----------- ; SIO Diskette Handler Command Bytes BYTE ddevice = $0300, ; serial bus ID -DO NOT ALTER duniMw}t = $0301, ; device (drive) number dcomnd = $0302, ; command byte dstats = $0303 ; status byteMx} CARD dbuffr = $0304 ; buffer address LO-HI format BYTE dtimlo = $0306 ; DO NOT ALTER, disk tMy}ime out CARD dbytes = $0308, ; byte count daux = $030A ; sector number BYTE ARRAY bufferMz}(128) PROC Dskinv=$E453 () ; diskette handler vector;; JSR to resident diskette handler;after setting up theM{} Device Control Block;RETURN PROC GetSector (CHAR drive, CARD sectnum);procedure reads a specified sector and M|} |;places it in the array pointed to by dbuffr |;which should be buffer in this program M}} |;-------------------------------------------------------| IF ((0=25 THEN Error(CTERR,0,CTERR)b} FI [ LDYA index PLA STAY c_t_hi PLA STAY c_t_lo TSX TXA STAY c_t_sp LDAY c_t_lo b} PHA LDAY c_t_hi PHA ]RETURNPROC Throw(BYTE index) DEFINE TXS="$9A", PHA="$48", LDYA="$AC", STX="$8b}6", TSX="$BA", TAX="$AA", LDAY="$B9" BYTE sp=$A2; get current stack pointer [ TSX : STX sp ] IF ib}ndex>=25 OR sp+2>c_t_sp(index) THEN Error(CTERR,0,CTERR) FI [ LDYA index LDAY c_t_sp TAX TXS LDb}AY c_t_lo PHA LDAY c_t_hi PHA ]RETURNMODULE ; just in caseA index LDAY c_t_sp TAX TXS LD`MPROC End=*()[$68$AA$68$CD$2E8$90$5$CD$2E6$90$F3$48$8A$48$60]just in caseA index LDAY c_t_sp TAX TXS LDd?Instructions for: RELGEN.ACT:== Relocation Generator& REOCAT.ACT:== Run-time Relocator These programs were intended tj}ocreate a self-relocating objectfile from either an ACTION!compiled program or an Assembledprogram. The original object fj}ilemust be a single-stage boot withonly one origin except for thetrailing run or init address. Thefollowing instructions j }detail thesteps to make the target objectfile. This file may be appended toother binary load files and mayhave other binaj!}ry files appended toit. The program will load at thenext possible page boundary(increment of 256) after MEMLO.Because RELj"}GEN compares twoversions of you object file, youmay want to init all variables tozero to keep the relocation tableat a mij#}nimum. Stray data in theuninitialized variables may beinterpreted as machine code thatneeds relocating.1) Compile (or Asj$}semble) your code at a convenient area but not conflicting with DOS. In ACTION!, use the following commands to force j%}the program's origin to a specified value ($3000 for example): SET 14=$3000 SET $491=$30002) Re-Compile your codej&} at $100 higher than the first. For the above example, this would be at $3100.3) From the ACTION! monitor, RUN theprj'}ogram RELGEN.ACT. It will promptyou for the filenames for the twoobject code files that you compiledabove. Remember to givj(}e the Dn:prefix to the filenames. The programwill compare the two object filesand note their differences as offsetsinto tj)}he file. This information issaved in ACTION! form in a file withthe original name and a ".GEN"extention. This will be usedj*} in thenext step. Also, the program createsan object file image of the originalbut with an origin of zero. This isdone toj+} make the relocation processeasier and this file, with a ".REL"extention will be used in step 5. Note: RELGEN.ACT requirj,}es four openDOS files simultaneously. By default,DOS usually has buffers for only 3.You must use the command: SET $709=j-}4in the ACTION! monitor and type D forDOS. Rewrite DOS to the disk andreboot. Now, DOS will allow the fourfiles to be opj.}ened.4) Now, Read the program RELOC.ACTinto the ACTION! Editor. This is a"generic" run-time relocator. Thefile generatedj/} with the RELGEN.ACTprogram (with the ".GEN" extention)must be merged into this programwith the editor Read function.Posij0}tion the cursor where instructedand read in the file. Compile thiscode but be sure that it is SET tocompile above the expej1}cted end ofYOUR program's target location.Save this object code to disk andgo to DOS.5) Using the DOS Copy command,appej2}nd the ".REL" file generated inRELGEN.ACT, to the merged relocatorfile saved in step 4. For example:CCopy from,to:TEST.j3}REL,AUTORUN.SYS/AThis assumes that you saved the filein Step 4 as AUTORUN.SYS.6) Finally, the appended file can beloadej4}d from DOS or named AUTORUN.SYSas above for permanent applications.If you have question, send E-Mail to: John DeMar 7106j5}6,337 on Compuserveor leave a message on the ACE-BASEBBS at (315)451-7747. Good Luck!#0oeex`C!3I3 ACTION RUNTIME BINj6}ARY FILE RELOCATORSee RELGEN.DOC for intructions. NeedsRELGEN.ACT to generate files fromyour compiled program.j7} 71066,337LOCATORSee RELGEN.DOC for intructions. NeedsRELGEN.ACT to generate files fromyour compiled program.h MODULE ;RELGEN.ACT;COPYRIGHT 1984, QMI, JS DeMar;REV. 1.1, March 20, 1984;OBJECT CODE RELOCATION GENERATOR for;ACTION! n9}compiled binary-load files.;WARNING!!! This program requires;four OPEN files simultaneously.;Be sure that DOS is configurn:}ed for;this. With DOS 2.0, set $709 equal;to at least 4, rewrite DOS and;reboot.;Requires the second file compiled;at an;}ny even page increment higher;than the first file, for example:;$3000 and $3100.;Generates a table of the locations;thatn<} require relocating and saves;it in a ".GEN" file in ACTION!.; The ".REL" file is the original;object code with an originn=} of "0". ;The actual relocator is compiled;from the generic relocator source;called "RELOC.ACT" merged with the;".GEN" fin>}le generated here. Append;".REL" file to that code and it;will load and relocate to MEMLO.DEFINE in1="1", in2="2",n?} out1="3", out2="4"BYTE abrt;---------------------------------PROC MyError(BYTE a,x,y)IF y=170 THEN Pn@}rintE("ERROR File not found!")ELSE Print("ERROR! ") PrintBE(y)FIabrt=1RETURN;---------------------------------PROCnA} Ferror()BYTE t,clock=$14PrintE("ERROR in Output filespec!")t=clock-$80DOUNTIL t=clockODRETURN;--------------------nB}-------------PROC Main()CARD start1,start2,end1,end2CARD offsets,offsete,i,count,hitsCARD test1,test2,old1,old2,old3,olnC}d0BYTE x,z,j,wnum,d1,d2, sthighBYTE ARRAY fname1(18),fname2(18), fnameout1(18),fnameout2(18)DOPrintE("}nD} Relocation Code Generator ")PrintE(" JS DeMar 3/84 ")PutE()PrintE(" Requires two code files compiled")PrnE}intE(" with an offset of $0100.")PutE()Print("Filespec for code A >") InputMD(device,fname1,18)PutE()Print("FilespnF}ec for code B >") InputMD(device,fname2,18)PutE()Scopy(fnameout1,fname1)SCopy(fnameout2,fnameout1)j=1IF fnameout1(1)#'nG}D OR fnameout1(0)<4 THEN Ferror()ELSEIF fnameout1(2)=': THEN z=0ELSEIF fnameout1(3)=': THEN z=1FIDO x=fnanH}meout1(j) j==+1 IF x=$20 THEN EXIT ELSEIF x='. THEN EXIT ELSEIF j>fnameout1(0) THEN j==+1 EXIT ELSEnI}IF j>11+z THEN Ferror() FIODfnameout1(j-1)='.fnameout1(j)='Gfnameout1(j+1)='Efnameout1(j+2)='Nfnameout1(0)=j+2nJ}j=1IF fnameout2(1)#'D OR fnameout2(0)<4 THEN Ferror()ELSEIF fnameout2(2)=': THEN z=0 EXITELSEIF fnameout2(3)=nK}': THEN z=1 EXITFIODDO x=fnameout2(j) j==+1 IF x=$20 THEN EXIT ELSEIF x='. THEN EXIT ELSEIF j>fnamenL}out2(0) THEN j==+1 EXIT ELSEIF j>11+z THEN Ferror() EXIT FIODfnameout2(j-1)='.fnameout2(j)='RfnameounM}t2(j+1)='Efnameout2(j+2)='Lfnameout2(0)=j+2Print("Generation file = ")PrintE(fnameout1)Print("Relocation file = ")PrinnN}tE(fnameout2)Error=MyErrorabrt=0Close(in1)Close(in2)Close(out1)Close(out2)Open(in1,fname1,4)Open(in2,fname2,4)IF abnO}rt=1 THEN Close(1) Close(2) RETURNFIOpen(out1,fnameout1,8)Open(out2,fnameout2,8)x=GetD(in1) ;throw away two $FF'snP}.x=GetD(in1)PutD(out2,$FF)PutD(out2,$FF)x=GetD(in1)PutD(out2,x)start1=x ;start addr of file1.x=GetD(in1)PutD(out2,nQ}x)start1==+(x*256)x=GetD(in1)PutD(out2,x)end1=xx=GetD(in1)PutD(out2,x)end1==+(x*256) ;end addr of file1.x=GetD(in2) nR};throw away two $FF's.x=GetD(in2)x=GetD(in2)start2=x ;start addr of file2.x=GetD(in2)start2==+(x*256)x=GetD(in2)endnS}2=xx=GetD(in2)end2==+(x*256) ;end addr of file2.offsets=start2-start1sthigh=start1/256offsete=end2-end1PrintDE(out1,nT}"MODULE")PrintD(out1,";For file ")PrintDE(out1,fnameout2)PrintDE(out1,"")Print("Code starts at ")PrintD(out1,"CARD startnU}=[")PrintCE(start1)PrintCD(out1,start1)PrintDE(out1,"]")Print(" and ends at ")PrintD(out1,"CARD finish=[")PrintCE(endnV}1)PrintCD(out1,end1)PrintDE(out1,"]")Print("Compile offset was ")PrintCE(offsets)IF offsete#offsets THEN PrintE("DifenW}rrent size files!") PrintE("ABORTED!")ELSE PrintDE(out1,"") PrintD(out1,"CARD ARRAY otable=[") wnum=0 hits=0 counX}nt=0 WHILE EOF(in1)=0 DO d1=GetD(in1) d2=GetD(in2) IF d1#d2 THEN IF count<(end1-start1)-5 THEN nY} hits==+1 IF wnum=0 THEN PrintD(out1," ") Print(" ") ElSE PrintD(out1," ") nZ} Print(" ") FI PrintCD(out1,count) Print(" ") PrintC(count) wnum==+1 In[}F wnum>4 THEN PrintDE(out1,"") PrintE("") wnum=0 FI FI old0=d1 test1=n\}old0*256 test1==+old1 test2=old2*256 test2==+old3 IF test1>=start1 AND test1<=end1 THEN IF ten]}st2=$02E3 OR test2=$02E1 THEN PrintDE(out1,"]") PrintE("]") PrintD(out1,"CARD hits=[") n^} PrintCD(out1,hits) PrintDE(out1,"]") PrintDE(out1,"") Print("CARD hits=[") PrintC(hn_}its) PrintE("]") PrintE("") PrintD(out1,"CARD runaddr=[") Print("CARD runaddr=[") n`} test1==-start1 PrintCD(out1,test1) PrintC(test1) PrintDE(out1,"]") PrintE("]")na} wnum=0 FI FI old3=old2 old2=old1 old1=d1 d1==-sthigh ELSE old3=olnb}d2 old2=old1 old1=d1 FI PutD(out2,d1) count==+1 ODFIPrintE("")PrintDE(out1,"")Close(in1)Close(nc}in2)Close(out1)Close(out2)PrintE("Finished!}")RETURN count==+1 ODFIPrintE("")PrintDE(out1,"")Close(in1)Close(l9MODULE ;RELGEN.ACT;COPYRIGHT 1984, QMI, JS DeMar;REV. 1.1, March 20, 1984;OBJECT CODE RELOCATION GENERATOR for;ACTION! re}compiled binary-load files.;WARNING!!! This program requires;four OPEN files simultaneously.;Be sure that DOS is configurrf}ed for;this. With DOS 2.0, set $709 equal;to at least 4, rewrite DOS and;reboot.;Requires the second file compiled;at arg}ny even page increment higher;than the first file, for example:;$3000 and $3100.;Generates a table of the locations;thatrh} require relocating and saves;it in a ".GEN" file in ACTION!.; The ".REL" file is the original;object code with an originri} of "0". ;The actual relocator is compiled;from the generic relocator source;called "RELOC.ACT" merged with the;".GEN" firj}le generated here. Append;".REL" file to that code and it;will load and relocate to MEMLO.DEFINE in1="1", in2="2",rk} out1="3", out2="4"BYTE abrt;---------------------------------PROC MyError(BYTE a,x,y)IF y=170 THEN Prl}rintE("ERROR File not found!")ELSE Print("ERROR! ") PrintBE(y)FIabrt=1RETURN;---------------------------------PROCrm} Ferror()BYTE t,clock=$14PrintE("ERROR in Output filespec!")t=clock-$80DOUNTIL t=clockODRETURN;--------------------rn}-------------PROC EndIt()Close(in1)Close(in2)Close(out1)Close(out2)RETURN;---------------------------------PROC Maro}in()CARD start1,start2,end1,end2CARD offsets,offsete,i,count,hitsCARD test1,test2,old1,old2,old3,old0BYTE x,z,j,wnum,d1,rp}d2, sthighBYTE ARRAY fname1(18),fname2(18), fnameout1(18),fnameout2(18)DOPrintE("} rq}ɠ")PrintE(" Ӡ򬠸")PutE()PrintE(" Requires two code files compiled")PrintE(" with anrr} offset of $0100.")PutE()Print("Filespec for code A >") InputMD(device,fname1,18)PutE()Print("Filespec for code B >") rs}InputMD(device,fname2,18)PutE()Scopy(fnameout1,fname1)SCopy(fnameout2,fnameout1)j=1IF fnameout1(1)#'D OR fnameourt}t1(0)<4 THEN Ferror()ELSEIF fnameout1(2)=': THEN z=0ELSEIF fnameout1(3)=': THEN z=1FIDO x=fnameout1(j) j==+1 ru} IF x=$20 THEN EXIT ELSEIF x='. THEN EXIT ELSEIF j>fnameout1(0) THEN j==+1 EXIT ELSEIF j>11+z THEN rv}Ferror() FIODfnameout1(j-1)='.fnameout1(j)='Gfnameout1(j+1)='Efnameout1(j+2)='Nfnameout1(0)=j+2j=1IF fnameout2(1)rw}#'D OR fnameout2(0)<4 THEN Ferror()ELSEIF fnameout2(2)=': THEN z=0 EXITELSEIF fnameout2(3)=': THEN z=1 EXIrx}TFIODDO x=fnameout2(j) j==+1 IF x=$20 THEN EXIT ELSEIF x='. THEN EXIT ELSEIF j>fnameout2(0) THEN j=ry}=+1 EXIT ELSEIF j>11+z THEN Ferror() EXIT FIODfnameout2(j-1)='.fnameout2(j)='Rfnameout2(j+1)='Efnameoutrz}2(j+2)='Lfnameout2(0)=j+2Print("Generation file = ")PrintE(fnameout1)Print("Relocation file = ")PrintE(fnameout2)Error{}r=MyErrorabrt=0Close(in1)Close(in2)Close(out1)Close(out2)Open(in1,fname1,4)Open(in2,fname2,4)IF abrt=1 THEN Close(r|}1) Close(2) RETURNFIOpen(out1,fnameout1,8)Open(out2,fnameout2,8)x=GetD(in1) ;throw away two $FF's.x=GetD(in1)PutD(r}}out2,$FF)PutD(out2,$FF)x=GetD(in1)PutD(out2,x)start1=x ;start addr of file1.x=GetD(in1)PutD(out2,x)start1==+(x*256)r~}x=GetD(in1)PutD(out2,x)end1=xx=GetD(in1)PutD(out2,x)end1==+(x*256) ;end addr of file1.x=GetD(in2) ;throw away two $FFr}'s.x=GetD(in2)x=GetD(in2)start2=x ;start addr of file2.x=GetD(in2)start2==+(x*256)x=GetD(in2)end2=xx=GetD(in2)endr}2==+(x*256) ;end addr of file2.offsets=start2-start1sthigh=start1/256offsete=end2-end1PrintDE(out1,"MODULE")PrintD(our}t1,";For file ")PrintDE(out1,fnameout2)PrintDE(out1,"")Print("Code starts at ")PrintD(out1,"CARD start=[")PrintCE(start1r})PrintCD(out1,start1)PrintDE(out1,"]")Print(" and ends at ")PrintD(out1,"CARD finish=[")PrintCE(end1)PrintCD(out1,endr}1)PrintDE(out1,"]")Print("Compile offset was ")PrintCE(offsets)IF offsete#offsets THEN PrintE("Diferrent size files!")r} PrintE("ABORTED!") EndIt() RETURNFIPrintDE(out1,"")PrintD(out1,"CARD ARRAY otable=[")wnum=0hits=0count=0FOR i=sr}tart1 TO end1DO d1=GetD(in1) d2=GetD(in2) IF d1#d2 THEN hits==+1 IF wnum=0 THEN PrintD(out1," ") r}Print(" ") ElSE PrintD(out1," ") Print(" ") FI PrintCD(out1,count) Print(" ") PrintC(count)r} wnum==+1 IF wnum>4 THEN PrintDE(out1,"") PrintE("") wnum=0 FI d1==-sthigh FI PutD(out2,r}d1) count==+1ODFOR i=0 TO 2 DO d1=GetD(in1) d2=GetD(in1)ODtest1=d1test1==+(d2*256)IF test1>=start1 AND test1<=enr}d1 THEN PrintDE(out1,"]") PrintE("]") PrintD(out1,"CARD hits=[") PrintCD(out1,hits) PrintDE(out1,"]") PrintDE(outr}1,"") Print("CARD hits=[") PrintC(hits) PrintE("]") PrintE("") PrintD(out1,"CARD runaddr=[") Print("CARD runaddr=r}[") test1==-start1 PrintCD(out1,test1) PrintC(test1) PrintDE(out1,"]") PrintE("]")ELSE PrintE("No Run Address! -r} ABORTED!")FIPrintE("")PrintDE(out1,"")EndIt()PrintE("Finished!")RETURN PrintE("]")ELSE PrintE("No Run Address! -pPMODULE ;RELOCATE.ACT;Run-time Relocator Code.;For use with RELGEN.ACT;COPYRIGHT 1984, JS DeMar;Rev. 2.0, August 17,1984v};---------------------------------SET 14=$6000SET $0491=$6000;---------------------------------;The beginning of the relv}ocator;table and code should be higher;than the end of the original;compiled program. But, there must;be enough space lefv}t for the table;and the relocator code itself!;---------------------------------;---------------------------------;Reav}d the ".GEN" file above here.;---------------------------------;Compile this after reading in the;".GEN" file above. Then v}append this;code to the ".REL" file using the;DOS C (COPY) command with /A after;the filenames:; PROGRAM.OBJ,PROGRAM.REL/v}A;Then rename the ".REL" file to;AUTORUN.SYS to run at boot-time.;---------------------------------PROC Relocate()BYTEv} offset,memlohi=$02E8,x,yCARD memlo=$02E7,i,j,top,entryCARD POINTER pBYTE ARRAY newplace[$8E y $4E y $4E y $4E y $4E y]v}newplace=memlonewplace==&$FF00offset=memlohii=memlo&$00FFIF i#0 THEN newplace==+$0100 offset==+1FIj=0FOR i=startv} TO finishDO p=i x=p^ newplace(j)=x j==+1ODFOR i=0 TO hits-1DO entry=otable(i) newplace(entry)==+offsetODv}runaddr==+newplace[$6C runaddr]ace(j)=x j==+1ODFOR i=0 TO hits-1DO entry=otable(i) newplace(entry)==+offsetODt"; Copyright (c) 1985 Harold Long; Permission granted to distribute; for non-commercial purposes.INCLUDE "D:READPIC.ACT" ;z} Available on Action! BBS.MODULE ; - GR15 Pseudo-halftone; screen print routine. Supports; 800XL and Epson printerz} only. See; program comments for adaptation to; other hardware environments.; Screen to print translation:; Each pixel z}on the screen occupies; two bits in memory. This is trans-; lated into a 6x2 matrix to keep; the h x w aspect ratios similz}ar.; The default is for color 1 to be; the least dark, and color 4 to be; the most dark. A translator table; is provided z}to allow hackers; the ability to redefine halftone; values to their heart's content.BYTE J,K,L ;countersCARz}D M, SAVMSC=$58 ;counters, reg'sBYTE ARRAY dots(960) ;pin valuesBYTE POINTER dotptr, scrnptr; Turns on a line of gz}raphics output.; Epson printer supports 960 bits in; "L" (Low speed double density) mode.; z}; 䮠PROC GrOn() ;turn on graphicsPrint("L") ;double densityPut(19z}2) Put(3) ;920 bits/lineRETURN; Convert a pixel to a halftone value.PROC DoPix(BYTE p) ;process a pixel; Halz}ftone value table:; Values are selected to approximate; 0%, 25%, 50%, and 100% density for; color registers 1 through 4. Nz}ote; that lookup alternates between table; tone1 and tone2 to give maximum; pattern flexibility.BYTE ARRAY tone1(4)=[$00 z}$00 $40 $C0]BYTE ARRAY tone2(4)=[$00 $40 $80 $C0]FOR J=0 TO 5 ;6 bytes wideDO IF (J MOD 2)=0 THEN ;odd valuez}s dotptr^=tone1(p) ;assumes dotptr is dotptr==+1 ;properly set up ELSE ;even values dotz}ptr^=tone2(p) ;base halftone dotptr==+1 FIODRETURNPROC DoByte(BYTE b) ;process a screen byteBYTE p z} ;the pixel valueFOR K=0 TO 6 STEP 2 ;do it 4 timesDO p=(b RSH (6-K)) & $03 ;mask it to get reg # DoPix(p) z} ;go convert pixel to halftoneODRETURNPROC DoLine(BYTE r) ;process a screen lineZero(dots,960) ;clear arz}raydotptr=dots ;initialize pointerscrnptr=SAVMSC+40*r ;row pointerFOR L=0 TO 39 ;40 bytes to a linez}DO DoByte(scrnptr^) ;the next screen byte scrnptr==+1 ;bump pointerODGrOn() ;flame on!doz}tptr=dots ;reset pointerFOR M=0 TO 959 ;full double density lineDO Put(dotptr^) dotptr==+1ODPutE()Rz}ETURN; Initialization and control loop.; Open printer, get input file name; and read it in (Micro Illustrator; format onz}ly). PROC Main()BYTE i BYTE ARRAY fname(18)Close(2)Open(2,"P:",8,0)Close(1)Print("Input file: ")InputS(fnamz}e)PutE()Open(1,fname,4,0)Graphics(15+16) ; ;z}ReadPic()Close(1)device=2; Print("3") ;Set printer toPut(6) z} ;6/216 inch (2 dots)FOR i=0 TO 191 ;192 screen rowsDO DoLine(i)ODdevice=0Close(2)RETURNPut(6) z} ;6/216 inch (2 dots)FOR i=0 TO 191 ;192 screen rowsDO ; Copyright (c) 1985 Harold Long; Permission granz}ted to distribute; for non-commercial purposes.INCLUDE "D:READPIC.ACT" ; Available on Action! BBS.MODULE ;ission granxr