•  Back 
  •  Driver types 
  •  Index 
  •  Tree View 
  •  Cross references 
  •  Help page 
  •  Show info about hypertext 
  •  View a new file 
Topic       : TOS - The Operating System
Author      : 
Version     : tos.hyp (December 19, 2008)
Subject     : Programmieren/Atari
Nodes       : 3010
Index Size  : 93790
HCP-Version : 5
Compiled on : Atari
@charset    : atarist
@lang       : 
@default    : Title
@help       : 
@options    : +g -i -s +x +zz -t4
@width      : 70
View Ref-File13.6.4.2  GDPS, virtual memory management                          TOS

#define VOR              1
#define ZURUECK         -1
#define MITTE            0

/********************************************************************/
/*                        Scanner structures                        */
/********************************************************************/
typedef struct                   /* Passing structure for scanner   */
{
   void  *next;                  /* Pointer to the next driver      */
   char  ident[4];               /* Magic GDPS as driver identifier */
   int   version;                /* Version number, currently < 200 */
   int   type;                   /* Driver type, 0 for scanner      */
   char  *info;                  /* Pointer to driver info and to   */
   char  *copyright;             /* the Copyright message           */
   int   devdescr;               /* Device description flags        */
   int   colours;                /* Number of colours, 0=B/W        */
   int   deep;                   /* Possible bit-depths             */
   int   free;                   /* Flag whether scanner is free    */
   int   scommand;               /* Command to scanner              */
   void  *command;               /* Pointer to the command structure*/
} SCANHEADER;

typedef struct                 /* Command structure for GDPI scanners*/
{
   int   result;                 /* Result that reports drivers     */
   int   modes;                  /* Permitted scan modes            */
   int   depth;                  /* Image depth in bits/pixel       */
   void  *vmemory:               /* Where image should be placed    */
   long  vmaxlen;                /* Available memory                */
   int   bytewidth;              /* Width of a line in bytes        */
   int   height;                 /* Height of the image in lines    */
   int   mmwidth;                /* Width (!U)and(!u)                       */
   int   mmheight;               /* Height in 1/10 millimeters      */
   int   xdpi;                   /* Resolution in X (!U)and(!u)             */
   int   ydpi;                   /* Y direction                     */
   int   modulo;                 /* 2=>image becomes word-aligned   */
   int   start_x;                /* Top left corner X in 1/10 mm    */
   int   start_y;                /* Top left corner Y in 1/10 mm    */
   long  ser_no;                 /* Serial number                   */

/****
The following part is defined only for calls of the scanners with
the commands of the 0x2XX series
******/
   int     add_bits;              /* Specifies how many additional   */
                                  /* bits are required. For instance */
                                  /* CRANACH Studio has 2 masks for  */
                                  /* each image. If one scans a bit- */
                                  /* map, the program requires not   */
                                  /* just 1 bit per pixel, but three */
                                  /* bits. In a similar way, with a  */
                                  /* greyscale picture one has to    */
                                  /* calculate 8 + 2 = 10 pixels. If */
                                  /* this value is not allowed for,  */
                                  /* then it may happen that after   */
                                  /* scanning CRANACH Studio can not */
                                  /* open its window, because though */
                                  /* memory is available for the     */
                                  /* scanned image, there is none    */
                                  /* for the required masks.         */
                                  /* One needs, for exampple, two    */
                                  /* additional bits for the mask.   */
   void *Dchange_pointer;         /* Pointer to this function        */
   void *Dupdate;                 /* Pointer to that function        */
   int  read;                     /* Virtual read buffer index       */
   int  write;                    /* Virtual write buffer index      */
   int  virt_flag;                /* Flag whether working with       */
                                  /* virtual memory management(1=yes)*/
} SCANCOM;
SCANCOM scancom;

void *Dchange_pointer(
                        void *pointer,
                         int v_handle,
                         int richtung,
                         long *max_vor,
                         long *max_zurueck
                       );

void Dupdate(int v_handle);

All tms products work with virtual memory management. This means that 
it does not have to access memory areas that are present in RAM. The 
virtual memory management implemented in tms products was optimized 
for the requirements of images.

General procedure: The driver passes in scancom.write a virtual 
handle. With this handle one can then access the virtual data. The 
data are obtained automatically from the hard drive when required, and 
stored.

One possible application would be:

UCHAR *real;
long max_forward, max_back;

