SecondReality/GLENZ/VIDINIT.ASM
2017-09-24 01:45:36 +02:00

519 lines
12 KiB
NASM

SC_INDEX equ 3c4h ;Sequence Controller Index register
GC_INDEX equ 3ceh ;Graphics Controller Index register
CRTC_INDEX equ 3d4h ;CRT Controller Index register
MEMORY_MODE equ 4 ;Memory Mode register index in SC
UNDERLINE equ 14h ;Underline Location reg index in CRTC
MODE_CONTROL equ 17h ;Mode Control register index in CRTC
GRAPHICS_MODE equ 5 ;Graphics Mode register index in GC
MISCELLANEOUS equ 6 ;Miscellaneous register index in GC
hseq1 LABEL WORD ;0=start
dw 479 ;display enable end
dw 485 ;start vertical blank
dw 490 ;start vertical retrace
dw 500 ;end vertical retrace
dw 505 ;end vertical blank
dw 510 ;vertical total
dw 480+1 ;200/350/400/480=lines/monitor, +1=double scanning
hseq2 LABEL WORD ;0=start
dw 349 ;display enable end
dw 354 ;start vertical blank
dw 360+50 ;start vertical retrace
dw 375+100 ;end vertical retrace
dw 395+100 ;end vertical blank
dw 399+100 ;vertical total
tweak320x200 PROC NEAR
;
; First, go to normal 320x200 256-color mode, which is really a
; 320x400 256-color mode with each line scanned twice.
;
mov ax,0013h ;AH = 0 means mode set, AL = 13h selects
; 256-color graphics mode
int 10h ;BIOS video interrupt
mov dx,3c8h
mov al,0
out dx,al
inc dx
mov cx,768
reclr: out dx,al
loop reclr
;
; Change CPU addressing of video memory to linear (not odd/even,
; chain, or chain 4), to allow us to access all 256K of display
; memory. When this is done, VGA memory will look just like memory
; in modes 10h and 12h, except that each byte of display memory will
; control one 256-color pixel, with 4 adjacent pixels at any given
; address, one pixel per plane.
;
mov dx,SC_INDEX
mov al,MEMORY_MODE
out dx,al
inc dx
in al,dx
and al,not 08h ;turn off chain 4
or al,04h ;turn off odd/even
out dx,al
mov dx,GC_INDEX
mov al,GRAPHICS_MODE
out dx,al
inc dx
in al,dx
and al,not 10h ;turn off odd/even
out dx,al
dec dx
mov al,MISCELLANEOUS
out dx,al
inc dx
in al,dx
and al,not 02h ;turn off chain
out dx,al
;
; Tweak the mode to 320x200 256-color mode by scanning each
; line twice.
;
mov dx,CRTC_INDEX
mov al,9
; out dx,al
inc dx
; in al,dx
and al,not 5fh ;set maximum scan line = 0
OR AL,1
; out dx,al
dec dx
;
; Change CRTC scanning from doubleword mode to byte mode, allowing
; the CRTC to scan more than 64K of video data.
;
mov al,UNDERLINE
out dx,al
inc dx
in al,dx
and al,not 40h ;turn off doubleword
out dx,al
dec dx
mov al,MODE_CONTROL
out dx,al
inc dx
in al,dx
or al,40h ;turn on the byte mode bit, so memory is
; scanned for video data in a purely
; linear way, just as in modes 10h and 12h
out dx,al
ret
;
; First, go to normal 320x200 256-color mode, which is really a
; 320x400 256-color mode with each line scanned twice.
;
mov ax,0013h ;AH = 0 means mode set, AL = 13h selects
; 256-color graphics mode
int 10h ;BIOS video interrupt
;
; Change CPU addressing of video memory to linear (not odd/even,
; chain, or chain 4), to allow us to access all 256K of display
; memory. When this is done, VGA memory will look just like memory
; in modes 10h and 12h, except that each byte of display memory will
; control one 256-color pixel, with 4 adjacent pixels at any given
; address, one pixel per plane.
;
mov dx,SC_INDEX
mov al,MEMORY_MODE
out dx,al
inc dx
in al,dx
and al,not 08h ;turn off chain 4
or al,04h ;turn off odd/even
out dx,al
mov dx,GC_INDEX
mov al,GRAPHICS_MODE
out dx,al
inc dx
in al,dx
and al,not 10h ;turn off odd/even
out dx,al
dec dx
mov al,MISCELLANEOUS
out dx,al
inc dx
in al,dx
and al,not 02h ;turn off chain
out dx,al
mov dx,SC_INDEX
mov ax,00f02h ;CLEAR ALL PLANES
out dx,ax
;mov ax,cs:vram
;mov es,ax
;mov cx,32768
;xor ax,ax
;rep stosw
;
; Tweak the mode to 320x200 256-color mode by scanning each
; line twice.
;
mov dx,CRTC_INDEX
mov al,9
out dx,al
inc dx
in al,dx
and al,not 5fh ;set maximum scan line = 0
OR AL,1
out dx,al
dec dx
;
; Change CRTC scanning from doubleword mode to byte mode, allowing
; the CRTC to scan more than 64K of video data.
;
mov al,UNDERLINE
out dx,al
inc dx
in al,dx
and al,not 40h ;turn off doubleword
out dx,al
dec dx
mov al,MODE_CONTROL
out dx,al
inc dx
in al,dx
or al,40h ;turn on the byte mode bit, so memory is
; scanned for video data in a purely
; linear way, just as in modes 10h and 12h
out dx,al
mov dx,CRTC_INDEX
mov ax,2813h
out dx,ax ;width>=320
ret
tweak320x200 ENDP
sethseq PROC NEAR ;ds:si=hseq
mov bl,1fh ;overflow
mov bh,40h ;maximum scan line
test word ptr ds:[si+12],1
jz sss9
or bh,80h
sss9:
mov ax,ds:[si+0]
test ax,256
jz sss3
or bl,2
sss3: test ax,512
jz sss4
or bl,64
sss4: mov ah,al
mov dx,3d4h
mov al,12h
out dx,ax
mov ax,ds:[si+2]
test ax,256
jz sss1
or bl,8
sss1: test ax,512
jz sss2
or bh,32
sss2: mov ah,al
mov dx,3d4h
mov al,15h
out dx,ax
mov ax,ds:[si+4]
test ax,256
jz sss7
or bl,4
sss7: test ax,512
jz sss8
or bl,128
sss8: mov ah,al
mov dx,3d4h
mov al,10h
out dx,ax
mov ax,ds:[si+6]
mov ah,al
and ah,15
or ah,20h ;disable vertical int
mov dx,3d4h
mov al,11h
out dx,ax
mov ax,ds:[si+8]
mov ah,al
mov dx,3d4h
mov al,16h
out dx,ax
mov ax,ds:[si+10]
test ax,256
jz sss5
or bl,1
sss5: test ax,512
jz sss6
or bl,32
sss6: mov ah,al
mov dx,3d4h
mov al,6h
out dx,ax
mov dx,3d4h
mov al,7h
mov ah,bl
out dx,ax
mov dx,3d4h
mov al,9h
mov ah,bh
out dx,ax
mov ax,ds:[si+12]
and ax,not 1
mov bh,0
cmp ax,350
jne sss10
mov bh,1*64
sss10: cmp ax,400
jne sss11
mov bh,2*64
sss11: cmp ax,480
jne sss12
mov bh,3*64
sss12: mov dx,3cch
in al,dx
and al,3fh
or al,bh
mov dx,3c2h
out dx,al
ret
sethseq ENDP
vptbl dw 06a00h ; horz total
dw 05901h ; horz displayed
dw 05a02h ; start horz blanking
dw 08d03h ; end horz blanking
dw 05e04h ; start h sync
dw 08a05h ; end h sync
dw 08b06h ;0d06h ; vertical total
dw 01f07h ;03e07h ; overflow
dw 04009h ; cell height
dw 06810h ; v sync start
dw 02a11h ; v sync end and protect cr0-cr7
dw 05d12h ; vertical displayed
dw 02e13h ; offset 92
dw 00014h ; turn off dword mode
dw 05d15h ; v blank start
dw 00016h ; v blank end
dw 0e317h ; turn on byte mode
vpend label word
mode13x proc
push ds
mov ax,cs
mov ds,ax
mov ax,13h ; start with standard mode 13h
int 10h ; let the bios set the mode
mov dx,3c4h ; alter sequencer registers
mov ax,0604h ; disable chain 4
out dx,ax
mov ax,0f02h ; set write plane mask to all bit planes
out dx,ax
push di
xor di,di
mov ax,0a000h ; screen starts at segment A000
mov es,ax
mov cx,21600 ; ((XSIZE*YSIZE)/(4 planes))/(2 bytes per word)
xor ax,ax
cld
rep stosw ; clear the whole of the screen
pop di
mov ax,0100h ; synchronous reset
out dx,ax ; asserted
mov dx,3c2h ; misc output
mov al,0a7h ; use 28 mHz dot clock ;a7
out dx,al ; select it
mov dx,3c4h ; sequencer again
mov ax,0300h ; restart sequencer
out dx,ax ; running again
mov dx,3d4h ; alter crtc registers
mov al,11h ; cr11
out dx,al ; current value
inc dx ; point to data
in al,dx ; get cr11 value
and al,7fh ; remove cr0 -> cr7
out dx,al ; write protect
dec dx ; point to index
cld
mov si,offset vptbl
mov cx,((offset vpend)-(offset vptbl)) shr 1
outlp: lodsw
out dx,ax
loop outlp
mov ax,cs
mov ds,ax
mov si,OFFSET hseq2
call sethseq
; mov dx,3dah
; in al,dx
; mov dx,3c0h
; mov al,11h+32
; out dx,al
; mov al,8
; out dx,al
pop ds
ret
mode13x endp
tweak640x400 PROC NEAR
;
; First, go to normal 320x200 256-color mode, which is really a
; 320x400 256-color mode with each line scanned twice.
;
mov ax,002fh
int 10h ;BIOS video interrupt
;
; Change CPU addressing of video memory to linear (not odd/even,
; chain, or chain 4), to allow us to access all 256K of display
; memory. When this is done, VGA memory will look just like memory
; in modes 10h and 12h, except that each byte of display memory will
; control one 256-color pixel, with 4 adjacent pixels at any given
; address, one pixel per plane.
;
mov dx,SC_INDEX
mov al,MEMORY_MODE
out dx,al
inc dx
in al,dx
and al,not 08h ;turn off chain 4
or al,04h ;turn off odd/even
out dx,al
mov dx,GC_INDEX
mov al,GRAPHICS_MODE
out dx,al
inc dx
in al,dx
and al,not 10h ;turn off odd/even
out dx,al
dec dx
mov al,MISCELLANEOUS
out dx,al
inc dx
in al,dx
and al,not 02h ;turn off chain
out dx,al
ret
;
; Change CRTC scanning from doubleword mode to byte mode, allowing
; the CRTC to scan more than 64K of video data.
;
mov al,UNDERLINE
out dx,al
inc dx
in al,dx
and al,not 40h ;turn off doubleword
out dx,al
dec dx
mov al,MODE_CONTROL
out dx,al
inc dx
in al,dx
or al,40h ;turn on the byte mode bit, so memory is
; scanned for video data in a purely
; linear way, just as in modes 10h and 12h
out dx,al
ret
tweak640x400 ENDP
hseq3 LABEL WORD ;0=start
dw 349 ;display enable end
dw 355 ;start vertical blank
dw 395 ;start vertical retrace
dw 405 ;end vertical retrace
dw 445 ;end vertical blank
dw 455 ;vertical total
dw 350 ;200/350/400/480=lines/monitor, +1=double scanning
tweak360x350 proc
push ds
mov ax,cs
mov ds,ax
mov ax,13h ; start with standard mode 13h
int 10h ; let the bios set the mode
mov dx,3c4h ; alter sequencer registers
mov ax,0604h ; disable chain 4
out dx,ax
mov ax,0f02h ; set write plane mask to all bit planes
out dx,ax
push di
xor di,di
mov ax,0a000h ; screen starts at segment A000
mov es,ax
mov cx,21600 ; ((XSIZE*YSIZE)/(4 planes))/(2 bytes per word)
xor ax,ax
cld
rep stosw ; clear the whole of the screen
pop di
mov ax,0100h ; synchronous reset
out dx,ax ; asserted
mov dx,3c2h ; misc output
mov al,0a7h ; use 28 mHz dot clock
out dx,al ; select it
mov dx,3c4h ; sequencer again
mov ax,0300h ; restart sequencer
out dx,ax ; running again
mov dx,3d4h ; alter crtc registers
mov al,11h ; cr11
out dx,al ; current value
inc dx ; point to data
in al,dx ; get cr11 value
and al,7fh ; remove cr0 -> cr7
out dx,al ; write protect
dec dx ; point to index
cld
mov si,offset vptbl
mov cx,((offset vpend)-(offset vptbl)) shr 1
outlpn: lodsw
out dx,ax
loop outlpn
mov ax,cs
mov ds,ax
mov si,OFFSET hseq3
call sethseq
pop ds
ret
tweak360x350 endp
hseq4 LABEL WORD ;0=start
dw 349 ;display enable end
dw 355 ;start vertical blank
dw 395 ;start vertical retrace
dw 405 ;end vertical retrace
dw 450 ;end vertical blank
dw 455 ;vertical total
dw 350 ;200/350/400/480=lines/monitor, +1=double scanning
tweak320x350 proc
call tweak360x350
ret
tweak320x350 endp