📄 monoio.asm
字号:
page 78,132
title Monochrome Display I/O driver for Monitor
LineLen = 132
nCols = 80
nRows = 25
MonoBase = 0
.model small
.code
.data
InitSeg segment byte public
InitSeg ends
public LineBuf
LineBuf db LineLen dup(0)
MonoPtr dd 0B0000000H
DGroup group _TEXT,_DATA,InitSeg
.code
public InBuf, OutCh, InCh, CrLf
extrn Backup:near, Command:near
;Get input line
assume cs:DGroup,ds:DGroup
INBUF:
MOV DI,offset DGroup:LINEBUF ;Next empty buffer location
XOR CX,CX ;Character count
GETCH:
CALL InCh ;Get input character
CMP AL,20H ;Check for control characters
JC CONTROL
CMP AL,7FH ;RUBOUT is a backspace
JZ BACKSP
CALL OutCh ;Echo character
STOSB ;Put in input buffer
INC CX ;Bump character count
CMP CX,LineLen ;Buffer full?
JBE GETCH ;Drop in to backspace if full
BACKSP:
JCXZ GETCH ;Can't backspace over nothing
DEC DI ;Drop pointer
DEC CX ;and character count
CALL BACKUP ;Send physical backspace
jmp GETCH ;Get next char.
CONTROL:
CMP AL,3 ;Ctrl-C?
JZ KILL
cmp al,1BH ;ESC?
jz Kill
CMP AL,8 ;Check for backspace
JZ BACKSP
CMP AL,13 ;Check for carriage return
JNZ GETCH ;Ignore all other control char.
STOSB ;Put the car. ret. in buffer
;Convert unquoted input to upper case
MOV SI,offset DGroup:LINEBUF
mov di,si
CaseChk:
lodsb
cmp al,"a"
jb NoConv
cmp al,"z"
ja NoConv
sub al,"a"-"A" ;Convert to upper case
NoConv:
stosb ;Put it back where we got it
cmp al,13 ;End of line?
jz InDone
cmp al,'"'
jz QuotScan
cmp al,"'"
jnz CaseChk
QuotScan:
mov ah,al ;Remember which quote mark
KillStr:
lodsb
stosb
cmp al,13
jz InDone
cmp al,ah
jnz KillStr
jmp CaseChk
InDone:
mov si,offset DGroup:LINEBUF ;Set up SI for command processing
;Output CR/LF sequence
CRLF:
MOV AL,13
CALL OutCh
MOV AL,10
jmp short OutCh
;Cancel input line
KILL:
CALL CRLF
CommandJ:
JMP COMMAND
;Character input routine
InCh:
MOV AH,0
INT 22 ;Call ROM BIOS for a character
RET
;Console output of character in AL
assume ds:nothing,es:nothing,ss:nothing
DELAY macro
jmp short $+2
endm
OutCh:
push ax
push dx
push es
push di
and al,7FH
les di,[MonoPtr]
cmp al,13
jz MonoCr
cmp al,10
jz MonoLf
cmp al,9
jz MonoTab
cmp al,8
jz MonoBs
cmp al,7
jz MonoBell
mov ah,7
stosw
ScrollTest:
cmp di,MonoBase+(nRows*nCols*2)
jb SavePtr
;Scroll screen
sub di,nCols*2
push ds
push si
push cx
push di
push es
pop ds
mov si,MonoBase+(nCols*2)
mov di,MonoBase
mov cx,(nRows-1)*nCols
rep movsw
mov cx,nCols
mov ax,7*100H + " " ;Fill with low-intensity blank
rep stosw
pop di
pop cx
pop si
pop ds
SavePtr:
mov word ptr [MonoPtr],di
;Set cursor register
mov dx,3B4H ;6845 index register I/O port
mov al,15 ;Cursor addr., low
out dx,al
xchg ax,di ;Address to ax
shr ax,1 ;6845 thinks it's 1 byte/char
inc dx ;Pick data register
DELAY
out dx,al
mov al,14 ;Cursor addr., high
dec dx
out dx,al
mov al,ah
inc dx
DELAY
out dx,al
pop di
pop es
pop dx
pop ax
ret
MonoCr:
;Compute start of this line
mov ax,di
xor dx,dx ;Extend to 32 bits
mov di,nCols*2
div di ;Compute row number
mul di ;Offset of start of row
mov di,ax
jmp SavePtr
MonoLf:
add di,nCols*2
jmp ScrollTest
MonoTab:
mov ax,di
xor dx,dx ;Extend to 32 bits
mov di,8*2 ;Tabs every 8
div di ;Compute tab position
;Remainder in dx tells us how far into the tab stop we are
sub di,dx ;Amount to move forward to next tab
add di,word ptr [MonoPtr]
jmp SavePtr
MonoBs:
dec di
dec di
jmp SavePtr
MonoBell:
jmp SavePtr
;************************************************************
InitSeg segment
assume cs:DGroup,ds:DGroup
;Clear screen
les di,[MonoPtr]
mov ax," "+7*100H ;Fill with low-intensity blanks
mov cx,80*25
rep stosw ;Clear screen
xor di,di
InitSeg ends
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -