Tvůrce webu je i pro tebe! Postav třeba web. Bez grafika. Bez kodéra. Hned.
wz

DOS.ASM

Interface Int 21h


; ============================================================================
;
;                          MicroDOS - Int 21h services
;
; ============================================================================

; ------------- Table of Int 21h functions

Int21Fnc:	dw	Int2100		; 00h terminate program
		dw	Int2101		; 01h get char. from STDIN with echo
		dw	Int2102		; 02h put character to STDOUT
		dw	Int2103		; 03h get character from STDAUX
		dw	Int2104		; 04h output character to STDAUX
		dw	Int2105		; 05h output character to STDPRN
		dw	Int2106		; 06h direct STDIO - kbd to screen
		dw	Int2107		; 07h char from STDIO, no echo
		dw	Int2108		; 08h char from STDIO, no echo, ^C
		dw	Int2109		; 09h display a string to STDOUT
		dw	Int210A		; 0Ah buffered keyboard input
		dw	Int210B		; 0Bh check STDIN status
		dw	Int210C		; 0Ch clear+invoke keyboard function
		dw	Int210D		; 0Dh flush all disk buffers
		dw	Int210E		; 0Eh select disk
		dw	Int210F		; 0Fh open file with FCB

		dw	Int2110		; 10h close file opened with FCB
		dw	Int2111		; 11h search for first file entry
		dw	Int2112		; 12h search for next file entry
		dw	Int2113		; 13h delete file specified by FCB
		dw	Int2114		; 14h sequential read from file FCB
		dw	Int2115		; 15h sequential write to file FCB
		dw	Int2116		; 16h find or create firectory entry
		dw	Int2117		; 17h rename file FCB
		dw	Int2118		; 18h unknown
		dw	Int2119		; 19h return current disk drive
		dw	Int211A		; 1Ah set disk transfer area (DTA)
		dw	Int211B		; 1Bh get current disk drive FAT
		dw	Int211C		; 1Ch get disk FAT for any drive
		dw	Int211D		; 1Dh unknown
		dw	Int211E		; 1Eh unknown
		dw	Int211F		; 1Fh read DOS disk block

		dw	Int2120		; 20h unknown
		dw	Int2121		; 21h random read from file FCB
		dw	Int2122		; 22h random write to file FCB
		dw	Int2123		; 23h return number of records in FCB
		dw	Int2124		; 24h set file record size FCB
		dw	Int2125		; 25h set interrupt vector
		dw	Int2126		; 26h create new PSP
		dw	Int2127		; 27h random file block read from FCB
		dw	Int2128		; 28h random file block write to FCB
		dw	Int2129		; 29h parse the command line
		dw	Int212A		; 2Ah get the system date
		dw	Int212B		; 2Bh set the system date
		dw	Int212C		; 2Ch get the system time
		dw	Int212D		; 2Dh set the system time

Int21Num	EQU	($-Int21Fnc)/2	; number of Int 21h functions

; ----------------------------------------------------------------------------
;                       Unsupported Int 21h functions
; ----------------------------------------------------------------------------

Int2105:
Int210E:
       
Int2111:
Int2112:
Int2118:
Int2119:
Int211A:
Int211B:
Int211C:
Int211D:
Int211E:
Int211F:
       
Int2120:
Int2121:
Int2122:
Int2123:
Int2124:
Int2125:
Int2126:
Int2127:
Int2128:
Int2129:
		mov	al,0		; AL <- 0 (unsupported function)
		ret

; ----------------------------------------------------------------------------
;                      Int 20h service (terminate program)
; ----------------------------------------------------------------------------

MyInt20:	mov	ah,0		; AH <- 0 function code
                jmp	short MyInt211

; ----------------------------------------------------------------------------
;                              Int 21h service
; ----------------------------------------------------------------------------

; ------------- Register offsets of Int 21h service (in stack)

REG21F		EQU	22		; Int 21h flaags register in stack
REG21CS		EQU	20		; Int 21h CS register in stack
REG21IP		EQU	18		; Int 21h IP register in stack
REG21ES		EQU	16		; Int 21h ES register in stack
REG21DS		EQU	14		; Int 21h DS register in stack
REG21BP		EQU	12		; Int 21h BP register in stack
REG21DI		EQU	10		; Int 21h DI register in stack
REG21SI		EQU	8		; Int 21h SI register in stack
REG21DX		EQU	6		; Int 21h DX register in stack
REG21CX		EQU	4		; Int 21h CX register in stack
REG21BX		EQU	2		; Int 21h BX register in stack
REG21AX		EQU	0		; Int 21h AX register in stack

