Category : Assembly Language Source Code
Archive   : AT_INIT.ZIP
Filename : AT_INIT.ASM

 
Output of file : AT_INIT.ASM contained in archive : AT_INIT.ZIP

.XLIST
PAGE 78,120
PAGE
TITLE ŠŽ AT_INIT AT INITIALIZATION PROGRAM
.LIST
SUBTTL ROUTINE TO INITIALIZE AT COMPATIBLE PARAMETERS
.286C ; ENABLE 80286 INSTRUCTION SET
COMMENT *

AT_INIT VERSION 1.10

Copyright 1987 Don Gentry

A limited license is granted to all users of this program,
to make copies of this program, and distribute them to
other users, on the following conditions:

1. The notice on this page is not to be removed or altered

2. No fee is to be charged for copying or distributing
the program.

3. No warranty of any kind is offered. This program is offered
on an "AS IS" basis. Each user should verify that it meets
his needs and verify correct operation.

FOR HELP OR SUGGESTIONS WRITE:

DON GENTRY
183 BELLEGROVE CIRCLE
BRANDON, MS 39042

OR CALL (601) 992-0577


INITIALIZATION ROUTINE AT_INIT

PURPOSE:
INITIALIZE WARM BOOT INDICATOR FOR RESET BUTTON
INITIALIZE DISKETTE PARAMETER TABLE FOR FASTER
DISK RESPONSE
TURN ON CAPS LOCK (I LIKE CAPS..)
SET TYPEMATIC RATE AND DELAY

PARAMETERS:
NONE

USEAGE:
ASSEMBLE, LINK, AND USE EXE2BIN TO CREATE AT_INIT.SYS
ADD THE STATEMENT THAT FOLLOWS TO CONFGIG.SYS:
DEVICE=AT_INIT.SYS
*
PAGE
REQ_HDR SEGMENT AT 0 ; REQUEST HEADER STRUCTURE DEFINITION
; --------------------------------------------------------------------
; | |
; | DOS DEVICE DRIVER REQUEST HEADER |
; | 06/01/85 |
; --------------------------------------------------------------------
;
RH_LEN DB ? ; LENGTH OF RH + ANY DATA
RH_UNIT DB ? ; UNIT CODE
RH_COMMAND DB ? ; COMMAND CODE
;
; ---------- COMMAND CODE EQUATES
;
CMD_INIT EQU 0 ; INITIALIZATION ENTRY
CMD_MCHK EQU 1 ; MEDIA CHECK
CMD_BPB EQU 2 ; BUILD BPB
CMD_IOCTLI EQU 3 ; IO CONTROL INPUT
CMD_READ EQU 4 ; INPUT DATA (READ FROM DEVICE)
CMD_NDI EQU 5 ; NON DESTRUCTIVE INPUT NO WAIT]
CMD_STAT EQU 6 ; INPUT STATUS
CMD_FLUSH EQU 7 ; INPUT FLUSH
CMD_WRITE EQU 8 ; OUTPUT DATA (WRITE TO DEVICE)
CMD_WRITEV EQU 9 ; WRITE WITH VERIFY
CMD_STATOUT EQU 10 ; OUTPUT STATUS
CMD_OFLUSH EQU 11 ; OUTPUT FLUSH
CMD_IOCTLO EQU 12 ; IO CONTROL OUTPUT
;
RH_STATUS DB ? ; STATUS WORD
ORG RH_STATUS ; REDEFINE STATUS WORD
RH_STAT_HI DB ? ; STATUS BYTE HIGH
STAT_ERR EQU 10000000B ; ERROR STATUS RETURNED
STAT_BUSY EQU 00000010B ; DEVICE BUSY
STAT_DONE EQU 00000001B ; OPERATION COMPLETE
RH_STAT_LO DB ? ; STATUS BYTE LOW
ERR_WPV EQU 00H ; WRITE PROTECT VIOLATION
ERR_UNIT EQU 01H ; UNKNOWN UNIT NUMBER
ERR_DNR EQU 02H ; DEVICE NOT READY
ERR_CMD EQU 03H ; UNKNOWN COMMAND
ERR_CRC EQU 04H ; CRC ERROR DETECTED
ERR_DRSL EQU 05H ; BAD DRIVE REQUEST STRUCTURE LENGTH
ERR_SEEK EQU 06H ; SEEK ERROR
ERR_MEDIA EQU 07H ; UNKNOWN MEDIA
ERR_SECTOR EQU 08H ; SECTOR NOT FOUND
ERR_PAPER EQU 09H ; PRINTER OUT OF PAPER
ERR_WRITE EQU 0AH ; WRITE FAULT
ERR_GEN EQU 0BH ; GENERAL FAILURE
;
; ---------- STATUS WORD EQUATES
;
DD ? ; RESERVED FOR DOS
DD ? ; RESERVED FOR DOS
RH_DATA EQU $ ; START OF OPERATION DATA
;
; ---------- FUNCTION CALL PARAMETER LISTS
;
; ---------- INITIALIZATION CALL (CMD CODE 0)
;
ORG RH_DATA ; SET LOCATION COUNTER
IN_UNITS DB ? ; NUMBER OF UNITS
IN_PGMEND DD ? ; ENDING ADDRESS
ORG IN_PGMEND ; REDEFINE ENDING ADDRESS
IN_PGMOFF DW ? ; OFFSET OF ENDING ADDRESS
IN_PGMSEG DW ? ; SEGMENT OF ENDING ADDRESS
IN_BPBPTR DD ? ; POINTER TO BPB ARRAY
ORG IN_BPBPTR ; REDEFINE BPB POINTER
IN_BPBOFF DW ? ; OFFSET TO BPB ARRAY
IN_BPBSEG DW ? ; SEGMENT OF BPB ARRAY
;
; ---------- MEDIA CHECK CALL (CMD CODE 1)
;
ORG RH_DATA ; SET LOCATION COUNTER
M_DES DB ? ; MEDIA DESCRIPTOR BYTE FROM DOS
;
M_ONES EQU 11111000B ; MUST BE ONES
M_DEMOUNT EQU 00000100B ; REMOVABLE MEDIA
M_8SECTOR EQU 00000010B ; 8 SECTOR
M_2SIDE EQU 00000001B ; DOUBLE SIDED
;
M_STAT DB ? ; RETURNED STATUS
M_CHG EQU -1 ; MEDIA HAS GHANGED
M_UNK EQU 0 ; DON'T KNOW IF CHANGED
M_SAME EQU 1 ; MEDIA HAS NOT GHANGED
;
; ---------- BUILD BPB CALL (CMD CODE 2)
;
ORG RH_DATA ; SET LOCATION COUNTER
BPB_DES DB ? ; MEDIA DESCRIPTOR FROM DOS
BPB_DTA DD ? ; DATA XFER ADDRESS
ORG BPB_DTA ; REDEFINE DTA ADDRESS
BPB_DTAOFF DW ? ; DTA OFFSET
BPB_DTASEG DW ? ; DTA SEGMENT
BPB_BPB DD ? ; BPB ARRAY TABLE ADDRESS
ORG BPB_BPB ; REDEFINE BPB ADDRESS
BPB_BPBOFF DW ? ; BPB OFFSET
BPB_BPBSEG DW ? ; BPB SEGMENT
;
; ---------- INPUT OR OUTPUT (CMD CODE 3,4,8,9,12)
;
ORG RH_DATA ; SET LOCATION COUNTER
IO_DES DB ? ; MEDIA DESCRIPTOR BYTE FROM DOS
IO_DTA DD ? ; DATA XFER ADDRESS (BUFFER)
ORG IO_DTA ; REDEFINE DTA ADDRESS
IO_DTAOFF DW ? ; DTA OFFSET
IO_DTASEG DW ? ; DTA SEGMENT
IO_CNT DW ? ; BYTE/SECTOR COUNT
IO_SECTOR DW ? ; STARTING SECTOR NUMBER
;
; ---------- NON DESTRUCTIVE INPUT NO WAIT (CMD CODE 5)
;
ORG RH_DATA ; SET LOCATION COUNTER
NDI_BYTE DB ? ; BYTE READ FROM DEVICE
REQ_HDR ENDS ; END OF STRUCTURE
;
; --------------------------------------------------------------------
; | ASSIGN THE CPU IDENTIFIER |
; | |
; | YOU SHOULD EQUATE THE SYMBOL TYPE_CPU TO IDENTIFY |
; | THE TYPE OF CPU USED FOR EXECUTION. IF RUNNING ON |
; | AN 80186, OR NEC V20 USE 186 AND THE EXTENDED INSTRUCTIONS |
; | WILL BE USED. |
; | |
; | 186 FOR NEC V20, 80186, OR 8088 |
; | 86 FOR 8088 OR 8086 |
; | |
; --------------------------------------------------------------------
;
TYPE_CPU EQU 186 ; DEFAULT IS 8086 (WILL RUN ON 186)
; ____________________________________________________________________
; | |
; | INCLUDE MACROS FOR EASE OF CODING & CLARITY |
; |____________________________________________________________________|
;
IFE TYPE_CPU-186
SHIFT MACRO DIR,DEST,NUM
SH&DIR DEST,&NUM ; SHIFT
ENDM
PUSHR MACRO ; SAVE REGISTERS
PUSHA ; SAVE REGS
ENDM
POPR MACRO ; RESTORE REGISTERS
POPA ; RESTORE REGS
ENDM
ENDIF
;
IFE TYPE_CPU-86
SHIFT MACRO DIR,DEST,NUM
REPT NUM
SH&DIR DEST,1 ; SHIFT
ENDM
ENDM
;
PUSHR MACRO ; SAVE REGISTERS
PUSH AX ; SAVE AX
PUSH CX ; SAVE CX
PUSH DX ; SAVE DX
PUSH BX ; SAVE BX
PUSH SP ; SAVE SP
PUSH BP ; SAVE BP
PUSH SI ; SAVE SI
PUSH DI ; SAVE DI
ENDM
;
POPR MACRO ; RESTORE REGISTERS
POP DI ; RESTORE DI
POP SI ; RESTORE SI
POP BP ; RESTORE BP
POP BX ; DISCARD SP [LIKE POPA ON 80186/V20] 0
POP BX ; RESTORE BX
POP DX ; RESTORE DX
POP CX ; RESTORE CX
POP AX ; RESTORE AX
ENDM ; END OF MACRO DEFINITION
ENDIF
;
PAGE
; ___________________________________________________________________
; | |
; | EQUATES FOR EASE OF CODING & CONDITIONAL ASSEMBLY |
; |___________________________________________________________________|
;
LF EQU 0AH ; LINE FEED
CR EQU 0DH ; CARRIAGE RETURN
EOM EQU '$' ; END OF MESSAGE
; ___________________________________________________________________
; | |
; | BEGIN THE CODE SEGMENT OF PROGRAM |
; |___________________________________________________________________|
;
CSEG SEGMENT PARA PUBLIC 'CODE' ; IDENTIFY CODE SEGMENT
ASSUME CS:CSEG ; INITIAL ASSUMPTION
; --------------------------------------------------------------------
; | |
; | DOS DEVICE DRIVER DEVICE HEADER |
; | |
; --------------------------------------------------------------------
;
DH_NEXT DD -1 ; DEVICE DRIVER CHAIN FIELD
DH_ATTR DW 0010000000000000B ; DEVICE ATTRIBUTE FIELD
; | |
; | `-----------------> NON-IBM FORMAT
; `-------------------> BLOCK DEVICE
;
DH_STRAT DW D_STRAT ; OFFSET OF STRATEGY ENTRY POINT
DH_RUPT DW D_RUPT ; OFFSET OF INTERRUPT ENTRY POINT
DH_NAME DB 'ACS-INIT' ; DEVICE DRIVER NAME
DB 'V1M00' ; VERSION & LEVEL
;
INIT_ID:
DB LF,LF,CR
DB 'AT_INIT V1.10 Copyright 1987 Don Gentry'
DB LF,CR,EOM
;
INIT_DSK:
DB 'Diskette parameters initialized'
DB LF,CR,EOM
;
INIT_IPL:
DB 'Warm boot indicator initialized'
DB LF,LF,CR,EOM
;
INIT_KB1:
DB 'Keyboard delay set to 250ms typematic rate 30cps'
DB LF,LF,CR,EOM
;
INIT_CAP:
DB 'Caps lock set'
DB LF,CR,EOM
;
DW 64 DUP(0) ; STACK STORAGE
DRIVSTAK EQU $ ; OUR LOCAL STACK
DOS_SP DW 0 ; DOS' STACK POINTER
DOS_SS DW 0 ; DOS' STACK SEGMENT
RH_PTR DD 0 ; REQUEST HEADER POINTER
ORG RH_PTR ; REDEFINE THE POINTER
RH_OFF DW 0 ; REQ HDR OFFSET ADDR
RH_SEG DW 0 ; REQ HDR SEGMENT ADDR
; --------------------------------------------------------------------
; | |
; | DOS DEVICE DRIVER STRATEGY ENTRY POINT |
; | |
; --------------------------------------------------------------------
;
; Since we aren't really a device driver (we just want to
; be loaded early in the IPL ) our STRATEGY entry really
; does nothing. We'll just save pointers and return to
; the caller.
;
D_STRAT PROC FAR ; STRATEGY ENTRY POINT
MOV RH_SEG,ES ; SAVE RH SEG ADDR
MOV RH_OFF,BX ; SAVE RH OFF ADDR
RET ; JUST RETURN
D_STRAT ENDP ; END OF PROCEDURE
;
D_RUPT PROC FAR ; INTERRUPT ENTRY POINT
; --------------------------------------------------------------------
; | |
; | DOS DEVICE DRIVER INTERRUPT ENTRY POINT |
; | |
; --------------------------------------------------------------------
;
; Since we aren't really a device driver (we just want to
; be loaded early in the IPL ) our INTERRUPT entry will
; only execute code on the INITIALIZATION entry. We won't
; leave any code resident.
;
ASSUME CS:CSEG ; INFORM ASSEMBLER
;
; GET OUR OWN STACK
;
PUSH AX ; SAVE AX CONTENTS
MOV DOS_SP,SP ; SAVE DOS SP
MOV DOS_SS,SS ; SAVE DOS SS
MOV AX,CS ; NEW STACK SEGMENT TO AX
CLI ; RUPTS OFF
MOV SS,AX ; TO STAK SEG REG
MOV SP,OFFSET DRIVSTAK ; NEW STACK POINTER
STI ; RUPTS BACK ON
;
ASSUME SS:CSEG ; INFORM ASSEMBLER
PUSHR ; SAVE DOS' REGS
PUSH ES ; SAVE ES REG
LES BX,RH_PTR ; RELOAD REQ_HDR ADDRESS
ASSUME ES:REQ_HDR ; INFORM ASSEMBLER
MOV AL,RH_COMMAND[BX] ; PICK UP COMMAND CODE
CMP AL,CMD_INIT ; INIT ENTRY ??
JE INIT_CMD ; ...YES - HANDLE INITILAZITION
;
; IF NOT INITIALIZATION ENTRY, DUMMY STATUS & EXIT
;
LES BX,RH_PTR ; RELOAD REQ_HDR POINTER
MOV RH_STAT_HI[BX],STAT_ERR+STAT_DONE ;STATUS
MOV RH_STAT_LO[BX],ERR_GEN ; REPORT GENERAL FAILURE
MOV IO_CNT[BX],00H ; SET NUMBER OF BYTES XFER'D
POP AX ; RESTORE AX REGISTER
RET ; RETURN TO CALLER
RES_CODE EQU $+1 ; MARK END OF RESIDENT ROUTINE
INIT_CMD: ; COMMAND IS INITIALIZE
;
; ----- CLEAR THE DISPLAY
;
MOV AH,06H ; SCROLL ACTIVE DISPLAY
MOV AL,00D ; ENTIRE WINDOW
MOV CH,00D ; UPPER LEFT ROW
MOV CL,00D ; UPPER LEFT COLUMN
MOV DH,25D ; LOWER LEFT ROW
MOV DL,79D ; LOWER LEFT COLUMN
MOV BH,07D ; ATTRIBUTE BYTE
INT 10H ; VIDEO RUPT TO BIOS
;
; ----- POSITION THE CURSOR
;
MOV AH,02H ; SET CURSOR POSITION
MOV DH,02D ; ROW
MOV DL,00D ; COLUMN
MOV BH,00D ; VIDEO PAGE NUMBER
INT 10H ; VIDEO RUPT TO BIOS
;
; ----- DISPLAY THE CONFIG.SYS PARMS
;
PUSH DS ; SAVE DE REG
LES BX,RH_PTR ; RELOAD REQ_HDR POINTER
LDS SI,IN_BPBPTR[BX] ; GET ADDRESS OF DATA
ASSUME DS:NOTHING ; INFORM ASSEMBLER
CHR_OUT: ; OUTPUT A CHARACTER
MOV DL,DS:[SI] ; GET A CHARACTER IN DL
MOV AH,02H ; SET DOS' RUPT CODE
INT 21H ; RUPT TO DOS
CMP DL,0AH ; JUST DISPLAY A LINE FEED ?
JE BUF_DONE ; ...YES - EXIT THE LOOP
CMP DL,0DH ; JUST DISPLAY A CARRIAGE RETURN
JE BUF_DONE ; ...YES - EXIT THE LOOP
INC SI ; GET ADDRESS OF NEXT CHARACTER
JMP CHR_OUT ; OUTPUT A CHARACTER
BUF_DONE: ; LOOP EXITS HERE
POP DS ; RELOAD DS REG
ASSUME DS:CSEG ; INFORM ASSEMBLER
;
; ----- SET PROGRAM ENDING ADDRESS IN REQ HEADER
;
MOV IN_UNITS[BX],00H ; SHOW NO UNITS
MOV IN_PGMOFF[BX],0000H ; SHOW NO CODE RESIDENT
MOV IN_PGMSEG[BX],CS ; GET PROGRAM SEGMENT
;
; ----- PRINT INITIALIZATION MESSAGE
;
LEA DX,INIT_ID ; GET ADDRESS OF MSG
MOV AX,0900H ; DOS PRINT FUNCTION
INT 21H ; INVOKE DOS
; ____________________________________________________________________
; | |
; | INITIALIZE DISKETTE PARAMETER TABLE |
; |____________________________________________________________________|
;
PUSH DS ; SAVE DS REGISTER
XOR AX,AX ; ZERO AX REG
MOV DS,AX ; ADDRESS PAGE 00
LDS DI,DWORD PTR DS:78H ; ADDRESS THE DISKETTE PARM TABLE
MOV BYTE PTR [DI],239 ; MODIFY HEAD STEP RATE,
MOV BYTE PTR [DI+2],200 ; MOTOR OFF TIME,
MOV BYTE PTR [DI+9],00 ; AND HEAD SETTLE TIME
XOR AX,AX ; RESET CODE FOR RUPT
INT 13H ; ISSUE RESET RUPT
POP DS ; RESTORE DS REG
;
; ----- PRINT DISKETTE INITIALIZATION MESSAGE
;
LEA DX,INIT_DSK ; GET ADDRESS OF MSG
MOV AX,0900H ; DOS PRINT FUNCTION
INT 21H ; INVOKE DOS
; ____________________________________________________________________
; | |
; | SET CAPSLOCK ON |
; |____________________________________________________________________|
;
PUSH DS ; SAVE DS REGISTER
MOV AX,40H ; ADDRESS BIOS DATA AREA
MOV DS,AX ; WITH DS REGISTER
MOV BX,17H ; DISPLACE TO KEYBOARD STATUS BYTE
MOV AL,40H ; CAPS LOCK BIT
OR [BX],AL ; SET CAPS LOCK BIT ON
POP DS ; RESTORE DS REG
;
; ----- PRINT CAPS LOCK INITIALIZATION MESSAGE
;
LEA DX,INIT_CAP ; GET ADDRESS OF MSG
MOV AX,0900H ; DOS PRINT FUNCTION
INT 21H ; INVOKE DOS
; ____________________________________________________________________
; | |
; | SET DELAY AND TYPEMATIC RATE |
; |____________________________________________________________________|
;
PUSH AX ; SAVE AX REGISTER
PUSH BX ; SAVE BX REGISTER
MOV AH,03H ; SET THE INTERRUPT
MOV AL,05H ; FUNCTION REQUEST CODES
MOV BL,00H ; SET RATE TO 30CPS
MOV BH,01H ; SET DELAY TO 250 MILLISEC
INT 16H ; ISSUE KEYBOARD SERVICE RUPT
;
; ----- PRINT CAPS LOCK INITIALIZATION MESSAGE
;
LEA DX,INIT_KB1 ; GET ADDRESS OF MSG
MOV AX,0900H ; DOS PRINT FUNCTION
INT 21H ; INVOKE DOS
POP BX ; RESTORE BX REG
POP AX ; RESTORE AX REG
; ____________________________________________________________________
; | |
; | INITIALIZE BIOS WARM BOOT INDICATOR |
; |____________________________________________________________________|
;
; ----- DOING THIS ALLOW US TO HIT THE RESET BUTTON AND RE-BOOT
; ----- WITHOUT RUNNING THROUGH POST
;
PUSH ES ; SAVE ES REG
MOV AX,040H ; GET SEG VALUE IN AX
MOV ES,AX ; SET ES SEG REGISTER
MOV AX,1234H ; GET WARM BOOT VALUE
MOV ES:[072H],AX ; SET WARM BOOT INDICATOR
POP ES ; RESTORE ES
;
; ----- PRINT WARM BOOT INITIALIZATION MESSAGE
;
LEA DX,INIT_IPL ; GET ADDRESS OF MSG
MOV AX,0900H ; DOS PRINT FUNCTION
INT 21H ; INVOKE DOS
;
; ----- RESTORE DOS REGS FROM OUR STACK
;
POP ES ; RESTORE ES REG
POPR ; RESTORE REGS
ASSUME DS:NOTHING,SS:NOTHING,ES:NOTHING ; INFORM ASSEMBLER
CLI ; RUPTS OFF
MOV SP,DOS_SP ; RESTORE DOS SP
MOV SS,DOS_SS ; RESTORE DOS SS
STI ; RUPTS BACK ON
POP AX ; RESTORE AX REG
RET ; RETURN TO CALLER
D_RUPT ENDP
CSEG ENDS ; END OF CODE SEG
END