home *** CD-ROM | disk | FTP | other *** search
- TITLE dispsub
-
- ; Assembly language subroutines for DISPDRIV module.
-
-
- 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
-