
%if 0

lDebug DM command - Dump MCB chain

Copyright (C) 2008-2025 E. C. Masloch

Usage of the works is permitted provided that this
instrument is retained with the works, so that any entity
that uses the works is notified of this instrument.

DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY.

%endif

		; DM command
mcbout:
%if _MCBPOSITION
	xor bx, bx
	extcallcall skipcomma
	dec si
	mov dx, msg.keyword_position
internaldatarelocation
	extcallcall isstring?
	jne .no_position
	not bx
.no_position:
	extcallcall skipcomma
	dec si
	mov byte [mcbposition], bl
internaldatarelocation
%endif

%if _MCBLIMIT
	mov bx, -1
	extcallcall skipcomma
	dec si
	mov dx, msg.keyword_limit
internaldatarelocation
	extcallcall isstring?
	jne .no_limit
	extcallcall skipequals
	extcallcall skipcomm0
	extcallcall getword
	dec si
	mov bx, dx
.no_limit:
	extcallcall skipcomma
	dec si
	mov word [mcblimit], bx
internaldatarelocation
%endif

%if _SDSUB
	xor bx, bx
	extcallcall skipcomma
	dec si
	mov dx, msg.keyword_skipsd
internaldatarelocation
	extcallcall isstring?
	jne .sd
	not bx
.sd:
	extcallcall skipcomma
	dec si
	mov byte [skipsd], bl
internaldatarelocation
%endif

%if ELD
	xor bx, bx
	extcallcall skipcomma
	dec si
	mov dx, msg.keyword_header
internaldatarelocation
	extcallcall isstring?
	je .header
	mov dx, msg.keyword_table
internaldatarelocation
	extcallcall isstring?
	jne .nottable
.table:
	mov bl, -1
	db __TEST_IMM16		; skip mov
.header:
	mov bh, -1
.nottable:
	extcallcall skipcomma
	mov word [header_high_table_low], bx
internaldatarelocation
%else
	extcallcall skipwhite
%endif
	mov dx, word [relocated(firstmcb)]
linkdatarelocation firstmcb
	extcallcall iseol?
	je .lolmcb
	extcallcall getword
%if _MCBLIMIT
	extcallcall skipcomm0
	dec si
	push dx
	mov dx, msg.keyword_limit
internaldatarelocation
	extcallcall isstring?
	jne .no_limit_2
	extcallcall skipequals
	extcallcall skipcomm0
	extcallcall getword
	mov word [mcblimit], dx
internaldatarelocation
	dec si
.no_limit_2:
	pop dx
	extcallcall skipcomma
%endif
	extcallcall chkeol
.lolmcb:
	mov si, dx
	mov di, relocated(line_out)
linkdatarelocation line_out
	mov ax, "PS"
	stosw
	mov ax, "P:"
	stosw
	mov al, 32
	stosb
	mov ax, word [relocated(pspdbe)]
linkdatarelocation pspdbe
	extcallcall hexword
	extcallcall putsline_crlf	; destroys cx,dx,bx
%if ELD
	mov dx, msg.headertable
internaldatarelocation
%if _MCBPOSITION
	rol byte [mcbposition], 1
internaldatarelocation
	jnc .notableposition
	mov dx, msg.headertableposition
internaldatarelocation
.notableposition:
%endif
	rol byte [header_high_table_low], 1
internaldatarelocation
	jc @F
	mov dx, msg.headerheader
internaldatarelocation
%if _MCBPOSITION
	rol byte [mcbposition], 1
internaldatarelocation
	jnc .noheaderposition
	mov dx, msg.headerheaderposition
internaldatarelocation
.noheaderposition:
%endif
	rol byte [header_high_table_low + 1], 1
internaldatarelocation
	jnc @FF
@@:
	extcallcall putsz
@@:
%endif
	mov cl, 'M'
.next:
	cmp si, byte -1
	je .invmcb
	cmp si, byte 50h
	jae .valmcb
.invmcb:
	mov dx, msg.invmcbadr
internaldatarelocation
	jmp putsz
.valmcb:
%if _MCBLIMIT
	cmp word [mcblimit], si
internaldatarelocation
	jae @F
	retn
@@:
%endif
	mov di, relocated(line_out)
linkdatarelocation line_out
	push ds
%if _PM
	extcallcall setds2si
%else
	mov ds, si
%endif
	mov ch, byte [0000]
	mov bx, word [0001]
	mov dx, word [0003]

	mov ax, si
	extcallcall hexword		; segment address of MCB
