@L}5 _$% l0$)$$Hȱ$ UhL" `e$$%`$%`  R@W!( L(1   Y I`  d  Ld M * @  $ % CC$$)%1 Udߥ$9%: !0 S$% DD˙`  }J)Lr  ; BIGST.ACT ; copyright (c) 1984 ; by Action Computer Services ; All Rights Reserved ; This program will creat}e a big ; global symbol table (max 510 ; entries, normally 255) when run. ; It will boot the cartridge as well, ; so you }must not have anything in ; the Editor that you want. It does ; not increase the space used to ; store variable names. I}f you want ; to 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! RO }Ms PROC Cold=$A326()[] PROC BigSymbolTable() CHAR bigST=$4C4 BYTE EBank=$D503 Zero($480, 255) ; following } statement causes all ; variables starting with uppercase ; letters to go into one half of the ; global symbol table and v }ariables ; starting with lowercase letters to ; go into other half (255 entries in ; each half). If you use mostly ; upp }ercase variable (this includes ; PROC/FUNC names) use 'M. If you ; use mostly lowercase variables then ; use 'm. big}ST = 'a ; boot cartridge with big S.T. ; Will not return. EBank = 0 Cold() RETURN MlNLO R"(+d ACTION! BUG SHEET #3 - part 1 This document supercedes the previous two bug sheets published for ACTION! November 6, 1}984 ------------------------------------- GENERAL INFORMATION Before getting to the bad stuff (the bugs), here ar}e some goodies about ACTION! which we would like to pass on to you: TIPS ON TEMPS A magazine article titled "Lights, Camera}, Action!" (by Dave Plotkin) which appeared in the July 1984 issue of ANTIC featured a set of routines to facilitate writing }ACTION!-based interrupt handlers. The article gave the listings for two routines (more properly, two DEFINEs) named "SaveTem}ps" and "GetTemps". These routines are adequate only if no math beyond addition and subtraction is performed in the interrupt} service routine. The following versions of these two routines will work properly in the more general case: Make the follow}ing DEFINEs in your program before you declare your interrupt routine (comments may be omitted-- they exist only for clari- f}ication):DEFINE SaveTemps= "[ $A2 $07 ; LDX #7 $B5 $C0 ; LOOP LDA $C0,X $48 ; } PHA $B5 $A0 ; LDA $A0,X $48 ; PHA $B5 $80 ; LDA $80,X $48 ; } PHA $B5 $A8 ; LDA $A8,X $48 ; PHA $CA ; DEX $10 $F1 ; } BPL LOOP $A5 $D3 ; LDA $D3 $48 ; PHA ]" DEFINE GetTemps= "[ $68 ; }PLA $85 $D3 ; STA $D3 $A2 $00 ; LDX #0 $68 ; LOOP PLA $95 $A8 ; ST}A $A8,X $68 ; PLA $95 $80 ; STA $80,X $68 ; PLA $95 $A0 ; } STA $A0,X $68 ; PLA $95 $C0 ; STA $C0,X $E8 ; INX $E0 $08 ; } CPX #8 $D0 $EF ; BNE LOOP ]" Use these routines inside your interrupt routine as follows: ; Your inter}rupt routine. PROC InterruptRoutine() ; Local declarations, if any. BYTE a, b, c, etc. ; First line of code within  }; procedure SaveTemps ... ; Your interrupt ; code goes here. GetTemps ; Last line of code !} ; within procedure. [$6C OldVBI] ; A special way to ; end for VBIs- see ; "}below. For example, the following program will set up the routine ChangeColor as a vertical blank interrupt routine (hit the#} START key to exit theprogram): DEFINE SaveTemps= "[ $A2 $07 $B5 $C0 $48 $B5 $A0 $48 $B5 $80 $48 $B5 $A8 $48 $C$}A $10 $F1 $A5 $D3 $48 ]" DEFINE GetTemps= "[ $68 $85 $D3 $A2 $00 $68 $95 $A8 $68 $95 $80 $68 $95 $A0 $68 $9%}5 $C0 $E8 $E0 $08 $D0 $EF ]" CARD OldVBI ; Will hold previous ; contents of vertical ;&} blank interrupt ; vector. ; This procedure will change the ; background color to random values. ; The main '}routine will set up this ; code to operate during the ; deferred vertical blank interrupt. PROC ChangeColor() BYTE hue, l(}um SaveTemps hue = Rand( 16 ) lum = Rand( 16 ) SetColor(2,hue,lum) GetTemps [ $6C OldVBI ] ; Vertical b)}lank ; interrupts must end ; like this ($6C is a ; 6502 indirect jump *} ; instruction). PROC Test() ; Main routine BYTE critic=$42, ; Critical I/O flag console=$D01F ; Console +}key ; hardware location CARD VBIvec=$224 ; Deferred vertical ; blank interrupt vector ; You must inst,}all a VBI ; routine like this: critic = 1 OldVBI = VBIvec VBIvec = ChangeColor critic = 0 ; ChangeCol-}or is now running ; as the vertical blank interrupt ; routine-- since our mainline ; code has nothing more to do,.} ; we just go into a loop waiting ; for the START key to be ; pressed. WHILE console&1 DO OD /} ; Now turn off the VBI routine. critic = 1 VBIvec = OldVBI critic = 0 RETURN This method of saving and restorin0}g ACTION zero page variables may also be used to write BASIC machine language subroutines in ACTION! Your main ACTION routin1}e should then have SaveTemps as the first executable line, and GetTemps as the last executable line before the RETURN stateme2}nt. :## # # .#Ƚ# # 𩛙## 1,#PD#ELJ- <.BJD#E  ACTION! BUG SHEET #3 - part 2 ------------------------------------- BUGS IN THE ACTION! CARTRIDGES The following is 4}a list of all bugs we currently know exist in the ACTION! cartridge. We list these bugs separately from those in the RunTime5} library and/or the PAD disk or ToolKit, which occur in following pages. Each bug is described in detail and, when possible,6} bug fixes are given. Many of these bugs deal only with specific versions of ACTION!. To find out which version of ACTION! 7}you own, type the following from the ACTION! monitor: ?$B000 [RETURN] Below is an actual copy of what printed following t8}hat command for one of our cartridges. 45055,$B000 = 0 $0730 48 1840 ^ To find out the version number, look9} at the character to the right of the equals sign (here printed with a caret under it). The "0" in this case implies that th:}e cartridge is version 3.0. If yours has a "6", you own version 3.6, etc. As of the date of this bug sheet, the current car;}tridge version is 3.6. 1. OFFSETS -- Using a TYPE declaration will generate a spurious error whenever the code <}offset (contents of location $B5) is non-zero. Affects: All versions of the cartridge to date. (Presumably =} only noticed if using RunTime disk, though.) Fix: Make all TYPE declarations before changing the code offset. >} Example: ; Beginning of program -- ; First, declare TYPEs TYPE IOCB = [ BYTE ?}Id, Devnum, Command, Status ] ; Then, if desired, ; change offset SET $B5 = @}$1000 ; example: offset=4096 2. OFFSETS -- Using a code offset greater than $7FFF (i.e., a negative offset,A} if you consider it to be of type INT) causes the compiler to generate improper code. Affects: All versionsB}, especially when used with the RunTime disk. Fix: No direct fix, but you may use the relocator program C} described later in this document (which is also usable with assembly language). 3. ATARI DOS -- Exiting to Atari DD}OS from ACTION! can cause a system crash if DUP.SYS is not present on the disk in drive 1. Affects: All verE}sions, but only when used with Atari DOS. Fix: Use DOS XL (or be careful when exiting to DOS). 4. ARRAYS AND F}ELSEIF -- We have just learned that there is a relatively obscure bug in ACTION! related to the use of ELSEIF. IG}n particular, statements similar to the form ELSEIF a(i) = 0 THEN ... (where a is an ARRAY and i is a CH}ARD OR INT), or statements like ELSEIF p^ = 0 THEN (where p is a POINTER) produce incorrect code. AffectI}s: All versions Fix: There is no direct fix at this time. The best way around the problem seems to be to codeJ} something like this: t = a(i) ; t is an INTEGER ... ELSEIF t=0 THEN ... This works properly. 5K}. WRITING OBJECT FILES -- If a monitor Write command fails because of a disk error (e.g., disk full, 162, or devL}ice done, 144), the IOCB is not properly closed. If the disk is changed before another disk operation is perM}formed, the new disk can have invalid data written to it. Affects: All versions Fix: If you get an error whenN} writing an ACTION! object file, type the following command to the monitor: X Close( 1 ) [RETURN] You cO}an then erase the file which caused the error. 6. HEX ARRAY SIZES -- Hexadecimal values as array dimensions cause P} incorrect code to be generated. Affects: All versions Fix: Use decimal array dimensions. 7. TYPE POINTERQ} ARGUMENTS -- PROC/FUNC declarations with record pointer arguments other than the first don't compile correctR}ly. For example, the following code generates an error 7 (invalid argument list): TYPE REC=[...] ... S} PROC Test( BYTE x, REC POINTER p ) Affects: All versions Fix: Omit the comma in the argument list fT}or the PROC/FUNC, as in: PROC Test( BYTE x REC POINTER p ) As this is just a temporary fix, U}it may not work in future versions, but the correct declaration (with the comma) will. 8. MONITOR LOCKUP -- TypV}ing the following command from the monitor will lock up the system: R* [RETURN] Affects: All versions W} Fix: Don't do it! If you do type that command, hit [RESET] 9. PADDLE FUNCTION -- The Paddle function does not wX}ork properly in all versions of the ACTION! cartridge. Affects: Versions 3.0 to 3.5 Fix: Make the followiY}ng declaration in your program: BYTE ARRAY Paddle(4) = 624 10. SOUND ON CHANNELS 3 AND 4 -- If you use a SoundZ}() procedure call after having done any disk I/O, sound channels 3 and 4 will remain silent. This is because [} Atari's OS does not reset some of the serial control registers completely. Affects: Versions 3.0 to 3.5 F\}ix: Type in and use the following procedure. You should call this before doing any Sound() calls and/or in plac]}e of any SndRst() calls: ; Contributed by Michael Ross PROC SoundOff() BYTE AudCtl = $D208, ^} SSKCtl = $232, SKCtl = $D20F SSKCtl = 3 SKCtl = 3 AudC_}tl = 0 SndRst() RETURN 11. TYPE FIELDS AS PARAMETERS -- Using fields of TYPEs as parameters to P`}ROCs or FUNCs generates incorrect code. For example, MoveBlock( rec.addr1, rec.addr2, length ) Affecta}s: Versions 3.0 to 3.5 Fix: Assign the TYPE field to a temporary variable and pass that as a parameter: b}temp1 = rec.addr1 temp2 = rec.addr2 MoveBlock(temp1,temp2,length) 12. SASSIGN PROBLEMS -- SAssign does not wc}ork properly when the source string has a length of zero. Affects: Versions 3.0 to 3.5 Fix: No fix available d}at this time. 13. CARD FIELDS IN TYPES -- Accessing CARD fields of TYPEs generates incorrect code. Affects:e} Versions 3.0 to 3.2 Fix: No fix available at this time. 14. MOVEBLOCK PROBLEMS -- MoveBlock does not move mof}re than 256 bytes of data. Affects: Versions 3.0 to 3.2 Fix: No fix at this time. You could write an ACTg}ION! routine to do the equivalent. 15. CONTROL-SHIFT RETURN -- Using [CS] RETURN to split a line into two lines h}generates garbage in the second line. Affects: Versions 3.0 and 3.1 Fix: No fix available, but not a disai}strous problem. 16. DIVISION ERRORS -- On old cartridges, neither the "/" operator nor the "MOD" operator works j}properly under certain conditions. Affects: Versions 3.0 and 3.1 Fix: Insert the following code into yourk} program before any of your own PROCedure or FUNCtion declarations (this can be done easily using INCLUDE): l}; Copyright (c) 1983 by ; Action Computer Services ; ; Permission is granted to ; duplicate and/or distributem} ; the contents of this file ; to ACTION! users. Copies of ; this file may not be sold or ; used for monetarn}y gain. PROC DivI=*() [$20 $A06C $85 $86 $A2 $10 $26 $82 $26 $83 $26 $86 $26 $87 $38 $A5 $86 $E5 $84 $A8 o} $A5 $87 $E5 $85 $90 $04 $85 $87 $84 $86 $CA $D0 $E5 $A5 $82 $2A $26 $83 $A6 $83 $4C $A032] PROC RemI=p}*() [$20 DivI $86A5 $87A6 $60] SET $4EA=DivI SET $4EC=RemI 17. ERROR ROUTINE NOT INITIALIZED -- The addressq} of the Error PROCedure is not restored by ACTION! if a user program has changed it. Affects: Versions 3.0 r}and 3.1 Fix: Make sure to restore the original Error vector upon exiting a program, if you changed it. 18.s} COMPLEX EXPRESSIONS IN UNTIL -- Complex relational expressions in an UNTIL statement generate incorrect code. Ft}or example, DO ... UNTIL a>0 AND b=3 OD Affects: Versions 3.0 and 3.1 Fix: Assign theu} expression to a temporary variable and test that variable, instead: DO ... temp = a>0 AND b=3 v} UNTIL temp OD 19. BANK SWITCH BUG -- When loading and running compiled ACTION! object files from DOS, w}the system can crash when using older cartridges. This is because the ACTION! library is not accessible. x} Affects: Version 3.0 only Fix: Put the following program lines at the VERY BEGINNING of your main procedure y}(i.e., the last procedure in your program): BYTE bank = $D500 ; This declares the variable ; 'baz}nk' to reside at $D500. bank = 0 ; This must be the ; first executable statement. 20. .COM PROGRAMS -- Runn{}ing compiled ACTION! programs as .COM files under OS/A+ causes those programs to execute twice. Affects: Al|}l versions, but only when using a version of OS/A+. DOS XL is not affected. Fix: Insert the following as the }} first global variable you declare: BYTE RTS=[$60] ; This MUST be the first ; line in your prog~}ram, ; aside from comments and ; SET commands. 21. PROC ADDRESSING -- Under certain conditions, specifyi}ng the address of a procedure (e.g., to interface to a machine code routine) causes ACTION! to generate incor}rect code which could cause your program to "hang". Affects: Versions 3.1 and 3.4 Fix: Insert an empty co}de block after the declaration of a procedure whose address is specified. For example: PROC CIO = $E456}() [] ; An empty code block! 22. ERROR #3 -- If you get an ERROR 3 during a compile, the system hangs when y}ou return to the editor. Affects: All versions Fix: Do not go to the editor until you type the following }line to the monitor. This command resets the ACTION! memory pointer. SET $E=$491^ 23. STRING INPUT -- }When using the string input library functions (InputS, InputSD, and InputMD), there must be room in the string } for the termination EOL, even though the resulting string length will not include it. Affects: All versions } Fix: Adjust your declaration appropriately. 8ͥΥ, +͑ϐ 86 ACTION! BUG SHEET #3 - part 3 ------------------------------------- BUGS IN THE ACTION! RUNTIME LIBRARY We have found }a few bugs in the original version(s) of the RunTime Library Disk. Fortunately, they are all easy to fix. (The RunTime libr }ary is independent of the cartridge, so bugs affect all versions.) In the fixes given below, the portion to be changed (to i }mplement the fix) is underlined. The rest of the line remains the same. To make the fixes, simply load the library file con }taining the affected PROCedure, edit, and save it back to disk. 1. Hex numbers are printed incorrectly by PrintH and th }e %H parameter of PrintF. Fix: Change second line of CCIO: PROC CCIO=*() [$A386$A0A$A0A$AA$A3A5$9D$342 ... } --- --- 2. PrintBDE can cause a spurious compile time error. Fix: Change first line of Prin }tBDE: PROC PrintBDE =*(BYTE d,n)[$A0$0] -- 3. A minor error exists in ChkErr. Fix: Chan }ge second line of ChkErr: PROC ChkErr=*(BYTE r,b,eC) [$1610$88C0$8F0 $98$80C0$12F0 ... } --- 4. If your program redefines a library procedure (e.g., one which declares its own version of PROC }Graphics), it will compile with no errors using the cartridge only (because declared procedures take precedence o }ver built-in ones). However, since th LLҠŠҢﬠà嬠 / ACTION! BUG SHEET #3 - part 4 ------------------------------------- PROBLEMS WITH PAD We will list the probl}ems (and solutions) regarding the Programmer's Aid Disk here in reasonably compact form. 1. BGET/BPUT PROBLEMS -- The BGet } and BPut routines in the IO.ACT file do not work properly under certain conditions. To fix this bug, replace} the BGet and BPut routines with the following ACTION! code: ;******************************** ;Burst (Block}) I/O routines to do ;quick disk I/O, utilizing a call ; to CIO ;******************************** PROC CIO=$}E456( BYTE areg, xreg ) ;******************************** CARD FUNC Burst( BYTE chan, mode, CARD ad}dr, buflen ) TYPE IOCB=[BYTE id,num,cmd,stat CARD badr,padr,blen BYTE a1,a2,a3, } a4,a5,a6] IOCB POINTER iptr chan ==& $07 iptr = $340+(chan LSH 4) iptr.cmd = mod}e iptr.blen = buflen iptr.badr = addr CIO( 0, chan LSH 4 ) RETURN( iptr.blen ) ;******************}************** CARD FUNC BGet( BYTE chan, CARD addr, len ) CARD temp temp = Burst(chan,}7,addr,len) RETURN( temp ) ;******************************** PROC BPut(BYTE chan, CARD addr,len) } Burst( chan, 11, addr, len ) RETURN 2. PRINTF -- The PRINTF routine has a bug which was reported and fixe}d in the Spring, 1984 newsletter. In the file PRINTF.ACT, use the ACTION! editor to find args ==+ s a}nd change it to args ==+ 2 3. PLAYER/MISSILE GRAPHICS -- Because S: uses some memory just below the display }list (undocumented), our method of finding the base address for Player/Missile Graphics needs a slight revisi}on. Use the ACTION! editor with the file PMG.ACT to find PM_BaseAdr=(HiMem- PM_MemSize(mode)) } &PM_AdrMask(mode) and change it to PM_BaseAdr=(HiMem- PM_MemSize(mode)-$80) &PM_Adr}Mask(mode) 4. If you use the PMMove procedure and specify a vertical movement of zero, the horizontal movement }does not take place (it should). To fix this, change the lines in PMG.ACT which read IF deltay=0 THEN } RETURN ; do nothing FI to the following: IF deltay=0 THEN ; do horizontal anyway PMHpos(}n)=x RETURN FI 5. PLAYER/MISSILE GRAPHICS -- The documentation for PMG.ACT states that you may read} the contents of PMHpos to find the horizontal position of a player or missile. This is simply not true. PMHpos } is a set of write-only hardware registers. (Note that in the ToolKit we have added a shadow array and change}d the name of the hardware registers, so this works correctly. If you wish, you could consider doing something } similar on your PAD.) 6. REAL NUMBER ROUTINES -- There are two discrepancies in PROCedure names in the REAL.ACT }library as compared to the REAL.DOC documentation, as follow: Name in .DOC Name in .ACT StrR } RealToStr ValR StrToReal We suggest that you change the source code in REAL.ACT to refl}ect the names given in the documentation (rather than vice versa), since this makes the names appear compatibile }with the library's other number-string conversion routines. 7. REAL NUMBER ROUTINES -- In that same area, the r}outine RealToStr (or should that be StrR?) needs to change the line which reads ptr=LBuff to the following}: ptr=InBuff 8. ALLOC.ACT -- The free list pointer may not be set up properly. Also, when freeing a blo}ck, right adjacency is not handled properly if left adjacency has already been found. Fix these problems as follo}ws: In the PROCedure Free, after the line reading: last.size==+nBytes insert the line: target=last} Also, in the same procedure, change the line reading: IF target+nBytes=current THEN to read: IF tar}get+target.size =current THEN In the PROCedure AllocInit, replace the line reading: FreeList.next=}p with the following lines: FreeList=p p==+4 FreeList.next=p ------------------------------------- } TOOLKIT TROUBLES It's hard to believe that a product as new as the ACTION! ToolKit can already have bug reports. Si}gh. Anyway, there are already three versions of the ToolKit. Version 1 has 31 free sectors (when you list its directory). V}ersion 2 has fewer free sectors and the second line of the file MUSIC.DEM reads ";Version 2". On version 3, the file ABS.ACT} starts with the version number. This last convention will be followed in future versions. The comments here are organized }by affected version(s). VERSION 1 ONLY 1. I/O ROUTINES -- The manual describes a routine called Format (in the IO.}ACT library), but no such procedure exists on the disk. However, the routine is there--it's just called Init } instead. You should change your disk to match your manual. 2. MUSIC.DEM -- The program called MUSIC.DEM will not }work as is on older 400/800 machines. This is because it uses a call to Graphics(15), which is only availabl}e on XL machines. You may change the program to use Graphics(8) with no effect except that the true colors of mo}de 15 become artifact colors in mode 8 instead. VERSIONS 1 AND 2 1. REAL ROUTINES -- There are two discrepanci}es in PROCedure names in the REAL.ACT library as compared to the REAL.DOC documentation, as follow: Name i}n .DOC Name in .ACT StrR RealToStr ValR StrToReal We suggest that you change} the source code in REAL.ACT to reflect the names given in the documentation (rather than vice versa), since }this makes the names appear compatibile with the library's other number-string conversion routines. 2. SORT ROU}TINES -- There are four discrepancies in PROCecure names in the SORT.ACT library as compared to the SORT.ACT }documentation, as follows: Name in .DOC Name in .ACT SortB BSort SortC CSo}rt SortI ISort SortS SSort Please change your disk file to agree with your m}anual. 3. PRINTF -- The PRINTF routine has a bug which was reported and fixed in the Sprint, 1984 newsletter. }In the file PRINTF.ACT, use the ACTION! editor to find args ==+ s and change it to args ==+ 2 VERS}IONS 1, 2, AND 3. 1. ALLOC ROUTINES -- The manual in- dicates that the procedure AllocInit requires that you pass } it the address of the first free byte of memory (because Alloc "dispenses" memory from the first free byte thr}ough the top of memory, as correctly described in the manual). However, since you MUST follow the procedure }described in the introduction to ALLOCATE.ACT (that is, you must declare in your program a CARD called EndProg an}d use the command SET EndProg=* after compiling), the parameter to AllocInit is not really needed and }so has been eliminated. (AllocInit uses EndProg just as Alloc does.) If you pass a parameter to AllocInit, it wi}ll be ignored. 2. WARP.DEM -- No mention is made in the Toolkit manual that this file can only be run when comp}iled from disk (unless you are using DOS XL to gain extra memory). WARP.DEM is just too big for ACTION! to ho}ld both the source and object in memory at one time. 3. ALLOCATE.ACT -- The free list pointer may not be set up } properly. Also, when freeing a block, right adjacency is not handled properly if left adjacency has already bee}n found. Fix these problems as follows: In the PROCedure Free, after the line reading: last.size==+nBytes } insert the line: target=last Also, in the same procedure, change the line reading: IF target+nBytes=}current THEN to read: IF target+target.size =current THEN In the PROCedure AllocInit, replace }the line reading: p=EndProg with the following lines: FreeList=EndProg p=EndProg+4 堠j ACTION! BUG SHEET #3 - part 5 ------------------------------------- ACTION MANUAL ERRATA First of all, you nee}d to know which version of the manual you have. If Part III is the Language, then you have the first version of the manual. }Otherwise, you have the second (newest) version. Unfortunately, both manuals contain content as well as typographical errors}. We'll skip the typos and concentrate on the content errors, since typos don't impair your understanding of the language (a}lthough you may wonder where we learned to spell). VERSION 1 ERRATA: PAGE ERROR 2 In the last paragraph, it says } that the library is on the disk. This is not true. It's in your cartridge. 23 Under the description }of , the comparison with the Atari screen editor is exactly reversed. If you are in REPL}ACE mode, this key works as in the Atari editor. 26 Under T, it says you may not use lower-ca}se characters as tags. This is untrue. 48 In the NOTE preceeding 4.3, you should add "The *, /, an}d MOD operators result in an implied INT type. For this reason, multiplication, division, and mo}dulus of large CARD numbers does not always work properly." 49 Section 4.4 says that you may only h}ave one special operator in a complex relational expression. This is untrue. For example, the following} is perfectly legal: (x=7 AND y#10) OR z<100 82 Section 6.2.3 implies that you may not use a fun}ction as a procedure. This is not true. You may call a function as though it were a procedure, b}ut the value returned from the function is ignored. 97 Section 8.1.1 states that you may either initialize} a POINTER to an address or give it a value. Only the second is possible, and you should use thi}s form: BYTE POINTER x= Not this: BYTE POINTER x=[] 99 In example #1 ther}e are two PrintF statements which have "ptr" as one parameter. These should be "bptr", not "ptr". 101 } In the last example of ARRAY declaration (BYTE ARRAY tests(5)...), the dimension is overruled by the } initialization options, and so its dimension is only three. To fill only the first 3 of 5 element}s, do the following: BYTE ARRAY tests(5)= [4 7 18 0 0] 104 In example #3 you see the p}rogram line "PrintE(b)". This should read "PrintE(barray)". 108 Section 8.3.1.2 states that you can }initialize the fields of a record when you declare it. This is untrue; you may only initialize its addr}ess. 110 The program line "rec.level = InputB()" should read "rec.level = GetD(7)". 112 Same as previou}s error. 115 Same as previous error. 112 The program line "continue=InputB()" should read "continue=Get}D(7)" 120 The program line "mode=InputB()" should read "mode=GetD(7)", and the program line "PrintE(}name)" should read "PrintE(nameptr)". 115 Same as previous error. 122 The program line "incctr=chgclr" }should read "incclr=chgclr". 142 Section 5.3 states that you should not use channel 7. ACTION! uses }this channel to get characters from the keyboard, and you may use it to do this also. However, d}on't close this channel or alter its configuration in any way. 153 The example of declaring an ACTIO}N! procedure at an address is wrong! If you do this, the internal pointer to the procedure will point t}o the specified address, but the code generated by the procedure will not be there. Instead, it w}ill be in with your main code. Use procedure and function addressing ONLY to call machine language } routines. 161 Where the table of contents lists the routines in section 2.3, it should read: P}rintBD NOT PrintDB PrintCD NOT PrintDC PrintID NOT PrintDI 162 Where the table of contents } lists the routines in sections 6.7 and 6.8, it should read: PeekC NOT CPeek PokeC NOT CPoke 1}65 Error in section 2.3. See changes for pg. 161 and make similar corrections. 179 Section 6.4 states s}ome information concerning the results of misusing the SCopy routine, detailing that the routine }does string trucation, etc., to make the procedure work. This is not true. You must make sure that the} strings are compatible in size. 181 Section 6.8 states that the parameters to Poke and PokeC } consist only of an address. Instead, they consist of an address and a value, as follows: Poke(<}address>,) PokeC(
,) 182 Section 6.11. MoveBlock will move a maximum block} of 256 bytes in versions 3.0 to 3.4 of ACTION! Versions 3.5 and up will move any number of byte}s. 191 Some error numbers are wrong. The corrections are: 14 Out of Space 15 Missing DO 19} Missing OD 24 Illegal FOR statement 26 Nesting Too Deep 27 Illegal TYPE reference 28 Illega}l RETURN 128 BREAK key abort Also, error 62 is error 61, and 54 & 56 do not exist. 197 In the Print}F statement, %D should be changed to %U. VERSION 2 ERRATA: PAGE ERROR 38 Section 2.7, paragraph 3. The } last sentence states that you can RUN compiled ACTION! programs from disk. This is untrue. The RUN co }mmand will only compile and run ACTION! source files. Use DOS to run compiled object files. 39 The } last RUN example (RUN PrintE()) will not work, since RUN expects a file name. Use the "Xecute" command } instead. 63 In the TECHNICAL NOTE preceeding section 4.3, "*" should be changed to "*, /, or MOD". } 126 The last assignment on the page makes newrecord point to the current record in the array, not t }he end of the array. 132 The program line "mode=InputB()" should be changed to "mode=GetD(7)". 138 } The program line "IF sub(1)=str(ctr)" should read "IF sub(1)=str(ctrl)". 163 The PutDE procedure require}s only a channel as a parameter, and does not put out both a character and a . Rather, it} puts out a only. 172 In graphics mode 0 and all text windows, color 1 is the character lum}inance, color 2 is the background color, and color 3 is unused. 174 In section 5.6, references to th}e "lower right corner" should instead be "lower left corner". 180 Section 6.1.2 states some informat}ion concerning the results of misusing the SCopy routine, detailing that the routine does string }truncating, etc. This is not true. You must make sure that the strings are compatible in size. 182 } Section 6.11. MoveBlock will move a maximum block of 256 bytes in versions 3.0 to 3.4 of ACTION! Vers}ions 3.5 and up will move any number of bytes. @$`ͤb A(MAG:d A> ACTION! BUG SHEET #3 - part 6 ------------------------------------- ACTION OBJECT CODE RELOCATION PROGRAM The program} SIMPLREL.ACT on this BBS may be used to cause an ACTION! program to load and run at a different address than that address at} which it was compiled. The same program will also work for assembly language object files, providing you also follow the gi}ven instructions. The program takes two object files as input and produces a third file which will load and run at a desired} address. The relocating program prompts the user for the two input files, which must have been compiled one page (256 bytes}) apart. It then prompts for an output file name (the relocated file), the page number of the starting address of the first }file, and the page number of the desired destination address. Both page numbers must be decimal values. For example, specify}ing 32 as the destination page will cause the output file to load at address 32*256 ($2000), not $3200. See part V, "The ACT}ION! Compiler", chapter 2, page 144, for information on compiling programs to a specified address (Used to compile the two ob }ject files one page apart). In order to use the relocating program, download SIMPLEREL.ACT and read the instructions therein!}. 'AA9AA$KAA2]A@h4$@!AR@$$MODULE ; Starburst 1.0 By Dan Rhea ; Modified from my Micrsoft Basic; version 7/85DEFINE YES="1", ; Define logical #}flags NO ="0"CARD tc01, ; Scratch Card 1 console=[53279], ; Console Keys option =[3], ; Λ$} select =[5], ; ԛ start =[6], ; ԛ lmargin=[82], ; left margin cursor =[752], ; curs%}or control attract=[77] ; attract modeINT ARRAY x(8), ; 8 possible x coordinates y(8) ; 8 possible y &}coordinatesCARD xaxis ; X axis for plotingBYTE yaxis ; Y axis for plotingBYTE xmax=[48], ; Maximum x coordi'}nate ymax=[48], ; Maximum y coordinate xtot=[95], ; Reflected maximum for xmax ytot=[95], ; Reflected maxim(}um for ymax bias=[32], ; X coordinate offset from 0 (centers output) lcol=[0], ; last color selected mseg=[)}50], ; Maximum segment length (75 with 50 default) adjx, ; X coordinate adjustment adjy, ; Y coordinat*}e adjustment dirc, ; Direction of plot travel (1 to 8) colr, ; Color of segment (1 to 3) segl, +} ; Length of segment (1 to mseg) move, ; movement counter spot, ; plot counter/pointer wrap=[YES,}], ; Wraparound flag glue=[YES], ; Connected segments flag tb01, ; Scratch byte 1 voic, ; Voice -} pitc, ; Pitch dist, ; Distortion volu, ; Volume ckey ; Console keyCHAR ansr .} ; Prompt answerPROC Intro () ; Introduction to Starburst PrintE ("}") Graphics (18)/} Position (0,1) PrintDE (6," OoOoOoOoO") PrintDE (6," o o") PrintDE (6," StBuT 10 "0}) PrintDE (6," ") PrintDE (6," O DAN O") PrintDE (6," o o") PrintDE (6,"1} OoOoOoOo") Position (0,10) PrintDE (6," PRESS ") DO FOR tc01=0 TO 3 ; Register select 2} DO tb01=tc01 colr=Rand(16) SetColor(tb01,colr,6) OD ckey=Peek(console) IF ck3}ey <> start THEN FOR tc01=0 TO 10000 ; Delay DO ; Tarry a bit OD FI UNTIL cke4}y = start ODRETURNPROC Setup (); Set up drawing parameters Graphics (0) SndRst () Poke (lmargin,1) Prin5}tE (" ") PrintE ("") PrintE ("| |") PrintE6} ("| Starburst 1.0 By Dan Rhea 07/15/85 |") PrintE ("| |") PrintE ("7}") PrintE ("") PrintE ("|This program will produce geometri8}c |") PrintE ("|patterns in Graphics Mode 7 using an|") PrintE ("|8 way reflection algorithm. You can |") PrintE ("|9}modify the type of patterns that are|") PrintE ("|generated by altering the following:|") PrintE ("| :} |") PrintE ("| 1. Wraparound (line wrap or not) |") PrintE ("| 2. Connected Lines (does the next |";}) PrintE ("| line start where the last one |") PrintE ("| completed) |") PrintE ("| 3. <}Extent (Maximum line length in a|") PrintE ("| random direction) |") PrintE ("=}") Poke (cursor,1) ; Cursor off; Determine if wraparound is wanted DO Position (1,20) Pri>}ntE ("") PrintE ("|Wraparound Enable? (Y/N) : |") PrintE ("?}") Position (28,21) ansr=GetD(7) IF ansr = 'Y OR ansr = 'y THEN @} wrap = YES tb01 = YES ELSEIF ansr = 'N OR ansr = 'n THEN wrap = NO tb01 = YES ELSEA} tb01 = NO FI UNTIL tb01 = YES OD; Determine if connected lines are wanted DO Position (1,20B}) PrintE ("") PrintE ("|Connected lines required? (Y/N) : |") PrintC}E ("") Position (35,21) ansr=GetD(7) IF ansr = 'Y OR ansr = 'y D}THEN glue = YES tb01 = YES ELSEIF ansr = 'N OR ansr = 'n THEN glue = NO tb01 = YESE} ELSE tb01 = NO FI UNTIL tb01 = YES OD; Determine maximum line segment extent DO PositF}ion (1,20) PrintE ("") PrintE ("|Maximum segment length (1-75) : |") G} PrintE ("") Position (33,21) mseg=InputB() IF mseg < 1 THENH} tb01 = NO ELSEIF mseg > 75 THEN tb01 = NO ELSE tb01 = YES FI UNTIL tb01 = YESI} OD; Give the user operating instructions during the draw mode Position (1,20) PrintE ("J}") PrintE ("|:Draw :Menu :Freeze|") PrintE ("") K}DO ckey=Peek(console) UNTIL ckey = start OD DO ckey=Peek(console) UNTIL ckL}ey <> start OD Poke (cursor,0) ; Restore cursorRETURN PROC Getxy () ; Set random X Y staM}rting coordinates x(1)=Rand(xmax) ; 0 to xmax-1 y(1)=Rand(ymax) ; 0 to ymax-1RETURNPROC Docld (); Set Color, LenN}gth and Direction dirc=Rand(8) ; 0 to 7 DO colr=Rand(4) ; 0 to 3 UNTIL colr <> lcol OD lcol=colO}r segl=Rand(mseg)+1 ; 1 to msegRETURNPROC Clamp (); Clamp the line or wrap it around as needed IF wrap = YES THEP}N IF x(1) < 0 THEN adjx = xmax-1 ELSEIF x(1) >= xmax THEN adjx = 0 ELSE adjx = xQ}(1) FI x(1) = adjx IF y(1) < 0 THEN adjy = ymax-1 ELSEIF y(1) >= ymax THEN adjy = 0R} ELSE adjy = y(1) FI y(1) = adjy ELSE IF x(1) < 0 THEN adjx = 0 ELSES}IF x(1) >= xmax THEN adjx = xmax-1 ELSE adjx = x(1) FI x(1) = adjx IF y(1) < 0 THENT} adjy = 0 ELSEIF y(1) >= ymax THEN adjy = ymax-1 ELSE adjy = y(1) FI y(1) U}= adjy FIRETURNPROC Flect (); DO 8 way reflection x(2) = xtot-x(1) x(3) = x(2) x(4) = x(1) x(5) = y(1)V} x(6) = xtot-x(5) x(7) = x(6) x(8) = x(5) y(2) = y(1) y(3) = ytot-y(1) y(4) = y(3) y(5) = x(1) y(6) = W}y(5) y(7) = ytot-y(6) y(8) = y(7)RETURN PROC Paint (); Draw the sucker FOR spot = 1 TO 8 DO xaxis=x(X}spot)+bias yaxis=y(spot) Plot (xaxis,yaxis) OD RETURNPROC Slide (); Move the guy in cell 1 in the desireY}d direction IF dirc = 0 THEN x(1)==+1 ELSEIF dirc = 1 THEN x(1)==+1 y(1)==+1 ELSEIF dirc = 2 THENZ} y(1)==+1 ELSEIF dirc = 3 THEN x(1)==-1 y(1)==+1 ELSEIF dirc = 4 THEN x(1)==-1 ELSEIF dirc =[} 5 THEN x(1)==-1 y(1)==-1 ELSEIF dirc = 6 THEN y(1)==-1 ELSEIF dirc = 7 THEN x(1)==+1 y(1\})==-1 ELSE ; Do Nothin Meng' FIRETURNPROC Noise () ; Use screen data for sound BYTE base=[63] voic ]}= colr pitc = x(1)+(colr*base) volu = y(1)/4 dist = 10 Sound(voic,pitc,dist,volu)RETURNPROC Main () Intr^}o () DO Setup () Getxy () Graphics (23) DO Poke(attract,0) Docld () co_}lor=colr FOR move = 1 TO segl DO Clamp () ; Wrap/Nowrap Flect () ; Reflect `} Paint () ; Plot all 8 Noise () ; Make some Slide () ; Move # 1 OD IF glue a}= NO THEN Getxy () FI ckey = Peek(console) IF ckey = select THEN DO b} ckey = Peek(console) UNTIL ckey <> select OD FI IF ckey = start THEN c} DO ckey = Peek(console) UNTIL ckey <> start OD Graphics(23) d} FI UNTIL ckey = option OD ODRETURN||||K(@THANKS FOR WATCHINGV(@a(@F; butterfly by michael mitchell ; 01/20/85 PROC DEMO2() CARD A,B,C,D,X,Y,J,K,COL,I,Q Graphics(11) Poke(710,0) Color!f}=00 A=1 B=1 C=1 D=1 X=Rand(70)+1 Y=Rand(190)+1 J=Rand(50)+1 K=Rand(190)+1 For I=1 TO 9400 DO Plot(X,Y) Drawto(J,K) !g}Plot(J,Y) Drawto(X,K) X==+A Y==+B J==+C K==+D Q=Rand(50) IF Q>40 THEN COL==+1 FI IF COL>14 THEN COL=1 FI COLOR=COL IF !q}B BIGST ACTB$BUGS1 ACTBU3BUGS2 ACTB BUGS3 ACTBEBUGS4 ACTB>BUGS5 ACTB BUGS6 ACTBC"BURST ACTBeBUTTER ACTBtCATCH ACTB COMPAR ACTB CONSOL ACTB)CTODSK ACTBTDATES ACTBDIVISI ACTB(2DLIST2 ACTBZEND ACTB[ENTRYB ACTBqENTRYC ACTBENTRYI ACTBENTRYY ACTB EXEC ACTX>=79 THEN A=-A X==+A FI IF J>=79 THEN C=-C J==+C FI IF J<=0 THEN C=-C J==+C FI IF X<=0 THEN A=-A X==+A FI IF Y>=191 THE!r}N B=-B Y==+B FI IF K>=191 THEN D=-D K==+D FI IF K<=0 THEN D=-D K==+D FI IF Y<=0 THEN B=-B Y==+B FI OD !s} :(@NOW, THANKS TO G.U.P/(@/(@ THE ATARI ALSO HAS$.(@  MODULE ; CATCH.ACT ; copyright (c) 1984 ; by Action Computer Services ; All Rights Reserved ; This module provides %u}two PROCs ; (Catch and Throw) which can be used ; for error trapping (and flow ; control, yeck!) in ACTION!. To ; use th%v}em, you must call the Catch ; PROC to indicate where you want ; the program to continue when you ; call Throw. When throw%w} is called, ; execution will continue following ; the last call to Catch with the ; same index as the call to Throw. ; Ca%x}lling Catch is similar (but not ; identical) to TRAP in BASIC. It ; differs in that the actual trapping ; is generated by%y} the user (by ; calling Throw) and that you can ; have multiple Catch'ers active at ; one time. Also, you cannot Throw ;%z} to a Catcher that is no longer ; active (the PROC/FUNC containing ; it has RETURN to it's caller). The ; Throw procedur%{}e tries to check for ; this error, but it is possible to ; fool it into thinking it's OK. If ; you want to solve this pro%|}blem, you ; can set 'c_t_sp(index)' to zero ; before you return from the PROC ; that contained the Catch(index). ; If ind%}}ex is greater than 24 or ; if there is no matching Catch index ; for the Throw, then Error will be ; called with a value o%~}f CTERR ; (defined below to be 71). If you ; setup your own Error procedure and ; use Catch and Throw, your error ; proc%}edure should handle this error ; as well or your program will most ; likely "go off the deep end". DEFINE CTERR = "71"%} BYTE ARRAY c_t_sp(25)=[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] BYTE ARRAY c_t_hi(25), c_t_lo(25) PROC%} Catch(BYTE index) DEFINE TSX="$BA", TXA="$8A", LDYA="$AC", STAY="$99", PLA="$68", LDAY="$B9", %} PHA="$48" IF index>=25 THEN Error(CTERR,0,CTERR) FI [ LDYA index PLA STAY c_t_hi PLA%} STAY c_t_lo TSX TXA STAY c_t_sp LDAY c_t_lo PHA LDAY c_t_hi PHA ] RETURN PR%}OC Throw(BYTE index) DEFINE TXS="$9A", PHA="$48", LDYA="$AC", STX="$86", TSX="$BA", TAX="$AA", %} LDAY="$B9" BYTE sp=$A2 ; get current stack pointer [ TSX : STX sp ] IF index>=25 OR sp+2>c_t_sp(index) %} THEN Error(CTERR,0,CTERR) FI [ LDYA index LDAY c_t_sp TAX TXS LDAY c_t_lo PHA LD%}AY c_t_hi PHA ] RETURN MODULE ; just in case =y` pvB67B:,%@,.b67AW$<; Compare - Check if two files are ; the same. ; by Mark Rose - March, 1985 PROC CmpFile( BYTE f1, f2 ) BYTE c1, c2 )} CARD i, nErrors i = 0 nErrors = 0 ; Until end-of-file, compare a char ; from each file and bump cou)}nt of ; errors, if not the same. DO ; Get one character from each file. c1 = GetD( f1 ) c2 = GetD)}( f2 ) IF (EOF(f1)#0) OR (EOF(f2)#0) THEN EXIT FI ; If chars dont compare, inform ; u)}ser. IF c1 # c2 THEN nErrors ==+ 1 PrintF( "%H: %H %H%E", i, c1, c2 ) FI i ==)}+ 1 OD IF (EOF(f1)#0) AND (EOF(f2)=0) THEN PrintE( "File 1 is shorter" ) ELSEIF (EOF(f1)=0) AND (EOF(f2)#)}0) THEN PrintE( "File 2 is shorter" ) ELSE IF nErrors = 0 THEN PrintE( "Files compare exactly)}" ) ELSE PrintE( "Files are the same length" ) FI FI RETURN PROC Compare() ; Need string)}s for two file names. BYTE ARRAY fn1( 30 ), fn2( 30 ) ; Get the two input files Print( "File 1: " ) InputS( fn)}1 ) Print( "File 2: " ) InputS( fn2 ) ; and open them. Close( 1 ) Open( 1, fn1, 4, 0 ) Close( 2 ) )}Open( 2, fn2, 4, 0 ) ; Perform the compare CmpFile( 1, 2 ) ; and close up. Close( 1 ) Close( 2 ) RETURN ##)}###########################################################################################RɥPee`/([;************************************ ;* * ;*(C)Copyright 1986 by Paul B. Loux * ;* -} * ;* These routines are in the public * ;* domain, and are not to be sold * ;* for a profit. They -}may be freely * ;* distributed, provided that this * ;* header remains in place. Use and * ;* enjoy! PBL, CIS 72337,2073. -} * ;* * ;************************************ ;* * ;* Fi-}le CONSOL.LIB * ;* * ;* Description: three functions * ;* are provide-}d which test if * ;* the user is pressing one of * ;* the START, SELECT or OPTION * ;* console buttons. Retu-}rns a * ;* one if pressed, zero if not. * ;* * ;************************************ -}MODULE BYTE CONSOL=$D01F BYTE FUNC Start() IF CONSOL&1 THEN RETURN(0) FI RETURN(1) BYTE FUNC Select() IF CONSOL&2 THEN-} RETURN(0) FI RETURN(1) BYTE FUNC Option() IF CONSOL&4 THEN RETURN(0) FI RETURN(1) ;************************************-} ; ; Example of usage: PROC Test6() BYTE value DO IF Start() THEN PRINTE("Start") FI IF Option() THEN PRINTE("Option") F-}I IF Select() THEN PRINTE("Select") FI OD RETURN 䠦J!6-F:A ,!6-F:A,T9F:,5 MODULE ; CMPTODSK.ACT ; Copyright (c) 1983 ; by Action Computer Services ; All Rights Reserved ; version 1.0 ; last modifi1}ed October 22, 1984 ; Compile to disk for ACTION! ; compiler. Note that all ARRAY ; declarations that generate storage ; m1}ust be before the first procedure ; declaration or else the address of ; the storage will not be setup ; correctly (all dimen1}sioned ARRAYs ; which are not assigned an initial ; value except BYTE/CHAR arrays of ; size 256 or less). Local ARRAY ; decl1}arations in the main PROC (last ; procedure in program) are also ; allowed. Note: there must be at ; least one PROC/FUNC i1}n program. ; Output file name will be same name ; as program being compiled with ; extention .OBJ ; IF AN ERROR OCCURS DURI1}NG ; COMPILATION, YOU SHOULD USE ; "/" to close all open files: ; >/ ; change dev in SPLEnd below to direct ; output to1} printer. DEFINE STRING = "CHAR ARRAY" DEFINE JMP = "$4C" ; JMP addr16 TYPE INSTR=[BYTE op CARD addr] INSTR Segvec=$4C6 INS1}TR SPLvec=$4DD INSTR MonCmd=$4FB INSTR OldMon BYTE oldDevice, curBank=$4C9 BYTE pf, Zop=$8A, tZop, dev CARD curproc=$8E, cod1}e=$E CARD codeBase=$491, codeSize=$493 CARD codeOff=$B5 CARD globals, gsize CARD totalSize, codeStart CHAR ARRAY cmdLine(0)=$1}590 BYTE ARRAY bank(0)=$D500 BYTE ARRAY zpage(32), temps(16) PROC InitMon() ; add "/" command to monitor which ; closes cha1}nnels 1-5 and warm ; starts cartridge. CHAR cmdchar=$591 BYTE i, WARMST=$8 DEFINE JMPI="$6C" ; make sure right comman1}d IF cmdchar#'/ THEN [JMP OldMon] FI bank(0) = 0 ; init library routines FOR i = 1 TO 5 DO Close(i) OD WARMST1} = 1 [JMPI $BFFA] ; warm start cart. INCLUDE "BLKIO.ACT" PROC Save() ; save state of variables used by ; both compiler an1}d library routines bank(0) = 0 ; init library routines tZop = Zop MoveBlock(zpage, $B0, $1B) ; to $CA MoveBlock(temp1}s, $5F0, 16) RETURN PROC Restore() ; restore state of variables used by ; both compiler and library routines CARD tcodeOf1}f Zop = tZop tcodeOff = codeOff MoveBlock($B0, zpage, $1B) ; to $CA MoveBlock($5F0, temps, 16) codeOff = tcodeOff 1} bank(curBank) = 0 RETURN PROC WriteHdr() PutCD(5, $FFFF) PutCD(5, codeStart) PutCD(5, codeStart+totalSize-1) Wri1}teBlock(5, globals, gsize) RETURN PROC WriteCode() codeSize = code - codeBase PrintD(dev, curproc) PrintD(dev, ": ") 1} PrintCDE(dev, codeSize) totalSize = totalSize + codeSize WriteBlock(5, codeBase, codeSize) code = codeBase codeOff 1}= codeOff + codeSize RETURN PROC SegEnd() Save() IF pf THEN ; print locals WriteCode() ELSE pf = 1 global1}s = codeBase gsize = code - codeBase codeBase = code totalSize = gsize codeStart = globals + codeOff Writ1}eHdr() FI Restore() RETURN PROC SPL() ; dummy proc for call below PROC SPLEnd() CHAR c BYTE nxttoken=$D3, i, n, b1}uf=$9B^ CARD nxtaddr=$C9, start=$2E2 STRING inbuf(0)=$5C8, name STRING out(17) DEFINE PLA = "$68", STA = "$1}8D" Save() dev = 0 ; to get output to printer: ; dev = 4 ; Close(4) Open(4, "P:", 8, 0) ; get output name IF nxttok1}en=30 THEN ; command line name = nxtaddr ELSE ; editor buffer name = inbuf FI ; see if device needed n = 0 I1}F name(2)#': AND name(3)#': THEN out(1) = 'D out(2) = ': n = 2 FI ; get name without extension FOR i = 1 TO name(1}0) DO c = name(i) IF c='. THEN EXIT FI IF c>'Z THEN c = c & $5F FI out(i+n) = c OD ; add extension ou1}t(i+n) = '. out(i+n+1) = 'O out(i+n+2) = 'B out(i+n+3) = 'J out(0) = i + n + 3 PutE() Print("output file is ") 1} PrintE(out) PutE() Close(5) Open(5, out, 8, 0) buf = 0 ; clear buf used by Open pf = 0 ; no proc decl yet ; JSR 1}for return so that we come ; back here after compilation [ PLA STA SPL+1 PLA STA SPL+2 ] SPL = SPL +1} 1 ; get right address Restore() SPL() Save() ; ignore space for arrays code = codeBase + codeSize WriteCode() 1} PutCD(5, $2E2) PutCD(5, $2E3) PutCD(5, start) Close(5) Open(5, out, $C, 0) WriteHdr() Close(5) PutDE(dev) 1} PrintCD(dev, totalSize) PrintDE(dev, " bytes of code") Restore() codeOff = 0 RETURN ; only code generated before In1}it is ; allocated space. Init will be ; garbage collected (well kind of). PROC Init() CARD codeBlock, bsize, csize, nBloc1}k CARD POINTER cur, next ; link in our routines Segvec.op = JMP Segvec.addr = SegEnd SPLvec.op = JMP SPLvec.addr =1} SPLEnd OldMon.op = MonCmd.op OldMon.addr = MonCmd.addr MonCmd.op = JMP MonCmd.addr = InitMon ; allocate our routine1} so it won't ; go away. codeBlock = codeBase - 4 next = $80 ; AFbase DO cur = next next = next^ UNTIL next=0 1}OR next=codeBlock OD IF next=0 THEN PutE() Put($FD) PrintE("I can't allocate space for your code") PrintE("Y1}ou better Boot and try again!") RETURN FI ; assume we can split block csize = @codeBlock-codeBlock nBlock = next^ 1} bsize = next(1) - csize next = @codeBlock cur^ = next next^ = nBlock next(1) = bsize codeBase = next + 4 RETURN 0};************************************ ;* * ;*(C)Copyright 1986 by Paul B. Loux * ;* 5} * ;* These routines are in the public * ;* domain, and are not to be sold * ;* for a profit. They 5}may be freely * ;* distributed, provided that this * ;* header remains in place. Use and * ;* enjoy! PBL, CIS 72337,2073. 5} * ;* * ;************************************ ; ; File: DATES.LIB ; ; Desciption: Library 5}of routines ; supporting the input, storage ; and manipulation of dates. ; ; Requirements: EntryD() utilizes ; "EntryS(5})" (universal string ; entry routine), "PrintM()" ; (output formatter), and the ; "ValD()" function provided ; 5} herein. ; ; EntryS() is available under the ; name ENTRYS.ACT ; ; PrintM() is available under the ; name PRINTM.ACT ; ;5}************************************ ; ; CARD FUNC ValD() ; PROC StrD() ; PROC Day() ; CARD FUNC EntryD() ; ;****************5}******************** ; ; Four routines are provided to ; facilitate the storage and ; manipulation of dates. The ; 5}CARD FUNC ValD() will ; convert a date in string format ; to a unique CARD value. The ; CARD returned by this f5}unction ; can be used to compute the ; number of calender days between ; two dates. The string can have ; non-numeric5} characters; for ; instance "12/31/85" is legal. ; Used together with its converse, ; PROC StrD(CARD number,), 5}; it is also possible to find ; the calender date which falls ; a given number of days before ; or after a reference 5}date. ; The string returned by StrD() ; contains only numbers; formatting ; must be performed separately. ; ; PROC Da5}y(CARD number,) ; provides the day of the week ; corresponding to a given calender ; date, as represented by a5} CARD ; value generated by ValD(). ; ; CARD FUNC EntryD() obtains a ; date from the keyboard. It uses ; EntryS(), the5} universal string ; entry utility; therefore it has ; the associated features of error ; checking, timeout, etc. EntryD5}() ; will assure the validity of the ; entered date, check it against ; optional minimum and maximum ; dates, and ech5}o succesful entry ; in mm-dd-yy format, by use of ; PrintM(). The calling program ; provides the entry buffer, so ; E5}ntryD() can be used to return ; a CARD value (as with ValD()) ; or to obtain an unformatted ; string (as with StrD()). 5}; ; PROC PrintM(,) and ; its variants *ME,*MD,and *MDE ; can be used to print a date in ; any format d5}esired, such as ; "mm-dd-yy". ; ; To facilitate usage into the next ; century, the date computations ; include a 40-5}year offset. Thus, ; the date "043020" is presumed to ; mean April 30, 2020. Therefore, ; date computations are only va5}lid ; for dates within the range from ; 1-1-1940 through 12-31-2039. ; ValD() and StrD() are consistent ; in this reg5}ard. ; ; Note that more efficient storage ; results from use of CARD values ; (2 bytes) rather than strings ; (5 or 65} bytes plus length byte). ; This technique also facilitates ; ease in sorting data by date. ; ; Technical note: in gene5}ral, any ; string variable should be pre- ; extended to its maxmium length ; prior to making a call which ; will u5}se it to pass data. ; ; ;************************************ ; ; "ValD()" ; ; Convert a date string into ; a unique5} CARD value. Input ; expected: ; ; "010185" ; "1-01-85" ; "Date: 01/01/85" ; etc. ; ; NOT: 5}"1/1/85" ; CARD FUNC ValD(BYTE ARRAY dateS) BYTE ARRAY digits(0)="......" BYTE ARRAY month(0)="..", day(0)="5}..", year(0)=".." BYTE mm,dd,yy BYTE dmax,bad_date BYTE len1 BYTE len2 BYTE ctr,tmp BYTE xtmp,ztmp CARD value 5} INT offset len1=dateS(0) len2=6 DO ; assure only digits tmp=dateS(len1) IF (tmp>47 AND tmp <58) TH5}EN digits(len2)=tmp len2==-1 FI len1==-1 UNTIL len1=0 OR len2=0 OD IF len2>1 THEN ; 4 or less #'s RETURN5}(0) FI IF len2=1 THEN ; 5 #'s digits(1)=48 ; '0 FI digits(0)=6 SCopyS(month,digits,1,2) SCopyS(day,dig5}its,3,4) SCopyS(year,digits,5,6) mm=ValB(month) dd=ValB(day) yy=ValB(year) bad_date=0 IF mm>12 OR ; legal da5}te mm<1 OR ; checks dd<1 THEN bad_date=1 FI IF mm=2 THEN IF yy MOD 4 THEN dmax=28 ELSE dmax=295} FI ELSEIF mm=4 OR mm=6 OR mm=9 OR mm=11 THEN dmax=30 ELSE dmax=31 FI IF dd>dmax THEN bad_date=1 FI I5}F bad_date THEN RETURN(0) FI IF yy<40 THEN ; 40 year offset yy==+100 FI IF mm<3 THEN xtmp=0 ztmp=(yy-1)/45} ELSE xtmp=(4*mm + 23)/10 ztmp=yy/4 FI mm==-1 value=365*yy+31*mm+dd+ztmp-xtmp RETURN(value) ;*********5}*************************** ; ; "StrD()" ; ; Restores a date compressed ; to a CARD value by ValD(), ; into a fix5}ed length string ; of six digital characters; ; no formating is performed. ; Example output: ; ; "010185" ; ; 5} Note: calling program must ; pre-extend string "dateS" ; to six places. ; PROC StrD(CARD dateC BYTE ARRAY5} dateS) BYTE ARRAY mm(0)="..", dd(0)="..", yy(0)=".." BYTE POINTER ptr1,ptr2 INT m,d,y,r,s,t,y1,ly BY5}TE dmax y=0 y1=0 IF dateC>36524 THEN ; yy=1** dateC==-36525 FI IF dateC>29220 THEN ; # too big dateC==-7305 y15}=20 FI IF dateC<61 THEN ; handle yr=0 dateC==+1461 y1=-4 FI y=dateC/365 r=dateC-(y*365)-y/4 IF r<31 THEN5} y==-1 r=dateC-(y*365)-y/4 FI IF r>59 then s=7 ELSE s=0 FI m=(r+s)/31 ly=(y/4)-((y-1)/4) IF m<3 THEN t=l5}y ELSE t=(4*m+23)/10 FI IF m=2 THEN IF y MOD 4 =0 THEN dmax=29 ELSE dmax=28 FI ELSEIF m=4 OR5} m=6 OR m=9 OR m=11 THEN dmax=30 ELSE dmax=31 FI d=r-31*(m-1)+t IF d>dmax THEN m==+1 IF m<3 THEN 5} t=ly ELSE t=(4*m+23)/10 FI d=r-31*(m-1)+t FI IF m=13 THEN y==+1 m==-12 FI y==+y1 StrI(m,mm) StrI(d,dd) S5}trI(y,yy) SCopy(dateS,"000000") ptr1=mm+1 ptr2=dateS+1 IF mm(0)=1 THEN ptr2==+1 ptr2^=ptr1^ ELSE ptr2^=ptr1^ pt5}r1==+1 ptr2==+1 ptr2^=ptr1^ FI ptr1=dd+1 ptr2=dateS+3 IF dd(0)=1 THEN ptr2==+1 ptr2^=ptr1^ ELSE ptr2^=ptr1^ 5} ptr1==+1 ptr2==+1 ptr2^=ptr1^ FI ptr1=yy+1 ptr2=dateS+5 IF yy(0)=1 THEN ptr2==+1 ptr2^=ptr1^ ELSE ptr2^=pt5}r1^ ptr1==+1 ptr2==+1 ptr2^=ptr1^ FI RETURN ;************************************ ; ; "Day()" ; ; Day of the5} week computation ; ; Returns variable-length string ; containing corresponding day ; of the week for the CARD val5}ue ; supplied. String can be easily ; massaged to obtain upper case ; only, first three letters,etc. ; ; Note: 5}string "day" must be ; pre-xtended to 9 places by the ; the calling program, to allow ; room for "Wednesday" res6}ponse. ; PROC Day(CARD dateC BYTE ARRAY day) CARD ref=[31412] ; Wednesday 1/1/86 INT dif BYTE num,dir BYTE ARRAY ptr CARD A6}RRAY dow(7) dow(0)="Wednesday" dow(1)="Thursday" dow(2)="Friday" dow(3)="Saturday" dow(4)="Sunday" dow(5)="Monday" dow(6)="T6}uesday" dow(7)="Wednesday" dir=0 dif=dateC-ref IF dif<0 THEN dif=-dif dir=1 FI num=dif MOD 7 IF dir THEN num=7-num FI p6}tr=dow(num) SCopy(day,ptr) RETURN ;************************************ ; ; ; CARD FUNC EntryD() ; ; Data ent6}ry utility used to ; gather a calender date from ; the keyboard in the "mmddyy" ; format. The routine performs ; ch6}ecks for illegal dates and ; echoes a valid response in ; "mm-dd-yy" format. Returns ; date as a CARD value as per6} ; ValD(), or as an unformatted ; string as per StrD(). ; ; This function uses both the ; EntryS() data entry uti6}lity ; and the PrintM() formatter. ; ; Calling options include the ; screen coordinates; high and ; low checks; 6}null-entry flag; ; and exit flag, per EntryS(). ; ; ;************************************ INCLUDE "ENTRYS.ACT" INCLUD6 }E "PRINTM.ACT" ;************************************ MODULE CARD FUNC EntryD(BYTE ARRAY field BYTE col,row,nu6 }llok,xit CARD min_date,max_date BYTE POINTER err_ptr) BYTE bad_date,accept,ctr, min,max,typec 6 }CARD value BYTE POINTER ptr1,ptr2 INT chk min=5 IF nullok THEN min=0 FI IF max_date=0 THEN max_date=51134 ; 12-6 }31-39 FI max=6 typec=5 ; pos int accept=0 chk=0 DO POSITION(row,col) PRINT(" ") ENTRYS(field,min,6 }max,typec,xit, col,row,err_ptr) IF err_ptr^#0 THEN RETURN(0) FI bad_date=0 IF field(0)=0 THEN IF nullo6}k=1 THEN RETURN(0) ELSE bad_date=1 FI FI value=ValD(field) IF value=0 THEN bad_date=1 ELSEIF valuemax_date THEN bad_date=2 FI IF bad_date=1 THEN MSG(8) ELSEIF bad_date=2 THEN MSG(7) ELSE 6}accept=1 FI UNTIL accept OD POSITION(col,row) PRINTM(field,"3} by *;*anyone for any reason. It was *;*written by: *;* William T. Colburn *;>4}* in February, 1987. *;* CI$: 72337,322 GEnie:W.T.COLBURN*;*Please enjoy this demonstration *;*program an>5}d share it with others! *;*Please keep this header with the *;*program listing when you do so. *;**********************>6}**************;* Š *;*This program makes use of the *;*routine ALLOCATE.ACT from the OS>7}S *;*Action! Tool Kit. ALLOCATE.ACT is*;*copywrited by OSS and is NOT in *;*the public domain. Therefore, *;*ALLOC>8}ATE.ACT was not included with*;*DLIST2.ACT by the Author, and *;*must NOT be added to it for public*;*distribution by >9}any other user of *;*this demonstration program. *;*The author of this routine refuses*;*to accept responsibility fo>:}r this *;*type of unethical action by any *;*users of my demonstration program.*;************************************C>;}ARD EndProg ;required for ALLOCATE.ACT; You do a 'SET EndProg=*'; from the monitor compiling,; but ><} running this program!INCLUDE "D8:ALLOCATE.ACT"; from the Action! Tool KitMODULE ; My gloabl variables here.BYTE ARRAY>=} dlist= ; display list! [ $22 ; length (34 bytes) $70 $70 $70 ;24 overscan lines >>} $42 $00 $00 ;load address of static here. $06 $06 ;two lines of Gr.1 $42 $00 $00 ;load >?}savmsc+200 here. $02 $02 $02 ;22 lines Gr. 0 $02 $02 $02 $02 $02 $02 $02 >@}$02 $02 $02 $02 $02 $02 $02 $02 $02 $02 $41 $00 $00 ;load address of dlis>A}t+1 here. ] BYTE ARRAY static ; static 80 byte display, allocated with Alloc() from Action! tool kit.PROC dspl>B}y_list() CARD savmsc=$58, ;contains low address of screen display dlist_vector=$230, ; points to the display list>C} old_savmsc=[0], ; save the savmsc here. temp_card=[0] ; temporary variable! BYTE dma=559, ; antic chip on>D}/off address crsinh=752, ;cursor on/off address loop ; loop counter BYTE POINTER dlist_ptr,; pointer to di>E}splay list array. save_dlist_ptr, static_ptr ; pointer to static dlist_ptr=dlist save_d>F}list_ptr=dlist save_dlist_ptr==+1 static=Alloc(81); allocate 81 bytes for 'static'. FOR loop=1 TO 80 DO >G} static(loop)=0 OD static(0)=80 ; set length of string static_ptr=static ; set pointer static_ptr==+1 ; poi>H}nt to entry #1. Graphics(0) old_savmsc=savmsc ; save start of screen adress dlist_ptr==+5 dlist_ptr^=static_ptr-(>I}(static_ptr RSH 8) LSH 8) dlist_ptr==+1 dlist_ptr^=static_ptr RSH 8 ;divide by 256! dlist_ptr==+4 temp_card=old_s>J}avmsc+120 dlist_ptr^=temp_card-((temp_card RSH 8) LSH 8) dlist_ptr==+1 dlist_ptr^=temp_card RSH 8 dlist_ptr==+22>K} dlist_ptr^=save_dlist_ptr-((save_dlist_ptr RSH 8) LSH 8) dlist_ptr==+1 dlist_ptr^=save_dlist_ptr RSH 8 ;divide by 25>L}6! dma=0 ; turn off the antic chip dlist_vector=save_dlist_ptr; install the dlist vector savmsc=old_savmsc; reset th>M}e screen starting address dma=34 ; turn on the antic chip;**crsinh=1 ; kill cursorRETURNMODULE ; for user.PROC Main(>N}) BYTE lmargn=$52, dma=559, Answer=[0] lmargn=3 PutE() PutE() PrintE("Did you do a: Ԡ罪")>O} PrintE("from the monitor after compiling") PrintE("but before running this program?") Print("Respond or ...?")>P} Answer=GetD(7) Put(Answer) IF Answer='Y OR Answer='y THEN Print("}") ELSE RETURN FI AllocInit(0>Q}); from ALLOCATE.ACT dsply_list(); install display list SetColor(2,10,3); pick your color SAssign(static,">R}",09,32) SAssign(static,"",45,56) SAssign(static,"displaylistmanager",61,80) Print("}") >S}; clear the screen Position(3,4) PrintE("See? This is the display list!") Position(3,7) PrintE("This screen has >T}a static display") PrintE("on the first three lines of the") PrintE("screen. The rest scrolls.") PrintE("The tricky>U} part of all this is") PrintE("that the characters in 'static'") PrintE("which you want to display must be") Pri>V}ntE("in the internal Atari code because") PrintE("they won't be translated!") PrintE("">W}) PrintE("To see scrolling, type 'E' and then") PrintE("press RETURN to go back to the") PrintE("editor. The displa>X}y list will") PrintE("remain in place until you return") PrintE("to the monitor or hit RESET.") lmargn=0RETURN>Y}<uPROC End=*() [$68$AA$68$CD$2E8$90$5$CD$2E6$90$F3 $48$8A$48$60] @?;************************************ ;* * ;*(C)Copyright 1986 by Paul B. Loux * ;* F\} * ;* These routines are in the public * ;* domain, and are not to be sold * ;* for a profit. They F]}may be freely * ;* distributed, provided that this * ;* header remains in place. Use and * ;* enjoy! PBL, CIS 72337,2073. F^} * ;* * ;************************************ ; ; FILE BYTE FUNC EntryB() ; ; Universal F_}byte-entry routine, ; requires PROC EntryS, the ; universal string entry routine. ; This routine takes input from ; K: inF`} string form (through ; EntryS) and checks for legal ; value (<=255) and other useful ; features before converting to ; aFa}n actual BYTE value. ; ; Includes range check, execute ; on single digit flag, a null- ; entry ok flag, and uses the ; thFb}e same xit flag as EntryS. ; Use of EntryS allows the same ; user interface (ESC and ^-Z ; handling, timeouts, etc.) ; ; Fc}Parameters are self-explanatory; ; minval and maxval are the range ; limits for acceptable response ; (limted to 0-255 of Fd}course); the ; XEQ, XIT and nullok flags are ; 1 or yes and 0 for no. ; ;************************************ ; INCLUDE "EFe}NTRYS.ACT" ; ;************************************ BYTE FUNC EntryB(BYTE col,row,minval, maxval,nullok,xeq,xFf}it BYTE POINTER err_ptr) BYTE ARRAY limit(0)="255", field(0)="..." BYTE fldlen=field BYTE acceptFg},min,max, typec,value INT chk min=0 IF minval>0 THEN min==+1 FI IF minval>10 THEN min==+1 FI IF minval>100 THEN min==+Fh}1 FI IF nullok THEN min=0 FI IF maxval=0 THEN maxval=255 max=3 ELSE max=0 IF maxval>0 THEN max==+1 FI IF maxval>10 THENFi} max==+1 FI IF maxval>100 THEN max==+1 FI FI typec=5 ; pos int accept=0 chk=0 DO ENTRYS(field,min,max,typec,Fj}xit, col,row,err_ptr) IF err_ptr^#0 THEN RETURN(0) FI ;(calling routine does error handling) IF fldlen=0 TFk}HEN field(1)='0 field(0)=1 FI IF fldlen=3 THEN ; overflow chk=SCOMPARE(field,limit) FI IF chk>0 THEN chFl}k=0 MSG(7) ELSE value=VALB(field) IF valuemaxval THEN MSG(7) ELSE accept=1 FI FI UNTIL accepFm}t OD RETURN(value) ;************************************ ; ; Example of use of EntryB() PROC Test2() BYTE x,y,min,max,nulFn}lflg,value BYTE errcde BYTE POINTER err_ptr errcde=0 err_ptr=@errcde min=100 max=200 nullflg=0 x=15 y=7 PUT(125) POSITIOFo}N(5,5) PUTE() PRINTE("Enter a number between ") PRINTB(min) PRINT(" and ") PRINTB(max) PRINT(": ") value=EntryB(X,Y,min,max,Fp}nullflg, 0,0,err_ptr) POSITION(5,10) PUTE() PRINTBE(value) PRINTE("Done...") RETURN Dd;************************************ ;* * ;*(C)Copyright 1986 by Paul B. Loux * ;* Jr} * ;* These routines are in the public * ;* domain, and are not to be sold * ;* for a profit. They Js}may be freely * ;* distributed, provided that this * ;* header remains in place. Use and * ;* enjoy! PBL, CIS 72337,2073. Jt} * ;* * ;************************************ ; ; CARD FUNC EntryC() ; ; Universal card-Ju}entry routine, ; requires PROC EntryS(), the ; universal string entry routine. ; Includes range check, execute ; on firstJv} digit flag, a null- ; entry ok flag, and uses the ; the same XIT flag as ENTRYS. ; ; This routine takes input from ; K: Jw}in string form (through ; EntryS) and checks for legal ; value (<=65535) and other useful ; features before converting to Jx}; an actual CARD value. ; ; Includes range check, execute ; on single digit flag, a null- ; entry ok flag, and uses the ;Jy} the same xit flag as EntryS. ; Use of EntryS allows the same ; user interface (ESC and ^-Z ; handling, timeouts, etc.) ;Jz} ; Parameters are self-explanatory; ; minval and maxval are the range ; limits for acceptable response ; (limted to 0-655J{}35 of course); ; the XEQ, XIT and nullok flags ; are 1 or yes and 0 for no. ; ;************************************ ; INCLJ|}UDE "ENTRYS.ACT" ; ;************************************ CARD FUNC EntryC(BYTE col,row CARD minval,maxval J}} BYTE nullok, xeq,xit BYTE POINTER err_ptr) BYTE ARRAY limit(0)="65535", J~} field(0)="....." BYTE fldlen=field BYTE accept,min,max,typec CARD value INT chk min=1 IF minval>10 THEN min==+1 FJ}I IF minval>100 THEN min==+1 FI IF minval>1000 THEN min==+1 FI IF minval>10000 THEN min==+1 FI IF nullok THEN min=0 FI IF J}maxval=0 THEN maxval=65535 max=5 ELSE max=1 IF maxval>10 THEN max==+1 FI IF maxval>100 THEN max==+1 FI IF maxval>1000 TJ}HEN max==+1 FI IF maxval>10000 THEN max==+1 FI FI typec=5 ; pos int accept=0 chk=0 DO ENTRYS(field,min,max,J}typec,xit, col,row,err_ptr) IF err_ptr^#0 THEN RETURN(0) FI ;Calling routine does error handling IF fldlenJ}=0 THEN field(1)='0 field(0)=1 FI IF fldlen=5 THEN chk=SCOMPARE(field,limit) FI IF chk>0 THEN chk=0 MSG(7) ELJ}SE value=VALC(field) IF valuemaxval THEN MSG(7) ELSE accept=1 FI FI UNTIL accept OD RETURN(valJ}ue) ;************************************ ; ; Example of use of EntryC() PROC Test3() BYTE x,y,nullflg CARD min,max,value J}BYTE errcde BYTE POINTER err_ptr errcde=0 err_ptr=@errcde min=1000 max=2000 nullflg=0 x=17 y=7 PUT(125) POSITION(5,5) PUJ}TE() PRINTE("Enter a number between ") PRINTC(min) PRINT(" and ") PRINTC(max) PRINT(": ") value=EntryC(x,y,min,max,nullflg, J} 0,0,err_ptr) POSITION(5,10) PUTE() PRINTCE(value) PRINTE("Done...") RETURN H[;************************************ ;* * ;*(C)Copyright 1986 by Paul B. Loux * ;* N} * ;* These routines are in the public * ;* domain, and are not to be sold * ;* for a profit. They N}may be freely * ;* distributed, provided that this * ;* header remains in place. Use and * ;* enjoy! PBL, CIS 72337,2073. N} * ;* * ;************************************ ; ; CARD FUNC EntryI() ; ; Universal integN}er-entry routine, ; requires PROC EntryS(), the ; universal string entry routine. ; Includes range check, a null- ; entryN} ok flag, and uses the ; the same XIT flag as ENTRYS. ; ; This routine takes input from ; K: in string form (through ; EnN}tryS) and checks for legal ; value (<=65535) and other useful ; features before converting to ; an actual INT value. ; ; N}Use of EntryS allows the same ; user interface (ESC and ^-Z ; handling, timeouts, etc.) ; ; Parameters are self-explanatorN}y; ; minval and maxval are the range ; limits for acceptable response ; (limted to +/-32767 of course); ; the XIT and nulN}lok flags are 1 ; for yes and 0 for no. ; ;************************************ ; INCLUDE "ENTRYS.ACT" ; ;*****************N}******************* INT FUNC EntryI(BYTE col,row INT minval,maxval BYTE nullok, N} xeq,xit BYTE POINTER err_ptr) BYTE ARRAY u_limit(0)="32767", l_limit(0)="-32767", N}field(0)="......" BYTE fldlen=field BYTE accept,min,max,typec INT chk,tmp INT value,tmpval CARD temp,minchk,maxchk,offset N} min=0 IF nullok=0 THEN IF minval<0 THEN temp=-minval min==+1 ELSE temp=minval FI IF temp>0 THEN min==+1 FI IF teN}mp>10 THEN min==+1 FI IF temp>100 THEN min==+1 FI IF temp>1000 THEN min==+1 FI IF temp>10000 THEN min==+1 FI FI max=1 IF N}maxval<0 THEN temp=-maxval max==+1 ELSE temp=maxval FI IF temp>0 THEN max==+1 FI IF temp>10 THEN max==+1 FI IF temp>100 THN}EN max==+1 FI IF temp>1000 THEN max==+1 FI IF temp>10000 THEN max==+1 FI IF max0 THEN MSG(7) ELSE value=VALI(field) IF minval<0 THEN offset=-minval minchk=0 maxval==+offset N}maxchk=maxval tmpval=value tmpval==+offset IF tmpval<0 THEN tmpval=maxval+1 FI temp=tmpval ELSE N} temp=value maxchk=maxval minchk=minval FI IF tempmaxchk THEN MSG(7) ELSE accept=1 FI FIN} UNTIL accept OD RETURN(value) ;************************************ ; ; Example of use of EntryC() PROC Test4() BYTE x,N}y,nullflg INT min,max,value BYTE errcde BYTE POINTER err_ptr errcde=0 err_ptr=@errcde min=-20000 max=-1000 nullflg=0 x=19 N} y=7 PUT(125) POSITION(5,5) PUTE() PRINTE("Enter a number between ") PRINTI(min) PRINT(" and ") PRINTI(max) PRINT(": ") valN}ue=EntryI(x,y,min,max,nullflg, 0,0,err_ptr) POSITION(5,17) PUTE() PRINTIE(value) PRINTE("Done...") RETURN L|;************************************ ;* * ;*(C)Copyright 1986 by Paul B. Loux * ;* R} * ;* These routines are in the public * ;* domain, and are not to be sold * ;* for a profit. They R}may be freely * ;* distributed, provided that this * ;* header remains in place. Use and * ;* enjoy! PBL, CIS 72337,2073. R} * ;* * ;************************************ ; ; File ENTRYYN.ACT ; ; BYTE FUNC ER}ntryYN() ; ; Returns either one or zero ; (true/false), representing a ; one-character (Y or N) user ; resR}ponse to yes/no questions ; (uses EntryS(),the universal ; string entry utility, to get ; the keystroke). ; ; R} The routine supports typical ; EntryS() features, including ; screen coordinates supplied ; by the calling rR}outine; pass ; through of error codes, for ; ESC and Ctrl-Z handling; and ; timeouts. This routine also ; aR}llows a default value for a ; null-response (if desired). ; ; Parameters: ; ; col=screen echo horiz column ; rowR}=screen echo vert column ; ; default= 0 for null="N" ; 1 for null="Y" ; 2 to disallow null ; ; R} err_ptr= pointer to pass err ; to calling routine. ; ;************************************ ; INR}CLUDE "ENTRYS.ACT" ; ;************************************ ; ; BYTE FUNC Ask_YN(BYTE col,row,default R} BYTE POINTER err_ptr) DEFINE max ="1", typec="7", xit ="0" BYTE response,min BYTE ARRAY R}field="x" IF default=2 THEN min=1 ELSE min=0 FI DO ENTRYS(field,min,max,typec,xit, col,row,err_ptr) IF err_R}ptr^#0 THEN RETURN(0) FI IF field(0)=0 THEN ; null entry IF default=0 THEN PUT('N) ELSE PUT('Y) FI RETR}URN(default) FI response=field(1) IF response=89 THEN ; 'Y RETURN(1) ELSEIF response=78 THEN ; 'N RETURN(0) FI OD R} RETURN(0) ; ; ;************************************ ; ; Example of usage: PROC Test8() BYTE answer BYTE x,y,default BYTE eR}rrcde BYTE POINTER err_ptr errcde=0 err_ptr=@errcde x=33 y=5 default=0 PUT(125) POSITION(1,5) PRINT("Do you own a computeR}r (Y/[N]): ") answer=Ask_YN(x,y,default,err_ptr) POSITION(1,7) IF answer THEN x=26 y=7 default=1 PRINT("Is it an AtarR}i ([Y]/N): ") answer=Ask_YN(x,y,default,err_ptr) POSITION(1,9) IF answer THEN x=17 y=9 default=2 PRINT("IsR} it an 8-bit? (Y/N)") answer=Ask_YN(x,y,default,err_ptr) POSITION(1,11) IF answer THEN PRINT("CongratR}ulations.") ELSE x=9 y=11 default=0 PRINT("520 ST? (Y/[N])") answer=Ask_YN(x,y,default,eR}rr_ptr) POSITION(1,13) IF answer THEN PRINT("Congratulations.") ELSE PRINTE("Must be a 1R}040 ST then.") FI FI ELSE PRINTE("Too bad.") FI ElSE x=32 y=7 default=1 POSITION(1,7) PRINTE("ToR}o bad.") FI RETURN P ;Com_Exec, by Craig S. Thom 1987 ;This PROC, when used with SpartaDOS ;v2.5 or greater, will allow the ;execution of ANYV} command processor ;command from within an Action! ;program. For example, Com_Exec("DIR D2:") ;will print the directory of DV}2: to ;the screen without otherwise altering ;the execution of any program. ;Care should be taken when executing ;external coV}mmands, however, since ;they may overwrite program memory. PROC VXCOMLI() ;LDA PORTB ;gets bank select status ;PHA V} ;and saves on stack. ;AND #FE ;resets bit 0, disabling ;STA PORTB ;ROM $C000-$CFFF & $F000-$FFFF. ;JSR VXCOMLI ;callsV} execute routine. ;PLA ;restores bank select ;STA PORTB ;status. ;RTS ;return. [$AD$01$D3$48$29$FE$8D$0V}1$D3 $20$D2$FF$68$8D$01$D3$60] PROC Com_Exec(BYTE ARRAY command) CARD POINTER DOSVEC BYTE POINTER LBUFV}, BUFOFF BYTE Sparta =$700, version=$701, i IF Sparta<>$53 OR version<$25 THEN PrintV}E("ComEx works only with SpartaDOS v2.5") PrintE("or greater.") RETURN FI IF command(0)>64 THEN PrintE("CommandV} too long!") RETURN FI DOSVEC=$000A LBUF=DOSVEC^+63 BUFOFF=DOSVEC^+10 BUFOFF^=0 ;set buffer offset to 0 FOR i=V}1 TO command(0);Copy command into DO ;CP buffer LBUF^=command(i) LBUF==+1 OD LBUF^=$9B VXCV}OMLI() RETURN MODULE 99999999999999999999999999999999999999999999999999999999999999999999999T`