Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.os.msdos.programmer > #992 > unrolled thread

How to program my own keyboard driver?

Started byRuud Baltissen <rbaltissen@gmail.com>
First post2013-09-19 09:26 -0700
Last post2013-09-20 20:21 -0500
Articles 12 — 5 participants

Back to article view | Back to comp.os.msdos.programmer


Contents

  How to program my own keyboard driver? Ruud Baltissen <rbaltissen@gmail.com> - 2013-09-19 09:26 -0700
    Re: How to program my own keyboard driver? JJ <duh@nah.meh> - 2013-09-20 06:02 +0700
      Re: How to program my own keyboard driver? Ruud Baltissen <rbaltissen@gmail.com> - 2013-09-20 03:07 -0700
    Re: How to program my own keyboard driver? Ross Ridge <rridge@csclub.uwaterloo.ca> - 2013-09-20 00:03 -0400
      Re: How to program my own keyboard driver? Ruud Baltissen <rbaltissen@gmail.com> - 2013-09-20 03:38 -0700
        Re: How to program my own keyboard driver? Ross Ridge <rridge@csclub.uwaterloo.ca> - 2013-09-20 09:19 -0400
    Re: How to program my own keyboard driver? "Rod Pemberton" <dont_use_email@nohavenotit.com> - 2013-09-20 00:53 -0400
      Re: How to program my own keyboard driver? Ruud Baltissen <rbaltissen@gmail.com> - 2013-09-20 03:42 -0700
        Re: How to program my own keyboard driver? Ross Ridge <rridge@csclub.uwaterloo.ca> - 2013-09-20 09:31 -0400
        Re: How to program my own keyboard driver? "Rod Pemberton" <dont_use_email@nohavenotit.com> - 2013-09-20 15:07 -0400
          Re: How to program my own keyboard driver? Ross Ridge <rridge@csclub.uwaterloo.ca> - 2013-09-21 11:56 -0400
    Re: How to program my own keyboard driver? "Bill Buckels" <bbuckels@mts.net> - 2013-09-20 20:21 -0500

#992 — How to program my own keyboard driver?

