koreth@ssyx.ucsc.edu (Steven Grimm) (06/25/89)
Submitted-by: linus.umd.edu!nixpbe!andreas (Andreas Hoepfner) Posting-number: Volume 2, Issue 46 Archive-name: overscan Now here is the program to initialize the BIGSCREEN from the german magazine 'ST Magazin'. The resolution grows up to 800 * 500. It has to be startet from the 'Auto folder', just before GEM comes up. [This is not the same as "bigscrn," posted to the binaries group; this requires a hardware modification. -sg] It patches the basepage adress for the new resolution and allocates about 69000 Bytes for it. Also included is (wow!) the C sourcecode ( for Megamax C ). +-----------------------------------------------------------------------+ | Andreas Hoepfner | | | | paper mail: e-mail: | | | | c/o/ Nixdorf Computer AG USA: uunet!linus!nixbur!hoepfner.pad | | Abt. ET-31 !USA: mcvax!unido!nixpbe!hoepfner.pad | | Pontanusstrasse 55 | | D-4790 Paderborn | | tel.: (+49) 5251 146475 | +-----------------------------------------------------------------------+ #!/bin/sh # shar: Shell Archiver (v1.22) # # Run the following text with /bin/sh to create: # OVERSCAN.C # sed 's/^X//' << 'SHAR_EOF' > OVERSCAN.C && X X/************************************************************************ X * X * OVERSCAN.C Karsten Isakovic,Berlin 28.04.89 X * X * MEGAMAX C Version 1.2 X */ X X/*.......................... HIGH-RES */ X #define HIGH_X 672 X #define HIGH_Y 480 X #define HIGH_OFF 1608 X/*.......................... MID-RES */ X #define MID_X 848 X #define MID_Y 280 X #define MID_OFF 5640 X/*.......................... LOW-RES */ X #define LOW_X 416 X #define LOW_Y 280 X #define LOW_OFF 5640 X X#include <osbind.h> Xextern char *_base; X Xint inst_ok; /* Wurde installiert oder nicht ? */ Xint RezX; /* Breite des Bildschirms */ Xint RezY; /* Hoehe des Bildschirms */ Xint BpL; /* BytesPerLine , also Bytes pro Bildschirmzeile */ Xlong LineA; /* Zeiger auf LineA Variablen */ Xlong WorkOut; /* Zeiger auf das WorkOut-Feld der 'v_opnwk()' aufruf- */ X /* enden Funktion (hoffentlich der DESKTOP !) */ Xlong Back; /* RuecksprungAddresse zu dieser Funktion */ Xlong SaveBasAdd;/* Zwischenspeicher zur Restauration des Desktops nach */ Xlong SaveVidAdd;/* einem inkompatiblen Programm */ X Xmain() X{ Xlong keep,prgtop; Xint do_setup(); X X Supexec(do_setup); X switch(inst_ok) X { X case 0 : Cconws("\n\rOVERSCAN Version 1.2 installiert\n\r"); X asm { move.l A7,prgtop(A6) } /* A7 steht auf Ende und */ X keep = (prgtop+200L)-(long)_base; /* _base auf Anfang des */ X Ptermres( keep,0); /* Programms */ X break; X case 1 : Cconws("\n\r Kein gueltiges TOS 1.4 / BETA-TOS"); X Cconws("\n\rOVERSCAN Version 1.2 nicht installiert\n\r"); X Cconin(); X case 2 : Cconws("\n\rOVERSCAN Version 1.2 nicht installiert\n\r"); X break; X } X} X X/******************** NEGATIVE LINE-A VARIABLEN ********************/ X X#define WKXRez -0x2b4 X#define WKYRez -0x2b2 X#define V_CEL_HT -0x2e X#define V_CEL_MX -0x2c X#define V_CEL_MY -0x2a X#define V_CEL_WR -0x28 X#define V_REZ_HZ -0xc X#define V_REZ_VT -4 X#define BYTES_LIN -2 X#define V_PLANES 0 X#define WIDTH 2 X X/*********************** HARDWARE **********************************/ X X#define GEMTRAP 0x088 X#define MEMTOP 0x436 X#define RESO 0x44c X#define V_BAS_ADD 0x44e X#define DUMPFLAG 0x4ee X#define SYSBASE 0x4f2 X#define HARDCOPY 0x502 X#define VID_BASHIGH 0xff8201L X#define VID_BASMID 0xff8203L X#define VID_ISMID 0xff8207L X X#define ADD_LEN 0x9000L X Xdo_setup() X{ X asm { X movem.l D0-A6,-(A7) X lea SaveA4(PC),A0 ; GLOBAL Zeiger A4 retten X move.l A4,(A0) ; X move.w #2,inst_ok(A4) ; noch nicht installiert X move.b VID_BASMID,D0 ; Testen ob der Schalter umgelegt ist X move D0,D1 ; Es wird gewartet bis der VideoAddress- X add #0x7d,D1 ; Zaehler bis zum Ende der normalen XWait1: cmp.b VID_ISMID,D1 ; Bildschirmseite hochgezaehlt hat. X bne Wait1 ; Dann wird getestet, ob er auf den XWait2: cmp.b VID_ISMID,D1 ; Anfang zurueckspringt. Wenn nicht ist X beq Wait2 ; der Schalter umgelegt. X cmp.b VID_ISMID,D0 ; X beq ende ; Nicht umgelegt -> Beenden X;----------------------------------------------------------- X move #1,inst_ok(A4) ; auf BETA RAMTOS testen X move.l #0x170ee,A0 ; X cmpi.l #0xe848cec0,(A0); LSR #4,D0 / MULU D0,D7 X bne RAMTOS1_4 ; Kein BETA-RAMTOS -> Teste TOS 1.4 X bra TOSok XRAMTOS1_4: X move.l #0x17192,A0 ; X cmpi.l #0xe848cec0,(A0); LSR #4,D0 / MULU D0,D7 X bne ROMTOS1_4 ; Kein RAMTOS 1.4 -> Teste ROMTOS 1.4 XROMTOS1_4: X move.l SYSBASE,A0 ; _sysbase X cmpi.w #0x0104,2(A0) ; os_version 1.04 ? X bne ende ; Kein ROMTOS 1.4 -> ENDE XTOSok: X move #0,inst_ok(A4) ; X dc.w 0xA000 ; LineA-Init X move.l A0,LineA(A4) ; Zeiger auf Variablen retten X lea OldVec(PC),A0 ; Alten GemTrapVektor retten X move.l GEMTRAP,(A0) ; X lea MyGem(PC),A0 ; X move.l A0,GEMTRAP ; und neuen Vektor eintragen X clr.l D0 ; X move.b RESO,D0 ; X cmpi.w #2,D0 ; Aufloesung HIGH ? X bne ende ; nein -> weiter X lea OldHard(PC),A0 ; Alten HardcopyVektor retten X move.l HARDCOPY,(A0) ; X lea MyHard(PC),A0 ; X move.l A0,HARDCOPY ; und neuen Vektor eintragen Xende: X lea Patched(PC),A0 ; PatchFlag loeschen X clr.l (A0) ; X movem.l (A7)+,D0-A6 ; X bra end_setup ; Ende des Setup-Teils X;------------------------------------------------------------------------ XSaveA4: move.l #0,-(A7) ; (dc.l) Speicher fuer GLOBAL-Zeiger XPatched:move.l #0,-(A7) ; (dc.l) Speicher fuer PatchFlag X X dc.b "XBRAOVER" ; XBRA-Protokoll ! (Ja das ist alles !!) XOldVec: move.l #0,-(A7) ; (dc.l) Alter Vektor XMyGem: X lea Patched(PC),A0 ; X tst.w (A0) ; Ist LineA schon geaendert ? X bne Normal ; ja -> weiter X cmp.w #0x73,D0 ; Ist es ein VDI-Aufruf ? X bne.s Normal ; nein -> weiter X move.l D1,A0 ; D1 ist Addresse der VDI-Parameterfelder X move.l A4,-(A7) ; A4 Register retten X move.l SaveA4(PC),A4 ; und GLOBAL-Zeiger holen X move.l 12(A0),WorkOut(A4); WorkOut-Zeiger speichern X move.l (A0),A0 ; VDI-Control[0] entspricht dem VDI-Befehl X cmpi.w #1,(A0) ; ist es Open-WorkStation ? X bne.s Norm2 ; nein-> weiter X move.l 6(A7),Back(A4) ; Ruecksprung merken X lea PatchIt(PC),A0 ; und PatchIt als Ruecksprung eintragen X move.l A0,6(A7) ; XNorm2: move.l (A7)+,A4 ; A4 Register zurueckholen XNormal: X move.l OldVec(PC),A0 ; X jmp (A0) ; Orginal-Routine ausfuehren X;------------------------------------------------------------------------ XPatchIt: X move.l SaveA4(PC),A1 ; GLOBAL-Zeiger in A1 holen ! X ;-------------------------------------------------------------- X move.l #0x170ee,A0 ; auf BETA RAMTOS testen X cmpi.l #0xe848cec0,(A0) ; X bne isRAMTOS1_4 ; nein -> TOS 1.4 Xis_BETATOS1_4: X move.l 0x522e,A0 ; BETA TOS X subi.l #ADD_LEN,8(A0) ; Memory-Free-List X subi.l #ADD_LEN,MEMTOP ; X move.l #0xcec0e84f,0x170ee ; Patch fuer Scrolling unter TOS X ; MULU D0,D7 / LSR #4,D7 statt X ; LSR #4,D0 / MULU Do,D7 X bra weiter XisRAMTOS1_4: X move.l #0x17192,A0 X cmpi.l #0xe848cec0,(A0) X bne isROMTOS1_4 X move.l 0x522e,A0 ; RAMTOS 1.4 X subi.l #ADD_LEN,8(A0) ; Memory-Free-List X subi.l #ADD_LEN,MEMTOP ; X move.l #0xcec0e84f,0x17192 ; zweimal Patchen X move.l #0xcec0e84f,0x1711d6 ; X bra weiter XisROMTOS1_4: X move.l 0x5328,A0 ; ROMTOS 1.4 Xtst_ROMTOS: X tst.l (A0) ; letzten Eintrag der Memory-Free-List X beq do_ROMTOS ; suchen X move.l (A0),A0 X bra tst_ROMTOS Xdo_ROMTOS: X subi.l #ADD_LEN,8(A0) ; Memory-Free-List X subi.l #ADD_LEN,MEMTOP ; X ;--------------------------------------------------------------- Xweiter: clr.l D0 X move.b RESO,D0 ; Jetzige Aufloesung Xlow: bne mid ; ist es LOW-RES ? X move.w #LOW_X,RezX(A1) ; X move.w #LOW_Y,RezY(A1) ; X move.w #236,BpL(A1) ; X move.l MEMTOP,V_BAS_ADD; X subi.l #0x1600L,V_BAS_ADD X move.l #LOW_OFF,D0 ; Offset X bra set X ;--------------------------------------------------- Xmid: cmpi.w #1,D0 ; ist es MID-RES ? X bne high ; nein -> weiter X move.w #MID_X,RezX(A1) ; X move.w #MID_Y,RezY(A1) ; X move.w #236,BpL(A1) ; X move.l MEMTOP,V_BAS_ADD; X subi.l #0x1600L,V_BAS_ADD X move.l #MID_OFF,D0 ; Offset X bra set X ;--------------------------------------------------- Xhigh: move.w #HIGH_X,RezX(A1);also HIGHRES X move.w #HIGH_Y,RezY(A1); X move.w #100,BpL(A1) ; X move.l MEMTOP,V_BAS_ADD; X addi.l #0x2000L,V_BAS_ADD X move.l #HIGH_OFF,D1 ; vor dem Bildschirmspeicher X asr.l #2,D1 ; Ruecklaufstrahl auf Schwarz setzen X addq.l #1,D1 ; X move.l V_BAS_ADD,A0 ; Xh_clp: move.l #-1,(A0)+ ; X dbf D1,h_clp ; X move.l #HIGH_OFF,D0 ; Offset X ;--------------------------------------------------- Xset: move.b 0x44fL,VID_BASHIGH ; VideoAddresse setzen X move.b 0x450L,VID_BASMID ; X move.l V_BAS_ADD,SaveVidAdd(A1); VideoAddresse retten X add.l D0,V_BAS_ADD ; Offset anbringen X move.l V_BAS_ADD,SaveBasAdd(A1); v_bas_add retten X move.l #0x4400,D1 ; Bildschirmspeicher auf Schwarz X move.l V_BAS_ADD,A0 ; loeschen Xsc_clp: move.l #-1,(A0)+ ; X dbf D1,sc_clp ; X bsr setLineA(PC) ; LineA Werte eintragen X move.l WorkOut(A1),A0 ; X move.w RezX(A1),0(A0) ; Work_out[0] = Breite X move.w RezY(A1),2(A0) ; Work_out[1] = Hoehe X lea Patched(PC),A0 ; den Patch nur einmal ausfuehren, X move.l #-1,(A0) ; also setzen wir ein Flag X move.l Back(A1),-(A7) ; Zum 'v_opnwk()' - Aufrufer X rts ; zurueckspringen X;------------------------------------------------------------------------ XsetLineA: X movem.l D0/A0-A1,-(A7) X move.l SaveA4(PC),A1 ; GLOBAL Zeiger in A1 holen ! X move.l LineA(A1),A0 ; LineA Zeiger holen X move.w RezX(A1),V_REZ_HZ(A0) ; Breite setzen X move.w RezX(A1),WKXRez(A0) ; X subi.w #1,WKXRez(A0) ; Breite-1 X move.w RezY(A1),V_REZ_VT(A0) ; Hoehe setzen X move.w RezY(A1),WKYRez(A0) ; X subi.w #1,WKYRez(A0) ; Hoehe-1 X move.w BpL(A1) ,BYTES_LIN(A0) ; Bytes pro Zeile setzen X move.w BpL(A1),WIDTH(A0) ; X move.w RezX(A1),D0 ; X asr.w #3,D0 ; X subq.w #1,D0 ; Breite/8 -1 X move.w D0,V_CEL_MX(A0) ; -> Anzahl Buchstaben pro Zeile X clr.l D0 ; X move.w RezY(A1),D0 ; X divu.w V_CEL_HT(A0),D0 ; X subq.w #1,D0 ; Hoehe/Buchstabenhoehe -1 X move.w D0,V_CEL_MY(A0) ; -> Anzahl Buchstabenzeilen X move.w V_CEL_HT(A0),D0 ; X mulu.w BpL(A1),D0 ; AnzBuchstaben*BytesProZeile X move.w D0,V_CEL_WR(A0) ; -> Blocklaenge fuer Scrolling X movem.l (A7)+,D0/A0-A1 X rts X;------------------------------------------------------------------------ X dc.b "XBRAOVER" ; HARDCOPY nur bei HIGH-RES XOldHard:move.w #0,-(A7) ; (dc.l) XMyHard: movem.l D0-D4/A0-A1/A4,-(A7) ; X move.l SaveA4(PC),A4 ; GLOBAL Zeiger holen X lea SaveVidAdd(A4),A0 ; VideoAddressZeiger setzen X move.b 1(A0),VID_BASHIGH ; X move.b 2(A0),VID_BASMID ; X move.l SaveBasAdd(A4),V_BAS_ADD; v_bas_add setzen X bsr setLineA(PC) ; LineA nochmal setzen (wird zB von X ; DEGAS veraendert ) X clr.l D0 ; X move.l #-1L,D4 ; Loeschwert (Schwarze Pixel) X move.l SaveVidAdd(A4),A1 ; X move.l SaveBasAdd(A4),A0 ; X subq.l #2,A0 ; Falls HIGH_OFF nicht /4 teilbar XHflp: move.l D4,(A1)+ ; Vor dem Bildschirm Ruecklauf X cmpa.l A0,A1 ; Pixel auf Schwarz setzen X blt Hflp ; X ;---------------------------------- X move.l SaveBasAdd(A4),A0 ; X clr.l D0 ; Den ungenutzten Bereich im X clr.l D1 ; Ruecklauf auf Schwarz setzen X move BpL(A4),D0 ; X move RezX(A4),D1 ; BytesProZeile-Breite/8 X asr #3,D1 ; -> Breite des Bereichs X sub D1,D0 ; X move RezY(A4),D2 ; Hoehe des Bereichs X subq #1,D2 ; X subq #1,D0 ; XHlp1: adda.l D1,A0 ; Normalen Bildbereich ueberspringen X move D0,D3 ; XHlp2: move.b D4,(A0)+ ; Bereich loeschen X dbf D3,Hlp2 ; X dbf D2,Hlp1 ; X ;---------------------------------- X move.l #250,D0 ; 1000 Bytes weiterloeschen X move.l A0,D0 ; X andi.l #0xffffffeL,D0 ; X move.l D0,A0 ; XHlp3: move.l D4,(A0)+ ; X dbf D0,Hlp3 ; X move #-1,DUMPFLAG ; DumpFlag loeschen X movem.l (A7)+,D0-D4/A0-A1/A4 X rts X;------------------------------------------------------------------------- Xend_setup: X } X} SHAR_EOF chmod 0600 OVERSCAN.C || echo "restore of OVERSCAN.C fails" exit 0