Alive
News Team Current issue History Online Support Download Forum @Pouet

01 - 02 - SE - 03 - 04 - 05 - 06 - 07 - 08 - 09 - 10 - 11 - 12 - 13 - 14

Alive 11
Overscan Techniques
Part II
;                  _____________     __________________________
;                 _\____  ;\    |____\   ;|    \   ;|______  ;/\
;=============== |    ,    |    \   ;|____|    |    |    /____| \ ==============
;                |_________|_________|____|_________/_________|\|
;                \         \         \    \         \         \ |
;                 \_al!ve___\_________\____\_________\_____ltk_\|
;
;================= [m]   [a]   [g]   [a]   [z]   [i]   [n]   [e] ===============

; Overscan Techniques - Part II - Listing 1 by Alien / ST CNX

; Comment: these routines are translated from the original. I have 
; not had time to test them again on a ST.

; Listing 1

; Program demonstrating that the GLUE
; controls the synchronisation signals
; in high and low resolutions. Uses
; the HBL interrupt (which is connected
; to the HBL signal of the GLUE)

            clr.l       -(a7)
            move.w      #$20, -(a7)     ; Super
            trap        #1
            addq.w      #6,a7

            clr.l       $FFFFFA06.w       ; Stop all MFP activity
            move.l      #HBL, $68.w
            move.l      #VBL, $70.w
            stop        #$2100

me:                                    ; This Program won't exit
            bra.s       me             ; So better save before you try it

HBL:
            lea         $FFFF8240.w, a0
            moveq       #7,d0
            move.l      d0,(a0)
            move.w      d0,(a0)
VBL:
            rte

            END

;                  _____________     __________________________
;                 _\____  ;\    |____\   ;|    \   ;|______  ;/\
;=============== |    ,    |    \   ;|____|    |    |    /____| \ ==============
;                |_________|_________|____|_________/_________|\|
;                \         \         \    \         \         \ |
;                 \_al!ve___\_________\____\_________\_____ltk_\|
;
;================= [m]   [a]   [g]   [a]   [z]   [i]   [n]   [e] ===============

; Overscan Techniques - Part II - Listing 2 by Alien / ST CNX

; Comment: these routines are translated from the original. I have
; not had time to test them again on a ST.

* Program demonstrating the Pseudo-Program
* horizontal of the Glue written by S.Short
* 1990/ST Mag. Written with the Turbo
* Assembler 1.6 (C) 1991 the author
* & Pressimage. All use for commercial or
* promotional purposes, direct or derived
* is forbidden without the written authorisation
* of the author. To use this in a public domain
* program specify the name of the author
* (S.Short or Alien of ST Connexion)

* HARDWARE ADDRESSES

Hbl             EQU $68                 ; HBL interrupt vector
Vbl             EQU $70                 ; VBL interrupt vector
Mfp_Port        EQU $FFFFFA01           ; I/O port of the MFP
Mfp_IER         EQU $FFFFFA06           ; MPF interrupt acknowledgement
Mfp_IMR         EQU $FFFFFA12           ; MPF interrupt mask
Glue_HZ         EQU $FFFF820A           ; Screen display frequency
Rez             EQU $FFFF8260           ; Screen resolution
Low_vid_count   EQU $FFFF8209           ; Video Counter LSB
Keyboard        EQU $FFFFFC02           ; Keyboard data

* RESOLUTION OF THE PROGRAM

Fifty_HZ        EQU 2
Sixty_HZ        EQU 0
Low             EQU 0
Mid             EQU 1
High            EQU 2
Chosen_R        EQU Low                 ; Chosen Resolution

                IFEQ (Chosen_R-High)&2
                FAIL
                ENDC

* INTERESTING POSITIONS

