

     |||||| |||||| ||  || |||||| ||||||
     ||     ||     ||| ||   ||   ||
     || ||| ||||   ||||||   ||   ||||               Your
     ||  || ||     || |||   ||   ||
     |||||| |||||| ||  || |||||| ||||||             GEnieLamp Computing

     ||    |||||| ||    || ||||||                   RoundTable
     ||    ||  || |||  ||| ||  ||
     ||    |||||| |||||||| ||||||                   RESOURCE!
     ||    ||  || || || || ||
     ||||| ||  || ||    || ||


                     ~ WELCOME TO GENIELAMP A2Pro! ~
                       """""""""""""""""""""""""""
                  ~ Handling Interrupts ~ Source Code ~
                ~ GNO/ME Help ~ Developer Announcements ~
           ~ TIPS AND TECHNIQUES: Writing Ampersand Routines "
                  ~ HOT NEWS, HOT FILES, HOT MESSAGES ~

 \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\////////////////////////////////////
  GEnieLamp A2Pro      ~ A T/TalkNET Publication ~       Vol.6, Issue 33
 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 Publisher.................................................John F. Peters
  Editor....................................................Tim Buchheim
 \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\////////////////////////////////////
          ~ GEnieLamp IBM ~ GEnieLamp Atari ~ GEnieLamp PowerPC ~
         ~ GEnieLamp A2Pro ~ GEnieLamp Macintosh ~ GEnieLamp TX2 ~
          ~ GEnieLamp Windows ~ GEnieLamp A2 ~ LiveWire (ASCII) ~ 
             ~ Member Of The Digital Publishing Association ~
  GE Mail: GENIELAMP                       Internet: genielamp@genie.com
 ////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

             >>> WHAT'S HAPPENING IN THE A2Pro ROUNDTABLE? <<<
             """""""""""""""""""""""""""""""""""""""""""""""""
                           ~ January 7, 1996 ~

 FROM MY DESKTOP ......... [FRM]        A2PRO ROUNDTABLE STAFF .. [DIR]
  Notes From The Editor.                 Directory of A2Pro Staff.              

 TIPS AND TECHNIQUES ..... [TIP]        HEY MISTER POSTMAN ...... [HEY]
  Writing Ampersand Routines.            Is That A Letter For Me?

 DEVELOPERS CORNER ....... [DEV]        LIBRARY BIT BONANZA ..... [LIB]
  News From Online Developers.           HOT Files You Can Download.
  
                     LOG OFF ................. [LOG]
                      GEnieLamp information.


[IDX]"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

READING GEnieLamp   GEnieLamp  has  incorporated  a  unique   indexing
"""""""""""""""""   system to help make  reading the  magazine easier.
To  utilize this system, load GEnieLamp into any ASCII  word processor
or text  editor.  In the index  you will find the  following  example:

                   A2PRO ROUNDTABLE STAFF .. [DIR]
                    Directory of A2Pro Staff.              

   To read this  article, set your  find or search command to [DIR].  If
you want to scan all of the articles, search for [EOA].  [EOF] will take
you to  the last page,  whereas [IDX]  will bring you back to the index.

MESSAGE INFO   To make it easy for you to respond to messages re-printed
""""""""""""   here in GEnieLamp, you will find all the information you
need immediately following the message.  For example:

                    (SMITH, CAT6, TOP1, MSG:58/M530)
        _____________|   _____|__  _|___    |____ |_____________
       |Name of sender   CATegory  TOPic    Msg.   Page number|

    In this  example, to  respond to  Smith's  message, log  on to  page
530 enter the bulletin board and set CAT 6. Enter your REPly in TOPic 1.

    A message number that is surrounded by brackets indicates  that this
message  is a "target" message and is  referring  to  a "chain"  of  two
or more  messages that are following the same topic.  For example: {58}.

ABOUT GEnie   GEnie's monthly fee is $8.95 which gives you up to four hours
"""""""""""   of non-prime time access to most GEnie services, such as
software downloads, bulletin boards, GE Mail, an Internet gateway, award-
winning multi-player games and friendly chat lines.  GEnie's non-prime time
connect rate is only $3.00 per hour.  Prime Time (8:00 am to 6:00 pm local
time on weekdays) is only $5.00 per hour.  To sign up for GEnie, just
follow these simple steps:

1.  Set your communications software to half duplex (local echo) 8 bits, no
 parity and 1 stop bit, at 300, 1200, 2400 or 9600 baud.

2.  Call (with modem) 1-800-638-8369 (US) or 1-800-387-8330 (Canada).

3.  Wait for the U#= prompt.  Type:  JOINGENIE and hit RETURN.  When you
 get the prompt asking for the signup/offer code, type: DSD524  and hit
 RETURN.

4.  Have a major credit card ready, as the system will prompt you for your
 information.  If you need more information, call GEnie's Customer Service
 department at 1-800-638-9636.
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""




[EOA]
[FRM]//////////////////////////////
                 FROM MY DESKTOP /
/////////////////////////////////
Notes From My Desktop
"""""""""""""""""""""
by Tim Buchheim
 [A2PRO.GELAMP]


    o TOP OF THE PAGE



                          >>>  TOP OF THE PAGE  <<<
                          """""""""""""""""""""""""
                        ~ A Letter From the Editor ~


DECEMBER?   If you're a regular reader of GEnieLamp A2Pro, then you're
"""""""""   probably wondering what happened to the December issue.  Well,
I simply was not able to complete it, for several reasons.  The main reason
was that I was sick with the flu (I think it was the type-A Texas strain)
for several weeks.  During this time it made me dizzy to sit up or read, so
I was unable to use the computer. :/

I got better around the 10th of December, and inteded to finish the issue
and call it the Mid-December issue, but I was unable to do so due to the
large amount of homework I had to make up. (I'm a senior in high school.)

Thus I decided to skip the December issue and wait for January.


GOOD NEWS   On December 22 I received a phone call from the Dean of
"""""""""   Admissions at Harvey Mudd College in Claremont, CA.  I am one
of thirty people admitted Early Decision.  I think it's cool that they
called me before Christmas.. I had planned to finish my Caltech and MIT
applications after Christmas, and this way I was able to throw them in the
trash instead. :)



                                              -- Timothy Carl Buchheim
                                                 Editor, GEnieLamp A2Pro



P.S.    Once again we have a feature article on 8-bit programming
        by Russ Nielson, so there wasn't room for the usual "RTC Watch"
        article and the continuing "Spotlight On" column.  Next month,
        though, "Spotlight On:" will be taking a look at Russ Nielson,
        and if there is enough room in the issue there will be an
        "RTC Watch" column.




                              [*][*][*]


    Do you have something  to say about  GEnieLamp A2Pro?  Please
    post  any questions or  comments you  may have in Category 1,
    Topic 15 in A2Pro's BB (m530;1).  Or, feel free to talk to me
    (A2PRO.GELAMP) anytime you see  me in a Real Time Conference.

    Readers out there on the Internet:   feel free to email me at
    a2pro.gelamp@genie.com     When writing, please tell me where
    you got your copy of  GEnieLamp,  if it wasn't on GEnie.  I'm
    always interested to see how many places GEnieLamp ends up :)

    By the way,  the  current  issue  and  most  back issues  are
    available online in  many  places.  GEnie users  should check
    Library #2  in the  DigiPub libraries  (DIGIPUB, page 1395;3)
    Those of  you not on  GEnie  should  use  gopher  software to
    connect to gopher.genie.com for issues; all recent issues and
    most older ones are there.

    I know that many  people get GEnieLamp from  various Apple II
    ftp  sites.   For  example,  ftp://grind.isca.uiowa.edu/  has
    many  backissues.  Note  that I am  not the one  who puts the
    issues there, (GEnie's ftp  software currently  has the "put"
    command  disabled) so  if an issue  is missing from  there, I
    can't do  anything about it.  The only  internet distribution
    site which I can update myself is gopher://gopher.genie.com


                              [*][*][*]



[EOA]
[DIR]//////////////////////////////
          A2PRO ROUNDTABLE STAFF /
/////////////////////////////////
By Tim Buchheim
 [A2PRO.GELAMP]


    o   A2Pro STAFF LIST



                        >>> A2Pro STAFF LIST <<<
                        """"""""""""""""""""""""

                          ______________________________________________

                           APPLE II PROGRAMMERS & DEVELOPERS ROUNDTABLE
       _____  ______      ______________________________________________
      /_____|/______\
     /__/|__|  ___|__|         Head Sysop: Hangtime         (HANGTIME)  
    /__/_|__| /_____/         Your Sysops: Greg Da Costa    (A2PRO.GREG)
   /________|/__/       __ __ __           Todd P. Whitesel (A2PRO.TODDPW)
  /__/   |__|__/______ /_//_// /           Nathaniel Sloan  (JNSLOAN)
 /__/    |__|________//  / \/_/            Tim Buchheim     (A2PRO.GELAMP)
                                           Dave Miller      (JUST.DAVE)
 _______________________________           Russ Nielson     (R.NIELSON1)



[EOA]
[TIP]//////////////////////////
         TIPS AND TECHNIQUES /
/////////////////////////////
Writing Ampersand Routines
""""""""""""""""""""""""""
By Russell Nielson
      [R.NIELSON1]