scancom->vmemory points to the free virtual memory. This is to be 
treated just like normal memory. so, say, free memory from addr 16MB 
to addr 50MB with scancom->vmemory = addr 30MB. As this address does 
not really exist, the pointer must be mapped to the real memory and 
the data loaded from the hard drive. This is achieved with the 
function Dchange_pointer.

 real = (UCHAR*)Dchange_pointer(
                                   scancom->vmemory,
                                   scancom->write,
                                   FORWARD,
                                   &max_forward,
                                   &max_back
                                 );

So real now points to an area of RAM.

scancom->write is the memory handle passed by the program.

FORWARD tells the memory management that we want to move as far as 
possible to the start of the memory. This optimizes disk accesses.

max_forward returns how many bytes from real one may move forward in 
the memory.

max_back returns how many bytes from real one may move backwards in 
the memory.

If these limits are reached then Dchange_pointer must be called anew. 
The minimum lengths for max_forward and max_back are:

               FORWARD  BACK  MID 
 max_forward:    32k     0k   16k 
 max_back:       0k     32k   16k 

Der Ram Speicher ist in 6 Blöcke unterteilt, von denen jeder einen he 
RAM memory is subdivided into 6 blocks, which each can represent a 
separate or also an overlapping portion of the virtual memory. To 
guarantee with overlapping blocks that after a memory alteration all 
blocks will reproduce the current memory contents, call the function 
Dupdate(scancom->write). This updates the other blocks. However, one 
only needs to use Dupdate before accessing a different block. For a 
scanner driver that only uses the block scancom->write, it suffices 
therefore to call Dupdate(scancom->write) at the end of the scanning 
process.

Sample code for the deletion of 10 MB as of address 32 MB:

v_pointer=32MB
size=10MB

while(size>0)
{
        real=Dchange_pointer(
                              v_pointer,
                              scancom->write,
                              FORWARD,
                              &max_forward,
                              &max_back);
        if(max_forward<=size)
        {
                memset(real,0,max_forward);
                size-=max_forward;
                v_pointer+=max_forward;
        }
        else
        {
                memset(real,0,size);
                size=0;
                v_pointer+=size;
        }
}
Dupdate(scancom->write);  !!!!!!!!!!!!!



****************************************************************************
Old programs call the scanner with the command 0x100 (and not 0x200).
These programs (e.g. tms CRANACH) also do not yet use virtual memory
management. Therefore the SCANCOM structure is not defined from the
position marked onwards. The functions Dchange_pointer or Dupdate
should then be replaced in the driver by dummy functions.

/********************************************************************/

Possible application as ACC:

/********************************************************************/
/*    main()                                                        */
/*                                                                  */
/*    Heart of the program                                          */
/********************************************************************/

int main( void )
{
   int work_in[12],work_out[58],dummy;
   int buffer[20];

   appl_id = appl_init();

   /* Open an own workstation */
   handle=graf_handle(&dummy,&dummy,&dummy,&dummy);
   for ( dummy=0; dummy<10; work_in[dummy++]=1 );
   work_in[10]=2;
   v_opnvwk(work_in,&handle,work_out);

   if(!rsrc_load("SCANNER.RSC"))
   {
      form_alert(0,NO_RSC_FILE);
      goto FOREVER;
   }

   if( appl_id != -1 )
   {
      if( !_app )
      {
         scanner_moeglichkeiten();
         menu_id = menu_register( appl_id, "  SCANNER" );
         event_loop();   /* Here one waits for the call of the    */
                         /* driver by the program; the dialog is  */
                         /* handled, the image is scanned and     */
                         /* the values placed in vmemory          */
      }

   }
FOREVER: /* Initialization has not worked */
   while(1)
        evnt_mesag((int*)buffer);
}

/********************************************************************/
/* Initialize scanner                  */
/********************************************************************/

void scanner_moeglichkeiten()
{
        long
                **zeiger;
        long
                stack;

/********** Divert pointer to GDPS *******************************/

        stack=Super(0);

        zeiger = (long **)0x41c;

        if(*(*zeiger+1)== 0x47445053l)
                header.next = *zeiger;
        else
                header.next = NULL;

        *zeiger = (void *)&header;

        Super((void *)stack);

/********************************************************************/

        sprintf(header.ident,"GDPS");
        header.version          =100;
        header.type             =0;          /* Scanner */
        header.info             =info;
        header.copyright        =copyright;
        header.devdescr         =1 | 2 | 4;  /* Device description flags */
        header.colours          =1;          /* Number of colours, 0=B/W */
        header.deep             =1 | 16;     /* Possible bit-depths      */
        header.free             =0;
        header.scommand         =0;          /* Command to scanner       */
        header.command          =&command;

}