; A list of positions follows: the first number
; corresponds to Mono_1, the second to Mono_2 and so on.
; The added fourth and fifth timings correspond to the time taken
; by the routines that change the resolution of the display frequency.
; Changing the display frequency takes 4*4 cycles, or 4 nops.
; Changing the display resolution takes 5*4 cycles, or 5 nops.
; Note that the 0 byte line obtained by changing display frequency
; does not occur on some power-ups; and that the 0 byte line obtained
; by switching to high resolution distorts the picture on some monitors:
; change the height of line 6 to see this effect.
; Complete Overscan: 1,0,0,1,1,89,13,9,230,2
; Left Overscan:     1,0,0,0,0,89+13+9+5+4,0,0,186,0
; Right Overscan:    0,0,0,1,0,89+5,13+9+5,204,0
; 80 byte line:      1,1,0,0,0,35,89+13+9+4-35,80,0
; 54 byte line:      0,1,0,0,0,35+5,89+13+9+4-35,54,0
; Right Overscan2:   0,1,0,0,0,89+5,13+9+4,0,204,0  (Switching to monochrome)
; 0 byte overscan:   0,0,0,1,0,14,75+5+13+9+5+5,0,0,0 (Changing frequency)
; 0 byte overscan:   0,1,0,0,0,6,89+13+9+5+4-6,0,0,0 (Switching to monochrome)

Mono_1          EQU 1
Mono_2          EQU 0
Freq_1          EQU 0
Freq_2          EQU 1
Stabiliser      EQU 1
Position_1      EQU 89
Position_2      EQU 13
Position_3      EQU 9
Line_Length     EQU 230
Offset          EQU 2
Height          EQU 100-1

******************************

                TEXT

s:
                lea     s(PC),A6
                bsr     Super
                bsr     Save_State
                bsr     Test_STE
                bsr     Reset_Shifter
                move.w  #Chosen_R,D0
                bsr     Set_Resolution
                bsr     Init_Screen
                bsr.s   TEST_GLUE
                bsr     Reset_Shifter
                bsr     Restore_State
                bsr     Super
                clr.w   -(SP)              ; exit program
                trap    #1

* ROUTINE TESTING THE GLUE LINE BY LINE

TEST_GLUE:
                bsr.s   Init_IRQs
                moveq   #$39,D2
                bsr.s   Test_Keyboard
                rts

Test_Keyboard:
                moveq   #0,D1
Loop1:
                move.b  Keyboard.w,D0
                eor.b   D0,D1
                and.w   #$7F,D0
                cmp.b   D2,D0
                bne.s   Test_Keyboard
                tst.b   D1
                bne.s   Loop1
                rts

Init_IRQs:
                move.l  #Vbl_routine1,Vbl.w ; Wait one interrupt
                stop    #$2300
                move.l  #Vbl_routine2,Vbl.w ; The real routine
                rts
Vbl_routine1:
                rte

* MAIN TASK

Vbl_routine2:
                movem.l D0-D5/A0-A2,-(SP)
                lea     Rez.w,A0
                lea     Glue_HZ.w,A1
                lea     Low_vid_count.w,A2
                moveq   #High,D0
                moveq   #Chosen_R,D1
                moveq   #Fifty_HZ,D1
                moveq   #Sixty_HZ,D3
                move.w  #Height,D4
                move.w  #$0777,$FFFF8240.w
                clr.w   $FFFF8246.w
                clr.w   $FFFF825E.w

                OPT O-
Sync:
                move.b  (A2),D5            ; Wait until the video counter starts
                beq.s   Sync
                neg.w   D5                 ; Compensate for the elapsed time
                lsl.l   D5,D5              ; Wait the remaining time
                moveq   #22,D5
Wait:
                dbra    D5,Wait
                nop
                nop

; d0= value corresponding to high resolution
; d1= value corresponding to low resolution
; d2= value corresponding to 50 Hz
; d3= value corresponding to 60 Hz
; a0= Address of the hardware resolution register
; a1= Address of the hardware frequency register

