mirror of
https://github.com/microsoft/MS-DOS.git
synced 2026-05-19 19:57:04 +01:00
MZ is back!
This commit is contained in:
committed by
Microsoft Open Source
parent
8ee9712c74
commit
2d04cacc53
@@ -0,0 +1,573 @@
|
||||
; Termcap description of capabilities:
|
||||
|
||||
;ibmans4:mtcon:IBM PC with V4.0 ANSI driver:\
|
||||
; :al=\E[L:am:bs:ce=\E[K:cl=\E[2J\E[H:cm=\E[%;%H:co#80:\
|
||||
; :dl=\E[M:do=\E[B:ho=\E[H:li#24:mi:nd=\E[C:\
|
||||
; :ms:pt:se=\E[m:so=\E[1;36m:up=\E[A:\
|
||||
; :kb=^h:ku=\E[A:kd=\E[B:kl=\E[D:kr=\E[C:kh=\E[H:kn#8:\
|
||||
; :k1=\ES:k2=\ET:k3=\EU:k4=\EV:k5=\EW:\
|
||||
; :k6=\EP:k7=\EQ:k8=\ER:
|
||||
|
||||
CMDTABL DB 'A'
|
||||
DW CUU ;CUrsor Up
|
||||
DB 'B'
|
||||
DW CUD ;CUrsor Down
|
||||
DB 'C'
|
||||
DW CUF ;CUrsor Forward
|
||||
DB 'D'
|
||||
DW CUB ;CUrsor Back
|
||||
DB 'H'
|
||||
DW CUP ;CUrsor Position
|
||||
DB 'J'
|
||||
DW ED ;Erase in Display
|
||||
DB 'K'
|
||||
DW EL ;Erase in Line
|
||||
DB 'L'
|
||||
DW IL ;Insert Line
|
||||
DB 'M'
|
||||
DW xDL ;Delete Line
|
||||
;; DB 'R'
|
||||
;; DW CPR ;Cursor Postion Report
|
||||
DB 'f'
|
||||
DW HVP ;Horizontal and Vertical Position
|
||||
DB 'h'
|
||||
DW SM ;Set Mode
|
||||
DB 'l'
|
||||
DW RM ;Reset Mode
|
||||
DB 'm'
|
||||
DW SGR ;Select Graphics Rendition
|
||||
;; DB 'n'
|
||||
;; DW DSR ;Device Status Report
|
||||
DB 's'
|
||||
DW SCP ;Save Cursor Position
|
||||
DB 'u'
|
||||
DW RCP ;Restore Cursor Position
|
||||
DB 00
|
||||
|
||||
; Graphic Rendition modes: parameter, mask, set
|
||||
GRMODE DB 00,00000000B,00000111B ; all off
|
||||
DB 01,11111111B,00001000B ; bold (increased intensity)
|
||||
DB 04,11111000B,00000001B ; underscore
|
||||
DB 05,11111111B,10000000B ; blink
|
||||
DB 07,11111000B,01110000B ; reverse video
|
||||
DB 08,10001000B,00000000B ; concealed
|
||||
DB 30,11111000B,00000000B ; foreground colors ...
|
||||
DB 31,11111000B,00000100B
|
||||
DB 32,11111000B,00000010B
|
||||
DB 33,11111000B,00000110B
|
||||
DB 34,11111000B,00000001B
|
||||
DB 35,11111000B,00000101B
|
||||
DB 36,11111000B,00000011B
|
||||
DB 37,11111000B,00000111B
|
||||
DB 40,10001111B,00000000B ; background colors ...
|
||||
DB 41,10001111B,01000000B
|
||||
DB 42,10001111B,00100000B
|
||||
DB 43,10001111B,01100000B
|
||||
DB 44,10001111B,00010000B
|
||||
DB 45,10001111B,01010000B
|
||||
DB 46,10001111B,00110000B
|
||||
DB 47,10001111B,01110000B
|
||||
DB 0FFH
|
||||
|
||||
; Set/Reset Modes: indexed by (SelChar-'<'*8) + (PARAM0 AND 7)
|
||||
SRMODE DW 0,0,0,0,0,0,0,0 ; SelChar '<'
|
||||
DW 1,1,1,1,1,1,1,WRAP ; SelChar '='
|
||||
DW 0,EnaL25,0,0,0,0,0,0 ; SelChar '>'
|
||||
DW 0,0,0,0,0,0,0,WRAP ; SelChar '?'
|
||||
|
||||
PAGE
|
||||
; The following are duplicates of the same variables from the ROM
|
||||
;
|
||||
;* WARNING - the following two variables are accessed as a word
|
||||
MODE DB 3
|
||||
MAXCOL DB 79
|
||||
IF LINE25 ; special treatment of line 25?
|
||||
maxrow equ 24
|
||||
ELSE
|
||||
maxrow equ 25
|
||||
ENDIF
|
||||
;* WARNING - the following two variables are accessed as a word
|
||||
COL DB 0 ; current column
|
||||
ROW DB 0 ; current row
|
||||
|
||||
|
||||
AnsiState LABEL BYTE ; the following must be saved on a screen swap
|
||||
WRAP DB 1 ; 0 = NO WRAP, 1 = WRAP
|
||||
EnaL25 DB 0 ; 0 = 25th line disabled, 1 = enabled
|
||||
STATE DW S1
|
||||
SAVCR DW 0 ; saved cursor position
|
||||
;* WARNING - the following two variables are accessed as a word
|
||||
SelChar DB 0 ; <,=,> or ? private use indicators
|
||||
PRMCNT LABEL BYTE ; number of parameters for command
|
||||
PRMCNTW DW 0
|
||||
NUMPARAM equ 5 ; max. number of parameters
|
||||
PARAM DB NUMPARAM DUP (?) ; buffer for command parameters
|
||||
;* WARNING - the following two variables are accessed as a word
|
||||
attrw LABEL WORD
|
||||
ATTR DB 00000111B ;CHARACTER ATTRIBUTE
|
||||
BPAGE DB 0 ;BASE PAGE
|
||||
|
||||
AnsiSize equ ($-AnsiState)
|
||||
|
||||
IF (AnsiSize GT TermSize)
|
||||
.RADIX 0 ; ERROR - Terminal state not big enough
|
||||
ENDIF
|
||||
|
||||
;-------------------------------------------------------------
|
||||
;
|
||||
; CHROUT - WRITE OUT CHAR IN AL USING CURRENT ATTRIBUTE
|
||||
;
|
||||
base dw 0b800h
|
||||
screen_seg dw 00000h
|
||||
|
||||
chrout: cmp al,13 ; carriage return?
|
||||
ja outchr
|
||||
jnz trylf
|
||||
mov [col],0
|
||||
;; jmp short setit
|
||||
jmp setit
|
||||
|
||||
trylf: cmp al,10 ; line feed?
|
||||
jz lf
|
||||
cmp al,7 ; bell?
|
||||
jnz trytab
|
||||
torom:
|
||||
mov bx,[attrw]
|
||||
and bl,7
|
||||
mov ah,14
|
||||
int 10h
|
||||
ret5: ret
|
||||
|
||||
trytab:
|
||||
cmp al,9 ; tab?
|
||||
jnz tryback
|
||||
mov al,[col]
|
||||
add al,8
|
||||
mov ah,al
|
||||
and ah,7
|
||||
sub al,ah
|
||||
cmp al,[maxcol]
|
||||
jb tunder
|
||||
mov al,[maxcol]
|
||||
tunder:
|
||||
mov [col],al
|
||||
jmp short setit
|
||||
|
||||
tryback:
|
||||
cmp al,8 ; backspace?
|
||||
jnz outchr
|
||||
cmp [col],0
|
||||
jz ret5
|
||||
dec [col]
|
||||
jmp short setit
|
||||
|
||||
outchr:
|
||||
mov bx,[attrw]
|
||||
mov cx,1
|
||||
mov ah,9
|
||||
int 10h
|
||||
inc [col]
|
||||
mov al,[col]
|
||||
cmp al,[maxcol]
|
||||
jbe setit
|
||||
cmp [wrap],1
|
||||
jz outchr1
|
||||
dec [col]
|
||||
ret
|
||||
outchr1:
|
||||
mov [col],0
|
||||
lf: cmp [row],(maxrow-1)
|
||||
ja setit ; on line 25, don't move
|
||||
jz lf1 ; on 24th line, scroll
|
||||
inc [row]
|
||||
jmp short setit
|
||||
lf1: call scroll
|
||||
|
||||
setit: mov dx,word ptr col
|
||||
mov bh,[bpage]
|
||||
mov ah,2
|
||||
int 10h
|
||||
ret
|
||||
|
||||
scroll: mov al,mode
|
||||
cmp al,2
|
||||
jz myscroll
|
||||
cmp al,3
|
||||
jz myscroll
|
||||
IF LINE25
|
||||
xor cx,cx ; from 0,0
|
||||
mov dh,(maxrow-1) ; to maxrow-1,maxcol
|
||||
mov dl,maxcol
|
||||
mov bh,attr
|
||||
mov ax,0601h ; scroll up one line
|
||||
int 10h
|
||||
ret
|
||||
ELSE
|
||||
mov al,10
|
||||
jmp torom
|
||||
ENDIF
|
||||
myscroll:
|
||||
mov bh,[attr]
|
||||
mov bl,' '
|
||||
mov bp,80
|
||||
mov ax,[base]
|
||||
add ax,[screen_seg]
|
||||
mov es,ax
|
||||
mov ds,ax
|
||||
xor di,di
|
||||
mov si,160
|
||||
mov cx,(maxrow-1)*80
|
||||
cld
|
||||
|
||||
; This code will never get executed since we get here when
|
||||
; mode = 2 or 3 only.
|
||||
;; cmp cs:[base],0b800h
|
||||
;; jz colorcard
|
||||
|
||||
;; rep movsw
|
||||
;; mov ax,bx
|
||||
;; mov cx,bp
|
||||
;; rep stosw
|
||||
;; jmp short sret
|
||||
|
||||
;;colorcard:
|
||||
mov dx,3dah
|
||||
wait2: in al,dx
|
||||
test al,8
|
||||
jz wait2
|
||||
mov al,25h
|
||||
mov dx,3d8h
|
||||
out dx,al ;turn off video
|
||||
rep movsw
|
||||
mov ax,bx
|
||||
mov cx,bp
|
||||
rep stosw
|
||||
mov al,29h
|
||||
mov dx,3d8h
|
||||
out dx,al ;turn on video
|
||||
sret: push cs
|
||||
pop ds
|
||||
ret
|
||||
|
||||
|
||||
CharOut: PUSH AX ; Main entry point
|
||||
PUSH BX
|
||||
PUSH CX
|
||||
PUSH DX
|
||||
PUSH SI
|
||||
PUSH DI
|
||||
PUSH ES
|
||||
PUSH BP
|
||||
|
||||
MOV [base],0B800H
|
||||
XCHG AX,SI ; SAVE CHARACTER TO STUFF
|
||||
MOV AX,40H ; POINT TO ROS BIOS
|
||||
MOV DS,AX
|
||||
MOV AX,DS:[49H] ; AL=MODE, AH=MAX COL
|
||||
DEC AH ; ANSI NEEDS 0-79 OR 0-39
|
||||
MOV WORD PTR CS:[MODE],AX ; SAVE MODE AND MAX COL
|
||||
CMP AL,7
|
||||
JNZ NOT_BW
|
||||
MOV WORD PTR CS:[base],0B000H
|
||||
NOT_BW: MOV AL,DS:[62H] ; GET ACTIVE PAGE
|
||||
MOV CS:[BPAGE],AL
|
||||
CBW
|
||||
ADD AX,AX
|
||||
MOV BX,AX
|
||||
MOV AX,DS:[BX+50H] ; AL=COL, AH=ROW
|
||||
MOV WORD PTR CS:[COL],AX ; SAVE ROW AND COLUMN
|
||||
MOV AX,DS:[4EH] ; GET START OF SCREEN SEG
|
||||
MOV CL,4
|
||||
SHR AX,CL ; CONVERT TO A SEGMENT
|
||||
PUSH CS
|
||||
POP DS
|
||||
MOV [screen_seg],AX
|
||||
XCHG AX,SI ; GET BACK CHARACTER IN AL
|
||||
|
||||
CALL VIDEO
|
||||
POP BP
|
||||
POP ES
|
||||
POP DI
|
||||
POP SI
|
||||
POP DX
|
||||
POP CX
|
||||
POP BX
|
||||
POP AX
|
||||
RET
|
||||
|
||||
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; OUTPUT SINGLE CHAR IN AL TO VIDEO DEVICE
|
||||
;
|
||||
VIDEO: MOV SI,OFFSET STATE
|
||||
JMP [SI]
|
||||
|
||||
S2: CMP AL,'['
|
||||
JZ S22
|
||||
JMP S1
|
||||
S22: MOV WORD PTR [SI],OFFSET S30
|
||||
XOR BX,BX
|
||||
MOV WORD PTR SelChar,BX
|
||||
MOV WORD PTR PARAM,BX
|
||||
JMP SHORT S3B
|
||||
|
||||
S30: CMP AL,'?' ; experimental use selector (SM/RM)?
|
||||
JA S7
|
||||
mov SelChar,al
|
||||
MOV WORD PTR [SI],OFFSET S3
|
||||
cmp al,'<'
|
||||
jae S3B
|
||||
|
||||
S3: CMP AL,';'
|
||||
JNZ S3C
|
||||
S3A: INC PRMCNT
|
||||
S3B: CALL GETPTR
|
||||
XOR AX,AX
|
||||
MOV WORD PTR [BX],AX ;DEFAULT VALUE IS ZERO
|
||||
RET
|
||||
|
||||
S3C: CMP AL,'0'
|
||||
JB S3D
|
||||
CMP AL,'9'
|
||||
JA S7
|
||||
CALL GETPTR
|
||||
SUB AL,'0'
|
||||
XCHG AL,BYTE PTR [BX]
|
||||
MOV AH,10
|
||||
MUL AH ;*10
|
||||
ADD BYTE PTR [BX],AL ;MOVE IN DIGIT
|
||||
RET
|
||||
|
||||
S3D:
|
||||
;; CMP AL,'"' ;BEGIN QUOTED STRING
|
||||
;; JZ S3E
|
||||
;; CMP AL,"'"
|
||||
JNZ S7
|
||||
;;S3E: MOV WORD PTR [SI],OFFSET S4
|
||||
;; MOV [INQ],AL
|
||||
S3RET: RET
|
||||
|
||||
;
|
||||
; ENTER QUOTED STRINGS
|
||||
;
|
||||
|
||||
;;S4: CMP AL,[INQ] ;CHECK FOR STRING TERMINATOR
|
||||
;; JNZ S4A
|
||||
;; DEC PRMCNT ;TERMINATE STRING
|
||||
;; MOV WORD PTR [SI],OFFSET S3
|
||||
;; RET
|
||||
|
||||
;;S4A: CALL GETPTR
|
||||
;; MOV BYTE PTR [BX],AL
|
||||
;; MOV WORD PTR [SI],OFFSET S4
|
||||
;; JMP S3A
|
||||
;
|
||||
; LOOK FOR ANSI COMMAND SPECIFIED IN AL
|
||||
;
|
||||
|
||||
S7: MOV BX,OFFSET CMDTABL-3
|
||||
;
|
||||
S7A: ADD BX,3
|
||||
CMP BYTE PTR [BX],0
|
||||
JZ S1B
|
||||
CMP BYTE PTR [BX],AL
|
||||
JNZ S7A
|
||||
;
|
||||
S7B: MOV AX,WORD PTR [BX+1] ;AX = JUMP ADDRESS
|
||||
MOV BX,OFFSET PARAM
|
||||
MOV DL,BYTE PTR [BX]
|
||||
XOR DH,DH ;DX = FIRST PARAMETER
|
||||
MOV CX,DX
|
||||
OR CX,CX
|
||||
JNZ S7C
|
||||
INC CX ; if DX=0, CX=1 else CX = DX
|
||||
S7C: JMP AX ;AL = COMMAND
|
||||
|
||||
S1: CMP AL,1Bh ;ESCAPE SEQUENCE?
|
||||
JNZ S1B
|
||||
MOV WORD PTR [SI],OFFSET S2
|
||||
RET
|
||||
|
||||
S1B: CALL CHROUT
|
||||
S1A: MOV WORD PTR [STATE],OFFSET S1
|
||||
RET
|
||||
|
||||
MOVCUR: CMP BYTE PTR [BX],AH
|
||||
JZ SETCUR
|
||||
ADD BYTE PTR [BX],AL
|
||||
LOOP MOVCUR
|
||||
SETCUR: MOV DX,WORD PTR COL
|
||||
XOR BX,BX
|
||||
MOV AH,2
|
||||
int 10h ; call ROM
|
||||
JMP S1A
|
||||
|
||||
HVP:
|
||||
CUP:
|
||||
IF LINE25
|
||||
CMP CL,(maxrow+1)
|
||||
jb cup3 ; new row is 24 or less
|
||||
JA SETCUR ; error - 26 or greater
|
||||
cmp EnaL25,0 ; else 25, is it allowed?
|
||||
jz SETCUR
|
||||
cup3:
|
||||
ELSE
|
||||
CMP CL,maxrow
|
||||
JA SETCUR
|
||||
ENDIF
|
||||
MOV AL,MAXCOL
|
||||
MOV CH,BYTE PTR [BX+1]
|
||||
OR CH,CH
|
||||
JZ CUP1
|
||||
DEC CH
|
||||
CUP1: CMP AL,CH
|
||||
JA CUP2
|
||||
MOV CH,AL
|
||||
CUP2: XCHG CL,CH
|
||||
DEC CH
|
||||
MOV WORD PTR COL,CX
|
||||
JMP SETCUR
|
||||
|
||||
CUF: MOV AH,MAXCOL
|
||||
MOV AL,1
|
||||
CUF1: MOV BX,OFFSET COL
|
||||
JMP MOVCUR
|
||||
|
||||
CUB: MOV AX,00FFH
|
||||
JMP CUF1
|
||||
|
||||
CUU: MOV AX,00FFH
|
||||
CUU1: MOV BX,OFFSET ROW
|
||||
JMP MOVCUR
|
||||
|
||||
CUD: MOV AX,(maxrow-1)*256+1
|
||||
IF LINE25
|
||||
cmp ah,[row] ; at bottom of screen?
|
||||
ja SETCUR
|
||||
ENDIF
|
||||
JMP CUU1
|
||||
|
||||
SCP: MOV AX,WORD PTR COL
|
||||
MOV SAVCR,AX
|
||||
JMP SETCUR
|
||||
|
||||
RCP: MOV AX,SAVCR
|
||||
IF LINE25
|
||||
cmp ch,maxrow
|
||||
jb rcp1
|
||||
cmp EnaL25,0
|
||||
jz rcp2
|
||||
ENDIF
|
||||
rcp1: MOV WORD PTR COL,AX
|
||||
rcp2: JMP SETCUR
|
||||
|
||||
SGR: XOR CX,CX
|
||||
XCHG CL,PRMCNT
|
||||
CALL GETPTR
|
||||
INC CX
|
||||
SGR1: MOV AL,BYTE PTR [BX]
|
||||
PUSH BX
|
||||
MOV BX,OFFSET GRMODE
|
||||
SGR2: MOV AH,BYTE PTR [BX]
|
||||
ADD BX,3
|
||||
CMP AH,0FFH
|
||||
JZ SGR3
|
||||
CMP AH,AL
|
||||
JNZ SGR2
|
||||
MOV AX,WORD PTR [BX-2]
|
||||
AND ATTR,AL
|
||||
OR ATTR,AH
|
||||
SGR3: POP BX
|
||||
INC BX
|
||||
LOOP SGR1
|
||||
JMP SETCUR
|
||||
|
||||
ED:
|
||||
IF LINE25
|
||||
cmp row,maxrow ; on 25th line?
|
||||
je EL ; yes, treat like Erase in Line
|
||||
ENDIF
|
||||
xor cx,cx
|
||||
mov dl,maxcol
|
||||
mov dh,(maxrow-1)
|
||||
cmp param,1 ; which subcommand?
|
||||
ja el2 ; all
|
||||
jb ed1
|
||||
mov dh,row ; to beginning
|
||||
dec dh
|
||||
jle EL
|
||||
jmp short ed2
|
||||
ed1: mov ch,row ; to end
|
||||
inc ch
|
||||
cmp ch,dh
|
||||
jae EL
|
||||
ed2: mov bh,attr
|
||||
MOV AX,0600H
|
||||
int 10h ; call ROM
|
||||
|
||||
EL: MOV CX,WORD PTR COL
|
||||
MOV dx,cx
|
||||
mov al,param
|
||||
inc al ; 0,1,2 => 1,2,3
|
||||
test al,1 ; to end?
|
||||
je el1
|
||||
mov dl,maxcol
|
||||
el1: test al,2 ; to beginning?
|
||||
je el2
|
||||
mov cl,0
|
||||
el2: mov bh,attr
|
||||
mov ax,0600H
|
||||
int 10h
|
||||
S1A_j: jmp S1A
|
||||
|
||||
IL: mov ah,7 ; scroll down
|
||||
jmp short dl1
|
||||
|
||||
xDL: mov ah,6 ; scroll up
|
||||
dl1: mov al,cl ; number of lines
|
||||
mov ch,row
|
||||
xor cl,cl
|
||||
mov dh,(maxrow-1)
|
||||
mov dl,maxcol
|
||||
mov bh,attr
|
||||
int 10h
|
||||
jmp S1A_j
|
||||
|
||||
RM: XOR CL,CL
|
||||
JMP SHORT SM1
|
||||
|
||||
SM: MOV CL,1
|
||||
SM1: mov bl,SelChar ; get selection character
|
||||
sub bl,'<' ; adjust
|
||||
jb S1A_j ; less than '<'
|
||||
cmp bl,4
|
||||
jae S1A_j ; greater than '?'
|
||||
xor bh,bh
|
||||
shl bx,1
|
||||
shl bx,1
|
||||
shl bx,1
|
||||
MOV AL,DL
|
||||
CMP AL,7
|
||||
JA S1A_j
|
||||
or bl,al
|
||||
shl bx,1
|
||||
mov bx,SRMODE[bx] ; get function indicator
|
||||
cmp bx,1 ; no or special function?
|
||||
jb S1A_j
|
||||
jz SM2 ; sets screen mode
|
||||
MOV [bx],CL
|
||||
JMP S1A_j
|
||||
|
||||
SM2: MOV AH,0
|
||||
int 10h ; call ROM
|
||||
JMP S1A_j
|
||||
|
||||
; GetPtr - get a pointer to the current parameter
|
||||
GETPTR: MOV BX,PRMCNTW
|
||||
CMP BX,NUMPARAM
|
||||
JB GET1
|
||||
DEC PRMCNT
|
||||
JMP GETPTR
|
||||
GET1: ADD BX,OFFSET PARAM
|
||||
RET
|
||||
@@ -0,0 +1,20 @@
|
||||
ibmbio.obj: ibmbio.asm defdbug.inc bugcode.inc
|
||||
masm ibmbio;
|
||||
|
||||
ibmmtcon.obj: ibmmtcon.asm ansi.inc defdbug.inc
|
||||
masm ibmmtcon;
|
||||
|
||||
ibmdsk.obj: ibmdsk.asm defdbug.inc
|
||||
masm ibmdsk;
|
||||
|
||||
sysini.obj: sysini.asm dossym.inc devsym.inc syscalls.inc
|
||||
masm sysini;
|
||||
|
||||
sysimes.obj: sysimes.asm
|
||||
masm sysimes;
|
||||
|
||||
ibmbio.exe: ibmbio.obj ibmmtcon.obj ibmdsk.obj sysini.obj sysimes.obj
|
||||
link ibmbio ibmmtcon ibmdsk sysini sysimes,ibmbio,ibmbio/map;
|
||||
|
||||
ibmbio.com: ibmbio.exe
|
||||
exe2bin ibmbio ibmbio.com
|
||||
Binary file not shown.
@@ -0,0 +1,553 @@
|
||||
;*** Bugcode.inc - Debug code for including into sysini.asm and ibmbio.asm
|
||||
;
|
||||
; Can't link in via buglib due to memory and relocation games played
|
||||
; by these modules. Each gets a private, local-only copy of these
|
||||
; modules.
|
||||
|
||||
|
||||
IFDEF DEBUGFLG
|
||||
|
||||
|
||||
;** DPRINTF _ Debug Printf
|
||||
;
|
||||
; Dprintf is a kernel debug print formatting package. It is intended
|
||||
; to produce conviently formatted output.
|
||||
;
|
||||
; Dprintf is called, indirectly, by a macro:
|
||||
;
|
||||
; DEBUG n,m,"string",<a1,...,an>
|
||||
;
|
||||
; string = format string
|
||||
; a1 = first argument
|
||||
; an = last argument
|
||||
;
|
||||
; The format string is an ASCIZ string which can contain 2 types of
|
||||
; specifications: data-format specifications and literal characters.
|
||||
; Data format specifications always begin with a '$' character; all
|
||||
; characters not part of a data format specification are treated as
|
||||
; literal characters.
|
||||
;
|
||||
; Literal characters
|
||||
; - any character not part of a format specification. Special
|
||||
; non-printing characters are:
|
||||
; \n - CRLF
|
||||
; \t - tab
|
||||
; \b - bell
|
||||
; \\ - \
|
||||
; \$ - $
|
||||
;
|
||||
; Format Specifications
|
||||
;
|
||||
; A format specification takes the form:
|
||||
; $ [@] <char>
|
||||
;
|
||||
; where <char> =
|
||||
;
|
||||
; x - print argument as a hex word
|
||||
; d - print argument as decimal word
|
||||
; c - print argument as ascii character
|
||||
; b - print argument as hex byte
|
||||
; For each of the above formats, the supplied argument
|
||||
; is a 16-bit word - the value to be printed. The optional @
|
||||
; (described below) allows a segmented address to be supplied,
|
||||
; instead.
|
||||
;
|
||||
; s[nn] - print argument as asciz string; if optional decimal
|
||||
; argument follows the format character this specifys
|
||||
; a maximum string length. Non printing characters are
|
||||
; printed in the form \nnn where "nnn" is the octal byte
|
||||
; value.
|
||||
; Note that this format character cannot be directly
|
||||
; followed by a digit unless that digit is to be taken
|
||||
; as the start of a length argument.
|
||||
;
|
||||
; Bnn - print argument as hex bytes. The required following
|
||||
; decimal argument is the number of bytes to print.
|
||||
;
|
||||
; Both of these formats take a long address as their argument.
|
||||
; The '@' character is thus invalid for these formats.
|
||||
;
|
||||
; WARNINGS
|
||||
; As befitting a debug routine, DPRINTF does not have a whole lot
|
||||
; of "failsafe" code in it. Supplying screwed up formats can
|
||||
; muck things up. Specifically:
|
||||
; The @ argument must NOT be specified with the 's' or 'B'
|
||||
; format
|
||||
; A string/byte-length argument of 0 is taken as 65536
|
||||
; The string "%% BAD FMT %%" appears in the output when
|
||||
; 1) an illegal format specifier is given, or
|
||||
; 2) the B format is given a 0 or missing length
|
||||
;
|
||||
; ENTRY (sp+n ) = address of format string (offset from return cs value)
|
||||
; (sp+n-2) = first argument word
|
||||
; (sp+n-4) = second argument word
|
||||
; .
|
||||
; (sp+4 ) = last argument word
|
||||
; (sp+2 ) = seg of return address
|
||||
; (sp ) = offset of return address
|
||||
; (bp) = offset of format string on the stack
|
||||
; EXIT none
|
||||
; USES flags
|
||||
|
||||
PUBLIC DPRINTF
|
||||
DPRINTF PROC near
|
||||
|
||||
push ds
|
||||
push es
|
||||
push bp
|
||||
push di
|
||||
push si
|
||||
push dx
|
||||
push cx
|
||||
push bx
|
||||
push ax ; save registers
|
||||
cld
|
||||
|
||||
mov si,[bp] ; get address of format string
|
||||
sub bp,2
|
||||
mov bx,sp
|
||||
mov ds,ss:20[bx] ; (ds:si) = address of format string
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
; Scan format string for next character
|
||||
;
|
||||
; (ds:si) = address of format string
|
||||
; (ss:bp) = address of next argument
|
||||
|
||||
dpf1: lodsb ; (al) = format string byte
|
||||
and al,al
|
||||
je dpf3 ; all done
|
||||
cmp al,'$'
|
||||
je dpf4 ; is data escape
|
||||
cmp al,'\'
|
||||
jnz dpf2 ; got the character
|
||||
|
||||
; it's an "\" escape code - crack the argument character
|
||||
|
||||
lodsb
|
||||
and al,al
|
||||
je dpf3 ; all done, ignore hanging \
|
||||
xchg ah,al
|
||||
mov al,0Ch
|
||||
cmp ah,'n'
|
||||
jne dpf1$5 ; not \n
|
||||
mov al,0dH
|
||||
call putchar
|
||||
mov al,0aH
|
||||
jmp SHORT dpf2 ; print LF
|
||||
|
||||
dpf1$5: cmp ah,'t'
|
||||
mov al,9
|
||||
je dpf2 ; is \t
|
||||
cmp ah,'b'
|
||||
mov al,7
|
||||
je dpf2 ; is \b
|
||||
xchg ah,al
|
||||
dpf2: call putchar
|
||||
jmp dpf1
|
||||
|
||||
; have the end of the format string - exit
|
||||
|
||||
dpf3: pop ax
|
||||
pop bx
|
||||
pop cx
|
||||
pop dx
|
||||
pop si
|
||||
pop di
|
||||
pop bp
|
||||
pop es
|
||||
pop ds
|
||||
ret
|
||||
|
||||
|
||||
;* Have a '$' character - is data format escape
|
||||
;
|
||||
; Get address of data into es:di
|
||||
;
|
||||
; (bp) = address of data value
|
||||
|
||||
dpf4: mov di,bp
|
||||
push ss
|
||||
pop es ; (es:di) = address of data value
|
||||
sub bp,2 ; point to next argument
|
||||
lodsb ; (al) = format specifier
|
||||
cmp al,'@'
|
||||
jne dpf5 ; not an indirect flag
|
||||
les di,[bp]
|
||||
sub bp,2 ; have an extra 2 for @
|
||||
lodsb
|
||||
dpf5: cmp al,'x'
|
||||
jne dpfd1 ; not 'x'
|
||||
|
||||
; is 'x' format - print hex word
|
||||
|
||||
mov ax,es:[di]
|
||||
call THW ; type hex word
|
||||
jmp dpf1
|
||||
|
||||
dpfd1: cmp al,'d'
|
||||
jnz dpfc1 ; not 'd'
|
||||
|
||||
; is 'd' format - print decimal word
|
||||
|
||||
mov ax,es:[di]
|
||||
call TDW ; type decimal word
|
||||
jmp dpf1
|
||||
|
||||
dpfc1: cmp al,'c'
|
||||
jne dpfb1
|
||||
|
||||
; is 'c' format - print character
|
||||
|
||||
mov al,es:[di]
|
||||
call putchar
|
||||
jmp dpf1
|
||||
|
||||
dpfb1: cmp al,'b'
|
||||
jne dpfs1
|
||||
|
||||
; is 'b' format - print hex byte
|
||||
|
||||
mov al,es:[di]
|
||||
call THB ; type hex byte
|
||||
jmp dpf1
|
||||
|
||||
dpfs1: cmp al,'s'
|
||||
jne dpfbb1
|
||||
|
||||
; is 's' format - print ASCIZ string. First, check for
|
||||
; optional decimal limit
|
||||
|
||||
public SSB
|
||||
SSB: sub cx,cx ; set 65536 limit
|
||||
les di,[bp] ; (es:DI) = fwa of string
|
||||
sub bp,2 ; argument to 's' was two words
|
||||
mov al,[si]
|
||||
cmp al,'0'
|
||||
jb dpfs2 ; not decimal
|
||||
cmp al,'9'
|
||||
ja dpfs2 ; not decimal
|
||||
call atod ; (ax) = decimal value, (ds:si) updated
|
||||
xchg cx,ax
|
||||
|
||||
; print asciz string at es:di, max of (cx) characters
|
||||
; (cx) = 0 means max of 65536
|
||||
;
|
||||
; Other sections of code in dpf jump here to print strings
|
||||
|
||||
dpfs2: mov al,es:[di]
|
||||
inc di
|
||||
and al,al
|
||||
je dpfs3
|
||||
call putchar
|
||||
loop dpfs2 ; continue if not at limit
|
||||
dpfs3: jmp dpf1
|
||||
|
||||
dpfbb1: cmp al,'B'
|
||||
je dpfbb2 ; is 'B' format
|
||||
|
||||
; error in format code - print message
|
||||
|
||||
dpferr: push cs
|
||||
pop es
|
||||
mov di,OFFSET dpfa ; (es:di) = error message
|
||||
sub cx,cx
|
||||
jmp dpfs2
|
||||
|
||||
dpfa: DB '%% BAD FMT %%',0
|
||||
|
||||
; have B format
|
||||
|
||||
dpfbb2: call atod ; (ax) = length specifier
|
||||
jc dpferr ; number not there - error
|
||||
xchg cx,ax
|
||||
jcxz dpferr ; number is 0 - error
|
||||
les di,[bp] ; (es:DI) = fwa of string
|
||||
sub bp,2 ; argument to 's' was two words
|
||||
dpfbb3: mov al,es:[di]
|
||||
call THB ; type hex byte
|
||||
mov al,' '
|
||||
call putchar ; space em out
|
||||
inc di
|
||||
loop dpfbb3 ; do em all
|
||||
jmp dpf1
|
||||
|
||||
DPRINTF ENDP
|
||||
|
||||
|
||||
;** THB - Type Hex Byte
|
||||
;
|
||||
; THB types a hex byte (via "putchar")
|
||||
;
|
||||
; ENTRY (AL) = byte
|
||||
; EXIT none
|
||||
; USES ax, flags
|
||||
|
||||
THBA DB '0123456789abcdef'
|
||||
|
||||
PUBLIC THB
|
||||
THB PROC near
|
||||
|
||||
push ax
|
||||
shr al,1
|
||||
shr al,1
|
||||
shr al,1
|
||||
shr al,1
|
||||
and ax,0fH
|
||||
xchg bx,ax
|
||||
mov bl,CS:THBA[bx]
|
||||
xchg ax,bx
|
||||
call putchar ; put first character
|
||||
pop ax
|
||||
and ax,0fH
|
||||
xchg bx,ax
|
||||
mov bl,CS:THBA[bx]
|
||||
xchg ax,bx
|
||||
call putchar
|
||||
ret
|
||||
|
||||
THB ENDP
|
||||
|
||||
|
||||
|
||||
|
||||
;** THW - Type Hex Word
|
||||
;
|
||||
; THW types a word in hex (via "putchar")
|
||||
;
|
||||
; ENTRY (AX) = word
|
||||
; EXIT none
|
||||
; USES AX, flags
|
||||
|
||||
PUBLIC THW
|
||||
THW PROC near
|
||||
|
||||
push ax
|
||||
xchg ah,al
|
||||
call THB
|
||||
pop ax
|
||||
call THB
|
||||
ret
|
||||
|
||||
THW ENDP
|
||||
|
||||
|
||||
|
||||
;** TDW - Type Decimal Word
|
||||
;
|
||||
; TDW types (via "putchar") the unsigned decimal representation
|
||||
; of a 16-bit unsigned integer. Only significant digits are
|
||||
; printed; if the number is 0 a "0" is printed.
|
||||
;
|
||||
; ENTRY (AX) = number
|
||||
; EXIT none
|
||||
; USES AX, flags
|
||||
|
||||
PUBLIC TDW
|
||||
TDW PROC near
|
||||
|
||||
push cx ; preserve registers
|
||||
push dx
|
||||
mov cx,10
|
||||
call tdw$ ; recurse cracking digits
|
||||
pop dx
|
||||
pop cx
|
||||
ret
|
||||
|
||||
TDW ENDP
|
||||
|
||||
|
||||
;* tdw$ - crack number recursively
|
||||
;
|
||||
; tdw$ cracks the least significant decimal digit. If there
|
||||
; are no higher-significant digits, print and return.
|
||||
; else, recurse for higher digits
|
||||
;
|
||||
; (AX) = value
|
||||
; (CX) = 10
|
||||
|
||||
tdw$ PROC NEAR
|
||||
|
||||
sub dx,dx
|
||||
div cx ; (ax) = quotient, (dx) = remainder
|
||||
and ax,ax
|
||||
jz tdw$1 ; this is highest-order, do it
|
||||
push dx
|
||||
call tdw$
|
||||
pop dx
|
||||
tdw$1: xchg ax,dx
|
||||
add al,'0'
|
||||
call putchar
|
||||
ret
|
||||
|
||||
TDW$ ENDP
|
||||
|
||||
|
||||
|
||||
;** ATOD - Convert ASCII string to decimal number
|
||||
;
|
||||
; ATOD is called to convert an ascii string of digits to a
|
||||
; decimal number. Digits are converted until we run out of them.
|
||||
;
|
||||
; ENTRY (DS:SI) = address of first digit
|
||||
; EXIT 'C' clear if OK
|
||||
; (AX) = value
|
||||
; (SI) updated to first non-digit
|
||||
; 'C' set if error - no digits, or result >65535
|
||||
; (DS:SI) points to error character
|
||||
; USES AX, SI, FLAGS
|
||||
|
||||
PUBLIC ATOD
|
||||
ATOD PROC near
|
||||
|
||||
push dx
|
||||
push cx ; save registers
|
||||
mov al,[si]
|
||||
sub al,'0'
|
||||
jc atod9 ; error - no digits
|
||||
cmp al,10
|
||||
cmc
|
||||
jc atod9 ; error - no digits
|
||||
sub ax,ax ; clear accumulator
|
||||
mov cx,10 ; base 10
|
||||
|
||||
; crack next digit
|
||||
;
|
||||
; (AX) = number accumulated so near
|
||||
; (CX) = 10
|
||||
; (DS:SI) = next character
|
||||
|
||||
atod1: xchg dx,ax ; keep accum in dx for a while
|
||||
lodsb ; (al) = character
|
||||
sub al,'0'
|
||||
jc atod7 ; not digit - all done
|
||||
cmp al,9
|
||||
ja atod7 ; not digit - all done
|
||||
sub ah,ah ; (ax) = digit value (0 - 9)
|
||||
push ax
|
||||
xchg ax,dx
|
||||
mul cx ; (ax) = 10*accum
|
||||
pop dx ; (dx) = digit to add
|
||||
jo atod8 ; overflow
|
||||
add ax,dx
|
||||
jmp atod1 ; go back for more
|
||||
|
||||
; Done with number, all OK
|
||||
;
|
||||
; (dx) = number
|
||||
; (ds:si) = address+1 of first unused character
|
||||
|
||||
atod7: clc
|
||||
|
||||
; Done with number, error
|
||||
; 'C' set
|
||||
|
||||
atod8: dec si ; backup over non-decimal (or error) char
|
||||
atod9: pop cx
|
||||
xchg ax,dx ; (ax) = number iff no error
|
||||
pop dx ; restore registers
|
||||
ret ; exit
|
||||
|
||||
ATOD ENDP
|
||||
|
||||
;** putchar - put a character on the console
|
||||
;
|
||||
; ENTRY (al) = character
|
||||
; EXIT none
|
||||
; USES ax,flags
|
||||
|
||||
|
||||
UR_DAT = 02f8H ; COM1 = 03f8H, COM2 = 02f8H
|
||||
UR_IEN = UR_DAT+1 ; Interrupt enable
|
||||
UR_IER = UR_DAT+2 ; interrupt ID
|
||||
UR_LCR = UR_DAT+3 ; line control registers
|
||||
UR_MCR = UR_DAT+4 ; modem control register
|
||||
UR_LSR = UR_DAT+5 ; line status register
|
||||
UR_MSR = UR_DAT+6 ; modem status regiser
|
||||
UR_DLL = UR_DAT ; divisor latch least sig
|
||||
UR_DLM = UR_DAT+1 ; divisor latch most sig
|
||||
|
||||
iflag DB 0 ; != 0 when initialized 8250
|
||||
|
||||
;* inchr - input character
|
||||
;
|
||||
; EXIT 'z' set if no character
|
||||
; 'z' clear if char
|
||||
; (al) = char
|
||||
|
||||
inchr: mov dx,UR_LSR
|
||||
in al,dx
|
||||
and al,1
|
||||
jz inchr1
|
||||
mov dx,UR_DAT
|
||||
in al,dx
|
||||
and al,07fh
|
||||
inchr1: ret
|
||||
|
||||
|
||||
PUBLIC putchar
|
||||
putchar PROC NEAR
|
||||
pushf
|
||||
cli
|
||||
push dx
|
||||
push cx
|
||||
push bx
|
||||
push ax ; (al) = character
|
||||
test iflag,255
|
||||
jnz putc1 ; is initialized
|
||||
inc iflag
|
||||
|
||||
; program the usart
|
||||
|
||||
mov dx,UR_LCR
|
||||
mov al,80h
|
||||
out dx,al ; command it
|
||||
sub al,al
|
||||
mov dx,UR_DLM
|
||||
out dx,al
|
||||
mov dx,UR_DLL
|
||||
mov al,12 ; 9600 baud = 12, 19.2 Kbaud = 6
|
||||
out dx,al
|
||||
mov al,3
|
||||
mov dx,UR_LCR
|
||||
out dx,al ; command normal mode
|
||||
|
||||
; see if CTL-Q or CTL-S
|
||||
|
||||
putc1: pushf
|
||||
cli
|
||||
call inchr
|
||||
jz putc3 ; no characters incomming
|
||||
cmp al,19 ; ctl-S?
|
||||
jnz putc3 ; no, ignore
|
||||
|
||||
; have ctl-s. wait till we see ctl-Q
|
||||
|
||||
putc2: call inchr
|
||||
jz putc2
|
||||
cmp al,17
|
||||
jnz putc2
|
||||
|
||||
putc3: popf
|
||||
mov dx,UR_LSR
|
||||
putc4: in al,dx
|
||||
test al,020h
|
||||
jz putc4
|
||||
|
||||
; ready. crank it out!
|
||||
|
||||
mov dx,UR_DAT
|
||||
|
||||
pop ax
|
||||
out dx,al
|
||||
|
||||
pop bx
|
||||
pop cx
|
||||
pop dx
|
||||
popf
|
||||
ret
|
||||
|
||||
putchar ENDP
|
||||
|
||||
ENDIF
|
||||
@@ -0,0 +1,122 @@
|
||||
;** DEFDBUG.ASM - Debugging Macro Definitions
|
||||
;
|
||||
;
|
||||
; DEBUG n,m,<format string>, <arg list>
|
||||
;
|
||||
;
|
||||
|
||||
.sall
|
||||
|
||||
DEBUG MACRO N,M,string,args
|
||||
local b,c
|
||||
IFDEF DEBUGFLG
|
||||
pushf
|
||||
DEBUGTST N,M
|
||||
jz b
|
||||
push ax
|
||||
push bp
|
||||
call c ;; push address of string
|
||||
DB '&string',0
|
||||
c: mov bp,sp
|
||||
; IFNB <args>
|
||||
IRP Y,<args>
|
||||
IFIDN <Y>,<ax>
|
||||
push 4[bp]
|
||||
ELSE
|
||||
IFIDN <Y>,<AX>
|
||||
push 4[bp]
|
||||
ELSE
|
||||
IFIDN <Y>,<bp>
|
||||
push 2[bp]
|
||||
ELSE
|
||||
IFIDN <Y>,<BP>
|
||||
push 2[bp]
|
||||
ELSE
|
||||
mov ax,Y
|
||||
push ax
|
||||
ENDIF
|
||||
ENDIF
|
||||
ENDIF
|
||||
ENDIF
|
||||
ENDM
|
||||
; ENDIF
|
||||
call DPRINTF
|
||||
mov sp,bp
|
||||
pop ax ;; discard format string offset
|
||||
pop bp
|
||||
pop ax
|
||||
b: popf
|
||||
ENDIF
|
||||
ENDM
|
||||
|
||||
|
||||
|
||||
|
||||
;** ERRNZ - generate assembly error if arg != 0
|
||||
;
|
||||
|
||||
ERRNZ MACRO EXPR
|
||||
IF1
|
||||
IFE expr
|
||||
ELSE
|
||||
RADIX 0 ; CONDITION NOT MET - ERROR
|
||||
ENDIF
|
||||
ENDIF
|
||||
ENDM
|
||||
|
||||
|
||||
;** DBBEG - Start debugging range
|
||||
;
|
||||
|
||||
DBBEG MACRO N,M
|
||||
LOCAL lab
|
||||
IFDEF DEBUGFLG
|
||||
pushf
|
||||
DEBUGTST N,M
|
||||
jnz lab ;; am to do it
|
||||
DBJMP %DBCNT
|
||||
lab:
|
||||
ENDM
|
||||
|
||||
|
||||
|
||||
DBJMP MACRO N
|
||||
jmp DBLAB&N
|
||||
ENDM
|
||||
|
||||
|
||||
;** DEBUGTST - Test Debug Flags
|
||||
;
|
||||
; DEBUGTST n,m
|
||||
;
|
||||
; Where N and M are bit masks.
|
||||
;
|
||||
; If one or more of the bits in N is set in the high byte
|
||||
; of BUGBITS, and one or more of the bits in M is set in
|
||||
; the low byte of BUGBITS then clear the Z flag.
|
||||
;
|
||||
; In other words:
|
||||
;
|
||||
; If both masks show a "hit" clear 'Z' else set 'Z'
|
||||
;
|
||||
; USES FLAGS
|
||||
|
||||
DEBUGTST MACRO N,M
|
||||
LOCAL A
|
||||
test BYTE PTR BUGBITS,n
|
||||
jz A
|
||||
test BYTE PTR BUGBITS+1,m
|
||||
A:
|
||||
ENDM
|
||||
|
||||
DBEND MACRO
|
||||
DBLAB %DBCNT
|
||||
DBCNT = DBCNT+1
|
||||
popf
|
||||
ENDM
|
||||
|
||||
DBLAB MACRO N
|
||||
DBLAB&N:
|
||||
ENDM
|
||||
|
||||
DBCNT = 1
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -0,0 +1,25 @@
|
||||
29 May 1984
|
||||
|
||||
The object files given here are sufficient to create the BIOS
|
||||
for the IBM system. Some sources are given as examples for
|
||||
OEM supplied device drivers. These sources do not necessarily
|
||||
implement all the features described in the device driver
|
||||
documentation. They have evolved in parallel with the
|
||||
documentation, so some features described in the documentation
|
||||
may not yet be present in the drivers. Below is a summary of
|
||||
the files supplied:
|
||||
|
||||
read_me This file.
|
||||
ibmbio.asm Main body of the BIOS.
|
||||
ibmdsk.asm Floppy and Hard disk drivers.
|
||||
ibmmtcon.asm Multi-screen console driver.
|
||||
ansi.inc ANSI X3.64 terminal emulation.
|
||||
bugcode.inc Module which implements debugging
|
||||
prints. The routine PUTC must be
|
||||
modified for other devices. See
|
||||
also the file DEFDBUG.INC.
|
||||
sys*.obj The SYSINIT program. No source supplied.
|
||||
biosobj.mak Contains instructions for building the
|
||||
IBM BIOS.
|
||||
bootpach.exe Modifies a V2.0 boot sector (on A:) for
|
||||
the IBM to accomodate the larger BIOS.
|
||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user