home *** CD-ROM | disk | FTP | other *** search
- ; pchcfunc.asm
- ;
- ; 11/10/88 by Ted
- ;
- ; Low Level RAM functions for Cscape Hercules Graphics support
- ;
- ; Copyright (c) 1988, 1989 Oakland Group Inc.
- ; ALL RIGHTS RESERVED
- ;
- ; This file contains the low level routines used by display code
- ; to talk to the Hercules Display Card
- ;
- ;------------------------REVISION HISTORY--------------------------------------;
- ;
- ;------------------------------------------------------------------------------;
- include PCDECL.MAC
-
- DOS_DATA_PAGE equ 40h
- ADDR_6845 equ 63h
-
- DSEG
-
- crtcparms label word
- db 00h, 35h
- db 01h, 2Dh
- db 02h, 2Eh
- db 03h, 07h
-
- db 04h, 5Bh
- db 05h, 02h
- db 06h, 57h
- db 07h, 57h
-
- db 09h, 03h
-
- CRTCPARMSLEN equ ($-crtcparms)/2
- ;---------
- BIOSDATAOFFS equ 49h
-
- biosdata label byte
- db 7 ; crt_mode
- dw 80 ; crt_cols
- dw 8000h ; crt_len
- dw 0 ; crt_start
- dw 8 dup(0) ; cursor_posn
- dw 0 ; cursor_mode
- db 0 ; active_page
- dw 3B4h ; addr_6845
- db 0Ah ; crt_mode_set (val for 6845 mode control register)
- db 0 ; crt_palette (unused)
-
- BIOSDATALEN equ $-biosdata
-
- ENDDS
- ;------------------------------------------------------------------------------;
- retrace_wait macro ;wait for video retrace
- local L01, L02, L03 ;uses dx for crt port address, trashes al
- ; leaves interrupts disabled
- L01:
- in al, dx ; wait for start of retrace
- test al, 80h
- jnz L01
- L02:
- in al, dx ; wait for end of retrace
- test al, 80h
- jz L02
-
- cli
- L03:
- in al, dx ; wait for start of retrace
- test al, 80h
- jnz L03
- endm
- ;------------------------------------------------------------------------------;
- PSEG
- ;------------------------------------------------------------------------------;
- ; boolean herc_present();
- ;------------------------
- pubproc DIGPRIV herc_present
- mov dx, 03BAh ; dx = crt status port
- xor bl, bl ; clear counter
- in al, dx ; first reading
- and al, 80h ; clear all but high bit
- mov ah, al ; save value in ah
-
- mov cx, 8000h ; test this many times
- testchange:
- in al, dx ; get second reading
- and al, 80h ; clear all but high bit
- cmp al, ah ; if no change, keep testing
- je nochange
- inc bl ; wait for 25 positives
- cmp bl, 25
- ja gotit ; got 25 positives; quit
- nochange:
- loop testchange
- mov ax, 0 ; didn't get 25 out of 8000h; fail
- jmp short endtest
- gotit:
- mov ax, 1
- endtest:
- ret
- endproc herc_present
- ;------------------------------------------------------------------------------;
- ;/*
- ; Returns the approximate number of video lines the Herc is currently
- ; displaying. For herc modes, the possible targets are:
- ; 7D0h - 80x25 text
- ; DB6h - 90x39 text
- ; DC0h - 80x44 text
- ; F4Bh - 720x348 graphics
- ;*/
- ; int herc_getlines();
- ;------------------------
- pubproc DIGPRIV herc_getlines
- ;---------
- ; reset light pen latch
- mov dx, 03BBh ; dx = light pen reset port
- out dx, al ; clear the latch (al don't care)
-
- ; wait for start of next retrace
- dec dx ; dx = 03BAh (crt status port)
- retrace_wait
-
- ; latch the current crtc address counter in the light pen registers
- dec dx ; dx = 03B9h (latch load port)
- out dx, al
- sti
-
- ; return the value in the light pen registers
- mov dx, 03B4h ; dx = crtc address port
- mov al, 10h ; al = light pen high register index
- out dx, al
- inc dx
- in al, dx ; read the register
- mov ah, al
- dec dx
- mov al, 11h ; al = light pen low register index
- out dx, al
- inc dx
- in al, dx ; read the register
-
- ;---------
- ; ax now has the current light pen latch value, i.e. the value of the
- ; crtc address counter at start of vertical retrace.
- ret
- endproc herc_getlines
- ;------------------------------------------------------------------------------;
- ; void herc_setgmode(int hpage);
- ;------------------------
- pubproc DIGPRIV herc_setgmode <hpage>
- push bp
- mov bp,sp
- pushm <ds, es, di, si>
- ;---------
- mov bx, 0A01h ; mode control bit for page 0, config switch bit for page 0
- mov cl, 6 ; set vidmode 6 for page 0
- cmp word ptr [bp].hpage, 0
- jz page0
- mov bx, 8A03h ; mode control bit for page 1, config switch bit for page 1
- mov cl, 5 ; set vidmode 5 for page 1
- page0:
-
- ; update bios data area
- mov ax, DOS_DATA_PAGE
- mov es, ax
- mov di, BIOSDATAOFFS
-
- IF FAR_DATA
- mov ax, seg DGROUP:biosdata
- mov ds, ax
- ENDIF
- mov si, offset DGROUP:biosdata
- mov ds:[si], cl ; poke the vidmode: 6 for page 0, 5 for page 1
- mov cx, BIOSDATALEN
- rep movsb
-
- ; set configuration switch
- mov dx, 3BFh ; dx = configuration switch port
- mov al, bl ; al bit 0 = 1 means enable graphics
- out dx, al ; al bit 1 = 0 means only use first 32k of video buffer
-
- ; blank the screen while programming crtc
- mov dx, 3B8h ; dx = mode control register
- xor al, al ; al bit 3 = 0 means disable video signal
- out dx, al ; blank the screen
-
- ; program the crtc
- sub dl, 4 ; dx = 3B4h = crtc index register
- mov si, offset DGROUP:crtcparms
- mov cx, CRTCPARMSLEN
- putout:
- lodsw
- out dx, ax
- loop putout
-
- ; wipe video buffer
- mov ax, 0B000h
- cmp word ptr [bp].hpage, 0
- jz wpage0
- mov ax, 0B800h
- wpage0:
- mov es, ax
- mov ax, 0
- mov di, 0
- mov cx, 4000h
- rep stosw
-
- ; set graphics mode
- add dl, 4 ; dx = 3B8h = mode control register
- mov al, bh ; bit3 = 1 means enable video, bit1 = 1 means graphics mode
- out dx, al ; bit7 = 1 means page 1
-
- ;---------
- popm <si, di, es, ds>
- pop bp
- ret
- endproc herc_setgmode
- ;------------------------------------------------------------------------------;
- ; void herc_settmode();
- ;------------------------
- pubproc DIGPRIV herc_settmode
- mov ax, 0007h
- int 10h
-
- ; set configuration switch
- mov dx, 3BFh ; dx = configuration switch port
- mov al, 0 ; al bit 0 = 0 means disable graphics
- out dx, al ; al bit 1 = 0 means disable second graphics page
- ret
- endproc herc_settmode
- ;------------------------------------------------------------------------------;
- ENDPS
- end
- ;------------------------------------------------------------------------------;
-