Category : Assembly Language Source Code
Archive   : 2DROTATE.ZIP
Filename : ROTATE.ASM

Output of file : ROTATE.ASM contained in archive : 2DROTATE.ZIP
; TITLE: 2d rotate
; FOR: Phantasm, (206) 232-5912
; The first programing oriented board to hit the 206 area.
; Any questions regarding this or ANY code in any language
; can, and will be answered on Phantasm.
; Send messages to 'Draeden' or post in the VLA programming
; section.
; The Deep (TDT/VLA), (305) 888-7724
; Our first distribution site. Messages will also be answered
; if posted at this location.
; Send messages to 'The Kabal'.
; DATE: 02/13/93
; NOTES: Compiled with TASM, TLINK
; Must have a 386 or better to run. Any speed.
; This program was chosen as an example because it utilizes
; a lot of the neat little tricks you can do in assembly,
; mainly Structures (STRUC), Unions (UNION), INCLUDEs,
; the REPT macro, and the DUP() macro.
; BWPRINT.ASM => Displays signed and unsigned bytes, words, or
; > double words
; SINCOS.DW => Contains data for the sine and cosine operations
; ROTATE.TXT => A text file that further explains how to rotate
; > objects, what BWPRINT.ASM does, and
; > what the SINCOS.DW file is.
; MAKE.BAT => The file that'll put it all together into an .EXE

DOSSEG ;tells compiler to sort segments according to the
;DOS standards- code, data, stack
.STACK 200h ;sets up a 512 byte stack
.DATA ;starts the data segment (empty)
.CODE ;starts the code segment
.386 ;tells compiler to allow 386 instructions
;tells compiler to assume offsets are taken from
;the code segment
LOCALS ;turns local labels on eg. @@local:


;=== GLOBALS -used to link multiple programs together

GLOBAL PrintByte:PROC, PrintWord:PROC, PrintBig:PROC
;above is for the file BWPRINT.ASM


;=== Data Includes -include physically puts the file in this one on compile

INCLUDE sincos.dw ;Labels SINE: and COSINE: contains sine(0-255)*256


;=== DATA Structures

Angle_Union UNION
B db 0
W dw 0
Angle_Union ENDS ;creates a new data type (eg. DW, DB, DD) called
;Angle_Union. Used just like in C
Point_Struc STRUC

X dw ?
Y dw ?
Point_Struc ENDS ;Create a structure (or a record)


;=== DATA

NumPts EQU 8

XYCord Point_Struc <-50,50>,<50,50>,<-50,-50>,<50,-50>
Point_Struc <-30,30>,<30,30>,<-30,-30>,<30,-30>
;sets up data for the corners of a 2d box

RotCord Point_Struc NumPts DUP(<>)

OldDi dw NumPts DUP (0) ;holds di for quick erasing

Angle Angle_Union ; the '?' defaults to zero, but you can't
;specify in a Union
AngleVel db 1 ;angle velocity

AddX dw 160 ;amount to ADD to each X cordinate
AddY dw 100 ;amount to ADD to each Y cord

Palette db 3 dup (0) ;sets up a palette that fades from (0,0,0) to
i = 1 ;(15*4,15*3,15*2) in 16 steps
db 4*i,3*i,2*i

Color db 15

AngleMsg db "ANGLE: $"
AngleVelMsg db "VELOCITY: $"

;=== Code Includes ;none.


;DESTROYS: ax, edx, edi, si, ebp
;Input: BX= X CX= Y which are rotated Angle degrees
;OutPut:BX= X CX= Y
RotateXY proc near
push ds
mov ax,cs ;the basic formula for rotations:
mov ds,ax ; X := cos(angle) * x - sin(Xan) * y
; Y := sin(angle) * x + cos(Xan) * y
mov si,[Angle.W]
add si,si ; si = angle*2
mov ax,[Cosine+si] ; ax = cos(angle)
imul bx ; ax = cos(angle) * x
shl edx,16 ; put dx in high edx
mov dx,ax ; save all 32 bits
mov edi,edx ; store for later use

mov ax,[Sine+si] ; ax = sin(angle)
imul cx ; ax = sin(angle) * y
shl edx,16
mov dx,ax
sub edi,edx ; edi = edi-eax=cos(angle)*x-sin(angle)*y
sar edi,8 ; remove the "256-factor"
mov ebp,edi ; ebp = x-coordinate

mov ax,[Sine+si] ; ax = sin(angle x)
imul bx ; ax = sin(angle x) * x
shl edx,16
mov dx,ax
mov edi,edx

