User Tools

Site Tools


blog:pushbx:2026:0119_mcp_boot_menu_timer_test_cases

MCP boot menu timer test cases

Two test cases that I created to debug the timer for the Master Control Program's boot menu default. I submitted these to a dosemu2 repo discussion.

First attempt

20260114/test.asm: This is the first attempt, cut directly from the MCP development repo. (Because it uses some macros, particularly the @@ anonymous local labels, it uses the lmacros collection.) What it does: Displays a timer that counts down seconds. It attempts to count the observation of different timer tick low words in word [40h:6Ch], avoiding calculations that involve the timer tick so as to harden against running across midnight. At midnight, the entire timer tick dword wraps around from 18_00AFh or 18_00B0h to 00_0000h. (There is some disagreement as to the exact limit.)

%if 0

MCP menu timeout example
 2026 by 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

%include "lmacros3.mac"

	cpu 8086
	org 256
start:
	mov bh, 20
	mov dh, 9

	call showtime1
	mov ax, 40h
	mov es, ax
.resetloop:
	xor di, di
	mov cx, word [es:6Ch]
.loop:
	mov ah, 01h
	int 16h
	jnz .keyin
	test bh, bh
	jz .timedout
	cmp word [es:6Ch], cx
	jne @F
.next:
	sti
	hlt
	jmp .loop

@@:
	inc di
	cmp di, 18
	jb .next
	dec bh
	call showtime1
	jmp .resetloop

.timedout:
.enter:
	mov al, dh
	add al, '0'
	jmp @F

.keyin:
	xor ax, ax
	int 16h
@@:
	mov ax, 4C00h
	int 21h

showtime1:
	push si
	push cx
	mov al, 13
	mov cx, 40
@@:
	call dispal1
	mov al, 32
	loop @B
	mov si, msg1.default.1
	call display1
	mov al, dh
	add al, '0'
	call dispal1
	mov si, msg1.default.2.inf
	cmp bh, -1
	je @F
	mov si, msg1.default.2
	call display1
	mov dl, 3
	xor ax, ax
	mov al, bh
	call disp_ax_dec_width_dl
	mov si, msg1.default.3
@@:
	call display1
	pop cx
	pop si
	retn


display1:
	push ax
.loop:
	cs lodsb
	test al, al
	jz .ret
	call dispal1
	jmp .loop

.ret:
	pop ax
	retn

dispal1:
	push bx
	push bp
	mov ah, 0Eh
	mov bx, 7
	int 10h
	pop bp
	pop bx
	retn


disp_ax_dec_width_dl:
	push ax
	push bx
	push cx
	push dx
	mov bx, dx
	mov bh, 0
	mov cx, 10
	mov dx, -1
	push dx
.loop1:
	xor dx, dx
	div cx
	push dx
	inc bh
	test ax, ax
	jnz .loop1

	sub bl, bh
	jbe .loop2
@@:
	mov al, 32
	call dispal1
	dec bl
	jnz @B

.loop2:
	pop ax
	add al, '0'
	jc .end
	call dispal1
	jmp .loop2

.end:
	pop dx
	pop cx
	pop bx
	pop ax
	retn


msg1:
.default.1:	asciz 13,"Will choose default "
.default.2:	asciz " in "
.default.2.inf:	asciz " if Enter pressed "
.default.3:	asciz " seconds "

Second attempt

20260115/test.asm: Second attempt. This contains code I used for debugging, namely it appends the cx value read from the timer tick and the di value after incrementing the counter to an array behind the progbits part of the program. After the timeout has expired, the contents of this array are dumped as hexadecimal words. To lessen the amount of output, the timeout is decreased from 20 seconds to 10 seconds.

The uploaded test case also contains a crucial bugfix: After incrementing the di counter when its limit (18) is not yet reached, the timer tick word observed is reloaded into cx from the timer tick variable. This allows the entire timer to work reliably even when there's more IRQs or other HLT-exiting transitions than only the default 18.2 Hz IRQ #0 timer.

The labels .resetloop and .2 in this test were renamed to .loopresetdi and .loopresetcx in the actual program use case.

%if 0

MCP menu timeout example
 2026 by 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

%include "lmacros3.mac"

	cpu 8086
	org 256
start:
	mov bp, array
	mov bh, 10
	mov dh, 9

	call showtime1
	mov ax, 40h
	mov es, ax
.resetloop:
	xor di, di
.2:
	mov cx, word [es:6Ch]
	mov word [bp], cx
	inc bp
	inc bp
.loop:
	mov ah, 01h
	int 16h
	jnz .keyin
	test bh, bh
	jz .timedout
	cmp word [es:6Ch], cx
	jne @F
.next:
	sti
	hlt
	jmp .loop

@@:
	inc di

	mov word [bp], di
	inc bp
	inc bp

	cmp di, 18
	jb .2
	dec bh
	call showtime1
	jmp .resetloop

.timedout:
.enter:
	mov al, dh
	add al, '0'
	jmp @F

.keyin:
	xor ax, ax
	int 16h
@@:

	mov si, msg1.linebreak
	call display1

dump:
	mov si, array
	xor cx, cx
.loop:
	cmp si, bp
	jae .end
	mov al, 32
	call dispal1
	lodsw
	call disp_ax_hex
	inc cx
	test cl, 7
	jnz .next
	push si
	mov si, msg1.linebreak
	call display1
	pop si
.next:
	jmp .loop
.end:
	mov si, msg1.linebreak
	call display1
	mov ax, 4C00h
	int 21h

showtime1:
	push si
	push cx
	mov al, 13
	mov cx, 40
@@:
	call dispal1
	mov al, 32
	loop @B
	mov si, msg1.default.1
	call display1
	mov al, dh
	add al, '0'
	call dispal1
	mov si, msg1.default.2.inf
	cmp bh, -1
	je @F
	mov si, msg1.default.2
	call display1
	mov dl, 3
	xor ax, ax
	mov al, bh
	call disp_ax_dec_width_dl
	mov si, msg1.default.3
@@:
	call display1
	pop cx
	pop si
	retn


disp_ax_hex:
    xchg al, ah
    call disp_al_hex
    xchg al, ah
disp_al_hex:
    push cx
    mov cl, 4
    rol al, cl
    call disp_al_nybble_hex
    rol al, cl
    pop cx
disp_al_nybble_hex:
    push ax
    push dx
    and al, 15
    add al, '0'
    cmp al, '9'
    jbe .got
    add al, 7
.got:
	call dispal1
    pop dx
    pop ax
    retn


display1:
	push ax
.loop:
	cs lodsb
	test al, al
	jz .ret
	call dispal1
	jmp .loop

.ret:
	pop ax
	retn

dispal1:
	push bx
	push bp
	mov ah, 0Eh
	mov bx, 7
	int 10h
	pop bp
	pop bx
	retn


disp_ax_dec_width_dl:
	push ax
	push bx
	push cx
	push dx
	mov bx, dx
	mov bh, 0
	mov cx, 10
	mov dx, -1
	push dx
.loop1:
	xor dx, dx
	div cx
	push dx
	inc bh
	test ax, ax
	jnz .loop1

	sub bl, bh
	jbe .loop2
@@:
	mov al, 32
	call dispal1
	dec bl
	jnz @B

.loop2:
	pop ax
	add al, '0'
	jc .end
	call dispal1
	jmp .loop2

.end:
	pop dx
	pop cx
	pop bx
	pop ax
	retn


msg1:
.default.1:	asciz 13,"Will choose default "
.default.2:	asciz " in "
.default.2.inf:	asciz " if Enter pressed "
.default.3:	asciz " seconds "
.linebreak:	asciz 13,10

align 2, db 0
array:
You could leave a comment if you were logged in.
blog/pushbx/2026/0119_mcp_boot_menu_timer_test_cases.txt · Last modified: 2026-01-19 19:34:29 +0100 Jan Mon by ecm