; Функции проверены.
;
; Входящие функции:
;
;  errno   - ячейка
;  open
;  close
;  creat
;  read
;  write
;  sleep
;  chdir
;  getcwd
;  strerr  - в Си как strerror
;  perror
;  isatty
;  unlink
;  remove
;  mkdir
;  rmdir
;  rename
;  getenv
;  putenv
;  sysenv
;  seek
;  lseek
;  tell
;  ltell
;  ioctl	-  не готова
;






	MODULE	errno
;---------------------------------------------------------------------
; errno variable
;---------------------------------------------------------------------
	dseg
errno_::
	db	0			; номер сист. ошибки

	ENDMODULE


	MODULE	open
;
; "io.h"
;---------------------------------------------------------------------
; creat()  Функция низко-уровневого ввода/вывода
;---------------------------------------------------------------------
; Функция creat создает новый файл.
; Если файл уже существует, урезает его до нулевой длины.
; Значение attr состоит из одной или нескольких констант:
; S_IWRITE и S_IREAD, объявленных в "stat.h". Если задаются обе
; константы, они объединяются при помощи логического ИЛИ "|".
; Функция возвращает номер дексриптора.
; При ошибке, возвращается значение -1 (0FFFFh) и errno
; содержит номер ошибки.
;
; uint creat(char *name, int attr)
; uint creat(char *name, char attr)
;--------------------------------------------------------------------------

; "io.h"
;---------------------------------------------------------------------
; open()  Функция низко-уровневого ввода/вывода
;---------------------------------------------------------------------
; Функция open открывает файл, определяемый по path-имени и подготавливает
; его к последующему чтению или записи, что определяется посредством
; oflag. Аргумент oflag является целым выражением, состоящим из комби-
; нации одной или более манифестных констант, объявленных в "io.h".
; Если задано больше одной константы, то они объединяются при помощи
; логического оператора ИЛИ "|". Значения аргумента oflag приводятся
; ниже:
;
;       O_RDWR       Файл открыт одновременно для чтения и записи.
;                    Если задается этот флаг, может быть выбран
;                    либо флаг O_RDONLY, либо O_WRONLY.
;
;       O_RDONLY     Файл открыт только для чтения. Если задается
;                    этот флаг, может быть выбран либо флаг O_RDWR,
;                    либо O_WRONLY.
;
;       O_WRONLY     Файл открыт только для записи. Если задан этот
;                    флаг, может быть задан также либо флаг O_RDONLY,
;                    либо ORDWR.
;
;       O_TRUNC      Существующий файл открыт на чтение и запись, и
;                    усечен к длине 0. Этот файл должен иметь разре-
;                    шение на запись. Содержимое файла уничтожается.
;
;       O_CREAT      Новый файл создан и открыт для чтения/записи;
;                    это не эффективно, если существует файл, опре-
;                    деляемый по path-имени.
;
;       O_EXCL       Возвращается значение ошибки, если существует
;                    файл, определяемый по path-имени. Применяется
;                    только вместе с O_CREATE.
;
;       O_APPEND     Указатель в файле переместить на конец файла.
;                    Для режимов O_RDONLY, O_TRUNC и O_CREAT не
;                    имеет смысла.
;
; Замечание!  O_TRUNC полностью уничтожает содержимое существующего
; файла, поэтому нужно внимательно использовать эту константу.
;
; Функция возвращает номер дескриптора файла, если Ok.
; При ошибке, возвращает значение -1 (0FFFFh) и ячейка errno содержит
; номер ошибки.
;
; in: hl = *pathname (указатель на имя файла)
;     de = oflag (тип операций)
; out: hl = номер дескриптора, если Ok
;      hl = -1 при ошибке
;
; uint open(char *pathname, int oflag)
; uint open(char *pathname, char oflag)
;
creat_::
open_::
	; e=oflag
	push	ix
	ld	a,3
	and	e			; mask 1,0 bits
	xor	3
	ld	d,a			; save "a"
	; a=0..2
	dec	a
	jr	z,open			; O_RDONLY
	ld	a,0Ch
	and	e			; 3,2 bits ?
	jr	z,open			; no  (O_WRONLY and O_RDWR)
	; O_CREAT or O_TRUNC
	ld	c,0Ah			; create file
	bit	4,e
	jr	z,trunc			; no O_EXCL
	inc	c			; create new file
