"Bill Buckels" <bbuck
...@mts.net> wrote:
>A Loader/Viewer for .BSV Saved Text Screen files
See below. This code is from an old hybrid bundle that I once wrote called
WINBMP. You can download the whole old thing at:
http://www.teacherschoice.ca/cprog/winbmp30.zip
Source included.
The code below is for a tsr which is assembled with masm then made into a
com using exe2bin. It is a companion to the code I posted previously.
Instead of exe2bin a person should probably use execom today.
Assemble under Windows XP using:
Microsoft (R) Macro Assembler Version 6.14.8444
Copyright (C) Microsoft Corp 1981-1997. All rights reserved.
Microsoft (R) Segmented Executable Linker Version 5.60.339 Dec 5 1994
Copyright (C) Microsoft Corp 1984-1993. All rights reserved.
EXECOM v.0499 Copyright (c) 1988,1989,1999 Thomas G. Hanlin III
Here are the steps:
@echo off
rem MASM.BAT
if not exist %1.asm goto NOTFOUND
c:\masm\ml /c %1.asm
c:\masm\link %1.obj, %1.exe, NUL,,NUL
if exist %1.exe erase %1.obj
c:\masm\execom %1.exe %1.com
goto END
:NOTFOUND
echo %1.ASM was not found!
echo Usage is : MASM [BaseName only - .ASM is assumed]
:END
From my point of view, if a programmer is going to call themselves an MS-DOS
programmer, the minimum I expect is a good working knowledge of interrupts,
and a a good working knowledge of low level adresses like where the screen
lives and how the file system works etc.
The goal here for you would be to take the two programs that I have posted
here and build them. Then capture some DOS screens from 80 column text
programs and display them and actually understand what you have done.
Keep in mind that also in my view a C Windows programmer should know how to
code at the Win32 API level.
Bill
x--- snip ---x
; Program Name : grabsv.asm
; Author : bill buckels
; Date : oct 1993
;;Revised jul 1996
;; removed the installation check
;; this causes some pentiums and PS2 compatible bios to
hang
; Purpose : a memory resident text screen grabber
; saves to disk in BSAVED image format
kb_data equ 60h ;keyboard data port
kb_ctrl equ 61h ;keyboard control port
eoi equ 20h ;8259 end-of-interrupt value
int_ctrl_port equ 20h ;8259 PIC port
alt_key equ 8 ;alt key shift code
period equ 34h ;hot key
_psegoff equ 22 ;interrupt vector table address for
_poffoff equ 20 ;the print screen handler vector entries
code segment para public 'code'
assume cs:code
org 100h
begin: jmp initialize ;jump to initialization code
_crt dd 0b8000000h ;CGA screen address
_vmodeptr dd 0400049h ;BIOS display mode record
_installed dd 0415h ;Our Signature
pseg dw ? ;Our Printscreen Vector Table Entries
poff dw ?
dos_seg dw ? ;Dos Busy ?
indos dw ? ;offset to indos flag
video_seg dw 0b800h ;CGA segment
ourpsp dw ? ;save our psp for context switch
theirpsp dw ? ;use their psp to restore context
; The Other ISR's in the chain must be serviced
old_int_9h label dword ;old keyboard interrupt vector
old_keyboard_int dw 2 dup (?)
old_int_1ch label dword ;old timer interrupt vector
old_timer_int dw 2 dup (?)
old_int_28h label dword ;old dos idle interrupt vector
old_dos_int dw 2 dup (?)
hotkeystat db 0 ;status of keyboard interrupt routine
dos_busy db 0 ;status of dos
vid_ctr dw 6 ;length of user defined filename
progress db 0 ;is a screen save in progress ?
tick_cnt db 0 ;timer counter
fheader db 0fdh, 0, 0b8h, 0, 0, 0a0h, 0fh ; bsaved header
footer db 1ah
buff db 'S' ; input field complete with screen attributes
db 70h
db 'V'
db 70h
db 'G'
db 70h
db 'R'
db 70h
db 'A'
db 70h
db 'B'
db 70h
db '0'
db 70h
db '0'
db 70h
db '.'
db 70h
db 'B'
db 70h
db 'S'
db 70h
db 'V'
db 70h
db ' '
db 70h
db ' ',1fh
db 'F',1fh
db 'i',1fh
db 'l',1fh
db 'e',1fh
db 'n',1fh
db 'a',1fh
db 'm',1fh
db 'e',1fh
db '?',1fh
db ' ',1fh
screenbuffer db 48 dup(?) ; save the screen under the field
fname DB 'SVGRAB00.BSV',0 ; filename buffer
fcnt1 DB '0' ; filename counters
fcnt2 DB '0'
handle DW ? ; filehandle
;-------------------------------------------------------
;Resident mainline and ISR routines
;-------------------------------------------------------
; hook the dos idle loop
; reset the dos busy flag if we are called
newdos proc near
mov dos_busy,0
jmp old_int_28h
iret
newdos endp
;check if dos is busy
;ortoo in case the printscreen vectors get messed-up
;put our routine back again
timertick proc near
sti
push ax
push cx
push dx
push bx
push sp
push bp
push si
push di
push ds
push es
mov bp,sp
cmp progress,0
jne inprogress
push cs ;put code seg into data seg
pop ds
mov dos_busy,0 ;test for dos busy?
mov ax,dos_seg
mov es,ax
mov bx,indos
cmp BYTE PTR es:[bx],0 ;if not we quietly leave
je SKIPDOS
mov dos_busy,1
SKIPDOS:
;replace the printscreen vectors
;every 5- seconds if it has been changed
inc tick_cnt
cmp tick_cnt,91
jl inprogress
mov tick_cnt,0
mov ax,0
mov es,ax
mov bx,_psegoff
mov ax, WORD PTR es:[bx]
cmp ax, pseg
je OK_SKIP
mov ax,pseg
mov WORD PTR es:[bx],ax
OK_SKIP:
mov bx,_poffoff
mov ax, WORD PTR es:[bx]
cmp ax, poff
je inprogress
mov ax, poff
mov WORD PTR es:[bx],ax
inprogress:
mov sp,bp
pop es
pop ds
pop di
pop si
pop bp
pop bx
pop bx
pop dx
pop cx
pop ax
cli
jmp old_int_1ch
iret
timertick endp
; when printscreen is pressed, save the screen to disk
printscreen proc near
sti
mov progress,1 ; don't bother us... we're busy
push ax
push cx
push dx
push bx
push sp
push bp
push si
push di
push ds
push es
mov bp,sp
les bx,DWORD PTR _vmodeptr ;are we in text mode 3 or less
cmp BYTE PTR es:[bx],3 ;if not we quietly leave
ja FALSEXIT
cmp dos_busy,0 ;is dos busy ?
jne FALSEXIT
;prepare for context switching
mov ah, 51h
int 21h
mov theirpsp,bx
mov ah, 50h
mov bx, ourpsp
int 21h
push cs ;put code seg into data seg
pop ds
;create the user name
lea dx, fname ; load the dos name buffer into es:[di]
mov di,dx
push ds
pop es
lea dx, buff ; load the field name buffer into ds:[si]
mov si, dx
doname:
mov al, BYTE PTR ds:[si] ;move the field into the dos buffer
cmp al, 32 ;skip the screen attributes
je finished ;Blank ? We are done
mov BYTE PTR es:[di],al
add si,2
inc di
jmp doname
finished:
mov al,0 ;Replace the Blank with a NULL terminator
mov BYTE PTR es:[di],al
sub di,5
mov al,fcnt1 ;Embed the Counter Values Into The Name
mov BYTE PTR es:[di],al
dec di
mov al,fcnt2
mov BYTE PTR es:[di],al
push ds ;Create/Truncate a Normal File
lea dx, fname
xor cx,cx
mov ah,3ch
int 21h
jc MYEXIT
pop ds
mov handle,ax ;save the handle for subsequent operations
inc fcnt1 ;increment filename
cmp fcnt1,'9'
jle DOIT
mov fcnt1,'0'
inc fcnt2
cmp fcnt2,'9'
jle DOIT
mov fcnt2,'0'
jmp DOIT
FALSEXIT:
jmp TRUEXIT
DOIT:
; write the header
push ds
lea dx, fheader
mov bx,handle
mov cx,7
mov ah,40h
int 21h
jc MYEXIT
pop ds
; point to the screen
; write the body... 4000 bytes
push ds
mov bx,handle
mov ds,video_seg
xor dx,dx
mov cx,4000
mov ah,40h
int 21h
jc MYEXIT
pop ds
; write the footer
push ds
lea dx, footer
mov bx,handle
mov cx,1
mov ah,40h
int 21h
jc MYEXIT
pop ds
push ds
;close the file
mov ah,3eh
mov bx,handle
int
...