ERROR_FileError: PUSH AX MOV DX, STR_ErrFile CALL DOS_PrintString POP AX CALL WriteLastDOSError JMP Exit ERROR_GeneralDOSError: ; AX has the error code PUSH AX MOV DX, STR_ErrOtherDOS CALL DOS_PrintString POP AX CALL WriteLastDOSError JMP Exit ERROR_GeneralError: ; AX has the error code, and it'll be a custom error, TODO: implement MOV DX, STR_ErrOther CALL DOS_PrintString JMP Exit FileCloseError: PUSH AX MOV DX, STR_ErrCloseFile CALL DOS_PrintString POP AX CALL WriteLastDOSError INT 20h ; Note the early exit WriteLastDOSError: CALL DecodeDOSError CALL DOS_PrintString RET DecodeDOSError: ; All right, so MOV BX, AX ; We first copy the error code into BX SHL BX, 1 ; Then multiply it by 2 to get the proper offset in the table MOV SI, DOS_ERRORS ; Load in the table address ADD SI, BX ; And add the offset we have in BX MOV DX, [CS:SI] ; And finally, return the proper string address RET ; This needs no explanation, but I forgot the RET statement once and was wondering why in the hell is DOSBox crashing on me include 'DOSERR.ASM'