; patching some bytes
; assembled with: `nasm -fbin -o patch.com patch.asm`

    org  0x100           ; .com files always start 256 bytes into the segment

    mov  ax, 0x00

    mov  dx, msg         ; the address of or message in dx
    mov  ah, 9           ; ah=9 - "print string" sub-function
    int  0x21            ; call dos services

    mov  dx, fname       ; open file to patch
    mov  al, 0x02        ; set al to open as read-write (0x02)
    mov  ah, 0x3d        ; ax <- file handle
    int  0x21            ; cf <- 0 (on success)

    jnc  seekfile        ; continue if CF is 0

    mov  dx, s_error_open
    mov  ah, 9
    int  0x21

    jmp  exit

seekfile:

    mov  bx, ax          ; retain file handle

    mov  ax, 0x00
    mov  ah, 0x42        ; seek (file handle is in bx)
    mov  cx, [poffset]   ; starting byte (high)
    mov  dx, [poffset+2] ; (low)
    int  0x21

    jnc  patchfile       ; continue if CF is 0

    mov  dx, s_error_seek
    mov  ax, 0x00
    mov  ah, 9
    int  0x21

    jmp  exit

patchfile:

    mov  ax, 0x00
    mov  ah, 0x40        ; write to file (file handle is in bx)
    mov  cx, [plen]      ; number of bytes to write
    mov  dx, patch       ; address of patch bytes
    int  0x21

    jnc  closefile       ; continue if CF is 0

    mov  dx, s_error_patch
    mov  ax, 0x00
    mov  ah, 9
    int  0x21

    jmp  exit

closefile:

    mov  ax, 0x00
    mov  ah, 0x3e        ; close file (file handle is in bx)
    int  0x21

    jnc  success         ; continue if CF is 0

    mov  dx, s_error_close
    mov  ax, 0x00
    mov  ah, 9
    int  0x21

    jmp  exit

success:

    mov  ax, 0x00
    mov  dx, s_success   ; the address of or message in dx
    mov  ah, 9           ; ah=9 - "print string" sub-function
    int  0x21            ; call dos services

    jmp  exit

exit:
    mov  ax, 0x00
    mov  ah, 0x4c     ; "terminate program" sub-function
    int  0x21         ; call dos services

; data

    ; reason ($-terminated)
    msg   db 'Patching to enable Soundblaster...', 0x0d, 0x0a, '$'

    ; filename (zero-terminated)
    fname db 'DATA.DAT', 0x00

    ; bytes
    patch   db 0x00, 0x00, 0x05, 0x00, 0x02, 0x00, 0x20, 0x02, 0x07, 0x00, 0x01, 0x00
    plen    dw 0x000c
    poffset dw 0x0000, 0x0868

    ; open file error
    s_error_open  db 'Error: Could not open file.', 0x0d, 0x0a, '$'

    ; seek file error
    s_error_seek  db 'Error: Could not seek file.', 0x0d, 0x0a, '$'

    ; write file error
    s_error_patch db 'Error: Could not write to file.', 0x0d, 0x0a, '$'

    ; close file error
    s_error_close db 'Error: Could not close file.', 0x0d, 0x0a, '$'

    ; success
    s_success db 'Success: Patched.', 0x0d, 0x0a, '$'
