crt0.o          \
        ctype.o         \
        cvline.o        \
+       dioclose.o      \
+       diocommon.o     \
+       dioopen.o       \
+       dioread.o       \
+       diowrite.o      \
        dosdetect.o     \
         get_ostype.o    \
         getenv.o        \
         joy_stddrv.o    \
        kbhit.o         \
         mainargs.o      \
+       mli.o           \
         oserrlist.o     \
         randomize.o     \
         rcout.o         \
 
--- /dev/null
+;
+; Oliver Schmidt, 24.03.2005
+;
+; unsigned char __fastcall__ dio_close (dhandle_t handle);
+;
+
+        .export        _dio_close
+        .import                dioepilog
+
+_dio_close:
+        lda    #$00
+        jmp    dioepilog
 
--- /dev/null
+;
+; Oliver Schmidt, 24.03.2005
+;
+
+        .export        dioprolog, diocommon, dioepilog
+        .import        popax
+
+        .include       "errno.inc"
+        .include       "mli.inc"
+
+dioprolog:
+        ; Set buffer
+        sta    mliparam + MLI::RW_BLOCK::DATA_BUFFER
+        stx    mliparam + MLI::RW_BLOCK::DATA_BUFFER+1
+
+        ; Get and set sect_num
+        jsr    popax
+        sta    mliparam + MLI::RW_BLOCK::BLOCK_NUM
+        stx    mliparam + MLI::RW_BLOCK::BLOCK_NUM+1
+
+        ; Get and set handle
+        jsr    popax
+        sta    mliparam + MLI::RW_BLOCK::UNIT_NUM
+        rts
+
+diocommon:
+        ; Call read_block or write_block
+        ldx    #RW_BLOCK_COUNT
+        jsr    callmli         
+
+dioepilog:
+        ; Return success or error
+        sta     __oserror
+        ldx    #$00
+        rts
 
--- /dev/null
+;
+; Oliver Schmidt, 24.03.2005
+;
+; dhandle_t __fastcall__ dio_open (driveid_t drive_id);
+;
+; drive_id = (slot * 2) + (drive - 1)
+
+        .export        _dio_open
+        .import                decaxy, return0
+
+        .include       "zeropage.inc"
+        .include       "errno.inc"
+        .include       "mli.inc"
+
+_dio_open:
+        ; Convert drive id into unit number
+        lsr
+        bcc    :+
+        ora    #%00001000
+:       asl
+        asl
+        asl
+        asl
+        sta    mliparam + MLI::ON_LINE::UNIT_NUM
+
+        ; Alloc 16-byte buffer just below stack
+        ldy    #16
+        lda    sp
+        ldx    sp+1
+        jsr    decaxy
+        sta    mliparam + MLI::ON_LINE::DATA_BUFFER
+        stx    mliparam + MLI::ON_LINE::DATA_BUFFER+1
+
+        ; Get device state
+        lda    #ON_LINE_CALL
+        ldx    #ON_LINE_COUNT
+        jsr    callmli
+        bcc    :+
+
+        ; DIO level access doesn't necessarily need a
+        ; ProDOS 8 disk so ignore "high level" errors
+        cmp    #$40
+        bcc    oserr
+
+        ; Return success
+:       lda    mliparam + MLI::ON_LINE::UNIT_NUM
+        ldx    #$00
+        stx    __oserror
+        rts
+
+        ; Return oserror
+oserr:  sta     __oserror
+        jmp    return0
 
--- /dev/null
+;
+; Oliver Schmidt, 24.03.2005
+;
+; unsigned char __fastcall__ dio_read (dhandle_t handle, sectnum_t sect_num, void *buffer);
+;
+
+        .export        _dio_read
+        .import        dioprolog, diocommon
+
+        .include       "mli.inc"
+
+_dio_read:
+        jsr    dioprolog
+        lda    #READ_BLOCK_CALL
+        jmp    diocommon
 
--- /dev/null
+;
+; Oliver Schmidt, 24.03.2005
+;
+; unsigned char __fastcall__ dio_write (dhandle_t handle, sectnum_t sect_num, const void *buffer);
+;
+
+        .export        _dio_write
+        .import        dioprolog, diocommon
+
+        .include       "mli.inc"
+
+_dio_write:
+        jsr    dioprolog
+        lda    #WRITE_BLOCK_CALL
+        jmp    diocommon
 
 ; Apple ProDOS 8 MLI
 ;
 
+READ_BLOCK_CALL = $80
+WRITE_BLOCK_CALL= $81
+RW_BLOCK_COUNT  = 3
+
 CREATE_CALL     = $C0
 CREATE_COUNT    = 7
 
 
         .struct MLI
                 .union
+                        .struct RW_BLOCK
+                                PARAM_COUNT    .byte
+                                UNIT_NUM       .byte
+                                DATA_BUFFER    .addr
+                                BLOCK_NUM      .word
+                        .endstruct
                         .struct CREATE
                                 PARAM_COUNT    .byte
                                 PATHNAME       .addr
 
--- /dev/null
+;
+; Oliver Schmidt, 30.12.2004
+;
+; Apple ProDOS 8 MLI
+;
+
+        .import                __dos_type
+
+        .include       "mli.inc"
+
+        .bss
+
+mliparam:       .tag   MLI
+
+        .data
+
+callmli:
+        ; Store parameters
+        sta    call
+        stx    mliparam
+
+        ; Check for ProDOS 8
+        lda    __dos_type
+        beq    oserr
+
+        ; Call MLI and return
+        jsr    ENTRY
+call:   .byte  $00
+        .word  mliparam
+        rts
+
+        ; Load oserror code and return
+oserr:  lda    #$01            ; "Invalid MLI function code number"
+        sec
+        rts
\ No newline at end of file