Overscan:
                IFNE Mono_1
                move.b  D0,(A0)            ; Change resolution
                nop
                move.b  D1,(A0)
                ENDC
                IFNE Freq_1             ; OR Change frequency
                move.b  D3,(A1)
                move.b  D2,(A1)
                ENDC

                IFNE Position_1
                REPT Position_1
                nop                        ; Wait for position 2
                ENDR
                ENDC

                IFNE Mono_2
                move.b  D0,(A0)            ; Change resolution
                nop
                move.b  D1,(A0)
                ENDC
                IFNE Freq_2             ; OR Change frequency
                move.b  D3,(A1)
                move.b  D2,(A1)
                ENDC

                IFNE Position_2
                REPT Position_2
                nop                        ; Wait for position 3
                ENDR
                ENDC
                IFNE Stabiliser
                move.b  D0,(A0)
                nop                        ; Stabiliser
                move.b  D1,(A0)
                ENDC

                IFNE Position_3
                REPT Position_3
                nop                        ; Wait for the end of the line
                ENDR
                ENDC

                dbra    D4,Overscan

                OPT O+

                movem.l (SP)+,D0-D5/A0-A2
                rte


* INITIALISE THE SCREEN

Init_Screen:
                move.l  $FFFF8200.w,D0     ; Draws a line on the screen,
                lsl.w   #8,D0              ; the background allows one to
                movea.l D0,A0              ; see the image shifts.
                lea     22+Offset(A0),A1
                move.l  #$55550000,D0
                move.l  #$55550000*Chosen_R,D1
                move.l  #$FF00FF00,D3
                move.w  #32000/8-1,D2
Isloop1:
                cmpa.l  A0,A1
                bgt.s   Isloop2
                movea.l A1,A0
                move.l  D3,(A0)+
                move.l  D3,(A0)+
                lea     Line_Length(A1),A1
                bra.s   Isloop3
Isloop2:
                move.l  D0,(A0)+
                move.l  D1,(A0)+
Isloop3:
                dbra    D2,Isloop1
                rts

* TOGGLE USER/SUPERVISOR

Super:
                movea.l SP,A5              ; It's a subroutine, so we have to
                move.l  Stack-s(A6),-(SP)  ; return to the program...
;                                            I.e. restore the stack
                move.w  #$20,-(SP)
                trap    #1
                move.l  D0,Stack-s(A6)
                movea.l A5,SP
                rts

* SAVE AND RESTORE THE MFP REGISTERS AND VECTORS WE WILL CHANGE

Save_State:
                movea.l (SP)+,A5
                move    SR,-(SP)
                move.l  Mfp_IER.w,-(SP)    ; .L access 2 MFP registers at once
                move.l  Mfp_IMR.w,-(SP)
                move.l  Hbl.w,-(SP)
                move.l  Vbl.w,-(SP)
                move.b  Rez.w,-(SP)
                clr.l   Mfp_IER.w
                clr.l   Mfp_IMR.w
                move    #$2300,SR
                jmp     (A5)

Restore_State:
                movea.l (SP)+,A5
                move.b  (SP)+,D0
                bsr.s   Restore_Rez
                move.l  (SP)+,Vbl.w
                move.l  (SP)+,Hbl.w
                move.l  (SP)+,Mfp_IMR.w    ; Same comment !
                move.l  (SP)+,Mfp_IER.w
                move    (SP)+,SR
                jmp     (A5)

Restore_Rez:
                and.w   #3,D0             ; This routine tests whether the user has
;                                            reconnected his monochrome monitor
                btst    #1,D0              ; Wait to avoid resetting the
                beq.s   Not_Mono1          ; computer when leaving the program
Wait1:
                btst    #7,Mfp_Port.w
                bne.s   Wait1
Not_Mono1:

Set_Resolution:
                move.l  #Vbl_routine1,Vbl.w
                stop    #$2300
                move.b  D0,Rez.w
                rts

* RESET SHIFTER

Reset_Shifter:
                move.l  #Vbl_routine1,Vbl.w
                moveq   #5,D0
Reset2:
                move.b  #1,Rez.w
                stop    #$2300
                clr.b   Rez.w
                stop    #$2300
                dbra    D0,Reset2
                rts

* TEST STE

; The least significant byte of the screen base address must be set to zero for
; the program to be able to synchronise itself to the least significant byte of
; the video counter.

Test_STE:
                move.l  $FFFF8200.w,D0
                move.l  D0,$FFFF8200.w
                clr.b   $FFFF820D.w
                rts

Counter:
                DS.W 1
Stack:
                END
Alive 11