[comp.sources.atari.st] v02i046: overscan -- Software driver for increased screen size

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