Subject: CBREAK mode in MS-DOS ==== SAMPLE CODE ====
From: [email-masked] (Joe Bormel)
Date: 21 Dec 1993 22:58:51 GMT
Newsgroups: comp.lang.perl

Thanks to everyone who responded to my plea for help to get CBREAK
functionality in PERL for MS-DOS.  I've packaged up the results into
an executable DOS batch file to serve as sample code for others.
--------cut here and place in a file named keybd.bat---type: keybd at c>
@REM=(qq!
@perl %0.bat %1 %2 %3 %4 %5 %6 %7 %8 %9
@goto end !) if 0 ;

# Name: 	keybd.bat
# Purpose:	MS-DOS program to demonstrate entering 'CBREAK' mode
#		and see keystrokes as they happen instead of a line
#		at a time after the ENTER key had been pressed.
# Source:	Source modified from usenet posting:
#		  original by Dan Carson - [email-masked]
#		  generously re-posted by Bill Middleton - [email-masked]
#		  ANSI keycode elaboration, subroutine packaging and
#		  sample code by Joe Bormel - [email-masked]
# Date:		1993
# Note:         This will not work with BPERL because:
#     * The ioctl() is not supported because of problems translating data
#       structures between real and protected modes in BPERL.  It does work
#	with PERL v4.0 patchlevel 36/ header below:]
#
#
#  $RCSfile: perl.c,v $$Revision: 4.0.1.8 $$Date: 1993/02/05 19:39:30 $
#  Patch level: 36
#
#  Copyright (c) 1989, 1990, 1991, Larry Wall
#  MS-DOS port Copyright (c) 1989, 1990, Diomidis Spinellis.
#
#  It is ftp'able as bin4036.zip (148,895 bytes).
#
# Bugs/Peculiarities:  You had to press ENTER or control/M twice to get
# it to register once.
#-------------------------------------------------------------------------

&keymap_table;		# Instantiate assoc array of keyboard mappings.
&raw;

print "Demonstration showing: &raw, &getkey, &cooked.\n";
print "  Exit by typing control/Z\n";