mov ax,[Cosine+si] ; ax = cos(angle x)
imul cx ; ax = cos(angle x) * y
shl edx,16
mov dx,ax
add edi,edx ; di = di-ax = sin(vx)*y + cos(vx)*z
sar edi,8 ; remove the (co)sin "256-factor"

mov bx,bp ; update X
mov cx,di ; update Y

pop ds

;rotates all points and saves them
pushad ;saves EVERYTHING (extended registers, too), except flags
mov ax,cs
mov ds,ax
mov es,ax

mov bp,0 ;point counter
mov bx,[XYCord.X +bp] ;load in cordinates to rotate
mov cx,[XYCord.Y +bp]
push bp
call RotateXY
pop bp

mov [RotCord.X +bp],bx ;save rotated cordinates IN A DIFFERENT PLACE
mov [RotCord.Y +bp],cx

add bp,4 ;size of each entry
cmp bp,NumPts*4 ;are we done, yet?
jb @@DoNextPoint ;No. Do another

RotateBox ENDP

;draws the dots to the screen
pusha ;saves only non extended registers
mov ax,0a000h ;segment to VGA memory
mov es,ax
mov ax,cs
mov ds,ax

mov bp,0 ;point counter
mov al,[Color]
mov si,bp
add si,si
mov bx,si ;bx= bp*2
add si,si ;si= bp*4

mov di,[OldDI+bx]
mov BYTE PTR es:[di],0 ;clear out old point

;pixel location = ScreenWidth*Ypos + Xpos = 320 * (Y+AddY) + X + AddX
mov di,[RotCord.Y +si]
add di,[AddY]
imul di,320
add di,[AddX]
add di,[RotCord.X +si]

mov [OldDi+bx],di

inc bp
cmp bp,NumPts ;are we done, yet?
jb @@DoNextPoint ;No. Do another

DrawBox ENDP


;=== CODE

mov ax,cs
mov ds,ax
mov es,ax

mov ax,0013h ;set 320x200x256 mode
int 10h

mov dx,offset Palette ;ES:DX points to palette data
mov ax,1012h ; WRITE palette
mov bx,0 ;start at color 0
mov cx,16 ; and write 16 of 'em
int 10h

mov dx,03d5h ;this bit of code turns the cursor OFF
mov al,0ah ;by setting bit 5 of index 0ah to 0
;(CRT controll register selector = 03d5h)
mov ah,0 ;this is done because some video cards
out dx,ax ;do not always turn off the cursor in
;graphics mode
;(note: it also turns all the other bit to 0)
call RotateBox
mov al,[AngleVel]
add [Angle.b],al ;note that by just increasing the byte part, the
;ranging is automatic (stays in 0-255 range)
mov dx,3dah
in al,dx
test al,8
jnz VRT ;wait until Verticle Retrace starts

in al,dx
test al,8
jz NoVRT ;wait until Verticle Retrace Ends

call DrawBox

mov ah,2
mov bx,0
mov dx,0
int 10h ;set cursor pos to (dl,dh) on page BX

mov ah,9
mov dx,offset AngleMsg
int 21h

mov al,[Angle.B]
clc ;says print it unsigned
call PrintByte

mov ah,2
mov bx,0
mov dx,0014h
int 10h ;set cursor pos to (dl,dh) on page BX

mov ah,9
mov dx,offset AngleVelMsg
int 21h

mov al,[AngleVel]
stc ;says print it signed
call PrintByte

mov ah,1
int 16h ;has a key been pressed? Z flag is set if not
jz BoxLoop
mov ah,0 ;a key has been pressed,
int 16h ; get it in AX (al= ascii, ah=scan code)

cmp al,27 ;was it the ESCAPE key?
je ByeBye ;Yup, take off

cmp al,"+" ;increases angle velocity
jne NotPlus
inc [AngleVel]
jmp SHORT BoxLoop
cmp al,"-" ;decreases angle velocity
jne NotMinus
dec [AngleVel]
jmp SHORT BoxLoop
cmp al," " ;will reset the angle velocity to Zero
jne NotSpace
mov [AngleVel],0
jmp BoxLoop
cmp al,13 ;will reset the angle to zero
jne NotEnter
mov [Angle.W],0
jmp BoxLoop

jmp BoxLoop

mov ax,0003h ;set 80x25x16 text
int 10h
mov ax,4c00h ;return control to DOS
int 21h

  3 Responses to “Category : Assembly Language Source Code
Archive   : 2DROTATE.ZIP
Filename : ROTATE.ASM

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: