home *** CD-ROM | disk | FTP | other *** search
- /* V 1.02
- (c) 1997 by Dimitri Junker
- Adenauerallee 30
- 52066 Aachen */
- /* Dies sind die C-Funktionen, die in PD eingefügt werden können*/
- /* Zum Sprachgebrauch: Bei der 2 Monitorlösung unterscheide ich zwischen:
- AES-Monitor: der über den das AES ausgibt, also der an der Grafikkarte
- Bitmap-Monitor: der, der per Offscreen-Bitmap beschrieben wird
- und am Original-Videoshifter hängt */
-
- /* -------------------------------------------------------------------- */
- /* Includes */
- /* -------------------------------------------------------------------- */
-
- #include "patch.h"
-
- /* -------------------------------------------------------------------- */
- /* Makros. & Konstanten */
- /* -------------------------------------------------------------------- */
-
- #define min(a, b) ((a) < (b) ? (a) : (b))
- #define _sysbase (0x4f2l)
-
- /* -------------------------------------------------------------------- */
- /* typedefs */
- /* -------------------------------------------------------------------- */
-
- typedef char BOOLEAN;
-
- /* -------------------------------------------------------------------- */
- /* lokale Funktionsprototypen */
- /* -------------------------------------------------------------------- */
-
- void prg_reset_a(void);
- void Set_Gd_trm(void);
- long get_act_pd(void);
- long init_sup(void);
- long set_mon(void);
- long get_cookie_jar();
- BOOLEAN get_cookie(long cookie_name, LONG *cookie_value);
- void draw_menu(void);
- long framelength(void);
- void v_clsvwk1(int handle);
-
- /* -------------------------------------------------------------------- */
- /* Globale Variablen */
- /* -------------------------------------------------------------------- */
- extern MFDB M_pd;
- extern PDX X_pd;
- extern int b_23E58;
- /* -------------------------------------------------------------------- */
- /* Funktionen */
- /* -------------------------------------------------------------------- */
-
-
- /* Im 2 Monitorbetrieb müssen PD teilweise andere Phys- bzw Logbase
- Adressen gemeldet werden, als dies die Betriebssystemroutinen
- machen würden. */
- void *Physbase2(void)
- { return(X_pd.p_baddr[X_pd.p_phys]);
- }
-
- void *Logbase2(void)
- { return(X_pd.p_baddr[X_pd.p_log]);
- }
- /* Diese Routine wird einmal statt der normalen v_opnvwk ausgeführt,
- sie öfnet keine virtuelle WS, sondern eine Offscreenbitmap
- an der Stelle, an der sich der Bildschirmspeicher befindet.
- Au₧erdem wird sie noch einmal von Mxalloc2 aufgerufen, um noch
- eine 2. Bitmap zu öffnen
- Beim 1. Aufruf wird auch noch einiges initialisiert, daher der Name */
- void v_opn_init2( int *work_in_alt, int *handle,int *work_out )
- { VDIPB vdipb;
- int contrl[15], work_in[20],i,bm;
- long farben,c_val;
- if(X_pd.p_baddr[0]) /* Aufruf von Mxalloc für Bitmap[1] */
- { bm=1;
- contrl[6]=work_in[0] =X_pd.p_bhdl[2];
- }
- else /* Aufruf von PD für Bitmap[0] */
- { bm=0;
- if(get_cookie('_VDO', &c_val))
- X_pd.p_masch=(int)(c_val>>16);
- else
- X_pd.p_masch=ST_MOD;
- X_pd.p_pdhdl=handle; /* hier speichert PD sein Handel */
- X_pd.p_baddr[0]=(void *)Supexec(init_sup);
- X_pd.p_baddr[2]=Physbase();
- X_pd.p_phys=X_pd.p_log=2; /* Aktuell AES-Monitor*/
- X_pd.p_bhdl[2]=contrl[6]=work_in[0] = graf_handle(&i, &i, &i, &i);
- }
- M_pd.fd_addr=X_pd.p_baddr[bm];
- contrl[0]=100;
- contrl[1]=0;
- contrl[4]=0;
- contrl[5]=1;
- for(i=1;i<11;i++)
- work_in[i]=work_in_alt[i];
- work_in[11] = M_pd.fd_w-1;
- work_in[12] = M_pd.fd_h-1;
-
- vdipb.contrl=contrl;
- vdipb.intin =work_in;
- vdipb.intout=work_out;
- vdipb.ptsout=work_out + 45;
- if(X_pd.p_vopn==NOVA)
- { work_in[13]=M_pd.fd_nplanes;
- work_in[14]=1;
- contrl[2]=6;
- contrl[3]=15;
- *((void **)(&contrl[7])) =M_pd.fd_addr;
-
- }
- else /* EdDi 1.1 */
- { work_in[13]=278; /* Breite eines Pixels in Mikrometern */
- work_in[14]=278; /* Höhe eines Pixels in Mikrometern */
- farben=1<<M_pd.fd_nplanes;
- *(long *)&work_in[15]=farben;
- work_in[17]=M_pd.fd_nplanes;
- work_in[18]=0;
- work_in[19]=1;
- contrl[2]=0;
- contrl[3]=20;
- *((MFDB **)(&contrl[7])) =&M_pd;
- }
- vdi( &vdipb ); /* v_opnbm oder v_opnvwk2 */
-
- X_pd.p_bhdl[bm]=*handle = contrl[6];
-
- /* Bei meinen ersten Versuchen erschien die Schrift Wei₧ auf Wei₧,
- deshalb sicherheitshalber auf Schwarz setzen */
- contrl[0]=22;
- contrl[1]=0;
- contrl[2]=0;
- contrl[3]=1;
- contrl[4]=1;
- contrl[5]=0;
- contrl[6]=*handle;
- work_in[0]=1;
- vdipb.intout=work_in+3;
- vdipb.ptsout=work_in+12;
- vdi( &vdipb ); /* vst_color */
- M_pd.fd_addr=X_pd.p_baddr[0];
- }
- /* ist eigentlich Teil von v_opn_init2, mu₧ aber im Supervisormode
- ausgeführt werden hier wird die Basepage ermittelt, die Bildschirm-
- Adresse (Bitmap-Monitor) bestimmt und die Auflösung gesetzt*/
- long init_sup(void)
- { long addr;
- X_pd.p_bp=(BASPAG *)get_act_pd(); /* Die eigene BASEPAGE merken */
- addr=(long)(*(unsigned char *)0xffff8201l);
- addr=addr<<8;
- addr|=(long)(*(unsigned char *)0xffff8203l);
- addr=addr<<8;
- if(X_pd.p_masch!=ST_MOD)
- addr|=(long)(*(unsigned char *)0xffff820dl);
- *( char *)0xffff8260l=X_pd.p_res;
- if(X_pd.p_masch==TT_MOD)
- { *( char *)0xffff8262l&=0xF8;
- *( char *)0xffff8262l|=X_pd.p_res;
- }
- X_pd.p_frame=(int)framelength();
- return(addr);
- }
- /* ist eigentlich Teil von v_opn_init1 und 2, mu₧ aber im Supervisormode
- ausgeführt werden hier wird ermittelt, ob TRAP 6 oder 8 Byte auf den SSP
- legt. Sie ist long, damit sie mit Supexec verwendet werden kann*/
- long framelength(void)
- { return((*(int *)0x59EL) ? 8 : 6 );
- }
- /* Im Einmonitorbetrieb ist zwar keine Alternative zu v_opnvwk
- nötig, aber da die Stelle gut für Initialisierung ist...
- Hier wird die Basepage ermittelt, Falls eine NOVA-Karte aktiv ist,
- wird der Mxalloc Modus auf 3 gesetzt, für andere Karten einfach testen*/
- void v_opn_init1( int *work_in, int *handle,int *work_out )
- { ICB *icb;
- X_pd.p_bp=(BASPAG *)Supexec(get_act_pd); /* Die eigene BASEPAGE merken */
- v_opnvwk(work_in,handle,work_out );
- if (get_cookie('IMNE',(long *)&icb))
- X_pd.p_bs_m=3;
- X_pd.p_ms=-1;
- X_pd.p_frame=(int)Supexec(framelength);
- X_pd.p_baddr[2]=Physbase();
- }
-
- /* Die 2 Bitmap-WS abmelden und Bildschirm löschen, ist besser für
- den Monitor */
- #pragma warn -par
- void v_clsbm( int handle )
- { VDIPB vdipb;
- int contrl[15],dummy[20],pxy[8];
-
- /* Bildschirm löschen */
- pxy[0]=pxy[1]=pxy[4]=pxy[5]=0;
- pxy[2]=pxy[6]=M_pd.fd_w-1;
- pxy[3]=pxy[7]=M_pd.fd_h-1;
- M_pd.fd_addr=X_pd.p_baddr[0];
- vro_cpyfm(X_pd.p_bhdl[0],ALL_BLACK,pxy,&M_pd,&M_pd);
-
- /* Beide Workstations schlie₧en */
- if(X_pd.p_vopn==NOVA)
- { v_clsvwk(X_pd.p_bhdl[0]);
- v_clsvwk(X_pd.p_bhdl[1]);
- }
- else
- { contrl[0]=101;
- contrl[1]=contrl[2]=contrl[3]=contrl[4]=0;
- contrl[5]=1;
- vdipb.contrl=contrl;
- vdipb.intin =dummy;
- vdipb.intout=dummy;
- vdipb.ptsout=dummy;
- contrl[6] = X_pd.p_bhdl[0];
- vdi( &vdipb );
- contrl[6] = X_pd.p_bhdl[1];
- vdi( &vdipb );
- }
-
- }
- #pragma warn +par
- /* NOVA-VDI <2.63 gibt bei vq_extnd eine falsche Anzahl Planes zurück*/
- void vq_extnd_nova( int handle, int owflag, int *work_out )
- { vq_extnd(handle,owflag,work_out );
- if(owflag)
- work_out[4]=M_pd.fd_nplanes;
- }
- /* Mauszeiger auf 2. Bildschirm zeichnen...
- es wird davon ausgegangen, da₧ die Auflösung des AES-Monitors grö₧er
- oder gleich der des kleinen ist.*/
- void vq_mouse2( int handle, int *pstatus, int *x,int *y )
- { int pxy[8],w,h,xv,yv;
- MFDB m_s;
- m_s=*&M_pd;
- m_s.fd_w=m_s.fd_h=16;
- m_s.fd_wdwidth=1;
- /* Die Mausposition und Status erfragen */
- vq_mouse(handle,pstatus,x,y);
-
- /* Falls au₧erhalb des kleinen Bildschirms Offset verändern*/
- xv=*x-X_pd.p_x_offs;
- if(xv<0)
- { X_pd.p_x_offs=*x;
- *x=0;
- }
- else
- { if(xv>=M_pd.fd_w)
- { X_pd.p_x_offs=*x+1-M_pd.fd_w;
- *x=M_pd.fd_w-1;
- }
- else
- *x=xv;
- }
- yv=*y-X_pd.p_y_offs;
- if(yv<0)
- { X_pd.p_y_offs=*y;
- *y=0;
- }
- else
- { if(yv>=M_pd.fd_h)
- { X_pd.p_y_offs=*y+1-M_pd.fd_h;
- *y=M_pd.fd_h-1;
- }
- else
- *y=yv;
- }
- /* Falls die Maus sich bewegt hat mu₧ der Zeiger neu gezeichnet werden
- natürlich nur wenn nicht der AES-Monitor aktiv ist*/
- if((*x!=X_pd.p_x || *y!=X_pd.p_y)&& X_pd.p_phys!=2)
- { m_s.fd_addr=X_pd.p_msave;
- /* Falls Mauszeiger an war Hintergrund restaurieren */
- if(X_pd.p_x!=-1)
- { w=min(16,M_pd.fd_w-X_pd.p_x)-1;
- h=min(16,M_pd.fd_h-X_pd.p_y)-1;
- pxy[0]=pxy[1]=0;
- pxy[2]=w;
- pxy[3]=h;
- pxy[6]=w+(pxy[4]=X_pd.p_x);
- pxy[7]=h+(pxy[5]=X_pd.p_y);
- vro_cpyfm(handle,S_ONLY,pxy,&m_s,&M_pd);
- }
- /* Falls jetzt an: Mauszeiger zeichnen */
- if(!X_pd.p_ms)
- { w=min(16,M_pd.fd_w-*x)-1;
- h=min(16,M_pd.fd_h-*y)-1;
- pxy[2]=w+(pxy[0]=*x);
- pxy[3]=h+(pxy[1]=*y);
- pxy[4]=pxy[5]=0;
- pxy[6]=w;
- pxy[7]=h;
- vro_cpyfm(handle,S_ONLY,pxy,&M_pd,&m_s);
- m_s.fd_addr=X_pd.p_mmaske;
- pxy[0]=pxy[1]=0;
- pxy[2]=w;
- pxy[3]=h;
- pxy[6]=w+(pxy[4]=*x);
- pxy[7]=h+(pxy[5]=*y);
- vro_cpyfm(handle,NOTS_AND_D,pxy,&m_s,&M_pd);
- m_s.fd_addr=X_pd.p_mzeiger;
- vro_cpyfm(handle,S_OR_D,pxy,&m_s,&M_pd);
- X_pd.p_x=*x;
- X_pd.p_y=*y;
- }
- else
- X_pd.p_x=-1; /* beim nächsten mal nicht restaurieren */
- }
- }
- /* Falls im 1-Monitorbetrieb in die Menüzeile geklickt wird, diese restaurieren
- falls die rechte Maustaste gedrückt wird Mauszeiger aktivieren*/
- void vq_mouse1( int handle, int *pstatus, int *x,int *y )
- { vq_mouse(handle,pstatus,x,y );
- if((*y<18 && *pstatus && !X_pd.p_ms)||X_pd.p_ms<0)
- draw_menu();
- if(*pstatus>1) /*Eine andere Maustaste als die linke gedrückt*/
- { v_show_c(handle,0);
- *pstatus&=1; /*Vor PD verbergen */
- }
- X_pd.p_ms=*pstatus;
- }
- /* Ein- und ausschalten des Mauscursors mu₧ auf die 2 Monitore verteilt
- werden. */
- void hide_curs2( void )
- { int pxy[8],w,h;
- MFDB m_s;
- m_s=*&M_pd;
- X_pd.p_ms++;
- if(X_pd.p_phys==2) /* AES-Monitor */
- v_hide_c(X_pd.p_bhdl[2]);
- else /* Bitmap-Monitor */
- { if(X_pd.p_x>-1) /* Wenn er sichtbar war löschen */
- { m_s.fd_w=m_s.fd_h=16;
- m_s.fd_wdwidth=1;
- m_s.fd_addr=X_pd.p_msave;
- w=min(16,M_pd.fd_w-X_pd.p_x)-1;
- h=min(16,M_pd.fd_h-X_pd.p_y)-1;
- pxy[0]=pxy[1]=0;
- pxy[2]=w;
- pxy[3]=h;
- pxy[6]=w+(pxy[4]=X_pd.p_x);
- pxy[7]=h+(pxy[5]=X_pd.p_y);
- X_pd.p_x=-1;
- vro_cpyfm(X_pd.p_bhdl[X_pd.p_phys],S_ONLY,pxy,&m_s,&M_pd);
- }
- }
- }
- void show_curs2( void )
- { int x,y,ps,reset=1;
- if(reset)
- { if(X_pd.p_ms)
- X_pd.p_ms--;
- }
- else
- X_pd.p_ms=0;
-
- if(X_pd.p_phys==2)
- { if(!X_pd.p_ms)
- reset=0;
- v_show_c(X_pd.p_bhdl[2],reset);
- }
- else
- vq_mouse2(X_pd.p_bhdl[X_pd.p_phys],&ps,&x,&y);
- }
- #pragma warn -par
-
- /* auch das Setscreen mu₧ auf die 2 Monitore verteilt werden */
- void Setscreen2( void *laddr, void *paddr, int rez )
- { int bm;
- if((long)laddr!=-1l) /* Logbase ändern? */
- { if(X_pd.p_baddr[0]==laddr)
- bm=0;
- else
- { if(X_pd.p_baddr[2]==laddr)
- bm=2;
- else
- bm=1;
- }
- *X_pd.p_pdhdl=X_pd.p_bhdl[bm]; /* dadurch simulierenm, da₧ PD ein anderes Handle untergejubelt wird */
- X_pd.p_log=bm; /* und merken */
- }
- if((long)paddr!=-1l) /* Physbase ändern */
- { if(X_pd.p_baddr[0]==paddr)
- bm=0;
- else
- { if(X_pd.p_baddr[2]==paddr)
- bm=2;
- else
- bm=1;
- }
- hide_curs2();
- if(bm<2) /* Bitmap-Monitor */
- { M_pd.fd_addr=paddr; /* Adresse für Videoshifter umsetzen */
- Supexec(set_mon);
- } /* AES-Monitor ist ja immer sichtbar */
- X_pd.p_phys=bm;
- show_curs2();
- }
- }
- /* Bildschirmadresse für Videoshifter setzen, also eine Art Setscreen */
- long set_mon(void)
- {
- *(unsigned char *)0xffff8201l=(unsigned char)((long)M_pd.fd_addr>>16);
- *(unsigned char *)0xffff8203l=(unsigned char)((long)M_pd.fd_addr>>8);
- if(X_pd.p_masch!=ST_MOD)
- *(unsigned char *)0xffff820dl=(unsigned char)M_pd.fd_addr;
- return(0l);
- }
-
-
- /* Mxalloc wird nur benutzt, um Speicher für den 2. und 3. Bildschirm zu
- reservieren, da PD davon ausgeht, da₧ sie ST-RAM benötigen. Da der
- Speicher für den 2. Bildschirm bereits vom AES reserviert ist, kann
- beim 1. Aufruf von Mxalloc der Speicher zurückgegeben werden, auf den
- die VideoBase Register zeigen. Da PD sicherheitshalber immer auf die
- nächste durch 256 teilbare Adresse aufrundet, und zwar so, da₧ wenn die
- von Mxalloc zurückgegebene Adresse bereits durch 256 teilbar ist, er
- 256 hinzuaddiert:
- addr+=256;
- addr&=0xffffff00;
-
- mu₧ diese Routine eine Adresse kleiner als Videobase zurückgeben.
- PD ruft zuerst Mxalloc auf, wenn dieses einen Wert <=0
- ( Assembler: ble ) zurückgibt wird nochmal mit Malloc probiert.
- Es reicht also Mxalloc zu ersetzen, auch auf TOS Versionen ohne Mxalloc.
-
- Problem:
- Falls Videobase nicht durch 256 teilbar ist, wird es Probleme geben.
- Dies ist bei mir nie der Fall gewesen, das AES reserviert wohl aus
- kompatibilitätsgründen immer Speicher an einer Seitengrenze. Falls aber
- irgendwann andere Programme den 2. Bildschirm nutzen, und evtl.
- Feinscrolling machen ist dies nicht mehr gesichert. Dann mü₧te z.B.
- das Aufrunden weggepatcht werden:
- add.l #$100,D0
- and.l #-$100,D0
- dies kommt 2* vor
- Oder in v_opnbm neuer Speicher reserviert werden.*/
-
- void *Mxalloc2( long amount, int mode )
- { int work_in[11],work_out[65],i;
- void *ret;
- switch((int)X_pd.p_mxa)
- { case 0:
- X_pd.p_mxa++;
- *X_pd.p_pdhdl=X_pd.p_bhdl[X_pd.p_log];
- ret=(void*)((long)X_pd.p_baddr[0]-2l);
- break;
- case 1:
- X_pd.p_mxa++;
- ret=Mxalloc(amount,mode );
-
- for(i=0;i<10;i++)
- work_in[i]=1;
- work_in[10]=2;
- X_pd.p_baddr[1]=(void *)(((long)ret+256l)&0xffffff00l);
- v_opn_init2(work_in,&X_pd.p_bhdl[1],work_out);
- break;
- default: /* sollte zwar nicht vorkommen, aber...*/
- ret=Mxalloc(amount,mode );
- }
- return(ret);
- }
- /* falls in v_opn_init X_pd.p_bs_m umgesetzt wurde wird nicht mehr
- ST-RAM für den 2. Bildschirm verwendet */
-
- #pragma warn -par
- void *Mxalloc1( long amount, int mode )
- { return(Mxalloc(amount,X_pd.p_bs_m ));
- }
- #pragma warn +par
- /* fügt beim Programm-Reset auch noch ein Fclose aller offenen Dateien durch*/
-
- void reset(void )
- { int i;
- long tst=64l;
- for(i=6;i<32;i++)
- { if((X_pd.p_flags[1]&tst)!=0l)
- Fclose(i);
- tst*=2l;
- }
- tst=1l;
- for(i=32;i<64;i++)
- { if((X_pd.p_flags[0]&tst)!=0l)
- Fclose(i);
- tst*=2l;
- }
- if(b_23E58!=-1)
- prg_reset_a();
-
- }
-
- /*------------------------------------------------------------------*/
- /* long get_act_pd() */
- /* */
- /* Gibt die Basepage des aktuellen Proz. zurück */
- /* */
- /* Parameter: keiner */
- /* Rückgabe :Die Funktion liefert als Ergebnis den Pointer, */
- /* allerdings als long, wegen Supexec */
- /* (c) by Dimitri Junker 1996 */
- /* nach Profibuch S.185 */
- /* Besonderheit: mu₧ per Supexec aufgerufen werden */
- /*------------------------------------------------------------------*/
- long get_act_pd(void)
- { BASPAG *bp;
- SYSHDR *os;
-
- os=*(SYSHDR **)_sysbase;
- os=os->os_base;
- bp=*os->_run;
- return((long)bp);
- }
-
- BOOLEAN get_cookie(long cookie_name, LONG *cookie_value)
- {
- LONG *cookie;
- int ret;
-
- /* Zuerst einen Zeiger auf den Cookie holen */
-
- if((cookie = (long *)Supexec(get_cookie_jar))==NULL)
- ret=0;
- else
- {
- do
- {
- /* Ist es unser Cookie ? */
- if(*cookie== cookie_name)
- break;
- else
- {
- /* nächster Cookie aus Jar */
- cookie = &(cookie[2]);
- }
- }
- while(cookie[0]); /* solange nicht NULL-Cookie */
-
- if(!cookie[0])
- ret=0;
- else
- { *cookie_value=cookie[1];
- ret=1;
- }
- }
- return(ret);
- }
- /*------------------------------------------------------------------*/
- /* long get_cookie_jar() */
- /* */
- /* Ermittelt die Adresse des Cookie Jar. */
- /* */
- /* Parameter:keine */
- /* Rückgabe :Adresse, falls der Cookie Jar gefunden wurde, */
- /* NULL falls kein Cookie-Jar */
- /* Besonderheit: mu₧ per Supexec aufgerufen werden */
- /* (c) by Dimitri Junker 1996 */
- /*------------------------------------------------------------------*/
-
- long get_cookie_jar()
- {
- LONG *cookiejar;
-
- cookiejar = *((LONG **) 0x5a0L);
- return((long)cookiejar);
- }
-