Pl GEMDOS.DOC

From Atari Wiki
Revision as of 00:13, 17 December 2023 by Olivier.jan (talk | contribs) (Replacing content of with translated version)
Jump to navigation Jump to search

                            CHAPTER 5:  
                            *** THE GEMDOS ***
                           --------------------


                     *** GEMDOS FUNCTIONS ***
                     -------------------------------

- The GEMDOS functions can be directly called in assembly.

 Just:
  .Pass the parameters needed by the function in the system stack
   (WORDS or L-W).
  .Pass the function code in the system stack. (WORD)
  .Call the GEMDOS with a TRAP #1 


- The same is true for BIOS and XBIOS functions.

 (Only the TRAP number changes: TRAP #13 for BIOS and TRAP #14 for
 XBIOS)

- ATTENTION! The GEMDOS, BIOS and XBIOS functions often return

 information: in certain data registers and some
 address registers.
 Care must be taken to preserve the concerned registers before 
 calling one of these functions so as not to lose their content.
 (e.g. using MOVEM)

- Before using the GEMDOS, BIOS and XBIOS functions, it is necessary

 to reserve a certain amount of memory because when the operating
 system launches your program, we must allocate the quantity of memory
 that the program really needs.
 (To avoid overlapping of data in memory)
 The operating system (the GEM Desktop) will read the BASE PAGE which
 is at the start of your .PRG program (see the INTRODUCTION chapter)
 before executing it.
 This BASE PAGE is of size $100 (256) bytes and contains all
 the information needed by the operating system for the loading
 of the PRG, but it is up to us to indicate the size of memory
 that will need to be reserved.
 After loading the program, SP points to the BASE PAGE, so 
 the various data contained in the
 BASE PAGE can easily be read by incrementing SP for example.
 Organization of the BASE PAGE:
                    ------------
 Byte:$00=Start of the Base Page
 ----- $04=Pointer to the end of free memory
       $08=Pointer to the start of the prg
       $0C=Size of the TEXT area
       $10=Pointer to the DATA area
       $14=Size of the DATA area
       $18=Pointer to the BSS area
       $1C=Size of the BSS area
       $20=Pointer to the DTA buffer
       $24=Pointer to the base page of the calling PRG (parent)
       $80=The command line
 To indicate the size of memory to reserve, there is a GEMDOS function, the parameters to pass are:
 .the number of BYTES to reserve (L-W)
 .A L-W which is the pointer to the end of free memory
 .a WORD equal to 0
 
 The function code is $4A (function 'SETBLOCK')
 To find the number of bytes to reserve (the total size of the PRG)
 thanks to the Base Page, we add:
 .The size of the Base Page ($100 bytes)
 .The space occupied by the instructions (L-W at $C(SP) because SP points to
  the start of the base page)
 .The size of the DATA area (L-W at $14(SP) )
 .The size of the BSS area  (L-W at $1C(SP) )
 
 We put the result in a dn register and place it as a parameter
 (L-W) in the system stack (MOVE.L  dn,-(SP) ) followed by a L-W which is
 the pointer to the end of free memory and a WORD equal to 0: 
 (MOVE  #0,-(SP) ) 
 Then we stack the code of the function SETBLOCK: MOVE  #$4A,-(SP)
 and call the GEMDOS with TRAP #1.
 This initialization must be done at the beginning of any program.
 ----------------------------------------------------------------
 To avoid retyping everything each time, we will create a
 MACRO INSTRUCTION that will do it for us.
 A MACRO is delimited by the directives:
 
 MACRO (After the name of the Macro to mark the beginning of the MACRO)
 -----
 ENDM  (At the end of the MACRO to mark the end of it)
 ----
    Example: A MACRO called ADD which adds the low word
    ---- of registers d0 and d1 will be written:


       TEXT

add MACRO ;beginning of the macro

       ADD.W    d0,d1   ;the Macro itself
       ENDM             ;End of the Macro
   ; This MACRO can then be used:
       MOVE     #3,d0
       MOVE     #5,d1
       add              ;call of the MACRO 'add'
       MOVE     d1,res
       BSS

res DS.W 1 ;We will find the word 5+3=8 in 'res'

       END
 The MACRO can be used as many times as you want, but
 care must be taken not to put Labels in your MACRO because they
 would be rewritten multiple times and this would cause errors...
 The MACRO can then be saved in a file.
 To indicate to the LINKER that you are going to use a MACRO that is in
 an external file, you will have to use the DIRECTIVE:
 INCLUDE   "file.xxx"
 -------
 It must be used before the first MACRO from 'file.xxx' is
 used. 
 The entire file will be ASSEMBLED separately, but only the used MACROs
 will be included.
 
 But let's go back to our GEMDOS 'setblock' function:
 The Listing of the SETBLOCK Macro will be:
         TEXT

SETBLOCK MACRO ;beginning macro

         move.l    a7,a5     ;USP in a5
         lea       stack,a7  ;'stack' is the address pointing to an area
                             ;of memory reserved for certain 
                             ;functions. 
                             ;(the name of the label is arbitrary...)
                             ;(Of course, you must reserve this area with
                             ;DS.x space: 200 bytes are generally enough)
         move.l   4(a5),a5   ;free memory ending address in a5
         move.l   $c(a5),d0  ;TEXT area length in d0
         add.l    $14(a5),d0 ;adds the size of the DATA zone 
         add.l    $1C(a5),d0 ;adds the size of the BSS zone
         add.l    #$100,d0   ;adds size of Base P. to d0
         move.l   d0,-(sp)   ;STACKS the space to reserve (1st parameter)
         move.l   a5,-(sp)   ;STACKS a5                  (2nd parameter)
         move     #0,-(sp)   ;STACKS word=0              (3rd parameter)
         move     #$4a,-(sp) ;STACKS the CODE of SETBLOCK
         trap     #1         ;GEMDOS call ->execution of the function.
         add.l    #12,sp     ;When returning, SP is incremented to
                             ;regain its initial value.
         ENDM                ;end of the MACRO
         END                 ;end of assembly


We will save this macro in the file 'INIT_TOS.L'.


All the programs we write will therefore have to look like this:
---------------------------------------------------------------------

    TEXT
    INCLUDE   "INIT_TOS.L"   ;Linkage of the file


    SETBLOCK                 ;call of the MACRO SETBLOCK
    .                        ;the instructions 
    .                        ;that form the prg
    .
    DATA                     ;the data zone
    .                        ;with the initialized data
    .
    .
    BSS                      ;the bss zone
    .                        ;with the reservations
    .
    .
    DS.B      200            ;and space reserved for the needs 

stack DS.B 1 ;of the GEMDOS, BIOS, XBIOS functions we

                             ;will use. (Upstream of the
                             ;'stack' label). USP points on 'stack' and 
                             ;will be decremented when passing the 
                             ;parameters to the functions 
                             ;(MOVE.x source, -(SP) )
                             ;:Let's not forget that only the memory that
                             ;the program really needs is 
                             ;reserved after SETBLOCK.
    END


 The listing of the SETBLOCK macro instruction is found in the file
 INIT_TOS.L on this disk and is fully available to you.


NB:You will therefore always have to make sure to reserve memory in the
-- BSS zone upstream from the address pointed to by the label we
   named 'STACK'.
   There is no need to economize on space by reserving little memory,
   the size of the BSS segment does not affect the
   size of the PRG...
   

- I will now enumerate the various functions of the GEMDOS.

 Only the commonly used functions will be studied, for the
 others, you will have to refer to THE ST BIBLE, but I doubt you
 will need to use them in the near future...
 For each function, I will give you:
 .The CODE and the NAME of the function
     ----       ---
 .The PARAMETERS to pass
      ----------
 .The PURPOSE of the function
     ---
 .A MACRO INSTRUCTION that uses the studied function if it 
  can be frequently useful to us...
      All these macro instructions that we will create from the 
  GEMDOS, BIOS and XBIOS functions will be collected in the file
  MACROS.L and of course, you can use them whenever
  you desire.


                     *** THE GEMDOS FUNCTIONS ***
                     -------------------------------

$00 (TERM), no parameter --- TERM allows to end the program and return to the calling program (or parent program). That is to say that if we use the TERM function of gemdos, the prg stops and returns to the GEM DESKTOP (if the program has only been loaded from the DESKTOP) or to the instruction following the calling instruction, of the FATHER program. In this latter case, the PRG using the term function is named SON program and has been loaded by the so called 'FATHER' program.

TERM MACRO ;TERM macro named 'TERM'

         CLR.W     -(SP)     ;TERM code
         TRAP      #1        ;GEMDOS call
         ENDM                ;MACRO end


$01 (CCONIN), no parameter --- CCONIN waits for a character on the keyboard and displays it at the current cursor position. The function returns, the ASCII code of the pressed key in the low byte of the low word of d0 and the SCANCODE of the key in the low byte of the high word of d0. The SCANCODE allows to identify keys that do not have an ASCII code (such as function keys) and it also allows to distinguish between keys that have the same ASCII code (such as numbers on the numeric keypad and those on the main block)

The ASCII code and SCANCODE can be reached in this way for example:

    MOVE      #$01,-(SP)     ;CCONIN CODE
    TRAP      #1             ;-->gemdos
    ADDQ.L    #2,SP          ;we reinitialize SP
    CMPI.B    #'A',d0        ;compare the low byte of the low word of
                             ;d0 with the ASCII code of
                             ;'A' that is $41
    BEQ       yes
    SWAP.W    d0             ;SWAP the 2 words of d0
    CMPI.B    #0,d0          ;is the SCANCODE nill ???
    BNE       no
    etc...
 

NB:You have noticed that I wrote:CMPI #'A',d0. -- Writing 'A' or the ASCII code of A that is $41 is identical.

  You can therefore for example replace MOVE  #$42,d0 with MOVE  #'B',d0
  ,this makes the listing more readable if you use instructions
  that must move data representing ASCII codes...
  The assembler will make the correction. (just as MOVE source,an is
  accepted and replaced by MOVEA source,an)

CCONIN MACRO ;The equivalent macro

         MOVE      #$1,-(SP)
         TRAP      #1
         ADDQ.L    #2,SP
         ENDM


$02 (CCONOUT), WORD=ascii code --- CCONOUT displays the character represented by the ASCII code that is passed as a parameter on the stack at the current cursor position.

CCONOUT MACRO $\1 ;here, $\1 tells the assembler that we

                               ;will pass a parameter to the macro.
         move      \1,-(SP)    ;we stack the parameter \1
         move      #2,-(SP)    ;then the code of CCONOUT   
         trap      #1          ;gemdos
         addq.l    #4,SP       ;correction of the stack   
         ENDM                  ;end of the MACRO

As you can see, we have just created a MACRO instruction that accepts a PARAMETER. It is indicated to the assembler by the directive: MACRO $\1

The parameter can be for example:#'A' or d0 or #$48 etc...

Examples of using the macro CCONOUT (with a parameter):


    CCONOUT   #'a'

will display an 'a' on the screen

    MOVE      #'a',d0
    CCONOUT   d0

idem

    CCONOUT   #53

will display the character with ASCII code 53.


$03 (CAUXIN), no parameter --- CAUXIN allows the reception of a character via the RS232 interface. If there has been no error, the ASCII code of the character returns in the low byte of d0.

    MOVE      #$3,-(SP)
    TRAP      #1
    ADDQ.L    #2,SP

$04 (CAUXOUT), WORD=ascii code --- CAUXOUT causes the emission of the character whose ASCII code has been passed as a parameter in the stack to the RS232 interface.

    MOVE      #'A',-(SP)     ;sends an 'A'
    MOVE      #$4,-(SP)
    TRAP      #1
    ADDQ.L    #4,SP


$05 (CPRNOUT),WORD=ascii code --- CPRNOUT emits the character whose ASCII code has been stacked to the printer. If the character was well sent, we obtain the word -1 in d0. If the printer is unable to receive the character, we obtain a word equal to 0 in d0.

    MOVE      #'A',-(SP)     ;we print an 'A'
    MOVE      #$5,-(SP)      ;CPRNOUT code
    TRAP      #1
    ADDQ.L    #4,SP

$06 (CRAWIO),WORD=$FF or ascii code --- CRAWIO admits two types of parameters. If the parameter is a WORD equal to $FF, CRAWIO tests if a key of the keyboard IS pressed.(like INKEY in BASIC) If a key was pressed, its ASCII code and its scan code enter in d0, otherwise d0 remains unchanged. If the parameter is different from $FF, this value is interpreted as the ASCII code of a character to send to the screen.

INKEY MACRO ;CRAWIO with $FF as parameter

         MOVE      #$FF,-(SP)
         MOVE      #$6,-(SP)
         TRAP      #1
         ENDM
 Example of using the INKEY macro:
 -------

test INKEY ;macro call INKEY

         CMPI.B    #'A',d0   ;compare the ASCII code of d0 with 'A'
         BEQ       yes       ;key 'A' pressed? If yes, goes to 'yes'
         JMP       test      ;otherwise return to 'test'     

yes NOP

As long as the 'A' key is not pressed, we jump to 'test'.


$07 (CRAWCIN), no parameter --- CRAWCIN waits for a key to be pressed. The recognized character is not displayed, but the ASCII code and scan code of the pressed key is transmitted to d0 in return.

WAIT MACRO ;waiting macro for a key

         MOVE      #$7,-(SP) ;CRAWCIN code
         TRAP      #1
         ADDQ.L    #2,SP     ;keys codes in d0.
         ENDM
             

$08 (CNECIN), no parameter --- Identical function to CRAWCIN, except that here, pressing CONTROL-C ends the PRG (like with PTERM), CONTROL-S stops the display, CONTROL-Q resumes the display interrupted by control-s.

$09 (PRINT LINE), L-W= address of a string of characters terminated by a --- zero byte.

This function allows to display a string of characters on the screen. The string of characters to be displayed must be located in the DATA area and must be terminated by a NULL byte.

PRINTLINE MACRO $\1 ;MACRO with \1 parameter: The address of

                                  ;the string of characters to be displayed.
              PEA       \1        ;STACK the address \1.
              MOVE      #$9,-(SP) ;PRINTLINE code
              TRAP      #1
              ADDQ.L    #6,SP
              ENDM

Example of using the macro PRINTLINE:


         PRINTLINE      laurent
         PRINTLINE      exp2
         PRINTLINE      exp3
         DATA

laurent DC.B 'laurent PIECHOCKI 8,impasse Bellevue 57980',0 exp2 DC.B 53,54,56,80,45,25,0 exp3 DC.B 27,'E',7,'LAURENT',25,0


NB:  To obtain effects such as screen erasing, line jumps... there are special codes that must be transmitted to
---  functions such as PRINTLINE,CCONOUT... 
     The codes preceded by the ASCII value 27 (ESC).
     -----------------------------------------------
     27,'E'  :erase the screen
     27,'B'  :positions the cursor one line lower
     27,'A'  :positions the cursor one line higher
     27,'C'  :positions the cursor one line further to the right
     27,'D'  :positions the cursor one line further to the left
     27,'J'