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
|