@L}5 _$% l0$)$$Hȱ$ UhL" `e$$%`$%`  R@P!( L(1   Y I`  d  Ld M * @  $ % CC$$)%1 Udߥ$9%: !0 S$% DD˙`  }J)Lr d M * @  $ % CC$$)%1 Udߥ$9%: !0 S$%} DD˙`  }J)Lr J  ((  p L ()   J}L= ( L 0q A    IB JC;? D W } LL  ` W )LA!  ߰")-݆ p" } $G@LL 08`Q")<2Q0 -G$Ș݆ UL# ; p8(()(0ʥ)NQ` }$GȘ݆LU )L ݆ L GȘ ݆LL )W>Z   HH)H }p h  hyhy D L> L JJ    ! LA*` BF }7'8  M HN H` 8 Z  \LdJJ!"! GFE@F (!L }EE !E^ ^ E E7EȩEdE/EȩE  D } .L }  ;F d  ;?F7F? ( .   Z D LL d } . D  L    p  E` , d)  D L) 0BM݊L݉} ML  N݆ L NLML [ TEqEHȱEqEh 0Gȹ G} HLL GɛL  LFREE SECTORS G) *Gȩ GȽG GȌ*jj >G} C8jJ3j2CD( C202C ԠBX` N 1? l LlD:RAMDISK}.COMLu L1 L ;LHL  T`  `8  ɐ     `TU  } L ? .  t`GBJ ~DEHI B V0dV!}QDEHI VF9 ,0 ,0 s0hhL  L` H hDHEh"}DEL8HI4 0 HI,0 0  9 .G VLO#},0 L4*IJ`llD1:AUTORUN.SYSNEED MEM.SAV TO LOAD THIS FILE.D8:MEM.SAV J y08 B|DEHI$} V0 0`B;DEL`?<0LV`@ʆ v s? F0Ξ05: [ BDEHI%} VY8 B V  @  /DE `E:D8:DUP.SYSERROR-SAVING USER MEMORY ON DISKTYPE Y TO &}STILL RUN DOS B;DE J  (` 9 V⪍ ઍ  -'}LLu ÝDEHILV 9 .l 9 .l  `` s$B BH(}I|DE V BLV nB,DE JLV B V BLVDEIʩ BꭝLu } 3E:}DISK OPERATING SYSTEM II VERSION COPYRIGHT 1984 ATARI CORP.A. DISK DIRECTORY I. FORMAT DISKB. RUN CARTRIDG*}E J. DUPLICATE DISKC. COPY FILE K. BINARY SAVED. DELETE FILE(S) L. BINARY LOADE. RENAME FILE M. RUN AT ADDRES+}SF. LOCK FILE N. CREATE MEM.SAVG. UNLOCK FILE O. DUPLICATE FILEH. WRITE DOS FILES P. FORMAT SINGLEL !N',}#"&))9(&*)/h)''-&؆莟R'S  vL/ˢ L }Insert DOS 2.0s, type Y Λx -}DEfHI 1莏#q! @ y0ɛ8A0,' ȅ 1 1ild! 1L!NO SUCH ITEMSELECT.} ITEM OR FOR MENU! 0 .z:*{}.|{ 1 0 0JB 18L%|DL/}%DIRECTORY--SEARCH SPEC,LIST FILE?[# 0 0 &|D3" 1L!NOT A DISK FILEN !B 1L!E# 1 !BD0}ED:}:1BJ|DE 1DEBHI 1 h0ߢ 0.1}  0?詛 1 y0YЛ 1 ;#L" ;#L! BL1TYPE "Y" TO DELETE...DELETE FILE SPEC2}COPY--FROM, TO?OPTION NOT ALLOWED036 FREE SECTORS COPYING---D2:GRTONE.ACTl# 0|D .L/%#3}##JB|DE 1BHID#E 1#0: B 1L!#͑### B 1#c$0SY4}S1}:## # # .#Ƚ# # 𩛙## 1,#PD#ELJ- <.BJD#E 5}1 1HH 0hh|DL%1}:̳# L% #D#EL% 1 0 . .0O% 1L!WILD CARDS NOT A6}LLOWED IN DESTINATION 0 <.|K}N 2 FORMAT. t* 5) 1L!`) 0NΞ 0 L1) 1 L!BAD LOAD FILELOAD FROM WHAT FILE?) 0 ?}0#B 1L!WHAT FILE TO LOCK?) 0 0$B 1L!WHAT FILE TO UNLOCK?DUP DISK-SOURCE,DEST DRIVES?TYPE "Y" IF OK TO US@}E PROGRAM AREACAUTION: A "Y" INVALIDATES MEM.SAV.FE! +L1   `*  70 2 2A} 0.* 1 y0 0)INSERT BOTH DISKS, TYPE RETURN^, 1 y038逍 N, 1L! ,B}C, t*  Lx+, 0 ^, 1 y0 , ,0,0 ,L+ ,I0 ,Vǭ0C}Ξ, 0 }, 1 y0C,ШC, 0K'!" H H 'h h Lx+!EF 5L1L!D,I,HhD}` NOT ENOUGH ROOMINSERT SOURCE DISK,TYPE RETURNINSERT DESTINATION DISK,TYPE RETURNE}`  `8 rL1`-* 1P* 1 y0Y`hhL!NAME OF FILE TO MOVE?- 0 0|DL% <.F},^ 1 70 0 .@L# .BJ 1  DEHIB V L1 ,} 1 70,L.  G}JB|,#P#DE 1 HI BDEHHII 1 B 1 ,^ 1 70,0La- B V,#PH},^ 1 70 0L#L!-* 1P* 1 y0Yj383}mm ݭI}}`8}``|* ? ɛ,`|:-)| / 1L!`DESTINATION CANT BE DOJ}S.SYS0 0H{ 24Δ 28/L!/) 2 Π 2 0 ξK}hAΞB,0 J 1 BDEHI,HÝDE 1HIHIDELSAVE-GIVE L}FILE,START,END(,INIT,RUN)O S0 1`BDEPHI V` S0H 1 L!M}0 0 1L~0`PLEASE TYPE 1 LETTER,0`hhL! 70 1L0L<1 ,;ɛ7,"ɛ:ݦ1ݥN}A"D|ݤD|ȩ:|ȩ|ɛ,,(/+.ީ1 1,ɛ`轤{NAMEO} TOO LONG B VL!` L1I H1EΝDL1|mDiE` V0`8d/8 i:222 1 LP}!ERROR- 170ɛ+,' 20*.. өr2 1``2TOO MANY DIGITSINVALID HEXAQ}DECIMAL PARAMETER800 0 8 00`,0'D800 H,ɛh`2L1NEED D1 THRU D8;uR} ECIMAL PARAMETER800 0 8 00`,0'D800 H,ɛh`2L1NEED D1 THRU D8;uLRS:H` B V`BDEhK)I JLVUVT`H 2` BHIhLV }}~ɛ  ;} 2T} ` RUN"D:MENU*.*"  \`bU}b U*.*"  \`b{ [ +'0@@A0@@[0@@2'!(} W}Π$('(POL(DThis Disk is full of ACTION! files marked with the Extender .O(ZHE(=Note: ACTION! is re X}quired to access these disk files.H(d--(%Also, there are several documentationna^(Vfiles marked with the Exten Y}der that you will want to read and/or print out.a(x,,($So... get out your ACTION! cartridge((( and start t Z}o examine these greatRO(Groutines so that you can begin to use them in your own programming.R(-*("Type to be [}gin using this disk!-(D:MENUso that you can begin to use them in your own programming.R(-*("Type to be &; WINDOWS by Harold Long, 1984; Thanks to Antic (tm) for the idea!MODULE ;Change to screen; ; Shifts ATASCII character c]}odes to ; "pure" screen codes (shuffles ROM ; character sequence.) ; BYTE FUNC ToScreen(BYTE c) BYTE temp ^} ;flow control temp=c&96 ;get msb's temp=temp RSH 5 ;and make lsb's IF temp=1 THEN ;1st _}group c=c!32 ;clear bit FI IF temp=2 THEN ;2nd group c=c%32 ;set bit `} c=c!64 ;clear bit FI IF temp=0 THEN ;3rd group c=c%64 ;set bit FI RETURa}N(c) MODULE ;Swap block;; Swaps memory blocks of equal size; Copyright (c) Harold Long, 1984; See ACS "MoveBlock" for db}ocumentationPROC SwapBlock=*(BYTE POINTER a,b,CARD sz)[$A085$A186$A284$A0$0$A5A5$22F0$A2B1$AA$A0B1$A291$8A$A091$C8$F3D0$Ac}1E6$A3E6$A5C6$EBD0$0BF0$A2B1$AA$A0B1$A291$8A$A091$C8$A4C4$F1D0$60];; Actually do the window by swapping; a data buffer d}area and screen memory.;PROC DoWindow(BYTE POINTER string, CARD SOF,lines,width,LOF)BYTE POINTER screen ;SAVMe}SCCARD II=PeekC($0058) ;Get upper left hand addrscreen=I+SOF ;add offsetFOR I=1 TO linf}es ;move codeDO SwapBlock(string,screen,width) screen=screen+LOF ;next line string=string+LOFg}ODRETURNMODULE ; BLKIO.ACT; Used to read in the graphics files; (c) 1983 ACS; Copyright (c) 1983; by Action Computh}er Services (ACS);; This software may be incorporated in; other software packages providing; that this copyright notice ii}s also; incorporated as well.; version 1.0; last modified August 25, 1983BYTE CIO_statusCHAR FUNC CIO=*(BYTE dev, CARj}D addr, size, BYTE cmd, aux1, aux2); IOCB# = dev; ICCOM = cmd; ICBA = addr; ICBL = size; ICAX1 = ak}ux1; ICAX2 = aux2[$29$F$85$A0$86$A1$A$A$A$A$AA$A5$A5$9D$342$A5$A3$9D$348$A5$A4$9D$349$A5$A6$F0$8$9D$34A$A5$A7$9D$34B$98l}$9D$345$A5$A1$9D$344$20$E456$8C CIO_status$C0$88$D0$6$98$A4$A0$99 EOF$60]CARD FUNC ReadBlock=*(BYTE dev, m} CARD addr, size)[$48$A9$7$85$A5$A9$0$85$A6$A5$A3$5$A4$D0$6$85$A0$85$A1$68$60$68$20 CIO$BD$348$85$A0$BD$349$85$A1$60]n}; Another variant of the "DoWindow" PROC,; pointing to the auxillary text windowPROC SmallWindow(BYTE POINTER string, CAo}RD SOF,lines,width,LOF)BYTE POINTER screen ;SAVMSCCARD II=PeekC($0294) ;Get upper left hand adp}drscreen=I+SOF ;add offsetFOR I=1 TO lines ;move codeDO SwapBlock(string,screen,width) q} screen=screen+LOF ;next line string=string+LOFODRETURN;; Demonstration routine; plunks in various; windor}ws in various places in screen.;PROC Wait() ;Wait for a whileBYTE I,JFOR I=0 TO 254DO FOR J=0 TO 25s}4 DO ODODRETURNPROC Main()BYTE ARRAY W1(1)=" This text is in a window!"BYTE ARRAY Pic(7680)BYTE I,J t} ;Temp'sBYTE POINTER screen,picscr ;pointers to alternate screensCARD FileSize,KGraphics(0) u};Clear screenPosition(2,8) ;Middle of stringPrintE("WINDOWS in Action! by Harold Long")PrintE("Converted v}from BASIC demo in Antic,")PrintE("November, 1984 by Jerry White and")PrintE("Dave Culbertson.")FOR I=1 to W1(0)DO ; Gow} swap characters around to match ; screen character ROM W1(I)=ToScreen(W1(I))ODWait()FOR I=0 TO 4 ;"DOx} WINDOWS" DO ; Randomizing values are chosen to ; 'bounce' window text near the ; pre-printed announcement. J=Rand(1y}0)+2 K=Rand(7)+6 ; Address adjustments are needed to ; eliminate artifacting on leading ; and trailing edges of windoz}w text. DoWindow(W1+3,K*40+J,1,W1(0)-2,0) Wait() DoWindow(W1+3,K*40+J,1,W1(0)-2,0) Wait()OD;; Following routine r{}eads in two graphics; files and overlays one on the other.;Graphics(15) ;Antic "E" mode displayscreen=Peek|}C($0058) ;start of screen memoryOpen(2,"D:OVERLAY.PIC",4,0) ;Open disk fileFileSize=ReadBlock(2,screen,7680) }};Get a picturePrintE(" ")PrintE(" GRAPHICS windows too!!")picscr=picClose(2)Open(2,"D:PICTURE.PIC",4,0) ;Next pi~}ctureFileSize=ReadBlock(2,picscr,7680) ;Get alternateClose(2)J=10For I=0 TO 3DO ; Funny address below (picscr+5) is } ; to adjust for different sized ; original artwork. It also shows ; how to shrink the window from the ; left hand sid}e. J=J+5 DoWindow(picscr+5,165,150,J,40) Wait() DoWindow(picscr+5,165,150,J,40) Wait()ODDoWindow(picscr+5,165,150},30,40);; Finally, text windows in text windows!!;PrintE(" Windows on windows!!")FOR I=0 TO 4DO K=Rand(3)+1 J=}Rand(7)+6 SmallWindow(W1+3,K*40+J,1,W1(0)-2,0) Wait() SmallWindow(W1+3,K*40+J,1,W1(0)-2,0) Wait()ODReturn; Author}'s comments:; *** WARNING *** This program will ONLY run on an 800XL because ; of the Graphics(15) call in the demo progra}m. 48K 400/800 owners; must replace the call with a "Build Antic 'E' PROCess.; *** Note to BBS users: *** You MUST provid}e your own graphics; files, named "PICTURE.PIC" and "OVERLAY.PIC", to run this demo.; The files HAVE to be in GR15 screen d}ump format, similar to the ; KOALA Pad "PICTURE" saves. I believe the ToScreen and SwapBlock; functions are the real contr}ibution of this program. The demo; routine is really pretty worthless. The DoWindow PROC might be; useful to flash messag}es on the screen for certain menu-driven; applications. Happy hacking!!he DoWindow PROC might be; useful to flash messagKMODULE ; TIME.ACT; copyright (c) 1984; Action Computer Services; All Rights Reserved; last modified February 8, 1984}; assumes already declared:;BYTE ARRAY buf(256);DEFINE JIFFIES="285" ; jiffies/hour;DEFINE JPD="$0" ; jiffies/day < 24; }NOTE: routines don't work past 1999; JIFFIES and JPD must be positiveTYPE TIME =[ BYTE T_DAY, T_MONTH, T_YEAR BYTE T_}HOUR, T_MIN, T_SEC] TIME tod, ; time of day dt ; delta timeBYTE ARRAY RTC(0)=$12BYTE FUNC GetVal(BYTE i)RETUR}N((buf(i)-'0)*10+buf(i+1)-'0)PROC PrintND(BYTE dev, n) PutD(dev, (n/10)+'0) PutD(dev, (n MOD 10)+'0)RETURNPROC Pri}ntTime(BYTE dev TIME POINTER t) PrintND(dev, t.T_HOUR) PutD(dev, ':) PrintND(dev, t.T_MIN) PutD(dev, ':) PrintND(d}ev, t.T_SEC)RETURNCARD FUNC Div60(CARD POINTER t) BYTE odd, remainder=$86 CARD res res = t^ odd = res & 1 res }= res RSH 1 res = res / 30 remainder = remainder LSH 1 t^ = remainder + oddRETURN(res)PROC UpdateTime() CARD tick}s BYTE t_lo=ticks, t_hi=ticks+1 BYTE th, d, days, month CARD h, m, s, dh BYTE ARRAY mdays(0)=[0 31 28 31 30 31 30} 31 31 30 31 30 31] t_lo = RTC(2) h = tod.T_HOUR m = tod.T_MIN s = tod.T_SEC WHILE RTC(2)=t_lo DO OD th = RTC(0)} RTC(0) = 0 t_hi = RTC(1) RTC(1) = 0 t_lo = RTC(2) s = s + Div60(@ticks) RTC(2) = ticks IF th#0 THEN ; oops, we }blew it m = m + th*18 s = s + (th*184 + 7)/15 FI IF s>59 THEN m = m + Div60(@s) FI IF m>59 THEN dh = Div6}0(@m) ; delta time offset to adjust for ; different clocks ticks = JIFFIES*dh s = s + Div60(@ticks) RTC(2) ==}+ ticks IF s>59 THEN WHILE s>59 DO s ==- 60 m == +1 OD WHILE m>59 DO m ==- 60} h == +1 OD FI h = h + dh IF h>23 THEN d = h/24 RTC(2) ==+ JPD*d h = h MOD 24 } tod.T_DAY ==+ d month = tod.T_MONTH days = mdays(month) IF month=2 AND (tod.T_YEAR & $3)=0 THEN} days = 29 ; leap year FI IF tod.T_DAY>days THEN tod.T_DAY ==- days tod.T_MONTH ==+ 1 } IF tod.T_MONTH>12 THEN tod.T_MONTH ==- 12 tod.T_YEAR ==+ 1 FI FI FI FI tod.T_H}OUR = h tod.T_MIN = m tod.T_SEC = sRETURNCARD FUNC DeltaDays(TIME POINTER t); return # days since Jan. 1, 1984 BYT}E dy, month CARD ddays CARD ARRAY mdays=[0 0 31 59 90 120 151 181 212 243 273 304 334] dy = t.T_YEAR - 84 ddays }= 365*dy + ((dy + 3) RSH 2) month = t.T_MONTH IF month>2 AND (dy & $3)=0 THEN ddays ==+ 1 ; leap year FIRETURN(dd}ays+mdays(month)+t.T_DAY-1)CARD FUNC DeltaTime(TIME POINTER t); returns delta time in dt; delta days as result BYTE c} CARD dtod, ddays BYTE dd_hi=ddays+1 UpdateTime() dt.T_SEC = tod.T_SEC - t.T_SEC c = 0 IF dt.T_SEC>127 THEN } c = 1 dt.T_SEC ==+ 60 FI dt.T_MIN = tod.T_MIN - t.T_MIN - c c = 0 IF dt.T_MIN>127 THEN c = 1 dt.T_MIN =}=+ 60 FI dt.T_HOUR = tod.T_HOUR - t.T_HOUR - c c = 0 IF dt.T_HOUR>127 THEN c = 1 dt.T_HOUR ==+ 24 FI dt}od = DeltaDays(tod) ddays = dtod - DeltaDays(t) - c dt.T_DAY = ddays dt.T_MONTH = dd_hiRETURN(ddays)BYTE FUNC DayOf}Week(TIME POINTER t)RETURN(DeltaDays(t) MOD 7)PROC PrintDate(BYTE dev TIME POINTER t) BYTE dow CARD ARRAY day(7), mo}nth(13) day(0) = "Sunday" day(1) = "Monday" day(2) = "Tuesday" day(3) = "Wednesday" day(4) = "Thursday" day(5) =} "Friday" day(6) = "Saturday" month(1) = "January" month(2) = "February" month(3) = "March" month(4) = "April" m}onth(5) = "May" month(6) = "June" month(7) = "July" month(8) = "August" month(9) = "September" month(10) = "October}" month(11) = "November" month(12) = "December" PrintTime(dev, t) PrintD(dev, " ") dow = DayOfWeek(t) PrintD(de}v, day(dow)) PrintD(dev, ", ") PrintD(dev, month(t.T_MONTH)) PutD(dev, ' ) IF t.T_DAY>9 THEN PutD(dev, t.T_DAY/10}+'0) PutD(dev, t.T_DAY MOD 10+'0) ELSE PutD(dev, t.T_DAY+'0) FI PrintD(dev, ", 19") PrintND(dev, t.T_YEAR) }PutDE(dev)RETURNPROC ZeroRTC() BYTE tick tick = RTC(2) WHILE RTC(2)=tick DO OD RTC(0) = 0 RTC(1) = 0 RTC(2) }= 0RETURN PROC SetTime() BYTE in DO Print("Enter date MM/DD/YY - ") InputS(buf) IF buf(0)=0 THEN ; for t}esting tod.T_MONTH = 2 tod.T_DAY = 8 tod.T_YEAR = 84 tod.T_HOUR = 23 tod.T_MIN = 57 tod.T}_SEC = 00 ZeroRTC() ELSE tod.T_MONTH = GetVal(1) tod.T_DAY = GetVal(4) tod.T_YEAR = GetVal(7) } Print("Enter time HH:MM:SS - ") InputS(buf) ZeroRTC() tod.T_HOUR = GetVal(1) tod.T_MIN = GetVal(4)} tod.T_SEC = GetVal(7) FI PutE() PrintDate(0, tod) PutE() Print("OK? ") in = GetD(7) Put(in) IF} in=$9B THEN EXIT FI PutE() UNTIL (in % $20)='y ODRETURNMODULE ; just in case? ") in = GetD(7) Put(in) IFX;**************************************;courtesy Lui Gonzalez/614-486-9392;returns random number from 0-MAX CARD FUNC RAND}OM(CARD MAX) BYTE LSB,MSB MSB=MAX RSH 8:LSB=MAX-MSB LSH 8 MAX=RAND(MSB+1)*256+RAND(LSB+1) RETURN(MAX);***************}***********************SB MSB=MAX RSH 8:LSB=MAX-MSB LSH 8 MAX=RAND(MSB+1)*256+RAND(LSB+1) RETURN(MAX);*************** RamXE and RamXL DOC This is the document}ation to RamXE, and RamXL. The CIS files are RAMXL.ACT, RAMXL.ASM, XLBAS.XMO, RAMXE.ASM, RAMXL.XMO, RAMX}E.XMO, and XEBAS.XMO. RAMXL.XMO is an USR routine for Atari BASIC. The file should be re}named RAMXL.OBJ and (L)oaded from the DOS menu. (It could also be named AUTORUN.SYS, which will cause it to } automatically load when DOS is booted.) RAMXL is actually an interrupt handler that allows programs to bank the} OS out on XL/XE computers without crashing the system. Normally when the OS is banked any interrupts wil}l crash the system, RAMXL takes the place of the normal OS interrupt code when the OS is out. When an in}terrupt occurs RAMXL is called, then it banks the OS back in and calls the OS interrupt routine. This al}lows VBLANK, keyboard, and DLI interrupts to occur when the OS is banked out. The first USR routine in R}AMXL is called to init the new interrupt code. This is done by the statement: A=USR(1605). } Once the new interrupt routines are installed you may call the other routine to move data to and from the RA}M under the OS. The format of the moveblock call is: A=USR(1577, , , ). There are three RAM blocks under the OS that are usable, they ar}e: $C000 to $CFFF 49152 to 53247 $D800 to $DFFF 55296 to 57343 } $E400 to $FFF9 58368 to 65529 This adds 13K to the usable RAM on XL/XE computers. The file XLBAS.XMO} is a short BASIC program that shows one use for RAMXL. It reads in a text file from the disk, the store}s it in the RAM under the OS. When you press a consol key, the screen is loaded from the extra RAM by RAMXL. } This allows very fast screen redraws. NOTE: RAMXL will NOT work with OS/A+ DOSXL, since DOSXL } also uses the RAM under the OS. RAMXL.ACT is an Action! equivilant to RAMXL. It al}lows use of the RAM under the OS from Action! by adding a new MoveBlock routine. } RAMXE.XMO is also an USR for Atari BASIC, but it allows access to the 64K of banked RAM in the 130XE. To } use RAMXE first check to see if the computer is a 130XE, by the statement: A=USR(1536).} If A=0 then the program is running on a 130XE, otherwise it is NOT a 130XE. The extra RAM is a}ccessed by the statement: A=USR(1577, , , , , ). The RAM in the 130XE is organized into 5 banks numbered 0} to 4. Each bank is 16K (16384 bytes) long and is located in the middle 16K of RAM ($4000 to $7FFF, 1638}4 to 32767). Bank 0 is the "normal" RAM that is available when the machine is turned on, the other 4 bank}s are accessable by using RAMXE. The file XEBAS.XMO is a short demonstation of how to use RAMXE. It rea}ds in a text file, then saves it into the banked RAM. When the consol keys are pressed, you page thru th}e text, as it is moved from the banked RAM to the screen RAM. NOTE: RAMXE is NOT compatible with Atari DO}S 2.5, since both use the banked RAM in the 130XE. mpatible with Atari DOgMODULE; RAMXL.ACT;-------------------------------------; Copyright 1985 by Daniel L. Moore.; RAMXL may not be sold, but ma }y be; freely copied and distributed.;-------------------------------------; Last modified on 03/30/85;------------------- }------------------; Support routines for the "extra" ; 14K of RAM in XLs that is located; under the OS ROM.; When an } interrupt occurs and the OS; is banked out, the RAMXL will bank; the OS in, and then call the ROM OX; interrupt handler. } When control; returns from the ROM OS, the OS is ; banked out, and control is returned; to the original program.; Onl }y the NMI and IRQ vectors are ; supported, since the XL hardware banks; the OS ROM in automatically when a ; chip reset o }ccurs (the RESET button).DEFINE INT_VECTOR = "$FFF0"CARD NMI_Vector = $FFFA, RES_Vector = $FFFC, IRQ_ }Vector = $FFFE, Return_Addr BYTE PortB = $D301, NMIEN = $D40E, X_StoragePROC OS_In }=*() ; ROM OS resident [$AD PortB ; LDA PortB $09 $01 ; ORA #$01 toggle OS bit to ON $8D PortB ; STA PortB } $60] ; RTSPROC OS_Out=*(); ROM OS not resident [$AD PortB ; LDA PortB $29 $FE ; AND #$FE toggle OS bit } to OFF $8D PortB ; STA PortB $60] ; RTSPROC JMP_Vector=*() [$4C $FFFF] ; JMP $FFFF PROC Handle_Interr }upt=*() ; Handle the interrupt that just occured. [$8E X_Storage ; STX X_Storage $AA ; TAX } A=the interrupt number $20 OS_In ; JSR OS_In ; Get the address of the desired interrupt routine $BD INT_VE }CTOR ; LDA INT_VECTOR,X $8D JMP_Vector+1 ; STA JMP_VECTOR $BD INT_VECTOR+1 ; LDA INT_VECTOR,X $8D JMP_Vector+2 ; STA } JMP_VECTOR+1; Setup the stack to fake an interrupt and call; the OS ROM interrupt code.; First the return address $AD } Return_Addr+1; LDA Return_Addr+1 $48 ; PHA $AD Return_Addr ; LDA Return_Addr $48 ; PHA; Th }en the proccessor status register $58 ; CLI enable IRQs, for Stage 2 VBLANK $08 ; PHP } $4C JMP_Vector] ; JMP JMP_VectorPROC Return_Here=*(); Return here after the ROM OS interrupt code runs; Bank the OS ou }t, the return to the; original program. [$20 OS_Out ; JSR OS_Out $AE X_Storage ; LDX X_Storage $68 } ; PLA from NMI.Handler or IRQ.Handler $40] ; RTI PROC NMI_Handler=*(); Handle NMIs that occur while the } OS is; banked out. Save the A reg, then get ; the vector number and call Handle_Interrupt. [$48 ; PHA $A9 }$0A ; LDA #$0A $4C Handle_Interrupt]; JMP Handle_InterrruptPROC IRQ_Handler=*() [$48 ; PHA $A9 $ }0E ; LDA #$0A $4C Handle_Interrupt]; JMP Handle_Interrrupt;-------------------------------------; End of actual } interrupt code.; All that is left is installing ; the vectors to the routines.;------------------------------------- PR }OC Install_CharSet(); Copy the ROM char set at $E000 to $E3FF; to the RAM bank, so that characters do; not flicker when th }e RAM is accessed.; If this is done, do not use the RAM; from $E000 to $E3FF (57344 to 58367). BYTE POINTER where BYTE te }mp FOR where=$E000 TO $E3FF DO OS_In() temp=where^ OS_Out() where^=temp OD OS_In()RETURNPROC Install_Interru }pts() Return_Addr=Return_Here; Set the return address pointer NMIEN=0 ; Turn all NMI interrupts off. [$78] ; SEI Tu }rn all IRQ interrupts off. OS_Out(); Install the new interrupt routines; vectors at $FFFA to $FFFF under the; OS ROM. }NMI_Vector = NMI_Handler IRQ_Vector = IRQ_Handler OS_In() [$58] ; CLI Turn IRQs back on. NMIEN=$40; Turn NMIs back }on. Install_CharSet()RETURN;-------------------------------------; Now the routine that lets you get to; the RAM that }is under the OS.; There are actually 2 memory areas; present: ; 4K at $C000 to $CFFF, 49152 to 53247; 10K at $D800 t }o $FFFF, 55296 to 65535;; The last 6 bytes of the 10K area are not; usable, since that is where the interrupt; routines a }re located. Therefore do not; use any RAM above $FFF9 (65529) or you; will crash the system.;---------------------------- }--------- PROC MoveBlockXL(BYTE POINTER dest,source, CARD size); This is a version of MoveBlock that lets; you use the ex }tra RAM in XLs. OS_Out() FOR dest=dest TO dest+size DO dest^=source^ source==+1 OD OS_In()RETURNMODULE; For u }ser. DO dest^=source^ source==+1 OD OS_In()RETURNMODULE; For u 7;; TODOS.ACT;; This little PROCedure allows you to exit any ACTION! program to the; ATARI DOS 2.0S DUP.SYS Menu.;; $} WARNING: This PROC will work properly ONLY if you have WARM booted; your system with an ATARI 2.0S DOS.SYS file$} on the diskette; in Drive #1. Furthermore, you must have a diskette with; with DUP.SYS on it in Dri$}ve #1 before calling this PROC.;; You may return to the ACTION! environment by selecting option "B"; (Run Cartridge) fro$}m the DUP.SYS Menu, but your ACTION! program will; have been wiped out by the exit to DUP.SYS!;;; Enjoy!;; Brad Paul$}sen [CIS PPN 70035,1050]PROC ToDOS() [ $6C$0A$00 ]RETURNo DUP.SYS!;;; Enjoy!;; Brad Paul$VCARD FUNC DivC(CARD a, b); returns a / b, a MOD b in rem CARD ab=$82, cd=$84, rem=$86 ab = a cd = b rem = 0[$85(}A5$29F0$8A2$8226$8326$8726$38$83A5$84E5$A8$87A5$85E5$490$8785$8384$CA$E7D0$82A5$2A$A2$0$83A4$8684$A085$A186$60$10A2$8226$8)}326$2A$4B0$84C5$390$84E5$38$CA$EFD0$8226$8326$8685$82A5$83A6$A085$A186$60]82A5$2A$A2$0$83A4$8684$A085$A186$60$10A2$8226$8(M;; ;ȮԠ ;-}٠ ;Ġʮڠ ; ;-} ; ; ;Ӡ̠͠ĠΠ-} ;ŠŠԠŠĠԠԠ ;ΠŠɠҠԮԠ ;ӠӠ٠ǠŠӠƠ ;Š-}ҮŠŠԠΠϠ ;ӠϠŠĠ̠ҭ ;ӠΠŠĮӠ͠ ;̠ˠȠ-}ɠҠ ;Ӯ ;;-} MODULEBYTE ARRAY line(255),file(14)BYTE i,byt;ӠàӠ ;ҠȠԠԠӠΠ BYTE FUN-}C bit(BYTE m,p)BYTE vIF m<4 THEN m=7-mELSE m=11-mFIIF p=0 THEN IF byt>127 THEN byt==-128 v=1 FIELSEIF - }p=1 THEN IF byt>63 THEN byt==-64 v=1 FIELSEIF p=2 THEN IF byt>31 THEN byt==-32 v=1 FIELSEIF p=3 THE- }N IF byt>15 THEN byt==-16 v=1 FIELSEIF p=4 THEN IF byt>7 THEN byt==-8 v=1 FIELSEIF p=5 THEN IF by- }t>3 THEN byt==-4 v=1 FIELSEIF p=6 THEN IF byt>1 THEN byt==-2 v=1 FIELSEIF p=7 THEN IF byt>0 THEN - } byt==-1 v=1 FIELSE v=0FIv== LSH mRETURN(v);ԠРӠҠ ;ӠŠϠŠĠ PROC PrintCH()- }BYTE ARRAY ch1(320),ch2(320)CARD chset=[57344],chad,ctr,ctr1=[0], ctr2,ctr3=[0]BYTE chr=[0],v,n1,n2device=2;Ԡ-}ŠϠ Zero(ch1,320);ϠԠĠ Zero(ch2,320)FOR ctr1=1 TO line(0) DO chr=line(ctr1);̠ -} ctr3==+1 ;ĠŠΠ ;٠ƠҠ IF chr<32 OR (chr>127 AND chr<160) -} THEN chad=chr+64 ELSEIF (chr>31 AND chr<96) OR (chr>159 AND chr<224) THEN chad=chr-32 ELSE c-}had=chr FI chr=chad IF chad>127 THEN chad==-128 FI chad==*8+chset FOR ctr=0 TO 7 DO byt=Peek(chad+ctr) -} IF chr>127 THEN byt==!255 FI FOR ctr2=0 TO 7 DO v=bit(ctr,ctr2) ;ԠԠӠΠ -}IF ctr<4 THEN ch1((ctr3-1)*8+ctr2)==+v ELSE ch2((ctr3-1)*8+ctr2)==+v FI OD OD ;Ơ-}ӠŠΠ ;Ҡ̬ԠӠ IF ctr1 MOD 40=0 OR ctr1=line(0) THEN -} ctr3==*8-1 n1=ctr3 MOD 256 n2=ctr3/256 Put(27) Put(i) Put(n1) Put(n2) ;Р FOR ctr=0 TO ctr3 D-}O Put(ch1(ctr)) OD PutE() Put(27) Put(i) Put(n1) Put(n2) ;͠ FOR ctr=0 TO ctr3 DO -} Put(ch2(ctr)) OD PutE() Zero(ch1,320);ϠӠԠ Zero(ch2,320);ΠŠŠ ctr3=0 -} ;ŠӠ FIODRETURN;ΠӠĠԠ PROC InputL()BYTE consol=53279Close(1)Close(0)Poke(-}82,0)Graphics(0)Print("ENTER FILENAME ")InputS(file)Open(1,file,4,0)DO Print("INGLE/OUBLE DENSITY ") Close(3) Op-}en(3,"K:",4,0) i=GetD(3) UNTIL i='S OR i='D ODIF i='S THEN i='K;Š ELSE i='L;Š FIClose(-}3)PrintE("PRESS TO ABORT")Open(2,"P:",8,0)PrintDE(2,"@UA")DO InputSD(1,line) PrintCH() IF EOF(1) THEN -} EXIT FI IF consol=6 THEN EXIT;Ԡ͠Š FIODdevice=0;ԠŠ Close(1);ŠӠ-} Close(2)RETURNonsol=6 THEN EXIT;Ԡ͠Š FIODdevice=0;ԠŠ Close(1);ŠӠ, Ȯԛ Λ ĠڛThis program is set up to print pro-grams or1} text as it looks on thescreen using the ATARI character set.If you wish you could write a shortPROC to download a special1 } characterset and use that.The main program is InputL which opensup channels: #1 Input file, Disk or C1!}assette #2 Output to printerChannel #3 is used to GET the densityof the printer graphics. The firstthing that hap1"}pens is the program willask you for the name of the file youwant to print and opens channel #1 todisk or cassette. It wil1#}l then askfor the density of dots, you have 2to choose from and . Itwould be easy to add by addin1$}g: ELSEIF i='Q THEN i='zThe program then opens the printer,sets it to TOF, unidirectional, and4/72 LF.1%}The last part is a DO OD loop thatkeeps going until the file hit EOF orthe key is hit.In the DO OD loop the progra1&}m readsin a line from the input file, andthen goes to: PROC PrintCH()------------------------------------- 1'} àȨThis PROC sets up the arrays that areused to print the characters and prints the line.There are 4 co1(}unters that are usedhere: ctr: 1st time it is used is for reading off the bytes of the1)} characters 2nd time is to dump the arrays to the printer ctr1: is used to read each 1*} character for the line ctr2: is used to put the bit information for each pri1+}nt column in the arrays ctr3: is used to print only 40 characters at a time 1,} it is also used to show how many columns to printI use 2 BYTE ARRAYS: ch1: this is 1-}the top half of the character ch2: this is the bottom half of the characterEach chara1.}cter in the character set is stored reading left-right. Theprinter reads the characters top-bottom, so the characters hav1/}e tobe translated. I do that by using: BYTE FUNC bit(BYTE m,p)------------------------------------- 10} ŠàŠ𩛛fig 1. The bit configuration of (F) 01234567 val byte pin fired11} 8 128 00000000 0 0 7 64 01111110 126 1 6 32 01100000 96 2 5 16 01111100 124 3 val 12} 11 118886 top 02200040------------------------------------- 8 12813} 01100000 96 4 7 64 01100000 96 5 6 32 01100000 96 6 5 16 00000000 0 7val 14} 22 22 04400000 bottom-------------------------------------Most printers are tou15}chy about whatis sent to them. So if you tried to send all 8 bits at once one valuemight be 13 which is a CR. That iswh16}y I decide to break the characterin half.The variable m which is ctr is set for the value 4-7, and is used tofind out wh17}ich pins are fired.The variable p is a control. In byte1 of fig. 1 the value is 126. If thetest IF p=0 THEN wasn't there18} then64 would be added to col.0 and notcol.1. The test may look redundantbut it is necessary.Again looking at byte 1 if19} p=1 thenbyt is decreased and v=1 to send thevalue for which pin to be fired back.At the end v is left shifted to getthe1:} correct value to send back.------------------------------------- ӛLike I said the program was wr1;}ittenfor a Gemini 10x or compatiblemachines, but you can change the setup codes to your machine. Also youcan change the 1<}length of the printedline by changing: BYTE ARRAY ch1(320),ch2(320)Zero(ch1,320)Zero(ch1,320)IF ctr1 mod 40=0 or ctr11=}=line(0) THEN Zero(ch1,320)Zero(ch1,320)These are all in PROC PrintCH(), andwhere 320 is it would be changed to(the l1>}ength you want)*8. The 40would be change to the length youwanted.The maximum characters are sinlge: 60 1?} double: 120 quad : 240If you have at theend of a line make sure you have aspace after it. I1@}f there isn't youget L shaped character, and this wasthe only way I could get rid of it.you have aspace after it. I0`;This program will change the density of any PERCOM compatible drive from;single to double density and vice versa. It also 5B}displays the values;in the drive option table before and after the change.;Note that by changing the CHANGE_DENSITY() proce5C}dure you could configure;the disk controller to handle a double sided or 96TPI (quad density);drive, assuming your controll5D}er can handle these drive types.;(The PERCOM RFD-1 and ATR8000 can, the TRAK, INDUS, etc. can't) DEFINE RDOCMD="$4E", WRO5E}CMD="$4F", TIMEOUT="$0F", SIOUT="$80", SIOIN="$40", BUSSID="'1"BYTE DCB=$0300, DDEVIC=$0300, DUNIT=$0301, 5F} DCOMND=$0302, DSTATS=$0303, DTIMLO=$0306, DRIVENUMBERCARD DBUF=$0304, DBYTE=$0308, DAUX12=$030A, SECTOR_SIZE,5G}BUF256BYTE POINTER PTRBYTE ARRAY BUFFER(12) PROC SIO=$E459() ;define location of serial bus handlerPROC FIRE_IO(BY5H}TE TIME, COMND, STATS CARD BUF, BYTES);this routine sets up the Device Control Block;and calls the SIO routine in the OS.5I} DDEVIC=BUSSID DUNIT=DRIVENUMBER DCOMND=COMND DTIMLO=TIME DSTATS=STATS DBUF=BUF DBY5J}TE=BYTES SIO()RETURNPROC OPTION_TABLE_ERROR();dummy error handling routine, put your own here I got lazyRETURN5K}PROC OPTION_TABLE(BYTE CMND) BYTE STATSD ;STATSD controls the direction of data 5L} ;transfer IF CMND=RDOCMD THEN ;read option table STATSD=SIOIN ;set for data in E5M}LSEIF CMND=WROCMD THEN ;write option table STATSD=SIOUT ;set for data out ELSE OPTION5N}_TABLE_ERROR() RETURN FI FIRE_IO(TIMEOUT,CMND,STATSD,BUF256,$0C) IF DSTATS#1 THEN 5O} OPTION_TABLE_ERROR() FI RETURNPROC TEST_OPTION_TABLE();this routine reads the option table and5P} displays the values BYTE BUFBYTE CARD BUFCARD PTR=BUFFER BUF256=PTR OPTION_TABLE(RDOCMD) PR5Q}INT("TRACKS ") BUFBYTE=PTR^ PRINTBE(BUFBYTE) PRINT("STEP RATE ") PTR==+1 BUFBYTE=PTR^ 5R} PRINTBE(BUFBYTE) PRINT("SEC/TRACK ") PTR==+1 BUFCARD=256*PTR^ PTR==+1 BUFCARD==+PTR^ 5S} PRINTCE(BUFCARD) PRINT("SIDES ") PTR==+1 BUFBYTE=PTR^ PRINTBE(BUFBYTE) PRINT("DE5T}NSITY ") PTR==+1 BUFBYTE=PTR^ PRINTBE(BUFBYTE) PRINT("SEC SIZE ") PTR==+1 BUFCAR5U}D=256*PTR^ PTR==+1 BUFCARD==+PTR^ PRINTCE(BUFCARD) PRINT("PRESENT ") PTR==+1 BUFB5V}YTE=PTR^ PRINTBE(BUFBYTE)RETURNPROC CHANGE_DENSITY(BYTE NEW_DENSITY) PTR=BUFFER BUF256=PTR OP5W}TION_TABLE(RDOCMD) ;read option table IF NEW_DENSITY=1 THEN ;sets single density PTR==+5 PTR^=0 5X} ;single/double flag PTR==+1 PTR^=0 ;high byte of sector size PTR==+1 5Y} PTR^=$80 ;low byte of sector size OPTION_TABLE(WROCMD) ;write new info ELSEIF NEW_DENSI5Z}TY=2 THEN ;sets double density PTR==+5 PTR^=4 ;density flag PTR==+1 PTR^=1 5[} ;high byte of sector size PTR==+1 PTR^=0 ;low byte of sector size OPTI5\}ON_TABLE(WROCMD) FIRETURNPROC MAIN() BYTE CHANGE_TYPE PRINTE("ENTER THE DRIVE NUMBER YOU WISH TO")5]} PRINTE("CHANGE THE DENSITY OF") DRIVENUMBER=INPUTB() TEST_OPTION_TABLE() PRINTE("ENTER '1' IF 5^}YOU WANT TO MAKE DRIVE") PRINT("NUMBER ") PRINTB(DRIVENUMBER) PRINTE(" SINGLE DENSITY") PRINTE("E5_}NTER '2' IF YOU WANT TO MAKE DRIVE") PRINT("NUMBER ") PRINTB(DRIVENUMBER) PRINTE(" DOUBLE DENSITY") 5`} CHANGE_TYPE=INPUTB() CHANGE_DENSITY(CHANGE_TYPE) TEST_OPTION_TABLE()RETURNDOUBLE DENSITY") 4hMODULE ;Plot7 submoduleBYTE xprev,yprevCARD ARRAY yLoc(192)PROC Plot7(BYTE px,py) BYTE i BYTE ARRAY pos, bm=[$C09b} $30 $0C $03], am=[$3F $CF $F3 $FC], cm=[$00 $55 $AA $FF] pos=yLoc(py) pos(px RSH 2)==&am(px&3)%(bm(px&3)&cm(col9c}or)) xprev=px yprev=pyRETURNBYTE FUNC Abs(INT m) IF m<0 THEN m=-m FIRETURN(m)PROC DrawTo7(BYTE x2,y2) BYTE x,9d}y,xend INT dx,dy,incr1,incr2,d dx=Abs(x2-xprev) dy=Abs(y2-yprev) d=(dy LSH 1)-dx incr1=dy LSH 1 incr2=(dy-dx)*29e} IF xprev>x2 THEN x=x2 y=y2 xend=xprev ELSE x=xprev y=yprev xend=x2 FI WHILE x79 THEN 9z} rx=159-cx ELSE rx=cx FI IF cy>47 THEN ry=95-cy ELSE ry=cy FI 9{} IF rx>ry THEN ry=Rand(ry) Mich_Circle(ry) ELSE rx=Rand(rx) Mich_Circle(rx) 9|} FI CONSOL=8 IF CONSOL#7 THEN EXIT FI OD IF CONSOL#7 THEN EXIT FI ODRETURN9}}I CONSOL=8 IF CONSOL#7 THEN EXIT FI OD IF CONSOL#7 THEN EXIT FI ODRETURN8MODULE ;Example for SteveDEFINE PHA="$48", PLA="$68", RTI="$40", JMP="$4C"BYTE WSYNC=$D40A,COLPF2=$D018,COLBK=$D01=}ACARD VDSLST=$200,SDLSTL=$230,XITVBL=$E462CARD POINTER SAVMSC=$58BYTE ARRAY dlist(0)=$680PROC dlistval=*()DEFINE BL8="$=}70", BM0="$02", BM1="$06", DLI="$80", LMS="$40", JVB="$41" [ BL8 BL8 BL8 BM0+LMS+DLI dlistval ;Must=} be plugged! BM1+DLI BM0 BM0 BM0 BM0 BM0 BM0 BM0 BM0 BM0 BM0 BM0 BM0 BM0 BM0 BM0 BM0 BM0 BM0 BM0 BM0 =}BM0 BM0 JVB dlist ]PROC dlih2=*() [ PHA ] WSYNC=0 COLBK=$C0 COLPF2=$C0 [ PLA RTI ]; Interrupt for Mode 1 line=}PROC dlih1=*() [ PHA ] WSYNC=0 COLBK=$40 VDSLST=dlih2 [ PLA RTI ]PROC vblih=*() VDSLST=dlih1 [ JMP XITVBL ]=}PROC MyPrint(CARD loc,CHAR POINTER string) BYTE length,i,j CHAR POINTER cursor cursor=SAVMSC^+loc length=string^=} string==+1 FOR i=1 TO length DO j=string^ IF j<96 THEN IF j>31 THEN j==-32 ELSE j==+=}64 FI FI cursor^=j string==+1 cursor==+1 ODRETURNPROC Main() CARD VVBLKD=$224 CARD POINTER=} lmsptr BYTE NMIEN=$D40E, COLOR1=$2C5,COLOR2=$2C6,COLOR4=$2C8 Graphics(0) lmsptr=dlistval+4 lmsptr^=SAVMSC^=} MoveBlock(dlist,dlistval,29) NMIEN=0 VVBLKD=vblih SDLSTL=dlist NMIEN=$C0 COLOR1=$0E COLOR2=$90 COLOR4=$=}90 Zero(SAVMSC^,960) MyPrint(14,"H O W D Y !!") MyPrint(40+3,"this is mode 1") MyPrint(40+20+8*40+8,"and this is mo=}de 0 again") DO OD ;Endless loopRETURNPrint(40+3,"this is mode 1") MyPrint(40+20+8*40+8,"and this is mo<:; by Harold Long, 1985;; Global section; Defines:DEFINE true="1"DEFINE false="0"DEFINE sswap="0" ;whichA} of three routinesDEFINE scut="1" ;are we doing...DEFINE spaste="2"; Parameter list for paste routine; "ToBCol" &A} "ToBRow" are redundant but; needed so we can 'flip' the list and; move things back and forth.BYTE POINTER FrScr A} ;"From Screen"BYTE FrTCol ;top colBYTE FrTRow ;top rowBYTE FrBCol A} ;bottom colBYTE FrBRow ;bottom rowBYTE POINTER ToScr ;"To Screen"BYTE ToTCol A} ;top colBYTE ToTRow ;top rowBYTE ToBCol ;bottom colBYTE ToBRow A} ;bottom rowBYTE SDMCTL=$22F, DINDEX=$57, RAMTOP=$6ACARD SDLSTL=$230, SAVMSC=$58BYTE ARRAY PMHshd(8)=[0 0 0 0 0 0 A}0 0] ;shadow regs for $D000BYTE key=764BYTE cpbuf=[0] ;active cut/paste bufferCARD scrn1,scrn2,scrn3 ;pointers A}to alternate screensBYTE scrno ;active screen #CARD MEMLO=$743, codebase=$491, codesize=$493, size, INITAD=$A}2E2BYTE ARRAY colpf(0)=$2C4 BYTE ARRAY colsv(20)CARD dsl1, dsl2, dsl3, text, lastgr, textmBYTE ARRAY fname(18) A} ;file name+extBYTE ARRAY file1(18),file2(18) BYTE ARRAY str132(18)BYTE POINTER ptrBYTE ARRAY buf(19)BYTE ARRAY Dir_strA}ing(960)BYTE ARRAY foo(3)BYTE ARRAY i(2),j(2),pi(4),pj(4), cp(4)BYTE ti,tjBYTE ARRAY cmd(5)BYTE ic A} ;input command char; Save one of three screen's color reg'sPROC SvCol(BYTE n) ; n=0:2BYTE IFOR I=0 TO 4DO colsv(I+nA}*5)=colpf(I)ODRETURN; Force cut/paste to last displayPROC CPcol()BYTE IFOR I=0 TO 4DO colsv(I+15)=colpf(I)ODRETURNA}; Restore color reg'sPROC RsCol(BYTE n)BYTE IFOR I=0 TO 4DO colpf(I)=colsv(I+n*5)ODRETURN; Swaps memory blocks of A}equal size; Copyright (c) Harold Long, 1984; See ACS "MoveBlock" for documentation;PROC SwapBlock=*(BYTE POINTER a,b,CARD A}sz);[$A085$A186$A284$A0$0$A5A5$22F0;$A2B1$AA$A0B1$A291$8A$A091$C8$F3D0;$A1E6$A3E6$A5C6$EBD0$0BF0;$A2B1$AA$A0B1$A291$8A$A0A}91$C8;$A4C4$F1D0$60]; READPIC - Reads MicroIllustrator; picture files. Original code by; Robert E. Wilson, REW ConsultiA}ng.;; Modified for Action! and converted; to code blocks by Harold Long,; Bolton, MA. 14-Jan-1985;PROC GetByt=*() [;PrA}ovides CCIO and bailout functions$A5$AA$C5$AC$D0$06$A5$A9$C5$AB$F0$16 $A2$10$A9$00$8D$58$03$8D$59$03$20$56 $E4$30$09$E6$A9A}$D0$02$E6$AA$60$A9$01 $85$A0$68$68$60];Provides screen address calculationPROC NxtPnt=*() [$24$A2$50$2C$C6$A5$F0 $0E$A9$5A}0$18$65$A3$85$A3$A9$00$65$A4 $85$A4$60$A9$60$85$A5$C6$A6$F0$0E$A9 $28$18$65$AD$85$A3$A9$00$65$AE$85$A4 $60$A9$02$85$A6$A9$A}01$18$65$AD$85$AD $85$A3$A9$00$65$AE$85$AE$85$A4$60];BYTE FUNC ReadPic=*() [; Segment contains 181 bytes.$A5$58$85$AD$8A}5$A3$A5$59$85$AE$85$A4 $A9$60$85$A5$A9$02$85$A6$A9$07$8D$52 $03$A9$A0$8D$54$03$A9$00$8D$55$03$85 $A7$85$AC$A9$FF$85$AB$85$A}A9$85$AA$20 GetByt$85$A0$A5$A9$C9$07$F0$0A$C9$0C $F0$10$C9$1A$F0$2B$D0$EB$A5$A0$4A$6A $6A$85$A2$18$90$E1$A9$05$85$A1$20GetA}Byt$A6$A7$9D$C4$02$E6$A7$C6$A1$D0$F2 $20GetByt$85$AB$20GetByt$85$AC$18$90 $C2$A5$A2$F0$24$20GetByt$85$A1$29$7F $D0$0F$20GA}etByt$85$A8$E6$A8$20GetByt $85$A7$18$90$06$85$A7$A9$01$85$A8$A5 $A1$29$80$85$A1$20GetByt$85$A0$A0$00 $A5$A0$91$A3$20NxtPntA}$A5$A2$F0$EE$C6 $A7$D0$04$C6$A8$F0$C2$A5$A1$F0$E9$D0 $E0]PROC End=*()[$68$AA$68$CD$2E8$90$5$CD$2E6$90$F3$48$8A$48$60]A}MODULE ; BLKIO.ACTBYTE CIO_statusCHAR FUNC CIO=*(BYTE dev, CARD addr, size, BYTE cmd, aux1, aux2)[$29$F$85$A0$A}86$A1$A$A$A$A$AA$A5$A5$9D$342$A5$A3$9D$348$A5$A4$9D$349$A5$A6$F0$8$9D$34A$A5$A7$9D$34B$98$9D$345$A5$A1$9D$344$20$E456$8C A}CIO_status$C0$88$D0$6$98$A4$A0$99 EOF$60]PROC WriteBlock=*(BYTE dev, CARD addr, size); Writes size byA}tes from addr to dev.; Status is saved in CIO_status.[$48$A9$B$85$A5$A9$0$85$A6$A5$A3$5$A4$D0$2$68$60$68$4C CIO]MODULEA}BYTE PM_Mode=[0], PMHitClr=$D01DCARD PM_BaseAdrBYTE ARRAY PMHpos(8)=$D000, PMVpos(8)=[0 0 0 0 0 0 0 0],A} PM_MisMask(4)=[$FC $F3 $CF $3F], PM_Width(5)=$D008CARD ARRAY PM_BSize=[0 $100 $80], PM_Waste=[0 76A}8 384];************************************PROC PMGraphics(BYTE mode) BYTE DMACtl=$22F, ;P/M enable loc. PrioA}rity=$26F, GRACtl=$D01D, PMBase=$D407, GraphP0=$D00D CARD HiMem=$2E5, OldHiMem, AppMHi=A}$E CARD ARRAY PM_AdrMask=[0 $F800 $FC00], PM_MemSize=[0 $800 $400] mode==MOD 3 Zero(PMHpos,8) ; move thA}em off the screen Zero(PMVpos,8) Zero(PM_Width,5) Zero(GraphP0,5) IF PM_Mode#0 THEN HiMem = OldHiMem DMACtl=$A}22 GRACtl=0 FI IF mode=0 THEN ; turn off pmg DMACtl=$22 GRACtl=0 ELSE IF mode=1 THEN ;sgl line A}DMACtl=$3E ELSE ;dbl line DMACtl=$2E FI OldHiMem=HiMem PM_BaseAdr=(HiMem-PM_MemSize(mode)-$80A})&PM_AdrMask(mode) PMBase=PM_BaseAdr RSH 8 IF PM_BaseAdr=4 THEN n=0 EA}LSE n==+1 FIRETURN(PM_BaseAdr+PM_Waste(PM_Mode)+(n*PM_BSize(PM_Mode)));************************************PROC PMA}Clear(BYTE n) CARD ctr BYTE ARRAY PlayAdr n==&7 PlayAdr = PMAdr(n) IF n<4 THEN Zero(PlayAdr,PM_BSize(PM_ModeA})) ELSE n==-4 FOR ctr=0 TO PM_BSize(PM_Mode)-1 DO PlayAdr(ctr)==&PM_MisMask(n) OD FIRETURN;*A}***********************************PROC PMMove(BYTE n,x INT y); change y for rel. move CARD i BYTE yOffset, plA}Length, mask1,mask2 INT deltaY BYTE ARRAY temp(256),PlPtr IF PM_Mode=0 THEN RETURN FI n==&7 deltaY=A}y-PMVpos(n) IF deltaY=0 THEN PMHpos(n)=x ;do horizontal anyway FI PlPtr=PMAdr(n) plLength=PM_BSize(PM_Mode) IF A}deltaY>=0 THEN yOffset=deltaY ELSE yOffset=plLength+deltaY FI IF n<4 THEN mask1=255 mask2=0 ELSE A}mask2=PM_MisMask(n&3) mask1=mask2!$FF FI;**This piece of code was replaced by;**the following code block to;**increA}ase speed.; FOR i=0 to plLength-1; DO; temp(i)=PlPtr(i)&mask1; OD[ $A0 0 ; LDY #0 $AD PlPtr ; LDA PLPTRA} $85 $A0 ; STA $A0 $AD PlPtr+1 ; LDA PLPTR+1 $85 $A1 ; STA $A1;LOOP $B1 $A0 ; LDA ($A0),Y $2D maskA}1 ; AND MASK1 $99 temp ; STA TEMP,Y $C8 ; INY $CC plLength ; CPY PLLENGTH $D0 $F2 ; BNE LOOP]A};**This piece of code was replaced by;**the following code block to;**increase speed.; FOR i=0 to plLength-1; DO; PlPA}tr(yOffset)==&mask2 %temp(i); yOffset==+1; IF yOffset>=plLength THEN; yOffset=0; FI; OD[ $A2 0 ; LDXA} #0 $AC yOffset ; LDY YOFFSET $AD PlPtr ; LDA PLPTR $85 $A0 ; STA $A0 $AD PlPtr+1 ; LDA PLPTR+1 $85 $A1 A} ; STA $A1;LOOP $B1 $A0 ; LDA ($A0),Y $2D mask2 ; AND MASK2 $1D temp ; ORA TEMP,X $91 $A0 ; STA A}($A0),Y $C8 ; INY $CC plLength ; CPY PLLENGTH $D0 2 ; BNE ISLOW $A0 0 ; LDY #0;ISLOW $E8 A} ; INX $EC plLength ; CPX PLLENGTH $D0 $E8 ; BNE LOOP] PMVpos(n)=y PMHpos(n)=x PMHshd(n)=xRETURN; CA}onvert ATASCII to P/M graphicsPROC Plot_Chr(BYTE chr, BYTE POINTER pm)BYTE IBYTE POINTER ADDRCARD STARTLIST A}STARTLIST = Peek(756)*256 IF chr >= 32 AND chr <= 95 THEN ADDR=((chr-32)*8+STARTLIST) ELSEIF chr >= 0 ANA}D chr <= 31 THEN ADDR=((chr+64)*8+STARTLIST) ELSEIF chr >= 96 AND chr <= 127 THEN ADDR=(chr*8+STARTLIST) FI A} FOR I = 0 TO 7 DO pm(I)=ADDR^ ADDR==+1 ODRETURNPROC setup_pm() BYTE ctr,x A} BYTE ARRAY p0,p1,p2,p3 PMGraphics(1) p0=PMAdr(0) p1=PMAdr(1) p2=PMAdr(2) p3=PMAdr(3) FOR ctr=0 TO 7 DO PMClA}ear(ctr) OD Plot_Chr('1,p0) PMColor(0,3,8) Plot_Chr('2,p1) PMColor(1,3,8) Plot_Chr('+,p2) PMColor(2,5,8) PlotA}_Chr('+,p3) PMColor(3,7,8)RETURNPROC MoveLine(BYTE POINTER front, back, BYTE width, fcol, tcol, mode)CARD FrByte, ToBytA}eBYTE ctr, FrBit, ToBit, ftemp, ttemp, fmask, tmaskBYTE mfbyte, mtbyteFOR ctr=0 TO width ; pixel count, not BYTES!DO FrBA}yte=(fcol+ctr) RSH 2 ToByte=(tcol+ctr) RSH 2 FrBit=(fcol+ctr) - (FrByte LSH 2) ToBit=(tcol+ctr) - (ToByte LSH 2) FrByte==A}+front ToByte==+back IF FrBit=0 THEN ftemp=Peek(FrByte) & $C0 fmask=Peek(FrByte) & $3F ELSEIF FrBit=1 THEN ftemp=PeeA}k(FrByte) & $30 fmask=Peek(FrByte) & $CF ELSEIF FrBit=2 THEN ftemp=Peek(FrByte) & $0C fmask=Peek(FrByte) & $F3 ELSEIFA} FrBit=3 THEN ftemp=Peek(FrByte) & $03 fmask=Peek(FrByte) & $FC FI IF mode=sswap OR mode=scut THEN Poke(FrByte,fmask)A} FI IF ToBit=0 THEN ttemp=Peek(ToByte) & $C0 tmask=Peek(ToByte) & $3F ELSEIF ToBit=1 THEN ttemp=Peek(ToByte) & $30 A} tmask=Peek(ToByte) & $CF ELSEIF ToBit=2 THEN ttemp=Peek(ToByte) & $0C tmask=Peek(ToByte) & $F3 ELSEIF ToBit=3 THEN tA}temp=Peek(ToByte) & $03 tmask=Peek(ToByte) & $FC FI Poke(ToByte,tmask) ftemp=ftemp LSH (FrBit LSH 1) RSH (ToBit LSH 1) A}ttemp=ttemp LSH (ToBit LSH 1) RSH (FrBit LSH 1) fmask=fmask % ttemp tmask=tmask % ftemp IF mode=sswap OR mode=scut THEN A}Poke(FrByte, fmask) FI Poke(ToByte, tmask)ODRETURNPROC paste(BYTE mode)BYTE POINTER front, backBYTE width,height,I A}width=FrBCol-FrTCol ;width of block WHILE (width+ToTCol>159) OR (width+FrTCol>159) DO width==-1 OD heigA}ht=FrBRow-FrTRow ;height of block WHILE (height+ToTRow>191) OR (height+FrTRow>191) DO height==-1 OD fronA}t=FrScr+40*FrTRow ;assumes graphics 4,5,D,E, or F. back=ToScr+40*ToTRow ;e.g., 40 bytes per scan line A}FOR I=1 TO height DO back==+40 ;bump a scan line front==+40 ;and continue moveA} MoveLine(front,back,width,FrTCol, ToTCol, mode) ODRETURN; synchronization routine, used to prevent; partial overlayA}s when rapidly flipping pastePROC sync(); Provides vertical synchronizationBYTE clk=$14, clk1clk1=clkDO UNTIL clk1 # clA}kODRETURN ; Build an ANTIC-E mode display list; for the 400/800 ownersCARD FUNC Antic_E()BYTE tempCARD change A}Graphics (8+16) ;need GR 8 size memory temp=SDMCTL ;save display control reg SDMCTL=0 A};turn off display Poke (SDLSTL+3,78) ;force the first LMS FOR change=(SDLSTL+6) TO (SDLSTL+204) ;we know how long moA}de 8 is DO IF Peek(change)=15 THEN Poke (change, 14) ELSEIF Peek(change)=79 THEN Poke (changeA}, 78) FI OD DINDEX=7 ;fool OS to think it's mode 7 SDMCTL=temp ;turn screen back onA}RETURN(SDLSTL) ;where the display list is...; full-screen flip routine; switches display list; from current to A}the one at "dislst"PROC PageFlip(BYTE n)CARD templst,dislstBYTE sdmtmpIF n=0 THEN dislst=dsl1ELSEIF n=1 THEN dislst=dsA}l2ELSEIF n=2 THEN ;text buffer dislst=text ELSEIF n=3 THEN ;cut/paste buA}ffer dislst=dsl3FItemplst=PeekC(SDLSTL+200)sdmtmp=SDMCTL ;get screen ctlSDMCTL=0 A};turn off screenPokeC(SDLSTL+200,dislst)SDMCTL=sdmtmpsync()RsCol(n)PokeC(SDLSTL+200,templst)SDLSTL=dislstRETURN; turA}n on text screenPROC texton()IF DINDEX=0 THEN ;skip if we are RETURN ;already GR 0FIA}SAVMSC=textmlastgr=SDLSTLDINDEX=0PageFlip(2) ;easy!RETURN; turn off text screen and go back to; last A}graphics screenPROC textoff()CARD templstBYTE sdmtmptemplst=PeekC(SDLSTL+30)sdmtmp=SDMCTLSDMCTL=0PokeC(SDLSTL+30,lastgA}r)DINDEX=7SDMCTL=sdmtmpsync()PokeC(SDLSTL+30,templst)SDLSTL=lastgrIF lastgr=dsl1 THEN RsCol(0)ELSE RsCol(1)FIRETURA}NPROC stat()CARD himem=$EPrint("Player/missles start at ")PrintCE(PM_BaseAdr)Print("Object code ends at ")IF cpbuf THEA}N PrintCE(INITAD+15)ELSE PrintCE(himem)FIRETURN; sets up two (or three) complete GR 15 display; screens, plus a GR 0 A}text screen,; plus single-width player/missle; area. (Whew!);PROC screens()PMGraphics(0)dsl1=Antic_E() A};start of display listscrn1=SAVMSC ;start of screen memoryRAMTOP==-$20 ;subtract 8KdslA}2=Antic_E() ;start of display listscrn2=SAVMSC ;start of screen memRAMTOP==-$20IF RAMTOPA} > $79 THEN ;48K and no cartridge! dsl3=Antic_E() scrn3=SAVMSC RAMTOP==-$20 cpbuf=trueELSE dsl3=dsl2 scrn3=scrn2 A}cpbuf=falseFIGraphics(0)SvCol(2) ;standard colorstext=SDLSTL ;SDLSTLtextm=SAVMSA}Csetup_pm()RAMTOP==+$40 ;fix pointerIF cpbuf THEN RAMTOP==+$20FIlastgr=dsl1 ;init A}last GR pointerRETURN; Pause for a keystrokeBYTE FUNC pause()BYTE strokeDO stroke=key UNTIL stroke # 255ODkey=255RA}ETURN(stroke);clear entire text areaPROC fullflush()BYTE POINTER foofoo=SAVMSCSetBlock(foo,960,0)RETURN; Flush the wA}orking text areaPROC flush()BYTE POINTER foofoo=SAVMSCfoo=foo+280SetBlock(foo,680,0)RETURN;Present a help screenPROCA} help()PutE()PrintE(" Editing Commands")PutE()PrintE("Left button positions cursor/ident")PutE()PrintE("'1' fliA}ps to screen one")PrintE("'2' flips to screen two")IF cpbuf THEN PrintE("'3' flips to cut/paste buffer")FIPrintE("'C' cuA}ts indicated area to buffer")PrintE("'P' pastes indicated area from buffer")PrintE("'S' swaps areas between screens")PrintA}E("'F' mirror reverses current screen")PrintE("'I' unfreezes screen ident number")PrintE("'L' unfreezes lower cursor")PrinA}tE("'U' unfreezes upper cursor")PrintE("'M' returns to command menu")Printe("'Z' erases current screen")PutE()PrintE("PreA}ss any key to exit screen.")pause()fullflush() ;clean up our actRETURN;Present an announcement page aA}nd;sign-on banner.PROC banner()PutE()PutE()PrintE(" - MicroIlustrator Picture")PrintE("cut & paste editor. CopA}yright (c)")PrintE("1985, Harold Long, Bolton, MA.")PrintE("Permission granted to distribute")PrintE("for non-commercial pB}urposes.")PutE()PrintE("Koala Pad (tm) or paddle controlers")PrintE("required. See Help screen for info.")PutE()PrintE(B}"Press any key to exit screen.")PutE()pause()fullflush() ;clean up our actRETURNBYTE FUNC IsLower(BYB}TE ct) IF (ct>='a) AND (ct<='z) THEN RETURN(1) FIRETURN(0)BYTE FUNC ToUpper(BYTE ct) IF IsLower(ct) THENB} ct ==-$20 FIRETURN(ct)PROC Test_Name(BYTE POINTER fname) BYTE chr, cnt, ext chr=0 ext=0 FOR cnt=1 TO fnamB}e(0) DO fname(cnt)=ToUpper(fname(cnt)) IF fname(cnt)='. THEN ext=cnt FI IF fname(cnt)=': THEN chr=1 FI OD IF B}(ext>0) AND (ext # (fname(0)-3)) THEN fname(0)=ext+3 FI IF chr=0 THEN str132(0)=fname(0)+3 str132(1)='D sB}tr132(2)='1 str132(3)=': FOR cnt=1 TO fname(0) DO str132(cnt+3)=fname(cnt) OD FOR cnt=0 TO str132(0) DO B} fname(cnt)=str132(cnt) OD FIRETURN; Write an uncompressed Koala file:PROC WritePic()BYTE POINTER IDptrBYTE I; KoaB}la header dataBYTE ARRAY ID(4)=[$FF $80 $C9 $C7]CARD size=[$001A]BYTE rev=[$01]BYTE compr=[$00] ;no compressionBYTE modeB }=[$0E]BYTE ARRAY active(4)=[$00 $2B $00 $C0]BYTE ARRAY kolor(5)CARD length=[7680]BYTE ARRAY kend(7)=[$00 $00 $9B $9B $9B B }$9B $A2]FOR I=0 TO 4DO kolor(I)=colpf(I)ODIDptr=IDWriteBlock(1,IDptr,$1B)WriteBlock(1,SAVMSC,7680)RETURNPROC WFileB }(BYTE n) ; Save the requested screenPosition(10,9)Print("File ") PrintB(n+1) Print(": ")IF n=0 THEN Print(file1)ELSE PrB }int(file2)FIPosition(17,9) Put(' )InputS(fname)Test_Name(fname)Position(17,9) Put(' )PrintE(fname)Close(1)IF n=0 THENB } SCopy(file1,fname) lastgr=dsl1 textoff() Open(1,file1,8,0) SAVMSC=scrn1ELSE SCopy(file2,fname) lastgr=dslB}2 textoff() Open(1,file2,8,0) SAVMSC=scrn2FIWritePic()Close(1)texton()RETURNPROC RFile(BYTE n)Position(10,9)PrintB}("File ") PrintB(n+1) Print(": ")Position(17,9) Put(' )InputS(fname)Test_Name(fname)Position(17,9) Put(' )PrintE(fname)B}Close(1)IF n=0 THEN SCopy(file1,fname) lastgr=dsl1 textoff() Open(1,file1,4,0) SAVMSC=scrn1ELSE SCopy(fileB}2,fname) lastgr=dsl2 textoff() Open(1,file2,4,0) SAVMSC=scrn2FIReadPic()SvCol(n) ;save colors CB}lose(1)texton()RETURN; Format directory entriesPROC Formname(BYTE ARRAY Dptr,buf)BYTE POINTER BptrBYTE jj=3 ; init inB}put buffer indexDptr(0)=2 ; init string countDptr(1)=' : Dptr(2)=' Bptr=Dptr+3 ; point past :WHILE buf(j) # $20 DO B}Bptr^=buf(j) ; move in next byte Bptr==+1 ; bump pointer Dptr(0)==+1 ; up string count j==+1 ; bump index to input bB}uffer ; *** dont exceed 8 chars in primary name IF j=11 THEN EXIT FI OD; deblank input bufferWHILE buf(j) = $20 B}DO j==+1 IF j = 14 THEN RETURN FI; NO EXT! ODBptr^='. : Bptr==+1 : Dptr(0)==+1; fill in extWHILE buf(j) # $20 DO BB}ptr^=buf(j) : j==+1 Bptr==+1 : Dptr(0)==+1 ODRETURN; Get directory from file fnamePROC dir()BYTE I=[0]I=0ptr = DirB}_string ; init pointerPosition(10,7)Print("Drive: ")Position(16,7) Put(' )InputS(fname)Test_Name(fname)Position(16,7) PB}ut(' )PrintE(fname)Close(1)Position(1,9)Open(1,fname,6,0)InputSD(1,buf) ; get first file; dont format # of sectors freeB} msg WHILE buf(2) = $20 ; a good a stopper as any other DO Formname(ptr,buf) PrintE(ptr) ; print file name formedB} ptr==+ptr(0)+1 ; point to next substring InputSD(1,buf) I==+1 UNTIL I=14 ODPoke($52,20)Position(20,9)WHB}ILE buf(2) = $20 DO Formname(ptr,buf) PrintE(ptr) ; print file name formed ptr==+ptr(0)+1 ; point to next substB}ring InputSD(1,buf) I==+1 UNTIL I=28 ODIF I=28 THEN Position(22,23) Print("...")FIPoke($52,2)Close(1); clB}ose dirRETURNBYTE FUNC askscr()BYTE fnum Position(10,7) Print("Screen 1 or 2: ") DO Position(24,7) Put(' ) InputB}S(foo) fnum=ValB(foo) UNTIL fnum=1 OR fnum=2 ODRETURN(fnum);Koala tablet routines;;Simple filter for pointsBYTE FB }UNC Pad(BYTE POINTER l)BYTE ICARD ltempltemp=0FOR I=0 TO 7DO ltemp==+l^ODI=ltemp RSH 3RETURN(I);Test limits of plaB!}yer iconsBYTE FUNC ilim(BYTE i)IF i > 208 THEN i=208 FIRETURN(i)BYTE FUNC jlim(BYTE j)IF j > 224 THEN j=224 FIRETURN(j)B"};Positions id numberPROC ident(BYTE c) ;moves "1" or "2" around screenIF PTrig(0)=0 THEN ;test for button pushed ti=PB#}ad(624) ;get val tj=Pad(625) ti=ilim(ti) ;limit val tj=jlim(tj) IF ti>45 AND tj>30 THEN ;must be on screen i(B$}c)=ti j(c)=tj PMMove(c,i(c),j(c)) ;move icon to new position FIELSE PMMove(c,i(c),j(c)) ;move icon to last saved positB%}ionFIRETURNPROC PriCur(BYTE c)BYTE oldi, oldjoldi=pi(c) oldj=pj(c)IF PTrig(0)=0 AND PTrig(1)#0 THEN ti=Pad(624) tj=PB&}ad(625) ti=ilim(ti) tj=jlim(tj) IF ti>45 AND tj>30 THEN pi(c)=ti pj(c)=tj IF pi(c) > pi(c+2) THEN ;push right pi(c+B'}2)=pi(c) ELSE pi(c+2)==+(pi(c)-oldi) FI IF pj(c) > pj(c+2) THEN ;push down pj(c+2)=pi(c) ELSE pj(c+2)==+(pj(B(}c)-oldj) FI PMMove(3,pi(c+2),pj(c+2)) PMMove(2,pi(c),pj(c)) FIELSE PMMove(2,pi(c),pj(c)) PMMove(3,pi(c+2),pj(c+2))B)}FIRETURNPROC SecCur(BYTE c)BYTE width, heightIF PTrig(0)=0 AND PTrig(1)#0 THEN ti=Pad(624) tj=Pad(625) ti=ilim(ti) tB*}j=jlim(tj) IF ti>45 AND tj>30 THEN pi(c+2)=ti pj(c+2)=tj IF pi(c+2) < pi(c) THEN ;push left pi(c)=pi(c+2) FI IF pB+}j(c+2) < pj(c) THEN ;push up pj(c)=pj(c+2) FI PMMove(2,pi(c),pj(c)) ;ack push PMMove(3,pi(c+2),pj(c+2)) ;real moveB,} FIFIIF c=0 THEN width=pi(2)-pi(0) pi(3)=pi(1)+width height=pj(2)-pj(0) pj(3)=pj(1)+widthELSE ;c=1 width=pi(3)-pi(1)B-} pi(2)=pi(0)+width height=pj(3)-pj(1) pj(2)=pj(0)+heightFIRETURN; Swap area between cursorsPROC swap()FrTRow=pj(0)-3B.}0FrBRow=pj(2)-30ToTRow=pj(1)-30ToBRow=pj(3)-30FrTCol=pi(0)-44FrBCol=pi(2)-44ToTCol=pi(1)-44ToBCol=pi(3)-44paste(sswapB/})RETURN; Paste to an active screen from the cut/paste bufferPROC pasted()BYTE IIF scrno=0 THEN ToScr=scrn1ELSEIF scrnB0}o=1 THEN ToScr=scrn2FIFrScr=scrn3FOR I=1 TO 4DO FrScr(I)=cp(I-1) ToTRow=pj(scrno)-30 ToBRow=pj(scrno+2)-30 ToTCol=piB1}(scrno)-44 ToBCol=pi(scrno+2)-44ODpaste(spaste)RETURN; Copy from either screen to the cut/paste bufferPROC cut()BYTE B2}IIF scrno=0 THEN FrScr=scrn1ELSEIF scrno=1 THEN FrScr=scrn2FI ToScr=scrn3FrTRow=pj(scrno)-30ToTRow=pj(scrno)-30FrBB3}Row=pj(scrno+2)-30ToBRow=pj(scrno+2)-30FrTCol=pi(scrno)-44ToTCol=pi(scrno)-44FrBCol=pi(scrno+2)-44ToBCol=pi(scrno+2)-44B4}CPcol() ;save the colorsFOR I=1 TO 4DO cp(I-1)=FrScr(I) ;save where it came fromODpaB5}ste(scut) ;cut screen with erase;pasted() ;restore screenRETURN; Reverse a selecB6}ted byte (obverse)BYTE FUNC obv(BYTE c)BYTE temptemp=0temp=(c & $3) LSH 6temp==% (c & $C) LSH 2temp==% (c & $30) RSH 2B7}temp==% (c & $C0) RSH 6RETURN(temp); Reverse the selected screen (mirror)PROC mirror(BYTE n)BYTE i,J,temp1, temp2BYTE PB8}OINTER cellCARD scrIF n=0 THEN scr=scrn1ELSEIF n=1 THEN scr=scrn2ELSEIF n=3 THEN scr=scrn3FIFOR j=0 TO 191DO cell=B9}scr+(40*j) FOR i=0 TO 19 DO temp1=Peek(cell+i) temp2=Peek(cell+39-i) temp1=obv(temp1) temp2=obv(temp2) Poke(celB:}l+i,temp2) Poke(cell+39-i,temp1) ODODRETURN; Edit either screen!PROC edit()BYTE svscrno ;screen color to saveBYTE PB;}OINTER zap ;screen memory to erase textoff() ;last active screen DO IF key=$12 THEN ;C B<} cut() key=255 ELSEIF key=$0A THEN ;P pasted() key=255 ELSEIF key=$3E THEN ;S FrScr=scrn1B=} ToScr=scrn2 swap() key=255 ELSEIF key=$0D THEN ;I ident(scrno) ELSEIF key=$0B THEN ;U B>}PriCur(scrno) ;p2 ELSEIF key=$00 THEN ;L SecCur(scrno) ;p3 ELSEIF key=$1F THEN B?} ;1 scrno=0 PageFlip(scrno) ident(scrno) PriCur(scrno) PMMove(1,0,0) key=255 ELSEIF key=$1E THEN B@} ;2 scrno=1 PageFlip(scrno) ident(scrno) PriCur(scrno) PMMove(0,0,0) key=255 ELSEIF key=$1A THEN BA} ;3 svscrno=scrno scrno=3 pageflip(scrno) key=255 ELSEIF key=$39 THEN ;H key=255 PMGrapBB}hics(0) texton() Position(0,0) fullflush() help() textoff() PMGraphics(1) ELSEIF key=$25 THEN ;MBC} PMGraphics(0) EXIT ELSEIF key=$17 THEN ;Z IF scrno=0 THEN zap=scrn1 ELSEIF scrno=1 THEN zap=sBD}crn2 ELSEIF scrno=3 THEN zap=scrn3 FI Zero(zap,7680) ;clears screen ELSEIF key=$38 THEN BE};F mirror(scrno) FI OD key=255 PMMove(0,0,0) PMMove(1,0,0) texton() RETURN; Command frame;PROC keycom() BF} ;process keyboard commandsError=keycom ;disable errorsDO texton() ;turBG}n on text area Poke($52,1) ;left margin Position(1,0) PrintE("Cmd Action Cmd Action") PrintE(BH}" R Read a screen W Write a screen") PrintE(" E Edit screen D Directory") PrintE(" Q Quit B RestaBI}rt/clear") PrintE(" H Help/cmd frame") Position(1,7) PrintE("Cmd: ") ;ask for command Position(5,7) Put(BJ}' ) InputS(cmd) ic=ToUpper(cmd(1)) ;force uppercase; DUMB command parser IF ic='? THEN stat() pause() fBK}lush() FI IF ic='Q THEN ;bail out End() FI IF ic='B THEN ;reinitialize screens screBL}ens() FI IF ic='H THEN ;help frame Position(0,0) fullflush() help() FI IF ic='D THEN BM} ;read a directory dir() pause() flush() FI IF ic='R OR ic='W THEN ;read a graphics file scrno=askscrBN}()-1 IF ic='R THEN RFile(scrno) ELSE WFile(scrno) FI flush() FI IF ic='E THEN PMGraphics(1) edit() FIODBO}RETURNPROC main() ;central loopscreens() ;go setup all screensbanner() BP} ;announcementskeycom()RETURN ;never get here... setup all screensbanner() @Y PicPaste Graphics Editor Copyright (c) 1985 Harold Long, Bolton, MA [Permission granted to distributeFR} for non-commercial purposes.] is a two-screen graphicseditor which provides several usefullutility functionFS}s that enhance andexpand the capabilities of the KoalaMicro Illustrator package. Fullycompatable with Koala software, youFT}can read and write GR15 screens, andusing player/missle graphics cursors,cut, paste, and swap areas on eitheractive screeFU}n. PicPaste is written in Action!, aTrademark of Action Computer Services.Portions of this program are Copy-right (c) 1FV}984, A.C.S. PicPaste is not designed to replacethe Micro Illustrator package. Itprovides support functions not foundinFW} the basic software, includingthe ability to mix graphics from twosource screens, create mirror images,and move graphics aFX}reas around thescreen. Color tuning, blending ofpasted areas, and original graphicsmust be accomplished using compatibleFY}software. PicPaste was developed on an Atari800XL, using DOS/XL Operating Systemand is not guaranteed to run on anyotheFZ}r configuration. It requires 40Kof AVAILABLE memory, suggesting thatany system with MEMLO > $2000 willnot be able to suppF[}ort operation. Inaddition, it has not been fully de-bugged. Comments and suggestions tothe author are most appreciated.F\} To compile and run PicPaste, youwill need to increase the number ofpages in Action! set aside for symboltable storage. F]} From a cold start, orre-booted cartridge, use the monitorcommand "SET $495=12". Do not readin PICPASTE.ACT; it won't fitF^} inmemory with the object code. Insteadcompile from the monitor with thecommand C "D:PICPASTE.ACT" format.Write out yourF_} object code with thecommand W "D:PICPASTE.BIN" format. Using the above procedure, you willneed to have the Action! cartF`}ridgeinstalled to run PicPaste. In thisconfiguration, it provides two screenediting, plus cut/paste to/from screentwo. Fa}An alternative configurationrequires that you have the Action! runtime library, and compile PicPastewith an INCLUDE "D:PICFb}PASTE.LIB" whichMUST contain the following routines:Total calls to SYSLIB: 286(INCLUDE SYSLIB.ACT in its entirety)TotaFc}l calls to SYSIO: 466Individual calls to routines:ChkErr: 98Break1: 98Open: 7PrintE: 38PrintDE: 38Close: 8Print: 11PFd}rintD: 11InS: 8InputS: 5InputSD: 8InputMD: 8InputD: 8CCIO: 21PutE: 13Put: 21PutD: 21PutD1: 21CToStr: 5PrintB: 2PFe}rintC: 5PNum: 5PrintCE: 3ValB: 1ValC: 1ValI: 1Total calls to SYSGR: 40Individual calls to routines:Graphics: 2PositFf}ion: 19Pos1: 19Total calls to SYSMISC: 69Individual calls to routines:PTrig: 5Peek: 21PeekC: 23Poke: 16PokeC: 4TotFg}al calls to SYSBLK: 14Individual calls to routines:Zero: 6SetBlock: 8Total calls to SYSSTR: 4Individual calls to routinFh}es:SCopy: 4 By creating a custom library forPicPaste, you can fit the runtimesystem and the object code into 12Kof memFi}ory, with enough free memoryleft to set up three complete GR15screens. Under this configuration,you will have two editingFj} screens,plus a separate cut/paste bufferarea giving you maximum flexibilityin manipulating graphics areas. Thiscan be cFk}ompiled and then saved via theW "D:PICPASTE.COM" format and runwithout the cartridge installed.hics areas. Thiscan be cDc;; READPIC - Reads MicroIllustrator; picture files. Original code by; Robert E. Wilson, REW Consulting.;; Modified forJm} Action! and converted; to code blocks by Harold Long,; Bolton, MA. 14-Jan-1985;PROC GetByt=*() [;Provides CCIO and bailJn}out functions$A5$AA$C5$AC$D0$06$A5$A9$C5$AB$F0$16 $A2$10$A9$00$8D$58$03$8D$59$03$20$56 $E4$30$09$E6$A9$D0$02$E6$AA$60$A9$0Jo}1 $85$A0$68$68$60];Provides screen address canculationPROC NxtPnt=*() [$24$A2$50$2C$C6$A5$F0 $0E$A9$50$18$65$A3$85$A3$A9$Jp}00$65$A4 $85$A4$60$A9$60$85$A5$C6$A6$F0$0E$A9 $28$18$65$AD$85$A3$A9$00$65$AE$85$A4 $60$A9$02$85$A6$A9$01$18$65$AD$85$AD $Jq}85$A3$A9$00$65$AE$85$AE$85$A4$60];BYTE FUNC READPIC=*() [; Segment contains 181 bytes.$A5$58$85$AD$85$A3$A5$59$85$AE$85$Jr}A4 $A9$60$85$A5$A9$02$85$A6$A9$07$8D$52 $03$A9$A0$8D$54$03$A9$00$8D$55$03$85 $A7$85$AC$A9$FF$85$AB$85$A9$85$AA$20 GetByt$Js}85$A0$A5$A9$C9$07$F0$0A$C9$0C $F0$10$C9$1A$F0$2B$D0$EB$A5$A0$4A$6A $6A$85$A2$18$90$E1$A9$05$85$A1$20GetByt$A6$A7$9D$C4$02$Jt}E6$A7$C6$A1$D0$F2 $20GetByt$85$AB$20GetByt$85$AC$18$90 $C2$A5$A2$F0$24$20GetByt$85$A1$29$7F $D0$0F$20GetByt$85$A8$E6$A8$20Ju}GetByt $85$A7$18$90$06$85$A7$A9$01$85$A8$A5 $A1$29$80$85$A1$20GetByt$85$A0$A0$00 $A5$A0$91$A3$20NxtPnt$A5$A2$F0$EE$C6 $A7Jv}$D0$04$C6$A8$F0$C2$A5$A1$F0$E9$D0 $E0];; Build an ANCIC E mode display list;MODULEBYTE SDMCTL=$22F, DINDEX=$57CARD SDJw}LSTL=$230PROC ANTIC_E() BYTE TEMP CARD CHANGE Graphics (8+16) ;Need GR 8 TEMP=Peek(SDMCTL) ;SavJx}e display control reg Poke (SDMCTL, 0) ;Turn off display Poke (SDLSTL+3,78) ;Force the first LMS FOR CHANGEJy}=(SDLSTL+6) TO (SDLSTL+204) ;WE KNOW HOW LONG MODE 8 IS DO IF Peek (CHANGE)=15 THEN Poke (CHANGE, 14) Jz} ELSEIF Peek (CHANGE)=79 THEN Poke (CHANGE, 78) FI OD Poke (DINDEX,7) ;Fool OS to think it's modeJ{} 7 Poke (SDMCTL, TEMP) ;Turn screen back onRETURNMODULE ;FILEHAN.ACT - General file and screen handler; Copyright J|}(c) 1984 Harold Long, Bolton MABYTE ARRAY fname(18) ;file name+extBYTE ARRAY infile(16),outfile(16) BYTE FUNC J}}IsLower(BYTE c) IF (c>='a) AND (c<='z) THEN RETURN(1) FIRETURN(0)BYTE FUNC ToUpper(BYTE c) IF IsLower(c) J~}THEN c ==- $20 FIRETURN(c)PROC Test_Name(BYTE POINTER fname) BYTE chr, cnt, ext BYTE ARRAY str132(24) chr=0J} ext=0 FOR cnt=1 TO fname(0) DO fname(cnt)=ToUpper(fname(cnt)) IF fname(cnt)='. THEN ext=cnt FI IF fname(cnt)J}=': THEN chr=1 FI OD IF (ext>0) AND (ext # (fname(0)-3)) THEN fname(0)=ext+3 FI IF chr=0 THEN str132(0)=fnameJ}(0)+3 str132(1)='D str132(2)='1 str132(3)=': FOR cnt=1 TO fname(0) DO str132(cnt+3)=fname(cnt) OD FJ}OR cnt=0 TO str132(0) DO fname(cnt)=str132(cnt) OD FIRETURN;; Main shell routine;PROC Shell(BYTE ARRAY infile, J}outfile)BYTE resultBYTE key=764 Close(1) ;for sure Open(1,infile,4,0) ;open input ANTIC_E() J};set up display list this way ;for all those poor 400/800 ;owners... result=REJ}ADPIC() Close(1)DO UNTIL key # 255ODkey=255RETURNPROC Get_Files()BYTE cntDO Poke(82,1) Put(125) PutE() PrinJ}tE(" - MicroIllustrator Utilities.") PrintE("Provides simple cut and paste") PrintE("functions as demonstration rouJ}tines.") PrintE("Copyright (c) 1984 Harold Long") PrintE("Permission granted to distribute for") PrintE("non-commercialJ} purposes.") PutE() Position(1,8) PrintE("Input File? ") Close(7) Open(7,"K:",4,0) DO Position(13,8) PuJ}t(' ) InputS(infile) Test_Name(infile) Position(13,8) Print(" ") Position(13,8) Put(J}' ) Print(infile) PutE() PutE() Print("Correct (Y/N)? ") DO cnt=GetD(7) UNTIL cnt='Y OR cnt='yJ} OR cnt='N OR cnt='n OD Put(cnt) UNTIL cnt='Y OR cnt='y OD PutE() Shell(infile, outfile)ODRETURNcnt='yHvTITLE'READPIC -- Reads ATARIARTIST Picture Files'SUBTTL'Definitions';;**** READPIC -- Reads ATARIARTIST Picture FileN}s ***;; By Robert Elden Wilson; REW Consulting; December, 1984;;; *** Definitions ***;BYTE:EQU$CB;WN}ill hold input byteMODE:EQU$CC;Unique data or Same data modeTYPE:EQU$CD;Compression typePNT:EQU$CE;Buffer pointerN}CNT96:EQU$D0;Counter (96-0)CNT2:EQU$D1;Counter (2-0)LEN:EQU$D4;Length of compression block;ICCMD:EQU$0352;ION}CB1 command byteICBA:EQU$0354;IOCB1 buffer addressICBL:EQU$0358;IOCB1 buffer length;SCRMEM:EQU$58;Address to PoiN}nter to Screen memoryCOLOR0:EQU$02C4;Playfield color 0 shadow;CIOV:EQU$E456;Address of CIO routine;;EJECTSUBTTN}L'Page Six';; *** Page Six ***;;; This block must be loaded into page 6.;ORG$0600;;;>>>GETBYT --Inputs a byte N}from the file;open on IOCB1. When number;of bytes input equals;value stored at LENGTH,;return address is poppedN};from stack and routine;returns to previous caller.;GETBYT:LDACOUNT+1;See if done yetCMPLENGTH+1BNECONTIN;NoN}, continueLDACOUNTCMPLENGTHBEQERROR;Yes, exitCONTIN:LDX#$10;Use IOCB1LDA#$00;Set buffer len to 0STAICBLN};This causes byteSTAICBL+1;to be returned in AJSRCIOV;Get byteBMIERROR;ErrorINCCOUNT;Increment # bytes readN}BNEDONEINCCOUNT+1DONE:RTS;That's all;ERROR:PLA;Pop off return addressPLARTS;Return to previous caller;CON}UNT:DW0;# bytes inputLENGTH:DW0;Length of fileBASE:DW0;Base screen address;;;>>>NXTPNT --Loads PNT with the scN}reen;address for the next byte;of picture data.;NXTPNT:BITTYPE;Check compression typeBVCNOCOMP;No compressionN}DECCNT96;Have we done 96 rows?BEQSTEP5;YesLDA#80;Add 80 to PNTCLCADCPNTSTAPNTLDA#$00ADCPNT+1STAPNN}T+1RTS;DoneSTEP5:LDA#96;Reset counterSTACNT96DECCNT2;Both odd/even rows done?BEQSTEP7;YesLDA#40;Add 40N} to BASECLCADCBASESTAPNT;and store in PNTLDA#$00ADCBASE+1STAPNT+1RTS;DoneSTEP7:LDA#$02;Reset counteN}rSTACNT2NOCOMP:LDA#$01;Add 1 to BASE & PNTCLCADCBASESTABASESTAPNTLDA#$00ADCBASE+1STABASE+1STAPNN}T+1RTS;Done;EJECTSUBTTL'Main Routine';; *** Main Routine ***;;; This block can be loaded anywhere.;ORG$00N}00;READIT:PLA;Remove arg cntLDASCRMEM;Get screen memory addressSTABASESTAPNTLDASCRMEM+1STABASE+1STAPNN}T+1LDA#96;Set up countersSTACNT96LDA#$02STACNT2LDA#$07;I/O will be readSTAICCMDLDA#BYTE;Store buffer N}addressSTAICBALDA#$00STAICBA+1STALEN;Init remaining variablesSTALENGTH+1LDA#$FFSTALENGTHSTACOUNTSTN}ACOUNT+1READHD:JSRGETBYT;Get a header byteSTABYTE LDACOUNT;Load # bytes readCMP#$07BEQCTYPE;Up to compresN}sionCMP#$0CBEQCOLORS;Up to colorsCMP#$1ABEQREADAT;Done with headerBNEREADHD;Keep reading headerCTYPE:LDAN}BYTE;Get dataLSRA;Move bits 0,1 to 6,7RORARORASTATYPE;Save compression typeCLCBCCREADHD;Read more headerN}COLORS:LDA#$05;Load counter to read colorsSTAMODENXTCOL:JSRGETBYT;Get a colorLDXLENSTACOLOR0,X ;Store itINN}CLENDECMODEBNENXTCOL;Get next oneJSRGETBYT;Get file sizeSTALENGTH;Store itJSRGETBYTSTALENGTH+1CLCBCN}CREADHD;Read more headerREADAT:LDATYPE;Get compression typeBEQINPBYT;No compressionCOMPR:JSRGETBYT;Get a mode bN}yteSTAMODEAND#$7F;Get countBNESHORT;Count < 128JSRGETBYT;Get long countSTALEN+1INCLEN+1JSRGETBYTSTAN}LENCLCBCCGETDATSHORT:STALENLDA#$01STALEN+1GETDAT:LDAMODE;Reload modeAND#$80;Strip off countSTAMODEN}INPBYT:JSRGETBYT;Get data byteSTABYTELDY#$00STORE:LDABYTESTA(PNT),Y;Store itJSRNXTPNT;Go calculate next aN}ddressLDATYPE;Check compressionBEQINPBYT;No compressionDECLEN;More in the block?BNENEXT;YesDECLEN+1BEQCN}OMPR;No, get next mode byteNEXT:LDAMODE;Check modeBEQSTORE;Repeated data modeBNEINPBYT;Unique data mode;ENDN}TITLE'READPIC -- Reads AN}TARIARTIST Picture Files'SUBTTL'Definitions';;**** READPIC -- Reads ATARIARTIST Picture FilTITLE'READPIC -- Reads ALbPicture Data Format for MicroIllustrator and Koala Painter and AtariArtist Each file consR}ists of two sections,a header and the data.Header:Offset Description------ -----------------------------$00-03 ID sR}equence: $FF,$80,$C9,$C7$04-05 # bytes in header (-1) usually $1A,$00$06 Revision #: $01$07 Compression tR}ype: $00=none, $01=vertival, $02=horizontal$08 Graphics mode: xx00yyyy where xx=GTIA bits from GPRIOR anR}d yyyy=ANTIC mode. Nprmally $0E$09-0C Active screen area (L,R,T,B) $00,$2B,$00,$C0$0D-11 Color register dR}ata for COLOR0 thru COLOR4$12-13 Total length of file: lsb,msb$14-15 Unused: $00,$00$16-19 Reserved: $9B,$9B,$9R}B,$9B$1A Unused: $A2The data follows immediately. Ifuncompressed, then it is in screenRAM order.In horizontal comR}pression, the datawill fill memory on order (fill eachrow on the screen left to right, topto bottom.In vertical compressR}ion, The datafills a 1-byte column, every otherrow, followed by the skipped row,then on to the next column.Compressed daR}ta consists of variablelength records. The first byte ofeach record determines the type ofrecord. Format: 1st byte 2nR}d byte 3rd byte <--------><--------><--------><....>>|0|Cnt<>0 | Data | Cnt bytes of repeated Data|1|Cnt<>0 | UniqR}ue | Data | ... Cnt bytes of unique data|0| 0 | msb Cnt | lsb Cnt | Data| Cnt (>127) bytes of repeated data|1R}| 0 | msb Cnt | lsb Cnt |data|.. Cnt (>127) bytes of unique dataThe subroutine READPIC.MAC will reada picture fileR} onto a mode E or Fscreen (assumed). It only looks atthe compression type and color valuesin the header and assumes that R}thepicture area and mode are compatiblewith a full screen mode E or Fpicture.))))))))))))))))))))))))))))))))))))))))))R})))))))))))))))))))))))))))))))))))))))))))))Picture Data Format for MicroIllustrator and Koala Painter R} ))))))))))))))))))))))))))))))))))))))))))Picture Data Format for MicroIllustrator and Koala Painter P