FromRuud Baltissen <rbaltissen@gmail.com>
Date2013-09-19 09:26 -0700
SubjectHow to program my own keyboard driver?
Message-ID<027615d4-f6f5-4664-bef1-e1aa1cd5f6bf@googlegroups.com>
I received a Commodore 8032-SK (http://commons.wikimedia.org/wiki/File:Museum-Enter-6094688.JPG) that was fried during a thunderstorm. I replaced is inners by a Pentium-II 233 MHz PC (http://www.baltissen.org/images/cbmhd-8032a.jpg). I use it to create images from real floppies. The program is written in Turbo Pascal and runs under W98 DOS. I attached the original keyboard to the on-board LPT port. My program can handle it but it would be cooler if I had a driver for it. Having some 25 years old experience with device drivers under DOS, I thought I could do it but unfortunately it didn't :(

I have this old book in German PC Intern 2.0, even with a driver, CONDRV.ASM, but I don't understand it completely. Another problem, the book uses MASM, I'm using NASM and NASM doesn't accept the ASM.

Another problem, my keyboard doesn't generate interrupts. This means I have to poll it. One idea is writing a TSR that is hooked on the timer interrupt. Then the keyboard buffer has to filled, but how/where exactly? I'm familiar with the buffer used by the BIOS of the XT.

Any help/info is welcome!

Thank you very much for any help!


Kind regards, Ruud Baltissen
www.Baltissen.org

[toc] | [next] | [standalone]


#993

FromJJ <duh@nah.meh>
Date2013-09-20 06:02 +0700
Message-ID<kgj4823kvciz.u39wuj3amoaa$.dlg@40tude.net>
In reply to#992
On Thu, 19 Sep 2013 09:26:45 -0700 (PDT), Ruud Baltissen wrote:
> I have this old book in German PC Intern 2.0, even with a driver,
> CONDRV.ASM, but I don't understand it completely. Another problem, the
> book uses MASM, I'm using NASM and NASM doesn't accept the ASM. 

Could you share that file? If it's too large, don't post it here. Upload it
to www.sendspace.com instead.

> Another problem, my keyboard doesn't generate interrupts. This means I
> have to poll it. One idea is writing a TSR that is hooked on the timer
> interrupt. Then the keyboard buffer has to filled, but how/where exactly?
> I'm familiar with the buffer used by the BIOS of the XT. 

That'll do. You'll need to hook INT 16h for some keyboard functions too, so
that both Commodore and IBM keyboards are usable.

You can use INT 16h AH=05h to store the keystores into the keyboard buffer.

[toc] | [prev] | [next] | [standalone]


#996

FromRuud Baltissen <rbaltissen@gmail.com>
Date2013-09-20 03:07 -0700
Message-ID<28b6cbc5-9c67-44b2-998f-b459ba241680@googlegroups.com>
In reply to#993
Hello JJ,


> Could you share that file?

http://www.baltissen.org/temp/CONDRV.ASM


> That'll do. ...

Thank you!


Kind regards, Ruud Baltissen
www.Baltissen.org 

[toc] | [prev] | [next] | [standalone]


#994

FromRoss Ridge <rridge@csclub.uwaterloo.ca>
Date2013-09-20 00:03 -0400
Message-ID<l1ghf9$3g5$1@rumours.uwaterloo.ca>
In reply to#992
Ruud Baltissen  <rbaltissen@gmail.com> wrote:
>I received a Commodore 8032-SK (http://commons.wikimedia.org/wiki/File:Muse=
>um-Enter-6094688.JPG) that was fried during a thunderstorm. I replaced is i=
>nners by a Pentium-II 233 MHz PC (http://www.baltissen.org/images/cbmhd-803=
>2a.jpg). I use it to create images from real floppies. The program is writt=
>en in Turbo Pascal and runs under W98 DOS. I attached the original keyboard=
> to the on-board LPT port. My program can handle it but it would be cooler =
>if I had a driver for it. Having some 25 years old experience with device d=
>rivers under DOS, I thought I could do it but unfortunately it didn't :(

I wouldn't create an MS-DOS character mode console (CON) driver for it.
I'd create a TSR, maybe loaded as a driver, that replaces the BIOS
keyboard interrupts.  The built in MS-DOS console input driver uses the
BIOS keyboard interrupts to get its input, so this will handle both.
You keyboard would then work both with programs that use MS-DOS to access
the keyboard and those that use the BIOS.  It wouldn't work with programs
that access the keyboard controller directly, but there's not much you
can do about that.

>Another problem, my keyboard doesn't generate interrupts. This means I have=
> to poll it. One idea is writing a TSR that is hooked on the timer interrup=
>t. Then the keyboard buffer has to filled, but how/where exactly? I'm famil=
>iar with the buffer used by the BIOS of the XT.

Create your own keyboard buffer, fill it in the timer interrupt and drain
it from your replacement BIOS keyboard (software) interrupt services.

					Ross Ridge

-- 
 l/  //	  Ross Ridge -- The Great HTMU
[oo][oo]  rridge@csclub.uwaterloo.ca
-()-/()/  http://www.csclub.uwaterloo.ca/~rridge/ 
 db  //	  

[toc] | [prev] | [next] | [standalone]


#997

FromRuud Baltissen <rbaltissen@gmail.com>
Date2013-09-20 03:38 -0700
Message-ID<f2918f57-9f87-47a5-b4f0-bd306149b557@googlegroups.com>
In reply to#994
Hallo Ross,


> I wouldn't create an MS-DOS character mode console (CON) driver for it.
> I'd create a TSR, maybe loaded as a driver, that replaces the BIOS
> keyboard interrupts.  The built in MS-DOS console input driver uses the
> BIOS keyboard interrupts to get its input, so this will handle both.

IMHO there is a flaw in this idea. The onboard 8042 (or whatever they use today) generates the interrupt the moment it receives something from the keyboard. What is now the trigger? There isn't one IMHO. Therefore my idea to hook the TSR to the timer interrupt.


Kind regards, Ruud Baltissen
www.Baltissen.org 

[toc] | [prev] | [next] | [standalone]


#999

FromRoss Ridge <rridge@csclub.uwaterloo.ca>
Date2013-09-20 09:19 -0400
Message-ID<l1hi1u$emt$1@rumours.uwaterloo.ca>
In reply to#997
Ross Ridge writes:
> I wouldn't create an MS-DOS character mode console (CON) driver for it.
> I'd create a TSR, maybe loaded as a driver, that replaces the BIOS
> keyboard interrupts.  The built in MS-DOS console input driver uses the
> BIOS keyboard interrupts to get its input, so this will handle both.

Ruud Baltissen  <rbaltissen@gmail.com> wrote:
>IMHO there is a flaw in this idea. The onboard 8042 (or whatever they use t=
>oday) generates the interrupt the moment it receives something from the key=
>board. What is now the trigger? There isn't one IMHO. Therefore my idea to =
>hook the TSR to the timer interrupt.

Obviously I'm not talking about the keyboard hardware interrupt.  As I
said later in my post, you would hook the hardware timer *and* replace
the BIOS keyboard *software* interrupt with your own.  MS-DOS generates
these software interrupts in order to read the keyboard.  So do many
MS-DOS applications.

						Ross Ridge

-- 
 l/  //	  Ross Ridge -- The Great HTMU
[oo][oo]  rridge@csclub.uwaterloo.ca
-()-/()/  http://www.csclub.uwaterloo.ca/~rridge/ 
 db  //	  

[toc] | [prev] | [next] | [standalone]


#995

From"Rod Pemberton" <dont_use_email@nohavenotit.com>
Date2013-09-20 00:53 -0400
Message-ID<op.w3o070kj0e5s1z@localhost>
In reply to#992
On Thu, 19 Sep 2013 12:26:45 -0400, Ruud Baltissen <rbaltissen@gmail.com>  
wrote:

> I received a Commodore 8032-SK [...]
> I attached the original keyboard to the on-board LPT port.

 From a PET schematic, it appears the keyboard works similarly to the C64.

If that's true, then the problem was solved, and more than once:

http://symlink.dk/projects/c64key/
http://www.vesalia.de/e_keyrah.htm
http://www.waitingforfriday.com/index.php/C64_VICE_Front-End
http://www.go4retro.com/products/ckey/

It could be possible for those to work or be adapted to your keyboard.

I'm surprised you're not familiar with these Ruud since it appears
you've posted a schematics for Commodore C64 like device.

I would start by comparing the keyboard connector lines of the C64
and 8032-SK.  I.e., do they have the same number of pins?  If not,
does the C64 have more than enough of both input and output lines?

C64
9 rows 0 through 8
9 columns A through I

PET
7 (or 8) rows (?) A through H (or J)
10 columns (?) 1 through 10

The C128 seems to be 8x11, so maybe an adapter for it would work.

> [keyboard TSR and/device driver for DOS]

Are you still interested in a DOS device driver when so
many keyboard adapters are available?

If so, you could look at :
  "Chapter 8. Writing an Installable Device Driver"
of IBM's "PC DOS 7 Technical Update" manual:
http://www.redbooks.ibm.com/redbooks/pdfs/gg244459.pdf


FYI, the C64 keyboard is just a matrix of input and output lines, where
the input lines are scanned one at a time.  I have a bunch packed up
in the basement somewhere...  If a key is pressed, an output line will
be active.  This usually requires one chip to decode a binary value to
a single line to implement scanning, and another chip with multiple
input lines which are read.  The first is a demultiplexer, e.g., a BCD
to decimal decoder or 1 of 8 decoder, etc.  The first chip is usually
fed by a few pins on a microprocessor with an incrementing output value.
A counter chip can also drive it.  The second is usually an addressable
latch, i.e., memory or I/O mapped with value readable by a microprocessor.
There are also standard logic chips for keyboard scanning for the chip
series Commodore used, e.g., 6526.


Rod Pemberton

[toc] | [prev] | [next] | [standalone]


#998

FromRuud Baltissen <rbaltissen@gmail.com>
Date2013-09-20 03:42 -0700
Message-ID<30441cb4-2bd7-45eb-9aba-3e27a91d8374@googlegroups.com>
In reply to#995
Hello Rod,


>  From a PET schematic, it appears the keyboard works similarly to the C64.

It depends how you define 'similar'. The C64 has an 8 * 8 matrix, the PET/CBM an incomplete 8 * 10 matrix. They are NOT interchangable.

 
> I'm surprised you're not familiar with these Ruud since ....

Of course I'm familiar with them. But the first three ones have an USB interface which, without a DOS driver, are worthless. And I even own a C= Key but I only want to use the CBM keyboard in DOS mode for the moment, parallel to the original one.

In fact I'm making my own keyboard adapter for later. I disassembled an IBM keyboard which has a 14 * 8 matrix (IIRC). Two possebilies:
- I connect the CBM keyboard directly and translate the output of the keyboard first.
- I rewire the CBM keyboard internally as good as possible. And then there is still some translating to do.
IMHO the LPT port hack is easier :)


