User Tools

Site Tools


blog:pushbx:2026:0119_mcp_boot_menu_timer_test_cases

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

blog:pushbx:2026:0119_mcp_boot_menu_timer_test_cases [2026-01-19 19:34:29 +0100 Jan Mon] (current)
ecm created
Line 1: Line 1:
 +====== 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 [[https://github.com/dosemu2/dosemu2/discussions/2748|a dosemu2 repo discussion]].
 +
 +
 +===== First attempt =====
 +
 +[[https://pushbx.org/ecm/test/20260114/test.asm|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 [[https://hg.pushbx.org/ecm/lmacros/file/c0a6f4cfe69d/lmacros2.mac#l1022|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. ([[https://retrocomputing.stackexchange.com/questions/25877/why-did-some-bioses-have-the-timer-tick-wrap-around-at-1800b1h-instead-of-at-180|There is some disagreement as to the exact limit]].)
 +
 +<code>%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 "</code>
 +
 +
 +===== Second attempt =====
 +
 +[[https://pushbx.org/ecm/test/20260115/test.asm|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'' [[https://hg.pushbx.org/ecm/mcp/rev/b7ebd8df73e0#l1.40|in the actual program use case]].
 +
 +<code>%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:</code>
 +
 +{{tag>mcp dosemu2 testspam}}
 +
 +
 +~~DISCUSSION~~
  
blog/pushbx/2026/0119_mcp_boot_menu_timer_test_cases.txt ยท Last modified: 2026-01-19 19:34:29 +0100 Jan Mon by ecm