INTRODUCTION   Programming in Applesoft is a very convienent way to write
""""""""""""   quick and simple programs to do ordinary things, but there
comes a time when Applesoft just isn't powerful enough to do all the things
we want, or need it to do.  Anyone who has ever programmed in Applesoft
extensively, knows that writing small machine language routines is almost
essential to do such tasks that are impossible with Applesoft.  One
common example would be sound generation; you cannot produce any "real"
sound or music from using Applesoft instructions because it is just way too
slow.  In order to produce sound or musical notes, you need to access the
softswitch at the speaker location repeatedly and at a very high rate,
which through Applesoft is not possible.  It's easy enough to write the
small machine language routine and call it from Applesoft to generate the
sounds, but that usually involves having  you POKE in the routine and
then CALLing it.  There's nothing wrong with this method, but it can get
very cumbersome when you need to pass several parameters and start using
many called routines.  In using the normal CALLing conventions you need
to POKE in all the values into the right memory locations so the routine
that is CALLed can pick up these values and do its thing.  Maintaining
these CALLing structures can be very confusing and lead to unnecessary
aggrivation.


AMPERSAND (&) COMMAND   But things are looking up because there is a very
"""""""""""""""""""""   useful command at our disposal called the Ampersand
command.  This calling convention is used directly from Applesoft to call
machine language routines in a "civilized" fashion.  The Ampersand
command works by setting up a vector into your machine language program. 
The Ampersand vector is located at $3F5.  A vector is simply a JuMP
instruction to your machine language routine that handles the Ampersand
command string.  So in order to set it up you would do this:

Amper     equ $3f5             ; Ampersand vector

SetAmper
          lda #$4c             ; opcode for JMP
          sta Amper            ; put at &-vector address
          lda #<AParse         ; get low order byte
          sta Amper+1          ; store it for the JMP
          lda #>AParse         ; get high order byte
          sta Amper+2          ; store it for the JMP
          rts                  ; leave

AParse	(code here)

If you look at the code you will see that we store a $4C into the first
byte of the Ampersand vector, then we store the address of 'Aparse' in
the next two bytes.  This sets up our vector and all '&' commands from
Applesoft will be routed to 'AParse'.  This setup is essentially a 'JMP
AParse', so when the '&' command sends control to the vector, it jumps to
our 'AParse' routine and the command is parsed and executed.


CREATING A COMMAND CENTER   This is all and well when all you have is one
"""""""""""""""""""""""""   command, but you will probably want to set up a
way to use the '&' command to call many routines, otherwise it wouldn't
be of much use to us.  What we are going to do is follow each '&' command
with a function number which tells our 'AParse' routine which routine is to
be performed.  On that note let's look at some code to set that up.

ptr       equ $eb              ; general usage pointer 
GetByte   equ $e6f8            ; evaluate expression to x-reg

AParse
          jsr GetByte          ; get function number
          cpx #3               ; validate function number (max of 3)
          bcc :valid
          rts                  ; not valid, return with error
:valid
          txa                  ; convert function number into index
          asl                  ; for accessing the function address table
          tax
          lda :F_Table+1,x
          sta ptr+1
          lda :F_Table,x
          sta ptr
          jmp (ptr)	           ; jump to function routine

:F_Table
          da Function1
          da Function2
          da Function3

Function1
          (do your stuff)
Function2
          (do your stuff)
Function3
          (do your stuff)

If you look at this code example you will see how it works.  First thing we
will do is get the first parameter after the '&' command which will be
our function number.  The 'JSR GetByte' evaluates this expression from
the command line and puts the value into the x-register.  In this case
the function will always be a number from (0-x) where 'x' is the maximum
number of functions we define.  If you look further you will see that we
take the x-register and convert it into an index to address our function
table, which contains the addresses of all our functions.  Using this
method limits our function table to 128 entries, because the maximum
value that an 8-bit register can hold is 256, but I cannot imagine having
near that many functions.    We use a neat trick called indirect jumping,
this works by putting the address of the routine into 'ptr' and jumping
to where 'ptr' points to.  If you understand indirect addressing then you
will see that this is no different.  We even valid the function number with
the 'cpx  #3' instruction which will only allow a function number from 0 to
2, if the number is not in this range control is passed back to Applesoft
via the 'rts' and Applesoft prints a 'SYNTAX ERROR'.  The reason a SYTAX
ERROR is generated is because the '&' command was never finished and the
program pointer was in the middle of the '&' command, and when Applesoft
regained control it got confused and program execution halted.  This is a
very useful method when designing and testing our '&' routines because if
you pass the wrong number of parameters or use a wrong function number, you
will get a SYNTAX ERROR.

Let me illustrate the format for an '&' command:

& value, value, variable, etc...

If our case we would do:

& function_number, value, value, etc..

Now is a good time to explain some of the routines that manipulate the
command line pointer.  When the '&' command is first envoked and control is
passed to 'AParse' the '&' command line pointer is at the first value in
the command, which is the first parameter.  We will use commands to pull
values from the command line and advance the pointer.  Note:  By using
these routines you can pass parameters in any format, including straight
numbers, variables, and expressions.  Here are some very useful Applesoft
parameter passing routines.  Please realize that some of these are the same
routines that Applesoft uses to manipulate strings and variables.

PtrGet    $dfe3   find named variable
GetByte   $e6f8   evaluate expression to x-reg
ComByte   $e74c   gobble comma, evaluate expression to x-reg
StrIni    $e3d5   create new string space
MovStr    $e5e2   move string into space
ChkCom    $debe   gobble comma
EndData   $d995   advance to end of data

PTRGET   This routine finds the address of the variable.
GETBYTE  This routine evaluates the next parameter on the command line and 
         places the value into the x-register.
COMBYTE  This routine will eat the comma from the command line and then 
         evaluate the next parameter on the command line.
STRINI   This routine will create new string space for a string variable.
MOVSTR   This routine will move the contents of one string to the new one.
CHKCOM   This routine will gobble the comma from the command line.
ENDDATA  This routine will advance the command line pointer to the end of
         the command line, hence ignoring all remaining parameters.

Using these expression routines, valid commands would look like this:

& 0, 10,20, A$
& 0, X, H, A$
& 0, 1*2+5-(10+4)-X, A-B+(B=1), ST$

The routines will evaluate the expressions and return the values.


AN ACTUAL ROUTINE   At this point we have our Ampersand vector set up, and
"""""""""""""""""   we have our parser routine directing control to the
appropriate function, so all that is left is to write an actual routine
which will pull the parameters from the command line and act on them. 
Let's use a print string command as our first function. Here's the format
we'll use for our print function:

& 0, vtab, htab, string

The '0' is the function number, then the 'vtab' would be the vtab
position to print the string, the 'htab' would be the htab position, and
lastly the 'string' would be the string to print.  A real example would
be this:

A$ = "Hello World!"
& 0, 2, 0, A$

This would translate to "print at vtab 3, htab 1, string A$".  Please be
aware that the true vtab values are 0-23 and the true htab values are 0-39;
in Applesoft the first position would be VTAB 1, because the '1' translates
to '0'.

Let's start with the code, please note that I changed 'Function1' to 'APrint'.

Htab      equ $24              ; htab
Vtab      equ $25              ; vtab
VarPtr    equ $83              ; pointer to variable value 
Cout      equ $fded            ; character out routine
DoTabs    equ $fb5b            ; set tabs from a/x regs

APrint
          jsr ComByte          ; get Vtab
          cpx #24              ; greater than 23 is no good
          bcs :out
          stx Vtab             ; store it
          jsr ComByte          ; get Htab
          cpx #40              ; greater than 39 is no good
          bcs :out
          stx Htab             ; store it
          jsr ChkCom           ; gobble comma
          jsr PtrGet           ; get address of string

          lda Vtab             ; position cursor for output
          ldx Htab
          jsr DoTabs

          ldy #0
          lda (VarPtr),y       ; get length of string
          tax
          iny
          lda (VarPtr),y       ; get LOB of string address
          sta :print+1
          iny
          lda (VarPtr),y       ; get HOB of string address
          sta :print+2
          txa
          tay
          ldx #0
:print    lda $ffff,x          ; get character (self-modified!)
          ora #$80             ; make it ASCII printable
          jsr Cout             ; character out
          inx
          dey
          bne :print

:out      rts                  ; return to Applesoft

