;------------------------------------------------ ; vmap.asm ; ; Copyright (c) 1991 by c.mos ;------------------------------------------------ STDSEG equ TRUE include std.inc ;----- Equations ----- MCBNM_UMB equ 4D55h ; 'UM' MCBNM_SD equ 4453h ; 'SD' MCBNM_SC equ 4353h ; 'SC' VECTCOLMS equ 48 XMSCOLMS equ 44 OWNERCOLMS equ 23 OWNER_SYS equ 0008h FREE_MIN equ 6 SUBSEGCNT equ 5 OPTIONCNT equ 5 OPT_C equ 00001b OPT_U equ 00010b OPT_M equ 00100b OPT_E equ 01000b OPT_N equ 10000b OPT_MAX equ 10000b ;----- Structures ----- Mcb struc mcb_id db ? mcb_owner dw ? mcb_size dw ? mcb_reserved db 3 dup(?) mcb_name db 8 dup(?) Mcb ends Work struc codeSeg dw ? mcbtopSeg dw ? mcbnow dw ? mcbnext dw ? mcbskip dw ? pspSeg dw ? shellSeg dw ? condevSeg dw ? owner dw ? putp dw ? total dw ? emsver dw ? emsver2 dw ? emsframe dw ? xmsver dw ? xmsver2 dw ? hmaused dw ? hmaowner dw ? embfree dw ? embmax dw ? xms dd ? dskbufPtr dd ? version db ? db ? vectcnt db ? subsegment db ? umb db ? dspown db ? dspvct db ? option db ? namebuf db 8 dup(?) Work ends cseg ;----- PSP definitions ----- org 2Ch psp_envseg label word org 81h psp_cmdline label byte ;----- VMAP main ----- org 100h entry: mov si,offset cgroup: mg_title call puts mov bp,offset cgroup: bpwork mov [bp].codeSeg,cs call readoption _if c mov si,offset cgroup: mg_usage call puts _else call sputbegin msdos F_VERSION mov word ptr [bp].version,ax test [bp].option,OPT_C+OPT_U+OPT_M _ifn z mov si,offset cgroup: mg_memhead call puts call memarena _endif test [bp].option,OPT_E _ifn z call ems_xms _endif _endif msdos F_TERM,0 ;----- Read options ----- ;<-- CY :option error readoption proc mov si,offset cgroup: psp_cmdline clr dl _repeat lodsb cmp al,CR _break e cmp al,'?' _cont b cmp al,'a' _if ae cmp al,'z' _if be sub al,'a'-'A' _endif _endif mov di,offset cgroup: optiontbl mov cx,OPTIONCNT repne scasb _if e mov ah,OPT_MAX shr ah,cl or dl,ah _else stc VZ_RET _endif _until test dl,not OPT_N _if z or dl,OPT_M+OPT_E _endif mov [bp].option,dl clc VZ_RET readoption endp ;------------------------------------------------ ; Memory Arena ;------------------------------------------------ memarena proc mov bx,-1 msdos F_MALLOC cmp ax,ECONTR je err_mcb clr ax mov es,ax mov ax,es:[2Eh*4+2] mov [bp].shellSeg,ax msdos F_PARMTBL mov ax,es:[bx-2] mov [bp].mcbtopSeg,ax mov ax,es:[bx+0Eh] mov [bp].condevSeg,ax mov ax,es:[bx+12h] mov word ptr [bp].dskbufPtr,ax mov ax,es:[bx+14h] mov word ptr [bp].dskbufPtr+2,ax test [bp].option,OPT_M+OPT_U _ifn z call isexistumb jc err_mcb tst ax _ifn z mov [bp].umb,TRUE call walkarena call disp_umbsize _endif _endif test [bp].option,OPT_M+OPT_C _ifn z mov ax,[bp].mcbtopSeg mov [bp].umb,FALSE call walkarena _if c err_mcb: call putcrlf mov si,offset cgroup: ng_arena call puts _endif _endif VZ_RET ;----- Is exist UMB ? ----- ;<-- AX :UMB top segment (0=not exist) ; CY :error isexistumb proc clr di mov ds,[bp].mcbtopSeg _repeat mov al,[di].mcb_id call nextmcb cmp al,'Z' je isumb1 cmp al,'M' _while e stc VZ_RET isumb1: cmp [di].mcb_id,'M' jne isumb2 cmp [di].mcb_owner,OWNER_SYS jne isumb2 call nextmcb mov ax,ds foundumb: clc VZ_RET isumb2: mov ax,ds clr al inc ah _repeat mov ds,ax cmp [di].mcb_id,'M' _if e call nextmcb call check_mcb je foundumb _endif add ax,100h cmp ax,0F000h _until ae clr ax VZ_RET isexistumb endp ;----- Display UMB total ----- disp_umbsize proc mov ax,OWNERCOLMS call sfillspc mov ax,[bp].total mov cl,6 shr ax,cl inc ax push ax mov si,offset cgroup: pf_umbsize call printf1 pop ax call putcrlf VZ_RET disp_umbsize endp ;----- Walk Memory Arena ----- ;--> AX :start segment ;<-- CY :error walkarena proc mov [bp].subsegment,FALSE mov [bp].total,0 arena1: clr di mov [bp].mcbskip,di mov [bp].dspown,FALSE mov [bp].dspvct,TRUE mov ds,ax mov [bp].mcbnow,ax call check_mcb _ifn e tstb [bp].subsegment jnz arena2 stc VZ_RET _endif mov [bp].subsegment,FALSE cmp [bp].version,4 _if ae cmp [di].mcb_owner,OWNER_SYS _if e cmp word ptr [di].mcb_name,MCBNM_SD _if e mov ax,ds inc ax mov [bp].subsegment,TRUE jmp arena1 _endif _endif _endif arena2: call stack_mcbs add [bp].total,cx call disp_header call disp_owner_parm tstb [bp].dspvct _ifn z call disp_vect _endif call putcrlf mov ax,[bp].mcbnext tst ax jnz arena1 VZ_RET ;----- Stack MCBs ----- stack_mcbs proc movseg es,ds mov ax,[di].mcb_owner ; AX :owner call check_sys _ifn z mov ax,OWNER_SYS _endif mov bx,1 ; BX :blks mov cx,[di].mcb_size ; CX :size cmp ax,[bp].codeSeg _if e clr ax ; if owner=me, it's free _endif mov [bp].owner,ax mov [bp].pspSeg,0 push ds stkmcb1: mov dx,ds inc dx cmp ax,dx _if e mov [bp].pspSeg,ax _endif call check_mcb _if e mov [bp].subsegment,FALSE _endif cmp [di].mcb_id,'Z' _if e add dx,[di].mcb_size mov [bp].mcbskip,dx mov [bp].mcbnext,0 jmps stkmcb8 _endif stkmcb2: call nextmcb mov [bp].mcbnext,ds mov dx,[di].mcb_owner tst dx _if z cmp [di].mcb_size,FREE_MIN jbe stkmcb3 _endif tstb [bp].umb _ifn z tstw [bp].mcbskip jnz stkmcb8 cmp dx,OWNER_SYS _if e cmp word ptr [di].mcb_name,MCBNM_SC je skip_rom _endif call check_rom _ifn c skip_rom: mov [bp].mcbskip,ds jmp stkmcb2 _endif _endif call check_mcb _ifn e call check_sys _ifn z mov dx,OWNER_SYS _else call cmp_name je stkmcb3 _endif _endif tstb [bp].umb _ifn z push ax mov ax,[di].mcb_size cmp ax,es:[di].mcb_size pop ax je stkmcb4 _endif cmp dx,[bp].codeSeg _if e clr dx _endif cmp ax,dx jne stkmcb8 stkmcb3: test [bp].option,OPT_N jnz stkmcb8 stkmcb4: tst ax _ifn z inc bx _endif add cx,[di].mcb_size jmp stkmcb1 stkmcb8: pop ds VZ_RET stack_mcbs endp ;----- Compare MCB owner name ----- ;<-- ZR :equal cmp_name proc pushm mov si,mcb_name mov di,si mov cx,8 repe cmpsb popm VZ_RET cmp_name endp ;----- Check ROM ----- ;<-- CY :not ROM check_rom proc push ax tstw [bp].pspSeg jnz notrom cmp dx,0FF00h jl notrom mov ax,ds cmp al,0FFh _if e inc ax add ax,[di].mcb_size tst al jz yesrom _endif notrom: stc yesrom: pop ax VZ_RET check_rom endp ;----- Display MCB header ----- ;--> AX :owner ; BX :blks ; CX :size disp_header proc push ax mov ax,ds inc ax push ax mov si,offset cgroup: pf_addr call printf1 pop dx pop ax tst ax _ifn z mov si,offset cgroup: mg_sys cmp ax,OWNER_SYS je dsppsp call check_sys1 jz dsppsp mov si,offset cgroup: pf_psp cmp ax,dx _if e mov si,offset cgroup: mg_larrow _endif _else mov si,offset cgroup: mg_blank mov ax,[bp].mcbskip tst ax _ifn z mov si,offset cgroup: pf_freeto _endif _endif dsppsp: push ax call printf1 pop ax mov dx,cx mov cl,4 rol dx,cl mov cx,dx and dx,0000Fh and cx,0FFF0h push dx push cx push bx mov si,offset cgroup: pf_blks_size call printf1 add sp,6 VZ_RET disp_header endp ;----- Display owner/parameters ----- disp_owner_parm proc movseg ds,ss mov ax,[bp].owner mov si,offset cgroup: mg_free tst ax jz dspowner cmp ax,OWNER_SYS _if e mov si,offset cgroup: mg_config test [bp].option,OPT_N _ifn z cmp [bp].version,4 _if ae call issubseg _endif _endif dspowner: call sputs mov [bp].dspvct,FALSE jmps dspowpr9 _endif cmp [bp].version,4 _if ae dec ax mov ds,ax cmp [di].mcb_id,'M' _ifn e mov ds,[bp].mcbnow mov [bp].pspSeg,ds _endif mov si,mcb_name call sputlower call isdevice jc dspowpr9 _else mov ds,ax cmp [di],20CDh ; is PSP ? _ifn e call isdevice jc dspowpr9 call isbuffers mov si,offset cgroup: mg_buffers jc dspowner jmps dspowpr9 _endif cmp ax,[bp].shellSeg _if e movseg ds,ss mov si,offset cgroup: mg_shell call sputs jmps dspenv _endif mov dx,ax cmp [bp].version,3 jb dspparm mov ax,psp_envseg tst ax jz dspparm dec ax mov ds,ax cmp [di].mcb_owner,dx jne dspparm inc ax mov es,ax call disp_envowner _endif dspenv: tstw [bp].pspSeg _if z call disp_env jmps dspowpr9 _endif dspparm: call disp_param dspowpr9: VZ_RET disp_owner_parm endp ;----- Is device subsegment ? ----- ;-->*SI :message issubseg proc push di mov es,[bp].mcbnow mov al,es:[di].mcb_id movseg es,ss mov di,offset cgroup: subsegIDs mov cx,SUBSEGCNT repne scasb _if e shl cx,1 mov si,offset cgroup: subsegnames + SUBSEGCNT*2 - 2 sub si,cx mov si,[si] _endif pop di VZ_RET issubseg endp ;----- Is CON device ? ----- ;<-- CY :Yes isdevice proc mov ax,[bp].condevSeg cmp ax,[bp].mcbnow jb not_dev cmp ax,[bp].mcbnext jae not_dev push ds mov ds,ax mov si,10 call sputspc call sputname pop ds stc VZ_RET not_dev: clc VZ_RET isdevice endp ;----- Is buffers ? ----- ;<-- CY :Yes isbuffers proc cmp [bp].version,3 jne not_buf mov dx,[bp].mcbnow inc dx lds si,[bp].dskbufPtr _repeat cmp si,-1 je not_buf mov ax,ds lds si,[si] cmp ax,dx _until z stc VZ_RET not_buf: clc VZ_RET isbuffers endp ;----- Display owner path in Env ----- ;--> ES :Env segment disp_envowner proc clr al clr di mov cx,-1 _repeat repnz scasb tstb es:[di] _until z inc di cmp word ptr es:[di],0001h jne dspown9 inc di inc di mov dx,di repnz scasb _repeat cmp di,dx _break e mov al,es:[di-1] cmp al,':' _break e cmp al,'\' _break e cmp al,'/' _break e dec di _until movseg ds,es mov si,di call sputlower dspown9: clr di VZ_RET disp_envowner endp ;----- Display Env ----- disp_env proc mov ax,[bp].mcbnow mov ds,ax inc ax mov ds,[di].mcb_owner cmp ax,psp_envseg _if e movseg ds,ss mov si,offset cgroup: mg_env call sputs mov [bp].dspvct,FALSE _endif VZ_RET disp_env endp ;----- Display parameter ----- disp_param proc mov ds,[bp].pspSeg mov si,offset cgroup: psp_cmdline cmp [di],20CDh ; is PSP ? ##2.01 jne dsppr9 tstb [bp].dspown _ifn z _repeat lodsb cmp al,SPC _while a dec si _endif _repeat lodsb cmp al,SPC _break b call sputc mov ax,VECTCOLMS call sputlimit _while b dsppr9: VZ_RET disp_param endp ;----- Display fooked vectors ----- disp_vect proc clr dx mov [bp].vectcnt,0 mov es,dx mov bx,[bp].mcbnow mov dx,[bp].mcbnext mov di,2 mov cx,256 _repeat mov ax,es:[di] add di,4 cmp ax,bx _if ae cmp ax,dx jb dspvct1 _endif nextvct: _loop VZ_RET dspvct1: mov al,[bp].vectcnt tst al jz dspvct2 cmp al,10 _if e mov [bp].vectcnt,0 call putcrlf dspvct2: mov ax,VECTCOLMS+1 call sfillspc _endif mov ax,256 sub ax,cx push ax mov si,offset cgroup: pf_vect call printf1 pop ax inc [bp].vectcnt jmp nextvct disp_vect endp walkarena endp ;----- Next MCB ----- nextmcb proc mov dx,ds add dx,[di].mcb_size inc dx mov ds,dx VZ_RET nextmcb endp ;----- Check MCB ID ----- ;<-- NZ : error check_mcb proc cmp [di].mcb_id,'M' _ifn e cmp [di].mcb_id,'Z' _endif VZ_RET check_mcb endp ;----- Check System data ----- ;<-- NZ : system data check_sys proc tstb [bp].subsegment _ifn z check_sys1: cmp [di].mcb_id,'D' _ifn e cmp [di].mcb_id,'I' _endif _endif VZ_RET check_sys endp memarena endp ;------------------------------------------------ ; EMS and XMS ;------------------------------------------------ ems_xms proc clr ax mov [bp].emsver,ax mov [bp].xmsver,ax mov [bp].hmaused,ax call check_ems call check_xms mov bx,[bp].emsver mov cx,[bp].xmsver mov ax,bx or ax,cx _if z VZ_RET _endif call putcrlf tst bx _ifn z push [bp].emsframe push [bp].emsver2 push bx mov si,offset cgroup: pf_ems call printf1 add sp,6 _endif tst cx _ifn z call xmscolm push [bp].xmsver2 push cx mov si,offset cgroup: pf_xms call printf1 pop cx pop ax _endif call putcrlf tst bx _ifn z mov si,offset cgroup: mg_ems2 call sputs _endif tst cx _ifn z call xmscolm mov ax,[bp].hmaused tst ax _ifn z push [bp].hmaowner push ax mov si,offset cgroup: pf_hma call printf1 pop ax pop ax _else mov si,offset cgroup: mg_nohma call sputs _endif _endif call putcrlf tst bx _ifn z mov si,offset cgroup: mg_ems3 call sputs _endif tst cx _ifn z mov ax,[bp].embfree tst ax _ifn z push ax call xmscolm mov si,offset cgroup: pf_emb call printf1 pop ax cmp ax,[bp].embmax _ifn e push [bp].embmax mov si,offset cgroup: pf_embmax call printf1 pop ax _endif _endif _endif call putcrlf tst bx _ifn z call disp_emsblk emm 42h ; Get Unallocated Page Count mov si,offset cgroup: mg_emsfree call sputs mov ax,bx push dx call disp_page call putcrlf mov si,offset cgroup: mg_emstotal call sputs pop ax call disp_page call putcrlf _endif VZ_RET xmscolm proc tst bx _ifn z mov ax,XMSCOLMS call sfillspc _endif VZ_RET xmscolm endp ;----- Check EMS ----- check_ems proc msdos F_GETVCT,INT_EMS movseg ds,ss mov si,offset cgroup: emsid mov di,000Ah mov cx,8 repe cmpsb jne noems emm 40h ; Get Status tst ah jnz noems emm 41h ; Get Page Frame Address tst ah jnz noems cmp bx,0F000h ; avoid melware bug ja noems mov [bp].emsframe,bx emm 46h ; Get Version tst ah jnz noems push ax mov cl,4 shr al,cl mov [bp].emsver,ax pop ax and al,0Fh mov [bp].emsver2,ax noems: VZ_RET check_ems endp ;----- Check XMS ----- check_xms proc cmp [bp].version,3 jb noxms mov ax,4300h int 2Fh cmp al,80h jne noxms mov ax,4310h int 2Fh mov word ptr [bp].xms,bx mov word ptr [bp].xms+2,es mov ah,00h call [bp].xms tst ax jz noxms mov byte ptr [bp].xmsver,ah clr ah mov [bp].xmsver2,ax mov ah,07h call [bp].xms cmp ax,1 _if e call check_hma _endif mov ah,08h call [bp].xms mov [bp].embfree,ax mov [bp].embmax,dx noxms: VZ_RET check_xms endp ;----- Check HMA ----- check_hma proc mov ax,0FFFFh mov es,ax mov cx,ax mov di,0FFFEh inc ax std repz scasw cld mov cl,10 shr di,cl mov [bp].hmaused,di cmp [bp].version,5 _if ae msdos 33h,06h ; Get DOS Version for DOS5 mov si,offset cgroup: mg_dos test dh,10h jnz sethmaowner _endif movseg ds,es movseg es,ss mov si,12h lea di,[bp].namebuf mov cx,8 _repeat lodsb stosb cmp al,SPC jl hmaunknown _loop lea si,[bp].namebuf jmps sethmaowner hmaunknown: mov si,offset cgroup: mg_unknown sethmaowner: mov [bp].hmaowner,si VZ_RET check_hma endp ;----- Display EMS block ----- disp_emsblk proc movseg ds,ss movseg es,ss mov di,offset cgroup: heaptop emm 4Dh ; Get All Handle Pages mov cx,bx _repeat _break cxz add di,4 dec cx _break z push di push [di] mov si,offset cgroup: pf_emshandle call printf1 pop ax pop di mov ax,[di+2] call disp_page mov dx,[di] push di lea di,[bp].namebuf emm 53h,0 ; Get Handle Name tst ah _if z call sputspc call sputspc push di mov si,offset cgroup: pf_name8 call printf1 pop ax _endif pop di call putcrlf _until VZ_RET disp_emsblk endp ;----- Display EMS block page/size ----- ;--> AX :page count disp_page proc pushm mov bx,ax mov cl,4 shl ax,cl push ax push bx mov si,offset cgroup: pf_emspage call printf1 pop ax pop ax popm VZ_RET disp_page endp ems_xms endp ;------------------------------------------------ ; Print subroutines ;------------------------------------------------ ; ;----- Call printf ----- ;--> SI :format string ptr printf1 proc pushm movseg ds,ss movseg es,ss mov di,[bp].putp mov bx,sp add bx,10 call $sprintf dec di mov [bp].putp,di popm VZ_RET printf1 endp ;----- Put string ----- ;--> SI :string ptr public puts puts proc pushm movseg ds,ss movseg es,ss mov di,si clr al mov cx,-1 repnz scasb not cx dec cx _ifn z mov bx,1 mov dx,si msdos F_WRITE _endif popm VZ_RET puts endp ;----- Put CR/LF & flash ----- putcrlf proc push si mov si,offset cgroup: mg_crlf call sputs mov si,offset cgroup: pfbuf call puts call sputbegin pop si VZ_RET putcrlf endp ;----- Put string to buffer ----- sputbegin proc push bx mov bx,offset cgroup: pfbuf mov [bp].putp,bx mov byte ptr ss:[bx],0 pop bx VZ_RET sputbegin endp ; ;----- sput string ----- ;--> DS:SI :string ptr sputs proc push ds movseg ds,ss _repeat lodsb call sputc _until z pop ds VZ_RET sputs endp ; ;----- sput char ----- ;--> AL :char ;<-- ZR :char=00h sputspc: mov al,SPC sputc proc pushm movseg es,ss mov di,[bp].putp stosb tst al _ifn z mov [bp].putp,di mov byte ptr es:[di],0 _endif popm VZ_RET sputc endp ; ;----- sput 8 char ----- ;--> DS:SI :string ptr sputname proc push cx mov cx,8 _repeat lodsb call sputc _break z _loop pop cx VZ_RET sputname endp ; ;----- sput 8 char to lower case ----- ;--> DS:SI :string ptr sputlower proc push cx mov cx,8 _repeat lodsb cmp al,SPC _break be cmp al,'.' _break e call tolower call sputc mov [bp].dspown,TRUE _loop pop cx VZ_RET sputlower endp ; ;----- char to lower case ----- ;--> AL :char tolower proc cmp al,'A' _if ae cmp al,'Z' _if be add al,20h _endif _endif VZ_RET tolower endp ; ;----- sput limit ----- ;--> AX :limit colums ;<-- CY :ok sputlimit proc push ax add ax,offset cgroup: pfbuf cmp [bp].putp,ax pop ax VZ_RET sputlimit endp ; ;----- fill spaces ----- ;--> AX :columns sfillspc proc _repeat call sputlimit _break ae push ax call sputspc pop ax _until VZ_RET sfillspc endp $ld_strseg macro movseg ds,ss endm include sprintf.inc endcs ;------------------------------------------------ ; Messages ;------------------------------------------------ dseg mg_memhead db CR,LF db 'addr PSP blks size owner/parameters ' db 'hooked vectors',CR,LF db '---- ---- ---- ------ ------------------------- ' db '-----------------------------' mg_crlf db CR,LF,0 ng_arena db '***** Memory Arena Trashed!',BELL,CR,LF,0 mg_free db '',0 mg_config db '',0 mg_shell db 'command',0 mg_env db ' (env)',0 pf_addr db '%04x',0 pf_psp db ' %04x',0 mg_blank db ' ',0 pf_freeto db '-%04x',0 mg_sys db ' sys ',0 mg_larrow db ' <-- ',0 pf_blks_size db '%4d%8ld ',0 pf_vect db ' %02x',0 pf_umbsize db '--- UMB total:%4d KB ---',0 emsid db 'EMMXXXX0' pf_ems db '----- EMS ver%d.%d (frame: %04xh) -----',0 mg_ems2 db 'handle pages size name',0 mg_ems3 db '------ ----- ------ --------',0 pf_emshandle db '%6d',0 pf_emspage db '%6d%6dk',0 mg_emsfree db ' free',0 mg_emstotal db ' total',0 pf_xms db '----- XMS ver%d.%02x -----',0 pf_hma db 'HMA used: %d KB by ' pf_name8 db '%8s',0 mg_nohma db 'HMA not used',0 pf_emb db 'EMB free: %d KB',0 pf_embmax db ' (max: %d KB)',0 mg_dos db 'DOS',0 mg_unknown db '???',0 subsegIDs db 'FXBLS' subsegnames dw offset cgroup:mg_files dw offset cgroup:mg_fcbs dw offset cgroup:mg_buffers dw offset cgroup:mg_lastdrv dw offset cgroup:mg_stacks mg_files db '',0 mg_fcbs db '',0 mg_buffers db '',0 mg_lastdrv db '',0 mg_stacks db '',0 mg_title db 'VMAP Version 2.01 Copyright (C) 1989-91 by c.mos' db CR,LF,0 mg_usage db 'Usage: vmap [c|u|m|e|n]',CR,LF db TAB,'c: Conventional Memory',CR,LF db TAB,'u: Upper Memory Blocks (UMB)',CR,LF db TAB,'m: Conventional & Upper Memory',CR,LF db TAB,'e: EMS & XMS',CR,LF db TAB,'n: No compress multi blocks',CR,LF db 0 optiontbl db 'CUMEN' pfbufp dw offset cgroup:pfbuf bpwork db type Work dup (?) pfbuf db 84 dup(?) heaptop label byte endds end entry ;------------------------------------------------ ; End of vmap.asm ;------------------------------------------------