trunc:	ld	a,20h			; attr "archive"
	rst	10h
	jr	op24
	;
open:	push	de
	ld	a,d			; O_RDONLY, O_WRONLY, O_RDWR
	ld	c,11h
	rst	10h
	pop	de
	jr	c,op24			; file not found
	bit	5,e			; O_APPEND
	jr	z,op24			; no
	; уст. указатель в конец файла
	push	af			; save file descriptor
	ld	hl,0
	push	hl
	pop	ix
	ld	b,2			; SEEK_END
	ld	c,15h			; move_fp
	rst	10h
	pop	bc
	ld	a,b
	;
op24:	ld	l,a			; file descriptor
	ld	h,0
	pop	ix
	ret	nc			; Ok
	ld	(errno_##),a
	ld	hl,-1			; error
	ret

;
; "io.h"
;---------------------------------------------------------------------
; Функция низко-уровневого ввода/вывода
;---------------------------------------------------------------------
; Функция закрывает файл.
; Функция возвращает 0, если файл успешно закрыт.
; При ошибке, возвращается значение -1 (0FFFFh) и errno
; содержит номер ошибки.
;
; uint close(FD fd)
;
close_::
	push	ix
	ld	a,l
	ld	c,12h
	rst	10h
	pop	ix
	ld	hl,0
	ret	nc			; Ok
	ld	(errno_##),a
	dec	hl			; -1
	ret

	ENDMODULE


	MODULE	read
;
; "io.h"
;---------------------------------------------------------------------
; Функция низко-уровневого ввода/вывода
;---------------------------------------------------------------------
; Функция читает число байт count из файла в буфер buff.
; Операция чтения начинается с текущей позиции указателя в файле.
; Функция возвращает число реально прочитанных байтов, которое
; однако, может быть меньше заявленного в count (например встре-
; тится конец файла). Мaксимaльнoе числo бaйтoв, кoтoрoе мoжнo
; прoчитaть из фaйлa зa oдин рaз, рaвнo 65534; пoскoльку 65535
; (OxFFFF) является неoтличимым oт -1, пoэтoму будет вoзврaщенa
; oшибкa.
; Функция возвращает 0, если делается попытка чтения конца файла.
; При ошибке чтения, возвращается -1 и errno содержит номер ошибки.
;
; size_t read(FD fd, void *buff, count)
;
read_::
	push	ix
	ld	a,l			; file descriptor
	ex	de,hl			; hl = buffer address
	ld	e,c			; de = number of bytes to read
	ld	d,b
	ld	c,13h
	rst	10h
	ex	de,hl			; hl = number of bytes actually read
	pop	ix
	ret	nc
	ld	(errno_##),a
	ld	hl,-1
	ret

	ENDMODULE


	MODULE	write
;
; "io.h"
;---------------------------------------------------------------------
; Функция низко-уровневого ввода/вывода
;---------------------------------------------------------------------
; Функция записывает число байт count из буфера buff в файл.
; Операции записи начинаются с текущей позиции указателя в файле.
; Если файл открыт для добавления, операции выполняются в конец
; файла. После осуществления операций записи, указатель в файле
; увеличивается на количество реально записанных байтов.
; Макс. число записываемых байтов в файл равно 65534; поскольку
; число 65535 является неотличимым от -1, то возвращается ошибка.
; Функция возвращает число реально записанных байт.
; При ошибке записи возвращается значение -1 и в errno устанавли-
; вается номер ошибки.
;
; out: hl=число реально запис. байт
;
; size_t write(FD fd, void *buff, count)
;
write_::
	push	ix
	ld	a,l			; file descriptor
	ex	de,hl			; hl = buffer address
	ld	e,c			; de = number of bytes to write
	ld	d,b
	ld	c,14h
	rst	10h
	ex	de,hl			; hl = number of bytes actually write
	pop	ix
	ret	nc
	ld	(errno_##),a
	ld	hl,-1
	ret

	ENDMODULE


	MODULE	sleep
;
; "dos.h"
; Функция приостанавливает выполнение
; программы на seconds секунд.
; После выполнения функции, прерывания
; остаются включенными.
;
; void sleep(uint seconds)
;
sleep_::
	ei
@1:	ld	a,l
	or	h
	ret	z
	ld	a,49			; 1/50 секунды
@2:	halt
	dec	a
	jr	nz,@2
	dec	hl
	jr	@1

	ENDMODULE


;	MODULE	pid
;
; char getpid()		-- MISIX only
; char getppid()	-- MISIX only
;
;getppid_::
;	ld	c,49h
;	db	21h
;getpid_::
;	ld	c,48h
;	ld	a,(_os_ver_##)
;	cp	2
;	ld	a,0
;	ret	nz
;	push	ix
;	call	5
;	pop	ix
;	ret
;
;	ENDMODULE


	MODULE	chdir
;
; "direct.h"
; Функция изменяет текущий каталог и текущий диск, если он указан
; в pathname. Если путь начинается с "\" - это означает путь от
; корневого каталога, иначе от текущего. Pathname должен ссылаться
; на существующий каталог.
; Функция возвращает значение 0, если рабочий каталог успешно изменен.
; При ошибке, возвращается -1 (0FFh) и errno содержит номер ошибки.
;
; char chdir(char *pathname)
;
chdir_::
	;push	ix
	ld	c,1Dh
	rst	10h
	ld	(errno_##),a
	;pop	ix
	ld	a,0
	ret	nc
	dec	a
	ret

	ENDMODULE


	MODULE	getcwd
;
; "direct.h"
; Функция получает полное (с буквой диска) path-имя текущего каталога
; и сохраняет его в буфере pathbuff. В конце path-имени текущего ката-
; лога стоит символ "\" с заключительным нулем в конце строки.
; Аргумент len определяет максимальную длину для path-имени, которая
; должна быть достаточной, чтобы вместить информацию вместе с заключи-
; тельным нулем. Максимальная длина path-имени в ДОС равна 256 байтов.
; Если длина path-имени превышает len, то path-имя обрезается на длину
; len, при этом символ "\" в конец строки не ставится.
; Если аргумент pathbuff равен NULL, то getcwd вызывает malloc для
; выделения буфера размером len байтов. Этот выделенный буфер позже может
; быть освобожден посредством функции free.
; Функция возвращает указатель на pathbuff.
; При ошибке возвращается NULL и errno содержит номер ошибки.
;
; char *getcwd(char *pathbuff, int len)
;
getcwd_::
	;push	ix
	ld	(@6+1),de
	ld	a,l
	or	h
	jr	nz,@1
	ex	de,hl			; hl=len
	inc	hl
	call	malloc_##
	ld	a,l
	or	h
	ld	a,30			; ENOMEM (Not enough memory)
	jr	z,@4
	;
@1:	ld	(@5+1),hl
	ld	hl,4100h		; exe-header as temp buffer
	push	hl
	inc	hl
	inc	hl
	; get current directory
	ld	c,1Eh
	rst	10h
	jr	c,@3
	ex	de,hl			; hl=end string
	ld	a,"\"
	dec	hl
	dec	hl
	cp	(hl)
	jr	z,@2
	inc	hl
	ld	(hl),a
	inc	hl
	ld	(hl),0
	; get current disk
@2:	ld	c,2
	rst	10h
	pop	hl
	jr	c,@4
	ld	c,"A"
	add	a,c
	ld	(hl),a
	inc	hl
	ld	(hl),":"
	dec	hl			; hl=4100h
	;
@5:	ld	de,0
	push	de
@6:	ld	bc,1
	ldir
	xor	a
	ld	(de),a
	pop	hl
	;pop	ix
	ret
	;
@3:	pop	hl
@4:	;pop	ix
	ld	(errno_##),a
	ld	hl,0			; NULL
	ret

	ENDMODULE


	MODULE	strerr
;
; "string.h"
; (в Си стоит как "strerror").
; Функция преобразует errno в стрoку системного сooбщения oб oшибке
; и вoзврaщaет укaзaтель нa эту стрoку.
; Функция, в отличие от perror, не выводит никаких сooбщений. Для вывода
; сообщения требуется вызвaть функцию вывoдa (например printf).
; Номер ошибки хранится в переменной errno, которая объявлена на внешнем
; уровне и используется как индекс в массиве системных сообщений.
; Системные сообщения об ошибках доступны через переменную _errlst_,
; являющуюся массивом системных сообщений об ошибках.
; Чтобы вернуть правильный результат, функция strerr должна быть вызвана
; сразу после библиотечной функции, возвратившей ошибку. Иначе, значение
; errno может быть перезаписано при последующих вызовах библиотечных функций.
; Для любого значения errno, не используемого в ДОС, функция strerr возвра-
; щает указатель на пустую строку.
;
; in: a = индекс строки ошибки
; out: hl = адрес строки
;
; char *strerr(char errno)
;
strerr_::
	cp	50+1
	jr	nc,@2
	ld	e,a			; errno
	ld	d,0
	inc	de
	ld	hl,_errlst_		; array of system messages
	ld	bc,__nerr		; size of array
@1:	xor	a
	cpir
	ret	po
	ret	nz
	dec	de
	ld	a,d
	or	e
	jp	nz,@1
	ret
	;
@2:	ld	hl,@3
	ret
	;
@3:	db	0Dh,0Ah,0

; array of system messages
_errlst_::
	db	0
	db	"No error",0				; 0
	db	"Invalid function",0			; 1
	db	"Invalid drive number",0		; 2
	db	"File not found",0			; 3
	db	"Path not found",0			; 4
	db	"Invalid handle",0			; 5
	db	"Too many open files",0			; 6
	db	"File already exists",0			; 7
	db	"File read only",0			; 8
	db	"Root overflow",0			; 9
	db	"No free space",0			; 10
	db	"Directory not empty",0			; 11
	db	"Can't delete current directory",0	; 12
	db	"Invalid media",0			; 13
	db	"Unknown operation",0			; 14
	db	"Directory exist",0			; 15
	db	"Invalid filename",0			; 16
	db	"Invalid EXE-file",0			; 17
	db	"Not supported EXE-file",0		; 18
	db	"Access denied",0			; 19
	db	"Not ready",0				; 20
	db	"Seek error",0				; 21
	db	"Sector not found",0			; 22
	db	"CRC error",0				; 23
	db	"Write protect",0			; 24
	db	"Read error",0				; 25
	db	"Write error",0				; 26
	db	"Drive failure",0			; 27
	db	"Extended error: 28",0			; 28
	db	"Extended error: 29",0			; 29
	db	"Not enough memory",0			; 30
	db	"Invalid memory block",0		; 31
	db	"Extended error: 32",0			; 32
	db	"Extended error: 33",0			; 33
	db	"Extended error: 34",0			; 34
	db	"35",0					; 35
	db	"36",0					; 36
	db	"37",0					; 37
	db	"38",0					; 38
	db	"39",0					; 39
	db	"40",0					; 40
	db	"41",0					; 41
	db	"42",0					; 42
	db	"43",0					; 43
	db	"44",0					; 44
	db	"45",0					; 45
	db	"46",0					; 46
	db	"47",0					; 47
	db	"48",0					; 48
	db	"49",0					; 49
	db	"50",0					; 50
_endlst_:

__nerr	equ	_endlst_ - _errlst_	; size of array

	ENDMODULE


	MODULE	perror
;
; "stdlib.h"
; Функция выводит сообщение об ошибке на stderr.
; В этом сообщении аргумент string выводится первым, затем выводится
; двоеточие, системное сообщение об ошибке от последнего библиотечного
; вызова, вернувшего ошибку и новая строка.
; Если аргумент string равен NULL, то функция пропускает сообщение string,
; заданное пользователем и выводит только системное сообщение об ошибке,
; и новую строку.
; Чтобы вывести правильный результат, функция perror должна быть вызвана
; сразу же после библиотечной функции, возвратившей ошибку. Иначе значение
; errno может быть перезаписано при последующих вызовах библиотечных функций.
; Функция perror не возвращает никакого значения.
;
; void perror(char *string)
;
perror_::
	;push	ix
	ld	a,l
	or	h
	jr	z,@1
	call	cputs_##
	ld	hl,@2
	call	cputs_##
@1:	ld	a,(errno_##)
	call	strerr_##
	call	cputs_##
	ld	a,0Ah
	call	putch_##
	;pop	ix
	ret
	;
@2:	db	": ",0

	ENDMODULE


;	MODULE	fcntl
;
; Для MISIX.
;
; int fcntl(FD fd, int mode, int arg)
; char fcntla
;
;fcntl_::
;fcntla_::
;	ld	a,(_os_ver_##)		; this function works ONLY in MISIX
;	cp	2
;	jr	nz,@1
;	ld	h,e
;	ld	e,c
;	ld	d,b
;	ld	c,3Eh
;	call	5
;	ld	(errno_##),a
;	or	a
;	ret	z
;@1:	ld	a,-1
;	ld	l,a
;	ld	h,a
;	ret
;
;	ENDMODULE


	MODULE	isatty
;
; "io.h"
;---------------------------------------------------------------------
; Функция низко-уровневого ввода/вывода
;---------------------------------------------------------------------
; Функция определяет, принадлежит ли данный дескриптор
; стандартным потокам (терминал, консоль,...).
; Функция возвращает:
;   true  - дескриптор принадлежит терминалу, консоли.
;   false - дескриптор принадлежит файлу.
;
; in: l = номер дескриптора
; out: a = true
;      a = false
;
; BOOL isatty(FD fd)
;
isatty_::
	xor	a
	cp	l
	jr	z,@1			; stdin
	bit	7,l			; stdout, stderr, ... ?
	ret	z			; no
@1:	inc	a
	ret

	ENDMODULE


	MODULE	unlink
;
; "io.h"
; Функция удаляет файл, определенный по pathname.
; Глобальные символы * и ? в имени файла не допускаются.
; Файлы с атрибутом "только для чтения" нельзя удалить данной
; функцией - предварительно нужно изменить этот атрибут.
; Функция возвращает 0, если файл успешно удален.
; При ошибке, возвращается -1 (0FFh) и errno содержит
; номер ошибки.
;
; char unlink(char *pathname)
; char remove(char *pathname)
;
unlink_::
remove_::
	push	ix
	ld	c,0Eh
	rst	10h
	pop	ix
	ld	(errno_##),a
	ld	a,0
	ret	nc
	dec	a
	ret

	ENDMODULE


	MODULE	mkdir
;
; "direct.h"
; Функция создает новый каталог с заданным path-именем.
; За один вызов функции может быть создан только один новый
; каталог, с именем последней компоненты pathname.
; Функция возвращает 0, если новый каталог успешно создан.
; При ошибке, возвращается -1 (0FFh) и errno содержит номер ошибки.
;
; char mkdir(char *pathname)
;
mkdir_::
	push	ix
	ld	c,1Bh
	rst	10h
	pop	ix
	ld	(errno_##),a
	ld	a,0
	ret	nc
	dec	a
	ret

	ENDMODULE


	MODULE	rmdir
;
; "direct.h"
; Функция удаляет пустой каталог, определенный в pathname.
; Нельзя удалить текущий каталог или корневой.
; Функция возвращает 0, если каталог успешно удален.
; При ошибке, возвращается -1 (0FFh) и errno содержит номер ошибки.
;
; char rmdir(char *pathname)
;
rmdir_::
	push	ix
	ld	c,1Ch
	rst	10h
	pop	ix
	ld	(errno_##),a
	ld	a,0
	ret	nc
	dec	a
	ret

	ENDMODULE


	MODULE	rename
;
; "io.h"
; Функция переименовывает файл или каталог, определенный в имени
; newname. Oldname должно задавать path-имя существующего файла
; или каталога. Newname не определяет имя уже существующего файла
; или каталога.
; Функцию rename нельзя использовать для перемещения файла из одного
; каталога в другой, указав другое path-имя в аргументе newname.
; Функция возвращает 0, если операция прошла успешно.
; При ошибке, возвращается -1 (0FFh) и errno содержит номер ошибки.
;
; char rename(char *oldname, char *newname)
;
rename_::
	push	ix
	ld	c,10h
	rst	10h
	pop	ix
	ld	(errno_##),a
	ld	a,0
	ret	nc
	dec	a
	ret

	ENDMODULE


	MODULE	getenv
;
; "stdlib.h"
; Функция возвращает для заданного имени переменной окружения
; varname указатель на значение (строку) этой переменной.
; Максимальная длина строки значения переменной окружения должна
; быть не более 255 байт.
; Возвращается значение NULL, если заданная переменная на текущий
; момент не определена.
; При ошибке также возвращается NULL, но в errno будет содержаться
; номер ошибки.
;
; in: hl = адрес имени переменной
; out: hl = адрес строки значения переменной
;
; char *getenv(char *varname)
;
getenv_::
	;push	ix
	ld	de,4000h		; exe-header as buffer for value
	push	de
	ld	bc,0146h		; get environment item
	rst	10h
	pop	hl			; pointer to buffer for value
	;pop	ix
	jr	c,@1			; error
	or	a
	jr	z,@1			; not found
	ret
@1:	ld	(errno_##),a
	ld	hl,0
	ret

	ENDMODULE


	MODULE	putenv
;
; "stdlib.h"
; Функция добавляет новую переменную окружения.
; Аргумент envstring должен быть указателем на строку следующего
; формата:
;
;           VARNAME=VALUE
;
; где: "VARNAME" - имя добавляемой переменной окружения
;      "VALUE - значение этой переменной.
;
; Элементы строки должны разделяться символом "=" и строка должна
; оканчиваться нулем.
;
; Функция возвращает 0, если она успешно отработала.
; При ошибке, возвращается значение -1 и errno содержит номер ошибки.
;
; in: hl = адрес имени переменной
; out: hl = адрес значения переменной
;
; uint putenv(char *envstring)
;
putenv_::
	;push	ix
	ld	bc,0246h		; set environment item
	rst	10h
	;pop	ix
	ld	hl,0
	ret	nc
	ld	(errno_##),a
	dec	hl
	ret


	ENDMODULE


	MODULE	sysenv
;
; "stdlib.h"
; Функция получает системное окружение.
; Аргумент sysenv должен быть указателем на буфер, предназначенный
; для данных системного окружения. Размер буфера должен быть доста-
; точным, чтобы вместить все данные системного окружения. Формат
; данных в буфере следующий:
; Строка каждой переменной окружения заканчивается на нуль.
; В конце строки последней переменной окружения, стоит допол-
; нительный нуль, показывающий, что дальше переменных нет.
; Пример (в асмовом варианте):
;
;  sysenv: db   "PATH=c:\fn;c:\zx",0
;          db   "SOLID=H",0
;          db   0
;
; Функция возвращает указатель на буфер sysenv.
; При ошибке, возвращается значение -1 и errno содержит номер
; ошибки.
;
; in: hl = адрес буфера sysenv
; out: hl = адрес буфера sysenv
;
; char *sysenv(char *sysenv)
;
sysenv_::
	;push	ix
	push	hl
	ld	bc,0046h		; set system environment
	rst	10h
	pop	hl
	;pop	ix
	ret	nc
	ld	(errno_##),a
	ld	hl,-1
	ret

	ENDMODULE


;	MODULE	dup
;
; "io.h"
; Создает второй дескриптор для открытого файла.
; Создание нового дескриптора не влияет на тип доступа к файлу.
; Функция возвращает номер 2-го дескриптора.
; При ошибке, возвращается -1 (0FFFFh) и errno устанавливается
; в одно из следующих значений:
;
;       EBADF   - неверный дескриптор файла.
;       EMFILE  - другие дескрипторы файла для
;                 него не доступны, т.к. много
;                 открытых файлов.
;
; FD dup(FD fd)
;
;dup_::	ld	a,(_os_ver_##)
;	or	a
;	ret	z
;	push	ix
;	dec	a
;	jr	z,du1
;	ld	h,0
;	ld	c,3Eh
;	call	5
;	pop	ix
;	ret
;du1:	ld	b,l
;	ld	c,47h
;	call	5
;	pop	ix
;	ld	l,b
;	ld	h,0
;	ret
;
;	ENDMODULE


;	MODULE	dup2
;
; "io.h"
; Функция форсирует заданный дескриптор fp2 для ссылки на тот же самый
; файл, на который ссылается дескриптор fp1. Если во время вызова этой
; функции, fp2 связан с открытым файлом, то этот файл закрывается.
;   fp1 - дескриптор открытого файла
;   fp2 - любое значение дескриптора
; Функция возвращает 0 в случае успеха.
; При ошибке, возвращается -1 (0FFFFh) и errno устанавливается в одно
; из следующих значений:
;
;       EBADF   - неверный дескриптор файла
;       EMFILE  - другие дескрипторы файла для него не доступны,
;                 т.к. много открытых файлов
;
; char dup2(FD fp1, FD fp2)             -- MISIX only
;
;dup2_::ld	a,(_os_ver_##)
;	cp	2
;	ret	nz
;	ld	h,1
;	ld	c,3Eh
;	push	ix
;	call	5
;	pop	ix
;	ret
;
;	ENDMODULE


	MODULE	seek
;
; "io.h"
;---------------------------------------------------------------------
; Функция низко-уровневого ввода/вывода
;---------------------------------------------------------------------
; Функция устанавливает указатель в файле на новое место расположения,
; которое определяется как смещение offset. Тип перемещения определяется
; аргументом type. Следующая операция в файле выполняется на новом месте
; расположения указателя. Диапазон перемещения указателя не может быть
; больше 65534. Если нужно переместить указатель на большее значение,
; необходимо использовать функцию lseek.
; Аргумент type может быть одной из следующих констант, определенных в
; "io.h":
;
;       SEEK_SET    от начала файла
;       SEEK_CUR    от текущей позиции указателя в файле
;       SEEK_END    от конца файла
;
; Функция возвращает значение нового положения указателя.
; При ошибке возвращается -1 и errno содержит номер ошибки.
; Установка указателя за пределами файла, ошибки не вызывает.
; Для устройств, не приспособленных к поиску (таких как терминалы
; и принтеры), возвращаемое значение -1.
;
; uint seek(FD fd, uint offset, int type)
; uint seek(FD fd, uint offset, char type)
;
seek_::
	bit	7,l			; std... devices ?
	jr	nz,@1			; yes
	push	ix
	ld	a,l
	ld	hl,0
	push	de
	pop	ix
	ld	b,c
	ld	c,15h
	rst	10h
	push	ix
	pop	hl
	pop	ix
	ret	nc
	ld	(errno_##),a
@1:	ld	hl,-1
	ret

	ENDMODULE


	MODULE	tell
;
; "io.h"
;---------------------------------------------------------------------
; Функция низко-уровневого ввода/вывода
;---------------------------------------------------------------------
; Функция возвращает текущую позицию указателя в файле.
; Позиция выражается как число байтов от начала файла.
; Значение возвращаемого указателя не может быть больше 65534. Если
; нужно получить большее значение, необходимо использовать функцию
; ltell.
; При ошибке возвращается -1 и errno содержит номер ошибки.
; Для устройств, не приспособленных к поиску (таких как терминалы
; и принтеры), возвращаемое значение -1.
;
; uint tell(FD fd)
;
tell_::
	bit	7,l			; std... devices ?
	jr	nz,@1			; yes
	push	ix
	ld	a,l
	ld	hl,0
	push	hl
	pop	ix
	ld	b,1
	ld	c,15h
	rst	10h
	push	ix
	pop	hl
	pop	ix
	ret	nc
	ld	(errno_##),a
@1:	ld	hl,-1
	ret

	ENDMODULE


	MODULE	lseek
;
; "io.h"
;---------------------------------------------------------------------
; Функция низко-уровневого ввода/вывода
;---------------------------------------------------------------------
; Функция устанавливает указатель в файле на новое место расположения,
; определяемое аргументами high и low, соответственно старшая и млад-
; шая часть 32-х битного значения перемещения.
; Тип перемещения определяется аргументом type. Следующая операция в
; файле выполняется на новом месте расположения указателя.
; Аргумент type может быть одной из следующих констант, определенных
; в "io.h":
;
;       SEEK_SET    от начала файла
;       SEEK_CUR    от текущей позиции указателя в файле
;       SEEK_END    от конца файла
;
; Функция возвращает структуру f_point, определенную в "types.h"
; При ошибке возвращается -1 и errno содержит номер ошибки.
; Установка указателя за пределами файла, ошибки не вызывает.
; Для устройств, не приспособленных к поиску (таких как терминалы
; и принтеры), возвращается значение -1.
;
; Usage:
;
;	static f_point *p;	// или "f_point *p" вне функции
;
;	p = lseek(FD fd, p->high, p->low, type);
;	printf("value: %X %X\n", p->high, p->low);
;
;
; struct fpoint *lseek(FD fd, uint high, uint low, int type)
; struct fpoint *lseek(FD fd, uint high, uint low, char type)
;
lseek_::
	bit	7,l			; std... devices ?
	jr	nz,@1			; yes
	ld	a,l			; descriptor
	push	ix
	push	bc
	pop	ix			; low
	ld	hl,4
	add	hl,sp
	ld	b,(hl)			; type
	ex	de,hl			; hl=high
	ld	c,15h
	rst	10h
	ld	(high),hl
	ld	(low),ix
	ld	hl,low
	pop	ix
	ret	nc
	ld	(errno_##),a
@1:	ld	hl,-1
	ret

low:	dw	0
high:	dw	0

	ENDMODULE


	MODULE	ltell
;
; "io.h"
;---------------------------------------------------------------------
; Функция низко-уровневого ввода/вывода
;---------------------------------------------------------------------
; Функция получает текущую позицию указателя в файле.
; Позиция выражается как число байтов от начала файла.
; Функция возвращает структуру f_point, определенную в "types.h"
; При ошибке возвращается -1 и errno содержит номер ошибки.
; Для устройств, не приспособленных к поиску (таких как терминалы
; и принтеры), возвращается значение -1.
;
; Usage:
;
;	static f_point *p;	// или "f_point *p" вне функции
;
;	p = ltell(FD fd);
;	printf("value: %X %X\n", p->high, p->low);
;
;
; struct fpoint *ltell(FD fd)
;
ltell_::
	bit	7,l			; std... devices ?
	jr	nz,@1			; yes
	push	ix
	ld	a,l
	ld	hl,0
	push	hl
	pop	ix
	ld	bc,0115h
	rst	10h
	ld	(high),hl
	ld	(low),ix
	ld	hl,low
	pop	ix
	ret	nc
	ld	(errno_##),a
@1:	ld	hl,-1
	ret

low:	dw	0
high:	dw	0

	ENDMODULE


	MODULE	ioctl
;
; "io.h"
;---------------------------------------------------------------------
; Функция низко-уровневого ввода/вывода
;---------------------------------------------------------------------
;
; int ioctl(FD fd, int cmd[,*argdx, argcx])	-- MS-DOS
; 
; Функция предназначена для управления устройств ввода/вывода или файлов.
; Используется системный вызов 0х44 MS-DOS. Параметр cmd указывает
; операцию для устройства:
;
; ------+------------------------------------------------------
;  cmd  |               Операция
; ------+------------------------------------------------------
;   0   | Получить информацию об устройстве. (rst 08h, 58h)
;   1   | Установить информацию об устройстве. (rst 08h, 59h)
;   2   | Прочитать argcx 1 байт по адресу, указанному в argdx.
;   3   | Записать argcx байт по адресу, указанному в argdx.
;   4   | Аналогично 2, только handle интерпретируется как
;       | номер устройства (0=текущий, 1=A и т.д.).
;   5   | Аналогично 3, только handle интерпретируется
;       | как номер устройства (0=текущий, 1=A и т.д.).
;   6   | Получить статус ввода.
;   7   | Получить статус вывода.
;   8   | Test removability; DOS 3.x only.
;  11   | Set sharing conflict retry count; DOS 3.x only.
; ------+------------------------------------------------------
;
; Сделать возвращение указателя на общую структуру ... контроля девайса/файла.
; При ошибке, функция возвращает -1.
;
; int ioctl(FD fd, char func, int arg)
; ;char ioctla(FD fd, char func, int arg)	-- DOS2 only
;
;ioctla_::
ioctl_::
	ret
	push	ix
	ld	a,e			; func
	ld	e,c			; de=arg
	ld	d,b
	ld	b,l			; FD fd  номер дескриптора
	ld	c,4Bh
	call	5
	pop	ix
	ex	de,hl			; вернуть hl = .. ?
	ret

	ENDMODULE