; ------------- Check function number

MyInt21:	cmp	ah,Int21Num	; check function number
		jb	MyInt211	; function number is OK
MyInt210:	mov	al,0		; error code - unsupported function

MyInt23:
MyInt24:
		iret

; ----------------------------------------------------------------------------
;                        Old style (CALL 5) DOS service
; ----------------------------------------------------------------------------
; - user call this with "call near 5" instruction (only in COM program)
; - PSP:5 addres contains "call far 0000:00c0h" instruction
; - address 0000:00c0h (=address of int 30h) contains "jump far" instruction
; ----------------------------------------------------------------------------

; ------------- Store return address

OldDOS:		pop	ax		; destroy offset of return address
		pop	ax		; AX <- segment of PSP
		pop	word [cs:OldStack]; store offset of return address

; ------------- Simulate Int 21h call

		pushf			; push flags to simulate Int 21h
		push	ax		; push segment of PSP
		push	word [cs:OldStack]; restore offset of return address
		cli			; disable interrupts

; ------------- Check function number

		cmp	cl,24h		; check maximal number of function
		ja	MyInt210	; invalid function number
		mov	ah,cl		; AH <- function code

; ------------- Push registers (at this point interrupt is disabled)

MyInt211:	call	PushAll		; push all registers

; ------------- Push DS:BX registers

		mov	[cs:PushDSBX+2],ds ; push DS
		push	cs		; push CS
		pop	ds		; DS <- CS
		mov	[PushDSBX],bx	; push BX

; ------------- Push stack pointer

		mov	[OldStack],sp	; push SP
		mov	[OldStack+2],ss	; push SS

; ------------- Init Int 21h stack

		mov	sp,cs		; SP <- CS
		mov	ss,sp		; SS <- CS
		mov	sp,Int21Stack1	; stack for Int 21h

; ------------- Console functions use own internal stack

		or	ah,ah		; function 00h (program end)
		jz	MyInt212	; internal stack 1
		cmp	ah,0Ch		; character functions ?
		ja	MyInt212	; no character functions
		mov	sp,Int21Stack2	; stack for console functions
MyInt212:	sti			; enable interrupts

; ------------- Prepare return address from service (simulates CALL NEAR)

		mov	bx,MyInt21Ret	; BX <- return address
		push	bx		; prepare return address

; ------------- Prepare jump address of service

		mov	bh,0		; BH <- 0
		mov	bl,ah		; BL <- function code
		shl	bx,1		; BX = function code * 2
		push	word [Int21Fnc+bx] ; push address of service

; ------------- Pop DS:BX registers and jump to the service

		lds	bx,[PushDSBX]	; pop DS:BX registers
		ret			; junp to the service
		
; ------------- Return from service (here is AL = return code)

MyInt21Ret:	cli			; disable interrupts

; ------------- Return old stack pointer

		mov	sp,[cs:OldStack]; SP <- old SP
		mov	ss,[cs:OldStack+2]; SS <- old SS

; ------------- Set AL register (return code)

		mov	bp,sp		; BP <- stack pointer
		mov	[bp+REG21AX],al	; store AL return code

; ------------- Pop registers

		call	PopAll		; pop all registers
		iret

; ----------------------------------------------------------------------------
;                      Get register pointer
; ----------------------------------------------------------------------------
; OUTPUT:	DS:SI = registers in call stack (offset RE21AX...REG21F)
; ----------------------------------------------------------------------------

GetReg:		lds	si,[cs:OldStack] ; DS:DI <- old stack
		ret

; ----------------------------------------------------------------------------
;                        Set output register AX
; ----------------------------------------------------------------------------
; INPUT:	AX = output register AX
; ----------------------------------------------------------------------------

SetRegAX:	push	ds		; push DS
		push	si		; push SI
		call	GetReg		; get register pointer
		mov	[si+REG21AX],ax	; store output register AX
		pop	si		; pop SI
		pop	ds		; pop DS
		ret

