LBSOS KRNLI/O ERRORFILE 'SOS.KERNEL' NOT FOUNDINVALID KERNEL FILExةw,@  4  J  ȱ⩤i8#) ) 8Le/ WAP /// SIG MENU.MAKER PROGRAM (v. 6.1) =".D1"210: Coldstart (320: Warmstart &*X=11000: TEXT SLOW-DOWN LOOP ,X.1 CHANGE DISK SUBROUTINE23œ202:2200<RFa$=" YOU MAY SELECT YOUR DISK BY V,BASIC.TOOLS2 d3!d,BASIC.TOOLS3qd4!d%SEG.T YjKŸ/ Q.A2L4d5z d2!d"Q4> d2!7"Q5Dd2!e"Q6Id2!e'RENAMERN d3!e +RENAMER.PGM $u j!j,BASIC.TOOLS1E1a8d3!hIII.BSB.13IC.06u' *MENU.MAKER  K;DISKNAME.DATd0!z *INVOK.INFO pd1!e"Q1 d1!e"Q2& d2!e"Q3.m#im#iЛ#Lȱ  6L憦  Lsmm l y` @8(Je稽 ʈOLUME NAME (/DISKNAME) OR DEVICE NAME (.Dx)"P12);::"80C";a$;:Zb$="CHANGING DISKS"$d=23:=0::"80C";b$;::12).n=12:=20:"MAKE A NEW MENU FOR DISK: ";N$xN$)<2110=N$ :210 I=1L(A$(I),A$))200B$( NOT FOUND.)"X=11000:X:::210Z a$="{,|,~,}; selects; back 1 level; G$:::320H: Error Routine 202:U=11:"79C";"BAD PATH ERROR (NO DISK IN DISK DRIVE OR DESIRED FILE ,2))=0"12";џ,6);:ٟ;$П,2))=>12" PM-":" AM-" 1830WW=1530 =26:=21 1600 &:WW=1:0 :SEG=1;".D1/S EG.F" SEG=1".D1/SEG.G"diskname$=3802  CATCH PASCAL TEXT FILES "JUNE":1750M$="JULY":1750M$="AUGUST":1750M$="SEPTEMBER":1750M$="OCTOBER":1750M$="NOVEMBER":1750M$="DECEMBER":1750826);"-";M$;" ";Ѡ,2));", ";"19";Р,2);" ";/П,2))=>13П,2))-12;џ,6);:1780$~240:=24:=0:"@ ..... "DATE.TIME.LINE" ....JM=Ҡ,4,2))BTM1630,1640,1650,1660,1670,1680,1690,1700,1710,1720,1730,1740^M$="JANUARY":1750hM$="FEBRUARY":1750rM$="MARCH":1750|M$="APRIL":1750M$="MAY":1750M$=B$(I),"CAT 0")1140*B$(I),"FONT 0")18504B$(I),"FOTO 0")1930>B$(I),"PASTXT 0")2070H540R\A$="RUNNING "+B$(I),16,B)f"79C";A$;:=0pB$(I),16,B) z::SEG=1".D1/SEG.T"t=+B$(I),16,B) yCT=CT+1I=1:I=2I>2=-1:I=I-2:IBOTM<30THPOS=44I=IBOTM/2)*2:=+IBOTM/2)-1:0=+IBOTM/2-.5):I=IBOTM:I/2=I/2)I=I-1 œ2120B=B$(I),16)," ")-1 B$(I),"BASIC 0")850B$(I),"TEXT 0")890 81+LCA):::: RebootN=THPOS:B$(I);XA<8A>11540bA-7640,660,690,720l:=THPOS:B$(I);v:520: 500THPOS=4:I/2=I/2)I=I-1I=IBOTM THPOS=44:I/2<>I/2)I=I+1I13000Zha$="{,|,~,}; selects; to new disk; J/2)=4:=+1:ۙ=44B$(J);:J=J+1I:1,180,22:2,280,21:2,2380,23:8A$(1000),B$(1000),C%(511),C$(20),name$(20):=10:=0UCA=128:LCA=UCA+32CT=15 IF PREFIX$= PREFIX$+MID$(B$(I),112405l=ơ):: Routine to back up one directory level.a$=С,l-1) s=a$)a$=a$,s-1)a$,1)="/"5060:s=s-1 5030=a$240( MENU.MAKER 6.10 * Thanks to C.M.Davidson for his help! MENU.MAKER TEXT MODULESEG=0"MENU.MAKER"890&*X=11000: TEXT SLOW-DOWN LOOP ,X.1,180,22:2,280,21:2,2380,23:z:A$="LISTING "+B$(I),16,B)$=01:=0::"80C";A$;::12)>=23:=0::": Stephen J. Street When you do a PERFORM, Business Basic scans the statement from left to right (just like all BB statements). As BB encounters each parameter to be passed, it puts information on the stack. If the parameter is preceeded by a '@' (meanint one of the routines doesn't work correctly (CNV2STR appears to work but somehow messes up BB string storage leading to the dreaded "variable error"). Hope this helps, Steve 06-Sep-85 11:21:00 Subject: BUSINESS BASIC AND ASSEMBLY STUFF FromBB routines is not very extensive (I can live with that) and in some cases it is just wrong! (I tells you to load the input pointers into the wrong zero page locations - debugging this can really ruin your afternoon). 2) at leas it is possible to find the string data in storage without using the interpreter routines but they are fairly straightforward to use so there is no incentive to do it yourself. The only problems I've run into are: 1) the documentation for using the nts of a string, etc. You really need the BB interpreter to do this things for you since any time you change the length of a string, Basic may need (or want) to do a "garbage collect" to re-organize string space. If you are not going to change the length,appy to discuss techniques or any particular problems yu are having. The easiest (and only practical) way to get at Business Basic string data is to use the BB interpreter subroutines which will do things like point you to the string data, change the conteusing the sos calls themselves. I use these sos calls and find it very easy to program in assembly that way. Tim Harrington - From: Stephen J. Street Tim ... I've done some access to Business Basic string variables from assembly language and would be huch in your debt. I've dedicated many hours of tedious work in assembling on the ///. If you have any specific questions conserning it, then you can contact me through easyplex or this board. I've seen many assembly lang. routines for the ///, but none Subject: BUSINESS BASIC AND ASSEMBLY STUFF 29-Aug-85 From: Tim Harrington I've written many assembly language programs for use with BASIC. The only thing I haven't done is access BASIC's string variables. If anyone can help me with that I would be mPPT3.DEMO AND BASIC HELPSSK 79C";"PRESS ANY KEY TO HALT LISTING"::202 1020#2,B$(I),16,B)ž#242:::1160Z=1#2;A$:"78A";A$Z=Z+1:Z>1842:::Z=1980*:=23:=0::"79C";"CONTINUE...?":1C$:C$<>"Y"C$<>"y"C$<>"N"C$<>"n"10g an address pointer rather than the actual value are to be passed) then the address is put on the stack (low byte then high byte) and BB buts the X-byte value in memory. The X-byte for the first (leftmost) '@var' is stored at $16E9. The next one is at $16EB, etc. up through $16F7 (so the maximum '@vars' that can be passed in one PERFORM is 8). NOTES: 1) If you are passing a combination of '@' and other parameters that BB only stores the X-byte each time it encounters a '@var'. Thus a PERFOR !"#th a assembly routine that calls directly to SOS_OPEN and SOS_CLOSE. I found that if you opened and closed files more than twelve times in a row (a must for a multi-user accounting system I an writing) the program would bomb with an out of memory error? Title: How do I free up memory while running?- Created by: ED GOODING on: 11/19/1988 15:42:28 04/01/87 From: Frank W. Moore I found an interesting error while using Basic Extension the other day. Basic Extension (by FoxWare) opens and closes files wiINE$=31)P$=!::"=".PRO2/"#::,:E6=4:=10:"1. Shorten Pathnames Prior to Backing Up Your Files."I@=5:=10:"2. Lengthen Pathanmes To Original Size After Backing Up."2J=6:=10:"3. Exit This Program to Catalyst."8T=7:=10:Dd Program Name: Renamer By: Ed Gooding August 1985*x Go to Line 1000- for documentation.::QTY.DATAS=19::"QTY.DATAS.LESS.ONE=QTY.DATAS-1PATHNAMES$(QTY.DATAS,2)BEEP$=7)TURN.SCREEN.OFF$=14)CLEAR.END.Ler mis-information. I'm so used to unstacking and saving I had forgotten that BB setup zero page in addition to the X-Byte. Steve Q: [Q]uit and go back to the preceding menu R: Select a subject file and [R]ead it (or just enter its number). I: List an [I'm so used to unstacking and saving I had forgotten that BB setup zero page in addition to the X-Byte. Steve on the stack so you will have to at least do two PLA's for each address passed in order to prevent stack overflow problems. Sorry for the earliations. So your assembly module doesn't have to do this. HOWEVER, BB also puts the address on the stack so you will have to at least do two PLA's for each address passed in order to prevent stack overflow problems. Sorry for the earlier mis-information. is a little more complicated. Correction to my earlier message on passing parameters from Business Basic to an Invokeable module: Business Basic DOES store the 16 bit portion of parameters passed by address (ie. "@var") in the appropriate zero page locof the addresses you are passed you should be sure and check for these anomolies and adjust the X-byte and address appropriately. Hope this helps ..... Steve PPS: Passing parameters to/from EXFN and EXFN% routines is somewhat different and 4) BB is quite careful to set the X-byte and 16 bit addresses so that you won't run into any of the ///'s addressing anomolies that occur near the beginning and ends of switchable banks. However, if you want to go more than 255 bytes off thing you pull off the stack will be the return address (which you of course must save and reload before your RTS back to the Basic program). Next (in this case) would be the 16 bit address for variable 'E', then the value for 'D', etc.nsibility to unstack them and put them in the proper zero page locations. 3) When your assembler routine unstacks the information passed, it will be in 'reverse' order since the stack is managed in a last in first out manner. So the first M name (A,B,@C,D,@E) will result in the X-byte for '@C' stored at $16E9 and the X-byte for '@E' at $16EB. 2) BB does NOT store the corresponding 16 bit addresses at $00E8, $00E9, etc. These are passed through the stack and it is your respoWell, I have a 512K system and knew I had plenty of memory! Further investigation in the Basic manuals told me that if the file buffer area gets too full, an "out of memory" error would occur. Figuring that Basic Extension was not doing some important ml way by BASIC, I know how to get at it by address and by value -- BUT -- doesn't BASIC move strings around at will without having the courtesy of notifying me? In other words, if I save the address of variable X$ ONLY ONCE when my module is%'()*at's the difference in using EXFN (.FUNC) vs. PERFORM (.PROC)?? I know that EXFN returns a value, PERFORM does not and I know that using .FUNC adds two words of garbage to the stack... what else?? (2) once a variable has been defined in the norma Title: How do I use verbs for invokables? - Created by: ED GOODING on: 11/19/1988 15:40:03 From: Steven Brineaux Ok, guys, I've got a couple of questions RE: Business BASIC and assembly language modules, and I would appreciate any/all help: (1) wh+,= FRE statment clears up the problem, so 'stating mem= FRE:PERFORM mopen(@open.file$,@file.number%) solved everything. -Regards, Frank Q: [Q]uit and go back to the preceding menu R: Select a subject file aFrom: Frank W. Moore John, I have never had problems with the garbage collection in strings, although I do always force collection in several places in my programs just to speed things up. I was just unware this would happen with multiple file opens and cequently, and reassigned values to variables often. According to the Basic Manual, p. 243 item 7, old strings are not erased from memory when a new string is assigned to a variable. The X=FRE command is recommended to clean up accumulated "garbage". t free memory. You could also try and ask BASIC to release a chunk of memory first before calling the Open routines if there wasn't enough memory. - Tim From: John Lomartire I ran into the same thing with a Basic program that opened and closed files frgment first and used that as an IO Buffer, then your problems would be solved and you would still have the maximum number of files open. The problem with BASIC is that it requests all available memory on boot. SOS has to hunt around for little holes to gees up to the SOS maximum, and that is one of the reasons I am using it. From: Tim Harrington Frank, does the BASIC Extension open routines supply SOS with an IO buffer or does it make SOS look for one? If it did a request segment call to SOS for a 1K seemory cleanup, I added the statement MEM = FRE just before the PERFORM mopen (@open.file$) statement. The problem disappeared. I am not certain if this is a problem with the Basic OPEN# statement, but I think not. Basic Extension allows you to open fil first INVOKEd, there's no guarantee that the address I saved will still be the correct address for X$ throughout the rest of the program's execution, right? (3) is there a way to tell from assembly language whether the variable I'm handed is a real, an integer (%), or a long integer (&)?? I know that integers are handled HHLL by BASIC rather than LLHH -- is the same true for long integers as well?? Steven From: Erik Olbrys Steve: With functions, the value to be returned is zero out the typeahead buffer (a CONTROL call in REQUEST.INV), but I purely cannot get BASIC to accept any of my attempts to do so. Maybe some of the BB freaks on this board can help. Lurkers, the problem is that John has a BB program that needs only one--/0123456789:;" and "CR" and the machine took three moves to my one. When I did the same thing advertently, with machine going first, the program crashed on a subscript error in 2800. BASIC and the typeahead buffer are doing something strange together. I think you must Title: ? on GET, INPUT, ON KBD and their use - Created by: ED GOODING on: 11/19/1988 15:37:46 04/18/88 From: Al Bloom To: John Lomartire John Got your TICTACTOE 4.88 and 4.88a today. It has a problem. When I started the game, I inadvertently pressed "1CONTROL,1),PATHNAMES$(LOOP.CONTROL,0)XPATHNAMES$(LOOP.CONTROL,0)QbPATHNAMES$(LOOP.CONTROL,1);:=25:" =======> ";PATHNAMES$(LOOP.CONTROL,0)lLOOP.CONTROL9v::"Directory names have been restored and locked."=P$:::: N/ are now shortened for backup purposes."=P$::" Lengthen pathnames routine.::X=0QTY.DATAS.LESS.ONE Y=01PATHNAMES$(X,Y)&Y0X+:LOOP.CONTROL=QTY.DATAS.LESS.ONE0-1DTURN.SCREEN.OFF$;:NPATHNAMES$(LOOP.::! Shorten pathnames routine.::LOOP.CONTROL=1QTY.DATASTURN.SCREEN.OFF$;LONG.NAME$,SHORT.NAME$LONG.NAME$LONG.NAME$,SHORT.NAME$2LONG.NAME$;:=25:" =======> ";SHORT.NAME$LOOP.CONTROLA::"Directory names"4. Exit This Program to Business Basic."E^=9:=10:CLEAR.END.LINE$;:"Enter 1 - 4 To Select Function: ";hSELECTION:SELECTION*rSELECTION<1SELECTION>4BEEP$:350|SELECTION=3=P$:SELECTION=4=P$:SELECTION=2520 Eric, Thanks for the offer. I have sent you e-mail with my address. Yes, I do know 6502 assembly, so what you said makes sense. It's just that most of the examples I see for BASIC <-> 6502 communication are PROCEDURES, not FUNCTIONS>, so I was curiouteven Brineaux Eric, Thanks for the offer. Yes, I do know 6502 assembly, so what you said makes sense. It's just that most of the examples I see for BASIC <-> 6502 communication are PROCEDURES, not FUNCTIONS>, so I was curious. Thanks again. Steven.an integer is to be passed and the second "%" means "The integer variable named x". I don't know if you know 6502 assembly language so I don't know if any of this makes sense to you. --Erik P.S.: I also had lots of difficulty in the beginning. From: She variable. After computing, push the value to be returned onto the stack, push the return address and RTS. BASIC picks up the value and assigns to TEMP. To send a value (not address): temp=EXFN%.what(%x%) The first "%" within the parenthesis means that pushed onto the stack. Example: temp=EXFN%.what(@x%) This sample pushes the ADDRESS of x% onto the stack, the ML code picks up (in this order) the return address, two words of "stack bias" (to remain compatible with Pascal), and the address of tstroke responses. At my behest, he used GET to do so. As a result, if the user enters more than one key-press the program goes nuts. If it were a Pascal program, I'd turn off the typeahead buffer or flush the buffer before issuing a read. I can't figure out how to do that in Bus. Basic. Can any of y'all help? Al 04/19/88 From: John Lomartire To: Al Bloom Al, THANKS A LOT!!! Just when I thought I could put TICTACTOE away you had to jump up with your great news. Why did you hit the RETURN anyway? Folrom: Al Bloom John, I tried Rick Sidwell's suggestion, modified as follows: 50 PRINT "Press a key..." : OFF KBD : GET K$ : ON KBD GOSUB 9000 9000 ON KBD GOTO 9000 9010 RETURN I like it. It's elegant. It can blow in TICTACTOE statement 1520 on a bad subs1 to 9. Press a key";:get key$ 9040 return As I say, the above is inelegant, and it doesn't cover all bases. However, it should hold you until/unless one of our BASIC phreaques comes through with something better. Sorry 'bout the hassle. Al 04/22/88 F960 963 P%(MOV)=VAL(press$) This replacement is needed in 9 places -- 960, 1240, 1580, 1860, 2140, 2440, 2660, 2880, and 3160 Finally, insert the 9000 subroutine 9000 REM -- Key error message 9010 print 9020 print 9030 print "Selection must be place all statements of this format 960 HOME:PRINT"Your Selection? ";:GET press$ with the following statement group 960 HOME:PRINT"Your Selection? ";:GET press$ 961 IF press$<"1" THEN gosub 9000:GOTO 960 962 IF press$>"9" THEN gosub 9000:GOTO and I couldn't do better than the brute force procedure outlined below. It's inelegant, but it seems to get around the worst aspects of the problem. First, change all occurrences of 8152 to 9999 so the last statement is 9999 CLOSE:BYE:END Second, re need to play around with it a bit to make it work. Good luck. 04/21/88 From: Al Bloom John, stick with me and you're sure to get into trouble. I tried the REQUEST.INV control procedure and the d-control in the TOOL.CODE module that comes with EXERSOS,OTO 9000 9010 RETURN After the GET gets a character, the ON KBD statment calls the subroutine at 9000 each time you press a key. This subroutine reenables ON KBD, ignores the key pressed, and resumes normal processing. I've never tried this, so you maynternal buffer, and sets a flag to execute any ON KBD statement that might exist when the interpreter finishes the current statement. You might try playing with ON KBD a bit: 50 PRINT "Press a key..." : OFF KBD : GET K$ : ON KBD GOTO 9000 9000 ON KBD Go: John Lomartire John, I think that BBasic uses events to handle keystrokes, which is why the D_Control call doesn't work. In other words, the .CONSOLE driver calls a special routine in BBasic whenever you press a key--that routine puts the key into an ihe superfluous RETURN is erased? (Using GET (string) then VAL did not work.) From: Neil Shapiro Just an idea.... How about using the string functions to always take the first character in a string as the input? -- Neil 04/21/88 From: Rick Sidwell Tsic line that needs help: 900 PRINT "Your Selection? ";:GET P%(MOV) 920 IF (P%(2)=P%(1)) GOTO 900 940 (Another line) 960 (Another line) etc. Problems occur beyond line 920 when the user types a number key AND A RETURN. How can it be ensured that tall those GET lines (9 of them) to INPUT statements. That works OK. Thanks for spotting the weird behavior and maybe some SOS expert can give out some guidance on how to use D__CONTROL from Basic. For anyone that might want to help, this is the kind of Batypeahead buffer, there is supposed to be a way to make a D__CONTROL SOS call from Basic that will flush the buffer, but I am not smart enough to know how to do it. Until such time as I get a clue on how to do this, the only out is to go back to changing lowing up on what you said, I have verified that the game does have the bug that you mentioned. My attempts to get rid of it since your message were also to no avail if I insisted on staying with the GET command. If the problem is due to "widgets" in the cript error. I tried it (1) vanilla with GET P%(MOV), (2) with a statement following each GET branching back if P%(MOV) was less than 1 or greater than 9, and (3) with GET'ing a character string and checking it for validity before converting to an integer. On my second move (me going first), all I had to do was lean on the "2" key for statement 1520 to go south. Yes, it always blows in 1520. Doesn't happen on the brute-force kluge I sent yesterday. I don't know if Rick's method is flawed or if there ihelp. Regards.....Ed 04/09/1987 16:57:04 I figured out how to flush the buffer after reading both the STANDARD DEVICE DRIVERS MANUAL (The CONSOLE driver), and the documentation for the REQUEST.INV invokable. After some experimenting, I discovered that af=?@AB send control code 5 to the console driver. See page 67 of the Standard Device Drivers manual for the specifics, and refer to the general docs on D_Control Invokable in the Programming/Bus.Basic/Documentation section here. Get back to me if you need any 04/03/1987 10:53:03 Is there any way in Business Basic to flush the type-ahead buffer? I know one can do it in Pascal. --- John R. Bell 04/07/87 23:22:05 Hi John: To flush the type-ahead buffer, you need to use the Device Control Invokable module, and/I  N/B/I/BUS.BASIC,N/B/I/J% N/B/I/J/DOCUMENTATION,N/B/I/J/K&  N/B/I/J/SAMPLE.PROGS.1,N/B/I/J/L&* N/B/I/J/SAMPLE.PROGS.2,N/B/I/J/M4 N/B/I/ASSEM.6502,N/B/I/O%> N/B/I/O/DISASSEMBLIES,N/B/I/O/PH N/B/I/O/DRIVERS,N/B/I/O/Q%R N/B/I/O/APPLE.III.HELP,N/B N/B/SOFTWARE,N/B/C N/B/C/REVIEWS.1,N/B/C/D& N/B/C/D/DA.DATASYSTEMS,N/B/C/D/E* N/B/C/D/E/PRODUCT.INFO.1,N/B/C/D/E/F* N/B/C/D/E/PRODUCT.INFO.2,N/B/C/D/E/G& N/B/C/D/E/TECH.NOTES,N/B/C/D/E/H N/B/PROGRAMMING,N/Beystrokes. Al 04/28/88 13:02:38 John/Al/Rick/et al: See the file named FLUSH.TYPE.AHED in this section for info on how to use the D_Control invokable to flush the type-ahead buffer. Ed Gooding, Sysop go back to the preceding menu R: Select a subje 9500 9510 RETURN 9999 CLOSE:BYE:END John, I hope you're lurking. In addition to the "move" getting statements, you must also bracket every one of your other GET's with the "off kbd" and with "on kbd goto 9500" else the 9500 routine will intercept k press$>"9" THEN GOSUB 9000:GOTO 960 964 P%(MOV)=VAL(press$) 9000 REM -- Key error message 9010 PRINT 9020 PRINT 9030 PRINT"Selection must be 1 to 9. Press a key"; 9040 OFF KBD:GET key$:ON KBD GOTO 9500 9050 RETURN 9500 ON KBD GOTOls the world what a hotshot BASIC programmer I am, yes? Anyhoo, you are correct. The following code does the job admirably. 960 HOME:PRINT"Your Selection? ";:OFF KBD:GET press$:ON KBD GOTO 9500 962 IF press$<"1" THEN GOSUB 9000:GOTO 960 963 IFment--and there isn't anything there. Try using GOTO instead of GOSUB; if it still doesn't work, I'll be happy to take a look at it. Rick 04/26/88 From: Al Bloom To: Rick Sidwell Rick My humblest apologies. I thought your GOTO was a typo. It sort of telwell To: Al Bloom The problem might be the ON KBD GOSUB 9000 statement in line 50. ON KBD automatically does a "gosub" to the given statement(s); if you do another gosub, it's hard to say what will happen. The RETURN will return to after the GOSUB states something the program isn't trapping. I suspect the latter, but I can't for the life of me find what it is. Rick, would you be willing to guinea-pig John's program? I've gone as far with it as my limited skills will allow. Al 04/25/88 From: Rick Sidter you invoke the REQUEST.INV module, all you need do is assign two string variables and issue a CONTROL request. It looks like this: 10 INVOKE "REQUEST.INV" . . . 20 NAME$=".CONSOLE" 30 X$="" 40 PERFORM CONTROL (%5,@X$)NAME$ This will flush the buffer for you. Supposedly, using STATUS instead of a CONTROL will tell you how many keystrokes are in the buffer, but I could never make that work. The answer would be in X$, but I could never figure out what form it would take. The REQUEST.INV gives o=0:ELSE carrier=1 670 RETURN Hope this helps. Jeff Anderson P.S. The variable device$ must be assigned ".RS232" or whatever you call your serial RS232 driver. Weber Baker Jeff; Thanks. Can I use status (as in IF STATUS) as a variable since it is a f******** 615 buffer$="" 620 buffer$=CHR$(15):PERFORM status(%1,@buffer$)device$ 630 status=TEN(HEX$(ASC(MID$(buffer$,15,1)))) 640 IF status>=128 THEN status=status-128 650 IF status>=64 THEN status=status-64 660 IF status>=32 THEN carrierrse you must have included an INVOKE "request.inv" statement. 100 GOSUB 600:IF NOT carrier THEN 100 ... 600 REM **************************************** 605 REM * Check for Carrier * 610 REM ********************************test the value of the 14th byte. Its the only way I know to do bit tests in Bus. Basic. Regards......Ed From: Jeff Anderson Weber--Here is a Business Basic routine that uses the REQUEST.INV module to check the appropriate bit for carrier presence. Of cou then nobody's home, but if its a 0, then you've got your CD. Regards......Ed From: Weber Baker Ed; Thanks. I guess I wasn't clear, how do I get to bit 5? Do I have to test the value of the entire byte? Weber From: Ed Gooding Weber: yes, you'll have to CEFGated. Weber From: Ed Gooding Weber: Refer to pages 124-125 of your device driver's manual. Look at Status Code 1 (retrieve control params), and at byte 14 of the status buffer. Bit 5 will tell you whether you have a carrier detect or not. If bit 5 = 1, From: Weber Baker Can anyone tell me how to get the Request.inv module to look for a Carrier Detect from a modem? I know how to test for data in the buffer and how to do the controls etc, but I need to read the single carrier detect bit. Any help appreci. --- John R. Bell Q: [Q]uit and go back to the preceding menu R: Select a subject file and [R]ead it (or just enter its number). I: List an [I]ndex of the subjects under this topic ?: Repeat these commands Subject (Q,R,I,?) ->"y" THEN 200 420 IF A$="N" OR A$="n" THEN END 430 GOTO 400 500 REM Flush the Type-Ahead Buffer 510 NAME$=".CONSOLE" 520 X$="" 530 PERFORM CONTROL (%5,@X$)NAME$ 540 RETURN If anyone is able to get the STATUS option to work, I'd appreciate hearing about itile. Type anything you wish." 310 FOR I=1 TO 2000:NEXT I 320 IF A$="Y" THEN GOSUB 500 330 INPUT "Press RETURN. ";B$ 340 PRINT "You typed the following while I was idling." 350 PRINT B$ 360 PRINT:PRINT 400 INPUT "Do it again? (Y/N) ";A$ 410 IF A$="Y" OR A$= the same disk with this program. 100 INVOKE "REQUEST.INV" 200 INPUT "Flush Type-Ahead buffer this time? (Y/N) ";A$ 210 IF A$="Y" OR A$="y" THEN A$="Y":GOTO 300 220 IF A$="N" OR A$="n" THEN GOTO 300 230 GOTO 200 300 PRINT "The computer will idle for a whne a very interesting amount of control. One can actually prevent character echoing and disable the ESCAPE mode, etc. Below is a small program that illustrates the ability to flush the type ahead buffer. Just make sure that the REQUEST.INV module is onunction of the invokable? Weber Q: [Q]uit and go back to the preceding menu R: Select a subject file and [R]ead it (or just enter its number). I: List an [I]ndex of the subjects under this topic ?: Repeat these commands Subject (Q,R,I,?) -> Title: Program to print your screen contents - Created by: ED GOODING on: 11/19/1988 14:41:29 Subject: BUSINESS BASIC Screen Dump 03-Sep-85 From: Jeff Anderson A few days ago you expressed an interest in a screen dump capability from Business Basi"2. Lengthen Pathanmes To Original Size After Backing Up." 330 VPOS=6:HPOS=10:PRINT"3. Exit This Program to Catalyst." 340 VPOS=7:HPOS=10:PRINT"4. Exit This Program to Business Basic." 350 VPOS=9:HPOS=10:PRINT CLEAR.END.LINE$;:PRINT"Enter 1 - MOPQRSTUV 260 TURN.SCREEN.OFF$=CHR$(14) 270 CLEAR.END.LINE$=CHR$(31) 280 P$= PREFIX$ 289 :: 290 PREFIX$=".PRO2/" 291 :: 300 HOME:TEXT 310 VPOS=4:HPOS=10:PRINT"1. Shorten Pathnames Prior to Backing Up Your Files." 320 VPOS=5:HPOS=10:PRINT 100 REM Program Name: Renamer By: Ed Gooding August 1985 120 REM Go to Line 1000- for documentation. 139 :: 140 QTY.DATAS=19 141 :: 145 QTY.DATAS.LESS.ONE=QTY.DATAS-1 150 DIM PATHNAMES$(QTY.DATAS,2) 250 BEEP$=CHR$(7)y the use of multipleB levels of sub-directories so that they can then be F backed up using Pascal programs such as Sys. Utilities G and Backup ///, which have 64 character limits on path-  names.< MISC.TOPICS.1,N/B/I/O/R\ N/B/I/PASCAL,N/B/I/S&f N/B/I/S/SAMPLE.PROGS.1,N/B/I/S/T'p N/B/I/S/SAMPLE.PROGS.2,N/B/I/S/T2::J ------------------------------------------------------------------G Purpose: To shorten long pathnames created b Does take forever to print a screen with this - Dennis Jackson Q: [Q]uit and go back to the preceding menu R: Select a subject file and [R]ead it (or just enter its number). I: List an [I]ndex of the subjects under this topic ?: Repeat these commands SEXT 180 PRINT#3; 190 NEXT 200 PRINT#3;CHR$(12) 210 CLOSE#3 220 RETURN 300 FOR star=1 TO 80:PRINT"*";:NEXT:RETURN 04/14/1988 02:31:33 Does take forever to print a screen with this - Dennis Jackson :NEXT:RETURN 04/14/1988 02:31:3340) THEN GOSUB 100 55 TEXT:HOME:END 100 OPEN#3,printer$ 110 FOR vertical=1 TO 23 120 TEXT:VPOS=vertical 130 FOR horizontal=1 TO 80 140 HPOS=horizontal 150 PERFORM readc(@value%) 160 PRINT#3;CHR$(value%); 170 Nreadcrt.inv" 20 TEXT:HOME:VPOS=8 25 GOSUB 300 30 PRINT TAB(12);"To print this screen, press ";CHR$(127);"-p. "; 32 PRINT "Any other keypress ends demo." 35 GOSUB 300 40 GET answer$ 45 answer=ASC(answer$) 50 IF(answer=208 OR answer=2HJKc. While not the most efficient method, the following simple Basic program allows a screen dump and requires only the invokable module "READCRT.INV" from your Business Basic disk: 10 printer$=".printer":REM Enter printer driver name here 15 INVOKE"4 To Select Function: "; 360 GET SELECTION:PRINT SELECTION 370 IF SELECTION<1 OR SELECTION>4 THEN PRINT BEEP$:GOTO 350 380 PRINT 390 IF SELECTION=3 THEN PREFIX$=P$:BYE 400 IF SELECTION=4 THEN PREFIX$=P$:END 410 IF SELECTION=2 THEN GOTO 520 417 :: 418 REM Shorten pathnames routine. 419 :: 420 FOR LOOP.CONTROL=1 TO QTY.DATAS 430 PRINT TURN.SCREEN.OFF$; 440 READ LONG.NAME$,SHORT.NAME$ 450 UNLOCK LONG.NAME$ 460 RENAME LONG.NAME$,SHORT.NAME$ 470 PRINT LONGFunctions: 1- Shorten pathnames prior to backing up. 9 2- Lengthen pathnames after backing up.E 3- Exit program and return to Catalyst, or reboot. < 4- Exit program and enter Business Basic. * How to cuse preceding menu R: Select a subject file and [R]ead it (or just enter its number). I: List an [I]ndex of the subjects under this topic ?: Repeat these commands Subject (Q,R,I,?) ->2 REM 300/1200 baud, 7 or 8 bits, odd parity, full duplex 1023 REM 24 hours a day, 7 days a week, 365 days a year 1030 REM ------------------------------------------------------------------ ---------------------- Q: [Q]uit and go back to th number of DATA statements that you end up with. 1014 REM 3. Change the device prefix in line 290 to match the name of 1015 REM the device you are backing up. 1020 REM 1021 REM Compliments of ///'s Company 804-747-8752 102EM How to customize for your own use: 1010 REM 1. Modify my DATA statements to correspond to the pathnames 1011 REM in your system. 1012 REM 2. Change the assigned value in line 40, QTY.DATAS to equal 1013 REM the finalShorten pathnames prior to backing up. 1006 REM 2- Lengthen pathnames after backing up. 1007 REM 3- Exit program and return to Catalyst, or reboot. 1008 REM 4- Exit program and enter Business Basic. 1009 R of sub-directories so that they can then be 1002 REM backed up using Pascal programs such as Sys. Utilities 1003 REM and Backup ///, which have 64 character limits on path- 1004 REM names. 1005 REM Functions: 1- GS.1,N/B/I/S/T 880 DATA N/B/I/S/SAMPLE.PROGS.2,N/B/I/S/T2 998 :: 999 REM ------------------------------------------------------------------ 1000 REM Purpose: To shorten long pathnames created by the use of multiple 1001 REM levels/I/J/SAMPLE.PROGS.2,N/B/I/J/M 820 DATA N/B/I/ASSEM.6502,N/B/I/O 830 DATA N/B/I/O/DISASSEMBLIES,N/B/I/O/P 840 DATA N/B/I/O/DRIVERS,N/B/I/O/Q 850 DATA N/B/I/O/MISC.TOPICS.1,N/B/I/O/R 860 DATA N/B/I/PASCAL,N/B/I/S 870 DATA N/B/I/S/SAMPLE.PRON/B/C/D/E/PRODUCT.INFO.2,N/B/C/D/E/G 760 DATA N/B/C/D/E/TECH.NOTES,N/B/C/D/E/H 770 DATA N/B/PROGRAMMING,N/B/I 780 DATA N/B/I/BUS.BASIC,N/B/I/J 790 DATA N/B/I/J/DOCUMENTATION,N/B/I/J/K 800 DATA N/B/I/J/SAMPLE.PROGS.1,N/B/I/J/L 810 DATA N/B 640 PREFIX$=P$ 650 END 651 :: 652 :: 700 DATA N/APPLE.III.HELP,N/B 710 DATA N/B/SOFTWARE,N/B/C 720 DATA N/B/C/REVIEWS.1,N/B/C/D 730 DATA N/B/C/D/DA.DATASYSTEMS,N/B/C/D/E 740 DATA N/B/C/D/E/PRODUCT.INFO.1,N/B/C/D/E/F 750 DATA (LOOP.CONTROL,0) 600 LOCK PATHNAMES$(LOOP.CONTROL,0) 610 PRINT PATHNAMES$(LOOP.CONTROL,1);:HPOS=25:PRINT" =======> ";PATHNAMES$(LOOP.CONTROL,0) 620 NEXT LOOP.CONTROL 630 PRINT:PRINT:PRINT"Directory names have been restored and locked." X=0 TO QTY.DATAS.LESS.ONE 530 FOR Y=0 TO 1 540 READ PATHNAMES$(X,Y) 550 NEXT Y 560 NEXT X 570 FOR LOOP.CONTROL=QTY.DATAS.LESS.ONE TO 0 STEP-1 580 PRINT TURN.SCREEN.OFF$; 590 RENAME PATHNAMES$(LOOP.CONTROL,1),PATHNAMES$.NAME$;:HPOS=25:PRINT" =======> ";SHORT.NAME$ 480 NEXT LOOP.CONTROL 490 PRINT:PRINT:PRINT"Directory names are now shortened for backup purposes." 500 PREFIX$=P$ 510 END 511 :: 512 REM Lengthen pathnames routine. 513 :: 520 FORtomize for your own use: E 1. Modify my DATA statements to correspond to the pathnames in your system.F 2. Change the assigned value in line 40, QTY.DATAS to equal G the final number of DATA statements that you end up with. F 3. Change the device prefix in line 290 to match the name of+ the device you are backing up.8 Compliments of ///'s Company 804-747-8752< 300/1200 baud, 7 or 8 bits, odd parity, full duplex7 24 hou XREF --":PRINT:l=0:RETURN Q: [Q]uit and go back to the preceding menu R: Select a subject file and [R]ead it (or just enter its number). I: List an [I]ndex of the subjects under this topic ?: Repeat these commands Subject (Q,R,I,?) ->e):s=s+74:l=l+1:IF l=20 THEN GOSUB 670:GOTO 640 650 IF LEN(a$)-s>0 THEN HPOS=6:PRINT MID$(a$,s) 660 RETURN 670 VPOS=23:PRINT USING"76c";"-- press RETURN to continue --"; 680 GET a$ 690 IF ASC(a$)<>13 THEN 690 700 HOME:PRINT USING"76c";"--) 520 GOTO 20 530 PERFORM reseqnce(@i$,@o$,%low,%high,%start,%bump) 540 GOTO 20 620 IF LEN(a$)<80 THEN PRINT a$:l=l+1:RETURN 630 PRINT MID$(a$,1,80):s=80:e=74:l=l+1:IF l=20 THEN GOSUB 670 640 IF LEN(a$)-80=>74 THEN HPOS=6:PRINT MID$(a$,s,standard two's complement form. 490 low=TEN(HEX$(low)):high=TEN(HEX$(high)):start=TEN(HEX$(start )) 500 INPUT"Should I allow lines to be moved? ";a$:IF ASC(a$)=ASC("Y") OR ASC(a$)=ASC("y") THEN 530 510 PERFORM renum(@i$,@o$,%low,%high,%start,%bumprt=VAL(start$) 460 INPUT"What increment between each line? (Default=10) ";bump$:IF LEN(bump$)=0 THEN bump=10:GOTO 480 470 IF ASC(bump$)<48 OR ASC(bump$)>57 THEN VPOS= VPOS-1:GOTO 460:ELSE bump=VAL(bump$) 480 REM Map numbers larger than 32767 into ASC(high$)>57 THEN VPOS= VPOS-1:GOTO 420:ELSE high=VAL(high$) 440 INPUT"Starting value for the renumbered lines? (Default=10) ";start$:IF LEN(start$)=0 THEN start=10:GOTO 460 450 IF ASC(start$)<48 OR ASC(start$)>57 THEN VPOS= VPOS-1:GOTO 440:ELSE sta)=0 THEN low=0:GOTO 420 410 IF ASC(low$)<48 OR ASC(low$)>57 THEN VPOS= VPOS-1:GOTO 400:ELSE low=VAL(low$) 420 INPUT"What line number should I renumber up to? (Default=63999) ";high$:IF LEN(high$)=0 THEN high=63999:GOTO 440 430 IF ASC(high$)<48 OR EAD PASCAL TEXT FILES."04=10:"78C";"ANY KEY RETURNS TO THE MENU."!>G$:::".D1/MENU.MAKER",320R",220(204::"79A";""; 2D=1:F=1 <#4;a$ FD=D+1 P#5;a$ZD=60#5;12)dD=60D=1nF=F+1::d$;::Y=1100:Y x13402  CATCH PASCAL TEXT FILES 202 :F*=08:"78C";"SORRY BUT MENU.MAKER CAN'T R".D1/MENU.MAKER",220 d$="" A$="PRINTING "+B$(I),16,B)=01:=0::"80C";A$;:#3,B$(I),16,B)Z=1#3;b$:"78A";b$Z=Z+1:Z=18:1290 1260 #4,B$(I),16,B)#5,".PRINTER"+ž#4#5;12):::".D1/MENU.MAKE30C$="N"C$="n"1160;:=23:=0::"79C";"PRESS ANY KEY TO HALT LISTING": $1020.202 8::Z=1B::=23:=0::"79C";"WOULD YOU LIKE A PRINTED COPY?":1C$:C$<>"Y"C$<>"y"C$<>"N"C$<>"n"1170*C$="N"C$="n"Z[rs a day, 7 days a week, 365 days a yearI ------------------------------------------------------------------ NOTE: This article originally came from THREE CHEERS, an Apple /// Magazine on disk. Unfortunately, while the information is useful, the AIDA.TOOLS Invokable mentioned here was never included on disk. A PEEKPOKE Invokable are available in the WAP PD li into an array, you should never read more!). You could even put the names of various arrays into a string array, then assign DD$= ARRAY$(k), for example, or pass the array name into the subroutine as a parameter. There is a lot of flexibils%" bytes. The "count%" variable is returned after a read, containing the number of bytes actually read. The IF test after the read checks that this figure agrees with the number of bytes in the array (though you might want to read fewer bytes90 RETURN The RW variable controls reading or writing. DD$ is the important value passed to FILREAD or FILWRITE which tells it the name of the array to find in memory, and from the beginning (0th cell) of which to begin reading or writing "nbyteatafile%,filename$ 1060 IF RW THEN PERFORM FILWRITE(%datafile%,@DD$,%nbytes%) 1070 IF NOT RW THEN PERFORM FILREAD(%datafile%,@DD$,%nbytes%,@count%): IF nbytes%<>count% THEN PRINT "Err: Read file <> array length!" 1080 CLOSE#datafile% 10ine for array read/write. RW=0 to read, =1 to write 1010 PRINT RW$(RW); "ing array DD%" 1020 nbytes%= (N+1) * 2:REM 2 since integer array 1030 datafile%= filenumb: REM # of data file 1040 DD$= "DD%": REM name of array to transfer 1050 OPEN#d10 INVOKE"request.inv":REM at beginning of program 20 DIM RW$(1): RW$(0)= "Read": RW$(1)= "Writ" 100 filename$= "dataout": RW= 1: REM write data 110 GOSUB 1000 200 filename$= "datain" RW= 0: REM read data 210 GOSUB 1000 1000 REM Subroutthe file name, and the number of bytes to transfer. Let's assume you have an array DIMensioned as DD%(N) which contains data you want to save save to disk, then re-fill with other data on the disk. Here are the appropriate BB statements to do it: g of numeric data arrays. They are FILREAD and FILWRITE. FILREAD/FILWRITE do a read or save directly into/from a vector. The data are saved as a binary file on the disk. The PERFORM command tells the invokable the name of the array or vector, e from Applesoft to BB. The tricks add back some of the flexibility of Applesoft. 1: ARRAY HANDLING AND REQUEST.INV If you haven't already discovered it, REQUEST.INV, provided with BB, contains very useful routines for rapid reading and savinl features you need, but it lacks the flexibility provided by the openness of the ][. This article and attached programs recount some of the pitfalls we encountered and useful tricks devised in transferring a large statistical analysis packagn Matthews Action-Research NW BASIC COMPARISONS Most Apple /// Business BASIC users also work with Applesoft, either from earlier ][ days, or through emulation mode. Business BASIC (hereafter "BB") has all the professiona`bcdefghijklmnopqrstuvwxyz{|}brary from Disk 1022 (Basic XT from D.A. Datasystems). H a n d y T o o l s f o r B u s i n e s s B A S I C Text by Dave Lingwood Programs by Briaity here, and more importantly, a lot of SPEED. Data transfer is much faster than with INPUT/PRINT. 2: DIMENSIONS, STRINGS AND THE 256K /// A problem we bumped into almost immediately with the stat package was the limit on array size, and the rule about string arrays in BB that affects the 256K machine. Simply put: a. No numeric array can be longer than 64K b. Strings must be defined in the first 64K block of program memory. The first, while a pain, you can live with by caref create the needed "overlay" statements by peeking the counter, then BLOADing the module to that point -- after creating PEEK, POKE, BLOAD, and BSAVE, of course! First, let's describe those four new commands, which are useful in their own right. ginal "back end" of the program, so as not to overwrite the data. Brian began to dig around in memory, and added a lot to what we had previously known about reserved locations in BB. Once he found the statement pointer he was able to the Applesoft zero page locations containing the current line pointer -- in effect the one-line subroutine found its own address in memory. Then the code was BLOADed, the only trick being that each "module" so loaded must be shorter than the ori faster than would have been the case on the ][, but there just wasn't enough disk space for the program! Back to the drawing board. The way overlay worked on the ][ was to find the RAM address of one line of the program: a simple subroutine peeked Nov., 1980). The various command-specific program segments were saved as binary files, then BLOADed quickly right into the middle of the running program, which never knew what had hit it. When we converted to the ///, the improved CHAIN wasthat the common code has to exist in each chained program. That means longer read time and disk space wasted through duplication of that code. The ][ version already had solved this by inventing program overlay (see "Call-A.P.P.L.E.," fic code that is used depending on which command the user gives. The traditional way to handle this is to have a main "menu" program chain various separate programs depending on which command is given. The trouble with this is essary? The answer lies in the heart of our program design, and is related to disk space and speed. The AIDA statistical package consists of a chunk of common code that is always used to process commands, read and save data, etc., plus specins Errlist=16 " errlist+1--errlist+20 " error messages What a classic pain. But, it works. 3: BLOAD+BSAVE+PEEK+POKE = PROGRAM OVERLAY A heck of an equation. Why resurrect these commands we thought the superior design of the /// made unnecnd the "base" of each list. For example, if we had 10 commands, 6 options, and 20 error codes the master string array would look like this: Cmdlist=0 strings cmdlist+1--cmdlist+10 are commands Optlist=10 " optlist+1--optlist+6 " optiobles as the program wades through all the string arrays to find the numerics. The solution we came up with, though a bother, was to dimension just one string array, then store all the various command lists, etc., in it, using an offset variable to fi 21! Variable/memory error Again, it means you've accessed a string that crosses the block boundary on a 256K machine. It brings the program to a screeching halt! Once you know this, the cure is to dimension all the strings first. Uhg. Speed tum define your fast numeric arrays first; but if your numeric array is a full 64K in size, that would force any string arrays subsequently defined to cross into the second 64K block, generating an error that is not mentioned anywhere handy: Error codeul program design (especially with FILREAD/FILWRITE available). The second causes real speed problems if you have many string arrays. Being an interpreter, BB has to scan through the list of all arrays to find the one you want. Normally you'dLater we'll combine them into the form needed for program overlay. Peeking and Poking Peek and Poke are defined in the AIDA.TOOLS invokable. Both routines are set up to peek or poke one- or two-byte values, and to use the "extend byte" for the RAM banks. The syntax is: x = exfn%.peek(%address,%xtend,%length) PERFORM poke(%address,%xtend,@VALUE%,%length) where: address = address of low byte (0-65535) xtend = extend byte (0-3) length = 0 for one-byte, 1 for 2-byte %79,%0,%1): xtend%=exfn%.peek(%5712,%0,%0): addr%=addr%+exfn%.peek(%addr+1,%xtend,0): RETURN RUN Line 998 calculates the address of the line following it. The peek in line 810 reads the BB end of program pointer. Thus, each module will begin at ow line numbers 800 INPUT "MODULE NAME TO SAVE? ";A$: FILE$= "MODULE."+A$ 810 GOSUB 998: last%=exfn%.peek(%61,%0,%1): len%= last% - addr% 820 PERFORM bsave(@FILE$,%addr%,%xtend%,@len%) 830 PRINT FILE$;" contains ";len%;" bytes.": END 998 addr%=exfn%.peek(as a BB program. You may choose to write it following the common code to permit testing. When ready to save the module as a binary module, SAVE the program first, then EXEC the following text file: DEL 1, 998: REM Remember, modules can't have these lny other string function, such as MID$, could also be used. In our program, the common code runs through line number 997. Line 998 is the transition subroutine, and code just above that point does the actual overlay. Each proto-module is created string contents out of the program and into normal string storage. The approach below will do the latter: READ A$: TITLE$= A$ + "" B$= "This is a string" + "" The string concatenation forces BB to move the string out of the program area. Anction statements may be defined there, no ONERR or ONEOF statements may be defined or have their destination there, d) no common or module code may refer to any line number here after the first BLOAD, and c) any string assignments must force the ode will be overwritten with the binary modules successively BLOADed. There are a few other rules for writing the initialization code, based on the obvious fact that those lines of the program aren't going to be there later. They are: a) no fuam is first loaded and run, initialization or startup code is contained in the overlay area. This initialization code MUST be longer than any later module will be, even if you must pad it out with long REM statements. Later this initialization con't want to have to re-read (as with chain) extensive common code. The program must be laid out like this: Common code (low line numbers) Transition subroutine (finds its own RAM address) Overlay "module" (high line numbers) When the progrin the number of bytes actually read from the disk. All four of these commands are contained in the AIDA.TOOLS invokable described at the end of this article. Overlay This technique lets you break long programs into shorter pieces, where you dM bsave(@filename$,%address,%xtend,@savelength%) PERFORM bload(@filename$,%address,%xtend,@foundlength%) Before BSAVE the number of bytes to be written must be stored in the "savelentth%" variable. After a BLOAD this same variable will conta assumes that you know WHAT you're poking, and why. The list of zero-page and other BB locations found elsewhere on this disk provides valuable guidance. Bload and Bsave The syntax for these commands, set up as invokables, looks like this: PERFORyte) decimal in the "true" (xtend=0) zero page. The poke will poke the two-byte value contained in "VALUE%" into 61 and 62. This would add 512 bytes onto the BB end of program pointer (clobbering variables, by the way). Careful: poking in particular VALUE% = value to poke For example: VALUE%= exfn%.peek(%61,%0,%1) VALUE%= VALUE% + 512: PERFORM poke(%61,%0,@VALUE%,%1) The peek will set variable "VALUE%" equal to the two-byte data found at locations 61 (low byte) and 62 (high bthe line following 998, and the length written is (as calculated in variable "len%") the number of bytes between this point and the end of the program. In BB it does not matter (as it emphatically does in Applesoft) that the common code be in memory, and always of the same length, when the binary files are written or read. This is because BB uses relative next-line pointers. That is, each line of BB code begins with a two-byte pointer containing the number of bytes to add to the line p~. No longer will you have to split a large program into separate modules on disk. Array variablles are still limited to a maximum of 64K per any given array, but your program may now use more than 64K of memory. 2) There is a new reserved s Title: Info on the 1.23Ax version of Basic - Created by: SYSOP on: 11/19/1988 12:28:38 Differences between version 1.23Ax of Business Basic and previous versions: 1) A Business Basic program under version 1.23Ax may now use more than 64K of memoryws was one of the first Seattle /// devotees; and he is, as this disk goes to press (drive?), the proud holder of a new Computer Science B.S. from the U of Washington, which he is applying these days for the benefit of Motorola. omputing: a background in English and Journalism, PhD in Communication Research, and R & D work in technology transfer and marketing, before forming his own software/information service company. He is also Secretary of A.P.P.L.E.. Brian Matthe have provided AIDA.TOOLS for the individual use of our readers. Commercial rights are, however, reserved. /// /// /// Author Biographies: Dave Lingwood sports the checkered career typical of many in microcs space taken up by the program code. Try it. THE AIDA.TOOLS INVOKABLE The assembler source code for AIDA.TOOLS is found in another file on this disk. The ready-to-use invokable is in its own file elsewhere on this disk. Note that the authors.peek(%addr+1,%xtend,0): RETURN When ready to load a module, GOSUB 800 with A$ equal to the last portion of the module file's name. Then GOTO or GOSUB to the code in that module. In use, the modules load very quickly, and of course, there is much lese to load in a module is similar to that above: 800 PRINT"LOADING MODULE ";A$: FILE$= "MODULE."+A$ 810 GOSUB 998 820 PERFORM bload(@FILE$,%addr,%xtend,@len%) 830 RETURN 998 addr%=exfn%.peek(%79,%0,%1): xtend%=exfn%.peek(%5712,%0,%0): addr%=addr%+exfn%the user, BLOAD that module if it is not now present. The module code must follow the rules given for the initialization code, above: no embedded strings that are used outside of the module, and no lines or functions called by other modules. The codyou'll have to keep track of the beginning line numbers of each command, and use an ON k GOSUB ln1,ln2...,ln3 statement. Of course, you also have to know the name of the module in which each command was BSAVEd, and when a command is given by have been saved. It is a help if the actual execution code in each module begins with the same line number. The common code can then execute that module by a simple GOSUB 1000, or whatever. If more than one command is contained in a module, then ointer in order to find the next line. In Applesoft this pointer contains the absolute address of the next line. The happy result of this design improvement in BB is that you may modify the common code to your heart's content after the modulestring variable with the name PROGPREFIX$. It is a second prefix in the system and anytime you LOAD, SAVE, or CHAIN a Basic program, the system will use this prefix. This allows you to have a default prefix set for your data files, as well as aave not already read the sections in the Business BASIC reference manual on this subject, please do so before continuing with the rest of this document, as it assumes that you have read and understood that material. In addition the reader should be familie interface to assembly language procedures and numeric functions. This allows you to extend the capabilities of Business BASIC for any given application without requiring that it carry around all possible functions, thus saving memory space. If you h Title: Using 6502 invokables from Bus. Basic - Created by: ED GOODING on: 11/18/1988 14:53:01 APPLE /// BUSINESS BASIC AND ITS ASSEMBLY LANGUAGE INTERFACE INTRODUCTION The Business BASIC statements INVOKE and PERFORM give you an easy-to-usubject file and [R]ead it (or just enter its number). I: List an [I]ndex of the subjects under this topic ?: Repeat these commands Subject (Q,R,I,?) ->r user, will return you to the preceding program selector menu. 02/22/1987 00:04:06 That extra line in the catalog is simply a line-feed and does not screw up any line counts.... --Erik Olbrys: [Q]uit and go back to the preceding menu R: Select a susiness Basic, be aware of another new verb named BYE. This verb will invoke the SOS_Terminate call, which if you are booting from floppies will display the "INSERT SYSTEM DISK AND PRESS CONTROL-RESET" message, or if you are a Catalyst/Selecto regarding CATALOG...you can abbreviate this command to just CAT if you wish. 4) Apple also made some speed improvements and some minor bug fixes that they chose not to document. Also, if you are upgrading to this from version 1.0 of B from the heading. Because previous versions did not have this line, some programs which scan a directory for files may not work the same with this change. These programs may have to be modified to account for this extra blank line. AlsoE HELLO, its going to be saved in the "B" directory, not in the "A" directory as in previous releases of Business Basic. 3) Listing a directory (CATALOG'ing) is slightly different. There is a blank line separating the file namesGPREFIX$. For instance, if you have your data prefix set as PREFIX$=".PROFILE/A", and your program prefix set as PROGPREFIX$=".PROFILE/B", and you type CATALOG, you will get a listing of the "A" directory. If you type SAV default prefix set to the directory where your programs are stored. NOTE: Be careful in adapting any current software to use this new variable as the above operations do not work as they did before; they now use the new PROar with the Apple ][ or /// Pascal Assembler (ref: Chapter 2 of the Apple /// Pascal Program Preparation Tools manual). The INVOKE statement creates a procedure name table to be used by the PERFORM statement. This table provides the PERFORMable names for the assembly-language procedures and functions. It also contains the expected parameter word-count for validating the amount, but not the form, of the parameters passed. The lack of specific type validation implies that this facility can be misud memory including the relocation data and the interpreter tables. This document assumes that the reader understands the special enhanced indirect addressing of the Apple ///. The pointer addresses created by Business BASIC are always passed to invokCs within that module. Cross-module .REFs and .DEFs are NOT supported and their use will generate the INVOKE ERROR. All invoked modules will ALWAYS be found in bankable memory within a single bank. This limits invoked modules to 32K of total combineSIC. .ABSOLUTE, .ALIGN, .INTERP, .CONST, .PUBLIC, .PRIVATE and .ORG will generate the INVOKE ERROR if used. The .DEF and .REF assembler directives can be used within a SINGLE invokable module to allow routine sharing among multiple .PROCs and/or .FUN name given with these directives is the symbolic name that will be used by the PERFORM and EXFN statements to access the assembly code. Several directives in the Pascal Assembler CANNOT be used when creating invokable modules for use with Business BAreparation Tools manual for the description of the Pascal Linker. A single invokable module can contain any reasonable number of entry points. These are specified by using the .PROC directive for procedures and the .FUNC directive for functions. TheLinker' in the Apple /// Pascal system is NOT a linker that will combine a collection of assembler code files into a bigger linkage-edited code file. It is designed only to link assembler routines to Pascal programs. Please refer to the Pascal Program Pmodule is a relocatable assembly language code file (no Pascal routines are allowed!) produced by the Apple /// Pascal Assembler. The relocatable code file may not have been linked or in any way modified after generation by the Pascal Assembler: the 'on of the executable code image(s) of the module(s) for execution. 4. Building the procedure name table to allow symbolic access via the PERFORM statement or the EXFN functions. INVOKABLE MODULE DESCRIPTION An invokable NT The INVOKE statement accomplishes four (4) functions: 1. Deletion of all previously invoked modules and recovery of the memory used by those modules. 2. Loading one or more assembler modules from a storage volume. 3. Relocatibefore the JSR is executed. The four result bytes are not included in either the expected word count or verification process. Both EXFN and EXFN% functions push four bytes on the stack, even though EXFN% only returns a two byte result. THE INVOKE STATEMEs entered via a JSR instruction. THE EXFN FUNCTION CALLS The EXFN and EXFN% functions are almost identical to PERFORM, except that a function name must be found in the procedure name table, and four dummy result bytes must be pushed on the stack just ck. When this processing is complete, the procedure name table is then searched for the supplied name. When it is found, the stacked word count is checked against the count from the procedure name definition, and if they match then the invokable routine i the procedure that is expecting to receive an address. KA BOOM! THE PERFORM STATEMENT The PERFORM statement saves the name following the word PERFORM and begins processing the parameter list (if one exists) by pushing the parameter data on the stased with potentially fatal results for the entire application. An example of this might be passing an integer in place of an address parameter. Since these two parameters are the same size on the 6502 stack, the PERFORM statement will go ahead and executeed modules with the extend byte adjusted so that the high byte of the enhanced indirect address is in the range $02 through $81. This is done to avoid the anomalies that occur when ($00xx),Y or ($FFxx),Y addressing is attempted. Note that system interpreters are always assigned zero page and stack at address $1Axx and $1Bxx, and the registers that control this should never be modified by an invokable module. The expected-words parameter of the .PROC and .FUNC directives gives the number of WORDS order. REAL INTEGER% LONGINTEGER& @ADDRESS LSB LSB LSB ADRLO <--- top of stack MSB MSB . ADRHI MSB . EXP . cant) byte first. This is shown graphically for the four types of parameters. Note that expressions always have a real result pushed onto the stack. Note that the JSR return address is on the stack above the parameter data in the usual address low byte It is impossible for invoked code to bank switch while residing within bankable memory itself! Parameters are pushed on the stack high (or most significant) byte first; therefore the invoked code must pull parameters off the stack low (or least signifiirect addressing mode. This is the only means of access that will work because the assembly code of an executing invoked module must be selected as the current bank, but Business BASIC's data storage tables will most likely NOT be in that selected bank. . Thus the first occurrence of an @ parameter address will be found at $E8, $E9 and $16E9 whether it is itself the first or third or fifth parameter in the list. Note that all parameters that are passed by address MUST be accessed via the enhanced indF7. This allows you to set up and use extended addressing. When both the address and value modes of parameter passing are used in a single procedure or function call, this pointer stack is filled in order as the address (@) parameters are encounteredinterpreter 'extend page', $16xx. The PERFORM statement provides up to eight address pointers in zero page for use by any specific procedure or function. This 'pointer stack' begins at address $E8, $E9 and $16E9 and continues through $F6, $F7 and $16tatement with the @ character. This causes two actions by BASIC: The low two bytes of the enhanced indirect address are placed on the stack. The enhanced indirect address is also set up in the interpreter zero page and in the ameters are processed from left to right and pushed on the stack in that order, thus the last parameter in the argument list will be the first to be pulled off the stack. Parameters are passed by address by preceding the variable name in the PERFORM ssitional only, NOT symbolic and fixed length. PARAMETER DESCRIPTION AND CONVENTIONS The specific order and type of parameters chosen for an invokable module is up to you. You can also decide either to pass a parameter by address or by value. The par the sum specified in the .PROC or .FUNC as a word count. You can pass two reals in place of one long integer, or four integers for two reals, but this will inevitably give your assembly code a severe case of indigestion. Thus the parameter passing is po 4 Pass by Address @ 1* 2 * Extended Addresses are three bytes but only two are passed on the stack. The total word count of all expected parameters for any given entry point must be added together andAR WORD COUNT BYTE COUNT Short Integer % 1 2 Long Integer & 4 8 Floating-Point Number none 2 4 Numeric Expression none 2(NOT bytes) that will be passed by Business BASIC to the invokable module on the 6502 stack. This count is calculated using the word count table, below, for the various types of possible parameters that BASIC can pass. PARAMETER DESCRIPTION TYPE CH . . . MSB STRING PARAMETERS String parameters can only be passed by address and explicit string functions are not allowed. String processing can be done by passing string addresses and operating on strings in memory with the PERFORM statement. BASIC uses a three-byte descriptor for each string. The address passed by BASIC for a string parameter is actually the address of this three-byte descriptor, not a pointe used to create it. Temporary descriptors are stored in zero page by various routines. Temporary descriptors are exactly like variable descriptors and they must also be converted, with NOTNOW, if you need to reference the ASCII string data. INCPCOM peP copies the ASCII data into the string data pool, creates the associated null back pointer, and builds a temporary string descriptor for the data. If the DOPAR routine is used to evaluate a string expression, the string result is returned as if STRCP wasmust be deallocated. Deallocation involves changing the back pointer to indicate the size of the 'free memory' space that is being deallocated. BASIC has two routines, STRCP and INPCOM, that will perform these two tasks for an invokable module. STRCo the descriptor of the string variable and the back pointer, in the string data pool, can be set up to point to the variable's descriptor. Before the existing descriptor for an existing variable is replaced with the new one, the old string data area he descriptor always contains the relative offset. If you want to assign some ASCII data to a string variable, the ASCII data must be copied into BASIC's string data pool and a descriptor built for that data. Then the new descriptor can be copied int A descriptor can not be used directly to reference the string's data without first being converted into a pointer to the string data (the routine NOTNOW performs this conversion). When BASIC returns a pointer to a descriptor or a temporary descriptor, tpple /// Business BASIC. The difference between a 'pointer to a descriptor', a 'descriptor' and a 'pointer to the string data' must be clearly understood. The subroutines described later, such as PTRGET, normally return a pointer to a descriptor. e interpreter's internal subroutines that process strings and perform other functions. This work-saving interface, described in a later section, is the ONLY interface to the internals of the BASIC interpreter that will be supported in future releases of ASIC. This is necessarily so since either of these actions could require doing 'garbage collection' or compression on the string data pool to recover free memory for the new string. Business BASIC provides an interface that allows access to some of thcur within the first 64K of either the simple or array variable tables and the string data pool can't be larger than 64K. Trying to create new variables, particularly strings, or to change the length of a string involves the entire memory system of BArom the beginning of the simple variable table or the array variable table. The type byte normally specifies to which table the offset applies. Since the descriptor and the back pointer have 16-bit relative offsets, all the string descriptors must ocing the offset. More than just the content of a string is stored in the string data pool. It also contains a three-byte descriptor that points back to the string's descriptor. This back pointer consists of a type byte and an unsigned relative offset f string data. The offset is an unsigned number that is subtracted from the highest address for the string data pool to locate the beginning of the actual ASCII data. This offset is invalid when the length is zero, so the length must be checked before usr to the actual string data. A string descriptor consists of a length byte, followed by a relative offset. The length is an unsigned value with zero indicating that the string is null. The next two bytes are a relative offset to the beginning of therforms the assignment of your temporary descriptor to a variable's descriptor and deallocates the old one and fills in the null back pointer. Using strings in BASIC is complicated, and it is recommended that you clarify your understanding of how it all works by explaining it to another programmer. FUNCTIONS AND PASSING THEIR RESULTS BACK External functions in Business BASIC operate through the EXFN. and EXFN%. statements described below. EXFN is used to return real or floating point results anram calling the invoked module be prepared to properly handle such errors. SOS calls can be made directly to SOS from invoked procedures or functions. Doing so can be very useful and likewise very dangerous: Business BASIC may have files open, memory the requested routine, and then reverses the bank switch and returns to the invoked module. Most, if not all, of the routines that can be used within the interpreter can take error exits and not return to the caller. This requires that the BASIC progiately preceding the routine number. Invokable modules will normally reside in a bank other than the one containing the desired routine, so direct access of the interpreter is impossible in any case. DISPATCH performs the necessary bank switch, callsles. The call interface consists of a routine number, and a fixed address entry point, within the interpreter's zero page. The routine number is stored into location $E7 and a JSR to DISPATCH is then executed. DISPATCH is located at $E4 in zero page, immedy designed to maintain the independence of code within the interpreter and the invokable modules while allowing access to the interpreter. This should allow the interpreter to be modified and ugraded in the future without modifying existing invokable moduis purpose and it is the ONLY interface that will be supported in future releases of the BASIC interpreter. Use of any other information or interface linkages may be invalid upon the next release of Business BASIC. This interface has been specificall 88 00 00 00 INTERFACING WITH THE BASIC INTERPRETER Invokable modules used to extend the Business BASIC language commonly will need to access some internal subroutines within the interpreter. A special interface is provided for th .999999 80 7F FF F7 0 00 xx xx xx (xx = 0 for literal assignment) 1 81 00 00 00 4 83 00 00 00 17 85 08 00 00 128 NUMERIC PACKED REAL (HEX) VALUE EXPN MSB ... LSB ------------------------------------ .0078125 7A 00 00 00 .25 7F 00 00 00 .5 80 00 00 00 han 129 the number is less than 1, except that a zero exponent defines a zero result although the bytes of the mantissa may not be assumed to be zero (i.e. they may be non-zero even though the number is zero). Some examples are shown below for clarity. result is a normalized 24-bit mantissa with an assumed most significant one bit which is replaced by the mantissa sign bit and an excess 128 signed exponent. When the mantissa sign bit is set or 1, the mantissa is negative and when the exponent is less tust be pushed on the stack in the sam manner as they are passed, i.e. with LSB on top of stack just below the return address. The integer result is a signed two's-complement integer with the sign bit taken as bit 7 (MSBit) of the high byte. The realunction routine pull off four dummy bytes before pulling off any parameter bytes. These four bytes contain meaningless data and must be ignored. Both types of functions push four bytes even though the EXFN% type only returns two bytes. The results md EXFN% is used to return integer results. The EXFN and EXFN% functions return their results on the 6502 stack. To be compatible with Apple /// Pascal, BASIC pushes four dummy bytes on the stack after each parameter. This requires that your external f allocated, events armed, etc. and doing anything to undermine the assumed state of these things will not be reflected in the status information being maintained by BASIC. Creating conflicts of this type could have disastrous results when BASIC acts on its incorrect information. This does not preclude making SOS calls, but some reasonable care should be given in selecting what an invokable module does directly with the operating system. Below is a summary list of the routines currently accessible thr an invoked module, it must be preserved if routines that modify it are going to be used. An example of this is the OPENIT routine for opening a file that must have TXTPTR modified to point to the pathname to be opened. If the existing TXTPTR (all th Some of the routines that can be called by the DISPATCH interface will modify the TXTPTR that is normally pointing at the end of the PERFORM or EXFN parameter list. Since this pointer is the means of continuing with the program after returning froment) and this is used to call the proper routines to execute each statement. Each statement routine performs the necessary syntax checking each time a statement is executed. TXTPTR's position determines what line and statement of the program is executing.cessing, syntax checking or conversions are performed until statement execution occurs. BASIC scans the tokenized form of a statement byte by byte using its 'program pointer' referred to as TXTPTR. All statements begin with a token (except the LET statemto modify or delete these undocumented entry points without notice and at any time, anyone using them does so at their own risk. Business BASIC is a tokenizing interpreter that compresses, upon program entry, keywords to one byte tokens. No other proC. CVT2STR 44 Converts FAC into a string and returns descriptor in FAC. The other obviously undocumented values in this list do exist, but are not usable without intimate knowledge of the interpreter internals. Apple Computer reserves the right tring descriptor pointing to it. INPCOM 34 Assigns a string (ptr in FAC) to a string variable at VARPNT. LETP2 35 Assigns a value in FAC to a variable of any type at VARPNT. INT 39 Returns real in FAC of the integer portion of real in FA FIN 27 Converts ASCII data at TXTPTR into floating numeric in FAC. DATAN 32 Moves TXTPTR to the end of the current tokenized statement. STRCP 33 Copies your string data at STRNG1 into string pool and builds a temporary s up string descriptor and string space at pointer in FAC. OPENIT 22 Open the filename at TXTPTR if it is of file type in X. GIVAYF 25 Convert A-Y integer and return real in FAC. POSINT 26 Rounds a real and makes it a positive integer in FAC.turns. SERROR 15 Raises if possible the BASIC error matching the SOS error in A. SCRUNCH 16 Requests BASIC to free up A pages of unused memory to SOS. EXPAND 17 Inverse of SCRUNCH (16). Expand memory for BASIC by A pages. FRECNOW 20 Free 10 Same as #9 above but search starts at beginning of program. NOTNOW 13 Given a pointer to a string descriptor return string data pointer and the length in A. ERROR 14 Raises the BASIC error condition given in X. Never re TXTPTR into a binary integer. GOTOB 7 Returns TXTPTR at the line in LINNUM if existent, else error. GETADR 8 Rounds real in FAC to a 16-bit address in POKER, POKER+1. FNDLNCO 9 Search forward from Y-X-A for line number >= LINNUM. FNDLIN ------ DOPAR 0 Evaluate an expression, return type and result. PTRGET 1 Find, in the variable tables, the variable at TXTPTR. ERRDIR 5 Returns if a program is running, else ILLEGAL DIRECT error. LINGET 6 Converts the line number atough the DISPATCH interface. Any suggestions for additions to this list should be submitted in writing to Apple Computer PCSD Software Technical Support. NAME # DESCRIPTION ------------------------------------------------------------------------ree bytes remember) isn't saved and restored BASIC will attempt to continue executing your program from the data at the end of the pathname, where OPENIT probably left TXTPTR, when you RTS back to BASIC. Business BASIC implements the TXTPTR as a subroutine that resides in zero page. This subroutine has two entry points, CHRGET and CHRGOT. This routine is very useful for syntaxing tokenized ASCII data. CHRGET (JSR $B5) gets the next sequential non-space character or token from the data at TXTPTR ($BC)criptor' for your string data (possibly read from a storage volume). These temporary descriptors must be released with FRECNOW before returning to BASIC if they are used by an invoked module. The temporary descriptor stack is located in zero page and so SGN and the 'implied' most significant mantissa bit must be set on in FACMSB. Pointers to string descriptors left in FACMO, FACLO and FACMOXB may or may not be enhanced indirect addressing pointers. Routine #33 (STRCP) creates a 'temporary string desults that are returned by an EXFN routine, the 'packed' format of BASIC real numbers was described. The unpacked format of reals in the FAC is the same except for the mantissa sign bit. It must be removed from bit 7 of FACMSB and placed in bit 7 of FACfloating point routines but is not stored in the storage tables after computations. This extended precision at compute time minimizes most of the anomalies usually associated with floating point numerics. In the previous description of floating point res ; fp LI SI STR-PTR + FACMOXB 006E: FACSGN .EQU FAC+5 ; FP LI 006F: FACX1 .EQU FAC+6 ; LI 0070: FACX2 .EQU FAC+7 ; LI 166D: FACMOXB .EQU FACMO+EXTPAGE ;address of string x-byte The FACLO location is used by the to offset to x-byte from pointer 0069: FAC .EQU 69 0069: FACEXP .EQU FAC+0 ; FP LI 006A: FACMSB .EQU FAC+1 ; FP LI 006B: FACMMB .EQU FAC+2 ; FP LI 006C: FACMO .EQU FAC+3 ; FP LI SI STR-PTR 006D: FACLO .EQU FAC+4d for real or floating point data, those with the LI comment are used as long integer data, SI for short integer and STR-PTR for pointers to string descriptors. GENERAL PURPOSE FLOATING POINT ACCUMULATOR FIELDS: 1601: EXTPAGE .EQU 1601 ;add 1 rposes. These purposes are varied, but the normal ones relevant to using the internal routines are input arguments and output results. These come in four types that use different parts of the FAC as shown below. The locations with the FP comment are use use these routines you must have a COMPLETE understanding of this Apple /// addressing mode. BASIC defines a floating point accumulator, known as the FAC in the above descriptions. This ten-byte area in zero page, starting at $69, is used for many puIC goes to considerable effort to maintain the high byte of these pointers in the range $02 through $81 to prevent enhanced indirect addressing anomalies from messing up and crashing the system. Before you begin writing invokable modules that are going toot change the TXTPTR since CHRGET will never leave TXTPTR pointing to a space. Many of the pointers available are really three-byte enhanced indirect addressing pointers and should always be treated as such regardless of actual content. Business BASe ($20), otherwise the next non-space character and thus does the same things as CHRGET except that the TXTPTR is not incremented before fetching the character. CHRGOT is normally only used after a call to CHRGET, and if this is always true, CHRGOT will n is reset (BNE) otherwise. Carry: is clear (BCC) if the character is an ASCII digit. is set (BCS) otherwise (i.e. not an ASCII digit). CHRGOT returns the current character at TXTPTR if it is not a spac. Upon return from CHRGET th A-register contains the character or token and the 6502 status flags are set as follows: Z-flag: is set (BEQ) if the character is a colon ($3A) or a line terminator ($00). a pointer in the FAC left by STRCP will not actually be an enhanced indirect pointer, but just to simplify invokable code, you should always handle these pointers as three-bytes. USEFUL BUSINESS BASIC ZERO PAGE VARIABLE EQUATES These zero page equates are not likely to need to change, but they might at some future release of Business BASIC. Please be sure all references to these locations are done with equates so that invokable modules could easily be re-assembled if changes are required later. ApNTRY: None. ON RETURN: In deferred mode, i.e. executing a BASIC program. ERROR EXITS: If in direct mode, the ILLEGAL DIRECT ERROR message is printed to the console. Control returns to direct mode. ROUTINE NAME: LINGET ERROR EXITS: Since array subscripts can be expressions most of the DOPAR error exits could be taken. ROUTINE NAME: ERRDIR NUMBER: 5 DESCRIPTION: Validates that a program is executing and returns. ON E REAL (unpacked) | $00 | $00 | FACEXP-FACSGN LONG INTEGER | $40 | $00 | FAC-FAC+7 STRING | $FF | $00 | POINTER IN FACMO,FACLO,FACMOXB SHORT INTEGER | $00 | $80 | FACMO,FACLO VALTYP and INTFLG determine the variable's type. ISARRAY will be $00 if a simple variable, $80 if array element. VARIABLE TYPE | VALTYP | INTFLG | RESULT MSB FIRST ----------------------------------------------------- ced in VARPNT. This routine calls DOPAR to evaluate array subscripts. DOPAR calls PTRGET to locate variables (note the recursion). ON ENTRY: TXTPTR points to the variable to be referenced. ON RETURN: VARPNT points to the variable's value. NUMBER: 1 DESCRIPTION: PTRGET searches the variable storage tables for a variable and returns the address of a variable. The variable name pointed to by the current TXTPTR is found or created in memory and a pointer to its value is pla can occur. TYPE MISMATCH, SYNTAX ERROR, BAD SUBSCRIPT, OVERFLOW, STACK OVERFLOW, REDIM'D ARRAY, DIVISION BY ZERO, STRING TOO LONG, FORMULA TOO COMPLEX, UNDEF'D FUNCTION, etc. ROUTINE NAME: PTRGET ssion to be evaluated. VALTYP = requested type of expression - $20 means either type ok. ON RETURN: FAC contains the result. TXTPTR points to the terminator and VALTYP set to type found. ERROR EXITS: Many ----------------------------------------------- REAL (unpacked) | $00 | FACEXP-FACSGN LONG INTEGER | $40 | FAC-FAC+7 STRING | $FF | POINTER IN FACMO,FACLO,FACMOXB ON ENTRY: TXTPTR points to the expreed only real or string can be the result. Short integers will always be returned as a real, use POSINT (#26) to convert real to short integer. The results are left in the FAC in the following format: EXPRESSION TYPE | VALTYP | RESULT MSB FIRST in a real result, any other type will exit with TYPE MISMATCH error. If string type is requested then a string expression is the only acceptable result. The only way to get long integer as a result is to request that type. If the any type ($20) is requesto BASIC when using DOPAR. New variables or arrays will be allocated if encountered during expression evaluation. VALTYP must be set from the values in the table below. If VALTYP is set to request real data then any numeric expression will result R evaluates (as an expression) the tokenized ASCII data found at the current TXTPTR. The ASCII data must be terminated by a colon or an EOL ($00). Most of the errors that can be generated by invalid expressions in BASIC will cause an error exit back intple Computer has every reason to maintain a stable interface for invokable modules, but the internals of the interpreter are subject to change and improvement. ROUTINE NAME: DOPAR NUMBER: 0 DESCRIPTION: DOPA NUMBER: 6 DESCRIPTION: Converts the ASCII line number pointed to by TXTPTR into a 16-bit integer in LINNUM, stored low-high. The entry requirements are met by loading the A-register via CHRGET or CHRGOT. LINGET will only accept unsigned integers in the range 0 -> 63999. There must be a non-digit following the valid digits. LINGET will stop on the first non-digit it ncounters and return the accumulated result. Leading spaces or zeros will be ignored. ON ENTRY: TXTPTR points to the error handler. Otherwise the error message is printed and control is returned to direct mode. This routine resets the stack and never returns. ON ENTRY: X-register = BASIC error code. ON RETURN: Never returns. ERROR EXITS: [ed note: no informationupplied by Apple] ROUTINE NAME: ERROR NUMBER: 14 DESCRIPTION: Raises the BASIC error condition given in the X-register. If ON ERR is in effect and execution is deferred mode then control is transferred to the INDEXB. ON ENTRY: INDEX points to a string descriptor. ON RETURN: INDEX points to the string data. A-register = length of string. Destroys A,X,Y registers. Preserves status register. ERROR EXITS: [ed note: no information s NUMBER: 13 DESCRIPTION: Given a pointer in INDEX, INDEX+1, and INDEXB to a string descriptor this routine leaves the string length in the A-register and a pointer to the actual string data in INDEX, INDEX+1, and NUMBER: 10 DESCRIPTION: Same as FNDLNCO except the search always starts with the beginning of the program. ON ENTRY: LINNUM contains line number to search for in the program. ON RETURN: See FNDLNCO. ERROR EXITS: None. ROUTINE NAME: NOTNOW existing line. ON RETURN: LOWTR is pointer to the first line whose number is >= LINNUM. Carry is set if matching line found, carry clear otherwise. ERROR EXITS: None. ROUTINE NAME: FNDLIN ue greater than or equal to LINNUM. ON ENTRY: LINNUM contains the line number to search for in program. The Y-X-A registers contain the extend-high-low beginning search address pointer and must point to the link byte of anCE - PART 2 of 3 ROUTINE NAME: FNDLNCO NUMBER: 9 DESCRIPTION: Searches through the BASIC program for the line number given in LINNUM. LOWTR is set to point at the link byte of the first line encountered with valess rounded to 16-bit integer, stored low-high. FAC contents destroyed. ERROR EXIT: ILLEGAL QUANTITY error exit will occur if the real is outside the range 0 -> 65535. APPLE /// BUSINESS BASIC AND ITS ASSEMBLY LANGUAGE INTERFA NUMBER: 8 DESCRIPTION: Rounds an unpacked real in the FAC to a 16-bit address (range 0-65535) in POKER, POKER+1 stored low-high. ON ENTRY: FAC contains address as a real with an exponent <2**16. ON RETURN: POKER contains addr is the line number to locate. ON RETURN: Sets TXTPTR to point to the end-of-line token (0) preceding the desired line. ERROR EXITS: The UNDEFINED STATEMENT error exit is taken if LINNUM is non-existent. ROUTINE NAME: GETADR NUMBER: 7 DESCRIPTION: Searches the resident BASIC program for line number given by LINNUM, LINNUM+1. Searches forward in the program if CURLIN is less than LINNUM, otherwise searches the program from the beginning. ON ENTRY: LINNUM non-digit. Uses location INDEX for scratch. ERROR EXITS: SYNTAX ERROR will result if a number >63999 is input. LINGET will only zero LINNUM, LINNUM+1 if carry is clear on entry. ROUTINE NAME: GOTOB first ASCII digit of the line number. A-register contains first ASCII digit of the line number. Carry must be set. ON RETURN: LINNUM, LINNUM+1 is the 16-bit equivalent, low-high. TXTPTR will point to the terminating supplied by Apple] ROUTINE NAME: SERROR NUMBER: 15 DESCRIPTION: Translate the SOS errors shown below to the corresponding BASIC error if in the table, otherwise issues SOS CALL ERROR #22. ON ENTRY: A-register is SOS return code. ON RETURN: Never returns. ERROR EXITS: [ed note: no information supplied by Apple SOS ERROR | BASIC # | BASIC ERROR MESSAGE ------------------------------------------- $10 | 30 | FILE NOT FOUND er. Opening a non-block device file must be done with TXTTYP ($04) as the file type, otherwise a TYPE MISMATCH error will occur. The file that is opened is only 'open' in SOS. It is NOT one of the ten BASIC files and is NOT accessible from the calling proT NUMBER: 22 DESCRIPTION: Evaluates a pathname and opens the file. TXTPTR points to a path name or string expression. The file is created if A-register <> 1 and is checked to be of the type indicated by X-registFACMO points to string's descriptor. ON RETURN: Descriptor if it was a temporary descriptor. ERROR EXITS: This routine should not take any error exits, but using it incorrectly could step on memory almost anywhere. ROUTINE NAME: OPENIe if the string result is not going to be assigned to a string variable. FACMO, FACMO+1, FACMOXB must point to the descriptor when this routine is called. This routine should be called after using STRCP to allocate a temporary work string. ON ENTRY: from SOS then the OUT OF MEMORY ERROR error exit is taken. ROUTINE NAME: FRECNOW NUMBER: 20 DESCRIPTION: If you evaluate a string expression the temporary string descriptor and string space must be freed after usegister = number of pages to expand memory. If A-register = 0 then expand to maximum available. ON RETURN: Memory now reclaimed, or an error flagged. ERROR EXITS: If A-register <> zero and BASIC can't allocate any free memory eased. ROUTINE NAME: EXPAND NUMBER: 17 DESCRIPTION: Inverse of SCRUNCH. Requests BASIC to expand its memory space by A-register pages. If A-register = zero then expand to all available memory. ON ENTRY: A-rmber of pages to release. If A-register = 0 then release as much as possible. ON RETURN: Memory now available through SOS memory management calls. ERROR EXITS: The OUT OF MEMORY ERROR exit will be taken if no memory can be rely from its unused memory space, A-register pages of memory. This memory is then freed for allocation by using SOS memory management calls. Requesting 'zero' pages asks BASIC to release all available unused memory back to SOS. ON ENTRY: A-register = nu $54 | 07 | OUT OF MEMORY $57 | 40 | DUPLICATE VOLUME $58 | 16 | TYPE MISMATCH ROUTINE NAME: SCRUNCH NUMBER: 16 DESCRIPTION: Requests BASIC to release back to SOS, memor $4D | 26 | CRC ERROR $4E | 35 | FILE LOCKED $50 | 23 | FILES BUSY $51 | 24 | NOT SOS $52 | 24 | NOT SOS $46 | 30 | FILE NOT FOUND $47 | 33 | DUPLICATE FILE $48 | 34 | DISK FULL $49 | 39 | DIRECTORY FULL SK SWITCHED $40 | 29 | BAD PATH $43 | 36 | FILE NOT OPEN $44 | 31 | PATH NOT FOUND $45 | 32 | VOLUME NOT FOUND $25 | 38 | RESOURCE UNAVAILABLE $27 | 25 | I/O ERROR $28 | 37 | DEVICE DISCONNECTED $2B | 27 | WRITE PROTECTED $2E | 28 | DIgram. In addition, issuing a global CLOSE (no filename) in BASIC will NOT close the file, since BASIC does not issue a global close command to SOS. Thus, opening a file with OPENIT and then taking an error exit back into the BASIC program could, result in a file being left permanently open if proper error processing is not present. A separate perform entry point just to close such a file is needed to allow the calling program to clean up after an error with the file still open. ON ENTRY: A-register = 3 DESCRIPTION: This routine copies ASCII data into BASIC's string data pool and builds a temporary string descriptor pointing to the data. This routine creates the data part of what BASIC calls a string, but it is a temporary one and not assigned to any vut TXTPTR. ERRORS: This routine will loop forever if a $00 or a $3A does not exist within 256 bytes of the input TXTPTR. DATAN does not use CHRGET. ROUTINE NAME: STRCP NUMBER: 3rrent statement. Stops when it finds the end-of-line token ($00) or a statement seperator colon. ON ENTRY: TXTPTR points inside a statement. ON RETURN: Y-register contains the byte offset to the end of a statement from the unchanged inp range of floating-point numbers. If ANYNUM <> 0 then the string was not really a number. ROUTINE NAME: DATAN NUMBER: 32 DESCRIPTION: Searches forward in the program for the end of the cu unpacked binary real. VALTYP = 0. ANYNUM (location $0D) will be $FF if no digits were encountered and $00 if one of more digits were encountered. ERROR EXITS: The OVERFLOW ERROR exit can occur, see BB Manuals for the valid a non-floating-point number terminator character to end the string. Floating-point characters include the ten digits, period, plus, minus and the letter E. ON ENTRY: TXTPTR points to ASCII representation of a real number. ON RETURN: FAC contains thee in the FACEXP-FACSGN. FIN will only process ten digits after the decimal point, but will skip TXTPTR over digits in excess of ten. FIN will always leave TXTPTR pointing to the first non-floating-point number character that it encounters. There must be ults if the real is outside the range for a 16-bit signed integer. ROUTINE NAME: FIN NUMBER: 27 DESCRIPTION: Converts the ASCII string, pointed to by TXTPTR, into its unpacked floating point valueal and makes it a positive integer. ON ENTRY: FACEXP-FACSGN contains the value as an unpacked real. ON RETURN: FACMO, FACLO contains high-low 16-bit value if the real was in the range 0-32767. ERROR EXITS: The ILLEGAL QUANTITY error resENTRY: A-Y is high-low signed 16-bit integer. ON RETURN: FAC is real with the same value. VALTYP = 0. ERROR EXITS: OVERFLOW error should NEVER occur. ROUTINE NAME: POSINT NUMBER: 26 DESCRIPTION: Rounds a r NUMBER: 25 DESCRIPTION: Converts the A-Y registers, input as a high-low signed 16-bit number, into an unpacked real in FACEXP-FACSGN. This is usually known as a FLOAT function, but is not explicitly available as such in Business BASIC. ON f requested type. (b) If OPEN returns error $54 (out of memory) OPENIT will call the SCRUNCH routine (#16) to free up four pages and retry the OPEN call. ROUTINE NAME: GIVAYF the GET-FILE-INFO, OPEN, and CREATE (if A-register <> 1) SOS calls with the following exceptions: (a) GET-FILE-INFO error $58 (not block device) always is handled by trying to OPEN with file type of TXTTYP, regardless o1 requests NOT to create the file if it is non-existent. X-register = SOS file type. TXTPTR points to the pathname. ON RETURN: A-register = SOS reference number. ERROR EXITS: All of the error exits forariable. If this temporary string is not to be assigned to a variable (use INPCOM for that) then it must be freed up after being used, by the FRECNOW routine (#20). ON ENTRY: Y-register = length of string. STRNG1, STRNG1+1, STRNG1XB is a pointer to the data to be copied. ON RETURN: A temporary string descriptor is build and pointed to be FACMO, FACMO+1, FACMOXB. VALYTP set to $FF. ERROR EXITS: OUT OF MEMORY ERROR exit could be taken. ROUTINE NAME: INPCOM .proc upshift,1 ;upshift is my procedure name, pla ; one word of parameter is expected tax pla tay pla ;pull off pointer to string variable strm. VALTYP = $FF. ERROR EXITS: None. The data in FAC must correctly match the given VALTYP. EXAMPLE STRING PERFORM ROUTINE index .equ 35 dispatch .equ 0e4 notnow .equ 13. ;interpreter subroutine numbers in decimal! ring (VALTYP = $FF). The FAC CANNOT contain a short integer with VALTYP = $00 and INTFLG = $80; use GIVAYF to convert it to type real first. ON ENTRY: FAC has some value determined by VALTYP. ON RETURN: FAC now has that value expressed in string foring for any valid VALTYP. Same as CONV function in BASIC. If the FAC is a real or long integer then a STR$ -like operation is done leaving a pointer to the string descriptor in FACMO, FACMO+1, FACMOXB. This routine does nothing if VALTYP already is a st FAC has real. ON RETURN: FAC has integer in real format. ERROR EXITS: None. Does nothing if FACEXP magnitude invalid. ROUTINE NAME: CONV2STR NUMBER: 44 DESCRIPTION: Takes the FAC and converts it to an ASCII st NUMBER: 39 DESCRIPTION: Converts the real in FACEXP-FACSGN into a real in FACEXP-FACSGN with no fractional part. Same as the INT function in BASIC. Only operates on the FAC if its FACEXP has a magnitude < 2^31 (8,388,608). ON ENTRY: able type. In addition if the FAC does not contain the type of data specified by VALTYP and INTFLG, whatever is in the FAC will be assigned as though it were correct. ROUTINE NAME: INT pe of the variable and FAC. ON RETURN: None. ERRORS: If VALTYP and INTFLG do not reflect the actual type of the variable at VARPNT, whatever is there will be stored into as though it was the proper variuld store anywhere in memory, SO USE IT RIGHT! ON ENTRY: VARPNT, VARPNT+1, VARPNTXB points to the variable. FAC-FAC+7 has variable's new value or points to a string descriptor. VALTYP and INTFLG control the assumed tyn FAC-FAC+7 and the flags VALTYP, INTFLG and does assignment into the variable pointed to by VARPNT. The various FAC data formats and their VALTYP's are given in this document under PTRGET (routine 1). This routine does not validate its input data and coxit will be taken if the variable's descriptor is more than 64K from its storage table origin pointer. ROUTINE NAME: LETP2 NUMBER: 35 DESCRIPTION: Assigns a value to a variable. Takes the value irage tables. ON ENTRY: VARPNT, VARPTN+1, VARPNTXB points to the string variable. FACMO, FACMO+1, FACMOXB points to the descriptor of the new value for the variable. ON RETURN: None. ERROR EXITS: VARIABLE ERROR eo the input string's descriptor. VARPNT, VARPNT+1, VARPNTXB points to the descriptor of the output variable, and the variable's old string value is returned to the free pool. VARPNT is normally set by using PTRGET to locate the desired variable in the sto NUMBER: 34 DESCRIPTION: Assigns a temporary string to a string variable or it duplicates an existing string and assigns the copy to the variable. Assumes that the value in FACMO, FACMO+1, and FACMOXB is a pointer ta index pla sta index+1 tya ;restore return address pha txa pha lda 16e9 ;get pointer extend-byte sta index+1601 ;now there is an extended pointer to lda #notnow ; the string descriptor at index sta dispatch+3 ;jsr notnow jsr dispatch ;puts pointer to string in index tay len linnum eol +------+----+----+----+-------+-----+-----+-----+------+-----+-----+------+ | 00 | 0B | 0A | 00 | FOR | x | = | 1 | TO | 1 | 0 | 00 | +------+----+----+----+-------+- +------+------+------+--- | 00 | 00 | 00 | +------+------+------+--- ! ARYTAB -----------------------+ Overhead = 4 bytes LINES ARE STORED IN ASCENDING ORDER APPLE /// BUSINESS BASIC SAMPLE PROGRAM | +------+---------+------------//---+------+ . . +------+---------+------------ ---------+------+ | lenN | linnumN | tokenized lineN | 00 | +------+---------+------------ ---------+------+ --+------------ ------------+------+ | len2 | linnum2 | tokenized line2 | 00 | +------+---------+------------ ------------+------+ +------+---------+------------//---+------+ | len3 | linnum3 | tokenized line3 | 00=====> | Overhead = 4 bytes Program Format TXTTAB ----+ ! +------+------+---------+------------//------+------+ | 00 | len1 | linnum1 | tokenized line1 | 00 | +------+------+---------+------------//------+------+ +------+----------+------+-------+---------------------------//----+------+ | Len | Line Number | Tokenized Line | 00 | +------+--lo--+--hi---+---------------------------//----+------+ | <============================ (Len) ================== | +-------------------------------+ <--- RAMEND | Drivers | +-------------------------------+ | Basic Interpreter | +-------------------------------+ APPLE /// BUSINESS BASIC PROGRAM FORMAT Line Format +------------------------------+ <--- FRETOP | String Data | | 64K maximum | +-------------------------------+ <--- HIMEM | Buffers | +-------------------------------+ <--- INVTAB | Invoked Modules --------+ <--- ARYTAB | Arrays | | 64K maximum | +-------------------------------+ <--- VARTAB | Variables | | 64K maximum | +-------------------------------+ <--- STREND +----ON +-------------------------------+ <--- RAMLOC | Graphics | | 0.5/8/32K bank 0 only | +-------------------------------+ <--- TXTTAB | Program | | 64K maximum | +----------------------- ;yes, return to BASIC ;could put more routines here .end APPLE /// BUSINESS BASIC AND ITS ASSEMBLY LANGUAGE INTERFACE - PART 3 of 3 APPLE /// BUSINESS BASIC MEMORY ALLOCATI ;make it uppercase alpha sta @index,y ;and put it back in the string $1 plp ;was that the last byte? bne $0 ;no, go back and do it again $2 rts peek at a byte of string cmp #"z"+1 ;is it lowercase alpha? bcs $1 ;no, forget this byte cmp #"a" ;could be bcc $1 ;it is! sbc #20 ;string length in a beq $2 ;if string length null then done $0 dey ;finished the last byte? php ;test later to see if it was last byte lda @index,y ;----+-----+-----+------+-----+-----+------+ | 06 | 14 | 00 | PRINT | x | 00 | +----+----+----+-------+-----+-----+ | 05 | 1E | 00 | NEXT | 00 | +----+----+----+-------+-----+ | 00 | 00 | 00 | +----+----+----+ Equivalent Source Program: 10 FOR x = 1 TO 10 20 PRINT x 30 NEXT APPLE /// BUSINESS BASIC VARIABLE FORMATS len valtyp real: RV +----+----+----+----+-----+-----+-----+-----+ | 08 | R | V |address LL (2 bytes) <-- top of 6502 stack APPLE /// BUSINESS BASIC PARAMETER PULL ORDER real: exp msb nsb lsb (4 bytes) integer%: hi low (2 bytes) long integer i% LL (2 bytes) msb l& ... lsb l& (8 bytes) exp r msb r nsb r lsb r (4 bytes) address HH s$ address LL s$ (2 bytes) return address HH return ce. For passing the address of the starting element of an array, use @ARRAY%(0). APPLE /// BUSINESS BASIC INVOKABLE MODULE PARAMETER PASSING INVOKE mymodule PERFORM me(%i%,&l&,r,@s$) i% HI <-- bottom of 6502 stack = $FF (2) Dimension count. (3) Dimension size: 2 bytes per dimension, right-most first. (4) Same format as value (see previous table). Maximum individual array size is 64K; all string arrays must be in the first 64K of array spa--> (1) (2) (3) (4) (1) Possible 'typ' values: real = $00 integer% = $80 longinteger& = $40 string$ E /// BUSINESS BASIC ARRAY FORMAT +-----------+---+---+---+---+---+----+----+----+---+----+---+----+--> | namelen | N A M E |typ|scnt| dimsize | value0 | value1 | etc. +-----------+---+---+---+---+---+----+----+----+---+----+---+----+ 0E 0D +---+---+---+---+---+---+---+---+---+---+---+---+ | A N O L D S T R G | 00| 00| 09| +---+---+---+---+---+---+---+---+---+---+---+---+ HIMEM --> 0C 0B 0A 09 08 07 06 05 04 03 02 01 APPL 21 20 1F 1E 1D 1C 1B 1A 1B 18 17 +---+---+---+---+---+---+---+---+---+---+ | J O H N A . | 41| FC| FF| +---+---+---+---+---+---+---+---+---+---+ 16 15 14 13 12 11 10 0F | 4A | 41 | FF| 07 | 16 | 00 | +----+----+----+---+----+----+----+ +---+---+---+---+---+---+---+---+---+---+---+ | A N E W S T R G | 81| F8| FF| +---+---+---+---+---+---+---+---+---+---+---+ 01 | 00 | 05 | 08 | 21 | 00 | +----+----+----+----+---+----+----+----+----+----+----+ VARTAB --> +----+----+----+---+----+----+----+ | len| name |typ|slen|offl|offh| +----+----+----+---+----+----+----+ | 07 ARYTAB --> +---------+----+----+---+----+---------+----+----+----+----+ | length | name |typ|scnt| dimsize |slen|offl|offh|slen| +-lo-+-hi-+----+----+---+----+-lo-+-hi-+----+----+----+----+ | 17 | 00 | 53 | 41 | FF| string: ST$ +----+----+----+----+-----+-----+----+ | 07 | S | T | FF | len | offset | +----+----+----+----+-----+-lo--+-hi-+ APPLE /// BUSINESS BASIC STRING STORAGE METHODS +----+----+----+----+-----+-----+ first, not lo-byte long integer: LI& +----+----+----+----+--7--+--6--+--5--+-//-+--1--+--0--+ | 0D | L | I | 40 | msb | | | | | lsb | +----+----+----+----+-----+-----+-----+-//-+-----+-----+ 00 | exp | msm | | lsm | +----+----+----+----+-----+-----+-----+-----+ integer: IV% +----+----+----+----+-----+-----+ NOTE abnormal | 06 | I | V | 80 | hi* | lo* | <- format: hi-byte &: msb ... lsb (8 bytes) @ptr: address hi address low (2 bytes) x byte? APPLE /// BUSINESS BASIC POINTER (@) PASSING FOR PERFORM, EXFN., EXFN%. Apple /// uses three-byte extended addressing pointers (explained elsewhere). These pointers are passed on the 6502 stack (two bytes) and in the interpreter's zero page and X-page. Up to eight pointers may be passed for simple variables, array elements. --------------------------------- on: 01/18/1989 15:19:21 QuickFile: Merging Files Even though QuickFile doesn't offer you the option of merging files, it does give you a foot in the door by letting you print reports to diskette. To merge files in QuickFile: First, design a "labels" fo1 Title: Modify Apple Speller to check 3EZ files Created by: SYSOP on: 01/29/1989 15:39:34 2 Title: List of current software versions - Created by: SYSOP on: 01/18/1989 15:19:52 Title: How to merge files in Quickfile - Created by: SYSOPI,?) ->n. Steven Hope this helps to explain. Steven Q: [Q]uit and go back to the preceding menu R: Select a subject file and [R]ead it (or just enter its number). I: List an [I]ndex of the subjects under this topic ?: Repeat these commands Subject (Q,R,iant of UCSD Pascal, which is to say that Pascal object programs are P-CODE, not native 6502 code; and in order to execute a Pascal program, the p-code interpreter must be resident, and the p-code interpreter doesn't speak BASIC. Hope this helps to explaiL' command (and it's not close, believe me) found in other dialects of BASIC. More info on using INVOKE and how to interface BASIC to Assembly language can be found here on ///'s Company in the Programming - Bus.Basic section. Apple /// Pascal is a var most BASICs on micros, is interpreted, and the program which interprets BASIC doesn't speak Pascal. The BASIC INVOKE command is used to connect to Assembly-language procedures and functions -- it's the closest thing standard Apple /// BASIC has to a 'CALnnot use pascal programs. The invoke verb is solely for specially designed 6502 assembler programs. Weber From: Steven Brineaux Michael, You CANNOT run BASIC programs inside the Pascal environment, or vice-versa. Apple /// Business BASIC, like understanding is that Pascal programs must have the Pascal System, which included the P-code interpreter in order to run. Pascal programs are not really compiled into 6502 code but to an intermediate code called p-code which is interpreted. Thus Basic caobey I want to be able to boot a Pascal program from within a Basic Program. How would I do this. I tried using the INVOKE command but I keep getting an error message. From: Weber Baker Michael; No doubt someone here will know more than I do, but myed from left to right. These pointers are only passed for '@' variables in the parameter list, NOT for the 'pass by value' expressions or variables. ------------------------------------------------------------------------------- 13-May-87 From: Michael R6ED $16F7 Extend ('X') Byte --------------------------------//-------- 1st 2nd 3rd 8th pointer pointer pointer pointer found found found found The parameter list is process------------------------------------------- (zero page register = $1A, so extend page is $1C) $E8 $EA $EC $F6 Address LL $E9 $EB $ED ... $F7 Address HH $16E9 $16EB $1rmat that prints each field of a record one below the other, with no blank lines between labels. Even if a field is blank, choose to print lines on continuous paper with no top or bottom margins and no headers. This will result in a file of contiguous, idewith the Pascal Filer's B)ad Blocks. Zero. Weird. There was some thunderstorm activity in the area, and the system has had spurious errors before in such situations, but powering down and back up has always fixed them. This time it didn't. So I rror when it read a file from the AR volume, and it had never crashed before... but I ran DCHECK on the volume and it reported no block conflicts, no bitmap errors, no problem. Weird. So I ran Systems Utilities Verify Volume. 0 Bad Blocks. Same e were running an AR Aging report, an old and reliable program, and it suddenly crashed with an 'I/O error #64, device error - bad address or data on diskette'; this had never happened before. I ran the delivery routing program, it crashed with the same e most three years, with nary a problem. Once in a while a bug pops up in the software, a little bad data sneaks past the data-entry routines, but I flush it out, close the loophole, and everything's fine. Until today. It started about noon. W Life without data, or... I HAVE TRUSTED THIS PROGRAM ONE TIME TOO MANY. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ I thought I had it all aced out. I've been running this system for alr). I: List an [I]ndex of the subjects under this topic ?: Repeat these commands Subject (Q,R,I,?) ->4 Title: Backup /// - Caveat Emptor!! - Created by: SYSOP on: 01/18/1989 15:18:22 ecuting this file will cause a new QuickFile file to be created, and all of your data will be "typed" in by the disk drive. Updated January 20,1986 Q: [Q]uit and go back to the preceding menu R: Select a subject file and [R]ead it (or just enter its numbehe new file. After terminating the EXEC file, quit QuickFile. Don't save this new file, though. Using your text editor again, load the EXEC file, and then load your combined file (see above) into the position just before the "%%%%". Again save the file. Ex't jump right into an existing file, since the EXEC mechanism cannot recognize and record the OA-I you need in order to go into Insert Mode. Don't terminate (%%) the EXEC file until QuickFile is waiting for input of the first field of the first record of tter, Pascal Editor, or a similar text editor to combine the files and re-save them to diskette as one file. Apple /// users with Pascal can then make an EXEC file that starts up QuickFile and creates a new file. You must create a new file, though: you canntically-structured records. Be sure that the files have the same number of fields in each record; control this number with the report format. The names of the fields are irrelevant. After the files you want to combine are printed to diskette, use AppleWrifigure, ok, I'll back up all the files and reformat the volume, see if that chases the bad address away... only I don't have enough space on the other hard disk volumes for the data files, just for the program files. Okay, so I'll use Backup/// for them, always worked before, right? Wrong. I'm sitting here now, backups all done, hard disk volume reformatted, ready to restore my data files, my AR and Customer files, all this month's invoices... ... and Backup /// refuses to recognize theaking a break from entering the 300 or so invoices that have yet to be reposted before our AR files are back almost the way they were before this thing started. I'm pushing the boss to let us spend the $2500 it would cost for an Infax system from Darryl A uses a CMC and A-143's) so I did end up re-initializing all my AR files... and left here 36 hours after I had come in, with enough of the customer file re-entered to be able to enter the next day's orders. After my 12 hours sleep, I came in, and am now tom Betz 06/02/1987 19:57:01 From: Tom Betz Dan Martin was very kind to me Sunday night, and transmitted his Brainsurgeon program to me at 11:30, and coached me through its use... unfortunately it didn't work with my Corvus and Disk /// combination (he will be placed in a safe for which I do not have the combination, so that I will never again be able to rashly decide to use it. Anybody have a Megaflex card for sale? I hear those big old Shugart 8" drives are really reliable... Ttted. When I have gone through every Backup/// formatted disk in the house, I will delete the Backup/// program from my hard disk and my Catalyst menu, and reformat all but two copies of Backup///, just in case I might have missed something. These copieskup software... and I know that when this thing is over, and I have reconstructed my data files, I am going to try to restore on regular floppies or hard disk every file I now have stored in Backup/// format. Those disks I can not restore will be reforma I've struggled with the question for an hour and a half, after moving and backing up files for the five hours before that. I still have no answers... ...except that I know I'll be here all night, because Apple Computer abandoned us with shoddy bacs covered entirely by a file I don't mind reconstructing... it's a minor auditing file, a convenience, on which nothing depends... but because I trusted Backup/// for it and 10 other files, those 10 files are lost to me forever. It's now 10:00 PM. file, and then more hours reconstructing the AR and Customer indexes and product preferences and on and on... I have sixteen disks here. Backup/// reported that all the disks formatted and verified correctly , I know, I watched. The first disk i early tomorrow when I should be closing out the month, so that I can begin the long hours of data entry from paper invoices and old posting journals and statements that I will need to re-construct the Customer file, the Invoice files, the AR Open Invoiceseman's messed with this problem a bit, and gives me Chris' number, but Chris won't be there until Monday... I thank him, but I know in my heart that tomorrow will be too late. I know in my heart that I'm going to have re-initialize all my data files verypin in Austin, TX. I never talked to Ron before, picked his name out of OnThree, but he's a real nice guy, and tries to help. He commiserates, says he doesn't use Backup ///, doesn't trust it, I say (bitterly) neither do I anymore, and he says Chris Acrachines in the house with no success, I get on the telephone. It's 8:30 on a Sunday night. Rod Whitten's home, he suggests Ed Gooding. Ed isn't home, so I leave a message. I try Daryl Andersen... he isn't home either, I leave a message. I try Ron Mal first disk of 16. I try copying the disk volume using System Utilities. No go. I try using the Pascal Filer. No go. I try using EDD. No go. I scream at the top of my lungs. About twenty-five minutes later, after I have tried all five mnderson, and I have his agreement, just have to find the cash. I would again implore all of you to never, NEVER trust Backup /// for important data... it may work once or twice or a hundred times, but that one time will come when it won't, for no particular reason... and you'll be crying like I was Sunday night. 06/20/1987 22:24:29 After reading the Backup warning, I hesitate to use Backup ///. Any other suggestions? Steve Fleming 06/21/87 08:06:40 Steve: You really have no other choice at this ties occupies on your profile, handy if you ever have to go in with a disk block editor to salvage or repair a file manually. It will be slow running to print all this out to your printer, but I would recommend doing it every 6 months or sos. It will also AUTOMATICALLY FIX a lot of data integrity errors, without any intervention from you. Also, if you choose the verbosity level=4, and send the output to your printer, it will print a disk map that shows every block that each filtion.....but, basically this program waltzes through your Profile, checking the bit map of every single file, making sure that there are no blown bitmaps, making sure that two files don't think they own the same block, and lot's of other goodieCatalyst menu. See the directions for installing simple Pascal programs in the Catalyst docs. 7) Ok, now for what this program does.......of course, read the docs file by loading them into Applewriter and printing them out for a full explana and 4th prompts, just key a carriage return. For the output file prompt, key disk.map.code (yep, same as the first prompt.) When the link finishes, you will have an eX)ecutable Pascal program. I installed this as a separate entry on my rt can call the 6502 part whenever it wants to do any disk drive accesses. To do this, you use the L)ink function from the Pascal command line. For the first prompt, key disk.map.code. For the second prompt, key disk.map.link. For the 3rd key disk.map.link. You can also direct the output to the printer if you would like to see what a 6502 program listing looks like. 6) Now, we need to put the Pascal codefile and the 6502 codefile together in one program so that the Pascal paost of the disk drive handling, the Pascal code is used for the user interface and the printing, etc. This is a good way to write professional programs and makes them run really fast. For the input prompt, key disk.map.asm, for the output filen key .printer to that prompt. You can press return at the Error file prompt since we know that the program will compile cleanly. 5) When that finishes, you will need to A)ssemble the disk.map.asm file into a 6502 codefile. This codefile does mmpile options, key an exclamation point (!). For the input prompt, key Disk.map (you can leave off the text, the compiler will automatically append it.) For the output prompt, key Disk.map.code. If you want a printout of the compile, thekey sequence. Then press Q)uit and S)ave it back to disk as Disk.map.text again. 3) Read Disk.map.asm into the Pascal E)ditor and convert it to Pascal Text as in step 2 above. 4) Next, C)ompile Disk.map.text into a pascal codefile. For co greater than 32K, and the Pascal E)ditor will gag on it. Save it back to disk as disk.map.text. 2) Read Disk.map.text into the Pascal E)ditor and convert it to a Pascal Text file by the use of the S)et E)nvironment A)scii F)alse CONTROL/C m the Programming/Pascal/Sample.progs.4 section called Disk.Map.Check. Convert it to a codefile as follows: 1) Read the Disk.map.pas file into Applewriter and remove the comments at the beginning of the program. With the comments, the source code isme. I know of two developers who say they are developing an alternative to Backup ///, but for now, "it's the only poker game in town." There are a few things that you can do to lower the risk of being bitten, however. One, download a Pascal program fro. For weekly use, you can use the verbo=0 level and press return at the prompt for where to send the output. 8) Ok, now back to how we improve our odds of getting a good Backup /// run: a) Run Disk.map.code against your hard disk to ensure that what you are backing up has integrity. Backup /// will backup up garbaged data from your hard disk, and never say a word to you about it, UNTIL you try to restore it back (nice, huh?). b) Use a commercial floppy disk driver cthe subjects under this topic ?: Repeat these commands Subject (Q,R,I,?) ->that ten megs for another $59.95. If I could just get it to work on our Constellation II network, i'd be in hog heaven. Q: [Q]uit and go back to the preceding menu R: Select a subject file and [R]ead it (or just enter its number). I: List an [I]ndex of price to pay for real data security. I would also advise anyone buying his first hard disk that this is a wise investment >instead< of a hard disk, because you can have another ten megs anytime for 59.95 from Lyben Computers, and have complete backup for device from D.A. Datasystems, and will use it to make file-by-file backups from here on out. That way, barring a real stupid screwup, the worst a bad block or bad data can do is destroy one file. This is an expensive ($2400) solution, but that's a cheap luck.......Ed Gooding, Sysop 07/09/1987 14:12:58 FROM: Tom Betz I have resolved never to use that sucker again... but then, I have a business doing my buying here. We have ordered, and should receive today or tomorrow, an INFAX 20-Meg Bernoulli-type rgeon program is also in the Apple.iii.help/Programming/Pascal/Sample.progs.4 section. e) It probably wouldn't hurt to offer a prayer to whomever you choose to worship before backing up, and definitely before you try to restore. Good Brain.Surgeon that, when used with a block editor, will allow you to extract important files from Backup /// diskettes. This may save you from having to do a lot of data entry into your /// if all of the above fails. The Brain.Suyour most current set fails, then you can go back one more generation, if that one fails, you can go back one generation further. If that one fails, all is not necessarily lost. Dan Martin has uploaded a program here named e fourth backup session, use the backup diskettes from the first session. For the fifth backup session, use the backup diskettes from the second session, and so on. This way, you will always have 3 full sets of backup disks. If Three is even better, even if it does tie up a lot of diskettes. It works like this: For the first backup, use a fresh set of formatted diskettes. For the second and third backup sessions, use fresh disk- ettes, also. For th ensure that the diskette is properly centered on the disk drive hub. If it's not, then you may not be able to read tomorrow what you write today. d) Use a generation system of backup disks, with at least two generations ouble clamp the disk drive door on every disk. Actually, you should get used to doing this on ANY diskette that you write. Insert the disk into the drive and close the door, then re-open the door, and close it again. This will It would also be a good idea to use the Confidence Program to check the speed of the floppy drive that you are going to backup to so that you know that the drive is within specs. c) When you run Backup ///, make sure that you dleaner disk in conjunction with a Bus. Basic program here on ///'s Company called Disk.Cleaner. It is in the Public.domain/Utilities/Section.3 area. Do a good clean job on the floppy to which you are going to backup your Profile.