while($c ne "0;0"){
  $c= &getkey;
  print "<$c>" if ord($c) != 0;

}
&cooked;
#-------------------------------------------------------------------------
sub raw {
  $old_ioctl = ioctl(STDIN,0,0);     # Gets device info
  $old_ioctl &= 0xff;
  ioctl(STDIN,1,$old_ioctl | 32);    # Writes it back, setting bit 5
}
#-------------------------------------------------------------------------
sub cooked {
  ioctl(STDIN,1,$old_ioctl);         # Sets PC back to cooked mode.
}
#-------------------------------------------------------------------------
sub getkey {
  local($key,$td,$val);
  sysread(STDIN,$key,1);             # Read a single character
  $val = ord($key);
  return $key if $val>=32;           # Return simple typewriter keys.

  if ($val == 0) {	             # handle 2 code keys.
    sysread(STDIN,$key2,1);          # Read the second character.
    $td  = "0;" . ord($key2);
    if (defined $KBMap{$td}) {
             $key = $KBMap{$td};
    } else { $key = $td;}
  } elsif ($val < 32) {
    $key = "Ctrl+" . pack("c",$val+64);
  }
  $key;
}
#-------------------------------------------------------------------------
sub keymap_table {
    ## Load an associative array with names for keycodes ##

  # Note that the function key mapping is done below.  If you need
  # any other keys, this program will show you what the codes coming
  # back from your keyboard really are.  Below is a listing of how
  # the ANSI codes are defined.  Just follow the format of the function
  # key definitions, e.g.   $KBMap{"0;61"} = "F3"; to add any others you need.

  @Embedded_Documentation=(qq~

   +======================================================================+
   | Key           Key        Shft+Key        Ctrl+Key        Alt+Key     |
   +======================================================================+
   | F1            0;59       0;84            0;94            0;104       |
   | F2            0;60       0;85            0;95            0;105       |
   | F3            0;61       0;86            0;96            0;106       |
   | F4            0;62       0;87            0;97            0;107       |
   | F5            0;63       0;88            0;98            0;108       |
   | F6            0;64       0;89            0;99            0;109       |
   | F7            0;65       0;90            0;100           0;110       |
   | F8            0;66       0;91            0;101           0;111       |
   | F9            0;67       0;92            0;102           0;112       |
   | F10           0;68       0;93            0;103           0;113       |
   | F11           0;133      0;135           0;137           0;139       |
   | F12           0;134      0;136           0;138           0;140       |
   | Kp-Home       0;71       55              0;119                       |
   | Kp-UpArrow    0;72       56              0;141   (Note: Kp = keypad  |
   | Kp-PgUp       0;73       57              0;132               key with|
   | Kp-LftArrow   0;75       52              0;115               NumLock |
   | Kp-RtArrow    0;77       54              0;116               on)     |
   | Kp-End        0;79       49              0;117                       |
   | Kp-DnArrow    0;80       50              0;145                       |
   | Kp-PgDn       0;81       51              0;118                       |
   | Kp-Insert     0;82       48              0;146                       |
   | Kp-Delete     0;83       46              0;147                       |
   | Home          224;71     224;71          224;119         224;151     |
   | UpArrow       224;72     224;72          224;141         224;152     |
   | PgUp          224;73     224;73          224;132         224;153     |
   | LftArrow      224;75     224;75          224;115         224;155     |
   | RtArrow       224;77     224;77          224;116         224;157     |
   | End           224;79     224;79          224;117         224;159     |
   | DnArrow       224;80     224;80          224;145         224;160     |
   | PgDn          224;81     224;81          224;118         224;161     |
   | Insert        224;82     224;82          224;146         224;162     |
   | Delete        224;83     224;83          224;147         224;163     |
   | PrtScreen                                0;114                       |
   | Pause/Break                              0;0                         |
   | Backspace     8          8               127             0;14        |
   | Enter         13         13              10              0;28        |
   | Tab           9          0;15            0;148           0;165       |
   +======================================================================+
   | Key           Key        Shft+Key        Ctrl+Key        Alt+Key     |
   +======================================================================+
   | A             97         65              1               0;30        |
   | B             98         66              2               0;48        |
   | C             99         67              3               0;46        |
   | D             100        68              4               0;32        |
   | E             101        69              5               0;18        |
   | F             102        70              6               0;33        |
   | G             103        71              7               0;34        |
   | H             104        72              8               0;35        |
   | I             105        73              9               0;23        |
   | J             106        74              10              0;36        |
   | K             107        75              11              0;37        |
   | L             108        76              12              0;38        |
   | M             109        77              13              0;50        |
   | N             110        78              14              0;49        |
   | O             111        79              15              0;24        |
   | P             112        80              16              0;25        |
   | Q             113        81              17              0;16        |
   | R             114        82              18              0;19        |
   | S             115        83              19              0;31        |
   | T             116        84              20              0;20        |
   | U             117        85              21              0;22        |
   | V             118        86              22              0;47        |
   | W             119        87              23              0;17        |
   | X             120        88              24              0;45        |
   | Y             121        89              25              0;21        |
   | Z             122        90              26              0;44        |
   +======================================================================+
   | Key           Key        Shft+Key        Ctrl+Key        Alt+Key     |
   +======================================================================+
   | 1             49         33                              0;120       |
   | 2             50         64                              0;121       |
   | 3             51         35                              0;122       |
   | 4             52         36                              0;123       |
   | 5             53         37                              0;124       |
   | 6             54         94              30              0;125       |
   | 7             55         38                              0;126       |
   | 8             56         42                              0;127       |
   | 9             57         40                              0;128       |
   | 0             48         41                              0;129       |
   | -             45         95              31              0;130       |
   | =             61         43                              0;131       |
   | [             91         123             27              0;26        |
   | \             92         124             28              0;43        |
   | ]             93         125             29              0;27        |
   | ;             59         58                              0;39        |
   | '             39         34                              0;40        |
   | ,             44         60                              0;51        |
   | .             46         62                              0;52        |
   | /             47         63                              0;53        |
   | Kp-Enter      13         13              10              0;166       |
   | Kp- /         47         47              0;149           0;164       |
   | Kp- *         42         42              0;150           0;55        |
   | Kp- -         45         45              0;142           0;74        |
   | Kp- +         43         43              0;144           0;78        |
   | Kp- 5         0;76       53              0;143                       |
   +======================================================================+

  ~) if 0 ; # End of:  @Embedded_Documentation

  $KBMap{"0;59"} = "F1";
  $KBMap{"0;60"} = "F2";
  $KBMap{"0;61"} = "F3";
  $KBMap{"0;62"} = "F4";
  $KBMap{"0;63"} = "F5";
  $KBMap{"0;64"} = "F6";
  $KBMap{"0;65"} = "F7";
  $KBMap{"0;66"} = "F8";
  $KBMap{"0;67"} = "F9";
  $KBMap{"0;68"} = "F10";
  $KBMap{"0;133"} = "F11";
  $KBMap{"0;134"} = "F12";

  $KBMap{"0;84"} = "Shft+F1";
  $KBMap{"0;85"} = "Shft+F2";
  $KBMap{"0;86"} = "Shft+F3";
  $KBMap{"0;87"} = "Shft+F4";
  $KBMap{"0;88"} = "Shft+F5";
  $KBMap{"0;89"} = "Shft+F6";
  $KBMap{"0;90"} = "Shft+F7";
  $KBMap{"0;91"} = "Shft+F8";
  $KBMap{"0;92"} = "Shft+F9";
  $KBMap{"0;93"} = "Shft+F10";
  $KBMap{"0;135"} = "Shft+F11";
  $KBMap{"0;136"} = "Shft+F12";

  $KBMap{"0;94"} = "Ctrl+F1";
  $KBMap{"0;95"} = "Ctrl+F2";
  $KBMap{"0;96"} = "Ctrl+F3";
  $KBMap{"0;97"} = "Ctrl+F4";
  $KBMap{"0;98"} = "Ctrl+F5";
  $KBMap{"0;99"} = "Ctrl+F6";
  $KBMap{"0;100"} = "Ctrl+F7";
  $KBMap{"0;101"} = "Ctrl+F8";
  $KBMap{"0;102"} = "Ctrl+F9";
  $KBMap{"0;103"} = "Ctrl+F10";
  $KBMap{"0;137"} = "Ctrl+F11";
  $KBMap{"0;138"} = "Ctrl+F12";

  $KBMap{"0;104"} = "Alt+F1";
  $KBMap{"0;105"} = "Alt+F2";
  $KBMap{"0;106"} = "Alt+F3";
  $KBMap{"0;107"} = "Alt+F4";
  $KBMap{"0;108"} = "Alt+F5";
  $KBMap{"0;109"} = "Alt+F6";
  $KBMap{"0;110"} = "Alt+F7";
  $KBMap{"0;111"} = "Alt+F8";
  $KBMap{"0;112"} = "Alt+F9";
  $KBMap{"0;113"} = "Alt+F10";
  $KBMap{"0;139"} = "Alt+F11";
  $KBMap{"0;140"} = "Alt+F12";

}

@REM=(qq!
:end !) if 0 ;