AccartocciAlfa":1jvq497m ha detto:
:cry:
e ma io sono un piccolo figlio irsuto della della Dea ignoranza... :baby)
mov cx,dx
add cx
sub cubo
int 12
bleeeeeee :tippen) ... diciamo che nn è il max.. preferisco fare l'utente microsoft e trovare gia tutto pronto e fatto!!!! :culo)
ehehehhe
volevi forse dire...
IDEAL
INCLUDE "model.mac" ; Memory model macros
header svga ; Set up memory model
CRTC EQU 3D4h ; Port of CRTC registers
begdataseg svga
$EXTRN _maxx,INTEGER
$EXTRN _maxy,INTEGER
$EXTRN _maxcolor,DWORD
$EXTRN _bytesperline,WORD
$EXTRN _pagesize,DWORD
$EXTRN _curBank,INTEGER
$EXTRN _bankSwitch,DWORD
$EXTRN _extendedflipping,BOOL
$EXTRN _bankAdjust,INTEGER
$EXTRN _writeBank,DWORD ; Relocated write bank routine
$EXTRN _readBank,DWORD ; Relocated read bank routine
$EXTRN _screenPtr,DWORD ; Start of display memory
OriginOffset dw 0 ; Offset within video buffer
BankOffset dw 0 ; Starting bank in video memory
enddataseg svga
begcodeseg svga
;----------------------------------------------------------------------------
; void putPixel16(int x,int y,long color)
;----------------------------------------------------------------------------
; Routine sets the value of a pixel in native VGA graphics modes.
;
; Entry: x - X coordinate of pixel to draw
; y - Y coordinate of pixel to draw
; color - Color of pixel to draw
;
;----------------------------------------------------------------------------
procstart __putPixel16
ARG x:INTEGER, y:INTEGER, color
WORD
enter_c 0
; Compute the pixel's address in video buffer
mov ax,[y]
mov bx,[x]
mul [_bytesperline] ; DX:AX := y * BytesPerLine
mov cl,bl ; CL := low-order byte of x
shr bx,3 ; _BX := x/8
add bx,ax
adc dx,0 ; DX:BX := y*BytesPerLine + x/8
add bx,[OriginOffset] ; DX:BX := byte offset in video buffer
adc dx,[BankOffset]
cmp dl,[BYTE _curBank]
je @@NoChange
mov ax,dx
call setBank
@@NoChange:
mov es,[WORD _screenPtr+2]
mov ah,1 ; AH := unshifted bit mask
and cl,7 ; CL := x & 7
xor cl,7 ; CL := # bits to shift left
; set Graphics Controller Bit Mask register
shl ah,cl ; AH := bit mask in proper postion
mov dx,3CEh ; GC address register port
mov al,8 ; AL := Bit Mask Register number
out dx,ax
; set Graphics Controller Mode register
mov ax,0205h ; AL := Mode register number
; AH := Write mode 2 (bits 0,1)
; Read mode 0 (bit 3)
out dx,ax
; set data rotate/Function Select register
mov ax,3 ; AL := Data Rotate/Func select reg #
out dx,ax
; set the pixel value
mov al,[es] ; latch one byte from each bit plane
mov al,[BYTE color] ; AL := pixel value
mov [es],al ; update all bit planes
; restore default Graphics Controller registers
mov ax,0FF08h ; default bit mask
out dx,ax
mov ax,0005 ; default mode register
out dx,ax
mov ax,0003 ; default function select
out dx,ax
leave_c
ret
procend __putPixel16
;----------------------------------------------------------------------------
; void putPixel256(int x,int y,long color)
;----------------------------------------------------------------------------
; Routine sets the value of a pixel in native VGA graphics modes.
;
; Entry: x - X coordinate of pixel to draw
; y - Y coordinate of pixel to draw
; color - Color of pixel to draw
;
;----------------------------------------------------------------------------
procstart __putPixel256
ARG x:INTEGER, y:INTEGER, color
WORD
enter_c 0
mov ax,[y]
mul [_bytesperline]
add ax,[WORD x]
adc dx,0 ; DX:AX := y * BytesPerLine + x
add ax,[OriginOffset]
adc dl,[BYTE BankOffset]; DL := bank number
mov bx,ax ; BX := Offset in buffer
cmp dl,[BYTE _curBank]
je @@NoChange
mov ax,dx
call setBank
@@NoChange:
mov es,[WORD _screenPtr+2]
mov al,[BYTE color]
mov [es],al ; Replace the pixel
leave_c
ret
procend __putPixel256
;----------------------------------------------------------------------------
; void putPixel32k(int x,int y,long color)
;----------------------------------------------------------------------------
; Routine sets the value of a pixel in native VGA graphics modes.
;
; Entry: x - X coordinate of pixel to draw
; y - Y coordinate of pixel to draw
; color - Color of pixel to draw
;
;----------------------------------------------------------------------------
procstart __putPixel32k
ARG x:INTEGER, y:INTEGER, color
WORD
enter_c 0
mov ax,[y]
mul [_bytesperline]
mov bx,[x]
shl bx,1
add ax,bx
adc dx,0 ; DX:AX := y * BytesPerLine + x * 2
add ax,[OriginOffset]
adc dl,[BYTE BankOffset]; DL := bank number
mov bx,ax ; BX := Offset in buffer
cmp dl,[BYTE _curBank]
je @@NoChange
mov al,dl
call setBank
@@NoChange:
mov es,[WORD _screenPtr+2]
mov ax,[WORD color]
mov [es],ax ; Replace the pixel
leave_c
ret
procend __putPixel32k
procstart __putPixel32k640
ARG x:INTEGER, y:INTEGER, color
WORD
enter_c 0
movzx eax,[y]
mov bx,[x]
mov edx,eax
shl eax,10
shl edx,8
add edx,eax
shl bx,1
mov ax,dx
shr edx,16
add ax,bx
adc dx,0 ; DX:AX := y * BytesPerLine + x * 2
add ax,[OriginOffset]
adc dl,[BYTE BankOffset]; DL := bank number
mov bx,ax ; BX := Offset in buffer
cmp dl,[BYTE _curBank]
je @@NoChange
mov al,dl
call setBank
@@NoChange:
mov es,[WORD _screenPtr+2]
mov ax,[WORD color]
mov [es],ax ; Replace the pixel
leave_c
ret
procend __putPixel32k640
;----------------------------------------------------------------------------
; void putPixel16m(int x,int y,long color)
;----------------------------------------------------------------------------
; Routine sets the value of a pixel in native VGA graphics modes.
;
; Entry: x - X coordinate of pixel to draw
; y - Y coordinate of pixel to draw
; color - Color of pixel to draw
;
;----------------------------------------------------------------------------
procstart __putPixel16m
ARG x:INTEGER, y:INTEGER, color
WORD
enter_c 0
mov ax,[y]
mul [_bytesperline]
mov bx,[x]
add ax,bx
adc dx,0
shl bx,1
add ax,bx
adc dx,0 ; DX:AX := y * BytesPerLine + x * 3
add ax,[OriginOffset]
adc dl,[BYTE BankOffset]; DL := bank number
mov bx,ax ; BX := Offset in buffer
cmp dl,[BYTE _curBank]
je @@NoChange
mov al,dl
call setBank
@@NoChange:
mov es,[WORD _screenPtr+2]
mov al,[BYTE color]
mov [es],al ; Replace the first byte
cmp bx,0FFFFh
jne @@NotSplit1
; Arrghh!! We have a case where a single pixel can be split across a
; bank boundary, if the bytes per line value is 1920. This can cause the
; machine to hang (and produce strange pixels).
inc dl
mov al,dl
call setBank ; Change video banks
@@NotSplit1:
mov al,[BYTE color+1]
mov [es:bx+1],al ; Replace the middle
cmp bx,0FFFEh
jne @@NotSplit2
inc dl
mov al,dl
call setBank ; Change video banks
@@NotSplit2:
mov al,[BYTE color+2]
mov [es:bx+2],al ; Replace the last byte
leave_c
ret
procend __putPixel16m
;----------------------------------------------------------------------------
; void clear16(void)
;----------------------------------------------------------------------------
; Routine to clear the screen. Works even if the display contains more than
; one bank, so will work for 1024x768 and 1280x1024 video modes.
;----------------------------------------------------------------------------
procstart __clear16
enter_c 0
; Setup graphics controller
mov dx,3CEh ; DX := Graphics Controller I/O port
mov ah,0 ; AH := Background color
xor al,al ; AL := 0 (Set/Reset register number)
out dx,ax ; load set/reset register
mov ax,0F01h ; AH := 1111b (mask for Enable set/reset)
; AL := 1 (enable Set/reset reg number)
out dx,ax ; load enable set/reset reg
mov ax,[_maxy]
inc ax
mul [_bytesperline] ; DX:AX := number of bytes to fill
mov bx,ax ; BX := bytes in last bank to fill
mov dh,dl ; DH := number of full banks to fill
les di,[_screenPtr] ; ES
I -> start of video buffer
add di,[OriginOffset]
xor ax,ax
mov ax,[BankOffset] ; AX := starting bank number
cld ; Moves go up in memory
or dh,dh ; More than one bank to fill?
jz @@SingleBank ; No, only fill a single bank
; Fill all of the full 64k banks first
@@OuterLoop:
push di
call setBank
mov cx,4000h ; Need to set 4000h double words per bank
rep stosd
pop di
inc al
dec dh
jnz @@OuterLoop
; Now fill the last partial bank
@@SingleBank:
call setBank
xor cx,cx
mov cx,bx
shr cx,2 ; _CX := number of double words to set
rep stosd
; Restore graphics controller
mov dx,3CEh ; DX := Graphics Controller I/O port
xor ax,ax ; AH := 0, AL := 0
out dx,ax ; Restore default Set/Reset register
inc ax ; AH := 0, AL := 1
out dx,ax ; Restore enable Set/Reset register
leave_c
ret
procend __clear16
;----------------------------------------------------------------------------
; void clear256(void)
;----------------------------------------------------------------------------
; Routine to clear the screen. Assumes pages begin on bank boundaries
; for simplicity of coding.
;----------------------------------------------------------------------------
procstart __clear256
enter_c 0
mov ax,[_maxy]
inc ax
mul [_bytesperline] ; DX:AX := number of bytes to fill
mov bx,ax ; BX := bytes in last bank to fill
mov dh,dl ; DH := number of full banks to fill
les di,[_screenPtr] ; ES
I -> video buffer
add di,[OriginOffset]
mov dl,[BYTE BankOffset]; DL := starting bank number
cld ; Moves go up in memory
or dh,dh ; More than one bank to fill?
jz @@SingleBank ; No, only fill a single bank
; Fill all of the full 64k banks first
@@OuterLoop:
push di
mov al,dl
call setBank
xor eax,eax ; Clear to black
mov cx,4000h ; Need to set 4000h double words per bank
rep stosd
pop di
inc dl
dec dh
jnz @@OuterLoop
; Now fill the last partial bank
@@SingleBank:
mov al,dl
call setBank
xor eax,eax ; Clear to black
xor cx,cx
mov cx,bx
shr cx,2 ; _CX := number of double words to set
rep stosd
leave_c
ret
procend __clear256
;----------------------------------------------------------------------------
; void clear32k(void)
;----------------------------------------------------------------------------
; Routine to clear the screen. Assumes pages begin on bank boundaries
; for simplicity of coding.
;----------------------------------------------------------------------------
procstart __clear32k
enter_c 0
mov ax,[_maxy]
inc ax
mul [_bytesperline] ; DX:AX := number of bytes to fill
mov bx,ax ; BX := bytes in last bank to fill
mov dh,dl ; DH := number of full banks to fill
les di,[_screenPtr] ; ES
I -> video buffer
add di,[OriginOffset]
mov dl,[BYTE BankOffset]; DL := starting bank number
cld ; Moves go up in memory
; Fill all of the full 64k banks first
@@OuterLoop:
push di
mov al,dl
call setBank
xor eax,eax ; Clear to black
mov cx,4000h ; Need to set 4000h double words per bank
rep stosd
pop di
inc dl
dec dh
jnz @@OuterLoop
; Now fill the last partial bank
mov al,dl
call setBank
xor eax,eax ; Clear to black
xor cx,cx
mov cx,bx
shr cx,2 ; _CX := number of double words to set
rep stosd
leave_c
ret
procend __clear32k
;----------------------------------------------------------------------------
; void clear16m(void)
;----------------------------------------------------------------------------
; Routine to clear the screen. Assumes pages begin on bank boundaries
; for simplicity of coding.
;----------------------------------------------------------------------------
procstart __clear16m
enter_c 0
mov ax,[_maxy]
inc ax
mul [_bytesperline] ; DX:AX := number of bytes to fill
mov bx,ax ; BX := bytes in last bank to fill
mov dh,dl ; DH := number of full banks to fill
les di,[_screenPtr] ; ES
I -> video buffer
add di,[OriginOffset]
mov dl,[BYTE BankOffset]; DL := starting bank number
cld ; Moves go up in memory
; Fill all of the full 64k banks first
@@OuterLoop:
push di
mov al,dl
call setBank
xor eax,eax ; Clear to black
mov cx,4000h ; Need to set 4000h double words per bank
rep stosd
pop di
inc dl
dec dh
jnz @@OuterLoop
; Now fill the last partial bank
mov al,dl
call setBank
xor eax,eax ; Clear to black
xor cx,cx
mov cx,bx
shr cx,2 ; _CX := number of double words to set
rep stosd
leave_c
ret
procend __clear16m
;----------------------------------------------------------------------------
; void setActivePage(int which)
;----------------------------------------------------------------------------
; Routine to set the video page for active output.
;
; Entry: page - Page number of page to use
;
;----------------------------------------------------------------------------
procstart _setActivePage
ARG which:INTEGER
enter_c 0
; Calculate 18 bit address of page in video memory
xor eax,eax
mov ax,[which] ; EAX := page number
mul [_pagesize] ; EDX:EAX := result
mov [OriginOffset],ax ; Save video buffer offset
shr eax,16
mov [BankOffset],ax ; Save video bank offset
leave_c
ret
procend _setActivePage
;----------------------------------------------------------------------------
; void setVisualPage(int which)
;----------------------------------------------------------------------------
; Routine to set the visible video page.
;
; Entry: page - Page number of page to use
;
;----------------------------------------------------------------------------
procstart _setVisualPage
ARG which:INTEGER
enter_c 0
; Calculate 18 bit address of page in video memory
xor eax,eax
mov ax,[which] ; EAX := page number
mul [_pagesize] ; EAX := starting address in memory
mov edx,eax
shr edx,16 ; DX:AX := starting address in memory
cmp [_extendedflipping],0
je @@VGAFlip ; We have no extended page flipping
div [_bytesperline] ; AX := starting scanline,
; DX := starting byte
mov cx,dx
cmp [WORD _maxcolor],0Fh
je @@16Color
cmp [WORD _maxcolor],0FFh
je @@SetIt
cmp [WORD _maxcolor+2],0FFh
je @@16MColor
shr cx,1 ; CX := starting pixel in buffer
jmp @@SetIt
@@16Color:
shl cx,3 ; CX := starting pixel in buffer
jmp @@SetIt
@@16MColor:
mov bx,ax ; Preserve AX
xor dx,dx
mov ax,cx
mov cx,3
div cx
mov cx,ax ; CX := starting pixel in buffer
mov ax,bx ; Restore AX
@@SetIt:
mov bx,ax ; BX := starting scanline in buffer
; Wait for display enable to be active (active low), to be sure that
; both halves of the start address will take place in one frame.
mov dx,03DAh ; DX := video status port
@@WaitDEVBE:
in al,dx
test al,1
jnz @@WaitDEVBE ; Wait for Display Enable
mov ax,04F07h
mov dx,bx ; DX := starting scanline number
xor bx,bx ; BX := 0 - set display start
int 10h ; Set the display start address
jmp @@Done
@@VGAFlip:
mov bx,ax ; BX := bottom 16 bits of address
; Wait for display enable to be active (active low), to be sure that
; both halves of the start address will take place in one frame. We
; preload a few values here to save time after the DE has been
; detected.
mov cl,0Ch ; CL := Start Address High register
mov ch,bh ; CH := high byte of new address
mov bh,bl ; BH := low byte of new address
mov bl,0Dh ; BL := Start Address Low register
mov dx,03DAh ; DX := video status port
@@WaitDEVGA:
in al,dx
test al,1
jnz @@WaitDEVGA ; Wait for Display Enable
cli
mov dx,03D4h ; DX := CRTC I/O port (3D4h)
mov ax,bx
out dx,ax
mov ax,cx
out dx,ax
sti
; Now wait for the start of the vertical sync, to ensure that the old
; page will be invisible before anything is drawn on it.
@@Done:
mov dx,03DAh ; DX := video status port
@@WaitStartVert:
in al,dx ; Wait for start of vertical retrace
test al,8
jz @@WaitStartVert
@@Exit:
leave_c
ret
procend _setVisualPage
;----------------------------------------------------------------------------
; setBank Sets the read/write bank from assembly language
;----------------------------------------------------------------------------
;
; Entry: _AX - New read/write bank number
;
; Exit: _AX - New read/write bank number
;
; Registers: All preserved!
;
; Note that some VESA BIOSes and TSR's set the first window to be
; write only and the second window to be read only, so we need to set both
; windows for most common operations to the same value. The Universal
; VESA VBE sets both the read and write banks to the same value for
; Window A, and changed the read bank only for Window B, hence the second
; call is _not_ required when the Universal VESA VBE is installed. You can
; determine what the window does by looking at the WindowAAttributes in
; the SuperVGAInfo block returned by function 00h. You could use this
; information to optimise bank switching when using faster VBE's like
; the Universal VESA VBE (but I have no bothered to do that here).
;----------------------------------------------------------------------------
procstart setBank
mov [_curBank],ax ; Save current write bank number
cmp [_writeBank],0
je @@VESABank
call [_writeBank] ; Call relocated version
ret
@@VESABank:
push ax
push bx
push dx
mul [_bankAdjust] ; Adjust to VESA granularity
push ax
mov dx,ax ; DX := bank number
xor bx,bx ; BX := select window A
cmp [_bankSwitch],0
je @@UseInt10
call [_bankSwitch] ; Set write window
pop dx
inc bx
call [_bankSwitch] ; Set read window
pop dx
pop bx
pop ax
ret
; Use the int 10h interface if the bankSwitch routine is NULL, which will
; be the case in protected mode until VBE 2.0
@@UseInt10:
mov ax,04F05h
int 10h
pop dx
inc bx
mov ax,04F05h
pop dx
pop bx
pop ax
ret
procend setBank
;----------------------------------------------------------------------------
; setReadBank Sets the read bank from assembly language
;----------------------------------------------------------------------------
;
; Entry: AX - New read bank number
;
; Exit: AX - New read bank number
;
; Registers: All preserved!
;
;----------------------------------------------------------------------------
procstart setReadBank
mov [_curBank],-1 ; Ensure banking will be re-loaded
cmp [_readBank],0
je @@VESABank
call [_readBank] ; Call relocated version
ret
@@VESABank:
push ax
push bx
push dx
mul [_bankAdjust] ; Adjust to VESA granularity
mov dx,ax ; DX := bank number
mov bx,1 ; BX := select window B
cmp [_bankSwitch],0
je @@UseInt10
call [_bankSwitch] ; Set read window
pop dx
pop bx
pop ax
ret
; Use the int 10h interface if the bankSwitch routine is NULL, which will
; be the case in protected mode until VBE 2.0
@@UseInt10:
mov ax,04F05h
int 10h
pop dx
pop bx
pop ax
ret
procend setReadBank
;----------------------------------------------------------------------------
; void setBank(int bank)
;----------------------------------------------------------------------------
; Sets the new read/write bank number from C
;----------------------------------------------------------------------------
procstart _setBank
ARG bank:INTEGER
push bp
mov bp,_sp
mov ax,[bank]
call setBank
pop bp
ret
procend _setBank
;----------------------------------------------------------------------------
; void setReadBank(int bank)
;----------------------------------------------------------------------------
; Sets the new reading bank number from C
;----------------------------------------------------------------------------
procstart _setReadBank
ARG bank:INTEGER
push bp
mov bp,_sp
mov ax,[bank]
call setReadBank
pop bp
ret
procend _setReadBank
;----------------------------------------------------------------------------
; void getPixel256(int x,int y,long* color)
;----------------------------------------------------------------------------
; Routine sets the value of a pixel in native VGA graphics modes.
;
; Entry: x - X coordinate of pixel to draw
; y - Y coordinate of pixel to draw
; color - Color of pixel to draw
;
;----------------------------------------------------------------------------
procstart __getPixel256
ARG x:INTEGER, y:INTEGER, color
WORD
enter_c 0
mov ax,[y]
mul [_bytesperline]
add ax,[WORD x]
adc dx,0 ; DX:AX := y * BytesPerLine + x
add ax,[OriginOffset]
adc dl,[BYTE BankOffset]; DL := bank number
mov bx,ax ; BX := Offset in buffer
cmp dl,[BYTE _curBank]
je @@NoChange
mov ax,dx
call setBank
@@NoChange:
mov es,[WORD _screenPtr+2]
mov al,[es] ; Replace the pixel
les bx,[bp+10]
mov es:[bx],al
xor ax,ax
inc bx
mov es:[bx],al
inc bx
mov es:[bx],ax
leave_c
ret
procend __getPixel256
;----------------------------------------------------------------------------
; long getPixel32k(int x,int y)
;----------------------------------------------------------------------------
; Routine sets the value of a pixel in native VGA graphics modes.
;
; Entry: x - X coordinate of pixel to draw
; y - Y coordinate of pixel to draw
; color - Color of pixel to draw
;
;----------------------------------------------------------------------------
procstart __getPixel32k
ARG x:INTEGER, y:INTEGER, color
WORD
enter_c 0
mov ax,[y]
mul [_bytesperline]
mov bx,[x]
shl bx,1
add ax,bx
adc dx,0 ; DX:AX := y * BytesPerLine + x * 2
add ax,[OriginOffset]
adc dl,[BYTE BankOffset]; DL := bank number
mov bx,ax ; BX := Offset in buffer
cmp dl,[BYTE _curBank]
je @@NoChange
mov al,dl
call setBank
@@NoChange:
mov es,[WORD _screenPtr+2]
mov ax,[es] ; get the pixel
les bx,[bp+10]
mov es:[bx],ax
inc bx
inc bx
xor ax,ax
mov es:[bx],ax
leave_c
ret
procend __getPixel32k
procstart __getPixel16m
ARG x:INTEGER, y:INTEGER, color
WORD
enter_c 0
mov ax,[y]
mul [_bytesperline]
mov bx,[x]
add ax,bx
adc dx,0
shl bx,1
add ax,bx
adc dx,0 ; DX:AX := y * BytesPerLine + x * 3
add ax,[OriginOffset]
adc dl,[BYTE BankOffset]; DL := bank number
mov bx,ax ; BX := Offset in buffer
cmp dl,[BYTE _curBank]
je @@NoChange
mov al,dl
call setBank
@@NoChange:
mov es,[WORD _screenPtr+2]
mov al,[es] ; get the first byte
push bx
push es
les bx,[bp+10]
mov es:[bx],al
pop es
pop bx
cmp bx,0FFFFh
jne @@NotSplit1
; Arrghh!! We have a case where a single pixel can be split across a
; bank boundary, if the bytes per line value is 1920. This can cause the
; machine to hang (and produce strange pixels).
inc dl
mov al,dl
call setBank ; Change video banks
@@NotSplit1:
mov al,[es:bx+1] ; Replace the middle
push bx
push es
les bx,[bp+10]
inc bx
mov es:[bx],al
pop es
pop bx
cmp bx,0FFFEh
jne @@NotSplit2
inc dl
mov al,dl
call setBank ; Change video banks
@@NotSplit2:
xor ax,ax
mov al,[es:bx+2] ; Replace the last byte
les bx,[bp+10]
inc bx
inc bx
mov es:[bx],ax
leave_c
ret
procend __getPixel16m
procstart __getPixel16
ARG x:INTEGER, y:INTEGER, color
WORD
enter_c 0
; Compute the pixel's address in video buffer
mov ax,[y]
mov bx,[x]
mul [_bytesperline] ; DX:AX := y * BytesPerLine
mov cl,bl ; CL := low-order byte of x
shr bx,3 ; _BX := x/8
add bx,ax
adc dx,0 ; DX:BX := y*BytesPerLine + x/8
add bx,[OriginOffset] ; DX:BX := byte offset in video buffer
adc dx,[BankOffset]
cmp dl,[BYTE _curBank]
je @@NoChange
mov ax,dx
call setBank
@@NoChange:
mov es,[WORD _screenPtr+2]
mov ah,1 ; AH := unshifted bit mask
and cl,7 ; CL := x & 7
xor cl,7 ; CL := # bits to shift left
; set Graphics Controller Bit Mask register
shl ah,cl ; AH := bit mask in proper postion
mov dx,3CEh ; GC address register port
mov al,8 ; AL := Bit Mask Register number
out dx,ax
; set Graphics Controller Mode register
mov ax,0205h ; AL := Mode register number
; AH := Write mode 2 (bits 0,1)
; Read mode 0 (bit 3)
out dx,ax
; set data rotate/Function Select register
mov ax,3 ; AL := Data Rotate/Func select reg #
out dx,ax
; set the pixel value
xor ax,ax
mov al,[es] ; latch one byte from each bit plane
push bx
push es
les bx,[bp+10]
inc bx
mov es:[bx],ax
pop es
pop bx
; restore default Graphics Controller registers
mov ax,0FF08h ; default bit mask
out dx,ax
mov ax,0005 ; default mode register
out dx,ax
mov ax,0003 ; default function select
out dx,ax
les bx,[bp+10]
inc bx
inc bx
xor ax,ax
mov es:[bx],ax
leave_c
ret
procend __getPixel16
;----------------------------------------------------------------------------
; void fillPixel32k(int x,int y,int counter,long color)
;----------------------------------------------------------------------------
; Routine sets the value of a pixel in native VGA graphics modes.
;
; Entry: x - X coordinate of pixel to draw
; y - Y coordinate of pixel to draw
; counter - how many pixel to be filled
; color - Color of pixel to draw
;
;----------------------------------------------------------------------------
procstart __fillPixel32k
ARG x:INTEGER, y:INTEGER, counter:INTEGER,color
WORD
enter_c 0
mov ax,[y]
mul [_bytesperline]
mov bx,[x]
shl bx,1
add ax,bx
adc dx,0 ; DX:AX := y * BytesPerLine + x * 2
add ax,[OriginOffset]
adc dl,[BYTE BankOffset]; DL := bank number
mov bx,ax ; BX := Offset in buffer
cmp dl,[BYTE _curBank]
je @@NoChange
mov al,dl
call setBank
@@NoChange:
mov ax,[WORD color]
mov es,[WORD _screenPtr+2]
mov cx,[WORD counter]
@@cicle:
mov [es],ax ; Replace the pixel
inc bx
jz @@shitty_bank
inc bx
jz @@shitty_bank
dec cx
jnz @@cicle
jz @@end
@@shitty_bank:
inc dl
mov fs,ax
xor ax,ax
mov al,dl
call setBank
mov ax,fs
dec cx
jnz @@cicle
@@end:
leave_c
ret
procend __fillPixel32k
;----------------------------------------------------------------------------
; void fillPixel16m(int x,int y,int counter,long color)
;----------------------------------------------------------------------------
; Routine sets the value of a pixel in native VGA graphics modes.
;
; Entry: x - X coordinate of pixel to draw
; y - Y coordinate of pixel to draw
; counter - pixel to be filled
; color - Color of pixel to draw
;
;----------------------------------------------------------------------------
procstart __fillPixel16m
ARG x:INTEGER, y:INTEGER, counter:INTEGER,color
WORD
enter_c 0
mov ax,[y]
mul [_bytesperline]
mov bx,[x]
add ax,bx
adc dx,0
shl bx,1
add ax,bx
adc dx,0 ; DX:AX := y * BytesPerLine + x * 3
add ax,[OriginOffset]
adc dl,[BYTE BankOffset]; DL := bank number
mov bx,ax ; BX := Offset in buffer
cmp dl,[BYTE _curBank]
je @@NoChange
mov al,dl
call setBank
@@NoChange:
mov es,[WORD _screenPtr+2]
mov cx,[WORD counter]
mov ax,[WORD color]
mov dh,[BYTE color+2]
@@cicle:
cmp bx,0FFFDh
jnb @@splitted
mov [es],ax
mov [es:bx+2],dh
add bx,3
dec cx
jnz @@cicle
jz @@end
@@splitted:
mov [es],al
inc bx
jnz @@not_split1
inc dl
mov al,dl
call setBank
@@not_split1:
mov [es],ah
inc bx
jnz @@not_split2
inc dl
mov al,dl
call setBank
@@not_split2:
mov [es],dh
inc bx
jnz @@cicle
inc dl
mov al,dl
call setBank
jmp @@cicle
@@end:
leave_c
ret
procend __fillPixel16m
procstart __fillPixel256
ARG x:INTEGER, y:INTEGER, counter:INTEGER,color
WORD
enter_c 0
mov ax,[y]
mul [_bytesperline]
add ax,[WORD x]
adc dx,0 ; DX:AX := y * BytesPerLine + x
add ax,[OriginOffset]
adc dl,[BYTE BankOffset]; DL := bank number
mov bx,ax ; BX := Offset in buffer
cmp dl,[BYTE _curBank]
je @@NoChange
mov ax,dx
call setBank
@@NoChange:
mov cx,[WORD counter]
mov es,[WORD _screenPtr+2]
mov al,[BYTE color]
@@cicle:
mov [es],al ; Replace the pixel
inc bx
jz @@new_bank
dec cx
jnz @@cicle
jz @@end
@@new_bank:
mov fs,ax
inc dl
mov al,dl
call setBank
mov ax,fs
jmp @@cicle
@@end:
leave_c
ret
procend __fillPixel256
;----------------------------------------------------------------------------
; void putPixel4G(int x,int y,long color)
;----------------------------------------------------------------------------
; Routine sets the value of a pixel in native VGA graphics modes.
;
; Entry: x - X coordinate of pixel to draw
; y - Y coordinate of pixel to draw
; color - Color of pixel to draw
;
;----------------------------------------------------------------------------
procstart __putPixel4G
ARG x:INTEGER, y:INTEGER, color
WORD
enter_c 0
mov ax,[y]
mul [_bytesperline]
mov bx,[x]
shl bx,1
shl bx,1
add ax,bx
adc dx,0 ; DX:AX := y * BytesPerLine + x * 4
add ax,[originOffset]
adc dl,[BYTE bankOffset]; DL := bank number
mov bx,ax ; BX := Offset in buffer
cmp dl,[BYTE _curBank]
je @@NoChange
mov al,dl
call setBank
@@NoChange:
mov eax,[color]
mov es,[WORD _screenPtr+2]
mov [es],eax ; Replace the pixel
leave_c
ret
procend __putPixel4G
;----------------------------------------------------------------------------
; void clear4G(long color)
;----------------------------------------------------------------------------
; Routine to clear the screen. Assumes pages begin on bank boundaries
; for simplicity of coding.
;----------------------------------------------------------------------------
procstart __clear4G
ARG color
WORD
enter_c 0
push es
mov ax,[_maxy]
inc ax
mul [_bytesperline] ; DX:AX := number of bytes to fill
mov bx,ax ; BX := bytes in last bank to fill
mov dh,dl ; DH := number of full banks to fill
mov ax,fs
mov es,ax
xor di,di ; ES:_DI -> start of video memory
add di,[originOffset]
mov dl,[BYTE bankOffset]; DL := starting bank number
cld ; Moves go up in memory
; Fill all of the full 64k banks first
@@OuterLoop:
mov al,dl
call setBank
mov eax,[color]
mov cx,4000h ; Need to set 4000h double USHORTs per bank
rep stosd
xor di,di
inc dl
dec dh
jnz @@OuterLoop
; Now fill the last partial bank
mov al,dl
call setBank
mov eax,[color]
xor cx,cx
mov cx,bx
shr cx,2 ; _CX := number of double USHORTs to set
rep stosd
pop es
leave_c
ret
procend __clear4G
endcodeseg svga
END
PS non trovo più la libreria 3D!!! :mecry)