%if ELD
	mov ah, 4
%endif
%if _MCBPOSITION
	rol byte [ss:mcbposition], 1
internaldatarelocation
	jnc .noposition
%if ELD
	mov ah, 3
	call stosb_repeated
%else
	mov al, 32
	stosb
%endif
	mov ax, si
	push bx
	push dx
	push cx
	xor dx, dx		; dx:ax = position as segment
	mov cx, 16		; cx = 16, multiplier (get position in bytes)
	mov bx, 5+4		; bx = 5+4, width
	extcallcall disp_dxax_times_cx_width_bx_size.store
	pop cx
	pop dx
	pop bx
%if ELD
	mov ah, 1
%endif

.noposition:
%endif

%if ELD
	call stosb_repeated
%else
	mov al, 32
	stosb
%endif
	mov al, ch
	extcallcall hexbyte		; 'M' or 'Z'
%if ELD
	mov ah, 3
	call stosb_repeated
%else
	mov al, 32
	stosb
%endif
	mov ax, bx
	extcallcall hexword		; MCB owner
%if ELD
	mov ah, 1
	call stosb_repeated
%else
	mov al, 32
	stosb
%endif
	mov ax, dx
	extcallcall hexword		; MCB size in paragraphs

	mov al, 32
	stosb
	mov ax, dx		; ax = size in paragraphs
	push bx
	push ax
	push dx
	push cx
	xor dx, dx		; dx:ax = size in paragraphs
	mov cx, 16		; cx = 16, multiplier (get size in bytes)
	mov bx, 5+4		; bx = 5+4, width

	extcallcall disp_dxax_times_cx_width_bx_size.store
	pop cx
	pop dx
	pop ax
	pop bx

	test bx, bx
	jz .freemcb		; free MCBs have no name -->
%if ELD
	mov ah, 1
	call stosb_repeated
%else
	mov al, 32
	stosb
%endif
	push si
	push cx
	push dx

	push ds
	mov si, 8
	mov cx, 2
	cmp bx, si		; is it a "system" MCB? (owner 0008h or 0007h)
	ja @F
	cmp byte [si], "S"	; "S", "SD", "SC" ?
	je .nextmcbchar		; yes, limit name to two characters -->
	jmp .nextmcbchar_cx_si	; no, assume full name given
@@:
	dec bx			; => owner block's MCB
%if _PM
	extcallcall setds2bx
%else
	mov ds, bx
%endif
.nextmcbchar_cx_si:
	mov cx, si		; = 8
.nextmcbchar:			; copy name of owner MCB
	lodsb
	stosb
	test al, al
	loopnz .nextmcbchar	; was not NUL and more bytes left ?
	test al, al
	jnz @F
	dec di
@@:
	pop ds

	cmp word [1], 8
	jne .not_s_mcb
	cmp word [8], "S"	; S MCB ?
	jne .not_s_mcb_check_sd

	mov ax, " t"
	stosw
	mov ax, "yp"
	stosw
	mov ax, "e "
	stosw

	xor ax, ax
	mov al, [10]
	extcallcall hexbyte

	 push ss
	 pop ds
	mov si, smcbtypes
internaldatarelocation
.s_mcb_loop:
	cmp word [si], -1
	je .s_mcb_unknown
	cmp word [si], ax
	je .s_mcb_known
	add si, 4
	jmp .s_mcb_loop

.s_mcb_known:
	mov si, word [si + 2]
	jmp .s_mcb_common

.s_mcb_unknown:
	mov si, smcbmsg_unknown
internaldatarelocation
.s_mcb_common:
	mov al, 32
@@:
	stosb
	lodsb
	test al, al
	jnz @B
%if _SDSUB
@@:
	jmp .not_s_mcb
%endif

.not_s_mcb_check_sd:

%if _SDSUB
	rol byte [ss:skipsd], 1
internaldatarelocation
	jc @B

	cmp word [8], "SD"
	jne @B

	pop dx
	pop cx
	pop si

	push si
	push cx
	push dx

	mov bp, si
	add bp, dx
	jc @F
	inc bp
	jnz @FF
@@:
	mov bp, -1
@@:
	xor dx, dx
.loop_sd:
	add si, dx
	jc .done_sd

	inc si
	jz .done_sd

	cmp si, bp
	jae .done_sd

	 push ss
	 pop ds
	extcallcall putsline_crlf	; destroys cx,dx,bx

	mov di, relocated(line_out)
linkdatarelocation line_out
%if _PM
	extcallcall setds2si
