Scrolling the screen in Assembly language back in the old 386 da
Mov CX,Scx
Mov DX,Sdx
Add DX,Y
Add CX,X
Mov Scx,CX
Mov Sdx,DX
Mov AX,04F07H
XOr BX,BX
Int 10H
I was just looking at my old files .. Mwahahahhahah .. calling interrupt 10 .. poof. Whatever I wrote 12 years ago doesn't work in my Intel Core 2 Duo anymore. It was 386, then 486 .. now it's Core-Quad or whatever.
Here's another one if you like wasting a couple minutes of your life reading this code below just to draw a line from X1,Y1 to X2,Y2 ..
Procedure Line(X1,Y1,X2,Y2:Integer);Assembler;
Const
Left = $07;
Right = $0B;
Upper = $0D;
Lower = $0E;Var
I,D,Dtx,Dty,Windowy2,Incx2,Incx,Incy,E:Integer;
Interchange:Byte;
Pattern:Word;Asm
Mov BX,Vp.X1
Add X1,BX
Add X2,BX
Mov SI,Vp.X2
Mov DI,Vp.Y1
Add Y1,DI
Add Y2,DI
Mov AX,Vp.Y2
@Start:
Mov Windowy2,AX
{BX|SI|DI|WindowY2 = vp.x1|vp.x2|vp.y1|vp.y2}Mov CL,0Fh {start with %1111 }
Cmp X2,BX {x2 < WindowX1 ?}
Jl @v1point2 {yes, don't change flag for "point is left of window"}
And CL,Left {no, reset flag }
@v1point2:
Cmp X2,SI {x2 > WindowX2 ?}
Jg @v2point2 {yes, don't change flag for "point is right of window"}
And CL,Right {no, reset flag }
@v2point2:
Mov AX,Y2
Cmp AX,DI {y2 < WindowY1 ?}
Jl @v3point2 {yes, don't change flag for "point is above window"}
And CL,Upper {no, reset flag }
@v3point2:
Cmp AX,Windowy2 {y2 > WindowY2 ?}
Jg @point1 {yes, don't change flag for "point is below window"}
And CL,Lower
@point1:
Mov CH,0Fh {start with %1111 }
Cmp X1,BX {x1 < WindowX1 ?}
Jl @v1point1 {yes, don't change flag for "point is left of window"}
And CH,Left {no, reset flag }
@v1point1:
Cmp X1,SI {x1 > WindowX2 ?}
Jg @v2point1 {yes, don't change flag for "point is right of window"}
And CH,Right {no, reset flag }
@v2point1:
Mov AX,Y1
Cmp AX,DI {y1 < WindowY1 ?}
Jl @v3point1 {yes, don't change flag for "point is above window"}
And CH,Upper {no, reset flag }
@v3point1:
Cmp AX,Windowy2 {y1 > WindowY2 ?}
Jg @v4point1 {yes, don't change flag for "point is below window"}
And CH,Lower
@v4point1: {CH holds the area code for point 1 }
{CL holds the area code for point 2, CH the one for point 1}
Mov AX,CX
And AL,AH {Code1 AND Code2 <> 0 ?}
Jnz @Done {yes, line is completely outside the window}
Mov AX,CX
Or AL,AH {Code1 OR Code2 = 0 ?}
Jz @Drawline {yes, line is completely inside the window}
{Now do the clipping itself: }
Mov AX,CX
Or AH,AH {Code1 =0 ?}
Jnz @Cl3 {no, everything ok lah yauow !}
Mov AX,X1 {yes, swap points!}
Xchg AX,X2
Mov X1,AX
Mov AX,Y1
Xchg AX,Y2
Mov Y1,AX
Xchg CL,CH
@Cl3:
Mov AX,X2
Sub AX,X1
Mov Dtx,AX {dtx := x2 - x1}
Mov AX,Y2
Sub AX,Y1
Mov Dty,AX {dty := y2 - y1}
Mov AL,CH {AL := Code1}
Test AL,Not Left {point1 left of window? }
Jz @Cl4 {no }
{yes, compute new coordinates:}
{ y1 := y1 + (y2 - y1) / (x2 - x1) * (WindowX1 - X1) }
{ and x1 := WindowX1}
Mov AX,BX
Sub AX,X1 {AX := WindowX1-x1}
Imul Dty
Idiv Dtx
Add Y1,AX
Mov X1,BX
Jmp @point1
@Cl4:
Test AL,Not Right {point1 right of window? }
Jz @Cl5 {no }
{yes, compute:}
{ y1 := y1 + (y2 - y1) / (x2 - x1) * (WindowX2 - X1), x1 := WindowX2}
Mov AX,SI {SI = WindowX2}
Sub AX,X1
Imul Dty
Idiv Dtx
Add Y1,AX
Mov X1,SI
Jmp @point1@Cl5:
Test AL,Not Upper {point1 above window? }
Jz @Cl6 {no }
{yes, compute:}
{ x1 := x1 + (x2 - x1) / (y2 - y1) * (WindowY1 - y1), y1 := WindowY1 }
Mov AX,DI {DI = WindowY1}
Sub AX,Y1
Imul Dtx
Idiv Dty
Add X1,AX
Mov Y1,DI
Jmp @point1@Cl6:
Test AL,Not Lower {point below window? }
Jz @point1 {no }
{yes, compute:}
{ x1 := x1 + (x2 - x1) / (y2 - y1) * (WindowY2 - y1), y1 := WindowY2 }
Mov AX,Windowy2
Push AX
Sub AX,Y1
Imul Dtx
Idiv Dty
Add X1,AX
Pop AX
Mov Y1,AX
Jmp @point1@Yincr:
Cmp Incy,0
Jl @Negy2
Add DI,BytesPerLine {y:=y+incy}
Jmp @Skip73
@Negy2:
Sub DI,BytesPerLine {y:=y-incy}
@Skip73:
Jnc @Nobanky
Add DX,Incy
Call Setbank
@Nobanky:
Retn@Drawline:
mov ax,linepattern
mov pattern,ax
Mov AX,Y1
Mov BX,X1
Call Vsetoffset
Mov DI,AX
Mov SI,X2 {SI=_DX}
Sub SI,X1
Mov Incx,1
Mov AX,Addx
Mov Incx2,AX
Jns @Bx_To_Dy
Neg Incx
Neg Incx2
Neg SI
@Bx_To_Dy:
Mov bX,Y2 {AX=_DY}
Sub bX,Y1
Mov Incy,1
Jns @Skip2
Neg Incy
Neg bX
@Skip2:
Mov Interchange,FALSE
Cmp bX,SI {_DY compare _DX [SI] }
Jl @Dy_Lower_Than_Dx
Inc Interchange
Xchg bX,SI
@Dy_Lower_Than_Dx:
Mov CX,SI {loop i:=_DX; ;initialization}
inc cx
ShL SI,1 {_DX * 2}
ShL bX,1 {_DY * 2}
Mov E,bX
Sub E,SI
Mov ES,SegA000
Mov AX,Currentcolor
@Mainloop: {main loop}
ror pattern,1
Jnc @Noplot
call plotcolor@Noplot:
Cmp E,0
Jnge @Skipe {while e >= 0}
Cmp Interchange,FALSE
Je @Itfalse1
Add DI,Incx2 {x:=x+incx}
Jnz @Nobank1 {DI=bankend ?}
Add DX,Incx
Call Setbank
Jmp @Nobank1
@Itfalse1:
Call @Yincr
@Nobank1:
Sub E,SI
@Skipe:
Cmp Interchange,FALSE
Je @Itfalse2
Call @Yincr
Jmp @Ittrue2
@Itfalse2:
Add DI,Incx2 {x:=x+incx}
Jnz @Ittrue2 {DI=bankend ?}
Add DX,Incx
Call Setbank
@Ittrue2:
Add E,bX
Loop @Mainloop
@Done:
End;
And here's the referenced Setbank
Procedure Setbank;Near;Assembler;
Asm
Cmp DL,Currentbank
Je @@Nochange
Mov Currentbank,DL
Push AX
Push BX
Mov AX,4F05H
XOr BX,BX {write bank - MOV}
Int 10HMov AX,4F05H
Mov BX,0001H {read bank - AND, OR , XOR}
Int 10H
@Noread:
Pop BX
Pop AX
@@Nochange:
End;
How about drawing a mouse cursor on the screen?
Procedure Drawmouse(X,Y:Integer);Assembler;
Var
Width,Height:Word;
AndPattern,Xorpattern:Word;
Nhorshift:Word;
savebank:byte;
Asm
cld
Mov Nhorshift,0
Mov Height,16
Mov Width,16
mov bx,x
mov dx,y
Lea SI,MouseShape
Lodsw
sub bx,ax {x-hotspot.x}
cmp bx,0
jge @xg
neg bx
mov nhorshift,bx
neg bx
add bx,16
mov width,bx
xor bx,bx
jmp @xdone
@xg:
mov ax,bx
add ax,16
cmp ax,getmaxx
jle @xdone
mov cx,getmaxx
inc cx
sub cx,bx
mov width,cx
@Xdone:
Lodsw
Sub dx,ax
Cmp dx,0
Jge @Yg
mov ax,dx
neg ax
shl ax,1
add si,ax
add dx,16
mov height,dx
xor dx,dx
jmp @ydone
@Yg:
Mov AX,dx
Add AX,16
Cmp AX,getmaxy
Jle @Ydone
Mov AX,getmaxy
Sub AX,dx
Inc AX
Mov Height,AX
@Ydone:
mov al,20h
add al,hicolor
mov byte ptr @p1,al
mov al,30h
add al,hicolor
mov byte ptr @p2,al
Mov AX,dx
call vsetoffset
Mov DI,AX
Push bytesperline
Mov AX,Width
shl ax,cl
Sub bytesperline,AX
Mov BL,White
Mov ES,SegA000
Mov Bx,white
cmp cl,false
je @puty
mov bx,0ffffh
@Puty:
LODSW {AND}
mov andpattern,ax
Mov ax,DS:[SI+30] {XOR}
mov xorpattern,ax
Mov CX,nhorshift
Rol andpattern,CL
Rol xorpattern,CL
Mov CX,Width
@Putx:
XOr aX,aX
Rol andpattern,1
Jc @Noandput
db $26
@p1:db $20
db $05
@Noandput:
Rol Xorpattern,1
Jnc @Noxorput
db $26
@p2:db $30
db $1d {ada warnaan}
@Noxorput:
add DI,addx
jnz @nobank
inc dl
call setbank
@nobank:
Loop @Putx
Add DI,bytesperline
jnc @nobank2
inc dl
call setbank
@nobank2:
Dec Height
Jnz @Puty
@@Done:
Pop bytesperline
End;
Then call interrupt 33 to set the X and Y. Wheew. Good night. What a week.