home *** CD-ROM | disk | FTP | other *** search
/ Piper's Pit BBS/FTP: ibm 0010 - 0019 / ibm0010-0019 / ibm0010.tar / ibm0010 / CDOSDSK4.ZIP / CDOSDSK4.TD0 / XIOS / CONIN.A86 < prev    next >
Encoding:
Text File  |  1989-01-26  |  29.4 KB  |  1,137 lines

  1. ; CONIN.A86
  2. title 'CONIN and PFKs'
  3. pagesize 60+11
  4. ;********************************************************
  5. ;*                            *
  6. ;*    CONSOLE INPUT / PROGRAMMABLE FUNCTION KEYS    *
  7. ;*    CDOS 6.0 XIOS                    *
  8. ;*    DRI OS ENGR, JMB                *
  9. ;*                            *
  10. ;********************************************************
  11. ; Major mods:
  12. ; 6.x
  13. ;  9 DEC 88 -- make all direct screen write apps full screen        GMS
  14. ; 12 OCT 88 -- patch out call io_switch                    GMS
  15. ; 11 Aug 88 -- call io_open/io_close round print_screen            IJ
  16. ;  9 AUG 88 -- lower PIN's priority during print_screen            GMS
  17. ;  9 AUG 88 -- use lcb_list instead of lcb_tab                GMS
  18. ;  2 AUG 88 -- change default F3 key to ctrlE                GMS
  19. ;  1 JUL 88 -- force mode change if 43 line mode app aborted        GMS
  20. ; 19 APR 88 -- added SunRiver support                    GMS
  21. ;  4 FEB 88 -- VS_CUR_TYPE_HW updated in trans_cur_type            GMS
  22. ;  4 DEC 87 -- VS_SCREEN_MODE now uses ROS video mode values        GMS
  23. ;  2 DEC 87 -- replaced ega$ with redefined video$            GMS
  24. ; 6.0
  25. ;  3 NOV 87 -- reset cursor bit in pc_kbd                GMS
  26. ; 17 OCT 87 -- Remove cntrl-break handler code                GMS
  27. ; 15 OCT 87 -- No line feed if pc_kbd if old mode pcmode 24 line    GMS
  28. ;  5 OCT 87 -- use larger cursor if ega mono                GMS
  29. ;  1 OCT 87 -- PFK tables made public for 386 PCTERM support        GMS
  30. ; 15 SEP 87 -- change to console numbers for conin_serial        GMS
  31. ; 10 AUG 87 -- PC_KBD supports new parameters                GMS
  32. ; 17 JUL 87 -- converted XIOS to small model                JW
  33. ; 5.2
  34. ;  1 APR 87 -- pc_shifts includes status bits for extended keyboard    GMS
  35. ;  4 MAR 87 -- bug fix, status line disappeared after mode change to B/W 80
  36. ;  3 MAR 87 -- changed default PFK value from SCEPTER
  37. ; 5.1
  38. ;  9 JAN 87 -- allow escape from print screen function
  39. ; 30 JUL 86 -- make conditional f-keys permanent
  40. ; 30 JUL 86 -- remove below
  41. ; 17 JUL 86 -- cntl-prntscr to cntl-p
  42. ; 17 JUL 86 -- change keypad defaults
  43. ; 27 MAY 86 -- return ^c for cntl_break
  44. ; 26 MAY 86 -- conditional f-keys for QXM
  45. ; 18 APR 86 -- support VS_CUR_TYPE_HW (for ega)
  46. ; 17 JAN 86 -- correct CONIN for dos pgms
  47. ; 15 OCT 85 -- CONIN/KEYBOARD-ISR redone for ROS usage
  48. ; 19 JUL 85 -- dress up PFK esc handlers
  49. ; 10 JUN 85 -- update 4.1 ASM86 XIOS to RASM86
  50.  
  51. ; include COPYRITE.TXT
  52.  
  53. nolist
  54. include CDOS.EQU
  55. include XIOS.EQU
  56. include PCHW.EQU
  57. include ROSDATA.EQU
  58. include ASCII.EQU
  59. include NAT.EQU
  60. list
  61. ; These have been included:
  62. ; include CDOS.EQU
  63. ; include XIOS.EQU
  64. ; include PCHW.EQU
  65. ; include ROSDATA.EQU
  66. ; include ASCII.EQU
  67. ; include NAT.EQU
  68.  
  69. CGROUP    group    CODE
  70. DGROUP    group    DATA
  71.  
  72.  
  73. public    io_const@, io_conin@, ww_key@, pc_kbd@, pc_shifts@
  74. public    pfk_tbl0$, pfk_tbl1$, pfk_tbl2$, pfk_tbl3$
  75. public    z_prog_pfk@, z_pfk_on@, z_pfk_off@
  76. public    check_no_switch@
  77.  
  78. eject
  79.  
  80.     cseg
  81. extrn           flagwait@:near,         flagset@:near    ;in HEADER.A86
  82. extrn         supervisor$:dword,           supif@:near
  83. extrn        io_list@:near,     conin_serial@:near    ;in LISTAUX.A86
  84. extrn          io_listst@:near
  85. extrn        io_open@:near,       io_close@ :near
  86. extrn         set_screen@:near,        vc_out_lf@:near    ;in WINDOWS1.A86
  87. extrn           z_up@:near,   z_erase_eos@:near
  88. extrn        show_cursor@:near
  89. extrn  leave_until_char@:near
  90. extrn           point_vs@:near,      get_all_mxs@:near    ; in WINDOWS2.A86
  91. extrn     ww_full_window@:near, new_pc_window@:near
  92. extrn       free_all_mxs@:near,     do_true_view@:near
  93. extrn      restore_state@:near,    check_full@:near
  94. extrn          io_switch@:near
  95. extrn      copy_full_top@:near,trans_cur_type@:near    ; in WINDOWS3.A86
  96. extrn          put_crt_s@:near                ; in WINDOWS3.A86
  97. extrn    switch_statline@:near,   io_statline@:near    ; in STATLINE.A86
  98. extrn        int16_entry@:near,   int10_entry@:near    ; in ROSIF.A86
  99. if SR
  100. extrn    test_srterm@   :near                ; in SRTERM.A86
  101. extrn    sr_ww_key@     :near
  102. endif
  103.  
  104.  
  105.     dseg
  106. public    pfk_code_tbl$
  107. public    pfk_scan_list$
  108. public    PFK_SCAN_LIST_SIZE
  109.  
  110. extrn        key_flag$:word, cntl_break$:byte        ; in KEYBOARD.A86
  111. extrn    beep_counter$:byte                ; in ISRS.A86
  112. extrn      switch_key$:byte,  wmenu_key$:byte
  113. extrn       prtsc_key$:byte
  114. extrn        ccb_list$:word,    lcb_list$:word        ; in PUBDATA.A86
  115. extrn    timer_count$:word,     blank$:word
  116. extrn      top_screen$:byte,    im_here$:byte        ; in WINDOWS3.A86
  117. extrn    graphic_bits$:byte, var_cursor$:word
  118. extrn    NX_kbd_type$ :byte, NX_natnlstat$ :byte     ; in NATDATA.A86
  119. extrn          video$ :byte                ; in WINDOWS1.A86
  120.  
  121. eject
  122.     cseg
  123. ;=========
  124. io_const@:
  125. ;=========
  126. ; This routine returns always ready, but it's really a nop, since
  127. ; normally PIN is the only one calling it, and PIN just sleeps on io_conin.
  128.  
  129.     xor    ax,ax                ; always ready
  130.     ret
  131.  
  132.  
  133. ;=========
  134. io_conin@:
  135. ;=========
  136.     cmp    dl,1
  137.      jb    conin_keyboard            ; jump if PC keyboard
  138.  
  139. ;;    sub    dl,1                ; else which serial terminal?
  140.     cmp    dl,NUM_AUX_PORTS        ; if too big...
  141.      ja    conin_no_go            ;  then forget it.
  142.     jmp    conin_serial@            ; else handle serial port
  143. conin_no_go:
  144.     sub    ax,ax                ; return null
  145.     ret
  146.  
  147. conin_keyboard:
  148. ; Get console input from the standard keyboard:
  149.  
  150.     mov    dl,top_screen$            ; current foreground console
  151.     call    point_vs@            ; get the screen structure
  152.  
  153.     test    VS_MODE,PCMODE_BIT        ; if a DOS program...
  154.      jnz    conin_wait1            ;  no func. keys so jump
  155.  
  156.     cmp    VS_PFK_COUNT,0            ; if no PFKs waiting...
  157.      je    conin_wait1            ;  then jump
  158.  
  159. ; Here if there are pending function key characters:
  160.     mov    si,VS_PFK_PTR            ; get the current pointer
  161.     lodsb                    ; get the value
  162.     test    al,al                ;  if valid then jump
  163.      jnz    conin_pfk
  164.     mov    VS_PFK_COUNT,al            ; else put 0 in the count
  165.     jmps    conin_wait1            ;  and wait for a key
  166.  
  167. conin_pfk:
  168.     mov    VS_PFK_PTR,si            ; update the pointer
  169.     dec    VS_PFK_COUNT            ; and the count
  170.     mov    ah,0                ; char is in al
  171.     ret
  172. eject
  173.  
  174. conin_wait:
  175. ;----------
  176. ; Here to wait for a real key to be typed:
  177.  
  178.     push    bx
  179.     push    cx
  180.     mov    dx,CI_FLAG            ; console-in flag
  181.     call    flagwait@
  182.     pop    cx
  183.     pop    bx
  184.  
  185. conin_wait1:
  186.     test    prtsc_key$,0ffh            ; did our isr slip this in?
  187.      jmpnz    print_screen
  188.     test    wmenu_key$,0ffh            ; anything there?
  189.      jmpnz    handle_wmenu
  190.     test    switch_key$,0ffh        ; how bout here?
  191.      jmpnz    handle_switch
  192.     test    cntl_break$,0ffh        ; set by int handler
  193.      jmpnz    handle_break            ; control break key
  194.  
  195.     mov    ah,1                ; ROS keyboard status
  196.     call    int16_entry@
  197.      jz    conin_wait            ; means nothing is available
  198.  
  199.     sub    ah,ah                ; else ROS key input function
  200.     call    int16_entry@
  201.  
  202.  
  203. ; Check for cntl-prntscr:
  204. ;    cmp    ax,7200h            ; what it looks like
  205. ;     jnz    not_cp
  206. ;    mov    ax,1710h            ; force to cntl-p
  207. ;not_cp: 
  208. ; The above was removed because it's not the IO system's job to do that.
  209. ; An application must be able to do an int 16h to get back 7200h, and some
  210. ; do.  The emulator must handle that if it's desired to do so.
  211.  
  212. ; Now check for a dos pgm:
  213.     test    VS_MODE,PCMODE_BIT        ; if DOS pgrm.
  214.      jnz    pc_kb_ret            ;  return immediately
  215.  
  216. ; Check for extended key:
  217.     or    al,al                ; extended? 
  218.      jnz    conin_ret            ; no, just ascii...jump.
  219.  
  220. ; Here if it may be a programmable:
  221.     cmp    ah,TWO_SCAN            ; If cntl @, leave it as null
  222.      je    conin_ret
  223.     cmp    ah,TAB_SCAN            ; if backtab, return FF
  224.      jne    not_bt
  225.     mov    al,FF                ; for COPYMENU
  226.     jmps    conin_ret
  227. not_bt:
  228.     cmp    ah,F1_SCAN            ; nothing below is programmable
  229.      jb    conin_done            ; no key yet
  230.     call    trans_pfk            ; maybe a PFK
  231.      jnz    conin_done            ; jump if no...loop
  232.     cmp    VS_PFK_EXP,0            ; if expansion is turned off
  233.      je    conin_done            ; then return the unexpanded key
  234.  
  235.     xchg    ah,al                ; pfk index to ah
  236.     call    point_pfk            ; a programmable
  237.      jmp    conin_keyboard            ; get first
  238. conin_done:
  239.     or    al,al
  240.      jmpz    conin_wait            ; nothing, so wait more
  241. conin_ret:
  242.     sub    ah,ah                ; else CPM spec.
  243. pc_kb_ret:
  244.     ret
  245. eject
  246.  
  247. ; Here if it was control break
  248. handle_break:
  249.     mov    ax,0ae03h            ; cntl-c set top bit on SCAN
  250.     mov    cntl_break$,0            ; code value for PC emulator
  251.     ret
  252.  
  253.  
  254.  
  255. handle_wmenu:
  256. ; Deal w/ WAKE or FULL menu keys:
  257.     mov    al,wmenu_key$
  258.     cmp    al,PLUS_SCAN
  259.      je    w_wake
  260.     cmp    al,DEL_SCAN
  261.      je    w_full
  262. ww_reset:
  263.     mov    wmenu_key$,0            ; zero it for next time
  264.     jmp    conin_wait            ; shouldn't get here
  265.  
  266. w_wake:
  267. ; Wake up the window manager:
  268.     cmp    im_here$,1            ; see if mgr is resident
  269.      jb    ww_reset            ;  forget it if not there
  270.     call    check_no_switch@        ; see if con. is no-sw. mode
  271.      jnz    ww_reset            ;  if so, forget it
  272.     cmp    graphic_bits$,0            ; if anyone is graphics,
  273.      jnz    ww_reset            ;  then also forget it
  274.  
  275.     mov    im_here$,2            ; indicate resident and active
  276.     mov    dx,WW_FLAG            ; WMENU flag
  277.     mov    key_flag$,dx            ; for the isr to use
  278.     mov    ww_stat_flag,TRUE        ; for ww_key status check
  279.     call    flagset@            ; wake it up
  280.     pushf                    ; fake an interrupt
  281.     callf    dword ptr dispatcher        ;  and a return
  282.     jmp    conin_wait            ; now wait for a wake-up
  283.  
  284. w_full:
  285. ; If current window is small, switch to full.
  286. ; If current window is full, switch to previous size.
  287.     mov    dl,top_screen$            ; get active console number
  288.     call    ww_full_window@            ; full/small switch
  289.     jmps    ww_reset            ; and wait for a real key
  290.  
  291.  
  292. handle_switch:
  293. ; The key combo detected by our ISR was a screen switch
  294.     call    get_all_mxs@            ; avoid deadly embrace w/ a
  295.     call    free_all_mxs@            ; proc. in suspend mode.
  296.     sub    al,al
  297.     xchg    al,switch_key$
  298.     sub    al,PAD4_SCAN            ; subtract bias
  299.     mov    ah,0FFh                ; indicates console switch
  300.     push    bx
  301.     mov    bx,offset switch_scan_table
  302.     xlat    bx                ; get console requested
  303.     pop    bx
  304.     cmp    al,-1
  305.      jne    sw_ret
  306.     jmp    conin_wait            ; should never happen
  307. sw_ret:
  308.     ret
  309. eject
  310.  
  311. trans_pfk:
  312. ;---------
  313. ; This routine takes an Extended scan code as returned from ROS and converts
  314. ; it to it's unexpanded CPM equivalent.
  315. ; Entry: ah = scan, al = 0
  316. ; Exit:  ZF = set, ah=PFK index, al=translation (w/ hi bit set)
  317. ;        if a CPM programmable
  318. ;     ZF = reset, ax = preserved if not
  319.  
  320.     push    es
  321.      mov    cx,ds
  322.      mov    es,cx                ; point es here
  323.      xchg    al,ah
  324.      mov    cx,PFK_SCAN_LIST_SIZE        ; how many to check
  325.      cld
  326.      mov    di,offset pfk_scan_list$
  327.      mov    dx,di
  328.      repne    scasb                ; look for it
  329.     pop    es
  330.      jz    found_scan            ; found it
  331.     xchg    al,ah
  332.     ret                    ; return w/ ZF = 0 if no match
  333.  
  334. found_scan:
  335.     dec    di
  336.     sub    di,dx
  337.     mov    ax,di
  338.     mov    ah,al
  339.     mov    al,pfk_code_tbl$[di]        ; get the cpm code
  340.     or    al,80h                ; set the high bit
  341.     cmp    al,al                ; ZF = 1
  342.     ret
  343. eject
  344.  
  345. point_pfk:
  346. ;---------
  347. ; Point to PFK table  --  called by z_prog_pfk and conin
  348. ;  entry:    al = pfk table index
  349. ;        bx -> vs_
  350. ;  exit:    VS_PFK_PTR -> pfk value
  351. ;        VS_PFK_COUNT = maximum char count
  352.  
  353.     sub    si,si                ; zero offset for low table
  354.     mov    cl,PFK_L_SIZE            ; chars per low pfk
  355.     cmp    al,LOW_PFKS            ; check for low table
  356.      jb    point_pfk1            ; skip if unshifted F1-F10
  357.     sub    al,LOW_PFKS            ; index into high table
  358.     mov    si,PFK_L_SIZE * LOW_PFKS    ; offset for high table
  359.     mov    cl,PFK_H_SIZE            ; chars per high pfk
  360. point_pfk1:
  361.     mul    cl                ; index into high table
  362.     add    si,ax
  363.     add    si,VS_PFK_TBL            ; add table offset
  364.     mov    VS_PFK_PTR,si            ; set initial pointer
  365.     mov    VS_PFK_COUNT,cl            ; and initial count
  366.     cmp    ax,ax                ; set zero flag
  367.     ret
  368.  
  369. eject
  370.  
  371. print_screen:
  372. ;------------
  373. ; Print the current screen (virtual console)
  374. ; to the current default list device (if unowned):
  375.     mov    di,rlr$            ; get running proc
  376.     mov    al,P_PRIOR[di]        ; priority
  377.     push    ax            ; and save for exit
  378.     mov    cl,P_PRIORITY
  379.     mov    dl,201            ; lower PIN's priority
  380.     push    si
  381.     call    supif@            ; during print screen
  382.     pop    si
  383.  
  384.     mov    al,top_screen$        ; get the top process
  385.     cbw
  386.     shl    ax,1            ; word pointer
  387.     xchg    ax,bx            ; bx = vc index
  388.     mov    bx,ccb_list$[bx]    ; bx -> top ccb
  389.     mov    si,C_OWNER[bx]        ; si = top process desc
  390.     mov    dl,P_LIST[si]        ; fetch default printer
  391.     xor    bh,bh
  392.     mov    bl,dl
  393.     shl    bx,1
  394.     mov    si,lcb_list$[bx]    ; si-> default lcb
  395.  
  396.     cli                ;; critical section
  397.     cmp    LCB_ATTACH[si],0    ;; if somebody owns this
  398.      jnz    print_screen_block    ;;   then just ignore key
  399.     mov    LCB_ATTACH[si],PRSC_PD    ;; insert a phony pd
  400.     sti                ;  interrupts now ok
  401.  
  402.     push    si            ; save for release
  403.     push    dx
  404.     mov    dh,1            ; L_ATTACH ourselves
  405.     call    io_open@        ; before we use the printer
  406.     pop    dx
  407.     push    dx
  408.     call    print_top_vc        ; now we print
  409.     pop    dx
  410.     mov    dh,1            ; L_DETACH ourselves
  411.     call    io_close@        ; we are finished with the printer
  412.     pop    si
  413.     mov    ax,LCB_QUEUE[si]    ; get the next proc in line
  414.     mov    LCB_ATTACH[si],ax    ;   and give it the lcb
  415.     test    ax,ax            ; if it's nobody
  416.      jz    print_screen_done    ;   then just leave
  417.  
  418.     mov    cx,F_WAKEUP        ; to awake the next process
  419.     lea    dx,LCB_QUEUE[si]    ; point to next
  420.     callf    supervisor$        ; non-stop flight
  421.     jmps    print_screen_done    ; that should do it
  422.  
  423. print_screen_block:
  424.     sti                ; release critical section
  425.     inc    beep_counter$        ; beep the error
  426. ;    jmps    print_screen_done    ;   and fall through
  427.  
  428. print_screen_done:
  429.     mov    prtsc_key$,0        ; reset
  430.     pop    dx            ; restore PIN's priority
  431.     mov    cl,P_PRIORITY
  432.     call    supif@
  433.     jmp    conin_wait1        ; await another character
  434.  
  435. ; The coast is clear, print the virtual console:
  436. ;  entry:    dl = printer number
  437.  
  438. print_top_vc:
  439.     push    dx            ; save the printer number
  440.     mov    dl,top_screen$        ; who is it anyway?
  441.     call    point_vs@        ; we keep bx now
  442.     mov    al,VS_MODE        ; save the match bit to keep
  443.     push    ax            ;   full screens in step
  444.     call    copy_full_top@        ; get vc in sync
  445.     pop    ax
  446.     mov    VS_MODE,al        ; restore mode with match bit
  447.     pop    dx            ; restore printer
  448.  
  449.     mov    si,0            ; vc pointer
  450.     mov    al,VS_CRT_ROWS        ; number of rows to print
  451.     cbw                ; wordize it
  452.     xchg    ax,cx            ; cx = row count
  453. print_top_rows:
  454.     push    cx            ; save row count
  455.     mov    cx,CRT_COLS        ; cx = column count
  456. print_top_cols:
  457.     call    print_top_in        ; get one char from vc
  458.     call    print_top_out        ;   and send it to printer
  459.     or    al,al
  460.     jnz    print_scrn_abort
  461.     loop    print_top_cols        ; for each column
  462.  
  463.     mov    al,CR            ; now do a crlf
  464.     call    print_top_out
  465.     or    al,al
  466.     jnz    print_scrn_abort
  467.     mov    al,LF
  468.     call    print_top_out
  469.     or    al,al
  470.     jnz    print_scrn_abort
  471.     pop    cx
  472.     loop    print_top_rows        ; do another row
  473. print_exit:
  474.     ret                ; finished
  475.  
  476. print_scrn_abort:            ; print screen aborted
  477.     pop    cx            ; exit ....
  478.     ret
  479.  
  480. print_top_in:
  481.     push    ds
  482.     mov    ds,VS_VC_SEG        ; reach into virtual console
  483.     lodsw                ; grab char and attrib
  484.     pop    ds
  485.     ret                ; with al = char
  486.  
  487. ; Exit: AL = 0 if ok
  488. ;         <> 0 keyboard abort..
  489. print_top_out:
  490.     push bx ! push cx !  push si
  491.     push    ax
  492.     push    dx
  493. not_ready:
  494.     mov    ah,1            ; ROS int 16 status
  495.     call    int16_entry@
  496.      jz    no_char
  497.     sub    ah,ah            ; ROS int 16 conin
  498.     call    int16_entry@        ; if so, get the char
  499.     cmp    al,ESC            ; was it escape
  500.     jz    abort_print
  501.     cmp    al,ETX            ; was it ^c?
  502.      jnz    no_char            ; jump if no
  503. abort_print:
  504.     pop    dx
  505.     pop    ax
  506.     jmps    pto_exit        ; return al <> 0
  507. no_char:
  508.     pop    dx            ; get device
  509.     push    dx
  510.     call    io_listst@
  511.     or     al,al
  512.     jz    not_ready
  513.     
  514.     pop    dx            ; get device
  515.     pop    cx            ; get the char for output
  516.     push    dx
  517.     call    io_list@        ; dl is right, print char
  518.     xor    al,al            ; ok return
  519.     pop    dx
  520. pto_exit:
  521.     pop si ! pop cx ! pop bx
  522.     ret
  523. eject
  524.  
  525. ; Check for console in no switch mode:
  526. ;  exit:    zf set switch is allowed
  527.  
  528. check_no_switch@:
  529. ;---------------
  530.     mov    al,top_screen$
  531.     cbw
  532.     shl    ax,1
  533.     xchg    bx,ax             ; bx = screen word ptr
  534.     mov    bx,ccb_list$[bx]     ; get foreground ccb
  535.     test    C_STATE[bx],CSM_NOSWITCH ; set flag if switchable
  536.     ret
  537.  
  538.  
  539.  
  540. ; XIOS back door entry to pass window manager a keystroke.
  541. ; Window manager will go to sleep on this call if cl < 0FEH.
  542.  
  543. ;  entry:    cl = 0FFH  =>  input/status
  544. ;    exit:    ax = char if char ready
  545. ;        ax = 0 if no char ready
  546. ;
  547. ;        cl = 0FEH  =>  status only
  548. ;    exit:    ax = 0FFH if char ready
  549. ;        ax = 0 if no char ready
  550. ;
  551. ;        cl < 0FEH  =>  wait for input
  552. ;    exit:    ax = char when ready
  553.  
  554. ;    exit:    if al = char then
  555. ;           ah = key type
  556. ;            0  =>  regular
  557. ;            0FFH  =>  special
  558.  
  559. ;=======
  560. ww_key@:
  561. ;=======
  562.  
  563. ; New code:
  564.     mov    di,rlr$
  565. if SR
  566.     cmp    P_CONS[di],NUM_VIR_CONS        ; is it master console
  567.     jb    main_vc
  568.     mov    dl,P_CONS[di]            ; get VC number
  569.     call    test_srterm@            ; is it SunRiver VC
  570.     jz    main_vc                ; no...
  571.     jmp    sr_ww_key@            ; SunRiver station
  572.  
  573. main_vc:
  574. endif
  575.     mov    prtsc_key$,0            ; we ignore this one
  576.     cmp    cl,0FEh
  577.      je    status_only
  578.     cmp    cl,0FFh
  579.      je    input_status
  580.  
  581. ; Here if cl < FE meaning wait for a char:
  582. wait:
  583.     push    cx
  584.     mov    dx,WW_FLAG
  585.     call    flagwait@
  586.     pop    cx
  587.      cmp    im_here$,1
  588.     jbe    wait
  589.  
  590. ; Check for keys:
  591. input_status:
  592.     sub    al,al
  593.     xchg    al,wmenu_key$            ; FULL or WAKE
  594.     test    al,al
  595.      jnz    return_wmenu_key
  596.     xchg    al,switch_key$
  597.     test    al,al
  598.      jnz    return_switch_key
  599.  
  600.     mov    ah,1                ; stat call
  601.     push    cx
  602.     call    int16_entry@
  603.     pop    cx
  604.      jnz    return_key
  605. no_kbd:
  606.     cmp    cl,0FFh                ; input or status?
  607.      jne    wait
  608.     sub    ax,ax                ; no char
  609.     ret
  610.  
  611. return_wmenu_key:
  612. ;----------------
  613.     cmp    al,DEL_SCAN            ; FULL?
  614.      jne    not_full
  615.     mov    ax,0FF7Eh
  616.     ret
  617. not_full:
  618.     mov    ax,0FF7Dh
  619.     ret                    ; wake
  620.  
  621.  
  622. return_switch_key:
  623. ;-----------------
  624.     sub    al,PAD4_SCAN            ; subtract bias
  625.     push    bx
  626.     mov    bx,offset switch_scan_table
  627.     xlat    bx
  628.     pop    bx
  629.     sub    ah,ah
  630.     add    ax,0FF70h            ; like WMENU wants it
  631.     ret
  632.  
  633.  
  634. return_key:
  635. ;----------
  636.     sub    ah,ah
  637.     push    cx
  638.     call    int16_entry@
  639.     pop    cx
  640.     test    al,al                ; extended code
  641.      jz    ext
  642.     sub    ah,ah                ; reg ascii
  643.     jmps    rk_ret
  644. ext:                
  645.     push    cx
  646.     call    trans_pfk
  647.     pop    cx
  648.      jnz    no_kbd                ; we really don't have a key
  649. got_cpm:
  650.     xchg    ah,al                ; WMENU wants the index
  651.     mov    ah,0ffh
  652. rk_ret:
  653.     ret
  654.  
  655.  
  656. status_only:
  657. ;-----------
  658.     mov    al,0ffh
  659.     test    wmenu_key$,al
  660.      jnz    st_done
  661.     test    switch_key$,al
  662.      jnz    st_done
  663.     mov    ah,1
  664.     call    int16_entry@
  665.     mov    al,0ffh
  666.      jnz    st_done
  667.     sub ax,ax ! ret
  668. st_done:
  669.     ret
  670. eject
  671.  
  672. ;************************************************
  673. ;*                        *
  674. ;*    ESCAPE PFK PROGRAMMING SUPPORT        *
  675. ;*                        *
  676. ;************************************************
  677.  
  678. z_prog_pfk@:
  679. ;-----------
  680. ; esc :  -  program a programmable function key
  681.  
  682.     call    leave_until_char@
  683.     push    es
  684.     push    ds ! pop es            ; local es for scan
  685.     mov    di,offset pfk_code_tbl
  686.     mov    dx,di                ; save start addr
  687.     mov    cx,LOW_PFKS + HIGH_PFKS        ; pfk count
  688.     repnz    scasb                ; scan for legal code
  689.     pop    es
  690.      jnz    z_pfk_done            ; done if not legal
  691.  
  692.     dec    di                ; correct overscan
  693.     sub    di,dx
  694.     xchg    ax,di                ; ax = index value
  695.     call    point_pfk            ; set pointer and count
  696.  
  697.     call    leave_until_char@
  698.     mov    di,VS_PFK_PTR            ; point to table entry
  699.     mov    [di],al                ; store the value
  700.     inc    di
  701.     mov    VS_PFK_PTR,di            ; bump the pointer
  702.  
  703.     test    al,al                ; if char = 0
  704.      jz    z_pfk_val1            ;   then we're done
  705.     dec    VS_PFK_COUNT            ; if entry is filled
  706.      jz    z_pfk_done            ;   we're also done
  707.     ret                    ; if not, stay here
  708. z_pfk_val1:
  709.     mov    VS_PFK_COUNT,al            ; zero the count
  710.  
  711. z_pfk_done:
  712.     jmp    restore_state@            ; reset the vector
  713. eject
  714.  
  715. z_pfk_off@:
  716. ;---------
  717. ; esc 6  -  turn pfk expansion off
  718.  
  719.     mov    VS_PFK_EXP,0            ; expansion flag false
  720.     ret
  721.  
  722. z_pfk_on@:
  723. ;---------
  724. ; esc 7  -  turn pfk expansion on
  725.  
  726.     mov    VS_PFK_EXP,0FFh            ; expansion flag true
  727.     ret
  728. eject
  729.  
  730. ;********************************
  731. ;*                *
  732. ;*    KEYBOARD  TABLES    *
  733. ;*                *
  734. ;********************************
  735.  
  736.     dseg
  737.  
  738. ; PFK codes used for programming and no-exp returns:
  739.  
  740. pfk_code_tbl$    db    ';<=>?@ABCD'        ; F1 - F10
  741.         db    'GHIKMOPQRS'        ; numeric pad
  742.         db    'abcdefghij'        ; alt F1 - F10
  743.         db    'klmnopqrst'        ; shift F1 - F10
  744.         db    'uvwxyz{|}~'        ; crtl F1 - F10
  745.  
  746.  
  747. ; List of extended codes which represent programmable keys:
  748. ; Same order as pfk_code_tbl.
  749. pfk_scan_list$    rb    0
  750.     db    3Bh,3Ch,3Dh,3Eh,3Fh,40h        ; unshifted F1-F10
  751.     db    41h,42h,43h,44h
  752.  
  753.     db    47h,48h,49h            ; pad home, up-arr, pgup
  754.     db    4Bh,4Dh                ; pad lft-arr, rt-arr
  755.     db    4Fh,50h,51h,52h,53h        ; pad end,dn-arr,pgdn,ins,del
  756.  
  757.     db    68h,69h,6Ah,6Bh,6Ch,6Dh        ; alt F1-F10
  758.     db    6Eh,6Fh,70h,71h
  759.  
  760.     db    54h,55h,56h,57h,58h,59h        ; shift F1-F10
  761.     db    5Ah,5Bh,5Ch,5Dh
  762.  
  763.     db    5Eh,5Fh,60h,61h,62h,63h        ; ctrl F1-F10
  764.     db    64h,65h,66h,67h
  765.  
  766. PFK_SCAN_LIST_SIZE    equ    offset $ - offset pfk_scan_list$
  767.  
  768. ; Console number  to be returned by a screen-switch key stroke:
  769.  
  770. switch_scan_table    db    3        ; scan = 75, PAD 4
  771.             db    -1        ; 76, PAD 5
  772.             db    -1        ; 77, PAD 6
  773.             db    -1        ; 78, PAD +
  774.             db    0        ; 79, PAD 1
  775.             db    1        ; 80, PAD 2
  776.             db    2        ; 81, PAD 3
  777.             db    -1        ; 82, PAD 0
  778.             db    -1        ; 83, PAD DEL
  779.  
  780. ww_stat_flag        db    0
  781. eject
  782.  
  783. pfk_tbl0$    rb 0                ; for virtual console #0
  784.  
  785. ; F1 - F10:
  786.     db    'HELP',CR,0,'              '
  787.     db    'FM',CR,0,'                '
  788.     db    05h,0,'                  '
  789.     db    'DIR',CR,0,'               '
  790.     db    'CHKDSK',CR,0,'            '
  791.     db    'DIR A:',CR,0,'            '
  792.     db    'FUNCTION',CR,0,'          '
  793.     db    'WMENU',CR,0,'             '
  794.     db    'DSKMAINT',CR,0,'          '
  795.     db    'STOP',CR,0,'              '
  796. eject
  797. ; numeric keypad:
  798.     dw    11h,0, 05h,0, 17h,0, 13h,0, 04h,0
  799.     dw    01h,0, 18h,0, 06h,0, 16h,0, 07h,0
  800. ;    dw    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7Fh,0
  801. ; alt F1 - alt F10:
  802.     dw    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  803. ; shift F1 - shift F10:
  804.     dw    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  805. ; ctrl F1 - crtl F10:
  806.     dw    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  807. eject
  808.  
  809. pfk_tbl1$    rb 0                ; for virtual console #1
  810.  
  811. ; F1 - F10:
  812.     db    'HELP',CR,0,'              '
  813.     db    'FM',CR,0,'                '
  814.     db    05h,0,'                  '
  815.     db    'DIR',CR,0,'               '
  816.     db    'CHKDSK',CR,0,'            '
  817.     db    'DIR A:',CR,0,'            '
  818.     db    'FUNCTION',CR,0,'          '
  819.     db    'WMENU',CR,0,'             '
  820.     db    'DSKMAINT',CR,0,'          '
  821.     db    'STOP',CR,0,'              '
  822. eject
  823. ; numeric keypad:
  824.     dw    11h,0, 05h,0, 17h,0, 13h,0, 04h,0    ; for cmd line edit
  825.     dw    01h,0, 18h,0, 06h,0, 16h,0, 07h,0
  826. ;    dw    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7Fh,0
  827. ; alt F1 - alt F10:
  828.     dw    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  829. ; shift F1 - shift F10:
  830.     dw    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  831. ; ctrl F1 - crtl F10:
  832.     dw    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  833. eject
  834.  
  835. pfk_tbl2$    rb    0            ; for virtual console #2
  836.  
  837. ; F1 - F10:
  838.     db    'HELP',CR,0,'              '
  839.     db    'FM',CR,0,'                '
  840.     db    05h,0,'                  '
  841.     db    'DIR',CR,0,'               '
  842.     db    'CHKDSK',CR,0,'            '
  843.     db    'DIR A:',CR,0,'            '
  844.     db    'FUNCTION',CR,0,'          '
  845.     db    'WMENU',CR,0,'             '
  846.     db    'DSKMAINT',CR,0,'          '
  847.     db    'STOP',CR,0,'              '
  848. eject
  849. ; numeric keypad:
  850.     dw    11h,0, 05h,0, 17h,0, 13h,0, 04h,0    ; for cmd line edit
  851.     dw    01h,0, 18h,0, 06h,0, 16h,0, 07h,0
  852. ;    dw    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7Fh,0
  853. ; alt F1 - alt F10:
  854.     dw    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  855. ; shift F1 - shift F10:
  856.     dw    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  857. ; ctrl F1 - crtl F10:
  858.     dw    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  859. eject
  860.  
  861. pfk_tbl3$    rb    0            ; for virtual console #3
  862.  
  863. ; F1 - F10:
  864.     db    'HELP',CR,0,'              '
  865.     db    'FM',CR,0,'                '
  866.     db    05h,0,'                  '
  867.     db    'DIR',CR,0,'               '
  868.     db    'CHKDSK',CR,0,'            '
  869.     db    'DIR A:',CR,0,'            '
  870.     db    'FUNCTION',CR,0,'          '
  871.     db    'WMENU',CR,0,'             '
  872.     db    'DSKMAINT',CR,0,'          '
  873.     db    'STOP',CR,0,'              '
  874. eject
  875. ; numeric keypad:
  876.     dw    11h,0, 05h,0, 17h,0, 13h,0, 04h,0    ; for cmd line edit.
  877.     dw    01h,0, 18h,0, 06h,0, 16h,0, 07h,0
  878. ;    dw    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7Fh,0
  879. ; alt F1 - alt F10:
  880.     dw    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  881. ; shift F1 - shift F10:
  882.     dw    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  883. ; ctrl F1 - crtl F10:
  884.     dw    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  885. eject
  886.  
  887. ;********************************************************
  888. ;*                            *
  889. ;*        PC MODE KEYBOARD SUPPORT        *
  890. ;*                            *
  891. ;********************************************************
  892.  
  893. ;    Code and data required for PC_MODE keyboard support in XIOS
  894. ;    MPV 22 NOV 83.
  895.  
  896.     cseg
  897.  
  898. ;==========
  899. pc_shifts@:
  900. ;==========
  901. ; New XIOS function 33 returns current vc shift states;
  902. ; Returns shift byte in AL:
  903. ;
  904. ; **** NOW with ADDED status bits ****
  905. ; returns extended keyboard shift status in AH 
  906.  
  907.     mov    ch,0
  908.     test    NX_natnlstat$,NX_nkbd_bit ; is it US keyboard
  909.     jz    norm_kbd        ; yes...
  910.     test    NX_kbd_type$,NX_enhanced ; international enchanced keyboard
  911.     jz    norm_kbd        ; no .. normal keyboard
  912.     mov    ch,1
  913. norm_kbd:
  914.     push    ds
  915.     mov    ax,PC_SEGMENT
  916.     mov    ds,ax
  917.     mov    ah,kb_flag_1_40
  918.     and    ah,SYS_SHIFT
  919.     mov    cl,5
  920.     shl    ah,cl
  921.     mov    al,kb_flag_1_40
  922.     and    al,73h            ; get rid of sys_shift,hold and insert
  923.     or    ah,al            ; mash into AH
  924.     mov    al,kb_flag_3_40        ; get extended status bits
  925.     and    al,0ch            ; remove hidden flag bits
  926.     or    ah,al            ; and merge
  927.     
  928.     mov    al,kb_flag_40        ; get normal status bits into al
  929.     or    ch,ch
  930.     jz    norm_kbd1
  931.     test    kb_flag_1_40,L_ALT    ;; is left ALT down
  932.     jnz    norm_kbd1        ; yes
  933.     and    al,not ALT_BIT        ; else make sure no ALT status
  934. norm_kbd1:                ; bit from Right ALT key
  935.     pop    ds
  936.     ret
  937.  
  938.  
  939. ;=======
  940. pc_kbd@:
  941. ;=======
  942. ; New XIOS function 32 switches VC input mode to/from PC MODE
  943. ; and also sets up the display for 25 lines without status line
  944. ; The COMMAND processor checks the ATTRIBUTES field in the CCB
  945. ; before loading a DOS process to check that the virtual console
  946. ; provides all the video services required by the DOS process as
  947. ; defined in its PIF data.
  948. ; If no PIF data available function is called with value
  949. ; as set in ATTRIBUTES field of CCB.
  950. ; (see :-  CCB definition in PUBDATA.A86)
  951. ;
  952. ;  entry:    dl = vcons number
  953. ;        cl = following Bits used
  954. ;             Bit 0 : = set when DOS program executes
  955. ;                   reset on termination
  956. ;             Bit 1 : = process requires 25 lines
  957. ;             Bit 2 : = process uses ANSI escape sequences
  958. ;             Bit 3 : = process uses Ros INT 10h
  959. ;             Bit 4 : = process accesses PC video hardware
  960. ;
  961. ;  exit:    ax = 0 success        ax = 0FFFFh failure
  962.  
  963.     cmp    dl,NUM_VIR_CONS            ; see if dl is too big
  964.      jb    pc_kbd_good            ; if it isn't, skip
  965. if SR
  966.     call    test_srterm@            ; test if SUN RIVER main console
  967.     jnz    pc_kbd_good            ; yes..
  968. endif
  969.     mov    ax,0FFFFh            ; if one of the serial consoles
  970.     ret                    ;   then deny pc-mode
  971.  
  972. pc_kbd_good:
  973.     push    cx                ; save enable/disable
  974.     push    dx                ; save the vc number
  975.     call    point_vs@            ; bx -> virtual con structure
  976.     mov    VS_PC_SHIFTS,0            ; clear the shift flags
  977.     test    cl,1
  978.      jz    disable_pcmode
  979.  
  980.     mov    al,VS_SCREEN_MODE        ; get the current screen mode
  981.     mov    VS_SCREEN_SAVE,al        ; store
  982.     or    VS_MODE,PCMODE_BIT        ; turn on the PC Mode
  983.     mov    al,CRT_ROWS_C            ; assume 24 lines
  984.     test    cl,CA_25LINES            ; do we require 25 line mode
  985.     jz    set_lines            ; no 
  986.     mov    al,CRT_ROWS_P            ; set 25 lines
  987. set_lines:
  988.     mov    VS_CRT_ROWS,al
  989.     test    cl,CA_HARDWARE            ; do we require screen writes
  990.     jz    is_full                ; no 
  991.     call    check_full@            ; see if it's full
  992.      jz    is_full                ; skip if full
  993.     mov    dl,VS_NUMBER
  994.     call    ww_full_window@            ; make 25 line DOS app full 
  995. is_full:
  996.     jmp    set_pc_window            ; if full, redo the window
  997.     
  998. disable_pcmode:
  999.     mov    ax,timer_count$            ; set by INIT or SETUP
  1000.     out    TIMER_0_REG,al            ;   in case some nasty pc mode
  1001.     mov    al,ah                ;   program has hammered it.
  1002.     out    TIMER_0_REG,al
  1003.  
  1004.     test    VS_MODE1,LINE_43_MODE        ; if 43 line mode ?
  1005.     jnz    change_to_alpha            ; force mode change
  1006.     mov    al,VS_SCREEN_SAVE        ; if the old mode is the same as the
  1007.     cmp    VS_SCREEN_MODE,al        ;   new, then skip the reset
  1008.      jz    disable_pcmode1
  1009.  
  1010. ; Here we want to skip the change-to-alpha if the former mode was 3 and
  1011. ; the new one is 2, to leave any final DOS pgm. messages on the screen.  But,
  1012. ; change the mode variable to 3 because the statline driver requires that.
  1013.     cmp    al,03
  1014.      jne    change_to_alpha
  1015.     cmp    VS_SCREEN_MODE,02
  1016.      jne    change_to_alpha            ; 3-2, skip change but fake-out
  1017.     mov    VS_SCREEN_MODE,al
  1018.     mov    switch_flag,1            ; must do io_switch before exit
  1019.     jmps    disable_pcmode1
  1020.  
  1021. change_to_alpha:
  1022.     mov    cl,VS_SCREEN_SAVE        ; get ROS mode
  1023.     push    bx
  1024.     call    set_screen@            ; do mode switch
  1025.     pop    bx
  1026.  
  1027. disable_pcmode1:
  1028.     cmp    VS_CRT_ROWS,CRT_ROWS_C        ; is old mode set to cpm size
  1029.     je    no_lf
  1030.     mov    dx,VS_CURSOR
  1031.     call    vc_out_lf@            ; force a scroll if at bottom
  1032.     mov    dx,VS_CURSOR
  1033.     call    z_up@                ; then move up a line to restore
  1034. no_lf:
  1035.     and    VS_MODE,not PCMODE_BIT      ; turn pc mode off
  1036.     mov    VS_CRT_ROWS,CRT_ROWS_C        ; set to cpm size
  1037.  
  1038. ; Restore the cursor in case pc mode did something funny:
  1039.     or    VS_MODE,CURSOR_BIT        ; make sure cursor on
  1040.     mov    cx,MONO_CURSOR
  1041.     cmp    VS_SCREEN_MODE,07        ; if color monitor, skip
  1042.      je    disable_color
  1043.     mov    cx,var_cursor
  1044. disable_color:
  1045.     push    cx
  1046.     call    trans_cur_type@            ; update VS_CUR_TYPE_HW
  1047.     pop    cx
  1048.  
  1049.     mov    VS_CUR_TYPE,cx
  1050.     mov    ah,1                ; int 10 function #
  1051.     call    int10_entry@            ; set cursor type
  1052.     call    show_cursor@            ; display correct cursor
  1053.  
  1054. set_pc_window:
  1055.     pop    dx
  1056.     push    dx
  1057.     cmp    VS_ROWSB,CRT_ROWS_C        ; if neither 24 or 25 lines
  1058.      jb    set_pc_statline            ;   then skip
  1059.  
  1060.     mov    al,CRT_COLS
  1061.     cmp    VS_COLSB,al            ; clear zf if wrong width
  1062.      jnz    set_pc_statline
  1063.  
  1064. ; So, we have a full screen, better make a whole new window:
  1065.  
  1066.     mov    ah,VS_CRT_ROWS
  1067.     sub    ax,0101h            ; bottom right corner
  1068.     push    ax
  1069.     call    get_all_mxs@            ;; lock out the world
  1070.     cmp    dl,top_screen$            ; if we're not top screen exit
  1071.     jne    set_pc_statlinea
  1072.     call    copy_full_top@            ;; update the image
  1073. set_pc_statlinea:
  1074.     pop    ax
  1075.     mov    VS_BOT_RIGHT,ax            ;; save new b_r corner
  1076.     mov    VS_TOP_LEFT,0            ;; make sure of t_l too
  1077.     push    bx
  1078.     call    new_pc_window@            ;; special pc mode entry
  1079.     pop    bx
  1080.  
  1081. set_pc_statline:
  1082.     pop    dx                ; restore vc number
  1083.     cmp    dl,top_screen$            ; now, if we're the top screen
  1084.      jnz    set_pc_clear            ;   then take care of the
  1085.     call    switch_statline@        ;   status line switch
  1086.     mov    al,0
  1087.     xchg    al,switch_flag            ; do we need to do switch
  1088.     cmp    al,1
  1089.     jne    set_pc_clear1
  1090.     push    bx
  1091.     mov    dl,top_screen$            ; do switch to restore 
  1092. ;;;;;;    call    io_switch@            ; status line update
  1093.     pop    bx
  1094. set_pc_clear1:
  1095. if SR
  1096.     mov    di,2*S_L_OFFSET            ; point to physical statline
  1097.     mov    cx,80                ; chars per line
  1098.     mov    ax,blank$
  1099.     call    put_crt_s@            ; store to our monitor
  1100.  
  1101.     mov    dl,top_screen$            ; do switch to restore 
  1102.     xor    dh,dh
  1103.     mov    si,dx
  1104.     shl    si,1
  1105.     mov    si,ccb_list$[si]    ; get ccb pointer for VC
  1106.     mov    dl,C_PC[si]        ; logical physical console number
  1107.     mov    cx,0
  1108.     push    bx
  1109.     call    io_statline@        ; force update of status line
  1110.     pop    bx
  1111. endif
  1112. set_pc_clear:
  1113.     push    dx            ; #IJ
  1114.     call    do_true_view@            ; correct cursor position
  1115.     pop    dx            ; #IJ
  1116.     pop    cx                ; restore enable/disable
  1117.     test    cl,1                ; if disable then done
  1118.      jz    set_pc_done
  1119.  
  1120.     cmp    dl,top_screen$        ; #IJ if we're not the top screen
  1121.      jnz    set_pc_done        ; #IJ  then do no more
  1122.     
  1123.     mov    dx,VS_CURSOR
  1124.     call    z_erase_eos@            ; clear from cursor to screen end
  1125. set_pc_done:
  1126.     sub    ax,ax                ; always successful
  1127.     ret
  1128.  
  1129.     dseg
  1130.  
  1131. switch_flag    db    0
  1132.  
  1133. end
  1134.  
  1135. ; END OF CONIN.A86
  1136.  
  1137.