📄 direct.asm
字号:
les di,To ; es:di is to address
lds si,From ; ds:si is from address
mov cx,80*25 ; HARDCODED screen size in words
IFDEF nosnow ; move the screen image
rep movsw
ELSE
call movideo
ENDIF
pop ds
pop si
pop di
mov sp,bp
pop bp
E_proc _scrcpy,SCRCPY,8
;******************************************************************************
;
; popup(row,col,nrows,ncols,savp)
;
; pop up a dialog box on the screen starting at row,col.
; If savp is not NULL, the current contents of the video ram
; under the box are saved.
;
;******************************************************************************
Param Row_p,4,12 ; parameters for popup() & popdwn()
Param Col_p,6,10
Param Nrows,8,8
Param Ncols,10,6
Param Savp,12,4
B_proc _popup,POPUP
push bp
mov bp,sp
push di
push si
mov ax,160 ; calc offset to start of
imul WORD PTR Row_p ; dialog box -
mov cx,Col_p ; row * 160 + (col << 1)
shl cx,1
add ax,cx
mov si,ax ; si now -> box start offset
mov boxloc,si ; save it for later
mov di,Savp ; get savp, the save addr ptr
or di,di ; does user want contents saved?
je skipsave
mov dx,si ; save current row offset
mov bh, BYTE PTR Nrows ; nrows to bh
mov bl, BYTE PTR Ncols ; ncols to bl
mov ax,ds ; set es and ds so str instrs
mov es,ax ; work the way we want
mov cx,WORD PTR _screen+2 ; ds points to video ram
mov ds, cx
IFNDEF nosnow
mov al,es: _vid_snow ; movideo needs _vid_snow
push ax
ENDIF
nxtrow: mov cl,bl ; move ncols to cx
xor ch,ch
IFDEF nosnow
rep movsw ; move data
ELSE
pop ax ; get/save _vid_snow
push ax
call movideo
ENDIF
add dx,160 ; calc offset of next row
mov si,dx
dec bh ; one more row done, any more?
jnz nxtrow
IFNDEF nosnow
pop ax ; clear stack
ENDIF
mov ax,es ; restore the ds reg
mov ds,ax
mov si,boxloc ; reget box starting offset
skipsave:
mov di,si ; video ram is now the dest
mov es,WORD PTR _screen+2 ; video ram segment
mov al,201 ; disp the upper left corner
mov ah,_vid_attrib ; the video attrib to use
IFDEF nosnow
stosw ; store in video ram
ELSE
mov cx,1
call stvideo
ENDIF
mov cx,Ncols ; now do the horizontal line
dec cx ; its ncols - 2 long
dec cx
mov Ncols,cx ; ncols - 2 is used again
mov al,205 ; horizontal bar char
IFDEF nosnow
rep stosw
ELSE
call stvideo
ENDIF
mov al,187 ; disp the upper right corner
IFDEF nosnow
stosw ; store in video ram
ELSE
mov cx,1
call stvideo
ENDIF
; now do the blank lines in the body of the box
mov bx,Nrows ; the body is nrows - 2 long
dec bx
dec bx
add si,160 ; bump row offset
mov di,si
rownxt: mov al,186 ; do the left vertical bar
IFDEF nosnow
stosw ; store in video ram
ELSE
mov cx,1
call stvideo
ENDIF
mov cx,Ncols ; now all the blanks
mov al,32
IFDEF nosnow
rep stosw
ELSE
call stvideo
ENDIF
mov al,186 ; do the right vertical bar
IFDEF nosnow
stosw ; store in video ram
ELSE
mov cx,1
call stvideo
ENDIF
add si,160 ; bump row offset
mov di,si
dec bx ; another row done
jnz rownxt
; now do the bottom row of the box
mov al,200 ; disp the lower left corner
IFDEF nosnow
stosw ; store in video ram
ELSE
mov cx,1
call stvideo
ENDIF
mov cx,Ncols ; now do the horizontal line
mov al,205 ; horizontal bar char
IFDEF nosnow
rep stosw
ELSE
call stvideo
ENDIF
mov al,188 ; disp the lower right corner
IFDEF nosnow
stosw ; store in video ram
ELSE
mov cx,1
call stvideo
ENDIF
pop si ; done, exit
pop di
mov sp,bp
pop bp
E_proc _popup,POPUP,10
;******************************************************************************
;
; popdwn(row,col,nrows,ncols,savp)
;
; Remove a pop up dialog box from the screen by restoring the prior
; contents from savp.
;
;******************************************************************************
B_proc _popdwn,POPDWN
push bp
mov bp,sp
push di
push si
mov ax,160 ; calc offset to start of
imul WORD PTR Row_p ; dialog box -
mov cx,Col_p ; row * 160 + (col << 1)
shl cx,1
add ax,cx
mov di,ax ; di now -> box start offset
mov si,Savp ; get savp, the save addr ptr
mov dx,di ; save current row offset
mov bh, BYTE PTR Nrows ; nrows to bh
mov bl, BYTE PTR Ncols ; ncols to bl
mov es,WORD PTR _screen+2 ; oh yea, es points to video ram
next: mov cl,bl ; move ncols to cx
xor ch,ch
IFDEF nosnow
rep movsw ; move data
ELSE
mov al,_vid_snow
call movideo
ENDIF
add dx,160 ; calc offset of next row
mov di,dx
dec bh ; one more row done, any more?
jnz next
pop si
pop di
mov sp,bp
pop bp
E_proc _popdwn,POPDWN,10
IFNDEF nosnow
;******************************************************************************
;
; movideo - move data to/from video memory
; - current video mode must be passed in al
;
;******************************************************************************
movideo PROC NEAR
test al,1 ; do we need to check for snow?
jnz goslow
rep movsw ; no snow, full speed ahead
ret ; that's all there is to it
goslow: push dx ; it's a cga, go slow time
mov dx,03dah ; dx = cga status port address
wait1: in al,dx ; get retrace status
test al,8 ; vertical retrace?
jnz mov_it ; yes, go get the char
ror al,1 ; low bit set? (horizontal retrace)
jc wait1 ; current retrace may be almost done
cli ; no interrupts until char loaded
wait2: in al,dx ; wait for start of next retrace
ror al,1
jnc wait2
mov_it: movsw ; move word to/from video ram
sti ; allow interrupts
loop wait1 ; all chars transfered?
pop dx ; restore dx
ret
movideo ENDP
;******************************************************************************
;
; stvideo - store the word in ax to video ram cx times
;
;******************************************************************************
stvideo PROC NEAR
test _vid_snow,1 ; do we need to slow for no snow?
jnz slowgo
rep stosw ; no snow, full speed ahead
ret ; that's all there is to it
slowgo: push bx ; snow, go slow
push dx
mov dx,03dah ; dx = cga status port address
mov bx,ax
wait3: in al,dx ; get retrace status
test al,8 ; vertical retrace?
jnz sto_it ; yes, go get the char
ror al,1 ; low bit set? (horizontal retrace)
jc wait3 ; current retrace may be almost done
cli ; no interrupts until char loaded
wait4: in al,dx ; wait for start of next retrace
ror al,1
jnc wait4
sto_it: mov ax,bx
stosw ; store word to video ram
sti ; allow interrupts
loop wait3 ; all chars transfered?
pop dx ; restore dx & bx
pop bx
ret
stvideo ENDP
ENDIF
_TEXT ENDS
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -