home *** CD-ROM | disk | FTP | other *** search
/ Frostbyte's 1980s DOS Shareware Collection / floppyshareware.zip / floppyshareware / VORX / EM15DM11.ARC / IBM.ASM < prev    next >
Assembly Source File  |  1989-08-18  |  25KB  |  1,156 lines

  1. ;ibm.asm - last modified Fri Aug 18 23:00:56 1989 PDT - mbf
  2. ;History:3,1
  3. ;Tue Aug 01 01:36:27 1989  Added cc primitive for setting cursor type (lines
  4. ;    798-814; see also emacs.asm) [mbf]
  5. ;Thu May 25 23:36:48 1989 Added bp variable (0..1) for toggling beep timeout
  6. ;    (lines 322, 710-18, 723; see also emacs.asm) [mbf]
  7. ;Wed May 24 14:46:14 1989 Added xychrout_ins to display 00h as a reverse video
  8. ;    '@' (lines 1018-19, 1040-48) [mbf]
  9. ;Mon May 22 22:53:38 1989 Fixed control character display problem; to display
  10. ;    ctrl chars in reverse video or bold, uncomment the appropriate code
  11. ;    (reverse video: 1027-33; bold: 1035, 1051); also made ctrl chars
  12. ;    display in actual ascii representation (i.e., ctrl-z now displays as a
  13. ;    right arrow, not a Z) 1037 [mbf]
  14. ;Sat May 20 19:34:33 1989 Changed uninit_exit_1 to cls to first, rather than
  15. ;    last, line on exiting emacs (lines 499) [mbf]
  16. ;Sat May 20 19:18:41 1989 Changed visi space to 0b1h (from 07h) and visi tab
  17. ;    to 0b0h (from 04h) (lines 306-7) [mbf]
  18. ;08-25-88 23:37:09 Create two new keycodes, "C- " and "M- ".
  19. ;05-30-88 22:27:44 fix a small problem in save/restore screen
  20. ;05-29-88 22:49:48 try getting the attributes from lower left.
  21. ;05-29-88 22:42:39 get the attributes from the lower right corner rather than upper right.
  22. ;05-27-88 23:25:34 fix a problem in putch where it put garbage characters up.
  23. ;05-27-88 00:09:00 read_ibm_cga sometimes gets called with ds=bufseg, not data.
  24. ;05-27-88 00:07:02 move_line didn't respect ibm_cga flag--it was always set.
  25. ;05-17-88 20:33:20 Add support for hardware scrolls (should work for all displays) [kdb]
  26. ;05-17-88 20:02:45 Make move_line wait while reading cga screen [kdb]
  27. ;05-17-88 19:35:35 Remove all reference to scrwait function [kdb]
  28. ;05-17-88 19:03:22 Macroize scrwait for single char [kdb]
  29. ;05-15-88 19:16:51 add scrwait in scrolls [kdb]
  30. ;05-15-88 18:58:45 Make move_line wait for each character [kdb]
  31. ;05-07-88 22:07:59 implement a swap_screen_flag.
  32. ;05-03-88 23:54:55 add more extended keys.
  33. ;04-17-88 19:22:28 add some extended keycodes.
  34. ;04-16-88 13:13:01 add extended keyboard support.
  35. ;04-14-88 22:51:58 If ibm_cga, don't store_debug.
  36. ;04-01-88 23:08:28 respond to mouse keys with M-, S-, and C-
  37. ;03-31-88 22:02:25 use C-break for the break character (duh)
  38. ;03-28-88 19:19:14 just clear the screen on a MDA.
  39. ;03-28-88 19:09:19 don't save and restore video memory on an MDA.
  40. ;03-28-88 18:28:50 remove block_cursor and under_cursor
  41. ;03-26-88 21:59:07 change back to bios calls to read the keyboard.
  42. ;03-24-88 00:02:13 add fore_original and back_original.
  43. ;02-21-88 12:24:50 make control be bright, meta inverse video.
  44. ;02-13-88 18:22:56 use the 18.2 ms timer tick to time the beep.
  45. ;02-13-88 16:43:45 don't map Timeout using M-, C-, or S-
  46. ;12-07-87 20:07:29 add store_debug
  47. ;12-05-87 11:23:35 make the color default to the current color.
  48. ;12-05-87 11:20:13 clear the screen on init_entry.
  49. ;12-05-87 11:16:53 save dos's screen and restore it when finished.
  50. ;07-05-87 22:14:22 caps lock shouldn't apply to M- and C- keys.
  51.     page    ,132
  52.  
  53. comment /
  54.  
  55.     Porting EMACS and Percival to MS-DOS computers other than the Z-100:
  56.  
  57. This entire file (Z-100.ASM) needs to be re-written, since it contains
  58. all the Z-100 dependencies.  The following conventions must be maintained:
  59.   1) Never leave this module with DF=1.
  60.   2) Never destroy ES.
  61.   3) Never MOV AX,DATA, always use the copy in the appropriate segment register.
  62.   4) Return NC if a routine succeeds, or fulfills its goals.
  63.  
  64. /
  65.     .xlist
  66.     include    memory.def
  67.  
  68.  
  69. data    segment    byte public
  70.  
  71.     public    max_screen_line
  72. max_screen_line    db    22    ;number of last text row on screen.
  73.  
  74.     public    num_screen_cols
  75. num_screen_cols    db    ?
  76.     db    0            ;in case they access it as a word.
  77.  
  78.     public    fore_original, back_original
  79. fore_original    db    ?
  80. back_original    db    ?
  81.  
  82.  
  83.     public    scan_lines_per_char
  84. scan_lines_per_char    db    8
  85.  
  86.     public    computer_name, computer_name_len
  87. computer_name    db    'IBM-PC'
  88. computer_name_len    equ    $-computer_name
  89.  
  90.     public    swap_screen_flag
  91. swap_screen_flag    dw    1    ;=1 if we should swap screens.
  92.  
  93. old_cursor    dw    ?        ;old cursor position from the swapped
  94.                     ;  screen.
  95.  
  96. key_names    label    byte
  97.     db    ',','Comma',0
  98.     db    '(','LPar',0
  99.     db    ')','RPar',0
  100.     db    7fh,'Delete',0
  101.  
  102.     db    -1,'Timeout',0
  103.     db    -2,'Left Down',0        ;mouse button key names.
  104.     db    -3,'Right Down',0
  105.     db    -4,'Left Up',0
  106.     db    -5,'Right Up',0
  107.     db    -6,'Middle Down',0
  108.     db    -7,'Middle Up',0
  109.     db    0
  110.  
  111.  
  112. key_others    label    byte
  113.     db    14,'Back Space',0
  114.     db    15,'Tab',0
  115.     db    28,'Return',0
  116.     db    1,'Escape',0
  117.     db    0
  118.  
  119. key_special    label    byte
  120.     db    127,'C-Back Space',0
  121.     db    10,'C-Return',0
  122.     db    0
  123.  
  124. key_table    label    byte
  125.     db    1,'M-Esc',0        ;extended
  126.     db    3,'C-@',0
  127.     db    14,'M-Back Space',0    ;extended
  128.     db    15,'S-Tab',0
  129.     db    16,'M-q',0
  130.     db    17,'M-w',0
  131.     db    18,'M-e',0
  132.     db    19,'M-r',0
  133.     db    20,'M-t',0
  134.     db    21,'M-y',0
  135.     db    22,'M-u',0
  136.     db    23,'M-i',0
  137.     db    24,'M-o',0
  138.     db    25,'M-p',0
  139.     db    26,'M-{',0        ;extended
  140.     db    27,'M-}',0        ;extended
  141.     db    28,'M-Return',0        ;extended
  142.     db    30,'M-a',0
  143.     db    31,'M-s',0
  144.     db    32,'M-d',0
  145.     db    33,'M-f',0
  146.     db    34,'M-g',0
  147.     db    35,'M-h',0
  148.     db    36,'M-j',0
  149.     db    37,'M-k',0
  150.     db    38,'M-l',0
  151.     db    39,'M-;',0        ;extended
  152.     db    40,"M-'",0        ;extended
  153.     db    41,'M-`',0        ;extended
  154.     db    43,'M-\',0        ;extended
  155.     db    44,'M-z',0
  156.     db    45,'M-x',0
  157.     db    46,'M-c',0
  158.     db    47,'M-v',0
  159.     db    48,'M-b',0
  160.     db    49,'M-n',0
  161.     db    50,'M-m',0
  162.     db    51,'M-Comma',0        ;extended
  163.     db    52,'M-.',0        ;extended
  164.     db    53,'M-/',0        ;extended
  165.     db    55,'M-Asterisk',0
  166.     db    59,'F1',0
  167.     db    60,'F2',0
  168.     db    61,'F3',0
  169.     db    62,'F4',0
  170.     db    63,'F5',0
  171.     db    64,'F6',0
  172.     db    65,'F7',0
  173.     db    66,'F8',0
  174.     db    67,'F9',0
  175.     db    68,'F10',0
  176.     db    71,'Home',0
  177.     db    72,'Up Arrow',0
  178.     db    73,'Pg Up',0
  179.     db    74,'M-Minus',0
  180.     db    75,'Left Arrow',0
  181.     db    76,'Five',0
  182.     db    77,'Right Arrow',0
  183.     db    78,'M-Plus',0
  184.     db    79,'End',0
  185.     db    80,'Down Arrow',0
  186.     db    81,'Pg Dn',0
  187.     db    82,'Ins',0
  188.     db    83,'Del',0
  189.     db    84,'S-F1',0
  190.     db    85,'S-F2',0
  191.     db    86,'S-F3',0
  192.     db    87,'S-F4',0
  193.     db    88,'S-F5',0
  194.     db    89,'S-F6',0
  195.     db    90,'S-F7',0
  196.     db    91,'S-F8',0
  197.     db    92,'S-F9',0
  198.     db    93,'S-F10',0
  199.     db    94,'C-F1',0
  200.     db    95,'C-F2',0
  201.     db    96,'C-F3',0
  202.     db    97,'C-F4',0
  203.     db    98,'C-F5',0
  204.     db    99,'C-F6',0
  205.     db    100,'C-F7',0
  206.     db    101,'C-F8',0
  207.     db    102,'C-F9',0
  208.     db    103,'C-F10',0
  209.     db    104,'M-F1',0
  210.     db    105,'M-F2',0
  211.     db    106,'M-F3',0
  212.     db    107,'M-F4',0
  213.     db    108,'M-F5',0
  214.     db    109,'M-F6',0
  215.     db    110,'M-F7',0
  216.     db    111,'M-F8',0
  217.     db    112,'M-F9',0
  218.     db    113,'M-F10',0
  219.     db    114,'C-PrtSc',0
  220.     db    115,'C-Left Arrow',0
  221.     db    116,'C-Right Arrow',0
  222.     db    117,'C-End',0
  223.     db    118,'C-Pg Dn',0
  224.     db    119,'C-Home',0
  225.     db    120,'M-1',0
  226.     db    121,'M-2',0
  227.     db    122,'M-3',0
  228.     db    123,'M-4',0
  229.     db    124,'M-5',0
  230.     db    125,'M-6',0
  231.     db    126,'M-7',0
  232.     db    127,'M-8',0
  233.     db    128,'M-9',0
  234.     db    129,'M-0',0
  235.     db    130,'M--',0
  236.     db    131,'M-=',0
  237.     db    132,'C-Pg Up',0
  238. ;all of the following are extended.
  239.     db    133,'F11',0
  240.     db    134,'F12',0
  241.     db    135,'S-F11',0
  242.     db    136,'S-F12',0
  243.     db    137,'C-F11',0
  244.     db    138,'C-F12',0
  245.     db    139,'M-F11',0
  246.     db    140,'M-F12',0
  247.     db    141,'C-Up Arrow',0
  248.     db    142,'C-Minus',0
  249.     db    143,'C-Five',0
  250.     db    144,'C-Plus',0
  251.     db    145,'C-Down Arrow',0
  252.     db    146,'C-Ins',0
  253.     db    147,'C-Del',0
  254.     db    148,'C-Tab',0
  255.     db    149,'C-Slash',0
  256.     db    150,'C-Asterisk',0
  257.     db    151,'M-Home',0
  258.     db    152,'M-Up Arrow',0
  259.     db    153,'M-Pg Up',0
  260.     db    155,'M-Left Arrow',0
  261.     db    157,'M-Right Arrow',0
  262.     db    159,'M-End',0
  263.     db    160,'M-Down Arrow',0
  264.     db    161,'M-Pg Dn',0
  265.     db    162,'M-Ins',0
  266.     db    163,'M-Del',0
  267.     db    164,'M-Slash',0
  268.     db    165,'M-Tab',0
  269.     db    166,'M-Return',0
  270.     db    167,'C- ',0
  271.     db    168,'M- ',0
  272.  
  273. ;    db    224,'Slash',0
  274. ;    db    224,'Return',0
  275.  
  276.     db    0,'Unknown',0
  277.  
  278.  
  279. one_key_string    db    ?,0
  280. ctrl_key_string    db    'C-'
  281. ctrl_key_char    db    ?,0
  282.  
  283. left_flag    equ    1
  284. right_flag    equ    2
  285. ctrl_flag    equ    4
  286. alt_flag    equ    8
  287. all_flags    equ    left_flag + right_flag + ctrl_flag + alt_flag
  288. shift_flags    db    ?
  289.  
  290. bios_seg    segment at 40h
  291.     org    17h
  292. bios_shifts    db    ?
  293. bios_seg    ends
  294.  
  295.  
  296. key_buffer    label    byte        ;this is where we put the ASCII
  297.     db    26 dup(?)        ;  representation of the key.
  298.  
  299.  
  300.     extrn    inversing: word        ;if we're inverse videoing.
  301.  
  302.     public    color
  303. color    db    0fh            ;xbbbifff bbb=background, ifff=fore.
  304.  
  305. font_8_table    label    byte
  306.     db    0b1h            ;visi space; mbf: was 007h
  307.     db    0b0h            ;visi tab; mbf: was 004h
  308.     db    ?            ;del
  309.     db    ?            ;eof
  310.     db    ?            ;visi newline
  311.     db    01ah            ;visi rgt mrgn
  312.     db    ?            ;random char.
  313.     db    01fh            ;visible newline.
  314.  
  315. ibm_cga    db    0            ;=0 if we can write to screen anytime,
  316.                     ;=1 if we should wait for retrace.
  317. have_ega    db    0        ;=0 if we don't have an EGA.
  318.  
  319. int_16_input    db    0        ;function code for keyboard input
  320. int_16_status    db    1        ;function code for keyboard status
  321.  
  322. dobeep        db    0        ;beep toggle variable [mbf]
  323.  
  324. data    ends
  325.  
  326.  
  327. code    segment    byte public
  328.     assume    cs:code, ds:data, es:nothing
  329. ;all of the code in this segment is called with the above assumes.
  330.  
  331. break_flag    db    ?
  332.  
  333. their_1b    dd    ?
  334. our_1b:
  335.     mov    cs:break_flag,1
  336.     iret
  337.  
  338.  
  339.     public    init_entry
  340. init_entry:
  341.     push    es            ;get their C-break.
  342.     mov    ax,351bh
  343.     int    21h
  344.     mov    word ptr their_1b+0,bx
  345.     mov    word ptr their_1b+2,es
  346.     pop    es
  347.  
  348.     push    ds            ;set our C-break.
  349.     mov    ax,cs
  350.     mov    ds,ax
  351.     mov    dx,offset our_1b
  352.     mov    ax,251bh
  353.     int    21h
  354.     pop    ds
  355.  
  356. ;
  357. ;Determine whether or not the BIOS supports extended keyboard functions.
  358. ;
  359.     mov    ah,5            ;write FFFFh to keyboard buffer
  360.     mov    cx,0FFFFh
  361.     int    16h
  362.     mov    ah,10h            ;then read it back
  363.     int    16h
  364.     cmp    ax,0FFFFh        ;is AX set correctly?
  365.     jne    init_entry_0        ;no - they don't have an extended kbd.
  366.     mov    int_16_input,10h    ;yes - use extended keyboard function codes.
  367.     mov    int_16_status,11h
  368. init_entry_0:
  369.  
  370. ;
  371. ;Now set the video mode to one that we can use.
  372. ;
  373.         mov    ah,15
  374.         int    10h            ;get video state of the PC
  375.     mov    num_screen_cols,40
  376.     cmp    al,1            ;40 column text mode?
  377.     jbe    init_entry_1        ;Yes, ok.
  378.     mov    num_screen_cols,80
  379.         cmp    al,3            ;Is screen CGA Text?
  380.         jbe    init_entry_1        ;Yes, ok.
  381.         cmp    al,7            ;Is screen MDA?
  382.         je    init_entry_5        ;Yes, ok - but we can't have an EGA.
  383.  
  384.     mov    ax,0*256 + 3        ;use 25x80 color if some strange mode.
  385.     int    10h
  386.  
  387. init_entry_1:
  388.     mov    ax,1200h        ;test for an EGA
  389.     mov    bx,10h
  390.     mov    cx,-1
  391.     int    10h
  392.     cmp    cx,-1
  393.     je    init_entry_2        ;no EGA.
  394.  
  395.     mov    have_ega,1        ;remember that we have an EGA.
  396.  
  397.     push    ds            ;get the max scanlines.
  398.     xor    ax,ax
  399.     mov    ds,ax
  400.     mov    al,ds:[484h]
  401.     mov    ah,ds:[485h]
  402.     mov    cl,ds:[44ah]
  403.     pop    ds
  404.  
  405.     mov    num_screen_cols,cl    ;remember how wide it is.
  406.     sub    al,2            ;leave room for a status and minibuffer line.
  407.     mov    max_screen_line,al
  408.  
  409. init_entry_2:
  410.     cmp    swap_screen_flag,0    ;should we swap the screen?
  411.     jne    init_entry_4        ;yes.
  412.     ret                ;no.
  413. init_entry_4:
  414.     mov    bh,0
  415.     mov    ah,3            ;get cursor position
  416.     int    10h
  417.     mov    old_cursor,dx
  418.  
  419.     mov    dl,max_screen_line    ;copy the page zero to page one.
  420.     add    dl,2
  421.     mov    al,dl
  422.     inc    al
  423.     add    al,dl
  424. init_entry_3:
  425.     call    move_line        ;enter with dl=source, al=destination.
  426.     dec    al
  427.     dec    dl
  428.     jns    init_entry_3
  429.  
  430. init_entry_5:
  431.     push    es
  432.   if 0
  433.     mov    dh,num_screen_cols
  434.     dec    dh
  435.   else
  436.     mov    dh,0
  437.   endif
  438.     mov    dl,max_screen_line
  439.     add    dl,2
  440.     call    get_video_ptr
  441.     mov    ax,es:[di]        ;get the attributes from the lower right.
  442.     pop    es
  443.     mov    fore_original,ah
  444.     and    fore_original,0fh
  445.     mov    cl,4            ;rotate the background to where we
  446.     shr    ah,cl            ;  want it.
  447.     and    ah,7
  448.     mov    back_original,ah
  449.  
  450. clear_screen:
  451.     mov    dh,0            ;clear the screen.
  452.     mov    dl,max_screen_line
  453.     add    dl,2
  454. clear_screen_1:
  455.     call    clear_to_eol        ;enter with dl=row, dh=column.
  456.     dec    dl
  457.     jns    clear_screen_1
  458.     ret
  459.  
  460.  
  461.     public    uninit_exit
  462. uninit_exit:
  463. ;called when exiting.  May destroy any but seg-regs.
  464.     push    ds            ;restore C-break.
  465.     lds    dx,their_1b
  466.     mov    ax,251bh
  467.     int    21h
  468.     pop    ds
  469.  
  470.     cmp    swap_screen_flag,0    ;should we swap the screen?
  471.     jne    uninit_exit_4        ;yes.
  472.     ret                ;no.
  473. uninit_exit_4:
  474.  
  475.     mov    ah,15
  476.     int    10h            ;get video state of the PC
  477.     cmp    al,7            ;don't restore the memory on an MDA
  478.     je    uninit_exit_1        ;  'cuz it ain't there.
  479.  
  480.     mov    dx,old_cursor
  481.     mov    bh,0
  482.     mov    ah,2            ;set cursor position
  483.     int    10h
  484.  
  485.     mov    al,max_screen_line    ;copy the page one to page zero.
  486.     add    al,2
  487.     mov    dl,al
  488.     add    dl,dl
  489. uninit_exit_3:
  490.     call    move_line        ;enter with dl=source, al=destination.
  491.     dec    dl
  492.     dec    al
  493.     jns    uninit_exit_3
  494.     ret
  495.  
  496. uninit_exit_1:
  497.     mov    dl,0
  498.  
  499.     mov    dh,0            ;mbf: was max_screen_line
  500.     ;add    dh,2
  501.     mov    bh,0
  502.  
  503.     mov    ah,2            ;set cursor position
  504.     int    10h
  505.  
  506.     call    clear_screen
  507.  
  508.     ret
  509.  
  510.  
  511.     public    store_ibm_cga
  512. store_ibm_cga:
  513.     cmp    have_ega,0        ;do we have an EGA?
  514.     jne    store_ibm_cga_1        ;yes - ignore them.
  515.     mov    ibm_cga,al
  516. store_ibm_cga_1:
  517.     ret
  518.  
  519.  
  520.  
  521.     public    store_debug
  522. store_debug:
  523.   if 0
  524.     cmp    ibm_cga,0        ;don't do this on an IBM CGA.
  525.     jne    store_debug_1
  526.     push    ds
  527.     push    es
  528.     push    ax
  529.     mov    ax,data
  530.     mov    ds,ax
  531.     mov    es,ax
  532.     mov    dh,num_screen_cols
  533.     sub    dh,2
  534.     mov    dl,max_screen_line
  535.     inc    dl
  536.     call    get_video_ptr    ;enter with dl=current row, dh=current column.
  537.                 ;return with es:di->character position.
  538.     pop    ax
  539.     mov    es:[di],al
  540.     mov    es:[di+2],ah
  541.     pop    es
  542.     pop    ds
  543. store_debug_1:
  544.   endif
  545.     ret
  546.  
  547.  
  548. ;this routine should check for a break character.  Return cy if none,
  549. ;  nc if we should break.
  550.     public    check_breakchar
  551. check_breakchar:
  552.     cmp    cs:break_flag,0        ;test the break flag.
  553.     mov    cs:break_flag,0        ;clear the break flag.
  554.     stc
  555.     je    check_breakchar_1
  556.     clc
  557. check_breakchar_1:
  558.     ret
  559.  
  560.  
  561.     public    check_for_key
  562. check_for_key:
  563. ;return zr,ax=0 if no key is waiting.
  564. ;return nz,ax=key if a key is waiting, but don't input the key yet.
  565.     mov    ah,int_16_status    ;check for a key.
  566.     int    16h
  567.     jne    check_for_key_1        ;go if we got a key.
  568.     mov    ax,0            ;return ax=0 if we didn't.
  569. check_for_key_1:
  570.     ret
  571.  
  572.  
  573.     public    get_key_value
  574. get_key_value:
  575. ;exit with ax=keycode.
  576.     mov    ah,int_16_input
  577.     int    16h
  578.     ret
  579.  
  580.  
  581.     public    decode_key
  582. decode_key:
  583. ;enter with ax=key value.
  584. ;exit with si,cx -> the key's name in ASCII.
  585.     mov    di,offset key_buffer
  586.  
  587.     cmp    ax,0f9h            ;one of the mouse buttons?
  588.     jb    decode_key_7
  589.     cmp    ax,0feh
  590.     ja    decode_key_7
  591.  
  592.     push    ax
  593.     push    ds
  594.     mov    ax,bios_seg
  595.     mov    ds,ax
  596.     assume    ds:bios_seg
  597.  
  598.     mov    ah,bios_shifts
  599.     and    ah,all_flags        ;isolate the flags we're interested in.
  600.     pop    ds
  601.     assume    ds:data
  602.     mov    shift_flags,ah
  603.     call    decode_meta
  604.     call    decode_ctrl
  605.     call    decode_shift
  606.     pop    ax
  607.  
  608. decode_key_7:
  609.  
  610.     or    al,al            ;extended function key?
  611.     je    decode_key_5
  612.     cmp    al,0e0h
  613.     je    decode_key_5
  614.  
  615.     push    ax            ;now we look for ASCII keys that
  616.     mov    si,offset key_others    ;  have dedicated keys.
  617.     call    decode_search        ;search for the scan code names.
  618.     pop    ax
  619.     jne    decode_key_2        ;go if we found it.
  620.  
  621.     mov    ah,al
  622.     mov    si,offset key_names    ;now search for the ASCII keys that
  623.                     ;  we don't (or can't) represent.
  624.     call    decode_search        ;search for the literal names.
  625.     jne    decode_key_1        ;copy it in.
  626.     mov    al,ah
  627.  
  628.     cmp    al,' '            ;control char?
  629.     jae    decode_key_6        ;no
  630.     add    al,'`'            ;yes - convert into letter.
  631.     mov    ctrl_key_char,al
  632.     mov    si,offset ctrl_key_string
  633.     cmp    al,'z'            ;control character > 'C-z'?
  634.     jbe    decode_key_1        ;no.
  635.     sub    ctrl_key_char,'`'-'@'    ;yes - make it C-[, not C-{
  636.     jmp    short decode_key_1
  637. decode_key_2:
  638.     push    si
  639.     mov    si,offset key_special
  640.     mov    ah,al            ;now see if it's one of the ones we
  641.     call    decode_search        ;  know are special.
  642.     pop    ax
  643.     jne    decode_key_1        ;yes - it is.
  644.     mov    si,ax
  645.     jmp    short decode_key_1
  646. decode_key_6:
  647.     mov    one_key_string,al
  648.     mov    si,offset one_key_string
  649.     jmp    short decode_key_1
  650.  
  651. decode_key_5:
  652.     mov    si,offset key_table    ;search for the extended functions.
  653.     call    decode_search
  654. decode_key_1:
  655.     lodsb                ;copy to the next null.
  656.     stosb
  657.     or    al,al
  658.     jne    decode_key_1
  659.     dec    di            ;don't include the null.
  660.     mov    si,offset key_buffer
  661.     mov    cx,di
  662.     sub    cx,si
  663.     ret
  664.  
  665.  
  666. decode_ctrl:
  667.     test    shift_flags,ctrl_flag
  668.     je    decode_ctrl_1
  669.     mov    ax,'C' + '-'*256
  670.     stosw
  671. decode_ctrl_1:
  672.     ret
  673.  
  674.  
  675. decode_shift:
  676.     test    shift_flags,left_flag + right_flag
  677.     je    decode_shift_1
  678.     mov    ax,'S' + '-'*256
  679.     stosw
  680. decode_shift_1:
  681.     ret
  682.  
  683. decode_meta:
  684.     test    shift_flags,alt_flag
  685.     je    decode_meta_1
  686.     mov    ax,'M' + '-'*256
  687.     stosw
  688. decode_meta_1:
  689.     ret
  690.  
  691.  
  692. decode_search:
  693. ;enter with ah=key to search for, si->table.
  694. ;exit with al=key, nz if found, al=0, zr if not found.
  695.     lodsb
  696.     or    al,al            ;end of table?
  697.     je    decode_search_2        ;yes - try shifted values.
  698.     cmp    al,ah            ;is this the key?
  699.     je    decode_search_2        ;yes.
  700. decode_search_1:
  701.     lodsb                ;skip to the next null.
  702.     or    al,al
  703.     jne    decode_search_1
  704.     jmp    decode_search
  705. decode_search_2:
  706.     or    al,al
  707.     ret
  708.  
  709.  
  710.     public    store_beep        ;mbf
  711. store_beep:
  712.     mov    dobeep,al
  713.     ret
  714.  
  715.     public    read_beep        ;mbf
  716. read_beep:
  717.     mov    al,dobeep
  718.     ret
  719.  
  720.  
  721.     public    ring_the_bell
  722. ring_the_bell:
  723.     cmp    dobeep,0        ;mbf
  724.     je    short ring_the_bell_exit
  725.     mov    bx,6779
  726.     mov    cx,2
  727.     call    beep
  728. ring_the_bell_exit:
  729.     ret
  730.  
  731.  
  732. ;Beep procedure count values
  733. ;---------------------------
  734. ;To generate a given freqency note out of the speaker with the Beep procedure
  735. ;on the PC using Channel 2 of the 8253 timer, the channel 2 count register
  736. ;must be loaded with a value such that the 8253 input clock frequency
  737. ;(1.19318 MHz) divided by the count figure equals the audio frequency.
  738. ;enter with bx=count figure for frequency to be generated.
  739. beep:
  740.     push    ds        ; make ds = bios.
  741.     mov    ax,40h
  742.     mov    ds,ax
  743.     mov    al,0b6h        ; Channel 2, LSB then MSB, Square Wave, Binary
  744.     out    43h,al        ; Program 8253 command register
  745.     mov    ax,bx        ; Get the frequency to be generated
  746.     out    42h,al        ; Load Channel 2 count register LSB
  747.     mov    al,ah
  748.     out    42h,al        ; Load Channel 2 count register MSB
  749.     in    al,61h        ; Read settings from 8255 PPI I/O Port "PB"
  750.     mov    ah,al        ; Save original settings in AH
  751.     or    al,3        ; Enable Timer Channel 2 & Speaker data
  752.     out    61h,al        ; program the 8255 with new setting-speaker on
  753. wait2:
  754.     mov    bx,ds:[6ch]    ; Get the current timer value.
  755. wait1:
  756.     cmp    bx,ds:[6ch]    ; Did the timer value "tick"?
  757.     je    wait1        ; No - keep waiting for a tick.
  758.     loop    wait2        ; LOOP is first executed
  759.     mov    al,ah        ; Get original 8255 Port "PB" settings
  760.     out    61h,al        ; Reset port to original values-speaker off
  761.     pop    ds
  762.     ret
  763.  
  764.  
  765. code    ends
  766.  
  767. code    segment    byte public
  768.     assume    cs:code, ds:nothing, es:data, ss:data
  769. ;all of the code in this segment is called with the above assumes.
  770.  
  771.  
  772.     public    read_ibm_cga
  773. read_ibm_cga:
  774.     mov    al,ibm_cga
  775.     ret
  776.  
  777.  
  778.     public    position_cursor
  779. position_cursor:
  780. ;enter with dh=col (0...80), dl=row (0..max_screen_line)
  781. ;exit with cursor set to that position.
  782.     push    si
  783.     push    di
  784.     push    bp
  785.     push    bx
  786.     xchg    dh,dl
  787.     mov    bh,0
  788.     mov    ah,2            ;set cursor position
  789.     int    10h
  790.     cld
  791.     xchg    dh,dl
  792.     pop    bx
  793.     pop    bp
  794.     pop    di
  795.     pop    si
  796.     ret
  797.  
  798. ;in mintscan [mbf]
  799. extrn getarg: near
  800. extrn get_number: near
  801. extrn return_null: near
  802.  
  803. ;set cursor type [mbf]
  804.     public    cc_prim
  805. cc_prim:
  806.     mov    cx,1
  807.     mov    bx,16
  808.     call    getarg
  809.     call    get_number
  810.     mov    cx,ax
  811.     mov    ah,01h
  812.     int    10h
  813.     call    return_null
  814.     ret
  815.  
  816. crt_status equ  3dah                    ; crt status port
  817. disp_enb equ    1                       ; display enable bit
  818.  
  819. putch    macro
  820.     local    nowait,loop1,loop2
  821.     push    bx
  822.     push    dx
  823.     mov    bx,ax
  824.     cmp    ibm_cga,0
  825.     je    nowait
  826.     mov    dx,crt_status
  827. loop1:
  828.     in    al,dx
  829.     test    al,disp_enb        ; display enabled?
  830.     jnz    loop1            ; yes, keep waiting
  831. loop2:
  832.     in    al,dx
  833.     test    al,disp_enb        ; now wait for it to go    off
  834.     jz    loop2            ; so can have whole cycle
  835. nowait:
  836.     mov    ax,bx
  837.     stosw
  838.     pop    dx
  839.     pop    bx
  840.     endm
  841.  
  842.  
  843.     public    move_line
  844. move_line:
  845. ;enter with dl=source row, al=destination row.
  846.     push    ax
  847.     push    bx
  848.     push    cx
  849.     push    dx
  850.     push    si
  851.     push    di
  852.     push    bp
  853.     push    ds
  854.     push    es
  855.  
  856.     push    ax            ;compute the source byte.
  857.     mov    al,num_screen_cols
  858.     shl    dl,1
  859.     mul    dl
  860.     mov    si,ax
  861.     pop    ax
  862.  
  863.     mov    ah,num_screen_cols    ;compute the destination byte.
  864.     shl    al,1
  865.     mul    ah
  866.     mov    di,ax
  867.  
  868.     mov    cx,word ptr num_screen_cols    ;move the line.
  869.     call    get_video_seg        ;get the video card plane.
  870.     mov    ds,ax
  871.     assume    ds:nothing, es:nothing
  872.  
  873.     cmp    ibm_cga,0
  874.     je    move_line_2
  875.  
  876. move_line_1:
  877.     push    dx
  878.     mov    dx,crt_status
  879. move_line_loop1:
  880.     in    al,dx
  881.     test    al,disp_enb        ; display enabled?
  882.     jnz    move_line_loop1        ; yes, keep waiting
  883. move_line_loop2:
  884.     in    al,dx
  885.     test    al,disp_enb        ; now wait for it to go    off
  886.     jz    move_line_loop2        ; so can have whole cycle
  887.     lodsw
  888.     pop    dx
  889.     putch
  890.     loop    move_line_1
  891.     jmp    short move_line_3
  892.  
  893. move_line_2:
  894.     rep    movsw
  895.  
  896. move_line_3:
  897.  
  898.     pop    es
  899.     pop    ds
  900.     assume    ds:nothing, es:data
  901.     pop    bp
  902.     pop    di
  903.     pop    si
  904.     pop    dx
  905.     pop    cx
  906.     pop    bx
  907.     pop    ax
  908.     ret
  909.  
  910.  
  911.     public    clear_to_eol
  912. clear_to_eol:
  913. ;enter with dl=current row, dh=current column.
  914.     push    bx
  915.     mov    bl,num_screen_cols
  916.     call    clear_count
  917.     pop    bx
  918.     ret
  919.  
  920.  
  921.     public    clear_count
  922. clear_count:
  923. ;enter with dl=current row, dh=current column, bl=column to clear to.
  924.     push    ax
  925.     push    bx
  926.     push    cx
  927.     push    si
  928.     push    di
  929.     push    bp
  930.     push    es
  931. clear_count_0:
  932.     cmp    dh,bl        ;already past it?
  933.     jae    clear_count_3    ;yes.
  934.  
  935.     mov    ah,color
  936.     mov    al,' '            ;clear to the background color.
  937.     push    ax
  938.     call    get_video_ptr
  939.     assume    ds:nothing, es:nothing
  940.  
  941.     pop    ax
  942.  
  943.     mov    cl,bl            ;compute the number of chars to clear.
  944.     sub    cl,dh
  945.     mov    ch,0
  946.  
  947.     cmp    ibm_cga,0        ;slow refresh?
  948.     je    clear_count_2
  949.  
  950. clear_count_1:
  951.     putch
  952.     loop    clear_count_1
  953.     jmp    short clear_count_3
  954.  
  955. clear_count_2:
  956.     rep    stosw
  957.  
  958. clear_count_3:
  959.     pop    es
  960.     assume    ds:nothing, es:data
  961.     pop    bp
  962.     pop    di
  963.     pop    si
  964.     pop    cx
  965.     pop    bx
  966.     pop    ax
  967.     ret
  968.  
  969.  
  970. get_video_ptr:
  971. ;enter with dl=current row, dh=current column.
  972. ;return with es:di->character position.
  973.     mov    al,num_screen_cols    ;compute the offset of the char.
  974.     mul    dl
  975.     add    al,dh
  976.     adc    ah,0
  977.     shl    ax,1
  978.     mov    di,ax
  979. get_video_seg:
  980. ;return with es,ax=video segment.
  981.     xor    ax,ax
  982.     mov    es,ax
  983.     mov    ax,0b000h
  984.     cmp    byte ptr es:[449h],7    ;MDA?
  985.     je    get_video_seg_1        ;yes - we have the segment already.
  986.     mov    ax,0b800h        ;no - segment at b800h.
  987. get_video_seg_1:
  988.     mov    es,ax
  989.     ret
  990.  
  991.  
  992.     public    xychrout
  993. xychrout:
  994. ;enter with dh=col, dl=row, al=character to print, ah=font to print it in.
  995.     push    ax            ;save everything that we might need.
  996.     push    bx
  997.     push    cx
  998.     push    dx
  999.     push    di
  1000.     push    si
  1001.     push    es
  1002.     push    ds
  1003.     mov    bx,es
  1004.     mov    ds,bx
  1005.     cmp    dh,num_screen_cols    ;past the right margin?
  1006.     jae    xychrout_3        ;yes - don't print.
  1007.     cmp    ah,0            ;font zero?
  1008.     jne    xychrout_5        ;no - print specially.
  1009.     mov    ah,color        ;assume no inverse video
  1010.   if 0
  1011.     cmp    al,80h            ;meta char?
  1012.     jb    xychrout_nometa        ;no
  1013.     mov    cl,4            ;yes, inverse video
  1014.     rol    ah,cl
  1015.     and    al,7fh            ;but move into normal char range
  1016. xychrout_nometa:
  1017.   endif
  1018.     cmp    al,00h            ;mbf: print 00h specially
  1019.     je    xychrout_ins
  1020.     cmp    al,20h            ;print control chars specially.
  1021.     jb    xychrout_control
  1022.     cmp    al,0ffh            ;print 255 specially
  1023.     je    xychrout_del
  1024.     jmp    short xychrout_1
  1025. xychrout_control:
  1026.     mov    ah,color
  1027.                 ;mbf: fix for rv video; uncmt if want rv
  1028.     ;mov    bl,color    ; sv it for new attr
  1029.     ;and    bl,088h        ; turn off color bits
  1030.     ;and    ah,077h        ; get colors only
  1031.     ;mov    cl,4
  1032.     ;ror    ah,cl        ; exch backgr and foregr
  1033.     ;or    bl,ah        ; new attr: rv vid
  1034.  
  1035.     ;;or    ah,08h        ;mbf: fix for bold (was 10h); uncmt if want bold
  1036.  
  1037.     ;;;add    al,'@'        ;mbf: so that ctrl chars now show as ctrl chars
  1038.  
  1039.     jmp    short xychrout_1
  1040. xychrout_ins:            ;mbf: make 00h look like a rv vid '@'
  1041.     mov    bl,color    ; sv it for new attr
  1042.     and    bl,088h        ; turn off color bits
  1043.     and    ah,077h        ; get colors only
  1044.     mov    cl,4
  1045.     ror    ah,cl        ; exch backgr and foregr
  1046.     or    bl,ah        ; new attr: rv vid
  1047.     mov    al,40h
  1048.     jmp    short xychrout_1
  1049. xychrout_del:
  1050.     mov    ah,color
  1051.     ;;or    ah,08h        ;mbf: fix for bold (was 10h); uncmt if want bold
  1052.     mov    al,7fh            ;bold del.
  1053.     jmp    short xychrout_1
  1054. xychrout_5:
  1055.     mov    ah,color
  1056.     mov    bx,offset font_8_table
  1057.     sub    al,4dh            ;first character in font 8.
  1058.     xlat
  1059. xychrout_1:
  1060.     mov    bx,inversing        ;set the inverse video flag.
  1061.     and    bl,77h            ;strip out just the color.
  1062.     xor    ah,bl            ;now flip the colors (if desired).
  1063.     push    ax
  1064.     call    get_video_ptr
  1065.     assume    ds:nothing, es:nothing
  1066.     pop    ax
  1067.     putch
  1068. xychrout_3:
  1069.     pop    ds
  1070.     pop    es
  1071.     assume    ds:nothing, es:data
  1072.     pop    si
  1073.     pop    di
  1074.     pop    dx
  1075.     pop    cx
  1076.     pop    bx
  1077.     pop    ax
  1078.     ret
  1079.  
  1080.  
  1081.     public    hardware_roll_down
  1082. hardware_roll_down:
  1083. ;exit: if this machine is capable of hardware roll, do it and exit with cy=0,
  1084. ;  otherwise, exit with cy=1.  The hardware roll must leave the last line
  1085. ;  on the screen as the last line.
  1086. ;preserve bx.
  1087.     cmp    ibm_cga,0
  1088.     je    no_roll_down
  1089.  
  1090.     push    bx
  1091.     push    cx
  1092.     push    dx
  1093.     mov    ch,ah
  1094.     mov    cl,0
  1095.     mov    dh,al
  1096.     mov    dl,num_screen_cols
  1097.     dec    dl
  1098.     mov    bh,color
  1099.     mov    ax,701h
  1100.     int    10h
  1101.     pop    dx
  1102.     pop    cx
  1103.     pop    bx
  1104.     clc
  1105.     ret
  1106. no_roll_down:
  1107.     stc
  1108.     ret
  1109.  
  1110.  
  1111.     public    hardware_roll_up
  1112. hardware_roll_up:
  1113. ;exit: if this machine is capable of hardware roll, do it and exit with cy=0,
  1114. ;  otherwise, exit with cy=1.  The hardware roll must leave the last line
  1115. ;  on the screen as the last line.
  1116. ;preserve bx.
  1117.     cmp    ibm_cga,0
  1118.     je    no_roll_up
  1119.  
  1120.     push    bx
  1121.     push    cx
  1122.     push    dx
  1123.     mov    ch,ah
  1124.     mov    cl,0
  1125.     mov    dh,al
  1126.     mov    dl,num_screen_cols
  1127.     dec    dl
  1128.     mov    bh,color
  1129.     mov    ax,601h
  1130.     int    10h
  1131.     pop    dx
  1132.     pop    cx
  1133.     pop    bx
  1134.     clc
  1135.     ret
  1136. no_roll_up:
  1137.     stc
  1138.     ret
  1139.  
  1140.  
  1141.     public    set_screen_color
  1142. set_screen_color:
  1143. ;enter with al=fore color, ah=back color
  1144.     shl    ah,1
  1145.     shl    ah,1
  1146.     shl    ah,1
  1147.     shl    ah,1
  1148.     or    al,ah
  1149.     mov    color,al
  1150.     ret
  1151.  
  1152.  
  1153. code    ends
  1154.  
  1155.     end
  1156.