> http://www.redbooks.ibm.com/redbooks/pdfs/gg244459.pdf

Thank you!


Kind regards, Ruud Baltissen
www.Baltissen.org

[toc] | [prev] | [next] | [standalone]


#1000

FromRoss Ridge <rridge@csclub.uwaterloo.ca>
Date2013-09-20 09:31 -0400
Message-ID<l1hin5$g21$1@rumours.uwaterloo.ca>
In reply to#998
Rod Pemberton writes:
>  From a PET schematic, it appears the keyboard works similarly to the C64.

Ruud Baltissen  <rbaltissen@gmail.com> wrote:
>It depends how you define 'similar'. The C64 has an 8 * 8 matrix,
>the PET/CBM an incomplete 8 * 10 matrix. They are NOT interchangable.

They're similar using the ordinary and usual meaning of the word.  
 
>> I'm surprised you're not familiar with these Ruud since ....
>
>Of course I'm familiar with them. But the first three ones have an USB
>interface which, without a DOS driver, are worthless. 

No, not if your motherboard supports USB keyboards, which most if not
all Pentium II era motherboards did. 

						Ross Ridge

-- 
 l/  //	  Ross Ridge -- The Great HTMU
[oo][oo]  rridge@csclub.uwaterloo.ca
-()-/()/  http://www.csclub.uwaterloo.ca/~rridge/ 
 db  //	  

