home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: Science
/
Science.zip
/
imdisp79.zip
/
DISPSUB.ASM
< prev
next >
Wrap
Assembly Source File
|
1992-11-29
|
15KB
|
517 lines
TITLE dispsub
; Assembly language subroutines for DISPDRIV module.
ifdef _286
.286
endif
DISPSUB_TEXT SEGMENT BYTE PUBLIC 'CODE'
DISPSUB_TEXT ENDS
DISPSUB_DATA SEGMENT WORD PUBLIC 'DATA'
DISPSUB_DATA ENDS
CONST SEGMENT WORD PUBLIC 'CONST'
CONST ENDS
_BSS SEGMENT WORD PUBLIC 'BSS'
_BSS ENDS
DGROUP GROUP CONST, _BSS, DISPSUB_DATA
ASSUME CS: DISPSUB_TEXT, DS: DGROUP, SS: DGROUP, ES: DGROUP
DISPSUB_DATA SEGMENT
DISPSUB_DATA ENDS
DISPSUB_TEXT SEGMENT
; EgaRegs is the address of what would be the beginning of a complete set
; of register tables. Since we are only using one particular mode, we don't
; allocate the entire set, but adjust EgaRegs backwards by the appropriate
; amount. (Note that the offset of EgaRegs may actually be a negative
; number. This does not cause any problem.)
EgaRegs equ $-(40h*18)
; Columns, rows, pixels, page size
db 80, 36, 14
dw 0B400h
; Sequencer registers
db 01h, 0Fh, 00h, 06h
; Miscellaneous output register
db 0ABh
; CRTC parameters
db 64h, 4Fh, 53h, 21h, 53h, 00h, 0F0h, 1Fh, 8 dup (00h)
db 0E0h, 2Ch, 0DFh, 28h, 0Fh, 0E1h, 0Ch, 0E3h, 0FFh
; Attribute registers
db 00h, 01h, 02h, 03h, 04h, 05h, 14h, 07h
db 38h, 39h, 3Ah, 3Bh, 3Ch, 3Dh, 3Eh, 3Fh
db 01h, 00h, 0Fh, 00h
; Graphics controller registers
db 00h, 00h, 00h, 00h, 00h, 00h, 05h, 0Fh, 0FFh
PUBLIC _putmem
_putmem PROC FAR
push bp
mov bp,sp
; segment = 4
; offset = 6
; value = 8
mov es, [bp+6] ;segment
mov bx,[bp+8] ;offset
mov ax,[bp+10] ;value
mov es:[bx],al
mov sp,bp
pop bp
ret
_putmem ENDP
PUBLIC _getmem
_getmem PROC FAR
push bp
mov bp,sp
; segment = 4
; offset = 6
mov es, [bp+6] ;segment
mov bx,[bp+8] ;offset
mov al,es:[bx]
sub ah,ah
mov sp,bp
pop bp
ret
_getmem ENDP
; int WritePixelEGA (line, samp, DN);
;
; WritePixelEGA displays a pixel on the EGA screen at the desired location.
;
; Parameters:
; line the line to display the pixel at (starts at 1)
; samp the sample to display the pixel at (starts at 1)
; DN the DN to write
;
; Registers:
; DI pointer to video memory (ES segment used)
; BL bit mask used to load pixels to bitplanes
;
; line = BP+6
; sample = BP+8
; DN = BP+10
PUBLIC _WritePixelEGA
_WritePixelEGA PROC FAR
PUSH BP
MOV BP, SP
PUSH DI
; Calculate the starting address in memory
; address := 80*(line-1) + (samp-1) shr 3;
MOV AX, [BP+6] ; get line parameter
DEC AX ; convert to start at 0 system
JL CLIP ; Abort if out of range
CMP AX, 479 ; EGA480
JG CLIP
MOV DI, AX
SHL DI, 1 ; multiply by 80
SHL DI, 1
ADD DI, AX
SHL DI, 1
SHL DI, 1
SHL DI, 1
SHL DI, 1
MOV AX, [BP+8] ; get samp parameter
DEC AX ; convert to start at 0 system
JL CLIP ; Abort if out of range
CMP AX, 639
JG CLIP
SHR AX, 1 ; divide it by 8
SHR AX, 1
SHR AX, 1
ADD DI, AX ; calculate the final memory offset
; and put in the video pointer
; Select Write Mode 2
MOV DX, 3CEH
MOV AL, 5
OUT DX, AL
MOV DX, 3CFH
MOV AL, 2
OUT DX, AL
MOV AX, 0A000H ; ES = EGA buffer segment address
MOV ES, AX
; Initialize bit mask
; mask = 0x80 >> ((samp-1) & 7);
MOV CX, [BP+8] ; get samp parameter
DEC CX
AND CX, 7
MOV BL, 80H ; shift bit over to start at the
SHR BL, CL ; right pixel
MOV DX, 3CEH
MOV AL, 8 ; Load the bit mask
OUT DX, AL
MOV DX, 3CFH
MOV AL, BL
OUT DX, AL
MOV AL, ES:[DI] ; Latch the bytes from each bitplane
MOV AX, [BP+10] ; Get the pixel value
MOV ES:[DI], AL ; Write the bytes back to the bitplanes
; Restore Write Mode 0
MOV DX, 3CEH
MOV AL, 5
OUT DX, AL
MOV DX, 3CFH
MOV AL, 0
OUT DX, AL
; Restore default bit mask
MOV DX, 3CEH
MOV AL, 8
OUT DX, AL
MOV DX, 3CFH
MOV AL, 0FFH
OUT DX, AL
CLIP:
POP DI
MOV SP,BP
POP BP
RET
_WritePixelEGA ENDP
; int DisplayLineEGA (buffer, line, samp, ns);
;
; DisplayLineEGA displays a line of pixels in a buffer on the EGA screen
; at the desired location.
;
; Parameters:
; buffer the buffer of bytes containing the pixels (nibbles) to
; be displayed
; line the line to display the pixels at (starts at 1)
; samp the sample to display the first pixel at (starts at 1)
; ns the number of samples to display
;
; Registers:
; DI pointer to video memory (ES segment used)
; SI pointer to pixel buffer (DS segment used)
; BL bit mask used to load pixels to bitplanes
; CX sample counter
;
; buffer = 6
; line = 8
; samp = 10
; ns = 12
PUBLIC _DisplayLineEGA
_DisplayLineEGA PROC FAR
PUSH BP
MOV BP, SP
PUSH DS
PUSH DI
PUSH SI
MOV AX, [BP+6] ; get segment of buffer
MOV DS, AX
MOV SI, [BP+8] ; get offset of buffer
; Calculate the starting address in memory
; address := 80*(line-1) + (samp-1) shr 3;
MOV AX, [BP+10] ; get line parameter
DEC AX ; convert to start at 0 system
MOV DX, 80 ; multiplying line by 80
MUL DX ;
MOV DX, [BP+12] ; get samp parameter
DEC DX ; convert to start at 0 system
SHR DX, 1 ; divide it by 8
SHR DX, 1
SHR DX, 1
ADD AX, DX ; calculate the final memory offset
MOV DI, AX ; and put in the video pointer
MOV AX, 0A000H ; ES = EGA buffer segment address
MOV ES, AX
; Select Write Mode 2
MOV DX, 3CEH
MOV AL, 5
OUT DX, AL
MOV DX, 3CFH
MOV AL, 2
OUT DX, AL
; Initialize bit mask
; mask := $80 shr ((samp-1) and 7);
MOV CX, [BP+12] ; get samp parameter
DEC CX
AND CX, 7
MOV BL, 80H ; shift bit over to start at the
SHR BL, CL ; right pixel
MOV CX, [BP+14] ; Start loop counter with ns parameter
MOV DX, 3CEH ; point DX to the right port
SAMPLOOP:
MOV AL, 8 ; Load the bit mask
OUT DX, AL
INC DX
MOV AL, BL
OUT DX, AL
DEC DX
MOV AL, ES:[DI] ; Latch the bytes from each bitplane
MOV AL, [SI] ; Get the nibble from the linebuf
MOV ES:[DI], AL ; Write the bytes back to the bitplanes
SHR BL, 1 ; shift the bit over in the bit mask
JNC ENDLOOP
; if the bit fell out the other end
MOV BL, 80H ; then move to the next byte in
INC DI ; video memory
ENDLOOP:
INC SI ; point to the next pixel
LOOP SAMPLOOP ; loop until all pixels are done
; Restore Write Mode 0
MOV DX, 3CEH
MOV AL, 5
OUT DX, AL
MOV DX, 3CFH
MOV AL, 0
OUT DX, AL
; Restore default bit mask
MOV DX, 3CEH
MOV AL, 8
OUT DX, AL
MOV DX, 3CFH
MOV AL, 0FFH
OUT DX, AL
POP SI
POP DI
POP DS
MOV SP,BP
POP BP
RET
_DisplayLineEGA ENDP
; int ClearDisplayEGA (DN,dispnl);
;
; ClearDisplayEGA sets the whole EGA screen to the DN pixel value
;
; Parameters:
; DN the pixel value to set the screen to
;
; Registers:
; DI pointer to video memory (ES segment used)
;
;
; DN = 6
PUBLIC _ClearDisplayEGA
_ClearDisplayEGA PROC FAR
PUSH BP
MOV BP, SP
PUSH DI
MOV AX, 0A000H ; ES = EGA buffer segment address
MOV ES, AX
; Select Write Mode 2
MOV DX, 3CEH
MOV AL, 5
OUT DX, AL
MOV DX, 3CFH
MOV AL, 2
OUT DX, AL
; Set bit mask to all bits on
MOV DX, 3CEH
MOV AL, 8
OUT DX, AL
MOV DX, 3CFH
MOV AL, 0FFH
OUT DX, AL
MOV AL, [BP+6] ; Get the pixel value
MOV DI, 0 ; Start at beginning of video memory
mov si, [BP+8]
cmp si,350 ; check for 350 or 480 line display
jne BYTE480
BYTELOOP:
MOV BL, ES:[DI] ; Latch the bytes from each bitplane
MOV ES:[DI], AL ; Write the bytes back to the bitplanes
INC DI ; point to the next byte
CMP DI, 28000 ; how many lines to clear
JNZ BYTELOOP ; loop until whole screen cleared
jmp RESTORE
BYTE480:
MOV BL, ES:[DI] ; Latch the bytes from each bitplane
MOV ES:[DI], AL ; Write the bytes back to the bitplanes
INC DI ; point to the next byte
CMP DI, 38400 ; how many lines to clear
JNZ BYTE480 ; loop until whole screen cleared
RESTORE:
; Restore Write Mode 0
MOV DX, 3CEH
MOV AL, 5
OUT DX, AL
MOV DX, 3CFH
MOV AL, 0
OUT DX, AL
POP DI
MOV SP,BP
POP BP
RET
_ClearDisplayEGA ENDP
PUBLIC _PGAsend
_PGAsend PROC FAR
; command = 6
; len = 8
PUSH BP
MOV BP, SP
PUSH SI
MOV AX, 0C600H
MOV ES, AX
MOV CX, [BP+8] ; put len in CX
MOV SI, [BP+6] ; get command array address in SI
WAIT1:
MOV BL, ES:[0300H] ; OutWritePtr
MOV AL, ES:[0301H] ; OutReadPtr
SUB AL, BL
DEC AL ; calculate numbytes
CMP AL, CL ; and compare it with len
JB WAIT1 ; wait until there's room in buffer
SUB BH, BH
OUTLOOP:
MOV AL, [SI] ; get the command byte
MOV ES:[BX], AL ; send it to the PGA
INC SI ; point to next command byte
INC BL ; increment the OutWritePtr
LOOP OUTLOOP ; loop until done all bytes
MOV ES:[0300H], BL ; save the OutWritePtr
POP SI
MOV SP, BP
POP BP
RET
_PGAsend ENDP
; Set640x480 puts an EGA card with a 24mhz feature adapter into 640x480
; graphics mode. Once the card in in the mode, pixels may be written using
; conventional EGA programming techniques. The only difference is there are
; more scan lines. (And there is only a single display page, not two.)
; The 24mhz feature adapter was described in the September 16, 1986 PC
; Magazine, page 298.
SaveTable equ 04A8h
SaveTableLen equ 7 ; Number of DWORDs in SaveTable
PUBLIC _EGAinit
_EGAinit PROC FAR
push ds
push es
push ax
push bx
push cx
xor ax, ax
mov es, ax
lds bx, es:SaveTable ; Get old save table
push ds ; Stash away for when we return
push bx
mov cx, SaveTableLen*2
add bx, SaveTableLen*4
SavePush: ; Make a copy of save table on stack
dec bx
dec bx
push [bx]
loop SavePush
mov bx, sp
mov ss:[bx], offset EgaRegs ; Point to our register set
mov ss:[bx+2], cs
CLI
mov es:SaveTable, bx ; Make our copy the active one
mov es:SaveTable+2, ss
STI
mov ax,0010h ; Set 640x480 color graphics
int 10h
CLI
add sp, SaveTableLen*4 ; Deallocate our copy from stack
pop es:SaveTable
pop es:SaveTable+2 ; Restore original save table
STI
pop cx
pop bx
pop ax
pop es
pop ds
ret
_EGAinit ENDP
DISPSUB_TEXT ENDS
END