pcs/xli.mac

181 lines
4.5 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

subttl Macro definitions
; In segment 'segzero' set $ to the next multiple of 'n'.
align macro n,segzero
org $ - (($-segzero) MOD n) + n
endm
; Issue a DOS function request (int 21h) after
; setting up registers ax,bx,cx,dx,ds,es.
; Registers not specified are not affected by the macro,
; code to move a reg to itself is skipped, and
; moves between DS and ES are handled.
dos_fr macro rax,rbx,rcx,rdx,rds,res
ifnb <rax> ;;ax
ifidn <rax>,<ax>
else
mov ax,rax
endif
endif
ifnb <rbx> ;;bx
ifidn <rbx>,<bx>
else
mov bx,rbx
endif
endif
ifnb <rcx> ;;cx
ifidn <rcx>,<cx>
else
mov cx,rcx
endif
endif
ifnb <rdx> ;;dx
ifidn <rdx>,<dx>
else
mov dx,rdx
endif
endif
ifnb <res> ;;es
ifidn <res>,<ds>
push ds
pop es
else
ifidn <res>,<es>
else
mov es,res
endif
endif
endif
ifnb <rds> ;;ds
ifidn <rds>,<es>
push es
pop ds
else
ifidn <rds>,<ds>
else
mov ds,rds
endif
endif
endif
int 21h
endm
; Given the value of "active_exe", put into BX the corresponding byte offset
; into various tables. If table="itself", just load BX.
;
; Note: The calculated byte offset must fit into BL because we use BH for
; scratch. We don't affect any other register this way. If the
; number of entries allowed in the tables is enlarged so that we
; could overflow into BH, this macro will need changing. Changing
; a table's format will obviously affect this macro too.
load_index macro table
mov bx,active_exe
ifdif <itself>,<table>
xor bh,bh
endif
ifidn <load_table>,<table>
shl bx,1 ;; 2 bytes/entry
endif
ifidn <fb_table>,<table>
shl bx,1 ;; 4
shl bx,1
endif
ifidn <pb_table>,<table>
shl bx,1 ;; 4
shl bx,1
endif
ifidn <state_table>,<table>
mov bh,bl
shl bx,1 ;;shift BH and BL simultaneously
shl bl,1
shl bl,1
add bl,bh ;; 10
xor bh,bh
endif
ifidn <status_table>,<table>
shl bx,1 ;; 2
endif
endm
; *** All registers on entry except CS,IP belong to the child. ***
; *** On exit, all registers except CS,IP,DS still belong to the child. ***
; This routine captures all the child's registers' values (except CS:IP,
; which is located on the stack at the saved SS:SP).
; DS is changed to PCS's data segment.
save_state macro
push ds ;pushes are in child's data segment
push ax
mov ax,data
mov ds,ax ;DS points to PCS's data segment
pop ax ;get back ax
mov save_ax,ax
mov save_bx,bx
mov save_cx,cx
mov save_dx,dx
mov save_si,si
mov save_di,di
pop ax ;get back ds (stack now same as on entry)
mov save_ds,ax
mov save_es,es
mov save_ss,ss
mov save_sp,sp
mov save_bp,bp
endm
; Save the parent's (i.e. PCS's) segment and pointer registers.
save_parent macro
mov pcs_state.st_es,es ;save our state
mov pcs_state.st_ss,ss
mov pcs_state.st_sp,sp
mov pcs_state.st_bp,bp
mov pcs_state.st_ds,ds
endm
; Restore the parent's segment and pointer registers.
restore_parent macro
mov bx,offset pcs_state ;restore parent's state
cli
mov es,[bx].st_es
mov ss,[bx].st_ss
mov sp,[bx].st_sp
mov bp,[bx].st_bp
;; mov ds,[bx].st_ds ;save_state made DS active already
sti
endm
; Save off our registers and restore child's, then resume child.
call_child macro x
save_parent
load_index state_table
lea bx,state_table[bx]
cli ; restore child's state
mov es,[bx].st_es
mov ss,[bx].st_ss
mov sp,[bx].st_sp
mov bp,[bx].st_bp
mov ds,[bx].st_ds
sti
xlidbg&x label byte
nop ;;this gets replaced with INT 3 for debug
nop
db 0CBh ;resume child via far return
endm
; Save off child's registers and restore ours, then continue.
resume_parent macro
save_state ;save child's registers in global area
restore_parent
load_index state_table
lea bx,state_table[bx]
mov ax,save_ds ;save child's regs in child-local area
mov [bx].st_ds,ax
mov ax,save_es
mov [bx].st_es,ax
mov ax,save_ss
mov [bx].st_ss,ax
mov ax,save_sp
mov [bx].st_sp,ax
mov ax,save_bp
mov [bx].st_bp,ax
endm