ok I've changed the comments buy I'm affraid it's not reall clear to put it as an example. This version is stable
PORT1 = 3f8h
THR = 0 ;Transmitter Holding Reg
RBR = 0 ;Reciver Buffer Reg
IER = 1 ;Interrupt Enable Reg
IIR = 2 ;Interrupt Identyfication Reg
LCR = 3 ;Line Control Reg
MCR = 4 ;Modem Control Reg
LSR = 5 ;Line Status Reg
MSR = 6 ;Modem Status Reg
INT_ON_RxD = 0x01
INT_ON_TxD = 0x02
INT_ON_LINE_STATUS = 0x04
INT_ON_MODEM_STATUS = 0x08
DATA_LEN_5 = 0x00
DATA_LEN_6 = 0x01
DATA_LEN_7 = 0x02
DATA_LEN_8 = 0x03
STOP_BIT_1 = 0x00
STOP_BIT_2 = 0x04
PARITY_NO = 0x00
PARITY_ODD = 0x08
PARITY_EVEN = 0x18
PARITY_HIGH = 0x28
PARITY_LOW = 0x38
BR_115200 = 0x01
BR_57600 = 0x02
BR_38400 = 0x03
BR_19200 = 0x06
BR_9600 = 0x0C
BR_4800 = 0x18
BR_2400 = 0x30
SCR_SIZE = 8000
LN_LEN = 160
org 100h
;-------------------------------------------------------------------------
macro cinvoke proc,[arg] ; indirectly call CDECL procedure
;-------------------------------------------------------------------------
{
common
size@ccall = 0
reverse
push arg
size@ccall = size@ccall+2
common
call proc
add sp,size@ccall
}
;-------------------------------------------------------------------------
macro outb port_nr,data
;-------------------------------------------------------------------------
{
mov dx , port_nr
mov al , data
out dx , al
}
;-------------------------------------------------------------------------
macro in_b port_nr
;-------------------------------------------------------------------------
{
mov dx , port_nr
in al , dx
}
;-------------------------------------------------------------------------
Start:
;-------------------------------------------------------------------------
call set80x50
call SetPalette
call ClrScr
call cursor_off
cinvoke _getvect,12
mov word [old_vect],dx
mov word [old_vect+2],ax
cinvoke _setvect,12,com_int,ds
mov bl,BR_115200
call com_setup
call ComMoni
call cursor_on
cinvoke _setvect,12,word [old_vect+2],word [old_vect]
ret
;-------------------------------------------------------------------------
com_int:
;-------------------------------------------------------------------------
pusha
push ds
push cs
pop ds
in_b PORT1 + LSR
test al,1
je @f
mov cl,al
and cl,0x0f
in_b PORT1
mov ebx,[io_end]
mov [io_buf+ebx],al
in_b PORT1 + MSR
shl al,2
push ax
and al,0xc0
pop dx
shl dl,2
and dl,0x30
or al,dl
or cl,al
mov [io_buf+ebx+1],cl
add byte[io_end],2
inc [icnt]
@@:
outb 0x20 , 0x20
pop ds
popa
iret
;-------------------------------------------------------------------------
_getvect:
;-------------------------------------------------------------------------
push bp
mov bp,sp
push es
mov ah, 035h
mov al, [bp+4]
int 021h
xchg ax,bx
mov dx,es
pop es
pop bp
ret
;-------------------------------------------------------------------------
_setvect:
;-------------------------------------------------------------------------
push bp
mov bp,sp
mov ah, 025h
mov al, [bp+4]
push ds
lds dx, [bp+6]
int 021h
pop ds
pop bp
ret
;-------------------------------------------------------------------------
com_setup: ;in bl - baudrate
;-------------------------------------------------------------------------
outb PORT1 + LCR , 0x80 ;SET DLAB ON
outb PORT1 + RBR , bl ;Set Baud rate - Divisor Latch Low Byte
outb PORT1 + IER,0x00 ;Set Baud rate - Divisor Latch High Byte
outb PORT1 + LCR , DATA_LEN_8 or STOP_BIT_1 or PARITY_NO
outb PORT1 + IIR , 0xC7 ;FIFO Control Register
outb PORT1 + MCR , 0x0B ;Turn on DTR, RTS, and OUT2
outb PORT1 + IER , 1
in_b 0x21
and al , 0x0ef
;COM1,3 (IRQ4) - 0xEF
;COM2,4 (IRQ3) - 0xF7
out 21h, al ;Set Programmable Interrupt Controller
in_b PORT1+MSR
in_b PORT1
ret
;-------------------------------------------------------------------------
kbhit:
;-------------------------------------------------------------------------
mov ah, 0Bh
int 21h
cbw
ret
;-------------------------------------------------------------------------
cs_conv:
;-------------------------------------------------------------------------
push edi
@@:
lodsw
cmp al , 'z'
jg parse
cmp al , ' '
jl parse
no_parse:
stosw
jmp pend
parse:
push eax
push eax
mov al,'['
stosw
pop eax
and al,0xf0
shr al,4
call hextoc
stosw
pop eax
and al,0x0f
call hextoc
stosw
mov al,']'
stosw
pend:
dec cx
jne @b
pop ecx
mov eax,edi
sub eax,ecx
ret
;-------------------------------------------------------------------------
hextoc:
;-------------------------------------------------------------------------
add al,'0'
cmp al,'9'
jle @f
add al,39
@@: ret
;-------------------------------------------------------------------------
move32:
;-------------------------------------------------------------------------
shr ecx,1
jnc @f
movsb
@@: shr ecx,1
jnc @f
movsw
@@: rep movsd
ret
;-------------------------------------------------------------------------
fill32:
;-------------------------------------------------------------------------
shr ecx,1
jnc @f
stosb
@@: shr ecx,1
jnc @f
stosw
@@: rep stosd
ret
;------------------------------------------------------------------------
cursor_on:
;------------------------------------------------------------------------
outb 0x3d4,0x0a
outb 0x3d5,0x0d
outb 0x3d4,0x0b
outb 0x3d5,0x0d
ret
;------------------------------------------------------------------------
cursor_off:
;------------------------------------------------------------------------
outb 0x3d4,0x0a
outb 0x3d5,0x01
outb 0x3d4,0x0b
outb 0x3d5,0x00
ret
;------------------------------------------------------------------------
set80x50:
;------------------------------------------------------------------------
mov ax,0003h
int 10h
mov ax,1112h
xor bl,bl
int 10h
ret
;------------------------------------------------------------------------
setvga:
;------------------------------------------------------------------------
mov dx,03dah
in al,dx
mov dx,03c0h
mov al,10h ;read mode control register
out dx,al
mov dx,03c1h
in al,dx
and al,0f7h ;erase bits for 16 backgroung colors,
mov ah,al ;instead of 8 and blinking
mov dx,03dah
in al,dx
mov dx,03c0h
mov al,10h
out dx,al
mov al,ah ;write new value to mode control register
out dx,al
mov al,30h
out dx,al
ret
;-------------------------------------------------------------------------
SetPalette:
;-------------------------------------------------------------------------
call setvga
mov si, Pal
mov cx,16
SPal:
mov dx,0x03c8
outsb
inc dx
outsb
outsb
outsb
loop SPal
ret
;-------------------------------------------------------------------------
ClrDisp: ;in edi - dst, eax - pattern, ecx - counter
;-------------------------------------------------------------------------
push es
push 0xb800
pop es
call fill32
pop es
ret
;-------------------------------------------------------------------------
ClrScr:
;-------------------------------------------------------------------------
pusha
mov edi,0
mov ecx,SCR_SIZE
mov eax,0xf120f120
call ClrDisp
popa
ret
;-------------------------------------------------------------------------
ClrLastLine:
;-------------------------------------------------------------------------
pusha
mov edi,SCR_SIZE-160
mov ecx,160
mov eax,0x01200120
call ClrDisp
popa
ret
;-------------------------------------------------------------------------
DispData: ;in esi - scr, edi - dst, ecx - counter
;-------------------------------------------------------------------------
push es
push 0xb800
pop es
call move32
pop es
ret
;-------------------------------------------------------------------------
ComMoni:
;-------------------------------------------------------------------------
mov ecx , [io_end]
sub ecx , [io_beg] ; io_dif = io_end - io_beg;
jz no_data ; if(!io_dif) goto no_data;
jnl @f ; if(io_dif<0)
add ecx , 256 ; io_dif += io_size
@@:
shr ecx , 1 ; io_dif /= 2;
mov esi , io_buf
add esi , [io_beg]
mov edi , [wk_end]
call cs_conv ; parsed = cs_conv(wk_end,io_beg,io_dif);
mov [parsed] , eax
add [wk_end] , eax ; wk_end += parsed;
add byte[io_beg],2 ; io_beg += 2;
mov ecx , [wk_end]
sub ecx , [wk_beg] ; dif_wk = wk_end - wk_beg
cmp ecx , SCR_SIZE ; if(dif_wk > sc_size)
jg sc_scroll ; goto sc_scroll
mov ecx , [wk_end]
sub ecx , [parsed]
mov esi , ecx ; src = wk_end - parsed
mov edi , [sc_end] ; dst = sc_end
mov ecx , [parsed] ; cnt = parsed
jmp sc_update
sc_scroll:
call ClrLastLine ; ClrLastLine();
add [wk_beg] , LN_LEN ; wk_bed += LN_LEN
sub ecx , LN_LEN ; wk_dif -= LN_LEN
mov [sc_end] , 0 ; sc_end = 0
mov esi,[wk_beg] ; src = wk_beg
mov edi,[sc_beg] ; dst = sc_beg
sc_update: ; cnt = wk_dif
push ecx
call DispData
pop ecx
add [sc_end] , ecx
no_data:
call kbhit
or ax,ax
je ComMoni
ret
Pal:
db 000h,01ah,022h,018h ; 0 dark green
db 001h,026h,02eh,020h ; 1 grass
db 002h,032h,038h,02eh ; 2 light green
db 003h,038h,038h,026h ; 3 yellow
db 004h,03ah,034h,024h ; 4 orange
db 005h,032h,028h,01eh ; 5 kakao
db 014h,02eh,02ch,024h ; 6 gray brown
db 03ch,02eh,02ah,01ch ; c light brown
db 038h,016h,00ah,000h ; 8 dark brown
db 039h,026h,01eh,028h ; 9 dark violet
db 03ah,02ch,028h,02eh ; a light violet
db 03bh,01eh,032h,02ch ; b light navy
db 007h,016h,02eh,02ch ; 7 dark navy
db 03dh,016h,024h,02eh ; d blue
db 03eh,02ah,02ah,02ah ; e gray
db 03fh,000h,000h,000h ; f black
old_vect dd ?
icnt dw ?
parsed dd 0
io_end dd 0
io_beg dd 0
wk_end dd wk_buf
wk_beg dd wk_buf
sc_end dd 0
sc_beg dd 0
align 16
io_buf rb 256
wk_buf db ?