' +JJJJ ?\>m0M='+l> /+l   d]@ŵLҦ]]LF L}BBL] X  ` 鷎귭෍ᷩ췩緈JJJJx Lȿ L8ᷭ緍췩 緍i 8 `巬 췌`x (`(8`I`B` ``>J>J>VU)?`8'x0|&HhHh VY)'&Y)xꪽ)' `Hh`V0^*^*>&` aI꽌ɪVɭ&Y&&Y& 꽌ɪ\8`&&꽌ɪɖ'*&%&,E'зЮ꽌ɪФ`+*xS&x'8*3Ixix&& 8  '  & x)*++`FG8`0($ p,&"ųųೳŪŪųųij  !"#$%&'()*+,-./0123456789:;<=>?   1 '" *"( (9"1 ( ,.(0# 2  /#0/#0 *?'#07#00/0/'#07#0:"4<*55/**5/*%5/)1/)1/)1/)'#0/#0*5/*75/**5/*:5//#0/#0'#07#0:::*::'#07#0"):$(%"%:$(%"%$$2%4%$$2%4%$(2()!)E(!8b $!H(+ "@H !D)"E` @ $ C ` DQ &J80^݌Hh ü ü݌ ռ ռ ռA ļD ļ? ļAEDE?HJ>h Լ ռ ռ ռ`HJ>݌h Hh݌`葠葠ȔЖȔЖȠHIHHHHhHH݌hHhHh݌H6 VDP (ED Z $0x8x D- ܸDD# H8`?E Vk *f???0xE Hh D#-EEE8` D ܸx D - ܸx8`-0ݩ?ʥD EEE`   LDcpq` [` ~  LӜu`".Q`pNФbptťܥm2<(-Py0\|e<6e<g< JJJJj귍hI  aUL@ kU8  L  Q^R(jQ0l^l\  wUuW ԧ H h@ [_ /QSIRb_L`LLLL`ª`LQLYLeLXLeLee ўQH\(h0L& Ꝥ$`( R \ZLl8 ўR HH\`\Z[YS6`LxQɿu3'RͲʎRʎ]]]ɍuL͟ɍ}RLRɍg^H8 ^hZLɍR LͲɊRR% QLܤͲ Z@ -^ ş\[Z QY\[Z8`l6Lş_Ȍb_Ͳ] )Y h( ֭ͲLɍ [LLĦ__ ^ 9 LҦ3 9 a   0LjLY u< (_9 ˭ɠuɠK_9 ?LˆʎõĵL õ ĵµ aµ`` L̦µ_bJLuLz`  ȟ QlXJ̥KlV  ȟ QlV eօ3L e3L &RL &QL d L4 Ne)n `@-eff L f`L . tQLѤ LҦL` OPu d L Ne)noon 8ɍ` ^f\õL ^NR  RΩLҦ)\Z ʽ LHv 3h`0h8` [L NС õ`A@` ŵL^Lõ`  \ 濭0 \  ȟ Q ^\lZl^?cqH şch`fhjõĵ@OAP`u@`@&`QR`E Ls  @DAE@u`8` %@ @A@`@`@A`Mµ ) LЦ`8@AWc@8@-@HAȑ@hHȑ@ȑ@hHȑ@Ȋ@ch8&ȑ@Hȑ@Ah@LHȑ@ȑ@ htphso`hMhL`9V8U897T6S67`INILOASAVRUCHAIDELETLOCUNLOCCLOSREAEXEWRITPOSITIOOPEAPPENRENAMCATALOMONOMOPRINMAXFILEFINBSAVBLOABRUVERIF!pppp p p p p`" t""#x"p0p@p@@@p@!y q q p@  LANGUAGE NOT AVAILABLRANGE ERROWRITE PROTECTEEND OF DATFILE NOT FOUNVOLUME MISMATCI/O ERRODISK FULFILE LOCKESYNTAX ERRONO BUFFERS AVAILABLFILE TYPE MISMATCPROGRAM TOO LARGNOT DIRECT COMMANč$3>L[dmx-(0 ؠ@跻~!Wo*9~~~~ɬƬ~_ j ʪHɪH`Lc (L ܫ㵮赎 ɱ^_ J QL_Ls贩紎 DǴҵԵƴѵӵµȴ 7 ַ :ŵƴѵǴҵȴµ納贍﵎ٵ്ᵭⳍڵL^ѵ-I `  4 ò-յ!  8صٵ紭ﵝ 7L (0+BC  7L HH`LgL{0 HH` õL H hBL BH [ h`Lo õ ڬL B ڬ LʬH hB@ յյ [L (ȴ) ȴ 7L L ( L (ȴL{ƴѵ洩ƴǴҵ 7 ^* B0 HȱBh ӵԵ 8 L8 ݲ` ܫ  / / ED B / / ]ƴS0Jȴ ȴ)  紅D贅E B ƴ  / 0L Ν `HD٤DEEhiHLGh ` ŵBѵ-` ѵB-` ܫ XI볩쳢8 DH E𳈈췍Ȍ X0 · JLǵBȵC`,յp` 䯩 R-յյ`յ0` K R-յյ`ɵʵӵԵ` 4 K ( ѵҵLBȱBL8` DBHBH : ַ޵BȭߵBhhӵԵ RBܵmڵ޵ȱBݵm۵ߵ` 䯩LR˵̵ֵ׵`êĪLR E( 8` R` ELRŪƪ`췌 յյI뷭鷭귭ⵍ㵍跬ª 뷰` Lf ݵܵߵ޵ ^`8ܵ i B8` 4L ֵȱB׵ ܯ䵍൭嵍 ` DȑB׵Bֵ  ַ յյ`굎뵎쵬 뵎쵌``õĵBCõĵ`µµ`L õBĵCصص Qƴ0"Bƴ 󮜳` 0۰ϬBƴ8`i#`ЗLw!0>ﵭ` m ﳐ 7i볍 8 ЉLw`H h ݲL~ `浍국䵍뵩嵠Jm赍嵊mjnnn浈ۭm浍浭m䵍䵩m嵍`"L ŵ8ŵH ~(`F d ֠z# u` APPLESOFT DECODER ABFB3:BLB:CDRD:90:AR$"":v$D1$("00"(NX1),3):D2$("00"(DT(SEL,2)),3).::12:"ProDOS UNDELETE";:31:D1$"/"D2$::"MODE:";:MODE$"A"Ğ88:"APPLESOFT";::MODE$"T"Ğ B19:"TEXT";::MODE$"M"90:BFBF2::NWOLDBO"K RESTORE CATALOG ST16(1(DT(SEL,2)1))(N$(SEL)):BUDT(SEL,3),ST(BU37)255ĹBU37,0:BU38,(BU38)1:1020BU37,(BU37)1CDWR:BF8:BL26:90:BFBF2: BIT: ASLkOLD(25616BYTE):TST(OLD2BIT):BB0:(TST2)TST2BB1: BB=1 MEANS BLOCK IS IN USEDT(SEL,2)1BBĺ(7)::"BLOCK NUMBER "B" IS NO LONGER FREE"::"It is not possible to UNDELETE "N$(SEL):BUDT(SEL,3)1,0:CDWR:BF8:BL25:re out of order"::"Press 'A' to abort the undeletion or anyother key to continue. ":ZZ$:ZZ$"A"ĀBLDT(SEL,1):BFB2:CDWR:90:990:1420:DONE  CHECK BIT MAP TO SEE IF BLOCK IS USED BYTE(B8):BIT7(B8BYTE):BO2DT(SEL,2)8107fBDT(SEL,1):930:BBĹ25616BYTE,NWpERRĺ(7):"There were "ER" block jumps in":" reconstructing the Key block"::"Press 'A' to abort the undeletion or anyother key to continue. ":ZZ$:ZZ$"A"ĀezEFLAGĺ(7):"Some blocks weEXTRA JUMP FROM 1ST TO 2ND KEY BLOCK NO.F*BB1:B280B7:EFLAG1f4BDT(SEL,1)ERRERR1:810>930:BBERER1:810HBR$"Y"İ1050:AR$"R"ERER1:810RBKNX1,B:25616BYTE,NW:PUT BLOCK ON KEY BLOCK & MARK BIT MAP \NXNX1:NX0HRė:(7)N$(SEL)" is probably a HI-RES file.":"If so, its display here will be garbage.":"Press any key to continue ":Z$:BR$"Y"İ1050AR$"R"ĺ(7):"Undeleting is aborted due to first blockbeing rejected!":) BB1:NX2:ERR0:EFLAG0::B(BK): READ KEY BLOCKKCSUM0:A2250:CSUMCSUM(BKA):CSUM770n930:BBĹ25616BYTE,NW:780(7)::N$(SEL)" is damaged"::"It is not possible to UNDELETE ":BUDT(SEL,3)1,0:CDWR:BF8:BL25:90:BFBF2:: HRBR$"Y"İ1056,0:60DT(SEL,2)1740RBDT(SEL,1): SET NUMBER OF BLOCK TO WORK WITH[930BR$"Y"İ1050:AR$"R"ĺ(7):"Undeleting was rejected. Program abortedwith no changes made!":25616BYTE,NW:990:1420BLDT(SEL,1):BFB2:CDRD:90HDRAWAL,TOTAL WITHDRAWAL,TAX ON WITHDRAWAL,TOTAL INCOME,TAX SHELTERED,TAXED j^ TAX SHELTER BENEFITST"$650.50 IS ENTERED AS 650.50":E"PRESS TO CONTINUE";A$X(4);"PR#0":c33,40p"ZZ111|,A$(ZZ)6A$(ZZ)A$(ZZ)S$@A$(ZZ)(A$(ZZ),17)J:OT DEPOSIT,INTEREST,SERVICE CHARGE,TAX ON INTEREST,TOTAL IN ACCOUNT, WIT: TOTAL WITHDRAWAL@A$(8);TW$;ZT$: TAX ON WITHDRAWAL bTIYSTW:TTI:210:TI$"$"T$A$(9);TI$;YT$::: TOTAL INCOME(4);"PR#0":"WHEN ENTERING NUMBERS, THE COMMA IS NOT":"USED. $6,000 IS ENTERED AS 6000": 10:WT$"-"T$#ZYSYSWS:YTYTWTCdA$(6);WS$;WT$: WITHDRAWALYnPSPSWS:PTPTWTcx1190{PS.01PT.011310TYS:210:YS$"$"T$TYT:210:YT$"$"T$TWYSRR:TTW:210:TW$"-"T$ZT0:TZT:210:ZT$"-"T$A$(7);YS$;YT$T$$A$(5);PS$;PT$:F1: TOTALS6A$"Y"İ340>:IM1Y`990:1020:1190:gM :"DEPOSITS ARE REDUCED TO ZERO.":DS0:DT0:PRRR990(10502WSPSWSPS<TWS:210:WS$"-"T$FWTPTWTPT PTWT:2tA$(3);SS$;ST$: SERVICE CHARGEC~TTITRP:TTT:210:TT$"-"T$hA$(4);E$;TT$: TAX ON INTEREST{PSPSDSISSSPTPTDTITSTTT:S$;"------------";"-----------"TPS:210:PS$"$"T$TET:210:ET$"$"T$TPT:210:PT$"$"(PSDS)RS:TIS:210:IS$"+"T$G$IT(PTDT)RT:TIT:210:IT$"+"T$e.A$(2);IS$;IT$: INTEREST8SS(PSDSIS)CS:SSMSSSMSBST(PTDTIT)CT:STMTSTMTLPS.01SS0VPT.01ST0`TSS:210:SS$"-"T$jTST:210:ST$"-"T$!LOAD and STORE work with two byte (word) operands, this DBsame concept can be extended to single byte operands. Examine the CAmacro for MOVEB (move byte; line #164). In this case, all of the A?conditional assembly is included in the same macro definimeter list. DThe third operand, byte request count, can be coded as #256 (read DBup to 256 bytes; see line #30), or as FILE1+59 (use the READ byte A?transfer count as the byte request count for writing; see line #31 of Listing 3).CA While al different types -of parameters to be used as macro operands.@> The READ and WRITE macros are not concerned about the data @>address operand or length operand. Both use MOVEW to move the DBdata address pointer (#]2) and length (]3) to the paranal A?assembly. In the case of the zero page indexed load, the Y-reg CAmust be set first, and is left at the same value after execution A?of the macro code. The STORE macro is similar except for the # B@operand. Use of these two macros allows severl cases (except LOAD 0), the A-reg is loaded with the low ?=byte of the symbol or value from the symbol address, and the A?X-reg is loaded with the high byte of the symbol or value from DBthe symbol address. This macro makes extensive use of conditioions 256/2579 LOAD #256 ;load constant of 256 ($00/$01)7 LOAD ABLE ;load word from location ABLE3 LOAD #ABLE ;load #ABLE and #ABLE/256; LOAD (ABLE) ;load from zero page pointer ABLEDB In alBdefinition for MOVEW appears in lines 157-163. MOVEW uses LOAD ]1 A?followed by STORE ]2. The LOAD macro is used to handle several different operands:, LOAD 0 ;no code expansion; LOAD 256 ;load word from locat length value was coded as an CAabsolute value (i.e., 256). This time, the parameter is coded as *#256, which brings us to our next topic.&A Word From Our Sponsor, Macro PowerB@ The statement MOVEW #]2;]1+55 appears in the READ macro. The Ds statements from ELSE to FIN. The grouping may be of the form:. IF (true) ELSE (false) FIN, or IF (true) FINCA You will note another change compared to our previous version A?of the READ macro. Last time, theonal assembly, we have used the opcodes A?IF, ELSE, and FIN to control code generation. When the test is DBtrue, the statements between IF and ELSE are processed by Merlin. A?If the test is false, then Merlin skips to the ELSE opcode and DBprocesseou wish to see the Hi-Res picture...(Y/N)":ZZ$:ZZ$"Y"Đ:(4)"BLOAD "N$(SEL)",A$4000":16302,0:%::(7):"Done! Please LOAD & check the file, "N$(SEL):::$xDT255TYPE$(A)"SYS":$TYPE$(A)(DT):g%HRĺ(7):"Done! Do y"DIR":#$<DT25TYPE$(A)"ADB":?$FDT26TYPE$(A)"AWP":[$PDT27TYPE$(A)"ASP":x$ZDT252TYPE$(A)"BAS":$dDT253TYPE$(A)"VAR":$nDT254TYPE$(A)"REL":$xDT255TYPE$(A)"SYS":$TYPE$(A)(DT):g%HRĺ(7):"Done! Do yATA":OFF512x#OFF511ĺ(7)::"End of Block "B".":" Press 'R' to Reject block or any other key to accept ":AR$:#A0MODE$"A"OFFOFF3:1150# OFFOFF1:1160##DT4TYPE$(A)"TXT":#(DT6TYPE$(A)"BIN":$2DT15TYPE$(A)"T"A13ĺ:1250,"A0A32Ğ:(A64);:"A0(MODE$"A"MODE$"T")ĺ:MODE$"A"(A(BTOFF1)(BTOFF2)0)ĺ(7):"End of DATA":OFF512 #A255MODE$"T"(TYPE$"ADB"TYPE$(SEL)"AWP"TYPE$(SEL)"ASP")ĺ:(A(BTOFF1)510)ĺ(7):"End of D$"A"(A127A235)ĺCMD$(A128);J!(16384)1281220:KEYBOARD STROBE}!KS(16384):16368,0:KS193MODE$"A":1070!KS212MODE$"T":1070!KS205MODE$"M":1070!KS155BR$"N":!OFF512:1270!A31A128ĺ(A);"MODE$Ğ& L25:"MACHINE LANGUAGE"::34,4= V:MODE$"M"1140Z `360:(16384)1281180l jOFF512:1270 tOFF2:MODE$"A"OFF0:1160 yNX1(BTOFF1)0OFFOFF2:1160 ~LN(BTOFF)256(BTOFF1):LN" ";:OFFOFF2!!A(BTOFF):MODEe the FILE1 modification date and time fields to the DBparameter list for FILE2, plus the access byte from FILE1 (if the CAinput file is locked, then the output file will also be locked). >incorrect (if FILE2 already existed). If FILE2 was originally :8shorter than the data copied to it, these steps are not ?=necessary. If FILE2 was longer, the eof value must be set to B@re. This is followed by the SETEOF call to A?set the end of file pointer (file length) for FILE2. Note that DBGETMARK returns the mark value to the same parameter list used by A?SETEOF to set the eof value. We then close FILE2. If these two B@stepsnt for writing (FILE1+59).?= When there is no more data in FILE1, the code is executed CAbeginning at line #36. Since we no longer have a need for FILE1, CAit is closed. Next, the GETMARK call is used to find the current Bfile position for FILE2 processing, @>followed by the loop which reads and writes the data. In line CA#30, the byte request count is 256. The number of bytes actually A?transferred is returned by the MLI to the parameter list. This Avalue is used as the byte request coueate date CAand create time from the GETINFO call for FILE1 (fourth operand, CAFILE1+34). The file access code, $C3, is set by the FCB macro in 7the create parameter list (unlocked, can be written).>< At lines 25 and 26, the files are opened for #21 will create a new file for FILE2. Input to the create CAMLI call is the information in the parameter list, plus the file DBtype from FILE1 (second operand), the subtype field (aux_type, or B@FILE1+25, which must be copied over), and the FILE1 cr DBinput to the GETINFO macro for the third operand is the file type DBfield of FILE1, obtained by the successful GETINFO call for FILE1 ?=(FILE1+24). If the type matches, jump to PROCEED to open the %files. Otherwise, we have an error.DB Linee code. At this point, FILE1 may have any file type.B@ Line #14 is the GETINFO call for FILE2. In this case, if the CAfile is not found, we will jump to the CREATE macro. If FILE2 is B@found, we want the file type to match that of FILE1. Therefore, The FOUND macro is used to perform this test.=; The ProDOS MLI does not perform checking for file type. A?Therefore, the GETINFO macro uses the MATCH macro to check the ?=file type. If the operand is coded as 0, then MATCH does not =generat. With EXP OFF, you will notice Merlin pause when 6assembling the CREATE call in line #21 of Listing 3.Now, Back To Our Progam@> Line #13 is the GETINFO call for FILE1. If the file is not DBfound, we will use our abbreviated error routine.ent form, it is easy to observe that B@we are moving one byte with file type, two bytes of subtype (or DBaux_type) information, a date field, and time field to the create CAparameter list. This is immediately followed by the create ($C0) <:MLI callhe definition of B@higher level macros is simplified by use of lower level macros. CACREATE is built using three macros and five macro calls. Without CAMOVEB and MOVEW, CREATE is a long string of hard to read LDA and DBSTA instructions. In the presexed B@operand, were based on current assembler syntax. You may choose B@any characters that you desire to indicate the mode of assembly A?for different operands. In our set of macros, LOAD, STORE, and ?=MOVEB are considered the low level macros. Ttion. 5This macro is used in GETINFO, SETINFO, and CREATE.DB Essentially, we have generalized our macro definitions to deal >indicate an immediate operand, and '(' to indicate an ind one line exists in a program, the minimum length is eight bytes:5 2 bytes next line pointer (LO/HI value)9 2 bytes Applesoft line number (LO/HI value)8 1 byte minimum data for an Applesoft line. 1 should be sufficient to B@serve as a base for developing some of the other functions that were mentioned.B@ An Applesoft program in memory consists of Applesoft program B@line(s) followed by the end of program indicator ($0000). If at B@leastfiles.B@ What we will develop here is a functional module to read one @>Applesoft program file, select lines by line number, and copy DBthose lines to a new file. This will provide the code for reading DBand writing Applesoft program files. This M CAstatements and combine program lines, and write a new compressed ?=copy to a different file; MERGE command to read two seperate A?program files and create a single program file as output; or a 9COMPARE command to compare two Applesoft program There are many functional applications that can make use of B@the ability to read Applesoft program files one line at a time. B@Examples include: LIST command to display a program from a disk <:file; COMPRESS command to read a program file, remove RE (display text file) and a DUMP CAfunction (display hex and character of any file). At this point, B@we will turn to processing an Applesoft file (BAS) in a line by -line fashion (selectively by line numbers).An Applesoft File UtilityA? need to add a few =;more macros - SETMARK, GETEOF, PREFIX, DELETE, RENAME, and @NEWLINE. NEWLINE? What's a NEWLINE? Patience. It will covered CAshortly. By using macros for reading data, we can put together a DBprogram to provide a TYPE functione entry itself. This method is necessary to CAdisplay certain fields from directory entries (file type $0F) or the directory header block.=; We now have sufficient information for developing other A?applications that use files under ProDOS. We le. At this point, we can easily @>develop the code the display the CATALOG line of output for a B@file (left as an exercise for the reader). Of course, one other DBway to get the information is to search the ProDOS file structure =;to find the filcopy subroutine.>< The GETINFO macro provides almost all of the information DBnecessary to perform a catalog display for a single file. We must B@still get the eof value. In order to obtain eof, open the file, A?issue GETEOF, and close the fising macros, we have developed a usable and working program that >code to create the same program without macros. We may end up A?doing that anyway for optimization of the program. However, by DBuogram. In fact, all of the program logic DBis contained in 32 lines of code (lines 13 through 44). If we use A?EXP ON, this one page listing expands to seven pages! However, 8this also includes the macro call lines and EOM lines.CA If we use EXPalways jump to the create macro call +upon sucessful completion of the delete).Is That All?:8 Hardly! But, before we move on, a few comments about A?assembling and using macros. From Listing 3, we have about one B@page of code for our prram will not change the A?create date and time. In order to do this, FILE2 must first be B@deleted and then recreated. This is left as an exercise for the B@reader (you will have to code a DELETE macro, insert the delete @>call after line #14, and block.DB Line #40 through #44 are not absolutely necessary. This update @>is performed so the output file essentially mirrors the input CAfile in the directory entry as well as the data. However, if the ?=output file already exists, this progy DBtesting, I used the STARTUP program from the ProDOS User's Disk). B@The values are coded at FIRST and LAST. If the line number just CAread from the file is less than FIRST, go back to LOOP. If it is >greater than LAST, then finish up. Now, fortes without end of file checking. A?Newline mode is then enabled and we read the program line with end of file checking.@> For our sample program, we will extract lines 1000 through @>2000 (change these values for your own sample program; for me fields (let ProDOS take B@care of these). This time, we are not creating an exact copy of >the file, but a new file with a subset of the program lines.?= The processing loop is in lines 73 through 84. We disable A?newline mode and read four byto store the result back to the second operand or to a third ?=operand. This macro is used to generate the new program line offset pointers.DB In this program, we specifically check for Applesoft file type @>and do nothing with the date and timted A?appropriately (with some work, this macro could be expanded to DBhand the multiple condition tests for less than or equal, greater 'than or equal, as well as not equal).DB Finally, there is an add word macro (ADDW). Its only option is ?= has been added and is used in comparing line numbers. LOAD A?is used to place the first operand in the registers. The third DBoperand can be L, E, or G, for less than, equal, or greater than, =;respectively. The test and jump instructions are genera each B@byte read from the file. The read operation will then terminate when a byte with $00 is found.CA Turn now to Listing 5 which contains our program. The NEWLINE CAmacro has been added, which is very simple. A compare word macro DB(CMPW) read the first four bytes of each program line with newline A?mode disabled, and then read the rest of the program line with B@newline mode enabled (enable mask = $FF and newline character = @>$00). $FF is used as the mask to leave all bits alone int we can enable newline mode with a newline ?=character of $00 to read individual Applesoft program lines. DBHowever, the first four bytes of each program line can have a $00 CAbyte as part of the next line pointer or the line number. So, we CAmust $7F with a A?newline character of $0D (return character). Thus, the newline @>character will get a match whenever $0D or $8D is read from a 8text file (AND with $7F converts $8D to $0D; a match).On With The ProgramDB It would appear thaCcharacter. Each byte read from the file is ANDed with the enable @>mask. The result is then compared to the newline character. A @>match causes the read request to terminate. When BASIC.SYSTEM ?=reads text files (TXT), it uses an enable mask ofble mask, DB 0 ;newline characterCA Reference number is set up by the OPEN macro. A mask value of A?$00 disables the newline character option. This is the default > In our previous program, we set up a request count for 256 <:bytes of data for each READ macro call. With this type of DBrequest, byte end of line marker ($00)3 2 bytes end of program marker ($0000)?= Thus, each Applesoft line begins with a pointer, the line B@number, followed by the tokenized program information, and ends =;with $00. This information is iLI.program. As before, we get the 8mark, set the end of file pointer, and close the file.Speaking of CLOSE...CA Time to issue SETEOF and CLOSE for now. Next time, we'll open @another file and look at some special applications of the Mlesoft program. As before, we get the 8mark, set the end of file pointer, and close the file.Speaking of CLOSE...CA Time to issue SETEOF and CLOSE for now. Next time, we'll open @another file and look at some special applications of the Msoft line. The pointer field must be correct in CAorder to load, list, or run the program lines from the new file. .Now, we write the updated line out to FILE2.<: At ENDFILE, we write out two bytes of zeros ($0000) to ?=indicate end of the Appo $0801). First, add 4 to the A?byte transfer count of the input file (FILE1+59) for the first B@four bytes read. Then, add this value (FILE1+59) to the subtype CAfield of the input file. Finally, move this value to the pointer DBfield of the Apple the tricky part.?= The next line pointer in each line must be updated before CAwriting the selected lines to the output file. The initial value CAis taken from the subtype field of FILE1 (FILE1+25 obtained with @>the GETINFO call; normally set tz#??     ҮӠŵӠŵؠخ̠ ӮŠŮӮɲOųӠӮӠ D  (768)0Āj ":"...LANGUAGE CARD CANNOT BE RELOADED":" UNTIL THE SYSTEM IS REBOOTED..."p ,A6: 769 (768)1250% I --IF THERE, LOAD INTG AND PA#1P 10:"(LOADING INTEGER INTO LANGUAGE CARD)" "BLOAD INTBASIC,A$D000" --WRITE PROTECT THE CARD A(16254): $C082  --NO CARD OR CAN'T RELOA804,0:805,208:806,208:807,10:808,173:809,129:810,192:811,173:812,129: s813,192:814,169:815,1:816,208:817,2:818,169:819,0:820,141:821,0: x822,3:823,104:824,205:825,0:826,224:827,240:828,3:829,173:830,128: }831,192:832,9,104:W _777,72:778,205:779,0:780,224:781,208:782,35:783,173:784,131:785,192: d786,173:787,131:788,192:789,169:790,165:791,141:792,0:793,208:794,205: i795,0:796,208:797,208:798,19:799,74:800,141:801,0:802,208:803,205:N nq -- DOS 3.3 HELLO  (:.(Y2"DOS VERSION 3.3 08/25/80"<:"APPLE II PLUS OR ROMCARD SYSTEM MASTER"F P --POKE LANGUAGE CARD FINDER Z768,0:769,173:770,0:771,224:772,72:773,173:774,129:775,192:776    `W -?Rf{9Z~$T2rIIzdk 3 R %g%:!#%'K*,y/K2I5t8;^?#CS$;" SAVINGS ";" SAVINGS"7TPS:210:PS$"$"T$PTPT:210:PT$"$"T$Z1230d1260"YOUR AGE IS "AG,:AGAG1" THE YEAR IS "YR:YRYR1TDS:210:DS$"+"T$TDT:210:DT$"+"T$A$(1);DS$;DT$: DEPOSIT ISETIREMENT WITHDRAWAL IS:":A$(10);"$"WS:A$(11);"$"WT:"YEARLY SERVICE CHARGE PERCENT IS:":A$(10);CS100"%":A$(11);CT100"%":"YEARLY SERVICE CHARGE MINIMUM IS:":A$(10);"$"MS:A$(11);"$"MT:A$"Y"İ340S$;"SHELTERED";" TAXED" IS:":A$(10);"$"PS:A$(11);"$"PT:sR"AMOUNT OF YEARLY DEPOSIT IS:":"TAX SHELTERED",DS$:"TAXED DEPOSIT",DT$:\A$"Y"İ340f"INTEREST RATE IS:":A$(10);RS100"%":A$(11);RT100"%":p"DEPOSITS WILL BE MADE FOR "Y" YEARS":7z"YEARLY R ";A$:A$(A$,1)'SL8:A$"Y"SL11V A$"Y"E$" ": 14 SPACES {A$"Y"ĺ(4);"PR#1":(9);"80N" A$"Y"İ140*:4"PRESENT TAX RATE IS "100RP"%.":>"TAX RATE AT RETIREMENT IS "100RR"%.":#H"INITIAL DEPOSITELTERED"::"ACCOUNT WILL NOW BE TAXED AS INCOME.":"A WITHDRAWAL FROM THE TAXED ACCOUNT OF"::"$"WT" WOULD BE EQUAL TO THE WITHDRAWAL"::"FROM THE TAX SHELTERED ACCOUNT.":"FROM TAXED ACCOUNT ";WT::"DO YOU WANT TO USE THE PRINTER Y/NTAX SHELTERED ";MS:B"MINIMUM CHARGE FOR TAXED ACCOUNT ";MT:q"YEARLY AMOUNT YOU WANT TO WITHDRAW AT":"RETIREMENT? ENTER $5,000 AS 5000 ":"FROM TAX SHELTERED ACCOUNT ";WS:WT(WSRRWS.5)4"THE WITHDRAWAL FROM THE TAX SHLUE OR A MINIMUM CHARGE"::"WHICH EVER IS GREATER.":Vv".15% IS ENTERED AS .15":"PERCENT FOR THE SHELTERED ACCOUNT ";CS:CSCS100:"PERCENT FOR THE TAXED ACCOUNT ";CT:CTCT100:"$35.50 IS ENTERED 35.50":"MINIMUM CHARGE FOR "FOR TAXED ACCOUNT ";RT:RTRT100:WD"NUMBER OF YEARS DEPOSITS WILL BE MADE ";Y:uN"YOUR PRESENT AGE ";AG:X"THE YEAR (SUCH AS 1985) ";YR:b"SOME ACCOUNTS HAVE A SERVICE CHARGE.":6l"THIS IS USUALLY A PERCENT OF THE"::"ACCOUNTS VA LESS MONEY TO "::"DEPOSIT. THE DEPOSIT AFTER TAXES"::"WOULD BE: $"DT:"ENTER THE DEPOSIT FOR THE TAXED ACCOUNT"::DT::DT$"$"(DT)&"ENTER INTEREST RATE"::"7.5% IS ENTERED AS 7.5 ":0"FOR TAX SHELTERED ACCOUNT ";RS:RSRS100:%: ";DS: TDS:210:DS$"$"T$C TADSRP:TTA:210:TA$" -"T$e DTDSTA:TDT:210:DT$"$"T$ "IF YOU PLACED YOUR DEPOSIT IN"::"A TAXED ACCOUNT, YOUR INCOME WOULD BE"::"LARGER AND THERE WOULD BE ADDITIONAL":L"TAXES AND YOU WOULD HAVE, "FOR THE TAX SHELTERED ACCOUNT ";PS:O "FOR THE TAXED ACCOUNT ";PT: "ENTER THE AMOUNT OF THE DEPOSIT."::"IT IS ASSUMED THAT THE DEPOSIT WILL BE"::"MADE ON JANUARY 1ST."::"ENTER $2,000 AS 2000": "DEPOSIT FOR TAX SELTERED ACCOUNTNT TAX RATE ":; "30% IS ENTERED AS 30 ";RP:RPRP100:_ "YOUR TAX RATE AT RETIREMENT " "30% AS 30 ";RR:RRRR100: "ENTER THE AMOUNTS FOR THE FOLLOWING:": "ENTER THE INITIAL AMOUNT OF PRINCIPLE": "$9,000 IS ENTERED AS 9000 ":"."T$T$"0":3005 (T$,L,1)"."T$T$"00":300J "T$T$".00":300V ,L(T$)o 6LSLT$" "T$:300~ @T$T$" " J T:"PRESS TO CONTINUE.";:X$ ^: hA$"Y"F0ĺA$(5);PS$;PT$: TOTALS r |"YOUR PRESEIGHTS RESERVED":A "****************************************"G ] T(100T.5)100 A$"Y"T(T.5):T$(T):300 T$(T):T.01T$".00":300 L(T$) L2(T$,1)"."(T$,1)"."290 (T$,L2,1)"."300 (T$,L1,1)l0dA$(11):S$" ": 17 SPACESQnE$" ": 11 SPACESjx130:340:1560:380u::5"****************************************":"TAX SHELTER BENEFITS":"(C) COPYRIGHT 1985 GERHALD HANSEL" "ALL R          ect the file to undelete ";:SEL$:SEL(SEL$)64:SEL$:SELMAX1ė:(7):620Xv34,5MODE$"T":TYPE$(SEL)"BAS"MODE$"A"TYPE$(SEL)"BIN"MODE$"M":DT(SEL,2)17HR1TYPE$(SEL)"SYS"MODE$"M" MAIN PROGRAM 215:N$(A);:21:TYPE$(A);:26:DT(A,1);:31:DT(A,2):AA1:MAXAL:PPPP39RD`N34,(37)XMAX0ĺ:" NO UNDELETED FILES WERE FOUND!"::"Insert another disk and press any key ":ZZ$:210b: SELECT FILE TO UNDELETE Nl"SelBLOCKS USED & ABORT IF TREE FILE_DT(A,3)PP: POINTER TO START OF DELETED FILE IN CATALOGDT(BUPP16):1310: GET FILE TYPEN1N16(BUPPN)0N$(A)N$(A)((BUPPN)):NN1:530NBZ:NB26NBNB26&"["(A64)"]";?0):ST0570:STORAGE TYPE & NO. OF CHAR'S IN NAMEY(BUPP1)0570: NO FILE NAMEDT(A,1)(BUPP17)256(BUPP18): KEY BLOCK NUMBER DT(A,2)(BUPP19)256(BUPP20):DT(A,2)256ĺ(7)"Tree files can't be undeleted"::NUMBER OF Undeleted files were found":::" Deleted Files":" File Name";:21:"TYPE";:26:"KEY";:31:"No of Bl's" READ FILE NAMES A1:MAX0:PP43:SP1:Z151:N$(Z)""PP512SP8PPPP5:SPSP12ST(BUPPBLE 16 "L"'S AND RETURNHrA1(DA$):511A,((DA$,A,1))128::144N|BFB1:CDRD:BL26:90:BFBF2::READ CATALOG & BIT MAP:NL(BU4)240:ZZ1NL:VN$VN$((BU4ZZ))::"Name of Volume ==> "VN$:>NF(BU37)256(BU38):NF" ATN"," PEEK"," LEN"," STR$"," VAL"," ASC"," CHR$"," LEFT$"," RIGHT$"," MID$"T765,104:766,104:767,96:390: MACHINE LANGUAGE DISASSEMBLY RETURN AT $2FD^ MACHINE LANGUAGE DISASSEMBLER CALLER hDA$"1400LLLLLLLLLLLLLLLL 2FDG":DISASSEM NEW "}6" TAB "," TO "," FN "," SPC("," THEN "," AT "," NOT "," STEP "," + "," - "," * "," / "," ' "," AND "," OR "," > "@" = "," < "," SGN "," INT "," ABS "," USR "," FRE","SCRN(",PDL","POS"," SQR"," RND"," LOG"," EXP"," COS"," SIN"MJ" TAN",""," LOMEM "," ONERR "," RESUME "," RECALL "," STORE "," SPEED= "," LET "," GOTO "," RUN "," IF "," RESTORE "," & "," GOSUB "," RETURN "," REM "," STOP "," ON "," WAIT "," LOAD "," SAVE "," DEF "," POKE "," PRINT "," CONT "," LIST "," CLEAR "," GET ","# "," IN# "," CALL "," PLOT "," HLIN "," VLIN " " HGR2 "," HGR "," HCOLOR "," HPLOT "," DRAW "," XDRAW "," HTAB "," HOME "," ROT= "," SCALE= "," SHLOAD "," TRACE "," NOTRACE "," NORMAL "," INVERSE "," FLASH "r"" COLOR= "," POP "," VTAB "," HIMEM: disk in drive # 1 and"= "press any key to continue!":ZZ$ B18:B218:B320:BUFFER256B1:BK25618:BT25620:X59:D196:HI0:SP1 A0106:CMD$(A):/ " END "," FOR "," NEXT "," DATA "," INPUT "," DEL "," DIM "," READ "," GR "," TEXT "," PRZ::32,0,191,128,236,2,208,8,96,3,96,0,8,2,0,96,32,218,253,32,58,255,32,190,253,96| N$(51),DT(51,3),TYPE$(51),CMD$(106) ::" ProDOS UNDELETE":34,5 10:"Do you wish to monitor the data recovery";:BR$ 13::"Place the ProDOS OCK:BL255LOBL255:HI12 ML13,LO:ML14,HIG ML: READ BLOCKM p INITIALIZATION ::RD128:WR129:READ/WRITE COMMANDS FOR BLOCK READ SUBROUTINE PRODOS BLOCK READ/WRITE ROUTINE S ML739:ZZ025:Z:MLZZ,":ZZ$:230x <(7)(7)::"Error Number "(222)" occurred in line number "(218)256(219)::"Undeleting ABORTED": F50 P READ PRODOS ROUTINE ZML739:ML10,96: DRIVE 1 dML3,CD: READ/WRITE COMMAND nML12,BF xLOBLL(104)24Ĺ104,24:6144,0:6145,0:6146,0:(4)"RUN PRODOS.UNDELETE"u ERROR HANDLING ROUTINE ~40170((222)255610 2"Error Number "(222)" occurred in line number "(218)256(219)::"Press any key to continue         he ENDFILE macro. With EXP ON, assemble the READ macro &both ways to see the generated code: EXP ON% READ FILE1;DATAREA;#256;0, READ FILE1;DATAREA;#256;ENDFILE1 EXP OFFCA To perform the conditi condition. If it is not 0, we will test the @>value of the third operand to determine if we should generate A?code for end of file checking (E=]3) or file not found (F=]3). ?=Notice the F option invokes the FOUND macro and the E option B@invokes trst byte, the character 0, @>and tests to see if it is equal to the first character of the A?macro operand, ]3 (equal is the only comparison performed). If DBthe first character of the third parameter is 0, we generate code CAto test for an errorle testing).A? Examine the test, IF 0=]3, in line #9. I have chosen to use A?the character 0 as an indication of an absent macro parameter. B@Macros must be flexible, so code is needed to test for optional Cparameters. The IF opcode takes the fi B@two new operands. The third operand is a test indicator and the CAfourth operand is a jump address. In line #67, the MLIE call has B@E as the third operand, and passes along ]4 from the READ macro <call (E indicates to expand code for end of fiREAD macro was updated to allow for end of file testing CAand jump to a routine to handle this condition. The first change ?=in the READ macro definition is use of the MOVEW (move word) A?macro which will be discussed shortly. The MLIE macro call hasrough 44 using GETMARK, SETEOF, and SETINFO.DB Let's go back to the top and take a closer look at the macros. CAListing 4 provides the complete set of macros, including new and changed macros.. Macro Changes and ImprovementsA? The e files. CAIf the output file does not exist, then CREATE is used to create a new file.@> OPEN, READ, WRITE, and CLOSE are unchanged from last time, B@except for the addition of end of file testing in READ. The big ?=changes are in line 37 thror routine has not changed.Generalized File Copy?= The file and buffer definitions have not changed, but the CAprogram makes use of several new macros to perform the file copy DBoperation. GETINFO is used to obtain information about thR.S). The B@macros are loaded in line #9 and the MLIERROR routine is loaded B@in line #46. These files begin with LST OFF and end with LST ON A?to cut down on the assembler generated output. Merlin Pro adds =;the suffix ".S" to the pathname. The er First of all, turn to Listing 3. We have taken advantage of B@two Merlin Pro features. The macros used last time in Listing 1 DBhave been moved to a seperate file (/MLI.MACROS/MACROS.S) and the A?MLI error routine has been moved (/MLI.MACROS/MLIERROll MLI functions and macro facilities, leaving the menu CAhandling, keyboard input, and screen output to be supplied as an DBexcercise for the reader. At the end of our discussion last time, 5we elaborated on some of the changes for this time.A? macros for using the MLI and excercised B@MLI functions that were not very complicated. This time, we are ?=going to expand on our macro usage and add facilities to our B@program to perform general purpose file copying. As before, our DBprogram wi The ProDOS MLI &Assembler MacrosPart 2By Ken Kashmarek30 September 1985B@ We are back with another edition of MLI & Macros. Last time, CAwe looked at some simple M%O====|====|====|====|====|====|====|====|====|====|====|====|====|====|====|====6"                         ȲҲӠӠܠұӠҲӠԠƍԠɮӯҍ󍪍ȱҠɮӯԮűȲҠɮӯԮŲű ȱұŲ䍠נűŲ䍠 űŲϠŲŲӍԠɮӯҍ󍪍ȱҠɮӯԮűȲҠɮӯԮŲű ȱұŲРЍ獪űŠű占ˠŲƠŲ荠ŠŲ占ϠŲŲנűŲҍűҠҍ䍪ŲŠŲűűű󍪍ĠΠűΠŲ፪РĠűűŠŲűӠɠ󍪍砳Ҡ΍Рƍ󍪍ŠɮӯӍ󍪍ϠűűϠŲŲűŲРčŲҠ    ݱݱٍōݱ΍΍΍ƠݲōƠݲݲٍōݲ΍΍͍Ԡ΍͍נàĠݱƠݱōŠݲ΍͍ àƠݱōƠݱݱōƠ͍Šà䍠ƠݱōƠݱݱٍٍݱٍٍōݱؠݱ΍΍͍נàĠݱƠݱōŠݲ΍͍ àƠݱōƠݱݱōƠðݱ͍ˠà占Šƻݱ͍Ơà占Šİݱ͍Ġà䍠ƠݱōƠݱݱؠݱōƠݱٍݱٍ؍ٍݱٍōݱؠݱ΍΍΍荠 ݱŠôݱƻݲȠݱݳݴ͍Ϡà䍠 ݱŠóݱƻݲ͍Šà占 ݲݱנݳݱנݴݱנݴݱŠ ԯԠύנݱ  ˬƬƍ  ΍נݱݲ  ō  Ĭō  Ȭō ͍ϠàݳݱŠ»ݱ͍Šà占Šûݱݱݱݱݱ͍ à ōנݱ ó ػōנݱ ōנݱݱݳ΍͍Πà占Šøݱݱݱݱݱݱ͍Ġà捠נݲݱנݳݱŠݱŻݴ͍Šà荠נݲݱףԠҍРŠҍРݱҠҠҍ٠͍Šà捠àٍƠݱōРÍŠРݱ΍Ҡҍ٠͍Ƞà荠ƠݲōݲРݱѠРԠƍɠàҠư ݱנݲ͍ŠàɠݱݲƠݳàҠҍōƠƽݳĠݴōƠŽݳŠݴ΍΍΍͍Ġà䍠àٍР     ҠԍΠ͠ˍ؍ҠؠԠΠӍҠԍŠ̠ӍűŠűРŰԠî͍Ԡ΍ҠŠ٠ҠōōҠԍӠԠƍ卪ԠՠĸōԠՠčؠՠƹŠՠҠȠҠōҠԠ΍ҠԍҠŠ٠ҠōōҠԍ ҠɮӯԮűȲҠɮӯԮŲű ȱұŲ ȲҲӠӠܠұӠҲӠԠƍԠɮӯҍ󍪍ȱԠĠƠ͍ŠŲŠű占ˠŲƠŲ荠ŠŲ占ӍԠɮӯҍ󍪍ȱԻ̻ЍנԻǻōנűנűűנűŠŲűРЍԠנǠŠԠנǠŠ獪ŠנŲŠŲűű󍪍ĠΠűΠŲ፪РŠűōĠűŠűƻōĠűōנݳݲōݳ΍͍󍪍ϠűűûűϠŲŲűŲРčűҠҍŲҠҍűҠҍ䍪ĠݱؠݲŠ΍РݲΠƠݴōƠ̽ݳŠԍ΍ƠŽݳŠԍ΍ƠǽݳԠԍѠԍ΍РݴԠ΍͍נàĠݱÍàݲƠݳݲōݳ΍àݲƠӠɠ󍪍砵Ҡ΍Рƍ󍪍ŠɮӯӍŠà ݲݱ ݳݱŠùݱ͍נà     ߂ꂍ`H h hh A ̵ LɮӯԮűɮӯԮŲJJJ JJaaa aa ʭ LL 씁͓L얁͕Lmmmm 킐 L 킐 ̵ ނ ނ  ČDGLX ͐KLR ̂ ̂DGL[ ЂKLULx  ȣ ゐ 肍߂ꂍ ɩ  ʭ ɩ