home *** CD-ROM | disk | FTP | other *** search
- page 56,132
- title WBIOS Window BIOS extension
- .sall
- ;
- ; Written 1984 By J. Eric Roskos; public domain.
- ; No support is provided by the author; you must make any desired
- ; revisions yourself.
- ;
- ; This program provides an extension to the BIOS function calls,
- ; functions 40H-43H. For a description of the calls, see the Turbo
- ; Pascal program WDEMO.PAS, which also shows the preferred way of
- ; using the functions. Note, however, that this BIOS extension is
- ; independent of any particular language, and will work with any
- ; program that does its I/O through the ROM BIOS's "WRITE_TTY"
- ; function (the plain MS-DOS display driver does this, for instance).
- ;
- ; There are a few enhancements to the IBM BIOS call: TABs are handled
- ; properly, BELs produce a more bell-like sound, and there is a "Raw"
- ; mode (although you'll have to add the function call to set it your-
- ; self) in which all characters are displayed as-is, without translation
- ; for CR, LF, BEL, etc. There is also an option to turn end-of-line
- ; wraps on or off, although again you must add the function call.
- ; To turn these modes on, set the variables "wrap" and "raw" as
- ; explained below in the comments. (These features were included in
- ; the program for future expansion, but have never been tested, and
- ; aren't guaranteed to work).
- ;
-
- ;
- ; Macros
- ;
-
- ;
- ; wto: write message to display. Append cr/lf unless crsup=nocr
- ;
-
- wto macro msg,crsup
- local msgstr,around
-
- jmp around
-
- msgstr db msg
- ifb <crsup>
- db 0DH,0AH
- endif
- db '$'
-
- around: push ax
- push bx
- push si
- push di
- push bp
-
- mov si,offset msgstr
- call putc
-
- pop bp
- pop di
- pop si
- pop bx
- pop ax
-
- endm
-
- prtreg macro rg,msg ; put register rg with message msg on display
-
- push ax
-
- mov ax,rg
- call prtax
- wto msg,nocr
-
- pop ax
- endm
-
-
- ;
- ; Code Segment
- ;
-
- cseg segment para public 'code'
- assume cs:cseg,ds:cseg,ss:cseg,es:nothing
-
- org 100H
- ;
- ; COM program startup
- ;
- cpstart proc far
- jmp near ptr start
- cpstart endp
-
- ;
- ; Local Procedures
- ;
- lcpos dw 0E60H
-
- putc proc near ; write a string to display W/O DOS intervention
- push es
- push ax
- mov ax,crt_seg
- mov es,ax
- mov di,cs:lcpos
- putc1:
- mov al,cs:[si]
- cmp al,'$'
- je putc2
- cmp al,0dH
- jne putc3
- mov cs:lcpos,0E60H
- mov di,0E60H
- jmp putc4
- putc3:
- mov es:[di],al
- inc di
- inc di
- putc4:
- inc si
- jmp putc1
-
- putc2:
- mov cs:lcpos,di
- pop ax
- pop es
- ret
-
- putc endp
-
- prtnum proc near ; print half a byte on screen
- push ds ; this procedure is used by prtax below
- push es
-
- push cs
- pop ds
-
- push bx
- mov bx,crt_seg
- mov es,bx
- mov bx,offset xltab
- xlatb
- mov bx,cs:lcpos
- mov es:[bx],al
- inc cs:lcpos
- inc cs:lcpos
-
- pop bx
- pop es
- pop ds
- ret
- xltab db '0123456789ABCDEF'
- prtnum endp
-
- prtax proc near ; print contents of ax register on screen
- push cx ; all registers are preserved
- push ax
- mov al,ah
- mov cl,4
- shr al,cl
- call prtnum
- pop ax
- push ax
- mov al,ah
- and al,0Fh
- call prtnum
- pop ax
- push ax
- mov cl,4
- shr al,cl
- call prtnum
- pop ax
- push ax
- and al,0Fh
- call prtnum
- pop ax
- pop cx
- ret
- prtax endp
-
- ;
- ; BIOS call dispatcher
- ;
-
- ;
- ; data area
- ;
-
- ;
- ; vector to ROM BIOS
- ;
-
- romoff dw ?
- romseg dw ?
-
- ;
- ; display variables
- ;
-
- active_page db ? ; parameters for wtty (window I/O) proc.
- crt_mode db ?
- color db 7
- rt_edge db 79
- bot_edge db 24
- lf_edge db 0
- top_edge db 0
- wd_width db 79 ; window width and height (really the coords of
- wd_height db 24 ; bottom corner relative to strt of window)
- wrap db 0 ; 0=don't CRLF at right margin, 1=do
- raw db 0 ; 0=xlate cr, lf, etc, 1=display w/o xlation
- crt_seg dw ? ; segment for CRT display RAM
-
- ;
- ; clock
- ;
-
- tick dw 0 ; 1/18th second counter
- tock dw 0 ; every-5-seconds counter (18.2 Hz adjust)
- clk_oset dw 0 ; save area for displaced clock int handler
- clk_seg dw 0
-
- ;
- ; window stack:
- ; 0[wsp] = left edge of window
- ; 1[wsp] = top edge of window
- ; 2[wsp] = right edge of window
- ; 3[wsp] = bottom edge of window
- ; 4[wsp] = cursor address (2 bytes)
- ; 6[wsp] = offset of window save area (2 bytes)
- ; 8[wsp] = segment of window save area (2 bytes)
- ; 10[wsp] = number of frames (1 byte)
- ;
-
- wssize equ 13 ; number of bytes in window stack frame
- wsframes equ 15 ; number of windows that can be stacked
-
- wsp dw offset wsend ; display window stack pointer
- wstack db wssize*wsframes dup (?) ; display window save stack
- wsend equ this word ; bottom of stack
- db wssize dup (?) ; extra frame in case of user error
-
- ;
- ; window queue: save area for windows
- ;
-
- wqp dw offset qbase ; next avail byte in window queue
- wqsize equ 8192 ; size of window queue - ok to tune
- qlim dw ? ; max address in window queue
-
- ;
- ;
-
- temp dw ? ; used when fixing up stack for return
-
- ;
- ; jump table for our BIOS functions
- ;
-
- jmptab label word
- dw offset setwindow
- dw offset pushwindow
- dw offset rstwindow
- dw offset frame
- tablen equ $-jmptab
-
-
- ;
- ; the dispatcher
- ;
-
- disp proc far
-
- ;
- ; see if it's one of our functions
- ;
-
- cmp ah,14 ; write TTY function
- jne tryrcp
- jmp ourfn
- tryrcp: cmp ah,3 ; read cursor position
- jne tryscp
- jmp readcsr
- tryscp: cmp ah,2 ; set cursor position
- je adjxy ; have to adjust coordinates
- cmp ah,6 ; scroll screen up
- jne trysd ; have to adjust corners
- jmp adjsc
- trysd: cmp ah,7 ; scroll screen down
- jne tryus ; adjust corners
- jmp adjsc
- tryus: cmp ah,40H ; one of our new functions?
- jl callbios ; no, call the BIOS
- jmp ourfn
-
- callbios:
- push cs:romseg ; not one of ours; call BIOS
- push cs:romoff
- ret
-
- ;
- ; adjust x and y coordinates for set-cursor-position
- ;
- adjxy:
- push dx ; save caller's dx
-
- add dh,cs:top_edge ; adjust the coordinates
- cmp dh,cs:bot_edge
- jle adjxy1
-
- ; if below the bottom edge, scroll up a line
-
- push ax ; save caller's registers
- push bx
- push cx
- push dx
- push si
- push di
- mov ax,0601H ; scroll up one line
- mov cx,0 ; in the current window
- mov dh,cs:wd_height
- mov dl,cs:wd_width
- mov bh,cs:color
- int 10H
- pop di ; restore caller's registers
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
-
- mov dh,cs:bot_edge ; now set cursor to bottom
-
- adjxy1: add dl,cs:lf_edge
- cmp dl,cs:rt_edge
- jle adjxy2
- mov dl,cs:rt_edge
-
- ; fix up stack so BIOS's IRET will return to
- ; our adjxy3 label
-
- adjxy2: mov cs:temp,ax ; save ax (can't push it!)
- push ax ; a dummy flag register save
- push cs ; return cs
- mov ax,offset adjxy3 ; return ip
- push ax
- mov ax,cs:temp ; restore saved ax
- jmp callbios ; and call the BIOS
-
- adjxy3:
- pop dx ; back from BIOS now: restore caller's
- iret ; dx, and return.
-
- ;
- ; adjust corners for scroll
- ;
- adjsc:
- push bx
- add ch,cs:top_edge ; adjust row posn of upper left
- cmp ch,cs:bot_edge
- jle adjsc1
- mov ch,cs:bot_edge
- adjsc1: add cl,cs:lf_edge ; adjust column posn of upper left
- cmp cl,cs:rt_edge
- jle adjsc2
- mov cl,cs:rt_edge
- adjsc2: add dh,cs:top_edge ; adjust row posn of lower right
- cmp dh,cs:bot_edge
- jle adjsc3
- mov dh,cs:bot_edge
- adjsc3: add dl,cs:lf_edge ; adjust column posn of lower right
- cmp dl,cs:rt_edge
- jle adjsc4
- mov dl,cs:rt_edge
- adjsc4: mov bl,cs:bot_edge ; adjust number of lines to scroll
- sub bl,cs:top_edge
- cmp al,bl
- jle adjsc5
- mov al,bl
- adjsc5: pop bx
- jmp callbios
-
- readcsr: ; read cursor position
- push ds ; save registers that must be kept
- push bx
-
- mov ax,40H ; switch to ROM BIOS data segment
- mov ds,ax
- mov bl,bh ; get param page number into bx
- xor bh,bh
- sal bx,1 ; convert to cursor table offset
- mov dx,[bx+50H] ; read csr posn from cursor table
- mov cx,word ptr 60H ; read csr mode from mode word
- push cs ; switch to our data segment
- pop ds
- sub dh,top_edge ; adjust position for window corner
- sub dl,lf_edge
-
- ; make sure cursor address is in range -- adjust if not
-
- cmp dh,0 ; check not above first row
- jge lrowok
- mov dh,0
- lrowok: cmp dh,wd_height ; check not below last row
- jle hrowok
- mov dh,wd_height
- hrowok: cmp dl,0 ; check not left of first column
- jge lcolok
- mov dl,0
- lcolok: cmp dl,wd_width ; check not right of last column
- jle hcolok
- mov dl,wd_width
- hcolok:
- pop bx ; restore bx register
- pop ds ; switch to caller's data segment
- iret ; and return
-
-
- ourfn:
- ;
- ; Process one of our functions.
- ;
-
- cld ; save all registers except ax
- push es
- push ds
- push dx
- push cx
- push bx
- push si
- push di
-
- push cs ; switch to our data/code segment
- push cs
- pop ds
- pop es
-
- ; find what routine they are invoking and call it
-
- cmp ah,14
- jne newfns
-
- call wtty
- jmp ourret
-
- newfns:
- mov al,ah
- xor ah,ah
- sub al,40H
- sal ax,1
- mov si,ax
- cmp ax,tablen
- jb validjmp
- jmp ourret
- validjmp:
- call word ptr [si+offset jmptab]
-
- ourret:
- pop di
- pop si
- pop bx
- pop cx
- pop dx
- pop ds
- pop es
- clc
- cmp ax,0 ; did we return an error code?
- je ourretok ; no, leave carry cleared
- stc ; set carry
- ourretok:
- ret 2 ; discard flags from interrupt
-
- disp endp
-
- ;
- ; setwindow - set corners of the current display window.
- ; (ch,cl) = (row,column) of upper left corner
- ; (dh,dl) = (row,column) of lower right corner
- ;
-
- setwindow proc near
-
- mov lf_edge,cl
- mov top_edge,ch
- mov rt_edge,dl
- mov bot_edge,dh
- mov al,dh ; compute relative bottom corner of window
- sub al,ch
- mov wd_height,al
- mov al,dl
- sub al,cl
- mov wd_width,al
- mov ax,0 ; always return successful
- ret
-
- setwindow endp
-
- ;
- ; setcolor - set attribute byte for display to al
- ;
-
- setcolor proc near
-
- mov color,al
- ret
-
- setcolor endp
-
- ;
- ; cls - clear the current window
- ;
-
- cls proc near
-
- mov cx,0
- mov dh,bot_edge
- sub dh,top_edge
- mov dl,rt_edge
- sub dl,lf_edge
- mov ax,0600H
- mov bh,color
- int 10H
- ret
-
- cls endp
-
- ;
- ; savqcalc - compute parameters for the save/restore window operation
- ; No input parameters.
- ; results: cx = number of words to xfer
- ; bl = number of words to transfer per line
- ; bh = zero, used in counting words xferred on this line
- ; dx = amount to add to screen pointer to wrap to next line
- ; ax = same as cx
- ;
- savqcalc proc near
-
- mov al,bot_edge ; get number of words to xfer
- sub al,top_edge ; compute number of lines in al
- inc al
- mov bl,rt_edge ; compute number of words per line in bl
- sub bl,lf_edge
- inc bl
- mov dl,80 ; get wraparound increment in dx = 80-bl
- xor dh,dh
- sub dl,bl ; compute word increment
- shl dx,1 ; convert to byte increment
- mul bl ; multiply ax = al*bl
- mov cx,ax ; gives word count to xfer, store in cx
- ; bl still contains # words to xfer per line
- xor bh,bh ; zero out bh to count up to bl before wrapping
- ret
-
- savqcalc endp
- ;
- ; pushwindow - push the current window state onto the window stack
- ;
-
- pushwindow proc near
-
- ; first, save the new corners on stack
-
- push cx
- push dx
-
- ; now see if there's room in the window queue:
- ; compute ax = (endrow-strtrow+1)*(endcol-strtcol+1)*2
- ; add ax to queue pointer and see if it overflows qlim
-
- mov al,dh ; get ending row
- sub al,ch ; subtract starting row
- inc al ; add 1
-
- mov bl,dl ; get ending column
- sub bl,cl ; subtract starting column
- inc bl ; add 1
-
- mul bl ; multiply the dimensions
- shl ax,1 ; and mult by 2 to convert to byte count
-
- add ax,wqp ; add the byte count to the queue pointer
- cmp ax,qlim ; compare against end of queue
- jl pushok ; if less, go ahead
-
- pop dx ; no room. get back dx and cx
- pop cx
- mov ax,1 ; set error code in ax
- jmp nosav ; and don't do the save
-
-
- ; save window corners and cursor position
- pushok:
- sub wsp,wssize ; adjust the stack pointer down a frame
- mov bx,wsp
- mov al,lf_edge
- mov [bx],al
- mov al,top_edge
- mov 1[bx],al
- mov al,rt_edge
- mov 2[bx],al
- mov al,bot_edge
- mov 3[bx],al
- mov ah,3
- mov bh,0
- int 10H ; get current cursor position
- mov bx,wsp ; get window stack pointer back
- mov 4[bx],dx ; save current cursor position
-
- ; set up the new window
-
- pop dx ; get back the new window corners
- pop cx
-
- call setwindow ; set the window corners
-
- ; now, save the area occupied by new window
-
- ; compute area to be saved
-
- mov al,top_edge ; get starting address in CRT segment
- mov bl,160
- mul bl
- add al,lf_edge ; ax = top_edge*160 * lf_edge*2
- adc ah,0
- add al,lf_edge
- adc ah,0
- mov si,ax ; store it in the si
-
- call savqcalc ; compute size of save area, etc.
-
- mov di,wqp ; set di to next byte in window queue
-
- push ds ; save ds for switch to screen segment
- mov ax,crt_seg ; switch ds to screen segment
- mov ds,ax
-
- ;;; assume ds:0B000H
-
- cld
- ; save address of screen save area on stack
- push di ; so we can get it back later
-
- pshmov:
- movsw ; move a word
- inc bh ; inc count of words moved
- cmp bh,bl ; done with this line?
- jge pshnxt ; yes, go move to next line
- loop pshmov
- jmp pshdon
- pshnxt:
- add si,dx ; increment si by wraparound increment
- xor bh,bh ; zero out the words-per-line counter
- loop pshmov ; and go move next word
-
- pshdon: ; here when finished saving
- mov ax,di ; remember next free mem address
-
- pop di ; get back the starting address of save area
- pop ds ; get back our data segment
-
- ;;; assume ds:dseg
-
- mov wqp,ax ; now set wqp to next free mem address
- mov bx,wsp ; get window stack pointer back again
- mov 6[bx],di ; save screen save area address on stack
- mov 8[bx],es ; (this word is currently always our ds)
-
- mov ax,0 ; set no-error code
- nosav:
- ret
-
- pushwindow endp
-
-
- ;
- ; rstwindow - restore most recent window state from stack
- ;
- rstwindow proc near
-
- ; first make sure there's a window on the stack
-
- cmp wsp,offset wsend
- jl rstok
- mov ax,1 ; nothing on stack. set error code in ax
- jmp norst ; and don't restore
-
- rstok:
- ; restore screen contents
-
- mov bx,wsp ; get window stack pointer
- mov al,10[bx] ; delete the frames around the window
- sub lf_edge,al
- sub top_edge,al
- add rt_edge,al
- add bot_edge,al
- shl al,1
- add wd_width,al
- add wd_height,al
- mov byte ptr 10[bx],0 ; now there are no frames around the window
-
- push es
- mov di,crt_seg ; get address of screen segment into es
- mov es,di
-
- ;;; assume es:0B000H
-
- ; compute area to be restored
-
- mov al,top_edge ; get starting address in CRT segment
- mov bl,160
- mul bl
- add al,lf_edge ; ax = top_edge*160 + lf_edge*2
- adc ah,0
- add al,lf_edge
- adc ah,0
- mov di,ax ; store it in the di
-
- mov bx,wsp ; get back our window stack pointer
- mov si,6[bx] ; get address of window save area
- mov wqp,si ; delete save area while we've got the address
-
- call savqcalc
-
- cld
- rstmov:
- movsw ; move a word
- inc bh ; inc count of words moved
- cmp bh,bl ; done with this line?
- jge rstnxt ; yes, go move to next line
- loop rstmov
- jmp rstdon
- rstnxt:
- add di,dx ; increment si by wraparound increment
- xor bh,bh ; zero out the words-per-line counter
- loop rstmov ; and go move next word
-
- rstdon: ; here when finished saving
- pop es ; get our es back
-
- ;;; assume es:dseg
-
- ; restore the screen corners and cursor position
-
- mov bx,wsp ; get stack frame
- mov al,[bx] ; restore corners
- mov lf_edge,al
- mov al,1[bx]
- mov top_edge,al
- mov al,2[bx]
- mov rt_edge,al
- mov al,3[bx]
- mov bot_edge,al
-
- mov al,bot_edge ; compute relative window edges
- sub al,top_edge
- mov wd_height,al
- mov al,rt_edge
- sub al,lf_edge
- mov wd_width,al
-
- mov dx,4[bx] ; set cursor position
- mov ah,2
- mov bh,0
- int 10H
-
-
- add wsp,wssize ; delete this stack frame
- mov ax,0 ; return no-error code
- norst:
- ret ; and return
-
- rstwindow endp
-
- ;
- ; frame - draw a frame around the current window
- ;
-
- frame proc near
-
- push es ; switch es to crt segment
- mov ax,crt_seg
- mov es,ax
-
- mov al,top_edge ; find starting address of window
- mov bl,160 ; ax = top_edge*160 + lf_edge*2
- mul bl
- mov bl,lf_edge
- shl bl,1
- add al,bl
- adc ah,0
- mov si,ax ; store it in the si for horizontals
- mov di,ax ; and in di for drawing verticals
-
- mov al,wd_height ; find distance to bottom line of window
- mov bl,160 ; ax = wd_height*160
- mul bl
- mov bx,ax ; store it in the bx
-
- mov byte ptr es:[si],0daH ; put on the top and bottom corners
- mov byte ptr es:[si+bx],0c0H
- inc si
- mov ah,color ; fill in attributes for corners
- mov byte ptr es:[si],ah
- mov byte ptr es:[si+bx],ah
- inc si
-
- mov cl,wd_width ; get width of window, minus 2
- xor ch,ch
- dec cx
- mov al,0c4H ; get horizontal line into ax
- mov ah,color
-
- horiz: ; draw the 2 horizontals
- mov word ptr es:[si],ax
- mov word ptr es:[si+bx],ax
- add si,2
- loop horiz
-
- mov al,0bfH ; top right corner
- mov word ptr es:[si],ax
- mov al,0d9H ; bottom right corner
- mov word ptr es:[si+bx],ax
-
- mov si,di ; get back starting address of window
- mov bl,wd_width ; get width of window minus 1 into bx
- xor bh,bh
- shl bx,1
- add si,160 ; move down a line (don't overwrite corners)
- mov cl,wd_height ; get height of window, minus 2, into cx
- xor ch,ch
- dec cx
- mov al,0B3H ; get vertical line into al
- mov ah,color ; get attribute into ah
-
- vert: ; draw the two verticals
- mov word ptr es:[si],ax
- mov word ptr es:[si+bx],ax
- add si,160
- loop vert
-
- inc lf_edge ; shrink the window
- inc top_edge
- dec rt_edge
- dec bot_edge
- sub wd_width,2
- sub wd_height,2
- mov bx,wsp
- inc byte ptr 10[bx] ; increment count of frames
-
- pop es
- ret
-
- frame endp
-
-
- ;
- ; wtty - same as function 14 in ROM BIOS, but uses windows.
- ;
- wtty proc near
-
- ; get CRT mode into ah and crt_mode
- ; get active page into active_page
-
- push es
- push bx
- mov bx,40H
- mov es,bx
- mov bx,62H ; 62H = offset active page
- mov ah,es:[bx]
- mov active_page,ah
- mov bx,49H ; 49H = offset CRT mode
- mov ah,es:[bx]
- mov crt_mode,ah
- pop bx
- pop es
-
- push ax ; save registers
- push ax ; save char to write
-
- ; read cursor position (inline for speed)
-
- push ds ; save registers that must be kept
- push bx
-
- mov ax,40H ; switch to ROM BIOS data segment
- mov ds,ax
- mov bl,bh ; get param page number into bx
- xor bh,bh
- sal bx,1 ; convert to cursor table offset
- mov dx,[bx+50H] ; read csr posn from cursor table
- mov cx,word ptr 60H ; read csr mode from mode word
- push cs ; switch to our data segment
- pop ds
- sub dh,top_edge ; adjust position for window corner
- sub dl,lf_edge
-
- pop bx ; restore bx register
- pop ds ; switch to caller's data segment
-
- ; end of read-cursor-position
-
- pop ax ; get back character
-
- cmp raw,0 ; raw I/O mode?
- jne rawio ; yes, no special char xlation
-
- cmp al,8 ; BS?
- je dobsp
- cmp al,0dH ; CR?
- je docr
- cmp al,0aH ; LF?
- je dolf
- cmp al,07H ; BEL?
- je dobel
- cmp al,09H ; TAB?
- je dotab
-
- rawio:
- mov bh,active_page ; set active page into bh which we got above
- mov bl,color ; get color also (attribute byte)
-
- mov ah,9 ; write character/attribute BIOS call
- mov cx,1 ; write only once
- int 10H
-
- inc dl ; advance cursor one position
- cmp wrap,0 ; wrap-around on?
- je scrpos ; no, don't wrap
- cmp dl,wd_width ; at the right edge of the screen?
- jnz scrpos ; no, don't wrap
- mov dl,0 ; yes, move it to left edge
- cmp dh,wd_height ; at bottom of screen?
- jnz down1 ; no, just move it down a line
-
- sclreq: ; have to scroll
- mov ah,2 ; jmp here to set cursor position also
- mov bh,0
- int 10H
-
- mov al,crt_mode ; get the crt mode
- cmp al,4
- jc gcolor
- cmp al,7
- mov bh,color ; fill with proper fg/bg
- jne scrl1
-
- gcolor:
- mov bh,color ; get filler fg/bg
-
- scrl1:
- mov ax,601H ; scroll one line
- mov cx,0 ; get current screen corners
- mov dh,wd_height
- mov dl,wd_width
- xint10:
- int 10h ; do scroll - here also for gen'l int 10 call
- wtret1: ; jmp here to return from wtty
- pop ax ; restore the character we wrote
- ret
-
- down1: ; move cursor down a line
- inc dh
- scrpos: ; jmp here to do set-cursor call
- mov ah,2
- jmp xint10
-
- dobsp: ; backspace
- cmp dl,0 ; do nothing if already at left edge
- je scrpos
- dec dl ; move back one position
- jmp scrpos
-
- docr: ; carriage return
- mov dl,0
- jmp scrpos
-
- dolf: ; linefeed
- cmp dh,wd_height
- jl down1 ; just move down
- jmp sclreq ; scroll (*** fix- makes redundant set csr call!)
-
- dobel: ; bell
- mov bl,2
- call beep
- jmp wtret1
-
- dotab: ; tab
- mov ah,3
- mov bh,0 ; get cursor position
- int 10H
- add dl,8 ; increment it by 8
- and dl,0F8H ; mask it down
- mov ah,2 ; set cursor position
- int 10H
- jmp wtret1 ; and return from call
-
- wtty endp
-
- ;
- ; beep the speaker for desired interval. This is how IBM does it -- kind
- ; of a mystery why they didn't put a counter in the clk int routine to turn
- ; the beeper off to avoid busy-waiting...
- ; This beeper is set up to sound like the Z19 beeper, which I especially like.
- ;
-
- beep proc near
- mov al,10110110B ; command to timer - generate square wave
- out 43H,al
- mov ax,0700H ; count to produce beep frequency
- out 42H,al
- mov al,ah
- out 42H,al
- in al,61H ; get orig. value in PPI with spkr enable bit
- mov ah,al
- or al,03 ; turn on speaker enable, starting beep
- out 61H,al
- mov cx,2000H ; this determines beep duration
- bpwt: loop bpwt
- mov al,ah ; turn speaker enable off, stopping beep
- out 61H,al
- ret
- beep endp
-
- ;
- ; everything below this point will be deleted from memory once the initial
- ; command exits
- ;
-
- qbase equ this word
- start proc near
-
- ; determine what kind of CRT is in use
-
- int 11H
- and ax,0030H
- cmp ax,0030H
- jne iscolor
- mov crt_seg,0B000H
- jmp setvec
- iscolor:
- mov crt_seg,0B800H
-
- setvec:
- ; set up the BIOS vectors
-
- mov ax,0
- mov es,ax
- mov ax,word ptr es:40H
- mov romoff,ax
- mov ax,word ptr es:42H
- mov romseg,ax
-
- mov ax,offset disp
- mov word ptr es:40H,ax
- mov ax,cs
- mov word ptr es:42H,ax
-
- mov dx,offset qbase ; get starting address for window queue
- add dx,wqsize ; allocate space for window queue
- mov qlim,dx ; save end of queue to test later
-
- int 27H
-
- start endp
-
- cseg ends
-
- end cpstart
-