The first thing we are going to do when entering our routine is to gobble
the comma after the function code and get our vtab value from the command
line.  The 'JSR ComByte' does this for us and the value is waiting in the
x-register.  We take the initiative to validate the vtab value with a range
from 0-23.  Anything outside this range will cause the program to jump to
the ':out' routine with a 'rts' to Applesoft and a SYNTAX ERROR will be
generated.  This is good practice because from Applesoft we will
determine the range problem and fix it.  The vtab value is then stored in a
variable.  Next we gobble the comma after the vtab parameter, get our
htab value, and store it as well.  The same type of validation is done here
as with the vtab value.  Now we have a string value coming up next, so we
gobble just the comma with 'JSR ChkCom'.  Now the command line pointer is
at our string parameter.  A call of 'JSR PtrGet' causes the routine to
locate the address for the string variable (notice that this is NOT the
string, it's the variable address!), and store it in zero page location
'VarPtr'.  We call the tabs routine to set our tabs which positions the
cursor on the text screen.  Now 'VarPtr' points to the string variable. 
The next three bytes at this address defines the variable.  The length of
the string comes first, then the address where the string is located.  So
we grab the length byte and transfer it to the x-register to use as a
loop counter for the print routine.  Next we grab the address of the string
and store it in the code itself at label ':print'.  This is called
self-modifying code, so when the 'lda $ffff' is executed, the '$ffff' has
been changed to point to the address of the string.  Now we print the
string, and we're done with a successful 'rts' back to Applesoft.


THE BASICS   That's all there is to an '&' command!  The print string
""""""""""   routine illustrates how to handle values and strings from the
command line, and how to use these values in a practical example.

Now I want to give you the source to a complete three-function program
and explain a few of the concepts.

========================== CODE BEGIN =============================

Sample    equ $666             ; Nothing
          org $6000            ; assemble address

          lst on               ; turn on listing
          case off             ; no case sensitivity
          tr on                ; expand macros
          tr adr
          xc off               ; 6502 opcodes only

          dsk Ampersand

*-------------------------------------------------
*   Zero page usage
*-------------------------------------------------

Pitch     equ $d6              ; holds pitch for tone
ptr       equ $eb              ; general usage pointer
Htab      equ $24              ; htab
Vtab      equ $25              ; vtab

*-------------------------------------------------
*   Zero page constants
*-------------------------------------------------
Cout      equ $fded            ; character out routine
DoTabs    equ $fb5b            ; set tabs from a/x regs
Tabs      equ $fc22            ; set tabs from $24/$25

Ch        equ $24              ; monitor HTAB value
Inverse   equ $32              ; Applesoft inverse flag location
VarPtr    equ $83              ; pointer to variable value
DscTmp    equ $9d              ; string descriptor: length, lo, hi

*  Softswitches

Key       equ $C000            ; keyboard buffer
SKey      equ $C010            ; clear buffer
Spkr      equ $C030            ; speaker location

*-------------------------------------------------
*   Monitor routines
*-------------------------------------------------

Amper     equ $3f5             ; Ampersand vector

Cout      equ $fded            ; character out routine
DoTabs    equ $fb5b            ; set tabs from a/x regs
Tabs      equ $fc22            ; set tabs from $24/$25

PtrGet    equ $dfe3            ; find named variable, addr in VarPtr
GetByte   equ $e6f8            ; evaluate expression to x-reg
ComByte   equ $e74c            ; gobble comma, evaluate expression to x-reg
StrIni    equ $e3d5            ; create new string space
MovStr    equ $e5e2            ; move string into space
ChkCom    equ $debe            ; gobble comma
EndData   equ $d995            ; advance to end of data

*-------------------------------------------------
*  Setup Ampersand Vector
*-------------------------------------------------

SetAmper	
          lda #$4c             ; opcode for JMP
          sta Amper            ; put at &-vector address
          lda #<AParse         ; get low order byte
          sta Amper+1          ; store it for the JMP
          lda #>AParse         ; get high order byte
          sta Amper+2          ; store it for the JMP
          rts                  ; leave

*-------------------------------------------------
*  Ampersand command line parser
*-------------------------------------------------
* Function 0 = Print string
*              & 0, vtab, htab, string-variable
*          eg. & 0,10,8,A$
*
* Function 1 = Do tone
*              & 1, pitch, duration
*          eg. & 1,40,66
*
* Function 2 = Line Input
*              & 2, vtab, htab, input limit
*          eg. & 2,4,1,20
*
*-------------------------------------------------

AParse
          jsr GetByte          ; get function number
          cpx #3               ; validate function number
          bcc :valid
          rts                  ; not valid, return with error
:valid
          txa                  ; convert function number into index
          asl                  ; for accessing the function address table
          tax 
          lda :F_Table+1,x
          sta ptr+1
          lda :F_Table,x
          sta ptr
          jmp (ptr)            ; jump to function routine

:F_Table
          da APrint            ; Function 0 = print string
          da DoTone	           ; Function 1 = do tone
          da LineInput         ; Function 2 = line input

*-------------------------------------------------
*  Ampersand print
*-------------------------------------------------

APrint
          jsr ComByte          ; get Vtab
          cpx #24              ; greater than 23 is no good
          bcs :out
          stx Vtab             ; store it
          jsr ComByte          ; get Htab
          cpx #40              ; greater than 39 is no good
          bcs :out
          stx Htab             ; store it
          jsr ChkCom           ; gobble comma
          jsr PtrGet           ; get address of string

          lda Vtab             ; position cursor for output
          ldx Htab
          jsr DoTabs

          ldy #0
          lda (VarPtr),y       ; get length of string
          tax
          iny
          lda (VarPtr),y       ; get LOB of string address
          sta :print+1
          iny
          lda (VarPtr),y       ; get HOB of string address
          sta :print+2
          txa
          tay
          ldx #0
:print    lda $ffff,x          ; get character (self-modified!)
          ora #$80             ; make it ASCII printable
          jsr Cout             ; character out
          inx
          dey
          bne :print

:out      rts                  ; return to Applesoft

*-------------------------------------------------
*  Tone routine
*-------------------------------------------------

DoTone
          jsr ComByte          ; get pitch
          stx Pitch	           ; save it
          jsr ComByte          ; get duration
          txa                  ; transfer to y-reg
          tay

Tone      ldx Pitch            ; create tone from pitch value
:2        dex
          bne :2
          bit Spkr             ; click speaker
          dey                  ; loop
          bne Tone

:out      rts                  ; return to Applesoft

*-------------------------------------------------
*  Tone routine for internal use
*-------------------------------------------------

IDoTone
          stx Pitch
          jmp Tone

*-------------------------------------------------
*  Line Input
*-------------------------------------------------

LineInput
          jsr ComByte          ; get Vtab
          cpx #24              ; greater than 23 is no good
          bcs :out
          stx Vtab             ; store it
          jsr ComByte          ; get Htab
          cpx #40              ; greater than 39 is no good
          bcs :out
          stx Htab             ; store it
          jsr ComByte          ; get input limit
          stx :Limit           ; store it
          jsr ChkCom           ; gobble comma
          jsr PtrGet           ; get address of string
          lda :Limit           ; length of new string
          jsr StrIni           ; create new string of given size
          ldy #0
          lda DscTmp           ; copy new descriptor to variable
          sta (VarPtr),y       ; string length descriptor
          iny
          lda DscTmp+1
          sta (VarPtr),y       ; string LOB descriptor
          sta ptr              ; pointer to string LOB
          iny
          lda DscTmp+2
          sta (VarPtr),y       ; string HOB descriptor
          sta ptr+1	           ; pointer to string HOB
          jmp :ok

:out      rts                  ; return to Applesoft

:ok       jsr Tabs             ; position cursor for output

          lda #0               ; character counter
          sta :Count

:getchar  jsr :flash           ; flash cursor and get character
          bpl :getchar         ; non-ASCII, get another character
          sec
          sbc #128             ; convert to low ASCII
          cmp #141-128         ; check for RETURN
          beq :return
          cmp #136-128         ; check for left arrow
          beq :delete
          cmp #255-128         ; check for DELETE
          beq :delete
          cmp #","-128         ; check for comma
          beq :getchar
          cmp #":"-128         ; check for colon
          beq :getchar
          cmp #160-128         ; only accept certain characters
          bcc :getchar         ; for input
          cmp #255-128
          bcs :getchar

          ldx :Count
          cpx :Limit           ; number of characters reached limit yet?
          bne :printit         ; not yet, print this guy
          ldx #230             ; if so, then allow no more!
          ldy #4
          jsr IDoTone
          jmp :getchar

:printit  ora #$80             ; make it ASCII printable
          jsr Cout
          ldy :Count
          sta (ptr),y          ; store character in string
          inc :Count
          ldx #30              ; some sound
          ldy #2
          jsr IDoTone
          jmp :getchar         ; get next character

:delete   ldx :Count           ; delete a character only if there is one
          cpx #0
          beq :getchar
          ldx :Count           ; only erase cursor if it's there
          cpx :Limit
          beq :delete2
          lda #" "
          jsr Cout
          dec Htab             ; cursor back one position
:delete2  dec Htab             ; cursor back one position
          jsr Tabs
          dec :Count
          ldx #30              ; some sound
          ldy #2
          jsr IDoTone
          jmp :getchar

:return   ldx :Count           ; only erase cursor if it's there
          cpx :Limit
          beq :return2
          lda #" "
          jsr Cout
:return2  ldy #0
          lda :Count           ; store character count of string length
          sta (VarPtr),y
          ldx #44              ; some sound
          ldy #4
          jsr IDoTone
          rts

:flash    bit SKey             ; clear strobe
:flash2   lda #"_"             ; print underline and move
          jsr :bprint          ;  cursor back
          jsr :delay           ; wait a bit
          bcs :gotkey
          lda #" "             ; print space and move
          jsr :bprint          ;  cursor back
          jsr :delay           ; wait a bit
          bcs :gotkey
          jmp :flash2          ; loop
:gotkey   rts 

:bprint   ldx :Count
          cpx :Limit           ; number of characters reached limit yet?
          beq :bout            ; yep, don't print a cursor
          jsr Cout             ; print character
          dec Htab             ; cursor back one position
          jsr Tabs
:bout     rts

:delay    ldx #0
:d1       dex
          ldy #55
          lda Key              ; if key
          bmi :key             ; get out
:d1a      dey
          bne :d1a
          cpx #0
          beq :d2
          bne :d1
:key      sec
          rts
:d2       clc
          rts

:Count    ds 1                 ; holds character count
:Limit    ds 1                 ; holds input limit

========================== CODE END ===============================

Let's start from the beginning.  The program will assemble to address $6000
which is simply a convienent location in memory that I chose.  The
listing will show as the compile is in progress, case sensitivity is off
(mix and match upper/lower case), macros will expand (we don't have any),
we'll use 6502 opcodes only, and the object code will assemble to a file
called 'Ampersand' on disk.

Zero Page usage:  The 'Pitch' variable holds the pitch for our Tone
routine, the 'ptr' variable is a general usage pointer, and the 'Htab'
and 'Vtab' are used in both the print string routine and the input routine.

The 'VarPtr' will point to the string variable after a 'PtrGet' call. 
'Cout' is the standard character out routine, 'DoTabs' will set the
cursor position depending on the a-register and the x-register, 'Tabs' will
set the cursor position depending on the 'Vtab' and 'Htab' values.  The
softswitches are self-explanatory.

The monitor routines have been described in detail, as have the 'SetAmper',
'AParse', and 'APrint' routines.  The next new routine is 'DoTone'.

'DoTone' first grabs the pitch value from the command line and stores it.
Then the duration is grabbed and transferred to the y-register to be
used as a duration counter.  Next the tone sound is generated by
accessing the speaker softswitch at a rate determined by the 'Pitch'
constant, thus generating the given tone.  After the sound is done, control
is returned to Applesoft.


RESTRICTED INPUT INSTRUCTION?   The last routine is the 'LineInput'
"""""""""""""""""""""""""""""   routine.  Have you every wanted an input
routine which restricts the user from entering to many characters?  In
Applesoft the INPUT instruction puts no restrictions on the users input
(except for the 224 character limit) and this can cause major problems. 
I thought it would be nice to have an input routine which restricts the
user to a given number of characters.  So here it is, the 'LineInput'
routine.

If you look you will see that four values are passed to the routine.  The
first two are the 'vtab' and 'htab' values of where to place the prompt
on the screen.  The third value is the maximum number of characters allowed
to be entered, and the fourth and final value is the string of where to
place the entered string.

The new routine here is the 'JSR StrIni' routine.  If you look closely
you will see that we get the address of the passed string, create a new
string variable with the given length (the input limit), copy the new
variable descriptor information to the new variable and lastly setup
'ptr' to point to the new string, so all entered characters are stored
directly into the new string.


APPLESOFT INTERFACING   If you examine the Applesoft program below you'll
"""""""""""""""""""""   see how each of the three functions could be used.

 1  REM  ***********************
 2  REM  *                     *
 3  REM  * Amperand Tester     *
 4  REM  * ---------------     *
 5  REM  *                     *
 6  REM  * By Russell Nielson  *
 7  REM  * On November 25, 1995*
 8  REM  *                     *
 9  REM  ***********************
 10 D$ =  CHR$ (4)
 20  PRINT  CHR$ (21): TEXT : HOME 
 21 :
 22 PSTRING = 0: REM  Function 0
 24 SOUND = 1: REM    Function 1
 26 LINE = 2: REM     Function 2
 29 :
 30  INVERSE : PRINT  SPC( 40 * 3): VTAB 2: HTAB 6: PRINT
     "A M P E R S A N D   T E S T E R";: NORMAL 
 40  POKE 34,4
 45  PRINT D$"-ampersand"
 50  VTAB 6: HTAB 5: PRINT "Please choose an option:"
 60  VTAB 8: PRINT "1.  Ampersand print string"
 70  PRINT "2.  Ampersand tone routine"
 80  PRINT "3.  Ampersand line input"
 90  PRINT : PRINT "4.  Quit"
 100  VTAB 20: HTAB 5: PRINT "Please choose by number:";: GET Z$
 110 Z =  VAL (Z$): IF Z = 0 OR Z > 4 THEN  PRINT  CHR$ (7): GOTO 100
 120  HOME 
 130  ON Z GOSUB 200,300,400,500
 135  POKE 49168,0
 140  POKE 34,4: POKE 35,24: HOME : GOTO 50
 199  REM  Ampersand Print
 200  VTAB 5: HTAB 13: PRINT "Print routine"
 201  GOSUB 900
 202 A$ = "Testing"
 210  FOR B = 1 TO 35
 220 V =  INT ( RND (1) * 16) + 6
 230 H =  INT ( RND (1) * (40 -  LEN (A$)))
 240  & PSTRING,V,H,A$
 250  IF  PEEK (49152) < 128 THEN  NEXT : HOME : GOTO 210
 298  RETURN 
 299  REM  Ampersand Tone
 300  VTAB 5: HTAB 14: PRINT "Tone routine"
 310  GOSUB 910
 320  FOR A = 1 TO 2
 330  FOR X = 10 TO 240 STEP 10: & SOUND,X,10: NEXT 
 340  FOR X = 230 TO 20 STEP  - 10: & SOUND,X,10: NEXT 
 350  NEXT 
 360  FOR A = 1 TO 75
 370  & SOUND, INT ( RND (1) * 256), INT ( RND (1) * 120) + 1
 380  NEXT 
 398  RETURN 
 399  REM  Ampersand Line Input
 400  VTAB 5: HTAB 11: PRINT "Line Input routine"
 410  GOSUB 910
 420  VTAB 10: HTAB 1: PRINT "Enter your name:                       |";
 430  & LINE,9,17,22,N$: POKE 49168,0
 440  VTAB 16: HTAB 5: PRINT "Thank you, "N$"!"
 450  VTAB 23: HTAB 13: PRINT "Press a key...";: GET Z$
 498  RETURN 
 499  REM  Quit
 500  POP : TEXT : HOME : END 
 900  VTAB 24: HTAB 10: PRINT "Press a key to stop";: POKE 35,23
 910  POKE 34,5: RETURN 


CONCLUSION   Now you have the knowledge to create powerful interfaces
""""""""""   between Applesoft and machine language.  Using the Ampersand
command definetly has its advantages as you can plainly see, and it should
be used as much as possible.


SUPPLEMENT   There is a file in the A2Pro Software Libraries that contains
""""""""""   this source code, the Applesoft program listed above, and the
object code that is generated by the source code.  That file number is 4882.



                               [*][*][*]


    We want your  articles!  If you want  to write an article for
    GEnieLamp A2Pro, then  contact  the editor,  A2PRO.GELAMP for
    more information.  We pay for articles with usage credits.


                               [*][*][*]



[EOA]
[HEY]//////////////////////////////
              HEY MISTER POSTMAN /
/////////////////////////////////
Is That A Letter For Me?
""""""""""""""""""""""""
By Tim Buchheim
 [A2PRO.GELAMP]


    o   BULLETIN BOARD HOT SPOTS

         o   WHAT'S NEW

              o   PROGRAMMERS' TIPS

                   o   MESSAGE SPOTLIGHT                             




                     >>>  BULLETIN BOARD HOT SPOTS  <<<
                     """"""""""""""""""""""""""""""""""
                        ~ Where All the Action Is! ~


 [*]  CAT 1,  TOP 25, MSG {8}......Important GEnie Announcements          
 [*]  CAT 2,  TOP 13, MSG {39}.....Handling Interrupts
 [*]  CAT 7,  TOP 6,  MSG {76}.....Programming with ProDOS (8-bit)        
 [*]  CAT 11, TOP 27, MSG {95}.....File Type Assignments              
 [*]  CAT 13, TOP 2,  MSG {76}.....Where to find information              
 [*]  CAT 16, TOP 5,  MSG {2}......KansasFest '96                         



                           >>>  WHAT'S NEW  <<<
                           """"""""""""""""""""
                            ~ Announcements ~


GENIE FOR SALE  A Letter from GEnie Acting President, Horace Martin
""""""""""""""
Dear GEnie Subscriber,

GE Information Services, the owner of GEnie Online Services, announced
yesterday that the company is working with the investment firm of Allen &
Company to identify potential buyers for GEnie.

The decision to seek a buyer for GEnie was a difficult one for GE Information
Services.  We feel tremendous loyalty to our customers, and we considered
very carefully the options available to us.  Finally, our business decision
was based on a desire to focus on GE Information Services' main mission -- to
provide business productivity solutions to businesses around the world.  We
lead this market, and we derive more than 95% of our revenues from this
market.  In 1995, GE Information Services has invested in GEnie with a new
graphical user interface, new multi-player game offerings, faster access
speeds, and simplified pricing.  We believe that GEnie presents a good fit
within a company whose main focus is in the consumer market.

GEnie subscribers are the best in the world, and we are keeping you front and
center as we seek a new owner for GEnie.  We assure you that you will receive
top quality service and support throughout this process.  We will make every
effort to make this transition transparent to you.  In the long run, we hope
that this transaction will make GEnie a better and even more exciting service
for you, our customer.

Please check GEnie's logon announcements periodically. Updates will be
provided whenever new information can be released.  (Type "GENIE" at any menu
prompt and select Item #2 from the menu which is presented to access the
announcements if you're already online, or take a moment to review them each
time you logon.)

Sincerely,

Horace Martin Acting President GEnie Online Services

                     (JUST.DAVE, CAT1, TOP25, MSG:8/M530)


MOVING   The snail address for A2Pro Technical Support (where you get
""""""   filetype assignments) has changed. The new address is:

    A2Pro Technical Support
    P.O. Box 8553
    Rolling Meadows, IL 60008-8553

As always, you can send e-mail to a2pro@genie.com to request a filetype also.

A2Pro Technical Support
                     (A2PRO, CAT11, TOP27, MSG:95/M530)



TECHNOTES ON WWW   Tony Morales, aka Hexman writes:
""""""""""""""""
If you've got some time sometime, check out my home page.  It's far from
done, but it's kind of interesting.  Its URL is
http://www.best.com/~hexman

Oh yeah, one last tidbit of "maybe" interest.  I have put all the Apple
II FTNs and TNs on the WWW, with a really nice hypertext method of
selecting notes to read.  The URLs are:

FTNs:  http://www.best.com/~hexman/a2ftn.html
TNs:  http://www.best.com/~hexman/a2tn.html

                   (R.NIELSON1, CAT13, TOP2, MSG:76/M530)



KANSASFEST '96   I'm here to make an official announcement that KansasFest
""""""""""""""   1996 will be July 17-21, 1996, at Avila College, Kansas City, Missouri.  That's about all the details I can give for now.

Cindy
(KFest Big Cheese)

                     (CINDY.A, CAT16, TOP5, MSG:2/M530)





                        >>>  PROGRAMMERS' TIPS  <<<
                        """""""""""""""""""""""""""
                    ~ Helpful Advice from the Experts ~



HANDLING INTERRUPTS   Hello. I'm working on some software, and I've finally
"""""""""""""""""""   hit the great wall I've been trying to avoid. I need
to install an interrupt, and I don't have a clue how one works, or how to
install-remove one. This is what I need to do:

1. Make it so when something comes in through slot 2, it will automatically
   jump to , let's say, $1234.
2. I've been trying hard ro understand, and I still can't understand.  But
   I think I know that there is a priority thing in the intterupts, like a
   1-4, and 1 is the first one checked. Well, I need this priority 1.

Maybe there's a file here that describes the MLI and interrupts? I have all
the manuals that describe all theese things, but they don't help at all.
Also, can somebody define exactly what 'DA' does? I know it's Define
Address, but wouldn't that be the same as DOO EQU $4534? Also, DFB, and
DB if there is one could also use some definition. My Stupid assembly
book is gone. Well, if anybody could help me, then i could continue.

Richard Noordhof -- R.NOORDHOF
Delivered by CoPilot V2.55 and ProTERM 3.1

                    (R.NOORDHOF, CAT2, TOP13, MSG:39/M530)


>>>>>   There are several kinds of interrupts, and a lot of details on how
"""""   to use them.  I'd suggest reading the material about interrupts in the Apple IIGS Toolbox Reference, Volume 1.  Follow up with a scan of the appropriate tech notes.  If you need to dig deeper, the Hardware and  Firmware reference manuals would be next.

As far as I know, you can't generate an interrupt when something comes in through slot 2--not without rewriting the slot 2 firmware, at least. The best you could do is write an interrupt handler that would check to see if anything was available there, and if so, handle it.

On the other hand, I'm not the expert on low-level interrupts.  Someone else may come along who knows something about some interrupts that are generated for low-level I/O events, and they may fill you in on some trick I/m not aware of.  Unless that happens, though, start with the info above.

Mike Westerfield
                    (BYTEWORKS, CAT2, TOP11, MSG:40/M530)


>>>>>   Aha...   serial interrupts...  a subject I hold dear to my heart!
"""""   :)

Interrupts are a risky business, and a misplaced interrupt can bring the
whole system crashing down on you!  :)

That said, they can also be great allies to speedy processing and
avoiding data loss.  Tread with care here and interrupts will be great
friends. :)

First thing I should warn you...  if you plan on running any faster than
2400 baud on an unaccelerated GS, you can forget about the standard
serial interrupt.  It's too far down the chain to be responded to in a
reliable manner going any faster (i.e. in the number of cycles used
checking the interrupt chain, another interrupt may have already occurred).

The best method I've seen for handling this reliably (which also happens to
be quite dangerous - play with great care) is to change the interrupt table
so that the very FIRST vector in the list is to a routine which checks to
see if your serial device is theone that generated the interrupt, and if
not, chains to whatever was in that spot in the chain previously.  The
biggest reason this is dangerous is because in GS/OS you're usually not
alone, and who know's who else (init's, DA's, whatever)has already
patched out that vector.  The patch in itself isn't what's dangerous,
it's what happens when you quit.  If an init or DA installs a 'rupt handler
in this method after yours, then you disinstall yours, you have now
effectively not only disintalled yours, but the inits or DA's routine as
well.  The safest method I've seen for dealing with this is to NOT
deinstall your routine, but leave a stub in memory (real short, with it's
own handle and UserID) that does nothing but pass control on to the
previous owner of that interrupt vector.  A 4-byte handle if you will... 
 JML prev_vector

Oh, Lock it down, too...  the vector is a pointer, not a handle, so if your
stub moves, it'll break.

The best way to deal with serial interrupts is to have your interrupt
handler do ABSOLUTELY AS LITTLE AS POSSIBLE (actually, this holds true
for just about any kind of interrupt).  When you are inside an interrupt
routine, EVERY MICROSECOND COUNTS!  The faster you can get your job done
and get out, the better.  If you can pass anything off on your main program
by setting a flag to be checked later, then by all means do it. :)  If
all you are doing is checking for incoming data, set up a buffer inside
your program, and then all your routine needs to do is drop the incoming
character in the buffer, update the "last character" pointer, and back
out again.  Then your program can deal with the contents of that buffer
next time it goes through your event loop.

Most of the specifics can be found in the places Mike mentioned. :)

Dave
                     (JUST.DAVE, CAT2, TOP13, MSG:41/M530)


<<<<<   Well, I'm programming on a GS with a TWGS. Yeah, I want a routine
"""""   that would check if anything came in, then put it somewhere in
memory. How would I do this?

Richard Noordhof -- R.NOORDHOF
Delivered by CoPilot V2.55 and ProTERM 3.1

                     (R.NOORDHOF, CAT2, TOP13, MSG:42/M530)


>>>>>   > I need to install an interrupt, and I don't have
"""""   > a clue how one works, or how to install-remove one.

Another good source which explains interrupts rather well is "Advanced
Programming Techniques for the Apple IIgs Toolbox" by Morgan Davis and Dan
Gookin. It has a whole chapter devoted to this topic. You could probably
buy it cheaply from someone.

Michael
                    (ANIMASIA, CAT2, TOP13, MSG:43/M530)





                        >>>  MESSAGE SPOTLIGHT  <<<
                        """""""""""""""""""""""""""
                   ~ Important or Interesting Messages ~


COMMAND LINE?   Hi... Anyways, I have a couple of questions about some
"""""""""""""   ProDOS 8 things...

First, where in memory is the 'command line' passed to a program stored.
Various program launchers for the II (which, of course, I cannot remember
now...) pass along the name of a file to the app being opened, so that it can
deal with it in an appropriate manner (eg, open it, or whatever). I want to
access this from Applesoft so that I can pass along a filename to a filename
to a SYS file that I am starting.

Also, where is the ProDOS quit code stored in memory, and how can I access
it? I want to program it to re-start BASIC.SYSTEM after the program exits,
but I'm not sure where the code is. (Now that I think about it, I think I
have a util on one of my old Softdisks that does this, but I need to practice
using the MLI anyways.)

                    (C.HARKE, CAT7, TOP6, MSG:76/M530)


>>>>>   The 'command line' info is being passed in the message center. This
"""""   is a IIgs thing and you'll find it in one of the tech notes. You
have to call the toolbox to get at it.

The P8 quit code is 3 pages ($300 bytes) starting at $D100 in the other bank
of the language card area. Those pages get copied to $1000 when you use the
MLI QUIT and then the MLI does a JMP $1000.

Todd Whitesel
                     (A2PRO.TODDPW, CAT7, TOP6, MSG:77/M530)


<<<<<   OK, thanks. I thought that it might be thru the message center
"""""   (although I don't know what the message center is since I'm mainly
an 8-bit programmer).  Funny, though, since the program I am passing the
parameter to ('INFOLOAD', for those who are interested) is an 8 bit, 6502
assembly language program, and I'm sure I read somewhere that ProSel 8
could pass an initial file along, as well. Maybe these functions only work
if you have a GS.

                    (C.HARKE, CAT7, TOP6, MSG:78/M530)


>>>>>   I only glanced at your previous post, but I think you were asking
"""""   about the passing of program names under ProDOS 8.  Yes it can be
done and no, it doesn't use the message center.  If you have Gary Little's
book "Exploring Apple GS/OS and ProDOS 8" look on page 222 - 'The Structure
of a ProDOS 8 System Program'.

If you don't have the book here's a quick overview. A system program that
follows the auto-run protocol has the following header:

    3 bytes - $4C $xx $xx: A JMP instruction to the start of program code
    2 bytes - $EE $EE:     Two ID bytes indicate auto-run protocol
    1 byte  - $xx          Size of buffer that follows
    ? bytes - A pascal string (leading length byte) with the name of the
              auto-run file. The length of this string (including length
              byte) must not exceed the buffer size given above.

A default filename is usually placed in the buffer, "STARTUP" in the case
of BASIC.SYSTEM.  The launching program may place a different file name in
the buffer after checking for the ID bytes and making sure the buffer
length is long enough to hold the filename string.

By the way, isn't INFOLOAD part of a program that allows you to run INFOCOM
programs under ProDOS 8?  If I recall, there was a bug in the program and I
had to change one byte to get it to work correctly.

  \ ___\ ___\
   \   !\    \
       A        Bob,
       H        AF6C
                     (R.ECKWEILER, CAT7, TOP6, MSG:79/M530)


