; PIXELPAN.ASM -- EGA/VGA Pixel Panning routines ; BY PEDER JUNGCK ( Copyright 1991 ) ; Assembly language routines designed for C-style calling conventions ; All example routines use a near call model ; NOTE: the SetLineLength function is error trapped for Mode 0Dh (320x200) SLOW_EGA equ 0 .model small .code Public _Video_Mode ; (int Mode) Public _SetLineLength ; (int Length) Public _SetViewPosition ; (HPixel,LineNum) Public _Set_Pixel ; (x,y,Color) BytesPerLine dw 40 ; screen width in bytes (320x200 Mode) VOffset equ 0a000h ; video RAM offset Video_ModeParms struc dw ? ; pushed BP dw ? ; return address pushed by call vm_mode dw ? ; pass new video mode parameter Video_ModeParms ends _Video_Mode proc near ; void Video_Mode(int Mode); push bp mov bp,sp ; put sp in bp, to get parameters on stack mov ax,[bp+vm_mode] xor ah,ah ; set video mode ( ah=0 ) int 10h ; call video BIOS pop bp ret _Video_Mode endp SetLineLengthParms struc dw ? ; pushed BP dw ? ; return address pushed by call LineLen dw ? ; pass new scan line length SetLineLengthParms ends _SetLineLength proc near ; int SetLineLength(int Length) push bp mov bp,sp ; put sp in bp, to find parameters on stack mov ax,[bp+LineLen] cmp ax,40 ; Minimum Line Length (320x200) 40 bytes jae Low_OK ; 1 page wide x 8 high (mode 0Dh default) mov ax,40 ; Must be at least the minimum length jmp Hi_OK Low_OK: cmp ax,320 ; 320 bytes wide leaves only 200 high jbe Hi_OK ; 8 pages wide and one high (mode 0Dh) mov ax,320 ; Must be less or equal to maximum Hi_OK: mov BytesPerLine,ax xchg bx,ax ; save parameter to BX mov dx,3d4h mov ax,13h out dx,ax ; BytesPerVideoRamRow Func inc dx ; 3d5h data port mov ax,bx ; number of lines to output shr ax,1 ; need words for port out dx,ax mov ax,bx ; return # of lines we set pop bp ret _SetLineLength endp SetViewPositionParms struc dw ? ; pushed BP dw ? ; return address pushed by call Hpixel dw ? ; pass in horizontal pixel offset LineNum dw ? ; pass in line number SetViewPositionParms ends _SetViewPosition proc near ;void SetViewPosition(int HPixel,int Linenum) push bp mov bp,sp ; put sp in bp, to find parameters on stack mov ax,[bp+HPixel] ; get horizontal pixel address mov cx,ax ; and save in cx and cx,07 ; get pixel offset of position shr ax,1 shr ax,1 shr ax,1 xchg bx,ax ; and save in bx mov ax,[bp+LineNum] ; get number of lines mul BytesPerLine ; multiply times bytes per line add bx,ax ; new upper left corner offset mov dx,3dah wait: in al,dx ; make sure not already doing a retrace test al,08h jz wait Retrace: in al,dx ; wait until the start of retrace test al,08 ; to perform clear of 3c0 port jnz Retrace cli ; disable interrupts in al,dx mov ax,bx ; upper corner in AH, BH holds high value mov al,0ch ; hi byte offset mov dx,3d4h out dx,ax mov al,0dh ; low byte offset mov ah,bl ; bl holds low byte value out dx,ax if SLOW_EGA ;*** add sti mov dx,3dah wait2: in al,dx ; wait til we start vertical retrace test al,08h jz wait2 cli ;end add endif mov dx,3c0h ; ATC index register mov al,33h ; palette address source 1, reg address 13 out dx,al xchg cl,al ; get pixel offset out dx,al sti ; enable interrupts pop bp ret _SetViewPosition endp Set_PixelParms struc dw ? ; pushed BP dw ? ; return address pushed by call ps_xpos dw ? ps_ypos dw ? Color dw ? Set_PixelParms ends _Set_Pixel proc near ; void Set_Pixel(int x, int y, int Color) push bp mov bp,sp push ds ; save the data segment mov ax,VOffset ; get the video RAM address mov ds,ax ; set data segment to EGA/VGA mov ax,[bp+ps_ypos] ; get the y coordinate mul BytesPerLine ; get the offset to line y mov bx,[bp+ps_xpos] ; get the x coordinate mov cx,bx ; and save in CX shr bx,1 ; and divide by 8 shr bx,1 shr bx,1 add bx,ax ; bx := BytesPerLine*y+(x/8) ; we now have x,y memory offset and cl,7 ; generate mask for one pixel in byte xor cl,7 mov ch,1 shl ch,cl ; ch := 1 >>>> (7-(x mod 8)) mov dx,3ceh ; now select write mode 2 mov al,5 out dx,al ; select mode (register 5) mov dx,3cfh mov al,2 out dx,al ; and set to write mode 2 mov dx,3ceh ; set up mask mov al,8 out dx,al ; select mask (register 8) mov dx,3cfh mov al,ch out dx,al ; set mask mov al,[bx] ; read from card and color dot mov ax,[bp+Color] mov [bx],al ; write color to dot mov dx,3ceh ; restore default mode mov al,5 out dx,al ; select mode (register 5) mov dx,3cfh mov al,0 out dx,al ; set write mode back to 0 mov dx,3ceh mov al,8 out dx,al ; select mask (register 8) mov dx,3cfh mov al,0ffh out dx,al ; and set default mask pop ds ; restore data segment pop bp ret _Set_Pixel endp end