From 2d04cacc5322951f187bb17e017c12920ac8ebe2 Mon Sep 17 00:00:00 2001 From: Mark Zbikowski Date: Thu, 25 Apr 2024 21:24:10 +0100 Subject: MZ is back! --- v4.0/src/INC/DOSMAC.INC | 630 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 630 insertions(+) create mode 100644 v4.0/src/INC/DOSMAC.INC (limited to 'v4.0/src/INC/DOSMAC.INC') diff --git a/v4.0/src/INC/DOSMAC.INC b/v4.0/src/INC/DOSMAC.INC new file mode 100644 index 0000000..ca21f8b --- /dev/null +++ b/v4.0/src/INC/DOSMAC.INC @@ -0,0 +1,630 @@ +; SCCSID = @(#)dosmac.asm 1.1 85/04/10 +; SCCSID = @(#)dosmac.asm 1.1 85/04/10 +; +; Macro file for MSDOS. +; + +TRUE EQU 0FFFFh +FALSE EQU 0 + +SUBTTL BREAK a listing into pages and give new subtitles +PAGE +BREAK MACRO subtitle + SUBTTL subtitle + PAGE +ENDM +.xcref break + +BREAK + +AsmVars Macro varlist +IRP var, +AsmVar var +ENDM +ENDM + +AsmVar Macro var +IFNDEF var +var = FALSE +ENDIF +ENDM + +BREAK + +; +; declare a variable external and allocate a size +; +AsmVar InstalledData +I_NEED MACRO sym,len +IF NOT InstalledData + DATA SEGMENT WORD PUBLIC 'DATA' + IFIDN , + EXTRN &sym:WORD + ELSE + IFIDN , + EXTRN &sym:DWORD + ELSE + EXTRN &sym:BYTE + ENDIF + ENDIF + DATA ENDS +ENDIF +ENDM + .xcref I_need + +; +; call a procedure that may be external. The call will be short. +; +invoke MACRO name +.xcref + IF2 + IFNDEF name + EXTRN name:NEAR + ENDIF + ENDIF +.cref + CALL name +ENDM +.xcref invoke + +PAGE +; +; jump to a label that may be external. The jump will be near. +; +transfer MACRO name +.xcref + IF2 + IFNDEF name + EXTRN name:NEAR + ENDIF + ENDIF +.cref + JUMP name +ENDM +.xcref transfer + +; +; get a short address in a word +; +short_addr MACRO name + IFDIF , +.xcref + IF2 + IFNDEF name + EXTRN name:NEAR + ENDIF + ENDIF +.cref + DW OFFSET DOSGROUP:name + ELSE + DW ? + ENDIF +ENDM +.xcref short_addr + +; +; get a long address in a dword +; +long_addr MACRO name +.xcref + IF2 + IFNDEF name + EXTRN name:NEAR + ENDIF + ENDIF +.cref + DD name +ENDM +.xcref long_addr + +; +; declare a PROC near or far but PUBLIC nonetheless +; +.xcref ?frame +.xcref ?aframe +.xcref ?stackdepth +.xcref ?initstack +?frame = 0 ; initial +?aframe = 0 ; initial +?stackdepth = 0 ; initial stack size +?initstack = 0 ; initial stack size + +procedure MACRO name,distance + ?frame = 0 + ?aframe = 2 ;; remember the pushed BP + PUBLIC name + IF1 + %OUT name... pass 1 + ENDIF + IF2 + %OUT name... pass 2 + ENDIF +name PROC distance + ?initstack = ?stackdepth ;; beginning of procedure +ENDM +.xcref procedure + +; +; end a procedure and check that stack depth is preserved +; +EndProc MACRO name, chk + IFDIF , ;; check the stack size + IF2 + IF ?initstack NE ?stackdepth ;; is it different? + %OUT ***** Possible stack size error in name ***** + ENDIF + ENDIF + ENDIF +name ENDP +ENDM +.xcref endproc +PAGE +; +; define a data item to be public and of an appropriate size/type +; + +I_AM MACRO name,size,init +;; declare the object public + PUBLIC name +;; declare the type of the object + IFIDN , +name LABEL WORD + I_AM_SIZE = 1 + I_AM_LEN = 2 + ELSE + IFIDN , +name LABEL DWORD + I_AM_SIZE = 2 + I_AM_LEN = 2 + ELSE + IFIDN , +name LABEL BYTE + I_AM_SIZE = 1 + I_AM_LEN = 1 + ELSE +name LABEL BYTE + I_AM_SIZE = size + I_AM_LEN = 1 + ENDIF + ENDIF + ENDIF +;; if no initialize then allocate blank storage + IFB + DB I_AM_SIZE*I_AM_LEN DUP (?) + ELSE +IF NOT InstalledData + IRP itm, + IF I_AM_LEN EQ 1 + DB itm + ELSE + DW itm + ENDIF + I_AM_SIZE = I_AM_SIZE - 1 + ENDM + IF I_AM_SIZE NE 0 + %out ***** initialization of name not complete ***** + ENDIF +ELSE + DB I_AM_SIZE*I_AM_LEN DUP (?) +ENDIF + ENDIF +ENDM +.xcref I_AM +.xcref I_AM_SIZE +.xcref I_AM_LEN +I_AM_SIZE = 0 +I_AM_LEN = 0 + +PAGE + +; +; define an entry in a procedure +; +entry macro name + PUBLIC name +name: +endm +.xcref entry + +BREAK + +error macro code +.xcref + MOV AL,code + transfer SYS_RET_ERR +.cref +ENDM +.xcref error + +BREAK +; +; given a label either 2 byte jump to another label _J +; if it is near enough or 3 byte jump to +; + +jump macro lbl + local a +.xcref + + ifndef lbl&_J ;; is this the first invocation +a: JMP lbl + ELSE + IF (lbl&_J GE $) OR ($-lbl&_J GT 126) +a: JMP lbl ;; is the jump too far away? + ELSE +a: JMP lbl&_J ;; do the short one... + ENDIF + ENDIF + lbl&_j = a +.cref +endm +.xcref jump + +BREAK + +return macro x + local a +.xcref +a: + RET +ret_l = a +.cref +endm +.xcref return + +BREAK + +condret macro cc,ncc + local a +.xcref +.xcref a +.cref + ifdef ret_l ;; if ret_l is defined + if (($ - ret_l) le 126) and ($ gt ret_l) + ;; if ret_l is near enough then + a: j&cc ret_l ;; a: j to ret_l + ret_&cc = a ;; define ret_ to be a: + exitm + endif + endif + ifdef ret_&cc ;; if ret_ defined + if (($ - ret_&cc) le 126) and ($ gt ret_&cc) + ;; if ret_ is near enough + a: j&cc ret_&cc ;; a: j to ret_ + ret_&cc = a ;; define ret_ to be a: + exitm + endif + endif + j&ncc a ;; j a: + return ;; return + a: ;; a: + ret_&cc = ret_l ;; define ret_ to be ret_l +endm +.xcref condret + +BREAK + +retz macro + condret z,nz +endm +.xcref retz + +BREAK + +retnz macro + condret nz,z +endm +.xcref retnz + +BREAK + +retc macro + condret c,nc +endm +.xcref retc + +BREAK + +retnc macro + condret nc,c +endm +.xcref retnc + +BREAK + +context macro r + PUSH SS + POP r + ASSUME r:DOSGROUP +endm +.xcref context + +BREAK + +SaveReg MACRO reglist ;; push those registers +IRP reg, + ?stackdepth = ?stackdepth + 1 + PUSH reg +ENDM +ENDM +.xcref SaveReg + +BREAK + +RestoreReg MACRO reglist ;; pop those registers +IRP reg, + ?stackdepth = ?stackdepth - 1 + POP reg +ENDM +ENDM +.xcref RestoreReg + +BREAK + +EnterCrit MACRO section + Invoke E§ion +ENDM + +LeaveCrit MACRO section + Invoke L§ion +ENDM + +Break + +AsmVars + +if debug +fmt MACRO typ,lev,fmts,args +local a,b,c + PUSHF +IFNB + TEST BugTyp,typ + JZ c + CMP BugLev,lev + JB c +ENDIF + PUSH AX + PUSH BP + MOV BP,SP +If (not sharef) and (not redirector) +Table segment +a db fmts,0 +Table ends + MOV AX,OFFSET DOSGROUP:a +else + jmp short b +a db fmts,0 +if sharef +b: mov ax,offset share:a +else +b: mov ax,offset netwrk:a +endif +endif + PUSH AX +cargs = 2 +IRP item, +IFIDN , + MOV AX,[BP+2] +ELSE + MOV AX,item +ENDIF + PUSH AX +cargs = cargs + 2 +ENDM + invoke PFMT + ADD SP,Cargs + POP BP + POP AX +c: + POPF +ENDM +else +fmt macro +endm +endif + +Break + +AsmVar Debug,$temp + +IF debug +DOSAssume Macro reg,reglist,message +local a,b + IFIDN , + $temp = 1 + ELSE + IFIDN , + $temp = 0 + ELSE + %out ***** Invalid DOS register reg in DOSAssume ***** + ENDIF + ENDIF + IRP r, + IFIDN , + $temp = $temp OR 2 + ELSE + IFIDN , + $temp = $temp OR 4 + ELSE + %out ***** Invalid register reg in DOSAssume ***** + ENDIF + ENDIF + ENDM + PUSH AX + MOV AX,$temp + PUSH AX +IF SHAREF + MOV AX,OFFSET a +ELSE + MOV AX,OFFSET DOSGroup:a +ENDIF + PUSH AX + Invoke SegCheck + POP AX +IF NOT SHAREF +Table SEGMENT +a DB message,0 +Table ends +ELSE + JMP SHORT a +b DB message,0 +a: +ENDIF +IRP r, + ASSUME r:DOSGroup +ENDM +ENDM +ELSE +DOSAssume Macro reg,reglist,message +IRP r, + ASSUME r:DOSGroup +ENDM +ENDM +ENDIF + +BREAK + +IF DEBUG +Assert MACRO kind, objs, message + LOCAL a,b + IFIDN , + CMP objs,0 + JZ a + fmt <>,<>, +a: + ELSE + IFIDN , + CMP objs,0 + JNZ a + fmt <>,<>, +a: + ELSE + PUSH AX + IRP obj, + PUSH obj + ENDM + IF SHAREF + MOV AX,OFFSET b + ELSE + MOV AX,OFFSET DOSGroup:b + ENDIF + PUSH AX + IFIDN , + Invoke BUFCheck + ENDIF + IFIDN , + Invoke SFTCheck + ENDIF + IFIDN , + Invoke DPBCheck + ENDIF + POP AX + IF SHAREF + JMP SHORT a +b DB Message,0 +a: + ELSE +Table segment +b db Message,0 +Table ends + ENDIF + ENDIF + ENDIF +ENDM +ELSE +Assert Macro +ENDM +ENDIF + +Break + +CallInstall MACRO name,mpx,fn,save,restore +IF Installed + IFNB + SaveReg + ENDIF + MOV AX,(mpx SHL 8) + fn + INT 2Fh + IFNB + RestoreReg + ENDIF +ELSE + Invoke name +ENDIF +ENDM + +Break + +localvar macro name,length +local a + ifidn , + ?frame = ?frame + 1 + a = ?frame + name EQU BYTE PTR [BP-a] + else + ifidn , + ?frame = ?frame + 2 + a = ?frame + name EQU WORD PTR [BP-a] + else + ifidn , + ?frame = ?frame + 4 + a = ?frame + name EQU DWORD PTR [BP-a] + name&l EQU WORD PTR [BP-a] + name&h EQU WORD PTR [BP-a+2] + else + ?frame = ?frame + length + a = ?frame + name EQU BYTE PTR [BP-a] + endif + endif + endif +endm + +enter macro + push bp + mov bp,sp + sub sp,?frame +endm + +leave macro + mov sp,bp + pop bp +endm + +Argvar macro name,length +local a + ifidn , + a = ?aframe + ?aframe = ?aframe + 1 + name EQU BYTE PTR [BP+a] + else + ifidn , + a = ?aframe + ?aframe = ?aframe + 2 + name EQU WORD PTR [BP+a] + else + ifidn , + a = ?aframe + ?aframe = ?aframe + 4 + name EQU DWORD PTR [BP+a] + name&l EQU WORD PTR [BP+a] + name&h EQU WORD PTR [BP+a+2] + else + a = ?aframe + ?aframe = ?aframe + length + name EQU BYTE PTR [BP+a] + endif + endif + endif +endm + +BREAK + +errnz macro x +if x NE 0 + %out ***** FATAL error: x <> 0 +foobar +endif +endm -- cgit v1.2.3