📄 exo.asm
字号:
loop engi_bottlp
mov WORD PTR es:[di][bx], exo__LRCB
mov WORD PTR es:[di][bx][2], 0h
pop di
pop es
pop bp
pop es
pop di
pop bx
pop ax
;-------------------
;Load window above
;-------------------
xor bh, bh ;bh <- 0
mov bl, ds:[si].endo.data.above
cmp bx, 0
je engi_yes
shl bx, 1
shl bx, 1
lds si, es:[di].exo.data.wintbl[bx]
;-------------------
;Loop back for a
;validity check
;-------------------
jmp engi_zero
engi_yes:
;-------------------
;We're done
;-------------------
popf
pop ds
pop es
pop di
pop si
pop dx
pop cx
pop bx
pop ax
retf
exo__engine ENDP
;
; exo__createwin Takes an ES:DI pointer to an exo object, as well
; as a DS:SI pointer to a endowindow to be added
; to the system.
;
exo__createwin PROC
push ax
push bx
push cx
push dx
push si
push ds
push di
push es
;-------------------
;Find first vacant
;slot in the wintbl
;-------------------
mov ax, 0
mov bx, 4
mov ch, 0
mov cl, es:[di].exo.data.winnum
shl cx, 1
shl cx, 1
crea_findfree: cmp WORD PTR es:[di].exo.data.wintbl[bx], ax
jne crea_no
crea_maybe: cmp WORD PTR es:[di].exo.data.wintbl[bx][2], ax
je crea_yes
crea_no:
add bx, 4
cmp bx, cx
jb crea_findfree
call es:[di].exo.methods.error
;-------------------
;Fill it in
;-------------------
crea_yes :
mov WORD PTR es:[di].exo.data.wintbl[bx], si
mov si, ds
mov WORD PTR es:[di].exo.data.wintbl[bx][2], si
;-------------------
;Set up the links:
;-------------------
shr bx, 1
shr bx, 1
xor ah, ah
mov al, es:[di].exo.data.top;ax = old top win
mov es:[di].exo.data.top, bl;bx = new top win
shl bx, 1 ;bx = new top win*4
shl bx, 1
lds si, es:[di].exo.data.wintbl[bx]
shr bx, 1 ;bx = new top win
shr bx, 1
mov ds:[si].endo.data.id, bl ;set the id of new
mov ds:[si].endo.data.above, 0 ;none above it
mov ds:[si].endo.data.below, al;old top below it
cmp al, 0 ; First Window
je FirstWin
xchg ax, bx ;bx = old top win
shl bx, 1 ;old top win*4
shl bx, 1
lds si, es:[di].exo.data.wintbl[bx]
mov ds:[si].endo.data.above, al
FirstWin:
pop es
pop di
pop ds
pop si
pop dx
pop cx
pop bx
pop ax
retf
exo__createwin ENDP
;
; exo__destroywin Takes an ES:DI pointer to an exo object, as well
; the window id in BX, and removes the window from
; the system
;
exo__destroywin PROC
push dx
push si
push ds
cmp es:[di].exo.data.bottom, bl
jne dest_notbott
;-------------------
;Case I: Bottom win
;-------------------
;If it is the bottom
;window, load it
push bx
shl bx, 1
shl bx, 1
lds si, es:[di].exo.data.wintbl[bx]
mov ah, ah ;ah <- 0
mov al, ds:[si].endo.data.above
;ax = new
;bx = old*4
mov es:[di].exo.data.bottom, al
;Set bottom ptr to new
xchg ax, bx
;ax = old*4
;bx = new
shl bx, 1
shl bx, 1
lds si, es:[di].exo.data.wintbl[bx]
;Now, none below new
mov ds:[si].endo.data.below, 0
pop bx
jmp dest_done
dest_notbott: cmp es:[di].exo.data.top, bl
jne dest_nottop
;-------------------
;Case II: Top win
;-------------------
;If it is the top
;window, load it
push bx
shl bx, 1
shl bx, 1
lds si, es:[di].exo.data.wintbl[bx]
mov al, ds:[si].endo.data.below
;ax = new
;bx = old*4
mov es:[di].exo.data.top, al;Set top ptr to new
xchg ax, bx
;ax = old*4
;bx = new
shl bx, 1
shl bx, 1
lds si, es:[di].exo.data.wintbl[bx]
;Now, none above new
mov ds:[si].endo.data.above, 0
pop bx
jmp dest_done
dest_nottop:
;-------------------
;Case III: Neither
;-------------------
push ax
push bx
push cx
shl bx, 1
shl bx, 1
lds si, es:[di].exo.data.wintbl[bx]
;ax = old->above
;bx = old*4
;cx = old->below
mov al, ds:[si].endo.data.above
mov cl, ds:[si].endo.data.below
push ax
xchg ax, bx ;ax = old*4
shl bx, 1 ;bx = old->above*4
shl bx, 1
;cx = old->below
lds si, es:[di].exo.data.wintbl[bx]
mov ds:[si].endo.data.below, cl
pop ax ;ax = old->above
xchg bx, cx ;bx = old->below*4
shl bx, 1 ;cx = old*4
shl bx, 1
lds si, es:[di].exo.data.wintbl[bx]
mov ds:[si].endo.data.above, al
pop cx
pop bx
pop ax
dest_done:
pop ds
pop si
pop dx
retf
exo__destroywin ENDP
;
; exo__movewin Takes an ES:DI pointer to an exo object, the window
; id in BX, new coordinates in (AL, AH) and moves the
; window in the system.
;
exo__movewin PROC
push ds
push si
push bx
;-------------------
;Load the endo win
;-------------------
shl bx, 1
shl bx, 1
lds si, es:[di].exo.data.wintbl[bx]
;-------------------
;Alter the endo win
;-------------------
mov ds:[si].endo.data.pxo, al
mov ds:[si].endo.data.pyo, ah
;-------------------
;Update the system
;-------------------
pop bx
pop si
pop ds
retf
exo__movewin ENDP
;
; exo__resizewin Takes an ES:DI pointer to an exo object, the window
; id in BX, new dimentions in (AL, AH) and resizes the
; window in the system.
;
exo__resizewin PROC
push ds
push si
push bx
;-------------------
;Load the endo win
;-------------------
shl bx, 1
shl bx, 1
lds si, es:[di].exo.data.wintbl[bx]
;-------------------
;Alter the endo win
;-------------------
cmp al, 1
jl error ; smallest win is 1x1
cmp ah, 1
jl error
mov ds:[si].endo.data.pxs, al
mov ds:[si].endo.data.pys, ah
;-------------------
;Update the system
;-------------------
error:
pop bx
pop si
pop ds
retf
exo__resizewin ENDP
;
; exo__floatwin Takes an ES:DI pointer to an exo object, as well
; the window id in BX, and places that window logically
; on the top of a screen.
;
exo__floatwin PROC
push ax ;ax = old
push bx ;bx = new
push dx
push si
push ds
shl bx,1
shl bx,1
lds si, es:[di].exo.data.wintbl[bx]
shr bx, 1
shr bx, 1
mov al, es:[di].exo.data.top;Hold old top win
cmp al, bl
je done ;already top
cmp bl, es:[di].exo.data.bottom
je is_bottom
jmp not_bottom
is_bottom:
push ds
push si
push bx
push ax
mov al, ds:[si].endo.data.above
mov es:[di].exo.data.bottom, al
mov bl, ds:[si].endo.data.above
shl bx,1
shl bx,1
lds si, es:[di].exo.data.wintbl[bx]
mov ds:[si].endo.data.below, 0
pop ax
jmp share
not_bottom:
push ds
push si
push bx
push cx
mov ch, ds:[si].endo.data.above
mov cl, ds:[si].endo.data.below
mov bl, ch
shl bx, 1
shl bx, 1
lds si, es:[di].exo.data.wintbl[bx]
mov ds:[si].endo.data.below, cl
mov bl, cl
shl bx, 1
shl bx, 1
lds si, es:[di].exo.data.wintbl[bx]
mov ds:[si].endo.data.above, ch
pop cx
share:
mov bl, es:[di].exo.data.top
shl bx,1
shl bx,1
lds si, es:[di].exo.data.wintbl[bx]
pop bx
mov ds:[si].endo.data.above, bl
pop si
pop ds
mov al, es:[di].exo.data.top
mov ds:[si].endo.data.below, al
mov ds:[si].endo.data.above, 0
mov es:[di].exo.data.top, bl
done:
pop ds
pop si
pop dx
pop bx
pop ax
retf
exo__floatwin ENDP
;
; exo__sinkwin Takes an ES:DI pointer to an exo object, as well
; the window id in BX, and places that window logically
; on the bottom of a screen.
;
exo__sinkwin PROC
push ax ;ax = old
push bx ;bx = new
push dx
push si
push ds
shl bx,1
shl bx,1
lds si, es:[di].exo.data.wintbl[bx]
shr bx, 1
shr bx, 1
mov al, es:[di].exo.data.bottom ;Hold bottom win
cmp al, bl
je done ;already bottom
cmp bl, es:[di].exo.data.top
je is_top
jmp not_top
is_top:
push ds
push si
push bx
push ax
mov al, ds:[si].endo.data.below
mov es:[di].exo.data.top, al
mov bl, ds:[si].endo.data.below
shl bx,1
shl bx,1
lds si, es:[di].exo.data.wintbl[bx]
mov ds:[si].endo.data.above, 0
pop ax
jmp share
not_top:
push ds
push si
push bx
push cx
mov ch, ds:[si].endo.data.above
mov cl, ds:[si].endo.data.below
mov bl, ch
shl bx, 1
shl bx, 1
lds si, es:[di].exo.data.wintbl[bx]
mov ds:[si].endo.data.below, cl
mov bl, cl
shl bx, 1
shl bx, 1
lds si, es:[di].exo.data.wintbl[bx]
mov ds:[si].endo.data.above, ch
pop cx
share:
mov bl, es:[di].exo.data.bottom
shl bx,1
shl bx,1
lds si, es:[di].exo.data.wintbl[bx]
pop bx
mov ds:[si].endo.data.below, bl
pop si
pop ds
mov al, es:[di].exo.data.bottom
mov ds:[si].endo.data.above, al
mov ds:[si].endo.data.below, 0
mov es:[di].exo.data.bottom, bl
done:
pop ds
pop si
pop dx
pop bx
pop ax
retf
exo__sinkwin ENDP
;
; exo__update Given an ES:DI pointer to an exo object, updates
; the physical screen based on the recent state of
; the VSM.
;
exo__update PROC
push ax
push bx
push cx
push dx
push si
push di
push bp
push es
push ds
;-------------------
;es:di is either
;this or video
;-------------------
;-------------------
;ds:si is either
;VSM or logical
;-------------------
mov cx, es:[di].exo.data.VSMsize
lds si, es:[di].exo.data.VSM
xor bp, bp ;bp <- 0
update_lp:
mov bx, WORD PTR ds:[si][bp] ;VSM winID
mov ax, WORD PTR ds:[si][bp][2] ;VSM offset
push ds
push si
cmp bx, 0
jne maybe_border
mov al, ' '
jmp put_data
maybe_border:
cmp bx, exo__TOPB
jne nextr
mov al, 205d
jmp put_data
nextr: cmp bx, exo__RIGHTB
jne nextb
mov al, 186d
jmp put_data
nextb: cmp bx, exo__BOTTOMB
jne nextl
mov al, 205d
jmp put_data
nextl: cmp bx, exo__LEFTB
jne nextulc
mov al, 186d
jmp put_data
nextulc: cmp bx, exo__ULCB
jne nexturc
mov al, 201d
jmp put_data
nexturc: cmp bx, exo__URCB
jne nextlrc
mov al, 187d
jmp put_data
nextlrc: cmp bx, exo__LRCB
jne nextllc
mov al, 188d
jmp put_data
nextllc: cmp bx, exo__LLCB
jne not_border
mov al, 200d
jmp put_data
loop_middle:
jmp update_lp
not_border:
shl bx, 1
shl bx, 1
lds si, es:[di].exo.data.wintbl[bx]
lds si, ds:[si].endo.data.logical
xchg ax, bx
mov ax, ds:[si][bx]
put_data:
mov ah, es:[di].exo.data.attr
push es
push di
les di, es:[di].exo.data.videoRAM
shr bp, 1
mov WORD PTR es:[di][bp], ax
shl bp, 1
pop di
pop es
pop si
pop ds
add bp, 4
loop loop_middle
pop ds
pop es
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
retf
exo__update ENDP
;
; exo__clear Given an ES:DI pointer to a exo object, clears
; the screen in text mode.
;
exo__clear PROC
push ax
push bx
push cx
push di
push es
pushf
;------------------
;Remember default
;attribute
;------------------
mov bl, es:[di].exo.data.attr
;------------------
;Find the size of
;video to clear
;------------------
mov cx, es:[di].exo.data.VSMsize
;------------------
;Load es:di to base
;of video
;------------------
les di, es:[di].exo.data.videoRAM
cld ;Forward direction
mov ah, bl
mov al, ' '
rep stosw
popf
pop es
pop di
pop cx
pop bx
pop ax
retf
exo__clear ENDP
_EXPRESSC ENDS
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -