dostests/dosbox.asm
2025-12-15 20:33:00 -08:00

91 lines
1.6 KiB
NASM

org 100h
bits 16
section .text
jmp _start
yesDosbox db "Yep, that is a DOSBox!",0dh,0ah,'$'
noDosbox db "Probably not a DOSBox.",0dh,0ah,'$'
oldUDAddr dw 0
oldUDSeg dw 0
isDosbox db 1
_catchUD:
push ax
push bx
mov bx, sp
mov bx, WORD [ss:bx+4]
mov ax, bx
mov bx, WORD [cs:bx]
and bh, 38h ; Keep only the opcode bits
cmp bx, 38feh ; little-endian FE 38
je .notDosbox
; uhh, we shouldn't end up here. clean up the IVT and IRET so the actual
; #UD handler is called.
push es
xor ax, ax
mov es, ax
mov bx, [oldUDAddr]
mov [es:18h], bx
mov bx, [oldUDSeg]
mov [es:1ah], bx
pop es
jmp .catchDone
.notDosbox:
; Not DOSBox -- increment the IP and unset the flag
add ax, 4
mov bx, sp
mov WORD [ss:bx+4], ax
mov [isDosbox], 0
.catchDone:
pop bx
pop ax
iret
_start:
push es
; store the old #UD...
xor ax, ax
mov es, ax
mov bx, [es:18h]
mov [oldUDAddr], bx
mov bx, [es:1ah]
mov [oldUDSeg], bx
; ... and set the new #UD handler
mov bx, cs
mov [es:1ah], bx
mov bx, _catchUD
mov [es:18h], bx
pop es
; DOSBoxCB 0x0000
db 0xfe, 0x38, 0x00, 0x00
mov ax, [isDosbox]
cmp ax, 0
jz .notDosbox
mov dx, yesDosbox
jmp .printAndQuit
.notDosbox:
mov dx, noDosbox
.printAndQuit:
mov ah, 09h
int 21h
; restore the old #UD handler
push es
xor ax, ax
mov es, ax
mov [es:1ah], oldUDSeg
mov [es:18h], oldUDAddr
pop ax
; and we're done!
mov ax, 4c00h
int 21h
hlt