; ----------------------------------------------------------------------------
;                        Set output register BX
; ----------------------------------------------------------------------------
; INPUT:	BX = output register BX
; ----------------------------------------------------------------------------

SetRegBX:	push	ds		; push DS
		push	si		; push SI
		call	GetReg		; get register pointer
		mov	[si+REG21BX],bx	; store output register BX
		pop	si		; pop SI
		pop	ds		; pop DS
		ret

; ----------------------------------------------------------------------------
;                        Set output register CX
; ----------------------------------------------------------------------------
; INPUT:	CX = output register CX
; ----------------------------------------------------------------------------

SetRegCX:	push	ds		; push DS
		push	si		; push SI
		call	GetReg		; get register pointer
		mov	[si+REG21CX],cx	; store output register CX
		pop	si		; pop SI
		pop	ds		; pop DS
		ret

; ----------------------------------------------------------------------------
;                        Set output register DX
; ----------------------------------------------------------------------------
; INPUT:	DX = output register DX
; ----------------------------------------------------------------------------

SetRegDX:	push	ds		; push DS
		push	si		; push SI
		call	GetReg		; get register pointer
		mov	[si+REG21DX],dx	; store output register DX
		pop	si		; pop SI
		pop	ds		; pop DS
		ret

; ----------------------------------------------------------------------------
;                        Set DOS result error flag (and AH <- 0)
; ----------------------------------------------------------------------------

DOSError:	mov	ah,0		; AH <- 0
		push	ds		; push DS
		push	si		; push SI
		call	GetReg		; get register pointer
		or	byte [si+REG21F],1 ; set error flag
		pop	si		; pop SI
		pop	ds		; pop DS
		ret

; ----------------------------------------------------------------------------
;                      Reset DOS result error flag
; ----------------------------------------------------------------------------

DOSOK:		push	ds		; push DS
		push	si		; push SI
		call	GetReg		; get register pointer
		and	byte [si+REG21F],~1 ; reset error flag
		pop	si		; pop SI
		pop	ds		; pop DS
		ret

; ----------------------------------------------------------------------------
;                           Push all registers
; ----------------------------------------------------------------------------

PushAll:	pop	word [cs:PushAllRet] ; store return address
		push	es		; 16: push ES
		push	ds		; 14: push DS
		push	bp		; 12: push BP
		push	di		; 10: push DI
		push	si		; 8: push SI
		push	dx		; 6: push DX
		push	cx		; 4: push CX
		push	bx		; 2: push BX
		push	ax		; 0: push AX
PushAll2:	jmp	[cs:PushAllRet]	; return

; ----------------------------------------------------------------------------
;                           Pop all registers
; ----------------------------------------------------------------------------

PopAll:		pop	word [cs:PushAllRet] ; store return address
		pop	ax		; pop AX
		pop	bx		; pop BX
		pop	cx		; pop CX
		pop	dx		; pop DX
		pop	si		; pop SI
		pop	di		; pop DI
		pop	bp		; pop BP
		pop	ds		; pop DS
		pop	es		; pop ES
		jmp	short PushAll2	; return

; ----------------------------------------------------------------------------
;                      Push registers AX, BX, CX, DX, DI
; ----------------------------------------------------------------------------

PushABCDI:	pop	word [cs:PushAllRet] ; store return address
		push	ax		; push AX
		push	bx		; push BX
		push	cx		; push CX
		push	dx		; push DX
		push	di		; push DI
PushABCDI2:	jmp	[cs:PushAllRet]	; return

; ----------------------------------------------------------------------------
;                       Pop registers AX, BX, CX, DX, DI
; ----------------------------------------------------------------------------

PopABCDI:	pop	word [cs:PushAllRet] ; store return address
		pop	di		; pop DI
		pop	dx		; pop DX
		pop	cx		; pop CX
		pop	bx		; pop BX
		pop	ax		; pop AX
		jmp	short PushABCDI2; return

; ----------------------------------------------------------------------------
;                                    Data
; ----------------------------------------------------------------------------

PushAllRet:	dw	0		; push return address

PushDSBX:	dd	0		; push DS:BX in 21h call

OldStack:	dd	0		; push old stack pointer

Zpět na stránku systému MICRODOS