📄 iolpt.asm
字号:
TITLE IOLPT - Line printer Device Drivers
;***
; IOLPT - Line printer Device Drivers
;
; Copyright <C> 1986, Microsoft Corporation
;
;Purpose:
; This module contains the device independent printer routines for
; the BASIC Compiler. While this module is intended for use with
; the IBM Personal Computer, there is only a small amount which
; actually depends on this fact.
;
; BASIC Syntax mapping to included runtime entry points:
;
; - LPOS Function:
;
; LPOS(x)
; |
; B$LPOS
;
; - WIDTH Statement:
;
; Four different Syntax possibilities map to four runtime entry points:
;
; WIDTH size WIDTH LPRINT size
; | |
; B$WIDT B$LWID
;
;
; WIDTH filenumber, size WIDTH device, size
; | |
; B$DWID B$DWID
;
;******************************************************************************
INCLUDE switch.inc
INCLUDE rmacros.inc ; Runtime Macro Defintions
USESEG CONST
USESEG _DATA
USESEG _BSS
USESEG OI_TEXT
USESEG DV_TEXT
USESEG DK_TEXT
INCLUDE seg.inc
INCLUDE baslibma.inc
INCLUDE devdef.inc
INCLUDE files.inc
INCLUDE ascii.inc
INCLUDE rtps.inc ; constants shared with QBI
INCLUDE const.inc
TTY EQU 0 ;default for b$PTRFIL is TTY
PRSTM EQU 0 ;print statement
CHANL EQU 1 ;#
USING EQU 2 ;using
WRSTM EQU 4 ;write statement
LPSTM EQU 8 ;lprint statement
iniwid= 80 ;Initial printer width
sBegin _DATA
externB b$PRFG ;flag for PRINT/LPRINT/WRITE [#][USING]
EXTRN b$ERDEVP:word
;error codes from int 24 handler
; 00 - Write Protected.
; *01 - Unknown Unit
; *02 - Not Ready
; 03 - Unknown command
; 04 - Data Error
; 05 - Bad Drive structure length
; 06 - Seek Error
; 07 - Unknown Media
; 08 - Sector not found
; *09 - Printer out of paper
; 10 - Write Fault (hard disks only)
; 11 - Read Fault
; 12 - Other error.
iniwid= 80 ; Initial printer width
B$LPTWID DB NUM_LPT DUP(INIWID,0) ;Width/initial position
B$LPTCRF DB NUM_LPT DUP(0,0) ;CR flag/unused field
;Must follow B$LPTWID
;width/pos field
LPDCBSZ = NUM_LPT * 2
;LPT Device Control Block field definitions:
_LPWID= 0 ;device width (columns per line)
_LPPOS= 1 ;current column device is in
;LPT Device Flag Block field definitions:
_LPFLG= lpdcbsz ;Boolean attributes mask for this device
;Attribute definitions
_LPCRF= 1 ;non-zero=last char sent was Carriage Return
_LPunused=lpdcbsz+1 ;Unused field.
LPTPOS EQU B$LPTWID+_LPPOS
LPTWIDTH EQU B$LPTWID[DI+2*DN_LPT1+_LPWID] ;Base for indexed by
POSITION EQU B$LPTWID[DI+2*DN_LPT1+_LPPOS] ; device number
sEnd _DATA
sBegin CONST
externW b$FILVEC
LPNAMES DB "LPT1LPT2LPT3LPT4"
LPERRS DW 1,2,9
sEnd CONST
sBegin _BSS
externW b$PTRFIL
externW b$ERDEV ;defined in GWDATA.ASM
externW b$LPTFDB ; defined in GLOBALS.INC
externB b$PATHNAM ; defined in GWINI.ASM
externB b$EOL,,1 ; set when in B$$WCLF
sEnd _BSS
sBegin DK_TEXT
externNP B$WCHSET ; in prnval.asm, set dispatch vector
sEnd DK_TEXT
sBegin DV_TEXT
externNP b$devused ; drag in dvinit for lprint support
externNP B$CLSLPT
sEnd DV_TEXT
assumes CS,OI_TEXT
sBegin OI_TEXT
; Run-time Entries
PUBLIC B$D_LPT1
PUBLIC B$D_LPT2
PUBLIC B$D_LPT3
PUBLIC B$D_LPT4
; Run-time Externals
externNP B$OPNLPT
externNP B$SNDLPT
externNP B$UPCASE
externNP B$LHDALC_CPCT ; deallocate FDB and compact local heap
externNP B$OPEN_DEV
externNP B$ERR_FC
externNP B$ERR_BFN
externNP B$ERR_IOE
externNP B$ERR_DNA
externNP B$ERR_DTO
externNP B$ERR_OTP
; Illegal Device Functions
LPT_EOF EQU B$ERR_FC
LPT_LOC EQU B$ERR_FC
LPT_LOF EQU B$ERR_FC
LPT_RANDIO EQU B$ERR_FC
LPT_BAKC EQU B$ERR_FC
LPT_SINP EQU B$ERR_FC
LPT_BLKIN EQU B$ERR_FC ;5.41 PBS 28/jun/83
LPT_BLKOUT EQU B$ERR_FC
; Device Independent Printer Interface
DSPMAC MACRO func
DW LPT_&func
ENDM
;----- File Action Routines -----------------------------------------------
; These routines are all called from the file dispatcher.
; The registers are set up as follows:
; (ES:)[SI] = file data block address (points to file mode field)
; (DI) = device offset (0 = disk , 2 = next , 4 = next , ...)
; (AH) = function code of routine
; (AL,CX,DX,BX) = parameters for each routine
; These routines are free to use SI and DI as temporaries
fileio PROC
;***
; LPT_OPEN - OPEN statement for LPTn:
;
;Purpose:
; Allocates FDB for LPTn:, and opens it for output.
;
;Entry:
; (BX) = file number
; (AL) = device number for OPEN
; (CX) = variable record length
; b$PATHNAM = null-terminated options string (including the "LPTn:")
;Exit:
; (ES:)[SI] = *FDB
;
;Uses:
;
;Preserves:
; BX, CX
;
;Exceptions:
;
;******************************************************************************
LPT_OPEN:
PUSH BX
PUSH CX
PUSH AX ;save device number
MOV AH,MD_SQO+MD_RND ; valid file modes
MOV DL,LPTWIDTH ; DL = width
CALL B$OPEN_DEV ; allocate FDB with no buffer
FDB_PTR ES,SI,SI ;(ES:)[SI] = *FDB
;Parse option string.
PUSH SI ; save FDB pointer
MOV SI,OFFSET DGROUP:b$PATHNAM+5 ; get the options string
CALL GETPR0 ;Get 1st char in Filename, skipping blanks
JZ Default ;If no "BIN" option, default to ASC
LPRBIN: CMP AL,"B" ;BIN?
JNZ BadLptOpt ;no, bad LPT option.
CALL GETPRM
CMP AL,"I" ; I?
JNZ BadLptOpt ;no, error
CALL GETPRM
CMP AL,"N" ; N?
JNZ BadLptOpt ;no, error
CALL GETPR0 ;Get next non-blank char
JNZ BadLptOpt ;If not EOS then bad LPT option
POP SI
OR FileDB.FD_FLAGS,FL_BIN ;indicate binary mode
JMP SHORT LPRBIX
Default:
POP SI
AND FileDB.FD_FLAGS,NOT FL_BIN ;indicate ascii mode
LPRBIX:
POP AX ;restore device number
PUSH AX ;and save it again
NEG AL ; convert to positive number
CBW ; AH = 0
SHL AX,1 ;get -2*device number
MOV DI,AX ;move to DI
CALL B$GLPUID ;get printer number in AH
CALL B$OPNLPT ; open the device
FDB_PTR ES ;restore FDB SEG in ES after movement
OR AH,AH ;test for error
JZ NLPERR ;if none, then jump around
CALL B$LHDALC_CPCT ; Deallocate the FDB and compact local heap
JMP SHORT LPERR ;if so, then branch
NLPERR:
MOV FileDB.FD_HANDLE,BX ;store handle away in FDB
POP AX ;restore register
pop cx
pop bx
RET
BadLptOpt:
POP SI ; SI = *FDB
CALL B$LHDALC_CPCT ; Deallocate the FDB and compact local heap
JMP B$ERR_BFN ;bad file name
;Get Next Option Char forcing upper case
; Exit - Z = end-of-statement, else [AL]=byte
; SI not advanced if End Of String
GETPRM:
CMP BYTE PTR [SI],0
JNZ GetNxt ;Brif EOS
RET
GetNxt: LODSB
JMP SHORT GETPR1
;Get Next Option Char skipping blanks and forcing upper case
; Exit -Z = end-of-statement, else [AL]=byte
; SI not advanced if End Of String
GETPR0:
LODSB ;Get next char
CMP AL," "
JZ GETPR0 ;Ignore Blanks
CMP AL,0 ;Is it End Of String?
JZ GETPRX
;++Not needed unless a second option added.
; CMP AL,","
; JNZ GETPR1 ;Brif not ","
; OR AL,AL ;set NZ (not end-of-statement)
; STC ;set carry
; RET ;Comma returns: NZ and TC
GETPR1:
call B$UPCASE
OR AL,AL ;Chars return NZ and NC
GETPRX:
RET ;EOS returns TZ and NC
;++
B$D_LPT1: ;moved here out of module offset 0
B$D_LPT2:
B$D_LPT3:
B$D_LPT4:
DSPNAM
page
;***
;LPT_DWID -- WIDTH device statement. Added with [16]
;
;Purpose:
;
;Entry:
; (AL) = device number
; (DL) = device width
; (DI) = device offset
;Exit:
; None
;Uses:
; None
;Exceptions:
; None
;
;******************************************************************************
cProc LPT_DWID,<NEAR>
cBegin
MOV LPTWIDTH,DL ; Set new printer width (indexes by DI)
CMP AL,DN_LPT1 ; LPT1:?
JNE WidthRet ; brif not -- don't set LPRINT width
MOV b$LPTFDB.FD_WIDTH,DL ; set width for LPRINT
WidthRet:
cEnd
;***
;LPT_WIDTH -- WIDTH file statement.
;
;Purpose:
;
;Entry:
; (DL) = device width
; (DI) = device offset
;Exit:
; None
;Uses:
; None
;Exceptions:
; None
;
;******************************************************************************
LPT_WIDTH:
MOV FileDB.FD_WIDTH,DL
RET
page
LPERRT: DW OFFSET B$ERR_DNA ; 1 = device not available
DW OFFSET B$ERR_DTO ; 2 = time out
DW OFFSET B$ERR_OTP ; 3 = out of paper
LPERR:
CMP AH,3
JBE ERROR1 ;branch if legal error code
JMP B$ERR_IOE ;map all other error codes to I/O error
Error1: MOV AL,AH
cbw ; [AX]=error code 1..n
DEC AX ;[AX]=error code 0..n
shl ax,1 ;[AX]=offset into error dispatch table
xchg ax,bx
mov si,offset dgroup:lpnames
pop ax
mov al,ah
cbw
shl ax,1
shl ax,1
add si,ax
mov di,[b$ERDEVP+2] ;get ptr to erdev$ string
PUSH ES
PUSH DS
POP ES
movsw
movsw
POP ES
mov [b$ERDEVP],4
mov ax,lperrs[bx]
mov [b$ERDEV],ax
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -