home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FreeWare Collection 3
/
FreeSoftwareCollection3pd199x-jp.img
/
oh_fm
/
graph2
/
line.asm
< prev
next >
Wrap
Assembly Source File
|
1980-01-02
|
6KB
|
314 lines
; 'LINE' command for native-mode
; run386 line
.386p ;386ネイティブモード
CODE segment
assume cs:CODE
screen macro page,md ;TBIOSを呼び出してscreenを
mov ax,0100h+page ;設定するマクロ
mov dx,md
call pword ptr fs:[20h] ;グラフィックBIOSを呼ぶ
endm
baibai macro x,y ;TBIOSを呼び出してドットの
mov ax,0202h ;大きさを設定するマクロ
mov dx,x
mov bx,y
call pword ptr fs:[20h]
endm
view macro x,y ;TBIOSを呼び出して表示する
mov ax,0203h ;画面の大きさを設定する
mov dx,x ;マクロ
mov bx,y
call pword ptr fs:[20h]
endm
LOOP_CNT equ 128
MAIN proc ;デモプログラム部分
TBIOS equ 110h ;TBIOSのセレクタ(実行用)
TBIOSw equ 118h ;TBIOSのセレクタ(書き込み可)
sub esp,1600 ; スタック上にワ-ク領域を確保
mov al,5
push Dword ptr TBIOSw
pop fs
mov fs:[10h],al ; TBIOS[10h] <- screen-mode
push Dword ptr TBIOS
pop fs
push ss
pop gs
mov edi,esp ; gs:edi <- ss:[esp]
mov ah,00h ; 画面初期化
mov ecx,1536
call pword ptr fs:[20h] ; call tbios
mov ax,0500h ; 書き込みペ-ジの指定
call pword ptr fs:[20h]
mov ax,0601h ; 表示ペ-ジの指定
mov edx,3
call pword ptr fs:[20h]
screen 1,3 ; page 1 = screen 3
screen 0,5 ; page 0 = screen 5
set256: baibai 2,2
view 256,256
add esp,1600
mov eax,0 ;初期化
mov edi,offset LINE_BUF
cld
mov ecx,loop_cnt
rep stosd
mov edx,0
mov edi,0
mov esi,1
MAIN1:
push edx
mov ax,word ptr ds:[DX1] ;x1を移動させる
add word ptr ds:[X1],ax ;画面の範囲を越えたら
cmp word ptr ds:[X1],0 ;反射するようにする
jge M1
mov word ptr ds:[X1],0
neg word ptr ds:[DX1]
jmp M2
M1: cmp word ptr ds:[X1],255
jle M2
mov word ptr ds:[X1],255
neg word ptr ds:[DX1]
M2: ;x2を移動させる
mov ax,word ptr ds:[DX2] ;x1と同じ
add word ptr ds:[X2],ax
cmp word ptr ds:[X2],0
jge M3
mov word ptr ds:[X2],0
neg word ptr ds:[DX2]
jmp M4
M3: cmp word ptr ds:[X2],255
jle M4
mov word ptr ds:[X2],255
neg word ptr ds:[DX2]
M4: ;y1を移動させる
mov ax,word ptr ds:[DY1] ;x1と同じ
add word ptr ds:[Y1],ax
cmp word ptr ds:[Y1],0
jge M5
mov word ptr ds:[Y1],0
neg word ptr ds:[DY1]
jmp M6
M5: cmp word ptr ds:[Y1],255
jle M6
mov word ptr ds:[Y1],255
neg word ptr ds:[DY1]
M6: ;y2を移動させる
mov ax,word ptr ds:[DY2] ;x1と同じ
add word ptr ds:[Y2],ax
cmp word ptr ds:[Y2],0
jge M7
mov word ptr ds:[Y2],0
neg word ptr ds:[DY2]
jmp M8
M7: cmp word ptr ds:[Y2],255
jle M8
mov word ptr ds:[Y2],255
neg word ptr ds:[DY2]
M8: ;ラインルーチンに渡す引き数をスタックに積む
mov eax,0 ;ページは0
push eax
push edx ;表示色
mov ax,word ptr ds:[Y2] ;y2
push eax
mov cl,al
mov ax,word ptr ds:[X2] ;x2
push eax
mov ch,al
mov ax,word ptr ds:[Y1] ;y1
push eax
mov bl,al
mov ax,word ptr ds:[X1] ;x1
push eax
mov bh,al
mov ax,dx
mov WORD PTR ds:[edi*4+LINE_BUF],bx
mov WORD PTR ds:[edi*4+LINE_BUF+2],cx
inc edi ;この線をとっておく
cmp edi,LOOP_CNT
jb M9
mov edi,0
M9:
call line ;ラインルーチンを呼ぶ
add esp,24 ;スタックレベルを戻す
mov bx,WORD PTR ds:[esi*4+LINE_BUF]
mov cx,WORD PTR ds:[esi*4+LINE_BUF+2]
;バッファから128本前のデータをとってくる
mov eax,0 ;引き数をセット
push eax
push DWORD PTR 0 ;色を黒にして消す
movzx ax,cl
push eax
movzx ax,ch
push eax
movzx ax,bl
push eax
movzx ax,bh
push eax
inc esi
cmp esi,LOOP_CNT
jb M10
mov esi,0
M10:
call line ;ラインルーチンを呼ぶ
add esp,24
pop edx
add edx,1
cmp edx,7fffh
jb MAIN1
mov ah,4Ch
int 21h
MAIN endp
; ラインルーチン本体
;void line(int x1,int y1,int x2,int y2,int col,int page);
; for 256*512*32K colors (GRAPHIC MODE 5) only
public line ;このへんはおまじないと思ってください
db 'line',4 ;for stackdump
line proc
push ebp
push esi
push edi
push ebx
mov bp,ss:[esp+20+16] ;色を読み込む
mov edi,ss:[esp+20+20] ;ページを読み込む
shl edi,9
mov bh,ss:[esp+20+0] ;x1を読み込む
mov bl,ss:[esp+20+4] ;y1 〃
mov ch,ss:[esp+20+8] ;x2 〃
mov cl,ss:[esp+20+12] ;y2 〃
mov dh,bl
mov dl,bh
movzx edx,dx
lea esi,[edi+edx*2] ;(x1,y1)のアドレス
;を求める
push ds ;dsをVRAMのセレクタに
mov dx,120h ;にする
mov ds,dx
mov edx,2 ;edxが横方向の増加量
sub ch,bh
jnb short #liney ;xが増える方向に線を引く?
neg edx ;減る方向だとedxをマイナスにする
neg ch
#liney: mov edi,512 ;ediが縦方向の増加量
sub cl,bl
jnb short #liner ;yが増える方向に線を引く?
neg edi ;減る方向だとediをマイナスにする
neg cl
#liner: cmp ch,cl ;xとyのどちらの変化量が
je short #lines ;大きいか調べて,chが
ja short #lineg ;大きいようにする
xchg ch,cl ;同じ時はlinesに飛ぶ
xchg edi,edx ;縦横の変化量も取り替える
#lineg: mov ah,cl ;割り算をして,
mov al,0 ;傾きを求める。
div ch
mov ah,128
movzx cx,ch ;ループカウンタに
movzx ecx,cx ;横方向のドット数を
inc cx ;いれる。
align 4
#lineg1:
mov ds:[esi],bp ;1ドット点をかく
add esi,edx ;横に座標を動かす
add ah,al ;傾きを足す
jnb short #lineg2 ;あふれたら縦に
add esi,edi ;点を動かす
#lineg2:
loop #lineg1 ;ループ
jmp #exit
align 4
#lines: movzx cx,ch ;ループカウンタに
movzx ecx,cx ;横方向のドット数を
inc cx ;いれる
align 4
#lines1: ;傾きが1のときの
mov ds:[esi],bp ;ルーチン
add esi,edx ;縦横に1回ずつ
add esi,edi ;動かしてドットをかく
loop #lines1
#exit:
pop ds ;スタックを元に
pop ebx ;戻す
pop edi
pop esi
pop ebp
ret
line endp
CODE ends
DATA segment
assume ds:DATA
X1 dw 38 ;メインプログラムで使っているワーク
Y1 dw 56
X2 dw 34
Y2 dw 100
DX1 dw 1
DY1 dw 2
DX2 dw 3
DY2 dw 4
LINE_BUF dd 128 dup(0) ;128本分のバッファを用意している
DATA ends
STACK segment stack
assume ss:STACK
db 2000 dup(?)
STACK ends
end MAIN