; ; File: ; ipl.asm ; Description: ; ipl start-up code ; ; Copyright (c) 1995 ; Pasquale J. Villani ; All Rights Reserved ; ; This file is part of DOS-C. ; ; DOS-C is free software; you can redistribute it and/or ; modify it under the terms of the GNU General Public License ; as published by the Free Software Foundation; either version ; 2, or (at your option) any later version. ; ; DOS-C is distributed in the hope that it will be useful, but ; WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See ; the GNU General Public License for more details. ; ; You should have received a copy of the GNU General Public ; License along with DOS-C; see the file COPYING. If not, ; write to the Free Software Foundation, 675 Mass Ave, ; Cambridge, MA 02139, USA. ; ; $Logfile: C:/dos-c/src/ipl/ipl.asv $ ; ; $Header: C:/dos-c/src/ipl/ipl.asv 1.2 01 Sep 1995 17:44:40 patv $ ; ; $Log: C:/dos-c/src/ipl/ipl.asv $ ; ; Rev 1.2 01 Sep 1995 17:44:40 patv ;First GPL release. ; ; Rev 1.1 30 Jul 1995 20:48:12 patv ;Eliminated version strings in ipl ; ; Rev 1.0 02 Jul 1995 8:52:04 patv ;Initial revision. ; page 60,132 title ipl start-up code IFDEF ??version _TEXT segment byte public 'CODE' DGROUP group _DATA,_BSS,_BSSEND ; small model assume cs:_TEXT,ds:DGROUP,ss:DGROUP _TEXT ends _DATA segment word public 'DATA' _DATA ends _BSS segment word public 'BSS' _BSS ends _BSSEND segment byte public 'STACK' _BSSEND ends ELSE _TEXT segment byte public 'CODE' _TEXT ends _DATA segment word public 'DATA' _DATA ends CONST segment word public 'CONST' CONST ends _BSS segment word public 'BSS' _BSS ends _BSSEND segment byte public 'STACK' _BSSEND ends DGROUP group CONST,_DATA,_BSS,_BSSEND ; small/tiny model assume ds:DGROUP, ss:DGROUP ENDIF _TEXT segment byte public 'CODE' assume cs:_TEXT extrn _main:near extrn _con_driver:near extrn _blk_driver:near ;STANDALONE equ 0 ;--------------------------------------------------- ; ; Device entry points ; cmdlen equ 0 ; Length of this command unit equ 1 ; Subunit Specified cmd equ 2 ; Command Code status equ 3 ; Status media equ 13 ; Media Descriptor trans equ 14 ; Transfer Address count equ 18 ; Count of blocks or characters start equ 20 ; First block to transfer ; ; page ; ; entry proc near jmp short ipl_start ; ; The "CON" device ; ; This device is the standard console device used by ; XDOS and ipl ; public _con_dev _con_dev label far dd -1 dw 8003h ; con device (stdin & stdout) dw offset con_strategy dw offset con_entry db 'CON ' ; ; Header for device ; public _blk_dev _blk_dev label far dd -1 dw 0000h ; block device dw offset blk_strategy dw offset blk_entry db 3 db 0,0,0,0,0,0,0 page ; ; ipl start-up ; ipl_start: cli ; prevent interrupts while starting mov bx,ax ; save the boot type mov ax,cs ; initialize the segment registers mov ds,ax mov es,ax mov ax,seg DGROUP:tos mov ss,ax mov sp,offset DGROUP:tos mov ds,ax mov es,ax mov bp,sp ; and set up stack frame for c sti ; now enable them mov _BootDrive,bx ; tell where we came from mov _NumFloppies,cx ; and how many call _main mov ax,0 push ax call _exit jmp $ entry endp ; ; _exit ; perform an "exit" and quit ; ; exit(code) ; int code; ; _exit proc near public _exit cli hlt jmp _exit _exit endp ; ; _MarkStack ; Take a snapshot of the current stack pointer. ; Segmented stack in MarkSS and MarkSP. ; ; NOTE: ; You need at least two more byts of stack space ; other than what is reported to support this ; call. ; ; void MarkStack(void) ; _MarkStack proc near public _MarkStack mov ax,ss ; get the stack segment mov _MarkSS,ax mov ax,sp ; and the stack pointer add ax,2 ; adjust for this call mov _MarkSP,ax ret _MarkStack endp page ; ; NUL device strategy ; _nul_strtgy proc far public _nul_strtgy mov word ptr rqhdr,bx ;save rq headr mov word ptr rqhdr+2,es ret _nul_strtgy endp ; ; NUL device interrupt ; _nul_intr proc far public _nul_intr push es push bx les bx,rqhdr ;es:bx--> rqheadr or word ptr es:[bx+3],100h ;set "done" flag pop bx pop es ret _nul_intr endp page ; ; con device strategy ; ; NOTE: This code is not standard device driver handlers ; It is written for sperate code and data space. ; con_strategy proc far push ds push ax ; small model mov ax,DGROUP ; small model - cs != ds mov ds,ax mov word ptr DGROUP:con_rp+2,es mov word ptr DGROUP:con_rp,bx pop ax pop ds ret con_strategy endp ; ; con device interrupt ; ; NOTE: This code is not standard device driver handlers ; It is written for sperate code and data space. ; con_entry proc far push si push ax push cx push dx push di push bp push ds push es push bx ; small model mov ax,DGROUP ; small model - cs != ds mov ds,ax ; ax to carry segment mov word ptr DGROUP:dos_stk,sp ; use internal stack mov word ptr DGROUP:dos_seg,ss pushf ; put flags in bx pop bx cli ; no interrupts mov ss,ax mov sp,offset DGROUP:con_stk_top push bx popf ; restore interrupt flag mov bp,sp ; make a c frame push word ptr con_rp+2 push word ptr con_rp call _con_driver pop cx pop cx les bx,dword ptr con_rp ; now return completion code mov word ptr es:[bx].status,ax ; mark operation complete pushf pop bx cli ; no interrupts mov sp,word ptr DGROUP:dos_stk ; use dos stack mov ss,word ptr DGROUP:dos_seg push bx popf ; restore interrupt flag pop bx pop es pop ds pop bp pop di pop dx pop cx pop ax pop si ret con_entry endp page ; ; block device strategy ; ; NOTE: This code is not standard device driver handlers ; It is written for sperate code and data space. ; blk_strategy proc far push ds push ax ; small model mov ax,DGROUP ; small model - cs != ds mov ds,ax mov word ptr DGROUP:blk_rp+2,es mov word ptr DGROUP:blk_rp,bx pop ax pop ds ret blk_strategy endp ; ; block device interrupt ; ; NOTE: This code is not standard device driver handlers ; It is written for sperate code and data space. ; blk_entry proc far pushf push ax push bx push cx push dx push bp push si push di push ds push es ; small model mov ax,DGROUP ; small model - cs != ds mov ds,ax ; ax to carry segment mov word ptr DGROUP:dos_stk,sp ; use internal stack mov word ptr DGROUP:dos_seg,ss pushf ; put flags in bx pop bx cli ; no interrupts mov ss,ax mov sp,offset DGROUP:blk_stk_top push bx popf ; restore interrupt flag mov bp,sp ; make a c frame push word ptr blk_rp+2 push word ptr blk_rp call _blk_driver pop cx pop cx les bx,dword ptr blk_rp ; now return completion code mov word ptr es:[bx].status,ax ; mark operation complete cli ; no interrupts mov sp,word ptr DGROUP:dos_stk ; use dos stack mov ss,word ptr DGROUP:dos_seg pop es pop ds pop di pop si pop bp pop dx pop cx pop bx pop ax popf ret blk_entry endp page ; ; special interrupt routine for break key handling ; ; ; i_save ; save machine context on stack after an interrupt ; does not save ss and sp ; ; assumes flags and cs:ip are on stack from interrupt ; i_save proc near public i_save push bp ; start saving bp mov bp,sp ; and mark frame for exit push di ; save the rest of the registers push si push bx push cx push dx push ds push es xchg ax,[bp+2] ; swap return address with ax push ax ; put it back mov ax,[bp+2] ; recover ax from entry mov bp,[bp] ; and bp ret i_save endp ; ; i_exit ; recovers context from i_save and does interrupt return ; must be jumped to ; ; warning - make sure you're using the right stack ; i_exit proc near public i_exit pop es ; recover context pop ds pop dx pop cx pop bx pop si pop di pop bp pop ax iret ; and make like a tree (leave) i_exit endp extrn _break_handler:near _break_key proc near public _break_key call i_save ; save context mov ax,cs ; correct for segments mov ds,ax ; ax to carry segment mov word ptr DGROUP:intr_dos_stk,sp ; use internal stack mov word ptr DGROUP:intr_dos_seg,ss pushf ; put flags in bx pop bx cli ; no interrupts mov ss,ax mov sp,offset DGROUP:intr_stk_top push bx popf ; restore interrupt flag mov bp,sp ; make a c frame call _break_handler ; call handler les bx,dword ptr con_rp ; now return completion code pushf pop bx cli ; no interrupts mov sp,word ptr DGROUP:intr_dos_stk ; use dos stack mov ss,word ptr DGROUP:intr_dos_seg push bx popf jmp i_exit ; and restore & exit _break_key endp ; ; VOID INRPT FAR handle_break() ; assume cs:_TEXT public _handle_break _handle_break proc far push ax push bx push cx push dx push es push ds push si push di push bp mov bp,cs:DGROUP mov ds,bp mov bp,sp ; do nothing pop bp pop di pop si pop ds pop es pop dx pop cx pop bx pop ax iret _handle_break endp _TEXT ends _DATA segment word public 'DATA' ; Globally referenced variables - WARNING: DO NOT CHANGE ORDER ; BECAUSE THEY ARE DOCUMENTED AS UNDOCUMENTED (?) AND HAVE ; MANY MULTIPLEX PROGRAMS AND TSR'S ACCESSING THEM public _first_mcb _first_mcb dw (?) ; Start of user memory public _DPBp _DPBp dd (?) ; First drive Parameter Block public _sfthead _sfthead dd (?) ; System File Table head public _clock _clock dd (?) ; CLOCK$ device public _syscon _syscon dd (?) ; console device public _maxbksize _maxbksize dw (?) ; Number of Drives in system public _firstbuf; _firstbuf dd (?) ; head of buffers linked list public _CDSp _CDSp dd (?) ; Current Directory Structure public _FCBp _FCBp dd (?) ; FCB table pointer public _nprotfcb _nprotfcb dw (?) ; number of protected fcbs public _nblkdev _nblkdev db (?) ; number of block devices public _lastdrive _lastdrive db (?) ; value of last drive public _nul_dev _nul_dev label dword dd -1 dw 8004h ; attributes = char device, NUL bit set dw offset _nul_strtgy dw offset _nul_intr db 'NUL ' public _njoined _njoined db (?) ; number of joined devices ; ; end of controlled variables ; _DATA ends _BSS segment word public 'BSS' public _BootDrive _BootDrive dw (?) public _NumFloppies _NumFloppies dw (?) _MarkSS dw (?) public _MarkSS _MarkSP dw (?) public _MarkSP rqhdr dd (?) con_rp dd (?) blk_rp dd (?) clk_rp dd (?) dos_stk dw (?) dos_seg dw (?) intr_dos_stk dw (?) intr_dos_seg dw (?) ; condev private stack dw 1024 dup (?) con_stk_top label byte public con_stk_top ; blockdev private stack dw 1024 dup (?) dw 1024 dup (?) blk_stk_top label byte public blk_stk_top ; interrupt stack dw 1024 dup (?) intr_stk_top label byte public intr_stk_top ; ipl private stack area ; dw 3072 dup (?) dw 8192 dup (?) tos label byte public tos _BSS ends _BSSEND segment byte public 'STACK' public last last label word ; must always be end of stack area public _last _last label byte ; and c version _BSSEND ends end