#ML }  X c0C)HCCH Mhhݩh `eCDiCD`  RyHP   * 1H0芢@) Y0.Ș`i`#(PMR\ \b Pgi 0  % @ / ՠ`d   0DDԝL \ - 2 t,/ҍҍҢ) $ #օ -'x(x(( C$0})0(1ԩ:/ " =# $ $ # Щ@ԩo ЩЩ} $$ $wФt$ , , L 0E0L4! e$ }, ƙ ,  },L!  , , i >L! Ŗ) 񦔠  $  $L" ]-} #曤L"2 ,  ,( e$Ɣ #Ɩɠҩ $L:"Ҥi暤  }=v& $ $:/ $ , , ,  ,< $v& L"t$L! R#Ƣ =#w } $L!& $L L"` L#襗 =#`A` $ , } , $υ' $&ƋХ8*Ɨŗ L|#拽JJ $拥8L#)ߥi $L#` }L----$`L-:H(50)1) $`012#* }2 ē`ȖxdPFA<72-(# HiL$h`Ŕ` %e` }, `@ #} -0~*00*1o Щ&  $ i0)1*ԩi]}敭& &&%L%&)&w&Ƚw&i \_idIJHKp $d}ҍҩҩҩq $ɇ $ $L%ҍҩ $&&]Ȍ^ȌqȌr&&ɁL1& $/ $}Ѝ Ѝ&@ # # C$ $ $$u&v&`!"#$mnopqr} $.9GUy`y`y`y`ly`y`y`l`y}<5/<5@<QQQl`y !%!%AAAAAAAAAAAAAAAAAAAAAA}AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA}AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA}"y-arkand#athy3loatman3#/2%,%6%,ppBA(pppFpA)ppM } A5)Hڍ ԍЩ)h@H ԍЭ}Щύ)h@H ԍЩЩ)h@Hȍ ԍЩ)h@H ԍ ԩ Щh@H ԍ ԩh@`>xx8* }./ (U((UUU(UUU(UU}88xxxxxxx???=}?<< 7=}켾;<<}=>}}ؼ|?<<?ooooo`onnvvppp>ppppppx| إƏL+I&!ҩ&}膝L+Ҧʽ&x +2!ƜƜƜL+ð 朩MiХ+接#+轄+ҩ膍 }҅7慥/ҥ8( Lb+L\ 膒 `aʩ}膒 , `2懩 & & & & &eeeie & & }&eei(栥 ƊL,`8$JJ8ő Ȣ`N煞L, }` p~>~~~~~~~x ő Ȣ`N煞L,C ( e " "Ӎ0(1./8ԩЩ Щoҩ010H'0#"} \&&8X(::X'::::';;;;۩Ѝ Ѝ Щ6xЩЩHЩJ#'#}m' Hh " Ѝ Ѕ'ҩҩx&8 )$} ) " ")' '0эЩL!i'%} ʕ٢ ԍ ՖHhp=&Hՠ -h)"&8Э ) u &} @ .8Ǝ! ")? ɂ8ꄂ80L'"L! Ȱ8` e`uJJJ "iJJJe`7'}`9::;;`ƅ*>>]]]0|ht8xx(((,`|i2}v.=]4 (>n<4 (>.4|ht8~z(((,` (~Vn\~4;3}>*>>]]]]6pppG8A( 4 (>.4|ht8~z(((,` (~Vn\~4;9BPOPCORN EXEB!TWOGUN EXELX;M+X; BLOAD -- load a binary file to memoryNX;O BLOAD P PHR Q CLOSE ROPEN === S QQLOADT P.}LR UA. CONTROL macrosAX;0X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;X;&X; The control macros of KER.}NEL.M65X;0X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;X;X;0X; GOSUB -- same as JSR except saves X&Y regsX;.} GOSUB  PUSHX  PUSHY   PULLY  PULLX X;X; IFEQ, IFNE, IFGT, IFLT --/X; compare two int.}eger values and branchX; if condition is metX; IFEQ DEQCMP =  H@THEN!  @THEN IFNE .}DEQCMP =  F@THEN!  @THEN IFLT DCMP =  I@THEN!  @THEN IFGT DCMP.} =  I@THEN!  @THENX;7X; DOI, LOOPI -- loop control using the 'I' variableX; DOI DPOKE Q.}QLOOP= DPOKE QQLOOP= Q>4?K PQQLOOP Q>5?K PQQLOOP ?K LOOPI DINC QQL.}OOP!IFGT QQLOOP=QQLOOP=@LIQQQLOOP 5QQQLOOP 5:@LIX;7X; DOJ, LOOPJ -- loop control .}using the 'J' variableX; DOJ DPOKE QQLOOP= DPOKE QQLOOP= Q>4?K PQQLOOPQ>5?K.} PQQLOOP?K LOOPJ DINC QQLOOP$IFGT QQLOOP=QQLOOP=@LJQQQLOOP5QQQLOOP.}5:@LJX;7X; DOK, LOOPK -- loop control using the 'K' variableX; DOK DPOKE QQLOOP= D.}POKE QQLOOP = Q>4?K PQQLOOPQ>5?K PQQLOOP?K LOOPK DINC QQLOOP$IFGT.} QQLOOP=QQLOOP =@LKQQQLOOP5QQQLOOP5:@LK TRAP VPOKE QQTRAP= p#A. .} MISCellaneous macrosAqX;r0X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sX;t*X; Miscellaneous macros from KERNEL.M65u.}X;v0X;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wX;x(X; DINC -- increment a word (2 bytes)yX;z DINC {# |H?.}K} # ~?KX;2X; VPOKE -- poke an immediate value into a wordX; VPOKE  Q>4 P  Q>5  P .}X;+X; DPOKE -- could be better called DMOVEX; DPOKE    Q P  Q  P Q.}> P Q> P X; X; POKE -- a single byte pokeX; POKE  PLDA P X;.X; WA.}IT -- wait a certain number of jiffiesX; WAIT POKE  = ?KQ H?KX;(X; STOP -- stop until S.}TART is pushedX; STOP  QQSTOPX;&X; SOUND -- just like BASIC's soundX; SOUND POKE =Q>.}PҶP2   $>   PLDA T?> 2 Q>   PLDA  T16 .}P PLDA M>LP9 PLDA P9X;%X; BMOVE -- move a block of memoryX; BMOV.}E VPOKE QQPASS= VPOKE = VPOKE =  QQBMOVX;9X; PGMOVE -- special move of a single pag.}e (256 bytes)X; PGMOVE POKE =  PLDA  QQPGMVX;3X; BCLR -- clear (set to zero) a block of m.}emoryX; BCLR VPOKE = VPOKE QQPASS=  QQBCLRX;-X; PGCLR -- fast clear of a page of memo.}ryX;X; PGCLR  PUSHY POKE = POKE =??L1P@73H?L1 PULLY a page of memo,o QQVBVR bQQHTM QQHTP  QQVM  QQHP  QQVP QQOVP QQPBAS  QQMBAS 2}QQPFLG  QQMFLG QQSHAP QQPSAV  QQHT QQMASK = =0= QQSMSZ 9QQMSM ===2}========@== =0=QQMBIT === PLDX   $> $  PMGR  PH2}R  PLDA  QQPMGR PLR  SETVEC VPOKE QQVBVR=    SHAPE  PUSHX  PLDA  T?> Q2}>5 PQQSHAP9 Q>4  PQQSHAP9 PULLX  PMCOLR  PUSHX  PLDX  PLDA  T16  PQQCMP2} PLDA , OQQCMPP9 PULLX ! PMOVE " PUSHX # PLDX $ PLDA % PQQHP9& PLDA ' P2}QQVP9(Q>) PQQPFLG9* PULLX +, MMOVE - PUSHX . PLDX / PLDA 0P91 PLDA 2 PQQVM93Q>2}4 PQQMFLG5 PULLX 67 PSIZE 8 PUSHX 9 PLDX :0;A< PLDX =P9> PLDA ? PQQHTP9@ PULLX 2}AB MSIZE C PUSHX D PLDX E0FAGT?HT?I PQQCMPJ PLDA K,L OQQCMPM>N QQQMSM9O LQQSMSZP P2}QQSMSZQP R PLDX S PLDA T PQQHTM9U PULLX VW MPLC X&Y PLDX Z QQQMBIT9[ PLDX \M2}9]5^$_7`a MPFC b&c PLDX d QQQMBIT9e PLDX fM9g5h$i7jk PPLC l&m PLDX2} n QQQMBIT9o PLDX pM 9q5r$s7tu PPFC v&w PLDX x QQQMBIT9y PLDX zM9{5|$2}}7~)X;************************************X; PMGR RUNTIME CODE)X;************************************2} QQPMGRPԅ,O>> PQQMBAS2 &QQPBAS2&QQPBAS2&QQPBAS2&QQPBASQ>P2}ГQ>>P/Q> %>4QQAPMM $>5QQAPMM \: QQAPMM%>?AL1Q8 PQQPSAV83)> H?AL12}$>?AL2 QQQHP9P9 QQQOVP9 RQQVP9 FQQNPX QQQPFLG9 FQQNPX QQQPBAS9Pέ QQQOVP9Pͯ QQ2}QHTP9 PQQHT%>C?AL3P@73 )QQHT H?AL3AT?? QQQSHAP8P˽QQQSHAP8P̿ QQQVP92}P PQQOVP9%>?AL4Q@7P@73 )QQHT H?AL4 QQNPX2(> H?AL2 QQQMFLG FQQRET Q2}QQMBASPQ>P??AL8P@73 H?AL8$>?AL5 QQQHTM9 PQQHT QQQVM9P%>?AL62}Q@7 LQQMASK9P@73 )QQHT H?AL62(> H?AL5 QQRET$>?AL7 QQQPSAV9P9Q> PQ3}QMFLG PQQPFLG92(> H?AL7 !@QQVBVR:2(> H?AL5 QQRET$>?AL7 QQQPSAV9P9Q> PQ02X;/X; The fine scroll macro library and support5X; subroutines. They are heavily interdependent,X; so must 7}always be .INCLUDEd togetherX; XDIM  YDIM  SCRBAS  CSRBAS  SDSPL  SHSROL  SVSROL  HS7}PEED  VSPEED  X0LIM  Y0LIM  LINES  JMPBYT  RVBIV  XLOC  YLOC  CWIDE  CHIGH 7} MLINES  SRBYTW  DIR  HCOUNT  VCOUNT  SCROLL  MODE 0OLDVBV ;; Will hold previous vb7}lank vector'VVBLKD$;; Deferred vblank vector0SETVBV\;; OS routine to set vblank vector X;  SCRDIM  PLDA 7}  > L>p PJMPBYT00 &MODEPOKE XDIM= POKE YDIM= VPOKE SCRBAS= VPOKE SDSPL= 7} QQDSRL SETXY POKE XLOC= POKE YLOC=  QQSXYSTOPSCROLL $OLDVBV %OLDVBV Q>!7} SETVBV"#QQCWID =====$QQCHIG = ====%QQMLIN === == & QQDSRL'DPOKE CSRBA7 }S=SCRBAS( $MODE) QQQCWID9* PCWIDE+ QQQCHIG9, PCHIGH- QQQMLIN9. PMLINES/Q>0 PXLOC1 PYLOC2 PVSPEED3 P7 }HSPEED4Q>5 PSCROLL6Q>7 PSHSROL8 PSVSROL9 QCWIDE:>;Q><(>= HQQSL2>V?? QQSL2@V?AV?B PSRBY7 }TWC QXDIMD;E SSRBYTWF PX0LIMG "X0LIMH QYDIMI;J SMLINESK PY0LIML "Y0LIMM QMLINESNT?O,P OMLINESQ P7 }LINESR #LINESS #LINEST #LINESU$X; WRITE BEGINING & END OF D LISTVDPOKE =SDSPLWQ>pX%>YP@7Z3[P@7 }7\3]P@7^ %LINES_3`3a3bQ>BcP@7d3eQfP@7g3hQiP@7jQ>k3lP@7m3nP@7o3p7}P@7qQ>Ar3sP@7t QSDSPLu3vP@7w QSDSPLx3yP@7zDPOKE RVBIV=${3DPOKE OLDVBV=VVBLKD;; Sav7}e old vblank vector| %>4QQAUTS} $>5QQAUTS~Q> SETVBV;; SETVBVQ>P QQSL3Q HQQSL3DPOKE 07}=SDSPLQ>P: QQAUTSX; SAVE 212 & 204 ON STACK-Qԍ5 Q5Q̑5 Q5DPOKE7} =CSRBASDPOKE =SDSPL%> QQTL1 QJMPBYTP@73QԜP@73 QP@7X; ADD XDIM TO 217}2,Qԣ OXDIMPԥ QO> P3 )LINES HQQTL1X; WRITE LAST MODE LINE QJMPBYTM>WP@7}73QԱP@73 QP@7X; WRITE SHADOWS QSHSROLP;; HSCROL QSVSROLPԺ7 P77}P̾7 P7P QSCROLLPDIRVDIREQQTNU;; NO UPWARD SCROL #VCOUNT QVSPEED RVCOUNT EQQTNU7}Q> PVCOUNT "SVSROL IQQTNU QYLOC HQQTASNQ> PSVSROL FQQTNU QQTASN QCHIGH PSVSROL "YLO7}C; QCSRBAS SXDIM PCSRBAS EQQTNU"CSRBAS QQTNU X; DOWN ?VDIR EQQTNV #VCOUNT QVSPEED R7}VCOUNT EQQTNVQ> PVCOUNT #SVSROL QCHIGH RSVSROL EQQTNVX; CHECK LIMIT QYLOC RY0LIM HQQTASN27} QCHIGH PSVSROL HQQTNV QQTASN2Q> PSVSROL #YLOC, QCSRBAS OXDIM PCSRBAS DQQTNV#CSRBAS7} QQTNV X; LEFT?VDIR EQQTNL #HCOUNT QHSPEED RHCOUNT EQQTNLQ> PHCOUNT #SHSROL QCWIDE7} RSHSROL  EQQTNL X; CHECK LIMIT  QXLOC  HQQTASN3  QCWIDE PSHSROL HQQTNL QQTASN3Q> PSHSROL "XLO7}C "CSRBASQ> RCSRBAS HQQTNL"CSRBAS QQTNL X; RIGHT ?VDIR EQQTNR #HCOUNT QHSPEED RHCOU7}NT  EQQTNR!Q>" PHCOUNT# "SHSROL$ IQQTNR%X; CHECK LIMIT& QXLOC' RX0LIM( HQQTASN4)Q>* PSHSROL+ FQQT7}NR, QQTASN4- QCWIDE. PSHSROL/ #XLOC0 #CSRBAS1 DQQTNR2#CSRBAS3 QQTNR4 !@RVBIV:5 QQSXY6 QX0LIM7 RXL7}OC8BGT QQSX19 PXLOC: QQSX1; QY0LIM< RYLOC=BGT QQSX2> PYLOC? QQSX2@DPOKE CSRBAS=SCRBASA %YLOCB 7}FQQSXL6C QQSXL4D,E QCSRBASF OXDIMG PCSRBASH DQQSXL5I#CSRBASJ QQSXL5K1L HQQSXL4M QQSXL6NX; ADD IN7 } XLOCO,P QCSRBASQ OXLOCR PCSRBASS DQQSXL7T#CSRBASU QQSXL7VX; CLEAR SHADOWSWQ>X PSHSROLY PSVSROLZ7!}7!@OLDVBV:;; Exit through old vertical blank vector.#CSRBASU QQSXL7VX; CLEAR SHADOWSWQ>X PSHSROLY PSVSROLZ4510 .OPT NOLIST0980 .OPT NOEJECT0990 .TITLE "A sample device driver for Atari's OS"1000 .PAGE "--- general remarks -;#}--"1010 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1020 ;1030 ; The "M:" driver --1040 ; Using memory as a device1050 ;1060 ; In;$}cludes installation program1070 ;1080 ; Written by Bill Wilkinson1090 ; for January, 1982, COMPUTE!1100 ;1110 ;;;;;;;;;%};;;;;;;;;;;;;;;;;;;;;;;1120 ;1130 ; EQUATES INTO ATARI'S OS, ETC.1140 ;1150 ICAUX1 = $34A ; The AUX1 byte of IOCB1160 ;;&}1170 OPOUT = 8 ; Mode 8 is OPEN for OUTPUT1180 ;1190 MEMLO = $2E7 ; pointer to bottom of free RAM1200 MEMTOP = $2E5 ; poin;'}ter to top of free RAM1210 ;1220 FR1 = $E0 ; Fltg Pt Register 1, scratch1230 ;1240 STATUSOK = 1 ; I/O was good1250 STATU;(}SEOF = $88 ; reached an end-of-file1260 ;1270 HATABS = $31A1280 ;1290 HIGH = $100 ; divisor for high byte1300 LOW = $FF ;)}; mask for low byte1310 ;1320 .PAGE "The installation routine"1330 ;====== CHANGE NEXT LINE TO SUIT YOUR MEMORY ======13;*}40 *= $30001350 ; This first routine is simply1360 ; used to connect the driver1370 ; to Atari's handler address1380 ; ;+}table.1390 ;1400 LOADANDGO1410 LDX #0 ; We begin at start of table1420 SEARCHING1430 LDA HATABS,X ; Check device name;,}1440 BEQ EMPTYFOUND ; Found last one1450 CMP #'M' ; Already have M: ?1460 BEQ MINSTALLED ; Yes, don't reinstall1470 IN;-}X1480 INX1490 INX ; Point to next entry1500 BNE SEARCHING ; and keep looking1510 RTS ; Huh? Impossible!!!1520 ;1530;.} ; We found the current end of the1540 ; table...so extend it.1550 ;1560 EMPTYFOUND1570 LDA #'M' ; Our device name, "M:";/}1580 STA HATABS,X ; is first byte of entry1590 LDA #MDRIVER&LOW1600 STA HATABS+1,X ; LSB of driver addr1610 LDA #MDRI;0}VER/HIGH1620 STA HATABS+2,X ; and MSB of addr1630 LDA #01640 STA HATABS+3,X ; A new end for the table1650 ;1660 ; now;1} change LOMEM so BASIC won't1670 ; overwrite us.1680 ;1690 MINSTALLED1700 LDA #DRIVERTOP&LOW1710 STA MEMLO ; LSB of to;2}p addr1720 LDA #DRIVERTOP/HIGH1730 STA MEMLO+1 ; and MSB therof1740 ;1750 ; and that's all we have to do!1760 ;1770 ;3}RTS1780 ;1790 ;1800 ;;;;;;;;;;;;;;;;;;;;;;;;;;;1810 ;1820 ; This entry point is provided1830 ; so that BASIC can reconn;4}ect1840 ; the driver via a USR(RECONNECT)1850 ;1860 RECONNECT1870 PLA1880 BEQ LOADANDGO ; No parameters, I hope1890 ;5}TAY1900 PULLTHEM1910 PLA1920 PLA ; get rid of a parameter1930 DEY1940 BNE PULLTHEM ; and pull another1950 BEQ LOAD;6}ANDGO ; go reconnect1960 ;1970 .PAGE "The driver itself"1980 ;1990 ; Recall that all drivers must2000 ; be connected to;7} OS through2010 ; a driver routines address table.2020 ;2030 MDRIVER2040 .WORD MOPEN-1 ; The addresses must2050 .WORD ;8}MCLOSE-1 ; ...be given in this2060 .WORD MGETB-1 ; ...order and must2070 .WORD MPUTB-1 ; ...be one (1) less2080 .WORD M;9}STATUS-1 ; ...than the actual2090 .WORD MXIO-1 ; ...address2100 JMP MINIT ; This is for safety only2110 ;2120 ; For man;:}y drivers, some of these2130 ; routines are not needed, and2140 ; can effectively be null routines2150 ;2160 ; A null rou;;}tine should return2170 ; a one (1) in the Y-register2180 ; to indicate success.2190 ;2200 MXIO2210 MINIT2220 LDY #1 ; ;<}success2230 RTS2240 ;2250 ; If a routine is omitted because2260 ; it is illegal (reading from a2270 ; printer, etc.), s;=}imply pointing2280 ; to an RTS is adequate, since2290 ; Atari OS preloads Y with a2300 ; 'Function Not Implemented' error;>}2310 ; return code.2320 ;2330 .PAGE "The driver function routines"2340 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2350 ;2360 ; Now;?} we begin the code for the2370 ; routines that do the actual2380 ; work2390 ;2400 MOPEN2410 LDA ICAUX1,X ; Check type o;@}f open2420 AND #OPOUT ; Open for output?2430 BEQ OPENFORREAD ; No...assume for input2440 LDA MEMTOP2450 STA MSTART ; ;A}We start storing2460 LDY MEMTOP+1 ; ...the bytes2470 DEY ; ...one page below2480 STY MSTART+1 ; the supposed top of mem;B}2490 ;2500 ; now we join up with mode 4 open2510 ;2520 OPENFORREAD2530 LDA MSTART ; simply move the2540 STA MCURRENT ;C}; ...start pointer2550 LDA MSTART+1 ; ...to the current2560 STA MCURRENT+1 ; ...pointer, both bytes2570 ;2580 LDY #STA;D}TUSOK2590 RTS ; we don't acknowledge failure2600 ;2610 ;2620 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2630 ;2640 ; the routine ;E}for CLOSE of M:2650 ;2660 MCLOSE2670 LDA ICAUX1,X ; check mode of open2680 AND #OPOUT ; was for output?2690 BEQ MCLRE;F}AD ; no...close input 'file'2700 ;2710 LDA MCURRENT ; we establish our2720 STA MSTOP ; ...limit so that2730 LDA MCURRE;G}NT+1 ; ...next use can't2740 STA MSTOP+1 ; ...go too far2750 ;2760 MCLREAD2770 LDY #STATUSOK2780 RTS ; and guaranteed;H} to be ok2790 ;2800 ;2810 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2820 ;2830 ; This routine puts one byte2840 ; to the memory for;I} later2850 ; retrieval.2860 ;2870 MPUTB2880 PHA ; save the byte to be PUT2890 JSR MOVECURRENT ; get ptr to zero page2;J}900 PLA ; the byte again2910 LDY #02920 STA (FR1),Y ; put the byte, indirectly2930 JSR DECCURRENT ; point to nxt byte;K}2940 RTS ; that's all2950 ;2960 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2970 ;2980 ; routine to get a byte put2990 ; in memory bef;L}ore.3000 ;3010 MGETB3020 JSR MSTATUS ; any more bytes?3030 BCS MGETRTS ; no...error3040 LDY #03050 LDA (FR1),Y ; ye;M}s...get a byte3060 JSR DECCURRENT ; and point to next byte3070 MGETRTS3080 RTS3090 ;3100 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;N};;3110 ;3120 ; check the status of the driver3130 ;3140 ; this routine is only valid3150 ; when READing the 'file'...31;O}60 ; "M:" never gets errors when3170 ; writing.3180 ;3190 MSTATUS3200 JSR MOVECURRENT ; current ptr to zero page3210 C;P}MP MSTOP ; any more bytes to get?3220 BNE MSTOK ; yes3230 CPY MSTOP+1 ; double chk3240 BNE MSTOK ; yes, again3250 LDY;Q} #STATUSEOF ; oops...3260 SEC ; no more bytes3270 RTS3280 ;3290 MSTOK3300 LDY #STATUSOK ; all is okay3310 CLC ; fla;R}g for MGETB3320 RTS3330 .PAGE "Miscellaneous subroutines"3340 ;3350 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3360 ;3370 ; final;S}ly, we have a couple of3380 ; short and simple routines to3390 ; manipulate MCURRENT, the ptr3400 ; to the currently acces;T}sed byte3410 ;3420 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3430 ;3440 ; MOVECURRENT simply moves3450 ; MCURRENT to the floating;U}3460 ; point register, FR1, in3470 ; zero page. FR1 is always3480 ; safe to use except in the3490 ; middle of an expr;V}ession.3500 ;3510 MOVECURRENT3520 LDA MCURRENT3530 STA FR1 ; notice that we use3540 LDY MCURRENT+1 ; both the A and3;W}550 STY FR1+1 ; Y registers...this3560 RTS ; is for MSTATUS use3570 ;3580 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3590 ;3600 ;;X} DECCURRENT simply does a two3610 ; byte decrement of the MCURRENT3620 ; pointer and returns with the3630 ; Y register ;Y}indicating OK status.3640 ; NOTE that the A register is3650 ; left undisturbed.3660 ;3670 DECCURRENT3680 LDY MCURRENT ;Z}; check LSB's value3690 BNE DECLOW ; if non-zero, MSB is ok3700 DEC MCURRENT+1 ; if zero, need to bump MSB3710 DECLOW37;[}20 DEC MCURRENT ; now bump the LSB3730 LDY #STATUSOK ; as promised3740 RTS3750 .PAGE "RAM usage and clean up"3760 ;3;\}770 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3780 ;3790 ; END OF CODE3800 ;3810 ;3820 ; Now we define our storage3830 ; locations.;]}3840 ;3850 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3860 ;3870 ;3880 ; MCURRENT holds the pointer to3890 ; the next byte to be PUT;^} or GET3900 MCURRENT .WORD 03910 ;3920 ; MSTOP is set by CLOSE to point3930 ; to the last byte PUT, so GET3940 ; won't t;_}ry to go past the end3950 ; of data.3960 MSTOP .WORD 03970 ;3980 ; MSTART is derived from MEMTOP3990 ; and points to the;`} first byte4000 ; stored. The bytes are stored4010 ; in descending addresses until4020 ; MSTOP is set by CLOSE.4030 MSTA;a}RT .WORD 04040 ;4050 ; DRIVERTOP becomes the new4060 ; contents of MEMLO4070 DRIVERTOP = *+$FF&$FF004080 ; (sets to next;b} page boundary)4090 ;4100 ;4110 ; The following is how you make4120 ; a LOAD-AND-GO file under4130 ; Atari's DOS 24140 ;c};4150 *= $2E04160 .WORD LOADANDGO4170 ;4180 ;4190 .END4120 ; a LOAD-AND-GO file under4130 ; Atari's DOS 24140 8B)AIOMAC.LIB -- OSS system I/O macrosAA Support MacrosA 10IOCB2 AYou must include SYSEQU.M65 ahead of th?e}is!!AX;$6X; These macros are called by the actual I/O macros.9X; to perform the rudimentary register load functions.?f}8X;BX;LX; MACRO: @CHVX;`6X; Loads IOCB number (parameter 1) into X register.jX;t 7 then a memory location1X; is assumed to?h} contain the channel number.X; @CH   Q T?T?T?T?>  $> (X;2X;<X; MAC?i}RO: @CVFX;P:X; Loads Constant or Value into accumultor (A-register)ZX;d+X; If value of parameter 1 is 0-255, @CVn+X; ?j}assumes it's an (immediate) constant.xX;'X; Otherwise the value is assumed to+X; be a memory location (non-zero page).?k}X;X;X; @CV   Q> Q X;X;X;X;"X; MACRO: @FL,X;65X; @FL is used to e?l}stablish a filespec (file name)@X;J-X; If a literal string is passed, @FL willT'X; generate the string in line, jump^&X;?m} around it, and place its addressh/X; in the IOCB pointed to by the X-register.rX;|(X; If a non-zero page label is passed?n}*X; the MACRO assumes it to be the label.X; of a valid filespec and uses it instead.X;X;X; @FL   ?o} !   @F = Q>4@F PICBADR9 Q>5@FPICBADR9 Q>4  PICBADR9& Q>5 0PICBADR9:D?p}NA XIO macroAXX;bX; MACRO: XIOlX;v/X; FORM: XIO cmd,ch[,aux1,aux2][,filespec]X;%X; ch is given as in the?q} @CH macro3X; cmd, aux1, aux2 are given as in the @CV macro+X; filespec is given as in the @FL macroX;5X; performs f?r}amiliar XIO operations with/for OS/A+X;/X; If aux1 is given, aux2 must also be given8X; If aux1 and aux2 are omitted, ?s}they are set to zero1X; If the filespec is omitted, "S:" is assumedX; XIO  3 % AXIO: wrong number o?t}f argumentsA  @CH   @CV *PICCOM9;; COMMAND4  > @CV H PICAUX19R @CV \ PICAUX29fp?u}Q>z PICAUX19 PICAUX29 3 @FL AS:A @@IO @FL @@@IO: CIOA ?v} OPEN macroAX; X; MACRO: OPEN X; (X; FORM: OPEN ch,aux1,aux2,filespec$ X;. %X; ch is given as in the @CH macro8 1?w}X; aux1 and aux2 are given as in the @CV macroB +X; filespec is given as in the @FL macroL X;V 1X; will attempt to open the ?x}given file name on` /X; the given channel, using the open "modes"j X; specified by aux1 and aux2t X;~ OPEN   &?y} AOPEN: wrong number of argumentsA    XIO COPN= = = =   XIO COPN= = = =    ?z} A BGET and BPUT macrosA X; X; MACROS: BGET and BPUT X; X; FORM: BGET ch,buf,len X; BPUT ch,buf,le?{}n( X;2 %X; ch is given as in the @CH macro< .X; len is ALWAYS assumed to be an immediateF 1X; and actual value...never a m?|}emory addressP /X; buf must be the address of an appropriateZ X; buffer in memoryd X;n +X; puts or gets length bytes to/f?}}rom thex 0X; specified buffer, uses binary read/write X; X; X; first: a common macro X; @GP @CH  Q> ?~} PICCOM9 Q>4  PICBADR9 Q>5  PICBADR9 Q>4  PICBLEN9 Q>5  PICBLEN9"  CIO, 6 X;@ B?}GET J  T ' ABGET: wrong number of parametersA^ h @GP = = =CGBINRr |  X; BPUT   ' AB?}PUT: wrong number of parametersA  @GP = = =CPBINR   X; A PRINT macroA X; X; MACRO: PRINT ?}X; (X; FORM: PRINT ch[,buffer[,length]] X; !X; ch is as given in @CH macro& (X; if no buffer, prints just a RETURN0 %X;?} if no length given, 255 assumed: X;D 8X; used to print text. To print text without RETURN,N -X; length must be given. See?} OS/A+ manualX X;b 2X; EXCEPTION: second parameter may be a literall .X; string (e.g., PRINT 0,"test"), in whichv -X; case?} the length (if given) is ignored. X; PRINT  3  ( APRINT: wrong number of parametersA    ?}  !   @IO = @GP =@IO= =CPTXTR    @GP = ==CPTXTR  @GP = ?}= =CPTXTR  * 4 ! > @IO H @GP =@IO==CPTXTRR \ f p X;z A INPUT macroA X; X; MACRO:?} INPUT X; X; FORM: INPUT ch,buf,len X; %X; ch is given as in the @CH macro )X; buf MUST be a proper buffer address?} 6X; len may be omitted, in which case 255 is assumed X; ,X; gets a line of text input to the given 'X; buffer, maximu?}m of length bytes X; INPUT  3 ( AINPUT: wrong number of parametersA$  .@GP = ==?}CGTXTR8B@GP = = =CGTXTRLV`jA CLOSE macroAtX;~X; MACRO: CLOSEX;X; FORM: CLOSE ch?}X;%X; ch is given as in the @CH macroX;X; closes channel chX; CLOSE   ( ACLOSE: wrong number of par?}ametersA @CH  Q>CCLOSE  PICCOM9 CIO(2X;<-X;;;;;;;;;;; END OF IOMAC.LIB ;;;;;;;;;;;;FX; of par<vs