
    include 'tclib2.i'  ; some usefull macro-definitions, see there

TCLIB_ID = 'TCLB'

TCLIB_SUBID_FLRQ = 'FLRQ'       ; filerequester
TCLIB_SUBID_CRYP = 'CRYP'       ; crypt-library
TCLIB_SUBID_OBJT = 'OBJT'       ; object-library
TCLIB_SUBID_FNCT = 'FNCT'       ; user-funtions
TCLIB_SUBID_MCRO = 'MCRO'       ; user-macros


* IMPORTANT: All routines may only change d0-d1/a0-a1, all other registers
* have to be preserved!


    STRUCTURE TCLib,0
    LONG tclib_header   ; moveq #-13,d0     or $70F34E75
                        ; rts
                        ; if user tries to start this file!
    LONG tclib_id       ; TCLIB_ID ('TCLB')
    LONG tclib_subid    ; one of the TCLIB_SUBID's declared above
    WORD tclib_version
    WORD tclib_revision
    LONG tclib_name     ; *text with short description of this lib
    LONG tclib_ver      ; *ver_text
    LONG tclib_author   ; *text with your name
    LONG tclib_flags    ; reserved, set to 0.l for now
    LONG lib_reserved1
    LONG lib_reserved2
*
    LONG tclib_init     ;INIT: routine is called on startup, return one of:
                        ;   0: if installed correctly
                        ;   1: can't use: remove - try to load next time
                        ;   -1: impossible to use: remove &  don't try
                        ;       to load this lib again
    LONG tclib_exit     ;END: routine is called before TurboCalc ends
                        ;   free all allocated mem & other resources
    LONG tclib_flush    ;FLUSH: routine is called when TurboCalc runs
                        ; runs short of memory.
                        ; lib is asked to free (temporarily) unused
                        ;  memory (not used up to now, simply set to 0.l)

    LONG tclib_method   ; Global routine for all purposes, called with
                        ; method (what shall be done?) and data.
                        ; Isn't currently used. (Simply set to 0)
    LABEL tclib_rout1   ; Here the type-specific routines start, they are
                        ; defined in the type-specific description below.
                        ;

    LABEL TCLib_SIZEOF



    STRUCTURE TCLib_filereq,TCLib_SIZEOF
    LONG libfr_filereq  ; open window & ask for filename
            ; error=filereq(filename, title_text, screen, pattern, flags)
            ;               a0        a1          a2      a3       a4
            ; para: a0: *filename (200 chars reserved, both for old and
            ;           for new filename, if returning d0=0)
            ;       a1: *title_text
            ;       a2: *screen (or 0.l for workbench)
            ;       a3: *pattern
            ;       d0: flags (bit0: save, bit1:drawer_only)
            ;           (drawer_only isn't needed up to now!)
            ; return: d0: 0=ok (filename is changed)
            ;             1=abort
            ;            -1=serious error (e.g. no mem)
            ;               (in this case a simple string-
            ;               filerequester will appear)
    LABEL libfr_SIZEOF



    STRUCTURE TCLib_objectclass,TCLib_SIZEOF
    LONG liboc_nextclass
            ; *next object-class (used by TC to keep list of all classes)
            ; should be set to 0.l
            ; (or to pointer on next object-class. This way you
            ; can store multiple classes in one tclib! Last class
            ; must have 0.l then!)
    LONG liboc_classtext
            ; *short_text (null-terminated), is object-description
            ; This text will be shown in the <Data-Create Object>-Requester!
    LONG liboc_classid
            ; This field contains up to 4 chars with an id for this
            ; objectclass (thus it should be unique). It is used to
            ; select and define a specific objectclass (for loading/
            ; saving or with the OBJECT-macro)
            ; If the text has less then 4 chars, fill it with \0s
            ; 'GEL\0', 'IFF\0', 'TEXT', 'CHRT' are used for the intern
            ; object-classes, 'LOGO' for the extern one.
            ; See MISSING.
    BYTE liboc_flags0
OBJCLASSFLAGS0_FRAME = 0    ; %00=off, %01=on, %10=3d, %11=3d-2
OBJCLASSFLAGS0_FRAME_3d = 1
OBJCLASSFLAGS0_BACKFILL = 2  ; enables backfill of object
OBJCLASSFLAGS0_BACKWHITE = 3 ; backfill with white (instead of grey)
    BYTE liboc_flags1
OBJCLASSFLAGS1_EDITTASK = 0 ; call _objectedit from the task not the process
OBJCLASSFLAGS1_ACTIONTASK = 1   ; dito for _objectaction (see tclib.doc)
    BYTE liboc_flags2
    BYTE liboc_flags3
            ; object-flags, if not defined below: reserved & set to 0
            ; liboc_flag0: default-values for new object:

    LONG liboc_objectnew
            ; object, flags = objectnew(num1/num2/*text)
            ; d0      d1                  d0   d1   a0
            ; generate a new, empty object
            ; para: d0/d1/a0: number/number/*text
            ;       Normally all three regs are set to 0.l, which asks
            ;       for a default object.
            ;       These paras are set by the macro-command OBJECT to
            ;       allow the creation of a specific object.
            ;
            ;       if called with paras, see macro OBJECT
            ;       otherwise all three regs are 0, it would be a good
            ;           idea to return 1 in d1 (to let the user
            ;           configurate his object - if needed)
            ; return: d0: *object (or 0.l if not possible)
            ;         d1: auto_edit (0=no, 1=call OBJECT_EDIT
            ;             after initialization - if called with default
            ;             paras 0/0/0 the a good idea to return d1=1
            ;             (and thus let the user configurate this object,
            ;             if possible)
            ; ATTENTION: d0 is used by TC to identify the object
            ; (of all classes), so d0 should be unique for all classes.
            ; Thus return a pointer to allocated mem (either with
            ; exec's or TC's routine!)
    LONG liboc_objectduplicate
            ; object = duplicate(object)
            ; d0                 a0
            ; Duplicate the object a0 return the new *object in d0
            ; (or 0.l, if duplication failed)
    LONG liboc_objectedit
            ; redisplay = edit(object)
            ; d0               a0
            ; 'edit' the object a0 - e.g. open a requesterto user-change
            ;                        object-settings
            ; para: a0=*object (a3=*sheet, a4=*tcobject, both private!!!)
            ; return: d0<>0: redisplay as something was changed!
    LONG liboc_objectdraw
            ; draw object a0
            ; para: a0:*object
            ;       a2: rp
            ;       a6: *GfxBase (simply to make life easier ;^)
            ;       d0-d3: object_box (x1/y1/x2/y2)
            ;       d4: scale (for screen 0.l,
            ;                  for printer: lower_word = numerator
            ;                                upper_word = denominator
            ;           'scale' is intended for scaling fonts
            ;           you might prefer to use object_box for that reason
            ;           (e.g. for scaling pictures)
            ;           can be used to scale fonts...
            ;               newsize=oldsize*(d4&0xffff)/(d4>>16)
            ;           or in asm (d0=oldsize)
            ;               tst.l   d4
            ;               beq.s   noscale
            ;               mulu    d4,d0
            ;               swap    d4
            ;               divu    d4,d0
            ;               swap    d4
            ;            noscale:
            ;
            ; d5: flags (currently unused: 0.l)
    LONG liboc_objectload
            ; Create new object by loading it from sheet.
            ; This is a bit tricky...
            ; para: d0=0 (or d0=1 & a0=*mem, see iii)
            ; (a2=*tcobject, a3=*sheet, a4=*load_handle)
            ;
            ; return:
            ;   a0: *object
            ;   d0: flags
            ; this allows the following tree possibilities:
            ;   i) a0=*object, d0=0 (or d0=1, see iii)
            ;  ii) a0=0.l, d0=0.l: error occured, no object created
            ;                      (e.g. no memory)
            ; iii) a0=0.l, d0=size
            ;       When you return this, TurboCalc reads d0 bytes and
            ;       calls this routine `loboc_objectload' again.
            ;       Create your object from this memory then and
            ;       return it in a0 (case i)
            ;       If you return with a0=object & d0=0, TurboCalc frees
            ;       the allocated memory for you (as TC allocated it)
            ;       If you insist on freeing this piece of memory by your
            ;       routine (e.g. it is exactly your private object-
            ;       structure), then return with d0=1.
            ;       (Remark: This mem is allocated with TC's AllocMemClear!
            ;       your OBJECT_FREE-routine thus must free this mem
            ;       with TC's FreeMem.)

    LONG liboc_objectsave
            ; When TurboCalc saves a sheet (with objects) this routine
            ; is called for every object.
            ; para: a0 = object
            ;       d0 = flags, normally 0 (or 1, see iv)!
            ; (a2=*tcobject, a3=*sheet, a4=*save_handle)
            ; return: a0 = *block
            ;         d0 = blocksize
            ;         d1 = flags
            ;
            ; You have the following four possibilities:
            ;
            ;   i) a0=*mem, d0=size, d1=0.l - don't free mem
            ;       Save size bytes starting at mem, but to not free
            ;       mem (usefull, if you simply return in a0 a pointer
            ;       to your private structure - probably to be used
            ;       with loading-case iii), d0=1 )
            ;  ii) a0=*mem, d0=size, d1=1.l
            ;       Save size bytes starting at mem, and free Mem via
            ;       TurboCalc's FreeMem-Routine - this piece of memory
            ;       thus should be allocated via AllocMem(Clear)
            ; iii) a0=*mem, d0=size, d1=2.l - free mem via exec's
            ;       Save size bytes starting at mem, and free Mem via
            ;       exec's FreeMem-Routine: _LVOFreeMem(mem,size)
            ; iv) a0=0.l, d0=size - return size only
            ;       You want to save the object yourself using
            ;       Write_Byte/Word/Long/Size (see below)
            ;       To do this, TurboCalc calls this routine again
            ;       (with para d0=1) after saving the object-header.
            ;       Important: TurboCalc *must* save the object-header
            ;       first, therefore the size must be specified correctly
            ;               1) set a0=0 & d0=size, return (do *not* write
            ;                  in this mode)
            ;               2) your routine is called again with d0=1
            ;                  Now write the size bytes with Write_...
            ;                  and return: a0=0.l, d0=0.l
    LONG liboc_objectaction
            ; This routine is called when clicking on the object
            ; para: d0=mode (0=click on object, 1=double-click)
            ;       d1=flags (for clicking: 0=clicked on object (macro)
            ;                               1=clicked on object (move)
            ;                               2=clicked on 'size'
            ;                               bit7: if set: object_back (for 1/2)
            ;                (for double-click: is 0.l up to now)
            ;       a0=object
            ;
            ; return: d0=error (0=ok)
            ;         for double-click: if you return with d0<>0
            ;               the default action (opening the settings-
            ;               requester) isn't done, double-click will
            ;               simple be aborted. This is usefull if you
            ;               want to replace the default double-click-action.
            ;         Return value is only used when OBJCLASSFLAGS1_ACTIONTASK
            ;         is selected. Otherwise it is ignored (as the routine
            ;         is called unsynchronously).
            ;
            ; Inportant: It is possible that (in future) new modes will be
            ; added. So please check for the current (implemented) modes
            ; and return d0=0 for the others (and do *not* rely on d0
            ; being 1 if d0<>0!!!).
            ;
            ; You might do whatever you want (e.g. playing a sample
            ; for moving/sizing, starting an external program on double-click)
            ; IF your object has no 'special action' simply omit this
            ; routine (by setting this pointer to 0.l)
            ;
    LABEL liboc_SIZEOF



    STRUCTURE TCLib_crypt,TCLib_SIZEOF
    LONG libcrypt_password  ; set password for en/decrypting
            ; para: a0= *string, null-terminated
            ;       either copy this string to your one buffer or
            ;       (even better) use an algorithm to calculate
            ;       real key (e.g. MD5 or CRC)
    LONG libcrypt_encrypt   ; encrypt block
            ; para: a0= *block
            ;       d0= length of block (in bytes)
    LONG libcrypt_decrypt   ; decrypt block
            ; para: a0= *block
            ;       d0= length of block (in bytes)
    LABEL libcrypt_SIZEOF



    STRUCTURE TCLib_function,TCLib_SIZEOF
    LONG libfnc_flags   ; reserved, unused, set to 0.l!
    LONG libfnc_count   ; #routines below (routine0..routinecount-1)
    LONG libfnc_defaultroutine
            ; this routine is called if either d7 >=count or
            ; libfnc_routine(d7) is 0.l
    LONG libfnc_routine0
;    LONG libfnc_routine1
;    LONG libfnc_routine2
;    ...
;    LONG libfnc_routine(count-1)
    LABEL libfnc_SIZEOF

* parameters for all the fnc_routines:
*   d0-d1:  Value1 (as float)
*   d2:     Value1 (as long)
*   d3-d4:  Value2 (as float)
*   d5:     Value2 (as long)
*   d7:     routine-offset (0..) If libfnc_routinex is called, this
*           is equal to x and thus not needed. If libfnc_defaulroutine
*           is called you might need this data.
*   a0:     String (or 0.l)

* Annotation: The two values are given both as float and as long.
* So you needn't convert them. 'Float' is the first one available
* in {mathieedoubbas/trans, mathieeesingbas/trans, mathffp/trans}
* (thus normally in double-ieee-format!).

* return (for functions):
* d0/d1.l:  data (type dependent)
* d2.l      type - one of:
TYPE_EMPTY = 0  ; no return value, shouldn't be used!
TYPE_NO = 1     ; dito - please return NUM 0 instead (d0-d2 = 0/0/3)
TYPE_FLOAT = 2  ; d0/d1.l is float as defined above
TYPE_NUM = 3    ; d0.l is long
TYPE_DATE = 4   ; d0.l is date (i.e. long)
TYPE_TIME = 5   ; d0.l is date (i.e. long)
TYPE_BOOL = 6   ; d0.l is bool (0=FALSE, 1=TRUE)
TYPE_TEXT = 7   ; d0=*text (or 0, then is empty text!!!)
                ;
TYPE_CELL = 8   ; d0.l=column/d1.l=row (you cannot return this in
                ; all situatuons)
TYPE_ERROR = 9  ; d0.l=error (1..12)
                ;      with 1=don't know, 2=DIV/0, 3=VERSION
                ;      4=REFERENCE, 5=)-BRACKET, 6=TYPE, 7=NOCELL
                ;      8=ARG_NO_RANGE, 9=(-BRACKET, 10=SEMICOLON
                ;      11=VALUE, 12=EOLINE

* return (for macros):
* d0.l:     error-code (0=ok, other see appendix of TurboCalc manual)

* Hint: As you cannot determine if a macro-command is called as functions
* it is a good idea to return the error code together with d2=TYPE_NUM (3).
* When called as macro, d2 is ignorded, otherwise it is interpreted
* as normal value.




*   default parameter for all routines: a5 = *BASE, structure see below
*

*****************************************************************
*****************************************************************
* as mentioned above, a5 (BASE) points to 'global-data-structure'
* containing both useful data and useful routines

* XVECT allocates 6 bytes
* definition of XVECT, XSR, XMP ... see 'tclib2.i'



    STRUCTURE MainData,0
    LONG DosBase            ; Important: Dos, Gfx & Intuitionbase will
    LONG GfxBase            ; be set correctly (as TC needs them to work),
    LONG IntuitionBase      ; but you can't rely on the other libbases.
    LONG LayersBase         ; They may be zero, if these libs aren't
    LONG DiskFontBase       ; currently available in the system (e.g.
    LONG WBBase             ; workbench is closed or KS 1.3 for asl.library)
    LONG ASLBase
    LONG IFFParseBase
    LONG RexxBase
    LONG AmigaGuideBase
    LONG LocaleBase
*
    LONG FirstWindow        ; private
    LONG FirstSheet         ;  .  not even think of touching them!!!
    LONG FirstFont          ;  .
    LONG FontList           ;  .
    LONG LocaleCatalog      ;  .
    LONG AmigaGuideHandle   ;  .
    LONG Screen             ; private
*
    LONG Com_DiskErrorAdr   ; error-routine-adr for Read_ & Write_
                            ; see below!

* some useful routines
* each vector consits of 6 bytes (first two: jmp, then the address)
* call them as you normally call libraries (see macros XSR & XMP above)
* if not mentioned otherwise, only d0-d1/a0-a1 are changed!

*
    XVECT AllocMem          ; para: d0 = size, return d0=a0=*mem - flags set
                            ; size is stored by TC & this piece of memory
                            ; will be freed automatically by TC
                            ; (when TC ends and it hasn't been freed yet)
    XVECT AllocMemClear     ; dito, but memory is cleared
    XVECT FreeMem           ; para: a0 = *mem, frees with AllocMem allocated
                            ; memory. Size was stored by AllocMem
    XVECT DuplicateA0       ; para: a0 =*string (0-terminated mem)
                            ; return: a0=*new piece of mem with the same text
                            ; (allocated with AllocMem)
                            ; changed: only a0 is changed!
* the next tree memory-routines are used for storing small pieces of memory
* they are used for cell-texts, function-texts, cell-information,...
    XVECT AllocTEXTMem      ; para: d0.l = size, return d0=a0=*mem
    XVECT FreeTextMem       ; para: a0.l = allocated mem (with AllocTEXTMem!)
    XVECT DuplicateTEXT     ; para: a0= *string (0-terminated)
                            ; return: a0=*mem (allocated with AllocTEXTMem)
*
    XVECT GetTexta0         ; private
    XVECT GetTexta1         ; private
    XVECT GetTexta2         ; private
    XVECT UpperCaseD0       ; d0.b  = UpperCase(d0.b)
*
    XVECT DOS_SendMessage_stack         ; private
    XVECT IDCMP_SendMessage_stack       ; .
    XVECT CheckA4_Sheet_getsheet        ; .  do not use these routines!!!
    XVECT CheckA4_Diagram               ; .
    XVECT CheckA3                       ; .
    XVECT StartClip                     ; .
    XVECT EndClip                       ; .
    XVECT SetClip                       ; private
*
    XVECT Call_CDX      ; d0/d1=float1, d3/d4=float2, d7=cmd
                        ; for cmd see list below!
* 'get information'-routines (column/row start at 0 for first one!)
    XVECT Column_GetEntry   ; para: d0=column, return: a0=*column or 0.l
    XVECT Column_GetEntry_readonly  ; dito, but no creation
    XVECT Row_GetEntry      ; para: d0=row, return: a0=*row or 0.l
    XVECT Row_GetEntry_readonly     ; dito, but no creation
    XVECT Cell_GetEntry     ; para: d0/d1=column/row, return: a0=*cell or 0.l
    XVECT Cell_GetEntry_readonly    ; dito, but no creation
    XVECT Cell_GetInt       ; para: d0/d1=column/row
                            ; return: d0=int, d2=TYPE_NUM(3.l) or d2=0 (error)
    XVECT Cell_GetFloat     ; para: d0/d1=column/row
                            ; return: d0/d1=float, d2=TYPE_FLOAT(2.l) or d2=0 (error)
    XVECT Cell_GetText      ; para: d0/d1=column/row
                            ; return: a0=*text (allocated with AllocMemClear)
                            ; or 0.l for error!
                            ; (everything will be converted to text!!!)
* loading/saving-routines.
*_Open-Routines change a4 as a private file-handle (containing a buffer,...)
* All other routines need this handle in a4
* Error handling: Except for _Open (and close, where no error can occur)
* the reading/writing routines jump to the adress 'DiskErrorAdr', if
* an error occurs. If you have stored the current stackpointer (a7)
* when calling _Open, you can set it and close the file.
* ..._Byte/Word/Long only change register d0, d1-d7/a0-a6 aren't touched!
    XVECT Read_Open_noerror ; d0=0:ok, else error - a4=handle (is returned)
    XVECT Read_Close    ; close file a4
    XVECT Read_Byte     ; d0.b = read byte from file a4
    XVECT Read_Word     ; d0.w
    XVECT Read_Long     ; d0.l
    XVECT Read_Size     ; read d0.l bytes to a0.l from file a4
    XVECT Read_TestEOF  ; d0=0: eof, else not
*
    XVECT Write_Open    ; d0=0:ok, else error - a4=handle (is returned)
    XVECT Write_Close   ; close file a4
    XVECT Write_Byte    ; write byte d0.b to file a4
    XVECT Write_Word    ; write word d0.w to file a4
    XVECT Write_Long    ; write long d0.l to file a4
    XVECT Write_Size    ; write d0.l bytes from a0.l to file a4
* drawing routines, for all: a2=rp, a6=gfxbase (has to be set!)
    XVECT XSetAPen      ; a2=rp, a6=gfxbase, d0=color
    XVECT XSetAPen_color ; a2=rp, a6=gfxbase, d0=color
    XVECT XSetBPen ; a2=rp, a6=gfxbase, d0=color
    XVECT XSetBPen_color ; a2=rp, a6=gfxbase, d0=color
    XVECT XDrawLine ; a2=rp, a6=gfxbase, d0-d3=x1/y1/x2/y2


**** cmd-values for Call_CDX:
CDX_X: equ $ffffff00    ; used for CDX_Atan+... to get moveq!
CDX_Fix: equ 0
CDX_Flt: equ 1
CDX_Cmp: equ 2
CDX_Tst: equ 3
CDX_Abs: equ 4
CDX_Neg: equ 5
CDX_Add: equ 6
CDX_Sub: equ 7
CDX_Mul: equ 8
CDX_Div: equ 9
CDX_Floor: equ 10
CDX_Ceil: equ 11
*
CDX_Atan: equ $80
CDX_Sin: equ $81
CDX_Cos: equ $82
CDX_Tan: equ $83
CDX_Sincos: equ $84 ; not possible!
CDX_Sinh: equ $85
CDX_Cosh: equ $86
CDX_Tanh: equ $87
CDX_Exp: equ $88
CDX_Log: equ $89
CDX_Pow: equ $8a
CDX_Sqrt: equ $8b
CDX_Tieee: equ $8c
CDX_Fieee: equ $8d
CDX_Asin: equ $8e
CDX_Acos: equ $8f
CDX_Log10: equ $90


