home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 19 / CD_ASCQ_19_010295.iso / dos / prg / midas / asmrfile.asm next >
Assembly Source File  |  1994-08-06  |  18KB  |  579 lines

  1. ;*      ASMRFILE.ASM
  2. ;*
  3. ;* Raw file I/O for MIDAS Sound System 16-bit C, Pascal or Assembler version
  4. ;*
  5. ;* Copyright 1994 Petteri Kangaslampi and Jarno Paananen
  6. ;*
  7. ;* This file is part of the MIDAS Sound System, and may only be
  8. ;* used, modified and distributed under the terms of the MIDAS
  9. ;* Sound System license, LICENSE.TXT. By continuing to use,
  10. ;* modify or distribute this file you indicate that you have
  11. ;* read the license and understand and accept it fully.
  12. ;*
  13.  
  14.  
  15. IDEAL
  16. P386
  17. JUMPS
  18.  
  19. INCLUDE "lang.inc"
  20. INCLUDE "errors.inc"
  21. INCLUDE "rawfile.inc"
  22. INCLUDE "mmem.inc"
  23.  
  24.  
  25.  
  26. DATASEG
  27.  
  28. fpos            DD      ?               ; temporary file position used by
  29.                                         ; some functions
  30.  
  31.  
  32. IDATASEG
  33.  
  34.  
  35. ;/***************************************************************************\
  36. ;*      errorCodes
  37. ;*      ----------
  38. ;* Table of error codes, with one word (16-bit) DOS error code, followed by
  39. ;* the corresponding MIDAS error code.
  40. ;\***************************************************************************/
  41.  
  42. LABEL   errorCodes      WORD
  43.         DW      02h, errFileNotFound    ; File not found
  44.         DW      03h, errFileNotFound    ; Path not found
  45.         DW      04h, errTooManyFiles    ; Too many open files
  46.         DW      05h, errAccessDenied    ; Access denied
  47.         DW      06h, errInvalidFileHandle       ; Invalid handle
  48.         DW      07h, errHeapCorrupted   ; Memory control blocks destroyed
  49.         DW      08h, errOutOfMemory     ; Insufficient memory
  50.         DW      09h, errInvalidBlock    ; Invalid memory block address
  51.         DW      0Fh, errFileNotFound    ; Invalid drive specified
  52.         DW      13h, errAccessDenied    ; Attempt to write on a write-prot.
  53.         DW      14h, errFileNotFound    ; Unknown unit
  54.         DW      1Dh, errFileWrite       ; Write fault
  55.         DW      1Eh, errFileRead        ; Read fault
  56.         DW      20h, errAccessDenied    ; Sharing violation
  57.         DW      50h, errFileExists      ; File already exists
  58.         DW      -1, -1                  ; end marker
  59.  
  60.  
  61.  
  62. CODESEG
  63.  
  64.  
  65. ;/***************************************************************************\
  66. ;*
  67. ;* Function:     int ErrorCode(void)
  68. ;*
  69. ;* Description:  Get the MIDAS error code corresponding to DOS Extended Error.
  70. ;*
  71. ;* Returns:      MIDAS error code in ax
  72. ;*
  73. ;\***************************************************************************/
  74.  
  75. PROC    ErrorCode       FAR
  76.  
  77.         push    ds si di
  78.         mov     ax,5900h                ; DOS function 59h - get extended
  79.         xor     bx,bx                   ; error
  80.         int     21h
  81.         pop     di si ds
  82.  
  83.         mov     dx,ax                   ; dx = extended error
  84.         xor     bx,bx                   ; offset to error table
  85.  
  86. @@errloop:
  87.         cmp     [errorCodes+bx],dx      ; Is the table error code the current
  88.         je      @@errok                 ; one? If is, return the table value
  89.         cmp     [errorCodes+bx],-1      ; end of table
  90.         je      @@noerr
  91.         add     bx,4
  92.         jmp     @@errloop
  93.  
  94. @@errok:
  95.         mov     ax,[errorCodes+bx+2]    ; ax = MIDAS error code
  96.         jmp     @@done
  97.  
  98. @@noerr:
  99.         mov     ax,errUndefined         ; undefined error
  100.  
  101. @@done:
  102.         ret
  103. ENDP
  104.  
  105.  
  106.  
  107.  
  108.  
  109. ;/***************************************************************************\
  110. ;*
  111. ;* Function:     int rfOpen(char *fileName, int openMode, rfHandle *file);
  112. ;*
  113. ;* Description:  Opens a file for reading or writing
  114. ;*
  115. ;* Input:        char *fileName          name of file
  116. ;*               int openMode            file opening mode, see enum
  117. ;*                                       rfOpenMode
  118. ;*               rfHandle *file          pointer to file handle
  119. ;*
  120. ;* Returns:      MIDAS error code.
  121. ;*               File handle is stored in *file.
  122. ;*
  123. ;\***************************************************************************/
  124.  
  125. PROC    rfOpen          FAR     fileName : dword, openMode : word, \
  126.                                 file : dword
  127.  
  128.         ; allocate memory for file structure:
  129.         call    memAlloc LANG, SIZE rfFile, [file]
  130.         test    ax,ax
  131.         jnz     @@err
  132.  
  133.         cmp     [openMode],rfOpenRead   ; open file for reading?
  134.         jne     @@noread
  135.         mov     al,0                    ; read only - access code
  136.         jmp     @@open
  137.  
  138. @@noread:
  139.         cmp     [openMode],rfOpenWrite  ; open file for writing?
  140.         jne     @@nowrite
  141.         mov     al,1                    ; write only - access code
  142.         jmp     @@open
  143.  
  144. @@nowrite:
  145.         cmp     [openMode],rfOpenReadWrite      ; open for read & write?
  146.         jne     @@invmode
  147.         mov     al,2                    ; read/write - access code
  148.         jmp     @@open
  149.  
  150. @@invmode:
  151.         mov     ax,errInvalidArguments  ; invalid function arguments
  152.         jmp     @@err
  153.  
  154. @@open:
  155.         mov     ah,3Dh                  ; DOS function 3Dh - open file
  156.         push    ds
  157.         lds     dx,[fileName]           ; ds:dx = file name
  158.         int     21h
  159.         pop     ds
  160.         jc      @@doserr                ; carry set if error
  161.  
  162.         les     bx,[file]               ; point es:bx to handle
  163.         les     bx,[es:bx]              ; point es:bx to file structure
  164.         mov     [es:bx+rfFile.handle],ax        ; store file handle
  165.  
  166.         xor     ax,ax
  167.         jmp     @@done
  168.  
  169. @@doserr:
  170.         call    ErrorCode               ; get DOS error code
  171.  
  172. @@err:
  173.         ERROR   ID_rfOpen
  174.  
  175. @@done:
  176.         ret
  177. ENDP
  178.  
  179.  
  180.  
  181.  
  182.  
  183. ;/***************************************************************************\
  184. ;*
  185. ;* Function:     int rfClose(rfHandle file);
  186. ;*
  187. ;* Description:  Closes a file opened with rfOpen().
  188. ;*
  189. ;* Input:        rfHandle file           handle of an open file
  190. ;*
  191. ;* Returns:      MIDAS error code
  192. ;*
  193. ;\***************************************************************************/
  194.  
  195. PROC    rfClose         FAR     file : dword
  196.  
  197.         les     bx,[file]               ; point es:bx to file structure
  198.         mov     bx,[es:bx+rfFile.handle]        ; bx = file handle
  199.         mov     ax,3E00h                ; DOS function 3Eh - close file
  200.         int     21h
  201.         jc      @@doserr                ; carry set if error
  202.  
  203.         ; deallocate file structure:
  204.         call    memFree LANG, [file]
  205.         test    ax,ax
  206.         jnz     @@err
  207.  
  208.         xor     ax,ax
  209.         jmp     @@done
  210.  
  211. @@doserr:
  212.         call    ErrorCode               ; get DOS error code
  213.  
  214. @@err:
  215.         ERROR   ID_rfClose
  216.  
  217. @@done:
  218.         ret
  219. ENDP
  220.  
  221.  
  222.  
  223.  
  224. ;/***************************************************************************\
  225. ;*
  226. ;* Function:     int rfGetSize(rfHandle file, long *fileSize);
  227. ;*
  228. ;* Description:  Get the size of a file
  229. ;*
  230. ;* Input:        rfHandle file           handle of an open file
  231. ;*               ulong *fileSize         pointer to file size
  232. ;*
  233. ;* Returns:      MIDAS error code.
  234. ;*               File size is stored in *fileSize.
  235. ;*
  236. ;\***************************************************************************/
  237.  
  238. PROC    rfGetSize       FAR     file : dword, fileSize : dword
  239.  
  240.         ; store current file position:
  241.         call    rfGetPosition LANG, [file], seg fpos offset fpos
  242.         test    ax,ax
  243.         jnz     @@err
  244.  
  245.         ; seek to end of file:
  246.         xor     eax,eax
  247.         call    rfSeek LANG, [file], eax, rfSeekEnd
  248.         test    ax,ax
  249.         jnz     @@err
  250.  
  251.  
  252.         ; read file position to *filesize:
  253.         call    rfGetPosition LANG, [file], [fileSize]
  254.         test    ax,ax
  255.         jnz     @@err
  256.  
  257.         ; return original file position:
  258.         call    rfSeek LANG, [file], [fpos], rfSeekAbsolute
  259.         test    ax,ax
  260.         jnz     @@err
  261.  
  262.         xor     ax,ax
  263.         jmp     @@done
  264.  
  265. @@doserr:
  266.         call    ErrorCode               ; get DOS error code
  267.  
  268. @@err:
  269.         ERROR   ID_rfGetSize
  270.  
  271. @@done:
  272.         ret
  273. ENDP
  274.  
  275.  
  276.  
  277.  
  278. ;/***************************************************************************\
  279. ;*
  280. ;* Function:     int rfRead(rfHandle file, void *buffer, ulong numBytes);
  281. ;*
  282. ;* Description:  Reads binary data from a file
  283. ;*
  284. ;* Input:        rfHandle file           file handle
  285. ;*               void *buffer            reading buffer
  286. ;*               ulong numBytes          number of bytes to read
  287. ;*
  288. ;* Returns:      MIDAS error code.
  289. ;*               Read data is stored in *buffer, which must be large enough
  290. ;*               for it.
  291. ;*
  292. ;\***************************************************************************/
  293.  
  294. PROC    rfRead          FAR     file : dword, buffer : dword, numBytes : dword
  295. LOCAL   readCount : dword, readBuf : dword
  296.  
  297.         mov     eax,[numBytes]          ; store number of bytes left to
  298.         mov     [readCount],eax         ; readCount
  299.         mov     eax,[buffer]            ; store buffer ptr in readBuf
  300.         mov     [readBuf],eax
  301.  
  302.         les     bx,[file]               ; point es:bx to file structure
  303.         mov     bx,[es:bx+rfFile.handle]        ; bx = file handle
  304.  
  305.         ; As the DOS read function only accepts 16 bits as number of bytes,
  306.         ; data must be read at chunks of 49152 bytes
  307.  
  308. @@readloop:
  309.         cmp     [readCount],0           ; any more bytes to read?
  310.         je      @@readok
  311.  
  312.         cmp     [readCount],49152       ; more than 49152 bytes left?
  313.         jbe     @@readrest
  314.  
  315.         ; More than 49152 bytes left to read - read 49152 bytes and advance
  316.         ; buffer pointer
  317.  
  318.         mov     ax,3F00h                ; DOS function 3Fh - read file
  319.         mov     cx,49152                ; read 49152 bytes
  320.         push    ds
  321.         lds     dx,[readBuf]            ; read to *readBuf
  322.         int     21h
  323.         pop     ds
  324.         jc      @@doserr                ; carry set if error
  325.         cmp     ax,49152                ; ax = number of bytes read. If not
  326.         jne     @@eof                   ; 49152, end of file was reached
  327.  
  328.         sub     [readCount],49152       ; 49152 bytes read
  329.         add     [word readBuf+2],3072   ; advance pointer 49152 bytes
  330.                                         ; (3072 paragraphs)
  331.         jmp     @@readloop
  332.  
  333.  
  334. @@readrest:
  335.         ; 49152 or less bytes remaining - read the rest
  336.  
  337.         mov     ax,3F00h                ; DOS function 3Fh - read file
  338.         mov     cx,[word readCount]     ; read the rest
  339.         push    ds
  340.         lds     dx,[readBuf]            ; read to *readBuf
  341.         int     21h
  342.         pop     ds
  343.         jc      @@doserr                ; carry set if error
  344.         cmp     ax,[word readCount]     ; ax = number of bytes read. If not
  345.         jne     @@eof                   ; readCount, end of file was reached
  346.  
  347.         mov     [readCount],0           ; no more to read
  348.  
  349. @@readok:
  350.         xor     ax,ax
  351.         jmp     @@done
  352.  
  353. @@eof:
  354.         mov     ax,errEndOfFile         ; unexpected end of file
  355.         jmp     @@err
  356.  
  357. @@doserr:
  358.         call    ErrorCode               ; get DOS error code
  359.         cmp     ax,errUndefined         ; undefined error?
  360.         jne     @@err
  361. @@readerr:
  362.         mov     ax,errFileRead          ; if is, change it to file read error
  363.  
  364. @@err:
  365.         ERROR   ID_rfRead
  366.  
  367. @@done:
  368.         ret
  369. ENDP
  370.  
  371.  
  372.  
  373.  
  374. ;/***************************************************************************\
  375. ;*
  376. ;* Function:     int rfWrite(rfHandle file, void *buffer, ulong numBytes);
  377. ;*
  378. ;* Description:  Writes binary data to a file
  379. ;*
  380. ;* Input:        rfHandle file           file handle
  381. ;*               void *buffer            pointer to data to be written
  382. ;*               ulong numBytes          number of bytes to write
  383. ;*
  384. ;* Returns:      MIDAS error code
  385. ;*
  386. ;\***************************************************************************/
  387.  
  388. PROC    rfWrite         FAR     file : dword, buffer : dword, numBytes : dword
  389. LOCAL   writeCount : dword, writeBuf : dword
  390.  
  391.         mov     eax,[numBytes]          ; store number of bytes left to
  392.         mov     [writeCount],eax        ; writeCount
  393.         mov     eax,[buffer]            ; store buffer ptr in writeBuf
  394.         mov     [writeBuf],eax
  395.  
  396.         les     bx,[file]               ; point es:bx to file structure
  397.         mov     bx,[es:bx+rfFile.handle]        ; bx = file handle
  398.  
  399.         ; As the DOS write function only accepts 16 bits as number of bytes,
  400.         ; data must be written at chunks of 49152 bytes
  401.  
  402. @@writeloop:
  403.         cmp     [writeCount],0          ; any more bytes to write?
  404.         je      @@writeok
  405.  
  406.         cmp     [writeCount],49152      ; more than 49152 bytes left?
  407.         jbe     @@writerest
  408.  
  409.         ; More than 49152 bytes left to write - write 49152 bytes and advance
  410.         ; buffer pointer
  411.  
  412.         mov     ax,4000h                ; DOS function 40h - write file
  413.         mov     cx,49152                ; write 49152 bytes
  414.         push    ds
  415.         lds     dx,[writeBuf]           ; write from *writeBuf
  416.         int     21h
  417.         pop     ds
  418.         jc      @@doserr                ; carry set if error
  419.         cmp     ax,49152                ; ax = number of bytes to written. If
  420.         jne     @@diskfull              ; not 49152, disk is full
  421.  
  422.         sub     [writeCount],49152      ; 49152 bytes written
  423.         add     [word writeBuf+2],3072  ; advance pointer 49152 bytes
  424.                                         ; (3072 paragraphs)
  425.         jmp     @@writeloop
  426.  
  427.  
  428. @@writerest:
  429.         ; 49152 or less bytes remaining - write the rest
  430.  
  431.         mov     ax,4000h                ; DOS function 40h - read file
  432.         mov     cx,[word writeCount]    ; write the rest
  433.         push    ds
  434.         lds     dx,[writeBuf]           ; write from *readBuf
  435.         int     21h
  436.         pop     ds
  437.         jc      @@doserr                ; carry set if error
  438.         cmp     ax,49152                ; ax = number of bytes to written. If
  439.         jne     @@diskfull              ; not writeCount, disk is full
  440.  
  441. @@writeok:
  442.         xor     ax,ax
  443.         jmp     @@done
  444.  
  445. @@diskfull:
  446.         mov     ax,errDiskFull          ; unexpected end of file
  447.         jmp     @@err
  448.  
  449. @@doserr:
  450.         call    ErrorCode               ; get DOS error code
  451.         cmp     ax,errUndefined         ; undefined error?
  452.         jne     @@err
  453.         mov     ax,errFileWrite         ; if is, change to file write error
  454.  
  455. @@err:
  456.         ERROR   ID_rfWrite
  457.  
  458. @@done:
  459.         ret
  460. ENDP
  461.  
  462.  
  463.  
  464.  
  465. ;/***************************************************************************\
  466. ;*
  467. ;* Function:     int rfSeek(rfHandle file, long newPosition, int seekMode);
  468. ;*
  469. ;* Description:  Seeks to a new position in file. Subsequent reads and writes
  470. ;*               go to the new position.
  471. ;*
  472. ;* Input:        rfHandle file           file handle
  473. ;*               long newPosition        new file position
  474. ;*               int seekMode            file seek mode, see enum rfSeekMode
  475. ;*
  476. ;* Returns:      MIDAS error code
  477. ;*
  478. ;\***************************************************************************/
  479.  
  480. PROC    rfSeek          FAR     file : dword, newPosition : dword, \
  481.                                 seekMode : word
  482.  
  483.         ; select DOS seek mode corresponding to seekMode:
  484.  
  485.         cmp     [seekMode],rfSeekAbsolute       ; absolute seek?
  486.         jne     @@noabs
  487.         mov     al,0
  488.         jmp     @@seek
  489.  
  490. @@noabs:
  491.         cmp     [seekMode],rfSeekRelative       ; relative seek?
  492.         jne     @@norel
  493.         mov     al,1
  494.         jmp     @@seek
  495.  
  496. @@norel:
  497.         cmp     [seekMode],rfSeekEnd            ; seek from end of file?
  498.         jne     @@invarg
  499.         mov     al,2
  500.         jmp     @@seek
  501.  
  502. @@invarg:
  503.         mov     ax,errInvalidArguments  ; invalid seeking mode
  504.         jmp     @@err
  505.  
  506. @@seek:
  507.         les     bx,[file]
  508.         mov     bx,[es:bx+rfFile.handle]        ; bx = file handle
  509.         mov     ah,42h                  ; DOS function 42h - move file pointer
  510.         mov     cx,[word newPosition+2]
  511.         mov     dx,[word newPosition]
  512.         int     21h
  513.         jc      @@doserr
  514.  
  515.         xor     ax,ax
  516.         jmp     @@done
  517.  
  518. @@doserr:
  519.         call    ErrorCode               ; get DOS error code
  520.  
  521. @@err:
  522.         ERROR   ID_rfSeek
  523.  
  524. @@done:
  525.         ret
  526. ENDP
  527.  
  528.  
  529.  
  530.  
  531. ;/***************************************************************************\
  532. ;*
  533. ;* Function:     int rfGetPosition(rfHandle file, long *position);
  534. ;*
  535. ;* Description:  Reads the current position in a file
  536. ;*
  537. ;* Input:        rfHandle file           file handle
  538. ;*               long *position          pointer to file position
  539. ;*
  540. ;* Returns:      MIDAS error code.
  541. ;*               Current file position is stored in *position.
  542. ;*
  543. ;\***************************************************************************/
  544.  
  545. PROC    rfGetPosition   FAR     file : dword, position : dword
  546.  
  547.         les     bx,[file]
  548.         mov     bx,[es:bx+rfFile.handle]        ; bx = file handle
  549.  
  550.         mov     ah,42h                  ; DOS function 42h - move file pointer
  551.         mov     al,1                    ; move relative to current position
  552.         xor     cx,cx                   ; new position = 0 (current)
  553.         xor     dx,dx
  554.         int     21h
  555.         jc      @@doserr                ; carry set if error
  556.  
  557.         ; dx:ax contains current file position - store it in *position:
  558.         les     bx,[position]
  559.         mov     [es:bx],ax
  560.         mov     [es:bx+2],dx
  561.  
  562.         xor     ax,ax
  563.         jmp     @@done
  564.  
  565. @@doserr:
  566.         call    ErrorCode               ; get DOS error code
  567.  
  568. @@err:
  569.         ERROR   ID_rfGetPosition
  570.  
  571. @@done:
  572.         ret
  573. ENDP
  574.  
  575.  
  576.  
  577.  
  578. END
  579.