%else
	mov ds, si
%endif
	mov ch, byte [0000]
	mov bx, word [0001]
	mov dx, word [0003]

	mov al, 32
	stosb				; indent SD sub-MCBs

	mov ax, si
	extcallcall hexword		; segment address of MCB
%if ELD
	mov ah, 4
%endif
%if _MCBPOSITION
	rol byte [ss:mcbposition], 1
internaldatarelocation
	jnc .sdnoposition
%if ELD
	mov ah, 3
	call stosb_repeated
%else
	mov al, 32
	stosb
%endif
	mov ax, si
	push bx
	push dx
	push cx
	xor dx, dx		; dx:ax = position as segment
	mov cx, 16		; cx = 16, multiplier (get position in bytes)
	mov bx, 5+4		; bx = 5+4, width
	extcallcall disp_dxax_times_cx_width_bx_size.store
	pop cx
	pop dx
	pop bx
%if ELD
	mov ah, 1
%endif

.sdnoposition:
%endif

%if ELD
	call stosb_repeated
%else
	mov al, 32
	stosb
%endif
	mov al, ch
	extcallcall hexbyte		; 'M' or 'Z'
%if ELD
	mov ah, 3
	call stosb_repeated
%else
	mov al, 32
	stosb
%endif
	mov ax, bx
	extcallcall hexword		; MCB owner
%if ELD
	mov ah, 1
	call stosb_repeated
%else
	mov al, 32
	stosb
%endif
	mov ax, dx
	extcallcall hexword		; MCB size in paragraphs

	mov al, 32
	stosb
	mov ax, dx		; ax = size in paragraphs
	push bx
	push ax
	push dx
	push cx
	xor dx, dx		; dx:ax = size in paragraphs
	mov cx, 16		; cx = 16, multiplier (get size in bytes)
	mov bx, 5+4		; bx = 5+4, width

	extcallcall disp_dxax_times_cx_width_bx_size.store
	pop cx
	pop dx
	pop ax
	pop bx

%if ELD
	mov ah, 1
	call stosb_repeated
%else
	mov al, 32
	stosb
%endif
	push si
	push cx
	push dx

	mov al, "'"
	stosb
	mov al, ch
	cmp al, 32
	jbe @F
	cmp al, 127
	jb @FF
@@:
	mov al, '.'
@@:
	stosb
	mov ax, "' "
	stosw

	mov al, ch
	mov ah, 0
	push ds
	 push ss
	 pop ds
	mov si, sdsubmcbtypes
internaldatarelocation
.sd_mcb_loop:
	cmp word [si], -1
	je .sd_mcb_unknown
	cmp word [si], ax
	je .sd_mcb_known
	add si, 4
	jmp .sd_mcb_loop

.sd_mcb_known:
	mov si, word [si + 2]
	jmp .sd_mcb_common

.sd_mcb_unknown:
	mov si, smcbmsg_unknown
internaldatarelocation
.sd_mcb_common:
	db __TEST_IMM8		; (skip stosb in first iteration)
@@:
	stosb
	lodsb
	test al, al
	jnz @B
	pop ds

	pop dx
	pop cx
	push cx
	push dx

	cmp ch, 'D'
	jne .sd_no_name

	mov si, 8
	mov cx, si
.nextsdmcbchar:			; copy name of SD sub-MCB
	lodsb
	stosb
	test al, al
	loopnz .nextsdmcbchar	; was not NUL and more bytes left ?
	test al, al
	jnz @F
	dec di
@@:

.sd_no_name:
	pop dx
	pop cx
	pop si

	test ch, ch
	jz .done_sd

	test dx, dx
	jz .done_sd

	jmp .loop_sd

.done_sd:
%endif

.not_s_mcb:
	pop dx
	pop cx
	pop si
.freemcb:

	pop ds
	cmp ch, 'M'
	je .disp
	cmp ch, 'Z'
	je .disp
.ret:
	retn

.disp:
	mov cl, ch
	push dx
	push cx
	extcallcall putsline_crlf	; destroys cx,dx,bx
	pop cx
	pop dx
	add si, dx
	jc .ret			; over FFFFh, must be end of chain --> (hmm)
	inc si
	jz .ret
	jmp .next

%if ELD
stosb_repeated:
	mov al, 32
	stosb
	rol byte [ss:header_high_table_low], 1
internaldatarelocation
	jnc .ret
	push cx
	xor cx, cx
	mov cl, ah
	rep stosb
	pop cx
.ret:
	retn
%endif