>>>>>   ProDOS 8 also has a filename passing mechanism, and the Message 
"""""   Center has nothing to do with it.  It only works on SYS files, and
only on those that have been configured for it.  In order to work, a SYS
file needs to be set up sothat there is a 64 byte (or whatever, but 64 is
standard) "buffer" at byte offset +06 into the file.  A launcher will first load the file, then copy the passed parameter into that buffer as a p-string before executing it.  The SYS file must be set up as follows:

  +$00: 4C 47 20     JMP $2047 (or wherever the buffer ends)
  +$03: EE EE        Parameter-capable signature bytes
  +$05: 41           Length of buffer (including the p-string length byte)
  +$06: buffer       pstring of parameter passed.  Should be zeroed at load
                     time in case no parameters are passed.
  +$47: actual code  (if the buffer isn't 64 bytes, this may not be +$47)

The Finder (6.0 and later) has been set up to deal with this when launching
P8 files (for example, I have an icon set up for PTD.* files that is mapped
to PT3.System, and I can double-click on a dial entry file in my PT3.DIAL
directory and have ProTERM launched and have it automatically dial that
service when it comes up).

 Dave
                     (JUST.DAVE, CAT7, TOP6, MSG:80/M530)


<<<<<   Thanks. I thought there must be a way to do that from pure ProDOS 8
"""""
Yes, INFOLOAD is the program that lets you load Infocom games from ProDOS.
It was acting up for me at first, breaking into the monitor whenever I loaded
an adventure. I had to go inside the INTERPRETER file and change the first 3
bytes from BRKs to NOPs ($EA? I can't remember). Now it works perfectly, I
have 6 or 7 games on one disk, and this program will be a menu for it.

Anyhow, thanks again for the help.

                    (C.HARKE, CAT7, TOP6, MSG:81/M530)


                               [*][*][*]


    While on GEnie,  do you spend  most of  your time downloading
    files?   If  so,  you  may  be  missing  out  some  excellent
    information in the Bulletin Board area.   The messages listed
    above  only  scratch  the  surface of  what's  available  and
    waiting for you in the bulletin board area.

    If you  are serious about your Apple II, the  GEnieLamp staff
    strongly urges  you to give  the bulletin board  area a  try.
    There are literally thousands  of messages posted from people
    like you from around the world.


                               [*][*][*]



[EOA]
[DEV]//////////////////////////////
              DEVELOPER'S CORNER /
/////////////////////////////////
News From The A2Pro Online Developers
"""""""""""""""""""""""""""""""""""""
By Tim Buchheim
 [A2PRO.GELAMP]


    o   ONLINE SUPPORT IN A2Pro

         o   GNO/ME

              o   DEVELOPER ANNOUNCEMENTS




                      >>> ONLINE SUPPORT IN A2Pro <<<
                      """""""""""""""""""""""""""""""

     CAT  TOP  COMPANY
     ===  ===  =======
     29   INDEPENDENT DEVELOPERS ONLINE
           2   DYA/DigiSoft Innovations Online
           8   Simplexity Software Online
          14   Quality Computers Q-LABS Online
          20   DreamWorld Software Online
          26   METAL/FV Software Online
          32   Kitchen Sink Software Online
          38   EdIt-16 (Bill Tudor)

     30        PROCYON, INC.
     31        SOFTDISK PUBLISHING
     33        GS+ MAGAZINE
     34        JEM SOFTWARE
     35        PRODEV, INC.
     36        THE BYTE WORKS

     Each month this column feature highlights and news from various
developers who provide support via A2Pro.


                          >>>  GNO/ME  <<<
                          """"""""""""""""


WHAT IS THIS THING?   Well, I may as well admit it,
"""""""""""""""""""
........I love the IIgs, but in the scheme of things am truly just a
beginner.   I am actually very interested in this program, from what I've
heard of it, but  I'm still very unclear about what it does.  If people in
the know could  describe it a little, I'm sure many of us would appreciate.

Thanks, Toby
                  (T.REITER2, CAT30, TOP2, MSG:206/M530)

>>>>> Toby,
"""""
> I love the IIgs, but in the scheme of things am truly just a
> beginner.   I am actually very interested in this program, from what I've
> heard of it, but  I'm still very unclear about what it does.  If people
> in the know could  describe it a little, I'm sure many of us would
> appreciate.

You asked for this, remember, so no complaints :). I just hope GEnie
doesn't choke on message length.   [Editor's note: It didn't. :)]