[toc] | [prev] | [next] | [standalone]


#1001

From"Rod Pemberton" <dont_use_email@nohavenotit.com>
Date2013-09-20 15:07 -0400
Message-ID<op.w3p4rbid0e5s1z@localhost>
In reply to#998
On Fri, 20 Sep 2013 06:42:11 -0400, Ruud Baltissen <rbaltissen@gmail.com>  
wrote:

>> I'm surprised you're not familiar with these Ruud since ....
>
> Of course I'm familiar with them.  But the first three [won't work]

Well, you only need one interface that works, e.g., USB, PS/2, AT, XT.
It's likely there are other projects out there if you search for them.

I seem to recall one that connected to AT.  I thought it was in the
C= Hacking electronic magazine, but I couldn't locate it...

> But the first three ones have an USB interface which, without
> a DOS driver, are worthless.

Standard USB keyboards for IBM compatible PCs fallback to using the
PS/2 protocol on USB wiring when they don't receive a USB handshake.
This is so the USB to PS/2 adapters work.

Could that could be useful?

I.e., a USB keyboard supports both USB and PS/2 protocols but is
wired for USB.  That's why the purple USB keyboard to PS/2 adapters
work.  If you use the purple USB keyboard to PS/2 adapter and connect
to PS/2, then keyboard works as PS/2.  You could also rewire the USB
connector to PS/2 yourself.  PS/2 to AT adapters are available too.
They just change the wiring also.  The green USB mice to PS/2 adapters
work the same way, but the wiring is different, opposite.

It's probably unlikely that those projects use standard keyboard
circuitry that would support both USB and PS/2 modes.

> In fact I'm making my own keyboard adapter for later. I disassembled
> an IBM keyboard which has a 14 * 8 matrix (IIRC).
>
> Two [possabilities]:
> - I connect the CBM keyboard directly and translate the output
> of the keyboard first.

That seems reasonable.  Of course, all the encoding of keys will
be wrong since the matrix is different.

> - I rewire the CBM keyboard internally as good as possible.
> And then there is still some translating to do.

That possibly damages the keyboard and could result in wiring issues.

> IMHO the LPT port hack is easier.

The pins are there for it.  The logic isn't.  I.e., software.

Of course, a newer PC might not have an external LPT port.

RS232C/D is more than fast enough, but you need serializing
logic, e.g., UART etc, logic to adjust voltage levels,
scanning logic, etc.

USB will be available for a while, and hopefully PS/2 too.  Some
machines can't enter the BIOS in certain configurations without a
PS/2 keyboard, requiring a CMOS reset if one is not available.


Rod Pemberton

[toc] | [prev] | [next] | [standalone]


#1003

FromRoss Ridge <rridge@csclub.uwaterloo.ca>
Date2013-09-21 11:56 -0400
Message-ID<l1kfk9$6kf$1@rumours.uwaterloo.ca>
In reply to#1001
Rod Pemberton <dont_use_email@nohavenotit.com> wrote:
>Standard USB keyboards for IBM compatible PCs fallback to using the
>PS/2 protocol on USB wiring when they don't receive a USB handshake.
>This is so the USB to PS/2 adapters work.

While it used to be common for USB keyboards to also support the PS/2
keyboard interface using a simple passive adapter, this was never a
standard and is very rare today.  Most modern USB keyboards only support
USB and won't work with any of these old adapters (which were manufacturer
specific and not generally interchangabe).  

Of course it's possible that one of these C64 keyboard USB devices also
supports PS/2 connections through some sort of passive adapter, but I
would't assume so unless it's actually listed as a feature.

An active USB to PS/2 adapter, one that actively converts the USB protocol
to the PS/2 protocol, should work just fine however.  It would just then
be a matter modifying C64 keyboard to USB adapter to work with the PET
keyboard instead. 

				Ross Ridge

-- 
 l/  //	  Ross Ridge -- The Great HTMU
[oo][oo]  rridge@csclub.uwaterloo.ca
-()-/()/  http://www.csclub.uwaterloo.ca/~rridge/ 
 db  //	  

[toc] | [prev] | [next] | [standalone]


#1002

From"Bill Buckels" <bbuckels@mts.net>
Date2013-09-20 20:21 -0500
Message-ID<l1isc7$epg$1@speranza.aioe.org>
In reply to#992
"Ruud Baltissen" <rbaltissen@gmail.com> wrote:
>Any help/info is welcome!

Here's something that might help...  chop-out the parts you don't need and 
add the other parts you want to add. Assemble to a com file.

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 21h
        mov ah,2
        mov dl,7
        int 21h
MYEXIT:
      pop ds
      clc
      mov ah, 50h
      mov bx, theirpsp
      int 21h
TRUEXIT:
      mov     sp,bp
      pop     es
      pop     ds
      pop     di
      pop     si
      pop     bp
      pop     bx
      pop     bx
      pop     dx
      pop     cx
      pop     ax
      mov progress,0      ;ok! we're not saving...
      cli
      iret
printscreen endp


keypress      proc near
              cmp hotkeystat,0       ;already displayed?
              jne short_exit         ;yes, then exit immediately
              sti                    ;enable interrupts
              push ax                ;save registers
              push bx
              push cx
              push dx
              push si
              push di
              push ds
              push es
              in al,kb_data                 ;get scan code from keyboard
              cmp al,period                 ;was the period pressed?
              jne exit                      ;no, then exit to normal routine
              mov ah,2                      ;get state of shift keys
              int 16h
              test al,alt_key               ;is the Alt key depressed?
              jne startup                   ;yes, then continue

