home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / cpm / cpm86 / fmacs86.ark / VT200.A86 < prev    next >
Text File  |  1989-02-09  |  20KB  |  748 lines

  1.     pagesize 86
  2.  
  3. v30    equ    1
  4.  
  5. ;Porting FREEMACS to CCPM computers assuming VT200 console with 8 bit controls
  6.  
  7. ;The following conventions must be maintained:
  8. ;  1) Never leave this module with DF=1.
  9. ;  2) Never destroy ES.
  10. ;  3) Never MOV AX,DATA, always use the copy in the appropriate segment register.
  11. ;  4) Return NC if a routine succeeds, or fulfills its goals.
  12.  
  13.     if v30
  14. ;macros for NEC V20/V30 or Intel 80186/286
  15.     codemacro SHRW parm:ew,count:db        ;shift word right by
  16.         db 0c1h                ;immediate count
  17.         modrm 5,parm
  18.         db count
  19.         endm
  20.     codemacro SHLB parm:eb,count:db        ;shift byte right by
  21.         db 0c0h                ;immediate count
  22.         modrm 4,parm
  23.         db count
  24.         endm
  25.     codemacro PUSHW parm:dw            ;push immediate word
  26.         db 068h
  27.         dw parm
  28.         endm
  29.     codemacro PUSHALL            ;push all register
  30.         db 060h                ;AX,CX,DX,BX,SP,BP,SI,DI
  31.         endm
  32.     codemacro POPALL            ;pop all register
  33.         db 061h                ;DI,SI,BP,SP,BX,DX,CX,AX
  34.         endm
  35.     endif
  36. ;
  37. call_di        equ    word ptr 0[bp]    ;\----------------/
  38. call_si        equ    word ptr 2[bp]    ; \         /
  39. call_bp        equ    word ptr 4[bp]    ;  \        /
  40. call_sp        equ    word ptr 6[bp]    ;\\\\ saved by ////
  41. call_bx        equ    word ptr 8[bp]    ;//// PUSHALL  \\\\
  42. call_dx        equ    word ptr 10[bp]    ;  /        \
  43. call_cx        equ    word ptr 12[bp]    ; /         \
  44. call_ax        equ    word ptr 14[bp]    ;/----------------\
  45.  
  46. call_es        equ    word ptr 16[bp]
  47. call_ds        equ    word ptr 18[bp]
  48.  
  49. ;
  50. ;
  51. c_rawio        equ    06h
  52. c_write        equ    02h
  53. c_writestr    equ    09h
  54. c_writeblk    equ    6Fh
  55. p_delay        equ    8Dh
  56.     codemacro CCPM parm:db        ;call CCPM
  57.         db 0b1h ! db parm        ;mov cl,parm
  58.         db 0cdh ! db 0e0h        ;int 0E0H
  59.         endm
  60.  
  61. data    dseg    word public
  62.  
  63.     public max_screen_line
  64. max_screen_line        db    21
  65.  
  66. esc    equ    1Bh
  67. dcs    equ    90h
  68. csi    equ    9Bh    ;control string introducer chars
  69. st    equ    9Ch
  70. ss2    equ    8Eh
  71. ss3    equ    8Fh
  72.  
  73. soh    equ    01h
  74. stx    equ    02h
  75. etx    equ    03h
  76. bs    equ    08h
  77. cr    equ    0Dh
  78. lf    equ    0Ah
  79. sho    equ    0Eh    ;shift out character
  80. shi    equ    0Fh    ;shift in character
  81.  
  82. init_cons    db    esc,'[62;0"p'    ;set vt200 mode 8-bit controls
  83.         db    csi,'H'        ;cursor to home
  84.         db    csi,'2J'    ;erase to end of screen
  85.         db    csi,'0m'    ;all attributes off
  86.         db    csi,'2l'    ;unlock keyboard
  87.         db    csi,'1;22r'    ;set scrolling region
  88.         db    esc,')0'    ;designate Special Graphics to G1
  89. ;____________________________________________________________________________
  90.     ;now we are (pre-)defining the user programable
  91.     ;function keys to return an artificial CSI-sequence
  92.     ;THIS CODE IS INSTALLATION DEPENDANT !!!!!
  93.         db    dcs,'0;1|'    ;clear user function keys
  94.         db    '17/9B35377E;'    ;User F6
  95.         db    '18/9B35387E;'    ;User F7
  96.         db    '19/9B35397E;'    ;User F8
  97.         db    '20/9B36307E;'    ;User F9
  98.         db    '21/9B36317E;'    ;User F10
  99.         db    '23/1B;'    ;User F11 = <ESC> or C-[
  100.         db    '24/08;'    ;User F12 = <BS> or C-H
  101.         db    '25/0A;'    ;User F13 = <LF> or C-J
  102.         db    '26/9B36367E;'    ;User F14
  103.         db    '28/9B36387E;'    ;User Help
  104.         db    '29/9B36397E;'    ;User Do
  105.         db    '31/9B37317E;'    ;User F17
  106.         db    '32/9B37327E;'    ;User F18
  107.         db    '33/9B37337E;'    ;User F19
  108.         db    '34/9B37347E',st;User F20
  109. keypad_mode_str    db    esc,'='        ;Application Keypad
  110.         db    '$'
  111. ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  112.  
  113. ;______________________________________________________________________________
  114.     ;the following holds true only for our own standard terminal setup at
  115.     ;the University of TUEBINGEN.
  116.     ;THIS CODE IS INSTALLATION DEPENDANT !!!!!
  117. uninit_cons    db    dcs,'0;1|'    ;reset user keys to BASF-PCI (SHIT MVS)
  118.         db    '17/1B34;'    ;F6  <ESC>4 = return
  119.         db    '18/1B32;'    ;F7  <ESC>2 = split
  120.         db    '19/1B39;'    ;F8  <ESC>9 = swap
  121.         db    '20/1B35;'    ;F9  <ESC>5 = rfind
  122.         db    '21/1B36;'    ;F10 <ESC>6 = rchange
  123.         db    '23/1B;'    ;F11 = <ESC>
  124.         db    '24/08;'    ;F12 = <BS>
  125.         db    '25/0A;'    ;F13 = <LF>
  126.         db    '26/01;'    ;F14 = <SOH> = home
  127.         db    '28/1B31;'    ;HELP <ESC>1 = help
  128.         db    '29/1B33;'    ;DO  <ESC>3 = end
  129.         db    '31/1B37;'    ;F17 <ESC>7 = up
  130.         db    '32/1B38;'    ;F18 <ESC>8 = down
  131.         db    '33/1B30;'    ;F19 <ESC>0 = left
  132.         db    '34/1B2D',st    ;F20 <ESC>- = right
  133.         db    esc,'c'        ;recall initial terminal parameters
  134.         db    '$'
  135. ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  136. ;
  137. roll_dn_string    db    csi,'H',csi,'1L$'
  138. roll_up_string    db    csi,'H',csi,'1M$'
  139.  
  140. ins_line_string    equ    roll_dn_string+2
  141. del_line_string    equ    roll_up_string+2
  142.  
  143. cur_pos_string        db    csi,'ror;colH$'
  144. clear_to_eol_string    db    csi,'K$'
  145.  
  146. sv_cursor_string    db    esc,'7$'
  147. rs_cursor_string    db    esc,'8$'
  148. rvideo_string        db    csi,'0;1;7m$'
  149.  
  150. key_buffer    dw    0
  151.  
  152. ss3_scan_tab    db    'ABCDMPQRSmlnpqrstuvwxy'
  153.  
  154. Comma_key    db    'Comma'
  155. LPar_key    db    'LPar'
  156. RPar_key    db    'RPar'
  157.  
  158. delete_string    db    '*Delete'
  159. ctrl_string    db    '*C-'
  160.  
  161. csi_name_tab    db    41h,07,'Scan-up'
  162.         db    42h,09,'Scan-down'
  163.         db    43h,10,'Scan-right'
  164.         db    44h,09,'Scan-left'
  165.         db    01h,04,'Find'
  166.         db    02h,11,'Insert-here'
  167.         db    03h,06,'Remove'
  168.         db    04h,06,'Select'
  169.         db    05h,11,'Prev-Screen'
  170.         db    06h,11,'Next-Screen'
  171.         db    17h,02,'F6'
  172.         db    18h,02,'F7'
  173.         db    19h,02,'F8'
  174.         db    20h,02,'F9'
  175.         db    21h,03,'F10'
  176.         db    23h,03,'F11'
  177.         db    24h,03,'F12'
  178.         db    25h,03,'F13'
  179.         db    26h,03,'F14'
  180.         public    breakchar    ; /this is normally the "Help" key,
  181.         db    28h,05,'BREAK'    ;< but here we'll use it as BREAK,
  182. breakchar    equ    28h*256+csi    ; \for HELP use user's key "UHelp"
  183.         db    29h,02,'Do'    ;  \ THIS CODE IS INSTALLATION DEPENDANT !!
  184.         db    31h,03,'F17'
  185.         db    32h,03,'F18'
  186.         db    33h,03,'F19'
  187.         db    34h,03,'F20'
  188. ;____________________________________________________________________________
  189.     ;*** PROGRAMMED user keys ***
  190.     ;THIS CODE IS INSTALLATION DEPENDANT !!!!!
  191.         db    57h,03,'UF6'
  192.         db    58h,03,'UF7'
  193.         db    59h,03,'UF8'
  194.         db    60h,03,'UF9'
  195.         db    61h,04,'UF10'
  196.         db    63h,04,'UF11'
  197.         db    64h,04,'UF12'
  198.         db    65h,04,'UF13'
  199.         db    66h,04,'UF14'
  200.         db    68h,04,'Help'    ;<"UHelp" Reserved for Help !!!
  201.         db    69h,02,'Do'    ;<"UDo" = "Do" !!!
  202.         db    71h,04,'UF17'
  203.         db    72h,04,'UF18'
  204.         db    73h,04,'UF19'
  205.         db    74h,04,'UF20'
  206. ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  207. ;
  208.         db    00h,07,'<?CSI?>'
  209.  
  210. ss3_name_tab    db    41h,07,'Scan-up'
  211.         db    42h,09,'Scan-down'
  212.         db    43h,10,'Scan-right'
  213.         db    44h,09,'Scan-left'
  214.         db    'M',05,'Enter'
  215.         db    'P',03,'PF1'
  216.         db    'Q',03,'PF2'
  217.         db    'R',03,'PF3'
  218.         db    'S',03,'PF4'    ;<< ESCAPE to terminal handler commands
  219.         db    'm',08,'KP-minus'
  220.         db    'l',08,'KP-comma'
  221.         db    'n',08,'KP-point'
  222.         db    'p',04,'KP-0'
  223.         db    'q',04,'KP-1'
  224.         db    'r',04,'KP-2'
  225.         db    's',04,'KP-3'
  226.         db    't',04,'KP-4'
  227.         db    'u',04,'KP-5'
  228.         db    'v',04,'KP-6'
  229.         db    'w',04,'KP-7'
  230.         db    'x',04,'KP-8'
  231.         db    'y',04,'KP-9'
  232.         db    00h,07,'<?SS3?>'
  233.  
  234. unknown_key_string    db    0,7,'Unknown'
  235.  
  236. font_select_string    db    shi,csi,'0'    ;all attributes off
  237. font_attribs        rb    12
  238. curr_font        db    0
  239.  
  240. special_font_string    db    csi,'0;1m'    ;bold
  241.             db    sho,'$'
  242.  
  243. special_chars        db    66h        ;00: any undefined
  244.             db    60h        ;01: visi space
  245.             db    61h        ;02: visi tab
  246.             db    6Eh        ;03: more character
  247.             db    68h        ;04: visible newline
  248. special_chars_lng    equ    (offset $) - (offset special_chars)
  249.  
  250. ctrl_char_string    db    esc,'7'
  251.             db    csi,'0;1m'    ;bold
  252. ctrl_char        db    '?'
  253.             db    esc,'8'
  254.             db    csi,'C$'
  255.  
  256.  
  257. help_buffer    rb    16
  258. temp        equ    help_buffer
  259.  
  260. ;data    ends
  261.  
  262. code    cseg    byte public
  263.  
  264.     public init_entry
  265. init_entry:
  266.     call prolog
  267.     mov dx,offset init_cons
  268.     ccpm c_writestr
  269.  
  270. epilog:    mov sp,bp
  271.     if v30
  272.     popall
  273.     else
  274.     pop di ! pop si ! pop bp ! pop ax    ;skip sp
  275.     pop bx ! pop dx ! pop cx ! pop ax
  276.     endif
  277.     pop es ! pop ds ! ret
  278.  
  279. prolog: pop prolog_return
  280.     push ds ! push es
  281.     if v30
  282.     pushall
  283.     else
  284.     push ax ! push cx ! push dx ! push bx
  285.     push sp ! push bp ! push si ! push di
  286.     endif
  287.     mov bp,sp ! mov ds,own_ds
  288.     jmp prolog_return
  289. prolog_return    rw    1
  290. own_ds        dw    seg key_buffer
  291.  
  292.     public uninit_exit
  293. uninit_exit:
  294.     call prolog
  295.     mov dx,offset uninit_cons
  296.     ccpm c_writestr
  297.     mov dx,10        ;wait 10 clock ticks ..
  298.     ccpm p_delay        ;.. for terminal recall
  299.     jmps epilog
  300.  
  301.     public check_for_key
  302. check_for_key:
  303.     ;return zr,ax=0 if no key is waiting.
  304.     ;return nz,ax=key if a key is waiting, but don't input the key yet.
  305.     call prolog ! mov ax,key_buffer        ;last key is in buffer ?
  306.     mov call_ax,ax
  307.     or ax,ax ! jnz epilog
  308.     mov dl,0ffh ! ccpm c_rawio    ;ask CCPM for a key present
  309. check_for_key_0:    xor ah,ah
  310.     ;
  311.     cmp al,csi ! jne check_for_key_1
  312.     mov dl,0fdh ! ccpm c_rawio    ;get first char. after CSI
  313.     cmp al,'A' ! jb check_for_csi_1    ;check for cursor keys
  314.     cmp al,'D' ! jbe check_for_csi_3
  315. check_for_csi_1:
  316.     cmp al,'1' ! jb check_for_key_err    ;not a CSI key
  317.     cmp al,'9' ! ja check_for_key_err
  318.     and al,0fh ! mov temp,al
  319.     mov dl,0fdh ! ccpm c_rawio    ;get second char after CSI
  320.     cmp al,'~' ! je check_for_csi_2    ;end of CSI key
  321.     cmp al,'0' ! jb check_for_key_err
  322.     cmp al,'9' ! ja check_for_key_err
  323.     and ax,0fh
  324.     if v30
  325.     shlb temp,4 ! add temp,al    ;form decimal packed
  326.     else
  327.     mov cl,4 ! shl temp,cl ! add temp,al
  328.     endif
  329.     mov dl,0fdh ! ccpm c_rawio    ;get third char. after CSI
  330.     cmp al,'~' ! jne check_for_key_err    ;must be '~'
  331. check_for_csi_2:    mov al,temp
  332. check_for_csi_3:    mov ah,csi
  333.     jmps check_for_key_2    ;save CSI code
  334.  
  335. check_for_key_1:
  336.     ;check for SS3 key
  337.     cmp al,ss3 ! jne check_for_key_2
  338.     mov dl,0fdh ! ccpm c_rawio    ;get first char after SS3
  339.     push ds ! pop es
  340.     mov di,offset ss3_scan_tab
  341.     mov cx,length ss3_scan_tab
  342.     repne scasb            ;scan SS3 key table
  343.     jne check_for_key_err        ;key error
  344.     cmp al,'S' ! je handler_seq    ;special VT200 handler command sequence 
  345.     mov ah,ss3
  346.     ;
  347. check_for_key_2:
  348.     mov key_buffer,ax        ;save key
  349.     mov call_ax,ax            ; and return it
  350.     or ax,ax ! jmp epilog
  351.  
  352. check_for_key_err:
  353.     call ring_the_bell
  354.     xor ax,ax ! jmps check_for_key_2
  355.  
  356. handler_seq:
  357.     ;test for special terminal handler command sequences by PF4
  358.     call get_ss3_seq        ;get the next SS3 sequence
  359.  
  360.     cmp al,'p' ! jb    handler_seq_PF4    ;not a decimal ASCII
  361.     cmp al,'r' ! ja check_for_key_err
  362.     ;
  363.     ;get ASCII char in decimal representation (000-255)
  364.     sub al,'p' ! mov cl,10 ! mul cl
  365.     push ax ! call get_ss3_seq ! pop dx
  366.     sub al,'p' ! jb check_for_key_err
  367.     cmp al,9   ! ja check_for_key_err
  368.     add ax,dx ! mov cl,10 ! mul cl
  369.     push ax ! call get_ss3_seq ! pop dx
  370.     sub al,'p' ! jb check_for_key_err
  371.     cmp al,9   ! ja check_for_key_err
  372.     add ax,dx ! cmp ax,255
  373.     ja check_for_key_err
  374.     mov ah,'B' ! jmps check_for_key_2        ;signal bin key
  375.     ;
  376. handler_seq_PF4:
  377.     ;if double PF4 then return PF4
  378.     cmp al,'S' ! jne handler_seq_PF3
  379.     mov ah,ss3 ! jmp check_for_key_2
  380.     ;
  381. handler_seq_PF3:
  382.     ;if "PF4 PF3" then alter the keypad mode (application <--> numeric)
  383.     cmp al,'R' ! jne handler_seq_err    ;*** yet !!!! --- error ----
  384.     xor keypad_mode_str+1,03h        ;toggle mode
  385.     mov dx,offset keypad_mode_str
  386.     ccpm c_writestr
  387.     xor ax,ax ! jmp check_for_key_2
  388.     ;
  389. handler_seq_err:
  390.     jmp check_for_key_err
  391.  
  392.  
  393. get_ss3_seq:
  394.     mov dl,0fdh ! ccpm c_rawio
  395.     cmp al,ss3 ! jne handler_seq_err
  396.     mov dl,0fdh ! ccpm c_rawio
  397.     xor ah,ah ! ret
  398.  
  399.  
  400.     public get_key_value
  401. get_key_value:
  402.     ;exit with ax=key code.
  403.     push ds ! mov ds,own_ds
  404.     xor ax,ax ! xchg ax,key_buffer    ;get key and clear buffer
  405.     pop ds ! or ax,ax ! jz $+3 ! ret
  406.     if v30
  407.     pushw offset get_key_value    ;return from check_key_value_0
  408.     else
  409.     mov ax,offset get_key_value ! push ax
  410.     endif
  411.     call prolog
  412.     mov dl,0fdh ! ccpm c_rawio    ;read char from console
  413.     jmp check_for_key_0        ;check control codes
  414.  
  415.     public decode_key
  416. decode_key:
  417. ;enter with ax=key value.
  418. ;exit with si,cx -> the key's name in ASCII.
  419.     call prolog
  420.     mov di,offset help_buffer
  421.     test ah,ah ! jz $+5
  422.     jmp decode_specials        ;decode special keys
  423. ;
  424.     cmp al,',' ! jne decode_key_LPar
  425.     mov call_si,offset Comma_key
  426.     mov call_cx,length Comma_key
  427.     jmp epilog
  428. decode_key_LPar:
  429.     cmp al,'(' ! jne decode_key_RPar
  430.     mov call_si,offset LPar_key
  431.     mov call_cx,length LPar_key
  432.     jmp epilog
  433. decode_key_RPar:
  434.     cmp al,')' ! jne decode_key_delete
  435.     mov call_si,offset RPar_key
  436.     mov call_cx,length RPar_key
  437.     jmp epilog
  438. decode_key_delete:
  439.     mov si,di            ;remember beginning
  440.     mov dl,al ! and dl,7fh        ;form 7-bit code
  441.     cmp dl,7fh ! jne decode_non_delete    ;jump if no <DEL> char
  442. ;
  443.     push si ! mov si,offset delete_string
  444.     mov cx,length delete_string
  445.     test al,80h ! jnz $+4
  446.     dec cx ! inc si            ;skip 8-bit-indicator
  447.     push cx ! rep movsb        ;move "Delete" string
  448.     mov al,0 ! stosb        ;append terminator
  449.     pop call_cx ! pop call_si
  450.     jmp epilog
  451.     ;
  452. decode_non_delete:
  453.     cmp dl,32 ! jb decode_ctrl_key
  454.     mov call_si,si            ;this is a normal displayable char
  455.     mov call_cx,1
  456.     stosw ! jmp epilog
  457.     ;
  458. decode_ctrl_key:
  459.     push si ! mov si,offset ctrl_string
  460.     mov cx,length ctrl_string
  461.     test ah,80h ! jnz $+4
  462.     dec cx ! inc si            ;skip 8-bit-indicator
  463.     push cx ! rep movsb        ;move "Ctrl"-char indicator
  464.     pop cx ! mov al,dl
  465.     add al,64 ! stosw        ;put the control char
  466.     inc cx ! mov call_cx,cx
  467.     pop call_si ! jmp epilog
  468.     ;
  469. decode_specials:
  470.     cmp ah,csi ! jne decode_ss3
  471.     mov bx,offset csi_name_tab    ;decode CSI controls
  472.     jmps decode_specials_1
  473. decode_ss3:
  474.     cmp ah,ss3 ! jne decode_bin
  475.     mov bx,offset ss3_name_tab
  476. decode_specials_1:
  477.     cmp al,[bx] ! je decode_specials_3
  478.     cmp byte ptr [bx],0
  479.     je decode_specials_3
  480.     add bl,1[bx] ! adc bh,0
  481.     inc bx ! inc bx ! jmps decode_specials_1
  482. decode_specials_2:
  483.     mov bx,offset unknown_key_string
  484. decode_specials_3:
  485.     mov cl,1[bx] ! lea si,2[bx]
  486. decode_specials_4:    xor ch,ch
  487.     mov call_cx,cx
  488.     mov call_si,si
  489.     jmp epilog
  490. decode_bin:
  491.     cmp ah,'B' ! jne decode_specials_2
  492.     mov si,offset help_buffer
  493.     mov [si],al ! mov cl,1 ! jmps decode_specials_4
  494.  
  495.  
  496.  
  497.     public ring_the_bell
  498. ring_the_bell:
  499.     push bx ! push cx ! push dx
  500.     mov dl,7 ! ccpm c_rawio
  501.     xor cx,cx ! loop $
  502.     mov dl,7 ! ccpm c_rawio
  503.     pop dx ! pop cx ! pop bx ! ret
  504.  
  505.     public position_cursor
  506. position_cursor:
  507. ;enter with dh=col (0...131), dl=row (0..max_screen_line)
  508. ;exit with cursor set to that position.
  509.     call prolog
  510.     if v30
  511.     pushw offset epilog        ;fall thru
  512.     else
  513.     mov ax,offset epilog ! push ax
  514.     endif
  515. pos_cursor:    std
  516.     mov di,offset cur_pos_string+7
  517.     xor ax,ax ! mov ah,dh ! inc ah
  518. position_cursor_1:            ;convert columne
  519.     or ah,ah ! jz position_cursor_2
  520.     if v30
  521.     shrw ax,8 ! div cb10
  522.     else
  523.     mov al,ah ! mov ah,0 ! div cb10
  524.     endif
  525.     xchg al,ah ! or al,'0' ! stosb
  526.     jmps position_cursor_1
  527. position_cursor_2:
  528.     mov al,';' ! stosb        ;put parameter delimiter
  529.     mov ah,dl ! inc ah
  530. position_cursor_3:            ;convert line number (row)
  531.     or ah,ah ! jz position_cursor_4
  532.     if v30
  533.     shrw ax,8 ! div cb10
  534.     else
  535.     mov al,ah ! mov ah,0 ! div cb10
  536.     endif
  537.     xchg al,ah ! or al,'0' ! stosb
  538.     jmps position_cursor_3
  539. position_cursor_4:
  540.     mov byte ptr [di],csi        ;insert control string introducer
  541.     mov dx,di ! ccpm c_writestr    ;write out cursor position command
  542.     cld ! ret
  543. cb10    db    10
  544.  
  545.      public clear_to_eol
  546. clear_to_eol:
  547. ;enter with dl=current row, dh=current column.
  548.     call prolog
  549.     call pos_cursor
  550. clear_to_eol_1:
  551.     mov dx,offset clear_to_eol_string
  552.     ccpm c_writestr
  553.     jmp epilog
  554.  
  555.     public    clear_count
  556. clear_count:
  557. ;enter with dl=current row, dh=current column, bl=column to clear to.
  558.     call prolog
  559.     call pos_cursor
  560.     mov cx,call_bx ! xor ch,ch
  561.     mov ax,call_dx ! xor ah,ah
  562.     sub cx,ax ! jb count_clear_2
  563. count_clear_1:
  564.     push cx ! mov dl,' '
  565.     ccpm c_rawio
  566.     pop cx ! loop count_clear_1
  567.     mov dx,call_dx ! call pos_cursor
  568. count_clear_2:    jmp epilog
  569.  
  570.     public    chroutput
  571. ;normal terminal output routine.
  572. ;enter with al=character to print at the current cursor position
  573. ;        ah=font to print in
  574. ;exit: cursor positioned after the printed char
  575. chroutput:
  576.     call prolog
  577.     jmps xychrout_1
  578.  
  579.     public    xychrout
  580. xychrout:
  581. ;enter with dh=col, dl=row, al=character to print, ah=font to print it in.
  582. ;exit: cursor positioned after the printed char
  583.     call prolog
  584.     call pos_cursor
  585. xychrout_1:
  586.     mov ax,call_ax            ;char to print
  587.     call set_font            ;set font from AH --- preserves AX
  588.     cmp ah,0FFh ! je xychrout_specials
  589.     mov dx,ax ! and al,7fh
  590.     cmp al,20h ! jb xychrout_ctrl    ;display control characters
  591.     ccpm c_write ! jmp epilog
  592.  
  593. xychrout_ctrl:
  594.     add al,40h ! test dl,80h
  595.     jz xychrout_ctrl1
  596.     add al,20h ! cmp al,07fh
  597.     jb xychrout_ctrl1
  598.     mov al,3ch
  599. xychrout_ctrl1:    mov ctrl_char,al
  600.     mov dx,offset ctrl_char_string
  601.     ccpm c_writestr ! jmp epilog
  602.  
  603. xychrout_specials:
  604.     mov bx,offset special_chars
  605.     cmp al,special_chars_lng
  606.     jbe $+4 ! mov al,0
  607.     xlat special_chars
  608.     mov dl,al ! ccpm c_write
  609.     jmp epilog
  610.  
  611. set_font:    ;set character fonts
  612.     cmp ah,curr_font ! jne $+3 ! ret    ;font already set
  613.     push ax ! mov dl,ah            ;get selected font to dl
  614.     cmp dl,0FFh ! je set_font_special    ;set special font
  615.     mov di,offset font_attribs
  616.     push ds ! pop es
  617.     rcr dl,1 ! jnc $+6
  618.     mov ax,'1;' ! stosw            ;set bold
  619.     rcr dl,1 ! jnc $+6
  620.     mov ax,'4;' ! stosw            ;set underline
  621.     rcr dl,1 ! jnc $+6
  622.     mov ax,'5;' ! stosw            ;set blink
  623.     rcr dl,1 ! jnc $+6
  624.     mov ax,'7;' ! stosw            ;set reverse
  625.     mov ax,'$m' ! stosw            ;terminate string
  626.     mov dx,offset font_select_string
  627. set_font_exit:
  628.     ccpm c_writestr                ;select font
  629.     pop ax ! mov curr_font,ah
  630.     ret
  631. set_font_special:
  632.     mov dx,offset special_font_string
  633.     jmps set_font_exit
  634.  
  635.  
  636.     public    hardware_announce
  637. ;Enter with dl=row, dh=col for string to announce
  638. ;ds:si=string to announce, cx=string length
  639. ;Preserves the cursor position !
  640. hardware_announce:
  641.     call prolog
  642.     mov word ptr temp,si        ;save string offset
  643.     mov ax,call_ds
  644.     mov word ptr temp+2,ax        ;save string segment
  645.     mov word ptr temp+4,cx        ;save string length
  646.     mov ah,curr_font ! push ax    ;save current font
  647.     mov dx,offset sv_cursor_string
  648.     ccpm c_writestr            ;save the cursor position
  649.     mov dx,call_dx
  650.     call pos_cursor            ;set new cursor position
  651.     cmp word ptr temp+4,0
  652.     jz hardware_announce_1
  653.     mov ah,9 ! call set_font    ;set reverse video + bold
  654.     mov dx,offset temp
  655.     ccpm c_writeblk            ;output string
  656.     mov cx,80 ! sub cx,call_cx
  657.     jbe hardware_announce_1
  658.     push cx ! mov dl,' '
  659.     ccpm c_write
  660.     pop cx ! loop $-8
  661. hardware_announce_1:
  662.     mov dx,offset clear_to_eol_string
  663.     ccpm c_writestr            ;clear to end of line
  664.     mov dx,offset rs_cursor_string
  665.     ccpm c_writestr            ;restore cursor position
  666.     pop ax ! call set_font        ;restore font
  667.     jmp epilog
  668.  
  669.     public    hardware_roll_down
  670. hardware_roll_down:
  671. ;exit: if this machine is capable of hardware roll, do it and exit with cy=0,
  672. ;  otherwise, exit with cy=1.  The hardware roll must leave the last line
  673. ;  on the screen as the last line.
  674. ;preserve bx.
  675.     call prolog
  676.     mov dx,offset roll_dn_string
  677.     jmps hw_roll_up
  678.  
  679.     public    hardware_roll_up
  680. hardware_roll_up:
  681. ;exit: if this machine is capable of hardware roll, do it and exit with cy=0,
  682. ;  otherwise, exit with cy=1.  The hardware roll must leave the last line
  683. ;  on the screen as the last line.
  684. ;preserve bx.
  685.     call prolog
  686.     mov dx,offset roll_up_string
  687. hw_roll_up:
  688.     ccpm c_writestr
  689.     clc ! jmp epilog
  690.  
  691.     public    hardware_ins_line
  692. hardware_ins_line:
  693. ;enter with al=line number where to insert the new line
  694.     call prolog
  695.     if v30
  696.     pushw offset ins_line_string
  697.     else
  698.     mov bx,offset ins_line_string ! push bx
  699.     endif
  700.     jmps hw_del_ins_line
  701.  
  702.     public    hardware_del_line
  703. hardware_del_line:
  704. ;enter with al=line number to delete
  705.     call prolog
  706.     if v30
  707.     pushw offset del_line_string
  708.     else
  709.     mov bx,offset del_line_string ! push bx
  710.     endif
  711. hw_del_ins_line:
  712.     xor dx,dx ! mov dl,al
  713.     call pos_cursor
  714.     pop dx ! ccpm c_writestr
  715.     jmp epilog
  716.  
  717.     public    block_cursor
  718. block_cursor:    stc ! ret
  719.  
  720.  
  721.     public    underscore_cursor
  722. underscore_cursor:    stc ! ret
  723.  
  724.     public    set_screen_color
  725. set_screen_color:
  726. ;enter with al=VT200 graphic rendition
  727. ; bit    0    All attributes off
  728. ;    1    Display bold
  729. ;    4    Display underlined
  730. ;    5    Display blinking
  731. ;    7    Display reverse
  732.     call prolog ! mov es,own_ds
  733.     mov di,offset help_buffer
  734.     xchg al,dl ! mov al,csi ! stosb        ;build control string
  735.     mov ah,';' ! mov cl,0
  736. set_screen_color_1:
  737.     rcr dl,1 ! jnc set_screen_color_2
  738.     mov al,cl ! and al,'0' ! stosw
  739.     inc cl ! cmp al,8 ! jb set_screen_color_1
  740. set_screen_color_2:
  741.     mov ax,'$m' ! dec di ! stosw
  742.     mov dx,offset help_buffer        ;write control string
  743.     ccpm c_writestr
  744.     jmp epilog
  745.  
  746. ;code    ends
  747.  
  748.     end