Sure. GNO/ME (precise pronouncement of this is not really known, though
it has been proposed to pronounce it _with_ the G, since GNO is a recursive
acronym for "GNO's Not ORCA" --- OTOH, that is probably a rumour, and all
the bad puns like "I don't GNO any more" or "the GNO/MEs have gotten to
my GS again" seem to suggest the G not be pronounced) is a multi-tasking,
multi-user environment for the GS. It has some mechanisms that are highly
analogous to Unix, and some things that are quite unlike Unix.

I could probably waffle on like that, but I'll just give some examples,
shall I?

GNO/ME is multitasking: What's that mean, exactly?

Means several processes (programs) can be run at once. Only one of these
programs may be graphical (use the GS desktop), and no P8 programs can be
run inside GNO/ME. For example, say I want to convert a bunch of files from
Unix to Apple text format, but I don't want to wait for it to happen, so
I could do:

udl -r texts/* &

If that syntax looks familiar, that is not by accident. GNO/ME's shell
(gsh) supports automatic wildcard expansion (my program does not need to
know how to handle); I can push programs into the background by using &.

I could now list my processes with a ps, and I would see that udl is
running, its state, and how long it has been running.

That GNO/ME does preemptive multitasking also means that you can kill rogue
processes with a Ctrl-C or, if that fails, a kill -9 (there is even a CDA
to do that if you can't access the console any more).

In practice, the number of processes you can _actually_ run at any one time
is limited by 64k of DP space, every program needs a bit of this. Some grab
as much as 24k of this space, others need only a meek 1k. So, even though
you might have another 4MB of RAM free, if your DP space runs out, you're
shafted. This is a limit imposed by how the 65SC816 was designed, not by
GNO/ME. The fabled 65SC832 was supposed to add a full 24-bit DP register
instead of a 16-bit one, but the 65SC832 is naught but a wet dream for us
right now, alas :).


GNO/ME is multi-user, you say? You mean several people can use my GS at
once?

Well, yes, kind of. You get a spiffy login: screen and can type "root"
and feel really in control. You can have a friend use his P6-150 to connect
to your GS's serial port (directly or through modem) and have his own
console and shell. Way rad! But not really useful ... the GS does not
have enough DP space to run a lot of processes, so two users on one machine
may already get tight if both of you actually want to do things, the GS
does not, presently, have an FST that supports access rights, so you GOT to
trust your friend since there is no way you can restrict his access to your
machine (other than giving him a very restricted login shell instead of
gsh, of course), and on the GS, you are in control all the time anyway,
so typing "root" on a machine that doesn't really have any paranoid
security alerts and automatic guns trained on you at login is a bit dull.
:)

That said, the multi-user feature probably has its uses. I am not really
a GNO/ME guru.


So, GNO/ME is kinda like Unix ... do I have to learn Unix?

No, but you have to learn to find your way around a Unix-like shell. It's
not really hard ... GNO/ME comes with a lot of the "popular" utilities,
so it might be perfect for getting the feel of a Unix shell without
actually having to _be_ at a Unix shell. I can ps to see my processes, have
ls show me my directory contents, I can cd /usr/local/bin (yes, GNO/ME
has support for fake root directories, /usr/local/bin is actually
:applications:gno:usr:local:bin on my machine, but I don't have to know
that), I can man to look up a command, there's less and df and du and
syslogd and dmake and many many many more.

So, who do you think should get GNO/ME?

Programmers. You program for the GS? Get GNO/ME. Don't wait. Order it
now. It _will_ be worth it. GNO/ME simply has many life-saving features ...
the only shell that will let you ^C a process (don't need to reboot just
because you went into an INF loop), the only shell that has a port of dmake
(excellent Unix make command, ported by Devin Reade. A must if you want
to automate your builds), the only shell that has more programming
utilities than one can shake a stick at.

Students and people who want to/have to learn Unix. As a first contact with
the daunting world of a Unix shell prompt, GNO/ME is perfect. The
security limitations it has also mean that you _cannot_ lock yourself out
of the system inadvertently, furthermore, you are alone on your machine, so
no sysadmin will come chasing you because you filled up the lpd queue or
core-dumped once too often. :)

Anyone who is into the Internet. GNO/ME is currently at version 2.04,
version 2.06 should be out RSN, and it will have BSD sockets support! If
that doesn't mean anything to you, don't worry. There will be a free TCP/IP
stack, and a commercial SLIP dialer add-on. In essence, this means that you
will be able to surf the net from your GS ... ftp, archie, telnet, email,
news and, dare I say it, the WWW are finally in your reach without having
to go through a shell account or use a PC/Mac to make the connection.

If you want to run shell utilities of any kind, GNO/ME is also an excellent
choice because I find it more productive to use than say ORCA/Shell
(which leads the race when it comes to robustness, though). Some/many
utilities are only available as shell utilities. Some popular examples:

- descii. Sure, you can use GSCII NDA, but GSCII NDA has a bug that will
  sometimes decode incorrectly. descii decodes correctly, every time. Plus,
  you can have it do its thang in the background.
- unarj/booz/unpp. Clanging my own bell here, but these utilies are
  currently the only way to unpack ARJ 2.41, ZOO 2.1 or PP archives on
  the GS.
- gzip, tar. That's right, you can access gzip and tar archives. ShrinkIt
  _this_, dude! You can't.
- udl. Am I really the guy who said "the sound of your horn is far sweeter
  if blown by somebody else"? Awww what the heck, I'm an ugly bastard
  anyway. To my knowledge the only utility that will batch-convert text
  files between Unix/Apple/MS-DOS formats, including any subdirectories
  encountered (the latter feature added by Devin Reade). Or, use cr2lf
  for more speed but less bells and whistles and the good conscience
  of using a 100% US product instead of an imported German one.
- mtools. Write to and read from MS-DOS disks with this set of shareware
  utilities. Sure, mtools comes with its own mini-shell, command.com,
  but I find GNO/ME _much_ easier to use.

Ok, Ok, you've got me cornered, I'll buy. What kind of hardware should I
have?

Well, a IIgs, obviously. 2MB of system memory minimum, though I'd recommend
4MB or more (Sequential has great deals on 4MB memory cards). A hard drive.
No kidding here, if you don't have a HD, don't even try to use GNO/ME. Some
kind of accelerator like a ZIP or TWGS helps, but is not essential. Heck,
it helps with using a GS at all, if you can bear using the Finder at
2.8MHz, you can use GNO/ME, and you'll get the feeling its blazing along as
well, probably (well, compared to a desktop program anyway :).


To learn more and get all the errors that I made in this post corrected,
drop bazyar@hypermall.com an email, he's the mastermind behind GNO/ME.

Soenke

--
God despises money: Look whom He gives it to

                  (S.BEHRENS1, CAT38, TOP2, MSG:207/M530)



MAN HELP   Hi All,
""""""""
I dlded a couple of utilities from A2Pro libs the other night.  The man
pages contain a bunch of formatting chars and don't display properly for
me.

A sample;

.TH AWK 1
.CT 1 files prog_other
.SH NAME
awk \- pattern-directed scanning and processing language
.SH SYNOPSIS
.B awk
[
.BI -F
.I fs
]
[
.BI -v
.I var=value
]

Is there some way I should be processing them?  Am I doing something
wrong?  What editor uses .B .SH .CT .BI etc. ?

Thanks for any help.

Mark Wade
                    (M.WADE7, CAT30, TOP3, MSG:192/M530)


>>>>>   Mark,
"""""
That is nroff/troff source.  Move the file into the /usr/man/man1 directory
and use the man command to view it.  GNO's -man macro package doesn't support
some of the commands (.DT, .BI, .IB, etc.), however, so you may seem some
error messages.

                    (S.REEVES2, CAT30, TOP3, MSG:193/M530)



MISSING FILES   I recently installed GNO/ME v2.0.4 and I have a problem.
"""""""""""""
Specifically, I cannot find two utilities: runover and dialup.
These are supposed to be present, according to /GNO.Disk1/Release.Notes.
I have examined all three installation disks, including the archives on the
disks.

Are they available? 
If so, where can I get them?

Thanks.

Kevin P. Reid

(P.S. GNO/ME is my first experience with a UNIX system. It's GREAT!!!!!!!!)

                    (G.W.HOFFMAN, CAT30, TOP3, MSG:199/M530)


>>>>>   Dialup is indeed available on GEnie.  Right here in A2Pro as a
"""""   matter of fact (and it's been there about a year and a half :)

 4082 DIALUP.V121.BXY          X D.MITTON     940424   30080     37  30
      Desc: DialUp V1.2.1 for GNO/ME V2.0.

I believe Runover is included as part of the MultiUser Package:

 3852 MULTIUSER.BXY            X B.TAO        940123  156672     27  30
      Desc: Multi-user package for GNO

If the manual says runover is for single-user mode, I think it's an error.
It's most definately a multi-user mode utility.  Init uses it when setting up
the alternate access points.

If you'll be installing the multi-user package, you'll also need the "Multi-
User Update" which I noticed is NOT in A2Pro.  If someone wants to upload it,
please do. :) I might if I get time, but no guarantees.

Dave
                    (JUST.DAVE, CAT30, TOP3, MSG:201/M530)



                       >>>  DEVELOPER ANNOUNCEMENTS  <<<
                       """""""""""""""""""""""""""""""""

JAWAID BAZYAR
"""""""""""""
>Newsgroups: comp.sys.apple2
>Subject: Jawaid Bazyar & Sequential
>Date: 26 Nov 1995 23:05:07 GMT
>Organization: SuperNet Inc. (303)-296-8202 Denver Colorado
>Lines: 30
>Message-ID: <49arr3$lug@news-2.csn.net>
>Reply-To: bazyar@hypermall.com
>NNTP-Posting-Host: 199.117.27.22
>Summary: I'm not a number, I'm a free man!
>X-Newsreader: TIN [version 1.2 PL2]

It's now time to tell everyone:

I, Jawaid Bazyar, am no longer associated with Sequential Systems, Inc. in
any fashion. I will no longer provide technical support for any of
Sequential's products, either via telephone, email, Sequential BBS, GEnie or
USENet. I will not develop any new products in the future for Sequential
Systems, nor will I enhance or fix existing Sequential products.

I _am_ still standing behind all products of Procyon Enterprises Inc. GNO/ME,
Switch-It!, Pick'n'Pile, and Splat! will continue to be sold and supported by
myself. In addition, I look forward to the release of GNO 2.0.6 and Derek
Taubert's TCP/IP package.

And if anyone needs inexpensive and professional Internet/WWW services,
that's exactly what I'm doing now, so please contact me! :-)

I would appreciate it if someone could post this note to GEnie, as I won't
have time to get on there for a while. I will come back soon to handle the
Procyon category in A2Pro.

I cannot at this time discuss the exact circumstances of this separation, as
it would potentially jeopardize legal proceedings, so please don't ask me
about it.

--
 Jawaid Bazyar              |   Affordable WWW & Internet Solutions
 Interlink Advertising Svcs |   for Small Business
 bazyar@hypermall.com       |   P.O Box 641               (303) 781-3273
 --The Future is Now!--     |   Englewood, CO 80151-0641  (303) 789-4197 fax

                    (JUST.DAVE, CAT30, TOP5, MSG:43/M530)


EGO SYSTEMS
"""""""""""
EGO Systems is Moving!
----------------------

Effective November 16th, 1995 EGO Systems will be moving to a new  location. 
After this date, you can  contact by one of the following means:

Voice phone:  423-843-1775 FAX:  423-843-0661 ORDERS ONLY:  800-662-3634

Snail Mail:
  EGO Systems
  7918 Cove Ridge Rd.
  Hixson, TN 37343

e-mail:
  Diz@genie.com
  GSPlusDiz@aol.com

In order to get everything moved on time (so we don't have to pay another
month's rent on our old office) EGO Systems will be closed on November 13th
through November 15th.  We will re-open on  November 16th at our new
location.  As before, our hours will be 9 am to 5 pm Eastern Time, Monday
through Friday.

Please pass this new contact information along to every Apple IIGS owner
that you know!


Diz EGO Systems
                     (DIZ, CAT33, TOP3, MSG:74/M530)




[EOA]
[LIB]//////////////////////////////
             LIBRARY BIT BONANZA /
/////////////////////////////////
HOT Files You Can Download
""""""""""""""""""""""""""
By Tim Buchheim
 [A2PRO.GELAMP]


    o   KARL BUNKER SOURCE CODE

         o   MORE SOURCE CODE

              o   MISCELLANEOUS




                 >>>  Karl Bunker Source Code  <<<
                 """""""""""""""""""""""""""""""""

File # 4894  FLOORTILES.BXY(GS)  (xxx)
Uploaded on 1/4/96 by A2.TIM
About 47K (d/l time approx. 4 minutes @ 2400 baud)

Karl Bunker's source for FloorTiles 2.0 is included in this archive.  The
source is copyrighted, but Karl has allowed online distribution. See the
included text file for details. Brought to you by Lost Classics. Requires
the Lisa 816 Assembler to use. Packed with GS-Shrinkit.


File # 4893  FAT104.BXY  (GS)
Uploaded on 1/4/95 by A2.TIM
About 79K (d/l time approx. 8 minutes @ 2400 baud)

Karl Bunker's source for File-A-Trix 1.0.4 is included in this archive.
The source is copyrighted, but Karl has allowed online distribution. See
the included text file for details. Brought to you by Lost Classics.
Requires the Lisa 816 Assembler to use. Packed with GS-Shrinkit.


File # 4892  FAT103.BXY  (GS)
Uploaded on 1/4/96 by A2.TIM
About 88K (d/l time approx. 9 minutes @ 2400 baud)

Karl Bunker's source for File-A-Trix 1.0.3 is included in this archive.
The source is copyrighted, but Karl has allowed online distribution. See
the included text file for details. Brought to you by Lost Classics.
Requires the Lisa 816 Assembler to use. Packed with GS-Shrinkit.


File # 4891  ANTWARS.BXY  (GS)
Uploaded on 1/3/96 by A2.TIM
About 78K (d/l time approx. 8 minutes @ 2400 baud)

Karl Bunker's source for AntWars is included in this archive.  The source
is copyrighted, but Karl has allowed online distribution. See the included
text file for details. Brought to you by Lost Classics. Requires the Lisa
816 Assembler to use. Packed with GS-Shrinkit.



                    >>>  More Source Code  <<<
                    """"""""""""""""""""""""""

File # 4886  JPEG.6.SRC.BXY  (ALL)
Uploaded on 12/10/95 by A2.TONY
About 981K (d/l time approx. 90 minutes @ 2400 baud)

This is the official source code for the IJG JPEG utilities v6. Please note
that this source code will NOT compile as-is on the IIgs. I am providing it
unaltered, as is the custom when distributing other people's source code.
This version has already been compiled for the IIgs, see file #25931 in the
A2 Library for the actual working programs. That said, the source isn't too
hard to port to the IIgs because the IJG has provided lots of
documentation, sample makefiles, a configuration program, etc. If you are
fluent in C and have a working knowledge of your shell (ORCA, GNO, etc.)
then you should be able to get the programs to compile and run. This is a
HUGE archive so a hard drive is obviously a requirement. Packed with
ShrinkIt GS 1.1.


File # 4884  AMPERSAND.BXY  (ALL)
Uploaded on 11/28/95 by R.NIELSON1
About 6K (d/l time approx. 1 minute @ 2400 baud)

Here are three files which show how the Ampersand (&) command works
between Applesoft and machine language.  There is an Applesoft program,
Merlin source file, and the object code to the routines in this archive.
If you've ever wanted to use this method for parameter passing, then you
will most definitely want this file! :)
Archived with ShrinkIt v.3.4.



                         >>>  Miscellaneous  <<<
                         """""""""""""""""""""""

File # 4877  OCC113.BXY  (GS)
Uploaded on 11/14/95 by S.BEHRENS1
About 81K (d/l time approx. 8 minutes @ 2400 baud)

occ is a command-line front end for ORCA/C that gives
you more Unix-like syntax. Useful when used with
Devin Reade's dmake port.
occ requires an Apple IIgs, GNO/ME or ORCA/Shell and
ORCA/C 2.0.3 or later.




[EOA]
[LOG]///////////////////////////////
                          LOG OFF /
//////////////////////////////////
GEnieLamp Information
"""""""""""""""""""""

   o   COMMENTS: Contacting GEnieLamp

        o   GEnieLamp STAFF: Who Are We?



GEnieLamp Information   GEnieLamp is published on the 1st of every month
"""""""""""""""""""""   on GEnie page 515.  You can also find GEnieLamp on
the main menus in the following computing RoundTables.


RoundTable      Keyword  GEnie Page     RoundTable      Keyword  GEnie Page
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
DigiPub         DIGIPUB      1395        Atari ST        ST          475
Macintosh       MAC          605         IBM PC          IBMPC       615
Apple II        A2           645         Apple II Dev.   A2PRO       530
Macintosh Dev.  MACPRO       480         Geoworks        GEOWORKS    1050
BBS             BBS          610         CE Software     CESOFTWARE  1005
Mini/Mainframe  MAINFRAME    1145        Programming     PROGRAMMING 1445
Data Comm.      DATACOMM     1450        IBM PC Prog     IBMPCPRO     617
PowerPC         PPC          1435        PowerPCProg     PPCPRO      1440



    GEnieLamp is also distributed on CrossNet and many public and
commercial BBS systems worldwide.

    o To reach GEnieLamp on Internet send mail to genielamp@genie.com

    o Back issues of GEnieLamp are available in the DigiPub RoundTable
      Library #2 on page 1395 (M1395;3).  Internet users should use
      the GEnie gopher (gopher.genie.com) which has most back issues
      (but might be missing a few of them).  After you connect to
      gopher.genie.com, choose the "Magazines and newsletters" item
      and then choose the menu item for the Apple II.

    o GEnieLamp pays for articles submitted and published with online
      GEnie credit time.  Upload submissions in ASCII format to library
      #31 in the DigiPub RoundTable on page 1395 (M1395;3) or Email it to
      GENIELAMP.  On Internet send it to: genielamp@genie.com

    o We welcome and respond to all E-Mail.  To leave comments,
      suggestions or just to say hi, you can contact us in the DigiPub
      RoundTable (M1395) or send GE Mail to John Peters at [GENIELAMP] on
      page 200.

    o If you would like to meet the GEnieLamp staff "live" we meet every
      Wednesday night in the Digi*Pub Real-Time Conference at 9:00 EDT
      (M1395;2).

    o The Digital Publishing RoundTable is for people who are interested
      in pursuing publication of their work electronically on GEnie or via
      disk-based media.  For those looking for online publications, the
      DigiPub Software Libraries offer online magazines, newsletters,
      short-stories, poetry and other various text oriented articles for
      downloading to your computer.  Also available are writers' tools and
      'Hyper-utilties' for text presentation on most computer systems.  In
      the DigiPub Bulletin Board you can converse with people in the
      digital publishing industry, meet editors from some of the top
      electronic publications and get hints and tips on how to go about
      publishing your own digital book.  The DigiPub RoundTable is the
      official online service for the Digital Publishing Association.  To
      get there type DIGIPUB or M1395 at any GEnie prompt.


                         >>> GEnieLamp STAFF <<<
                         """""""""""""""""""""""

 GEnieLamp  o John Peters         [GENIELAMP]    Publisher
 """""""""  o Mike White          [MWHITE]       Managing Editor

  APPLE II  o Doug Cuff           [EDITOR.A2]    EDITOR
  """"""""  o Ray Pasold          [R.PASOLD]     A2 Staff Writer
            o Charlie Hartley     [A2.CHARLIE]   A2 Staff Writer

     A2Pro  o Tim Buchheim        [A2PRO.GELAMP] EDITOR
     """""

     ATARI  o Sheldon H. Winick   [GELAMP.ST]    ATARI EDITOR
     """""  o Bruce Smith         [B.SMITH123]   EDITOR/TX2
            o Mel Motogawa        [M.MOTOGAWA]   Atari Staff Writer
            o Richard Brown       [R.BROWN30]    Atari Staff Writer
            o Al Fasoldt          [A.FASOLDT]    Atari Staff Writer
            o Timothy V. Steed    [T.STEED1]     Atari Staff Writer
            o Lloyd E. Pulley     [LEPULLEY]     Atari Staff Writer

       IBM  o Sharon La Gue       [SHARON.LAMP]  IBM EDITOR
       """  o Tika Carr           [LAMP.MM]      MULTIMEDIA EDITOR
            o Susan M. English    [S.ENGLISH1]   Multimedia Graphics Artist
            o Wayne & Chris Ketner[C.KETNER]     IBM Staff Writers

 MACINTOSH  o Richard Vega        [GELAMP.MAC]   MACINTOSH EDITOR
 """""""""  o Tom Trinko          [T.TRINKO]     Mac Staff Writer
            o Bret Fledderjohn    [FLEDDERJOHN]  Mac Staff Writer
            o Ricky J. Vega       [GELAMP.MAC]   Mac Staff Writer

  POWER PC  o Ben Soulon          [BEN.GELAMP]   POWER PC EDITOR
  """"""""  o Eric Shepherd       [SHEPPY]       Power PC Staff Writer

   WINDOWS  o Bruce Maples        [GELAMP.WIN]   EDITOR
   """""""  o Tika Carr           [LAMP.MM]      Windows Staff Writer

      ETC.  o Jim Lubin           [J.LUBIN]      Add Aladdin Scripts
      """"  o Scott Garrigus      [S.GARRIGUS]   Search-ME!
            o Mike White          [MWHITE]       (oo) / DigiPub SysOp
            o John Peters         [GENIELAMP]    DigiPub SysOp
            o Phil Shapiro        [P.SHAPIRO1]   Contributing Columnist
            o Sanford E. Wolf     [S.WOLF4]      Contributing Columnist
            o Douglas Parks       [DELUXE]       Contributing Columnist


\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\////////////////////////////////////
 Opinions expressed herein are those  of the individual authors, and do
 not  necessarily  represent  opinions of  GEnie Information  Services,
 GEnieLamp Online Magazines, or T/TalkNet  Online Publishing.  Bulletin
 board messages are reprinted verbatim, and are included in this publi-
 cation with permission  from GEnie Information Services and the source
 RoundTable.   GEnie Information Services,  GEnieLamp Online Magazines,
 and T/TalkNet Publishing  do not guarantee the accuracy or suitability
 of any information included herein.   We reserve the right to edit all
 letters and copy.

 Material  published in  this edition may be  reprinted under the  fol-
 lowing terms only. Reprint permission granted, unless otherwise noted,
 to  registered computer  user groups and  not for profit publications.
 All articles  must remain unedited  and include  the issue  number and
 author  at the top of each article reprinted.  Please include the fol-
 lowing at the end of all reprints:

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\///////////////////////////////////
 The  preceeding article  is reprinted  courtesy of  GEnieLamp  Online
 Magazine.  (c) Copyright 1996 T/TalkNET  Publishing and  GEnie Infor-
 mation Services.  Join GEnie  now and receive $50.00 worth  of online
 credit. To join GEnie, set your modem to 9600 baud (or less) and half
 duplex (local echo). Have the modem dial 1-800-638-8369 in the United
 States or  1-800-387-8330  in Canada.  When you see the  U#=  prompt,
 type:  JOINGENIE  and hit the  RETURN  key.   When you get the prompt
 asking for the signup code, type  DSD524  and hit RETURN.  GEnie will
 then ask you for your signup information.   For more information call
 (voice) 1-800-638-9636.
////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
[EOF]