;Exit is achieved thru here when execution is to be
;transferred to the normal
;BIOS keyboard interrupt handling routine.

exit:         pop es                 ;restore registers
              pop ds
              pop di
              pop si
              pop dx
              pop cx
              pop bx
              pop ax
short_exit:   jmp old_int_9h         ;goto BIOS keyboard routine

;The key combination Alt-Period was just pressed.
;Reset the keyboard and issue an
;EOI to the 8259 PIC to enable hardware interrupts.

startup:      call kb_reset          ;reset keyboard, end 8259 int
              push cs                ;set DS and ES to the code segment
              pop ds
              push cs
              pop es
              assume ds:code

;Check the current video mode to see if it's 80-column text mode 3
;If it's not, gracefully abort this
;routine by exiting thru an IRET.
;Set the interrupt routine status flag and
;Save the contents of the portion of the screen
;that will underlie the input field.
;Wait for a keypress.

              mov ah,15           ;get display mode
              int 10h
              cmp al,3            ;mode 3?
              jne done            ;yes, then continue
              mov hotkeystat,1    ;set interrupt routine status flag
              mov fcnt1,'0'       ;reset the counters
              mov fcnt2,'0'
              call open_screen    ;save screen contents

getaction:    mov ah,0            ;get a keypress
              int 16h
              cmp al,0            ;is it an extended code?
              je getaction        ;yes, then ignore
              cmp al,13           ;Enter key pressed?
              je do_done          ;no, then process
              cmp al,8            ;backspace pressed
              je process          ;allow only alpha-numeric input
              cmp al,'z'
              ja getaction
              cmp al,'a'
              jae process
              cmp al,'Z'
              ja getaction
              cmp al,'A'
              jae process
              cmp al,'9'
              ja getaction
              cmp al,'0'
              jb getaction
process:
              call update
              jmp getaction

;The Enter Key has been pressed.
;Restore the original contents of the screen,
;reset the status flag, and exit to the application.

do_done:
              call close_screen    ;restore video memory contents
              mov hotkeystat,0     ;reset status flag
done:         pop es               ;restore register values for exit
              pop ds
              pop di
              pop si
              pop dx
              pop cx
              pop bx
              pop ax
              iret           ;return to interrupted program
keypress      endp

;KB_RESET resets the keyboard and issues an EOI to the 8259 PIC.
kb_reset      proc near
              in al,kb_ctrl                 ;get current control port value
              mov ah,al                     ;save it in AH
              or al,80h                     ;set bit 7
              out kb_ctrl,al                ;send reset value
              mov al,ah                     ;get original value
              out kb_ctrl,al                ;send it out to enable keyboard
              cli                           ;suspend interrupts
              mov al,eoi                    ;get EOI value
              out int_ctrl_port,al          ;send EOI to 8259
              sti                           ;enable interrupts
              ret
kb_reset      endp

;call from keyboard handler to update the field
;and the screen as required
update proc near
      push es
      push ds
      push ax
      push bx
      push dx
      push si
      push di

      push cs
      pop ds

      cmp  al, 8            ;backspace... push everything back
      jne  normal           ;no? then insert a character
      cmp  vid_ctr,0        ;first character? don't allow underflow!
      jle  keydone          ;skip it!

      dec  vid_ctr
      lea  dx, buff
      mov  di, dx
      mov bx,vid_ctr
      shl bx,1
      mov si,bx
      add di,si

reverse:                     ;pull the current character out
       add  di,2
       mov  al,BYTE PTR ds:[di]
       sub  di,2
       mov  BYTE PTR ds:[di],al
       add  di,2
       add  si,2
       cmp  si,24
       jl  reverse

       jmp  keyupdate        ;display the shorter field

