Category : C Source Code
Archive   : ICURSES.ZIP
Filename : SCRNIO_A.ASM
TITLE SCRNIO_A -- Assembly direct-video driver for icurses
% .MODEL memmodel,C
INCLUDE MIXED.INC
COMMENT +
/* scrnio_a.asm -- */
/******************************************************************/
/* SCREEN PHYSICAL INTERFACE CALLS -- IMPLEMENTED FOR DIRECT VIDEO
currently set for MSC 5.1 compiler -- also works for TurboC
CALLS:
scrinit(snow) screen initialization, snow check (ignored for BIOS)
scurs(l, c) set cursor to line l, column c
gcurs(*l, *c) get cursor position
wchat(c, at) write character 'c' with attribute 'at'
rchar() return character (low byte) and
attribute (high byte)
wscrlup(n, at, sty, stx, eny, enx) Scroll part of screen
'n' lines, using attribute 'at', upper
left-hand corner (sty, stx), lower right-hand
corner (eny, enx).
cursoff() turn off cursor
curson() turn on cursor
*/
/*****************************************************************/
+
.CODE
;#include
;#include
;unsigned scrseg; /* segment to use for video adapt (not used) */
scrseg dw 0
;int mono_only; /* monochrome card being used */
mono_only dw 0
;int csnow; /* control snow flag (not used in BIOS version) */
csnow dw 0
;int scrncol; /* number of columns on screen */
scrncol dw 0
;int scrinited = 0; /* screen initialized flag */
scrinited dw 0
;void scrinit(int snow)
scrinit PROC snow:WORD
; {
; union REGS r;
;
; if (!scrinited)
cmp cs:scrinited,0 ;check whether already inited
jnz snow_control ;already done, do snow control
; {
; scrinited = 1;
mov cs:scrinited,1 ;set it as inited
; r.h.ah = 0x0f; /* want to get video mode */
; int86(0x10, &r, &r);
mov ax,0f00H;
int 010H
; scrncol = r.h.ah;
mov cl,ah
xor ch,ch
mov cs:scrncol,cx
; if (r.h.al == 0x07)
cmp al,07h ;is it mono?
jne not_mono
; {
; scrseg = 0xb000; /* segment for mono card */
mov cs:scrseg,0B000H ;segment
; mono_only = 1;
mov cs:mono_only,1 ;flag
; csnow = 0; /* never snow control for mono */
mov cs:csnow,0 ;flag
; }
jmp short endif0
; else
not_mono:
; {
; mono_only = 0;
mov cs:mono_only,0
; scrseg = 0xb800; /* segment for color card */
mov cs:scrseg,0B800H
; scrinit(snow); /* go set snow flag */
push snow
call scrinit
add sp,2
; }
endif0:
jmp endif2
; }
; else
snow_control:
; {
; r.x.ax = 0x1200; /* check for an ega */
mov ax,01200H
; r.x.bx = 0x0010;
mov bx,0010H
; r.x.cx = 0xffff;
mov cx,0ffffH
; int86(0x10, &r, &r);
int 10H
; if (r.x.cx != 0xffff)
inc cx
jz else1
; csnow = snow; /* if color, non-ega card, copy flag */
mov ax,snow
mov cs:csnow,ax
jmp short endif1
; else
else1:
; csnow = 0;
mov cs:csnow,0
endif1:
; }
endif2:
; }
ret
scrinit ENDP
; }
;/* set cursor position */
;void scurs(int line, int col) /* zero based */
; {
; union REGS ir, or;
;
; ir.h.dh = (char) line;
; ir.h.dl = (char) col;
; ir.h.bh = 0;
; ir.h.ah = 2;
; int86(0x10, &ir, &or);
; }
scurs PROC line:WORD, col:WORD
mov dh, BYTE PTR (line)
mov dl,BYTE PTR (col)
xor bh,bh
mov ah,2
int 10H
ret
scurs ENDP
;/* get cursor position */
;void gcurs(int *line, int *col) /* zero based */
; {
; union REGS ir, or;
;
; ir.h.bh = 0;
; ir.h.ah = 0x3; /* Read cursor position */
; int86(0x10, &ir, &or);
; *line = or.h.dh;
; *col = or.h.dl;
; }
gcurs PROC USES ES, line:PTR WORD, col:PTR WORD
xor bh,bh
mov ah,3
int 10h
xor ah,ah
mov al,dh ;gline
pLes bx,line ;get pointer to line
mov FP[bx],ax ; *line = gline
mov al,dl ;gcol
pLes bx,col ;get pointer to col
mov FP[bx],ax ; *col = gcol
ret
gcurs ENDP
;/* write character & attribute */
;void wchat(char c, char at, int line, int col)
; {
; int p;
; static unsigned int chat;
; static void far *pchat = &chat;
;
; p = (line * 80 + col) * 2;
; chat = (unsigned char) c + 256 * (unsigned char) at;
;/* pchat = &chat; */
; movedata(FP_SEG(pchat), FP_OFF(pchat), scrseg, p, 2);
; }
wchat PROC USES ES, c:WORD, at:WORD, line:WORD, col:WORD
mov ax,cs:scrseg ;set screen's seg. reg.
mov es,ax
mov ax,cs:scrncol ;80 cols per line, hopefully
mul line ;ax = lines * scrncol
add ax,col ;ax = (lines*scrncol) + cols
mov bx,ax
shl bx,1
mov al,byte ptr (c) ;character
mov ah,byte ptr (at) ;attribute
mov es:[bx],ax
ret
wchat ENDP
;/* read characer & attribute */
;unsigned int rchat(int line, int col)
; {
; int p;
; static unsigned int chat;
; static void far *pchat = &chat;
;
; p = (line * 80 + col) * 2;
;/* pchat = &chat; */
; movedata(scrseg, p, FP_SEG(pchat), FP_OFF(pchat), 2);
; return chat;
; }
rchat PROC USES ES, line:WORD, col:WORD
mov ax,cs:scrseg ;set screen's seg. reg.
mov es,ax
mov ax,cs:scrncol ;80 cols per line, hopefully
mul line ;ax = lines * scrncol
add ax,col ;ax = (lines*scrncol) + col
mov bx,ax
shl bx,1
mov ax,es:[bx] ;ax has 'c' in low byte, 'at' in high
ret
rchat ENDP
;/* scroll up a section of screen, or clear a section of screen */
;void wscrlup(int nline, int attr, int sty, int stx, int eny, int enx)
; {
; union REGS ir, or;
;
; ir.h.ah = 0x6;
; ir.h.al = (unsigned char) nline;
; ir.h.bh = (unsigned char) attr;
; ir.h.ch = (unsigned char) sty;
; ir.h.cl = (unsigned char) stx;
; ir.h.dh = (unsigned char) eny;
; ir.h.dl = (unsigned char) enx;
; int86(0x10, &ir, &or);
; }
wscrlup PROC nline:WORD, attr:WORD, sty:WORD, stx:WORD, eny:WORD, enx:WORD
mov al,byte ptr (nline)
mov bh,byte ptr (attr)
mov ch,byte ptr (sty)
mov cl,byte ptr (stx)
mov dh,byte ptr (eny)
mov dl,byte ptr (enx)
mov ah,06 ;
int 10H
ret
wscrlup ENDP
;/*
; move from a buffer to the screen
; sty - y offset in buffer to start
; stx - x offset in buffer to start
; ny - number of rows to copy
; nx - number of cols to copy
; ydelt - width of buffer in columns
; psty - physical start of window area - add sty to get first row to change
; pstx - physical start
;*/
;void move2scr(unsigned short *bufr, int sty, int stx,
; int ny, int nx, int ydelt, int psty, int pstx)
; {
; unsigned i, p, n;
; unsigned short *sbuf;
; unsigned int sbufseg, sbufoff;
;
;#ifdef SMALLDAT
; {
; struct SREGS s;
;
; segread(&s);
; sbufseg = s.ds;
; }
;#else
; sbufoff = FP_OFF(bufr);
;#endif
; sbuf = bufr + (sty * ydelt) + stx;
; for (i=0; ny; i++, ny--)
; {
; p = (((psty+sty+i) * COLS) + pstx+stx) * 2;
; n = nx * 2;
;#ifdef SMALLDAT
; sbufoff = (unsigned int) sbuf;
;#else
; sbufoff = FP_OFF(sbuf);
;#endif
; movedata(sbufseg, sbufoff, scrseg, p, n);
; sbuf += ydelt;
; }
; }
move2scr PROC USES ES SI DI, bufr:PTR WORD, sty:WORD, stx:WORD, \
ny:WORD, nx:WORD, ydelt:WORD, psty:WORD, pstx:WORD
pLds si,bufr ;get pointer to screen image
mov ax,sty ;bufr + (sty * ydelt) + stx
mul ydelt
add ax,stx
shl ax,1
add si,ax ;ds:si is now 'sbuf'
; hand optimization: calculate 'p' 1 time, then at end of loop
; always add '160'. This will move down one line. 'di' will
; be 'p'.
;
mov ax,psty
add ax,sty
mul cs:scrncol
add ax,pstx
add ax,stx
shl ax,1
mov di,ax ; 'p' -- pointer to screen
mov dx,nx ;get a copy of nx
shl dx,1 ; number of bytes to copy
cld ;always go forward
mov ax,cs:scrseg ;destination is screen segment
mov es,ax
mov bx,cs:scrncol
shl bx,1 ;scrncol * 2
mov ax,ydelt
shl ax,1
mov cx,ny ;number of iterations in loop
forloop:
xchg dx,cx ;save cx, put nx*2 in cx
push si
push di
push cx
rep movsb ;wow, it this works, it'll be a miracle
pop cx
pop di
pop si
xchg cx,dx
add di,bx ;next line on screen
add si,ax ;next line of screen image in RAM
loop forloop
ret
move2scr ENDP
;****************************************************************
;void curson(void)
; {
; union REGS x;
;
; x.h.ah = 0x0f;
; int86(0x10, &x, &x);
; if (mono_only)
; x.h.ch = 11, x.h.cl = 12;
; else
; x.h.ch = 6, x.h.cl = 7;
; x.h.ah = 0x01;
; int86(0x10, &x, &x);
; }
curson PROC
cmp cs:mono_only,0
jz curson1
mov cx,0B0CH
jmp short curson2
curson1:
mov cx,0607H
curson2:
mov ah,01H
int 10H
ret
curson ENDP
;void cursoff(void)
; {
; union REGS x;
;
; x.h.ah = 0x01;
; x.h.ch = 31;
; x.h.cl = 31;
; int86(0x10, &x, &x);
; }
cursoff PROC
mov ah,01H
mov cx,1f1fH
int 10H
ret
cursoff ENDP
end
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/