normal:
       cmp vid_ctr,5         ;6-character limit
       jg keydone            ;skip it!
       push ax               ;save the character
       lea  dx, buff
       mov  di, dx
       mov bx,vid_ctr
       shl bx,1
       mov si,bx
       add si,14
       add di,si

forward:                     ;make a space for the character

       mov  al,BYTE PTR ds:[di]
       add  di,2
       mov  BYTE PTR ds:[di],al
       sub  di,4
       sub  si,2
       cmp  si,bx
       jne  forward

       pop  ax                  ;pop the character and insert it.
       mov  BYTE PTR ds:[di],al
       inc vid_ctr

keyupdate:
      lea  dx, buff            ;point to the field
      mov  di, dx
      mov  es, video_seg       ;point to the screen
      xor  si,si

keydo:
      mov  al,BYTE PTR ds:[di] ; display the entry field
      mov  BYTE PTR es:[si],al ; all 24 characters
      inc di
      inc si
      cmp si,48
      jl keydo
keydone:

      pop di
      pop si
      pop dx
      pop bx
      pop ax
      pop ds
      pop es
      ret
update endp

close_screen proc near
      push es
      push ds
      push ax
      push dx
      push si
      push di

      push cs
      pop  ds
      lea  dx, screenbuffer
      mov  di, dx
      mov  es, video_seg
      xor  si,si

closeit:
      mov  al, BYTE PTR ds:[di] ; restore the screen
      mov  BYTE PTR es:[si],al
      inc di
      inc si
      cmp si,48
      jl closeit

      pop di
      pop si
      pop dx
      pop ax
      pop ds
      pop es
      ret
close_screen endp

open_screen proc near
      push es
      push ds
      push ax
      push dx
      push si
      push di

      push cs
      pop  ds
      lea  dx, screenbuffer
      mov  di, dx
      mov  es, video_seg
      xor  si,si

open1:
      mov  al, BYTE PTR es:[si] ; save the screen
      mov  BYTE PTR ds:[di],al
      inc di
      inc si
      cmp si,48
      jl open1

      lea  dx, buff
      mov  di,dx
      xor  si,si

open2:
      mov  al,BYTE PTR ds:[di] ; display the entry field
      mov  BYTE PTR es:[si],al
      inc di
      inc si
      cmp si,48
      jl open2

      pop di
      pop si
      pop dx
      pop ax
      pop ds
      pop es
      ret
open_screen endp

;------------------------------------------------------------
;         RESIDENT PORTION ENDS *** TRANSIENT PORTION STARTS
;------------------------------------------------------------

TITLE$  db 'ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»',13,10
        db 'º  GRABSV(C) Copyright by Bill Buckels 1993,1996 º',13,10
        db 'º  A Memory Resident Text-Screen Frame-Grabber   º',13,10
        db 'º                                                º',13,10
        db 'º  Press Shift-Print Screen to Save Text Images  º',13,10
        db 'º  Text Screens will be saved in BSAVED Format   º',13,10
        db 'º                                                º',13,10
        db 'º  Press Alt-Period To Over-ride Image Name      º',13,10
        db 'ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ'
TERM$   db 32  ; replace with a terminator
db  13,10
db 'Disclaimer: Although due care and caution is exercised by GRABSV(C),'
db  13,10
db 'Conflicts may arise when used with some programs or other TSRs.'
db  13,10
db 'This is also true with any TSR, especially those that write to disk.'
db  13,10
db 'Warning!!! Do Not Load More than 1 copy. The Installation check has 
been'
db  13, 10
db 'Removed for this version...'
db 13, 10
db 'Bill Buckels will not be held responsible for loss or damage caused by'
db  13,10
db 'the use of this program. Do you wish to continue ? (Y/N) $'

DUPE$    db 10,13,7,'GRABSV(C) is already installed!$'
NOWLOAD$ db 10,13,'GRABSV(C) is Now Resident!'
NICEDOS$ db 10,13,1,2,'Have a Nice Dos!$'

NEEDCGA$ db 'ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»',13,10
         db 'º  GRABSV(C) Copyright by Bill Buckels 1993,1996 º',13,10
         db 'º  A Memory Resident Text-Screen Frame-Grabber   º',13,10
         db 'ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ',13,10
         db 'A CGA Compatible Video Adapter is Required to Use 
GRABBSV(C)',13,10
         db 'It must be in 80 x 25 Text Mode...$'

;LIST$ writes a string to stdout
LIST$ proc near
      mov ah,9h ; call dos function 9H
      int 21h
      ret
LIST$ endp

;exit if the answer is no!
YESNO$ proc near
       mov ah,15           ;get display mode
       int 10h
       cmp al,3            ;mode 3?
       jne notcga          ;yes, then continue

       ;; removed the installation check
       ;; this causes some pentiums and PS2 compatible bios to hang
       ;; les     bx,DWORD PTR _installed    ;are we already installed
       ;; cmp     BYTE PTR es:[bx],128       ;if so we leave
       ;; je      installed

       lea dx, TITLE$
       call LIST$
       mov ah,1
       int 21h
       cmp al,'Y'
       je agree
       cmp al,'y'
       je agree
       lea dx,NICEDOS$
       call LIST$
       int 20h
notcga:
       lea dx, NEEDCGA$
       call LIST$
       lea dx, NICEDOS$
       call LIST$
       int 20h
installed:
       mov TERM$,'$'
       lea dx, TITLE$
       call LIST$
       lea dx, DUPE$
       call LIST$
       lea dx, NICEDOS$
       call LIST$
       int 20h
agree:
       lea dx, NOWLOAD$
       call LIST$
       ;; removed the installation check
       ;; this causes some pentiums and PS2 compatible bios to hang
       ;; mov     al, 128
       ;; les     bx,DWORD PTR _installed    ;installed signature
       ;; mov     BYTE PTR es:[bx],al
       ret
YESNO$ endp

;INITIALIZE performs tasks to set the stage for the resident part
;of the program.

initialize proc near

;let them know who we are

         call YESNO$

         ;prepare for context switching
         ;save our psp
         mov ah, 51h
         int 21h
         mov ourpsp,bx

         ;get the address of the dos busy flag
         mov ah, 34h
         int 21h
         mov dos_seg,es
         mov indos,bx

         ;save keyboard
         mov ah,35h              ;get current interrupt 9 vector
         mov al,9
         int 21h
         mov old_keyboard_int,bx       ;save vector offset
         mov old_keyboard_int[2],es    ;save vector segment
         ; save dos idle
         mov ah,35h               ;get current interrupt 28h vector
         mov al,28h
         int 21h
         mov old_dos_int,bx       ;save vector offset
         mov old_dos_int[2],es    ;save vector segment
         ; save timer tick
         mov ah,35h               ;get current interrupt 1ch vector
         mov al,1ch
         int 21h
         mov old_timer_int,bx     ;save vector offset
         mov old_timer_int[2],es  ;save vector segment

         mov ah,25h               ;set new printscreen vectors
         mov al,5
         lea dx,printscreen       ;point it to new handler
         int 21h
         ;save the address of the printscreen vectors
         mov ah, 35h
         mov al, 5
         int 21h
         mov pseg,es
         mov poff,bx

         mov ah,25h                ;set new keyboard vectors
         mov al,9
         lea dx,keypress           ;point it to new handler
         int 21h
         mov ah,25h                ;set new dos idle vectors
         mov al,28h
         lea dx,newdos             ;point it to new handler
         int 21h
         mov ah,25h                ;set new timertick vectors
         mov al,1ch
         lea dx,timertick          ;point it to new handler
         int 21h


;Exit thru INT 27h and reserve some room
;the offset of TITLE$ is a marker to end of resident code

           mov dx,offset TITLE$            ;reserve space for code
           int 27h                         ;terminate-but-stay-resident
initialize    endp

code          ends
              end begin


[toc] | [prev] | [standalone]


Back to top | Article view | comp.os.msdos.programmer


csiph-web