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

  1. ;emacs.asm - last modified Fri Aug 18 23:01:26 1989 PDT - mbf
  2. ;History:722,45
  3. ;Sat Jul 29 14:53:07 1989 Added cc primitive for setting cursor type (lines
  4. ;    1852, 1932, 2006; see also ibm.asm) [mbf]
  5. ;Fri May 26 09:30:20 1989 Added bp variable (0..1) for toggling beep timeout
  6. ;    (lines 117, 147, 176, 238-39, 630-33, 725-27; see also ibm.asm) [mbf]
  7. ;10-02-88 20:50:38 add a buffer for mouse clicks.
  8. ;10-01-88 14:50:07 make #(lv,ms) return four numbers.
  9. ;09-23-88 20:37:28 clean up auto_save
  10. ;09-18-88 23:13:35 Add "string index", si_prim
  11. ;09-18-88 12:32:52 use lowercase pathnames in #(lv,cd).
  12. ;09-12-88 23:40:00 if the buffer-modified flag is 2, then the buffer is read-only.
  13. ;09-10-88 05:44:35 Use bl instead of num_screen_cols in announce().
  14. ;09-10-88 05:40:21 try returning / when they try to find it.
  15. ;08-16-88 00:23:20 change auto save so it only count changes to a file.
  16. ;07-24-88 23:25:20 Put the third argument to #(an) *after* the cursor.
  17. ;07-19-88 00:17:27 Create 'li' primitive.
  18. ;05-15-88 19:58:02 Remove reference to non-existent init_memory [kdb]
  19. ;05-07-88 22:07:45 if stdout and stderr are redirected, don't bother swapping screens.
  20. ;04-17-88 22:47:53 add the ex redirect code.
  21. ;04-03-88 23:28:39 move the version number into another file.
  22. ;04-01-88 22:47:59 add tc variable.
  23. ;03-30-88 21:22:49 move xlat_to_mark to memory.asm
  24. ;03-30-88 20:48:45 add tr_prim
  25. ;03-27-88 19:47:54 add store_firstline and store_lastline
  26. ;03-26-88 15:53:35 put the variables in alphabetic order.
  27. ;03-26-88 14:24:12 expand the ?v_prim symbols to the two letter symbols.
  28. ;03-26-88 10:02:03 get rid of old single-letter variables.
  29. ;03-26-88 10:01:52 add auto-save counter
  30. ;03-23-88 23:56:09 Add variables 'fo' and 'bo' for original colors.
  31. ;03-13-88 12:27:10 remove #(ef)
  32. ;03-10-88 22:41:26 add #(l?)
  33. ;12-13-87 21:17:22 
  34. ;11-26-87 11:45:11 fix goofyness in it_prim.
  35. ;09-09-87 00:49:51 after fixing redisp for the column redisplay bug, bump the version.
  36. ;07-15-87 22:10:51 up the version letter because I gave a copy to Pat.
  37. ;07-13-87 23:11:23 remove xyputch.
  38. ;07-13-87 23:00:03 move things around between files.
  39. ;07-10-87 23:09:06 add #(lv,vn) - version number.
  40. ;07-10-87 22:54:07 fix the problem with #(lv,xx) where xx is not a variable.
  41. ;07-10-87 00:23:10 remove trailing blank from #(sv,cd,...)
  42. ;07-10-87 00:17:28 add #(sv,cd,...)
  43. ;07-08-87 21:37:15 put a trailing \ on 'cd' variable.
  44. ;07-08-87 21:01:05 create the 'cd' variable.
  45. ;07-05-87 14:16:38 make complete paths in ff_prim an assembly-time option.
  46. ;07-05-87 14:02:28 compute the prefix length in ff_prim properly.
  47. ;07-05-87 11:55:54 Return full pathname and lowercase in ff_prim.
  48. test_prims    equ    0
  49.     page    ,132
  50.  
  51.     .xlist
  52.     include    memory.def
  53.     include    mint.def
  54.     include    findfile.def
  55.  
  56. data    segment    byte public
  57.  
  58.     extrn    version_number: byte, version_number_len: abs
  59.  
  60. ;the following externs are defined in 'mintprim'
  61.     extrn    read_errors: word
  62.     extrn    write_errors: word
  63.     extrn    data_bottop: word
  64.     extrn    data_topbot: word
  65.  
  66. ;the following externs are defined in 'mintscan'
  67.     extrn    fbgn: word, fend: word
  68.     extrn    next_ids: word
  69.  
  70. ;the following externs are defined in the computer-dependent file.
  71.     extrn    max_screen_line: byte
  72.     extrn    num_screen_cols: word
  73.     extrn    computer_name: byte
  74.     extrn    computer_name_len: abs
  75.  
  76.     public    filename, filename2
  77. filename    db    64 dup(?)
  78. filename2    db    64 dup(?)
  79.  
  80. rename_error    db    'Rename error'
  81. rename_error_len    equ    $-rename_error
  82.  
  83. speller_txt    db    'Speller'
  84. speller_txt_len    equ    $-speller_txt
  85.  
  86.     extrn    next_redisp_line: word
  87.  
  88.     public    standard_ids
  89. standard_ids    db    '#(d,#(g))',0
  90.  
  91. nokbd_ids    db    '#(k)#(d,#(g))',0
  92. auto_ids    db    '#(Fauto-save)',0
  93.  
  94. auto_save_limit    dw    0
  95. auto_save_cntr    dw    0
  96.  
  97. byte_ptr    label    byte
  98.  
  99. foreback_color    label    word
  100. fore_color    db    7
  101. back_color    db    0
  102.  
  103. ex_stdin    dw    ?        ;-1 if we're not redirecting.
  104. ex_stdout    dw    ?        ;-1 if we're not redirecting.
  105. ex_stderr    dw    ?        ;-1 if we're not redirecting.
  106.     extrn    swap_screen_flag: word    ;=1 if we should swap screens.
  107.  
  108.     extrn    tab_size: word
  109.     extrn    fore_original: byte
  110.     extrn    back_original: byte
  111.  
  112. variable_table    label    byte
  113.     db    'as'            ;Auto Save
  114.     db    'bc'            ;Background Color
  115.     db    'bl'            ;Bot Line
  116.     db    'bo'            ;Background Original
  117.     db    'bp'            ;Beep Toggle [mbf]
  118.     db    'bs'            ;Bot Scroll
  119.     db    'cd'            ;Current Directory
  120.     db    'cl'            ;Line Number
  121.     db    'cn'            ;Computer Name
  122.     db    'cs'            ;Column on Screen
  123.     db    'cw'            ;Current Window
  124.     db    'fc'            ;Foreground Color
  125.     db    'fo'            ;Foreground Original
  126.     db    'im'            ;Inverse Mark
  127.     db    'is'            ;Inhibit Snow
  128.     db    'lc'            ;Lefthand Column
  129.     db    'mb'            ;Modified Buffer
  130.     db    'ms'            ;Mint Space
  131.     db    'nl'            ;Number of Lines
  132.     db    'ow'            ;Other Window
  133.     db    'pb'            ;Percent of Buffer
  134.     db    'rs'            ;Row on Screen
  135.     db    'tc'            ;Tab Columns
  136.     db    'tl'            ;Top Line
  137.     db    'ts'            ;Top Scroll
  138.     db    'vn'            ;Version Number
  139.     db    'ws'            ;Whitespace Showing
  140. variable_count    equ    ($-variable_table)/2
  141.  
  142. lv_prim_table    label    word
  143.     dw    lv_prim_as
  144.     dw    lv_prim_bc
  145.     dw    lv_prim_bl
  146.     dw    lv_prim_bo
  147.     dw    lv_prim_bp        ;mbf
  148.     dw    lv_prim_bs
  149.     dw    lv_prim_cd
  150.     dw    lv_prim_cl
  151.     dw    lv_prim_cn
  152.     dw    lv_prim_cs
  153.     dw    lv_prim_cw
  154.     dw    lv_prim_fc
  155.     dw    lv_prim_fo
  156.     dw    lv_prim_im
  157.     dw    lv_prim_is
  158.     dw    lv_prim_lc
  159.     dw    lv_prim_mb
  160.     dw    lv_prim_ms
  161.     dw    lv_prim_nl
  162.     dw    lv_prim_ow
  163.     dw    lv_prim_pb
  164.     dw    lv_prim_rs
  165.     dw    lv_prim_tc
  166.     dw    lv_prim_tl
  167.     dw    lv_prim_ts
  168.     dw    lv_prim_vn
  169.     dw    lv_prim_ws
  170.  
  171. sv_prim_table    label    word
  172.     dw    sv_prim_as
  173.     dw    sv_prim_bc
  174.     dw    sv_prim_bl
  175.     dw    sv_prim_bo
  176.     dw    sv_prim_bp        ;mbf
  177.     dw    sv_prim_bs
  178.     dw    sv_prim_cd
  179.     dw    sv_prim_cl
  180.     dw    sv_prim_cn
  181.     dw    sv_prim_cs
  182.     dw    sv_prim_cw
  183.     dw    sv_prim_fc
  184.     dw    sv_prim_fo
  185.     dw    sv_prim_im
  186.     dw    sv_prim_is
  187.     dw    sv_prim_lc
  188.     dw    sv_prim_mb
  189.     dw    sv_prim_ms
  190.     dw    sv_prim_nl
  191.     dw    sv_prim_ow
  192.     dw    sv_prim_pb
  193.     dw    sv_prim_rs
  194.     dw    sv_prim_tc
  195.     dw    sv_prim_tl
  196.     dw    sv_prim_ts
  197.     dw    sv_prim_vn
  198.     dw    sv_prim_ws
  199.  
  200.     extrn    stackp: byte
  201.  
  202.     public    trace_handle
  203. trace_handle    dw    -1
  204.  
  205. sa_jump        dw    ?
  206. sa_n_jump    dw    ?
  207.  
  208. mouse_buffer    dw    0        ;mouse button buffer.
  209.  
  210. data    ends
  211.  
  212.  
  213. code    segment    byte public
  214.     assume    cs:code, ds:data, es:data
  215.  
  216.     extrn    set_screen_color: near
  217.  
  218.     extrn    redisplay: near        ;ax=line to leave the cursor on.
  219.  
  220.     extrn    buffer_free: near
  221.     extrn    read_firstline: near
  222.     extrn    read_lastline: near
  223.     extrn    store_firstline: near
  224.     extrn    store_lastline: near
  225.     extrn    read_newrow: near
  226.     extrn    read_linesbefore: near
  227.     extrn    read_linecount: near
  228.     extrn    read_buffer_modified: near
  229.     extrn    store_buffer_modified: near
  230.     extrn    read_ibm_cga: near
  231.     extrn    store_ibm_cga: near
  232.     extrn    read_inverse_mark: near
  233.     extrn    store_inverse_mark: near
  234.  
  235.     extrn    read_showblanks: near
  236.     extrn    store_showblanks: near
  237.  
  238.     extrn    read_beep: near        ;mbf
  239.     extrn    store_beep: near
  240.  
  241.     extrn    read_top_percent: near
  242.     extrn    read_bot_percent: near
  243.     extrn    store_top_percent: near
  244.     extrn    store_bot_percent: near
  245.  
  246.     extrn    read_other_window: near
  247.     extrn    read_current_window: near
  248.     extrn    store_other_window: near
  249.     extrn    store_current_window: near
  250.  
  251.     extrn    chrout: near        ;al=char to overwrite to screen.
  252.  
  253.     extrn    paint_screen: near    ;sets entire screen to be repainted.
  254.  
  255.     extrn    paint_window: near    ;causes the current buffer to be shown in the current window.
  256.  
  257.     extrn    insert_string: near    ;si,cx describe the string.
  258.  
  259.     extrn    buffer_allocate: near    ;entry: cx=buffer number to select,
  260.                     ;  cx=0 to create new buffer.
  261.                     ;  ax=0 for read/write buffer.
  262.                     ;exit: ax=new buffer number if enough
  263.                     ;  memory, ax=0 otherwise.
  264.     extrn    read_mark: near        ;entry: al=mark to read to.
  265.                     ;exit: es:si, cx describing string.
  266.  
  267.     extrn    del_to_mark: near    ;entry: al=mark to delete to.
  268.  
  269.     extrn    set_mark: near        ;entry: al=dest mark, ah=source mark.
  270.  
  271.     extrn    goto_mark: near        ;entry: al=mark to go to.
  272.  
  273.     extrn    xlat_to_mark: near    ;entry: al=mark to translate to.
  274.                     ;  es:bx = translate table,
  275.                     ;  dx = length of translate table.
  276.  
  277.     extrn    stack_marks: near    ;entry: ax>0 to create temp marks,
  278.                     ;  ax=0 to delete temp marks,
  279.                     ;  ax<0 to create perm marks and delete
  280.                     ;  all temp marks.
  281.  
  282.     extrn    compute_cursor: near    ;exit with dx=column (0..65535)
  283.  
  284.     extrn    set_column: near    ;entry: ax=desired column
  285.  
  286.     extrn    set_line: near        ;entry: ax=desired line.
  287.  
  288.     extrn    read_firstcolumn: near    ;get the left hand column.
  289.  
  290.     extrn    store_firstcolumn: near    ;set the left hand column.
  291.  
  292.     extrn    ring_the_bell: near
  293.  
  294.  
  295. ;the following extrns are in the computer-dependent file
  296.     extrn    xychrout: near
  297.     extrn    clear_count: near
  298.     extrn    position_cursor: near
  299.     extrn    check_for_key: near
  300.  
  301. ;the following extrns are in 'files'
  302.     extrn    read_file: near
  303.     extrn    write_file: near
  304.  
  305. ;the following extrns are in 'search'
  306.     extrn    regexp_pat: near
  307.     extrn    set_pattern: near
  308.     extrn    search: near
  309.  
  310. ;the following extrns are in 'mintscan'
  311.     extrn    nomem: near
  312.  
  313. ;the following externs are in 'pick'
  314.     extrn    pick_on: near
  315.     extrn    pick_off: near
  316.     extrn    check_pick: near
  317.     extrn    get_pick_values: near
  318.  
  319.  
  320.     public    init_ids
  321. init_ids:
  322.     mov    sp,offset stackp
  323.     call    check_for_key        ;use the standard ids only if kbd ready.
  324.     jnz    init_ids_1
  325.     mov    ax,offset nokbd_ids
  326. init_ids_2:
  327.     cmp    next_ids,offset standard_ids    ;only use a different one if
  328.     jne    init_ids_1            ;we're at the standard ids.
  329.     mov    next_ids,ax
  330. init_ids_1:
  331.     jmp    init_ids_continue
  332.  
  333.     extrn    init_ids_continue: near
  334.  
  335.  
  336. write_protect:
  337.     call    read_buffer_modified    ;see if this buffer is read-only.
  338.     cmp    al,2
  339.     je    write_protect_1        ;yes - leave immediately.
  340.     ret
  341. write_protect_1:
  342.     pop    ax            ;discard our return address.
  343.     jmp    return_null
  344.  
  345.  
  346. auto_save:
  347.     mov    ax,auto_save_cntr    ;is the counter already at zero?
  348.     or    ax,ax            ;is the counter already at zero?
  349.     je    auto_save_1        ;yes - don't decrement it.
  350.     dec    ax            ;time to auto-save?
  351.     jne    auto_save_1        ;no.
  352.     mov    ax,auto_save_limit    ;yes - reset the counter.
  353.     mov    next_ids,offset auto_ids
  354. auto_save_1:
  355.     mov    auto_save_cntr,ax
  356.     ret
  357.  
  358.  
  359.     if    test_prims
  360.  
  361. ;test primitive.  fills memory to the max.  strictly for testing only.
  362. ts_prim:
  363.     di_points_fbgn
  364.     mov    cx,data_topbot
  365.     sub    cx,di
  366.     dec    cx
  367.     push    cx
  368.     mov    al,' '
  369.     rep    stosb
  370.     pop    cx
  371.     jmp    return_sicx
  372.  
  373.  
  374. formSeg    segment    public
  375. ;the following externs are defined in 'mintform'
  376.     extrn    formhash: word
  377. formSeg    ends
  378.  
  379. ;dump formhash.  strictly for testing only.
  380. tt_prim:
  381.     mov    cx,256
  382.     di_points_fbgn
  383.     chk_room_cnt
  384.     mov    si,offset formhash
  385. tt_prim_1:
  386.     test    cx,3fh
  387.     jne    tt_prim_4
  388.     mov    ax,LINENEW
  389.     stosw
  390. tt_prim_4:
  391.     mov    dx,0
  392.     lodsw
  393.     mov    bx,ax
  394. tt_prim_2:
  395.     cmp    bx,NIL        ;at end of list yet?
  396.     je    tt_prim_3
  397.     mov    bx,[bx].hash_link
  398.     inc    dx
  399.     jmp    tt_prim_2
  400. tt_prim_3:
  401.     mov    ax,dx        ;get the count
  402.     add    al,'0'        ;convert to ascii (cheaply)
  403.     stosb
  404.     loop    tt_prim_1
  405.     jmp    return_tos
  406.  
  407.     endif
  408.  
  409. ;redisplay.
  410. rd_prim:
  411.     call    getarg1
  412.     jcxz    rd_prim_1
  413.     call    paint_screen        ;paint,
  414.     call    paint_window
  415.     jmp    short rd_prim_3        ; always redisplay
  416. rd_prim_1:
  417.     call    check_for_key        ;redisplay only if no key waiting.
  418.     jnz    rd_prim_2
  419. rd_prim_3:
  420.     call    redisplay
  421. rd_prim_2:
  422.     jmp    return_null
  423.  
  424.  
  425. ;overwrite the screen.
  426. ow_prim:
  427.     call    getarg1
  428.     jcxz    ow_prim_2
  429. ow_prim_1:
  430.     lodsb
  431.     xor    ah,ah
  432.     call    chrout
  433.     push    si
  434.     push    cx
  435.     pop    cx
  436.     pop    si
  437.     loop    ow_prim_1
  438. ow_prim_2:
  439.     jmp    return_null
  440.  
  441.  
  442.     extrn    get_math: near
  443.     extrn    gotoxy: near
  444.  
  445. ;gotoxy
  446. xy_prim:
  447.     call    get_math
  448.     mov    dh,al
  449.     mov    dl,bl
  450.     call    gotoxy
  451.     jmp    return_null
  452.  
  453.  
  454. ;announce a string
  455. an_prim:
  456.     mov    bx,num_screen_cols    ;end of the line.
  457.     mov    cx,2            ;if the second arg is non-null,
  458.     mov    dh,0            ;start in this column
  459.     call    getarg
  460.     jcxz    an_prim_1
  461.     call    read_lastline        ;  put the announcement after the current window.
  462.     inc    al
  463.     mov    dl,al
  464.     call    announce1
  465.     call    clear_count        ;clear to the end of the annunciator.
  466.     jmp    return_null
  467. an_prim_1:
  468.     mov    dl,max_screen_line    ;get the row.
  469.     inc    dl
  470.     inc    dl            ;put our announcement after it.
  471.     call    announce1        ;announce the left part.
  472.     call    position_cursor        ;  put the cursor at the end of the string
  473.     mov    cx,3            ;now announce the right part.
  474.     call    announce
  475.     call    clear_count        ;clear to the end of the annunciator.
  476.     jmp    return_null
  477.  
  478.  
  479. announce1:
  480.     mov    cx,1
  481. announce:
  482. ;given an argument in cx, print it at row=dl, column=dh.
  483.     call    getarg
  484.     jcxz    announce_2        ;if null, we';re done.
  485. announce_1:
  486.     cmp    dh,bl            ;end of the line.
  487.     jae    announce_2        ;if we hit end of line, we're done.
  488.     lodsb                ;get a character.
  489.     mov    ah,0
  490.     call    xychrout
  491.     inc    dh
  492.     loop    announce_1
  493. announce_2:
  494.     ret
  495.  
  496.  
  497. ;insert a string.
  498. is_prim:
  499.     call    write_protect
  500.     call    getarg1
  501.     call    insert_string
  502.     jc    is_prim_1        ;go if we can't insert it.
  503.     jmp    return_null
  504. is_prim_1:
  505.     mov    cx,2
  506.     jmp    return_arg
  507.  
  508.  
  509.     extrn    get_mint_space: near
  510.  
  511. lv_prim:
  512. ;load variable
  513.     mov    bx,offset lv_prim_table
  514.     call    parse_variable
  515.     di_points_fbgn
  516.     jmp    word ptr [bx]
  517.  
  518. lv_prim_cd:
  519.     mov    cx,64+3            ;we need at most 64 plus 'a:\'.
  520.     chk_room_cnt
  521.     mov    ah,19h            ;get the current drive.
  522.     int    21h
  523.     mov    dl,al
  524.     inc    dl
  525.     add    al,'a'
  526.     stosb
  527.     mov    ax,':' + '\'*256
  528.     stosw
  529.  
  530.     mov    si,di            ;get the directory here.
  531.     mov    ah,47h            ;get current directory.
  532.     int    21h
  533. lv_prim_cd_1:                ;find the terminating null.
  534.     lodsb
  535.     call    to_lower        ;lowercase the filename.
  536.     mov    [si-1],al
  537.     or    al,al
  538.     jne    lv_prim_cd_1
  539.     dec    si
  540.     xchg    di,si            ;di should point to the null.
  541.  
  542.     cmp    si,di            ;are we in a subdirectory?
  543.     je    lv_prim_cd_2
  544.     mov    al,'\'            ;yes - store a trailing backslash.
  545.     stosb
  546. lv_prim_cd_2:
  547.     jmp    return_tos
  548.  
  549.  
  550. lv_prim_vn:
  551.     mov    si,offset version_number
  552.     mov    cx,version_number_len
  553.     chk_room_cnt
  554.     rep    movsb
  555.     jmp    return_tos
  556.  
  557.  
  558. lv_prim_cn:
  559.     mov    si,offset computer_name
  560.     mov    cx,computer_name_len
  561.     chk_room_cnt
  562.     rep    movsb
  563.     jmp    return_tos
  564.  
  565.  
  566. lv_prim_im:
  567.     call    read_inverse_mark
  568.     stosb
  569.     jmp    return_tos
  570.  
  571. lv_prim_pb:
  572.     call    read_linecount
  573.     inc    ax
  574.     push    ax
  575.     call    read_linesbefore
  576.     inc    ax
  577.     mov    dx,100
  578.     mul    dx
  579.     pop    cx
  580.     div    cx
  581.     jmp    return_number
  582.  
  583. lv_prim_ms:
  584.     mov    cx,6*4
  585.     chk_room_cnt
  586.     call    get_mint_space
  587.     jmp    return_tos
  588.  
  589. lv_prim_fc:
  590.     mov    ah,0
  591.     mov    al,fore_color
  592.     jmp    return_number
  593.  
  594. lv_prim_bc:
  595.     mov    ah,0
  596.     mov    al,back_color
  597.     jmp    return_number
  598.  
  599. lv_prim_fo:
  600.     mov    ah,0
  601.     mov    al,fore_original
  602.     jmp    return_number
  603.  
  604. lv_prim_bo:
  605.     mov    ah,0
  606.     mov    al,back_original
  607.     jmp    return_number
  608.  
  609. lv_prim_ow:
  610.     call    read_other_window
  611.     jmp    return_number
  612.  
  613. lv_prim_cw:
  614.     call    read_current_window
  615.     jmp    return_number
  616.  
  617. lv_prim_ts:
  618.     call    read_top_percent
  619.     mov    ah,0
  620.     jmp    return_number
  621. lv_prim_bs:
  622.     call    read_bot_percent
  623.     mov    ah,0
  624.     jmp    return_number
  625. lv_prim_ws:
  626.     call    read_showblanks
  627.     inc    ax
  628.     jmp    return_number
  629.  
  630. lv_prim_bp:                ;mbf
  631.     call    read_beep
  632.     inc    ax
  633.     jmp    return_number
  634.  
  635. lv_prim_nl:
  636.     call    read_linecount
  637.     inc    ax
  638.     jmp    return_number
  639. lv_prim_rs:
  640.     call    read_newrow
  641.     inc    ax
  642.     jmp    return_number
  643. lv_prim_cs:
  644.     call    compute_cursor
  645.     mov    ax,dx
  646.     inc    ax
  647.     jmp    return_number
  648. lv_prim_lc:
  649.     call    read_firstcolumn
  650.     inc    ax
  651.     jmp    return_number
  652. lv_prim_tc:
  653.     mov    ax,tab_size
  654.     inc    ax
  655.     jmp    return_number
  656. lv_prim_tl:
  657.     call    read_firstline
  658.     mov    ah,0
  659.     inc    ax
  660.     jmp    return_number
  661. lv_prim_bl:
  662.     call    read_lastline
  663.     mov    ah,0
  664.     inc    ax
  665.     jmp    return_number
  666. lv_prim_mb:
  667.     call    read_buffer_modified
  668.     mov    ah,0
  669.     jmp    return_number
  670. lv_prim_is:
  671.     call    read_ibm_cga
  672.     mov    ah,0
  673.     jmp    return_number
  674. lv_prim_as:
  675.     mov    ax,auto_save_limit
  676.     jmp    return_number
  677. lv_prim_cl:
  678.     call    read_linesbefore
  679.     inc    ax
  680.     jmp    return_number
  681.  
  682.  
  683. sv_prim:
  684. ;store variable
  685.     mov    bx,offset sv_prim_table
  686.     call    parse_variable
  687.     push    bx
  688.     mov    cx,2
  689.     call    get_decimal_arg
  690.     pop    bx
  691.     call    word ptr [bx]
  692.     jmp    return_null
  693.  
  694. sv_prim_fc:
  695.     mov    fore_color,al
  696.     mov    ax,foreback_color
  697.     call    set_screen_color
  698.     ret
  699.  
  700. sv_prim_bc:
  701.     mov    back_color,al
  702.     mov    ax,foreback_color
  703.     call    set_screen_color
  704.     ret
  705.  
  706.  
  707. sv_prim_ow:
  708.     call    store_other_window
  709.     ret
  710.  
  711. sv_prim_cw:
  712.     call    store_current_window
  713.     ret
  714.  
  715. sv_prim_ts:
  716.     call    store_top_percent
  717.     ret
  718. sv_prim_bs:
  719.     call    store_bot_percent
  720.     ret
  721. sv_prim_ws:
  722.     call    store_showblanks    ;whitespace.
  723.     ret
  724.  
  725. sv_prim_bp:                ;mbf
  726.     call    store_beep
  727.     ret
  728.  
  729. sv_prim_im:
  730.     mov    cx,2
  731.     call    getarg_mark
  732.     call    store_inverse_mark
  733.     ret
  734. sv_prim_cd:
  735.     mov    cx,2            ;get the "filename" into filename.
  736.     call    getarg_filename
  737.     mov    ax,[si]            ;get the first two chars.
  738.     or    al,al            ;do we have anything at all?
  739.     je    sv_prim_cd_1        ;no.
  740.     cmp    ah,':'            ;is the second char ':'?
  741.     jne    sv_prim_cd_2        ;no.
  742.     add    si,2            ;parse past these characters.
  743.     call    to_lower        ;convert the drive character to lowercase.
  744.     sub    al,'a'
  745.     mov    ah,0eh            ;select drive
  746.     mov    dl,al
  747.     int    21h
  748. sv_prim_cd_2:
  749.     mov    dx,si            ;save a copy and find the first null.
  750. sv_prim_cd_3:
  751.     lodsb
  752.     or    al,al
  753.     jne    sv_prim_cd_3
  754.     sub    si,2            ;make si -> last char of path.
  755.     cmp    si,dx            ;is this a one character subdir?
  756.     je    sv_prim_cd_4        ;yes - don't strip trailing slashes.
  757.     xor    al,al
  758.     xchg    al,[si]            ;store a null there.
  759.     cmp    al,'\'            ;was it a backslash?
  760.     je    sv_prim_cd_4        ;yes.
  761.     cmp    al,'/'            ;was it a slash?
  762.     je    sv_prim_cd_4        ;yes.
  763.     mov    [si],al            ;no - store the original char.
  764. sv_prim_cd_4:
  765.     mov    ah,3bh            ;change to this directory.
  766.     int    21h
  767. sv_prim_cd_1:
  768.     ret
  769.  
  770. sv_prim_tc:
  771.     cmp    ax,2
  772.     je    sv_prim_tc_1
  773.     cmp    ax,4
  774.     je    sv_prim_tc_1
  775.     cmp    ax,8
  776.     je    sv_prim_tc_1
  777.     cmp    ax,16
  778.     jne    sv_prim_tc_2
  779. sv_prim_tc_1:
  780.     dec    ax
  781.     mov    tab_size,ax
  782.     call    paint_screen
  783. sv_prim_tc_2:
  784.     ret
  785.  
  786. sv_prim_tl:
  787.     dec    ax
  788.     call    store_firstline
  789.     ret
  790.  
  791. sv_prim_bl:
  792.     dec    ax
  793.     call    store_lastline
  794.     ret
  795.  
  796. sv_prim_fo:
  797. sv_prim_bo:
  798. sv_prim_vn:
  799. sv_prim_cn:
  800. sv_prim_pb:
  801. sv_prim_ms:
  802. sv_prim_nl:
  803.     ret
  804. sv_prim_rs:
  805.     mov    next_redisp_line,ax
  806.     ret
  807. sv_prim_cs:
  808.     call    set_column
  809.     ret
  810. sv_prim_lc:
  811.     dec    ax
  812.     call    store_firstcolumn
  813.     ret
  814. sv_prim_mb:
  815.     call    store_buffer_modified
  816.     ret
  817. sv_prim_is:
  818.     call    store_ibm_cga
  819.     ret
  820. sv_prim_as:
  821.     mov    auto_save_limit,ax
  822.     mov    auto_save_cntr,ax
  823.     ret
  824. sv_prim_cl:
  825.     call    set_line
  826.     ret
  827.  
  828.  
  829.  
  830.  
  831. parse_variable:
  832. ;parse a variable letter.
  833. ;return bx -> proper entry in the table pointed to by bx on entry.
  834. ;the default is at the end of the table.
  835.     call    getarg1
  836.     mov    ax,'l'            ;defaults to line
  837.     jcxz    parse_variable_1
  838.     lodsb
  839.     dec    cx
  840.     je    parse_variable_1
  841.     mov    ah,[si]
  842. parse_variable_1:
  843.     mov    di,offset variable_table
  844.     mov    cx,variable_count
  845.     repne    scasw
  846.     sub    cx,variable_count-1
  847.     neg    cx
  848.     shl    cx,1
  849.     add    bx,cx
  850.     ret
  851.  
  852.  
  853. pp_prim:
  854.     di_points_fbgn
  855.     mov    cx,11            ;make sure there's enough room.
  856.     chk_room_cnt
  857.     call    get_pick_values
  858.     push    dx            ;save vertical
  859.     mov    ax,cx
  860.     mov    cx,0
  861.     mov    bx,10
  862.     call    put_number
  863.     mov    al,','
  864.     stosb
  865.     pop    ax            ;pushed as dx
  866.     jmp    return_number
  867.  
  868.  
  869. sa_prim:
  870.     mov    di,fend            ;make di point to some free memory.
  871.     add    di,2
  872.     mov    si,fbgn            ;point si at "sa".
  873.     mov    si,[si]            ;point si at the first arg.
  874.     mov    dx,0            ;count the arguments here.
  875. sa_prim_1:
  876.     cmp    si,[si]            ;are we pointing at fend?
  877.     je    sa_prim_2
  878.     mov    [di],si            ;save a pointer to the argument.
  879.     add    di,2
  880.     chk_room
  881.     mov    si,[si]            ;make it point to next arg.
  882.     inc    dx
  883.     jmp    sa_prim_1
  884. sa_prim_2:
  885. ;dx=number of arguments.
  886. ;fend+2->argument pointers.
  887.  
  888.     mov    bx,fend            ;make bx point to some free memory.
  889.     add    bx,2
  890.  
  891.     mov    sa_jump,dx
  892.     dec    dx
  893.  
  894. loop1:
  895.     cmp    sa_jump,1        ;is JUMP > 1?
  896.     jbe    sa_prim_4        ;no - sort complete
  897.     shr    sa_jump,1        ;JUMP = JUMP DIV 2
  898.  
  899. loop2:
  900.     mov    bp,1            ;set DONE = TRUE
  901.     mov    ax,dx            ;get N
  902.     sub    ax,sa_jump        ;compute N - JUMP
  903.     mov    sa_n_jump,ax        ;store N - JUMP
  904.     mov    cx,0
  905.                     ;for J = 1 to N - JUMP DO
  906. loop3:
  907.     mov    si,bx
  908.     add    si,cx            ;make si -> a[J]
  909.     add    si,cx
  910.     mov    di,si
  911.     add    di,sa_jump        ;offset I by JUMP
  912.     add    di,sa_jump
  913.  
  914.  
  915.     push    cx
  916.  
  917.     push    si
  918.     push    di
  919.  
  920.     mov    si,[si]            ;get the two arguments under consideration.
  921.     mov    di,[di]
  922.  
  923.     mov    ax,[si]            ;compute length of this arg.
  924.     sub    ax,si
  925.     sub    ax,mark_overhead
  926.     add    si,mark_overhead-1    ;make si=> text of argument.
  927.  
  928.     mov    cx,[di]            ;compute length of this arg.
  929.     sub    cx,di
  930.     sub    cx,mark_overhead
  931.     add    di,mark_overhead-1    ;make si=> text of argument.
  932.  
  933.     cmp    ax,cx            ;if the first string is shorter,
  934.     jb    sa_prim_8        ;  return if if they're equal.
  935.                     ;second string is smaller.
  936.     push    cx
  937.     repe    cmpsb            ;compare the two strings
  938.     pop    cx
  939.     pop    di
  940.     pop    si
  941.     jb    sa_prim_5        ;go if they're in order already.
  942.     ja    sa_prim_6        ;if they're not in order, swap them.
  943.     cmp    ax,cx            ;were the strings equal?
  944.     je    sa_prim_5        ;yes - don't swap them.
  945.     jmp    short sa_prim_6
  946.  
  947. sa_prim_8:
  948.     xchg    cx,ax            ;first string is smaller.
  949.     repe    cmpsb            ;compare the two strings
  950.     pop    di
  951.     pop    si
  952.     jbe    sa_prim_5        ;go if they're in order already.
  953.  
  954. sa_prim_6:
  955.     mov    ax,[si]            ;swap them.
  956.     xchg    ax,[di]
  957.     mov    [si],ax
  958.     mov    bp,0            ;set DONE = FALSE
  959. sa_prim_5:
  960.     pop    cx            ;get the counter back.
  961.     inc    cx            ;bump the counter
  962.     cmp    cx,sa_n_jump        ;is cx = N - JUMP?
  963.     jbe    loop3            ;if cycle not complete, go again
  964.     cmp    bp,0            ;is DONE = FALSE
  965.     je    loop2            ;no, another cycle
  966.     jmp    loop1            ;keep going until sort is complete
  967.  
  968. sa_prim_4:
  969.     inc    dx            ;because we 'dec'ed it before.
  970.     mov    bx,fend            ;make bx point to some free memory.
  971.     add    bx,2
  972.     mov    di,bx            ;compute the end of the table.
  973.     add    di,dx
  974.     add    di,dx
  975.     push    di
  976. sa_prim_7:
  977.     mov    si,[bx]
  978.     add    bx,2
  979.     mov    cx,[si]            ;compute length of this arg.
  980.     sub    cx,si
  981.     sub    cx,mark_overhead
  982.     add    si,mark_overhead-1    ;make si=> text of argument.
  983.     inc    cx            ;include space for the comma.
  984.     chk_room_cnt
  985.     dec    cx
  986.     rep    movsb
  987.     mov    al,','            ;comma terminate the strings.
  988.     stosb
  989.  
  990.     dec    dx            ;done with all of them?
  991.     jne    sa_prim_7        ;no - do another.
  992.  
  993.     jmp    return_tos
  994.  
  995.  
  996. bl_prim:
  997.     call    ring_the_bell
  998.     jmp    return_null
  999.  
  1000.  
  1001. ;push/pop marks
  1002. pm_prim:
  1003.     call    get_decimal_arg1
  1004.     call    stack_marks
  1005.     jc    pm_prim_1
  1006.     jmp    return_null
  1007. pm_prim_1:
  1008.     mov    cx,2
  1009.     jmp    return_arg_active
  1010.  
  1011.  
  1012. ;set mark (to point)
  1013. sm_prim:
  1014.     mov    cx,2
  1015.     call    getarg_mark
  1016.     mov    al,'.'        ;if 2nd is missing, use '.'
  1017.     jcxz    sm_prim_1
  1018.     lodsb
  1019. sm_prim_1:
  1020.     mov    ah,al        ;get source mark
  1021.     push    ax        ;save source mark
  1022.     call    getarg_mark1
  1023.     pop    bx        ;pushed as ax
  1024.     mov    ah,bl        ;get dest mark
  1025.     call    set_mark
  1026.     jmp    return_null
  1027.  
  1028.  
  1029. ;set point (to marks)
  1030. sp_prim:
  1031.     mov    cx,1
  1032.     call    getarg
  1033.     jcxz    sp_prim_1
  1034. sp_prim_2:
  1035.     lodsb
  1036.     push    si
  1037.     push    cx
  1038.     call    goto_mark
  1039.     pop    cx
  1040.     pop    si
  1041.     loop    sp_prim_2
  1042. sp_prim_1:
  1043.     jmp    return_null
  1044.  
  1045.  
  1046. ;delete to mark
  1047. dm_prim:
  1048.     call    write_protect
  1049.     call    getarg1
  1050.     jcxz    dm_prim_1
  1051. dm_prim_2:
  1052.     lodsb
  1053.     push    si
  1054.     push    cx
  1055.     call    del_to_mark
  1056.     pop    cx
  1057.     pop    si
  1058.     loop    dm_prim_2
  1059. dm_prim_1:
  1060.     jmp    return_null
  1061.  
  1062.  
  1063. ;read to mark
  1064. rm_prim:
  1065.     call    getarg_mark1    ;get mark number to read from.
  1066.     call    read_mark    ;returns es:si, cx describing string.
  1067.     assume    ds:nothing
  1068.     di_points_fbgn
  1069. ;    chk_room_cnt
  1070.     mov    ax,es
  1071.     call    buffer_free    ;make sure that there's that much room.
  1072.     jc    rm_prim_1    ;if cy, there must be no room.
  1073.     rep    movsb        ;move the string.
  1074.     push    es        ;restore our ds.
  1075.     pop    ds
  1076.     jmp    return_tos
  1077. rm_prim_1:
  1078.     add    sp,2        ;conserve the stack.
  1079.     push    es        ;restore our ds.
  1080.     pop    ds
  1081.     assume    ds:data
  1082.     mov    cx,2
  1083.     jmp    return_arg_active
  1084.  
  1085.  
  1086. ;translate characters.
  1087. tr_prim:
  1088.     call    write_protect
  1089.     mov    cx,2        ;translate according to arg 2.
  1090.     call    getarg
  1091.     push    si
  1092.     push    cx
  1093.     call    getarg_mark1    ;get mark number to read from.
  1094.     pop    dx
  1095.     pop    bx
  1096.     call    xlat_to_mark
  1097.     jmp    return_null
  1098.  
  1099.  
  1100. ;count to mark
  1101. rc_prim:
  1102.     call    getarg_mark1    ;get mark number to read from.
  1103.     call    read_mark    ;returns ds:si, cx describing string.
  1104.     push    es        ;restore our ds.
  1105.     pop    ds
  1106.     mov    ax,cx
  1107.     di_points_fbgn
  1108.     jmp    return_number
  1109.  
  1110.  
  1111. ;spell check
  1112. sc_prim:
  1113.     push    ds
  1114.     xor    ax,ax
  1115.     mov    ds,ax
  1116.     lds    si,ds:[4*82h]        ;get the speller's interrupt.
  1117.     sub    si,speller_txt_len+2    ;backup past the string and version.
  1118.     mov    di,offset speller_txt
  1119.     mov    cx,speller_txt_len    ;see if the speller is installed.
  1120.     repe    cmpsb
  1121.     pop    ds
  1122.  
  1123.     mov    ax,-1            ;if no speller, return -1.
  1124.     jne    sc_prim_1        ;no speller.
  1125.  
  1126.     call    getarg1_filename
  1127.     push    si
  1128.     mov    cx,2
  1129.     call    get_decimal_arg
  1130.     mov    ah,al
  1131.     pop    si            ;get the pointer to the word.
  1132.     int    82h
  1133. sc_prim_1:
  1134.     di_points_fbgn
  1135.     jmp    return_number
  1136.  
  1137.  
  1138. ;mark before point #(mb,mark,before,after)
  1139. mb_prim:
  1140.     call    getarg_mark1
  1141.     call    read_mark
  1142.     push    es        ;restore our ds.
  1143.     pop    ds
  1144.     jc    mb_prim_1    ;go if point is before mark
  1145.     mov    cx,2
  1146.     jmp    return_arg
  1147. mb_prim_1:
  1148.     mov    cx,3
  1149.     jmp    return_arg
  1150.  
  1151.  
  1152.  
  1153. ;look pattern.  return arg 2 if bad pattern.
  1154. lp_prim:
  1155.     mov    cx,3            ;see if we should be regular or not.
  1156.     call    getarg
  1157.     mov    dx,cx            ;remember it.
  1158.     mov    cx,4            ;see if we should fold case or not.
  1159.     call    getarg
  1160.     mov    di,cx            ;remember it.
  1161.     call    getarg1
  1162.     call    set_pattern
  1163.     jc    lp_prim_1
  1164.     jmp    return_null
  1165. lp_prim_1:
  1166.     mov    cx,2
  1167.     jmp    return_arg_active
  1168.  
  1169.  
  1170. ;look regular.  return arg 2 if bad pattern.
  1171. lr_prim:
  1172.     call    getarg1
  1173.     call    regexp_pat
  1174.     jc    lr_prim_1
  1175.     jmp    return_null
  1176. lr_prim_1:
  1177.     mov    cx,2
  1178.     jmp    return_arg_active
  1179.  
  1180.  
  1181. ;look for a string.  return arg 5 if not found.
  1182. lk_prim:
  1183.     call    getarg_mark1
  1184.     push    ax
  1185.     mov    cx,2
  1186.     call    getarg_mark
  1187.     push    ax
  1188.     mov    cx,3
  1189.     call    getarg_mark
  1190.     push    ax
  1191.     mov    cx,4
  1192.     call    getarg_mark
  1193.     mov    dl,al        ;set arg 4 (last)
  1194.     pop    ax        ;restore arg 3 (first)
  1195.     mov    dh,al
  1196.     pop    cx        ;restore arg 2 (end) pushed as ax.
  1197.     pop    ax        ;restore arg 1 (start)
  1198.     mov    ch,al
  1199.     call    search
  1200.     jc    lk_prim_1
  1201.     jmp    return_null
  1202. lk_prim_1:
  1203.     mov    cx,5
  1204.     jmp    return_arg_active
  1205.  
  1206.  
  1207. ;look for a string.  return arg 5 if found, arg 6 if not.
  1208. lt_prim:
  1209.     call    getarg_mark1
  1210.     push    ax
  1211.     mov    cx,2
  1212.     call    getarg_mark
  1213.     push    ax
  1214.     mov    cx,3
  1215.     call    getarg_mark
  1216.     push    ax
  1217.     mov    cx,4
  1218.     call    getarg_mark
  1219.     mov    dl,al        ;set arg 4 (last)
  1220.     pop    ax        ;restore arg 3 (first)
  1221.     mov    dh,al
  1222.     pop    cx        ;restore arg 2 (end) pushed as ax.
  1223.     pop    ax        ;restore arg 1 (start)
  1224.     mov    ch,al
  1225.     call    search
  1226.     mov    cx,5        ;if we found it, return arg 5.
  1227.     jnc    lt_prim_1
  1228.     mov    cx,6        ;else return arg 6.
  1229. lt_prim_1:
  1230.     jmp    return_arg
  1231.  
  1232.  
  1233. ;find the first and next occurrences of a file.
  1234. ff_prim:
  1235.     mov    dx,offset filename2
  1236.     mov    ah,1ah
  1237.     int    21h
  1238.     call    getarg1_filename
  1239.     mov    dx,si            ;remember the filename for find_first.
  1240.  
  1241.     di_points_fend
  1242.     mov    ax,[si]
  1243.     cmp    ah,':'            ;does this filename have a drive?
  1244.     jne    ff_prim_9        ;no.
  1245.     mov    ax,[si+2]        ;yes - skip it.
  1246. ff_prim_9:
  1247.     cmp    ax,'/'            ;are they referring to root?
  1248.     je    ff_prim_a
  1249.     cmp    ax,'\'
  1250.     jne    ff_prim_b
  1251. ff_prim_a:
  1252.     mov    cx,5
  1253.     chk_room_cnt
  1254. ff_prim_8:
  1255.     lodsb
  1256.     cmp    al,'/'
  1257.     jne    ff_prim_c
  1258.     mov    al,'\'
  1259. ff_prim_c:
  1260.     stosb
  1261.     or    al,al
  1262.     jne    ff_prim_8
  1263.     dec    di
  1264.  
  1265.     mov    cx,2            ;copy the separator argument.
  1266.     call    getarg
  1267.     chk_room_cnt
  1268.     rep    movsb
  1269.  
  1270.     jmp    return_tos
  1271.  
  1272. ff_prim_b:
  1273.     mov    ah,4eh            ;find first matching file
  1274.     mov    cx,10h            ;find subdirs, too.
  1275. ff_prim_1:
  1276.     int    21h            ;find first or find next.
  1277.     jnc    ff_prim_2        ;more files...
  1278.     jmp    return_tos
  1279. ff_prim_2:
  1280.  
  1281.     mov    si,offset filename2.find_buf_name
  1282.     mov    ah,0
  1283. ff_prim_3:
  1284.     lodsb
  1285.     or    al,al
  1286.     je    ff_prim_4
  1287.     cmp    al,'.'            ;remember if we got a '.'.
  1288.     jne    ff_prim_6
  1289.     inc    ah
  1290. ff_prim_6:
  1291.     call    to_lower
  1292.     chk_room
  1293.     stosb
  1294.     jmp    ff_prim_3
  1295. ff_prim_4:
  1296.  
  1297.     test    filename2.find_buf_attr,10h    ;is this a subdir?
  1298.     je    ff_prim_5        ;no.
  1299.     mov    al,'\'            ;yes- store a trailing backslash.
  1300.     chk_room
  1301.     stosb
  1302.     jmp    short ff_prim_7        ;don't consider storing '.'.
  1303. ff_prim_5:
  1304.     or    ah,ah            ;did we find a '.'?
  1305.     jne    ff_prim_7
  1306.     mov    al,'.'            ;no - store a trailing '.'.
  1307.     stosb
  1308. ff_prim_7:
  1309.  
  1310.     mov    cx,2            ;copy the separator argument.
  1311.     call    getarg
  1312.     chk_room_cnt
  1313.     rep    movsb
  1314.  
  1315.     mov    ah,4fh            ;find next.
  1316.     jmp    ff_prim_1
  1317.  
  1318.  
  1319. to_lower:
  1320.     cmp    al,'A'            ;uppercase?
  1321.     jb    to_lower_1
  1322.     cmp    al,'Z'
  1323.     ja    to_lower_1
  1324.     add    al,'a'-'A'        ;use uppercase.
  1325. to_lower_1:
  1326.     ret
  1327.  
  1328.  
  1329. ;rename a file.
  1330. rn_prim:
  1331.     call    getarg1_filename
  1332.     mov    cx,2
  1333.     call    getarg
  1334.     mov    di,offset filename2
  1335.     rep    movsb
  1336.     xor    al,al
  1337.     stosb
  1338.     mov    dx,offset filename
  1339.     mov    di,offset filename2
  1340.     mov    ah,56h            ;rename file
  1341.     int    21h
  1342.     jnc    rn_prim_1
  1343.     mov    si,offset rename_error
  1344.     mov    cx,rename_error_len
  1345.     jmp    return_sicx
  1346. rn_prim_1:
  1347.     jmp    return_null
  1348.  
  1349.  
  1350. ;delete a file.
  1351. de_prim:
  1352.     call    getarg1_filename
  1353.     mov    dx,si
  1354.     mov    ah,41h            ;delete file
  1355.     int    21h
  1356.     jnc    de_prim_1
  1357.     mov    al,2
  1358.     mov    bx,offset read_errors
  1359.     jmp    return_string
  1360. de_prim_1:
  1361.     jmp    return_null
  1362.  
  1363.  
  1364. ;read a file
  1365. rf_prim:
  1366.     call    write_protect
  1367.     call    getarg1_filename
  1368.     call    read_file
  1369.     mov    bx,offset read_errors
  1370.     jmp    return_string
  1371.  
  1372.  
  1373. ;write a file.
  1374. wf_prim:
  1375.     call    getarg1_filename
  1376.     push    si            ;preserve the pointer to the filename.
  1377.     mov    cx,2
  1378.     call    getarg_mark
  1379.     pop    si
  1380.     call    write_file
  1381.     mov    bx,offset write_errors
  1382.     jmp    return_string
  1383.  
  1384.  
  1385. ;allocate a buffer
  1386. ba_prim:
  1387.     call    get_decimal_arg1
  1388.     push    ax
  1389.     mov    cx,2
  1390.     call    getarg
  1391.     mov    ax,cx
  1392.     pop    cx            ;pushed as ax.
  1393.     call    buffer_allocate
  1394.     di_points_fbgn
  1395.     jmp    return_number
  1396.  
  1397.  
  1398. ;insert from a buffer
  1399. ;#(bi,buffer number,mark,yes,no)
  1400. bi_prim:
  1401.     call    write_protect
  1402.     call    get_decimal_arg1    ;get the buffer number.
  1403.     push    ax
  1404.     mov    cx,2            ;get the mark.
  1405.     call    getarg_mark
  1406.     pop    cx
  1407.     call    buffer_insert
  1408.     jc    bi_prim_1        ;go if we can't insert it.
  1409.     mov    cx,3
  1410.     jmp    return_arg
  1411. bi_prim_1:
  1412.     mov    cx,4
  1413.     jmp    return_arg
  1414.  
  1415.  
  1416. ao_prim:
  1417.     call    getarg1        ;get the first argument
  1418.     mov    dx,cx        ;save size of first argument
  1419.     mov    di,si        ;save pointer to first argument
  1420.     mov    cx,2        ;get second argument
  1421.     call    getarg
  1422.     cmp    cx,dx        ;second shorter than first?
  1423.     jb    ao_prim_2    ;yes - use second's length.
  1424.     mov    cx,dx        ;no - use first's length.
  1425.     repe    cmpsb        ;strings alphabetically ordered?
  1426.     jb    ao_prim_4    ;no, return 4th.
  1427.     jmp    short ao_prim_3
  1428. ao_prim_2:
  1429.     repe    cmpsb        ;strings alphabetically ordered?
  1430.     jbe    ao_prim_4    ;no, return 4th.
  1431. ao_prim_3:
  1432.     mov    cx,3
  1433.     jmp    return_arg
  1434. ao_prim_4:
  1435.     mov    cx,4
  1436.     jmp    return_arg
  1437.  
  1438.  
  1439. it_prim:
  1440. ;check for key, timed.
  1441.     call    check_for_key        ;character waiting?
  1442.     jne    it_prim_1        ;yes - don't turn the pick on.
  1443.     call    auto_save
  1444.     call    pick_on
  1445.     call    input_timed
  1446.     push    ax            ;preserve the key value.
  1447.     call    pick_off
  1448.     pop    ax
  1449.     jmp    short it_prim_2
  1450. it_prim_1:
  1451.     call    input_timed
  1452. it_prim_2:
  1453.     call    decode_key        ;no - change the key into a string.
  1454.     di_points_fbgn
  1455. it_prim_3:
  1456.     lodsb
  1457.     or    al,al
  1458.     je    it_prim_4
  1459.     chk_room
  1460.     stosb
  1461.     jmp    it_prim_3
  1462. it_prim_4:
  1463.     jmp    return_tos
  1464.  
  1465.  
  1466. input_timed:
  1467.     call    get_decimal_arg1
  1468.     mov    bp,ax            ;save the wait time.
  1469.  
  1470.     xor    ax,ax            ;check the mouse buffer first.
  1471.     xchg    ax,mouse_buffer
  1472.     or    ax,ax
  1473.     jne    input_timed_5        ;got one - see if we should restuff it.
  1474.  
  1475.     xor    si,si            ;si is the elapsed time.
  1476.     mov    ah,2ch            ;get the current hundreths.
  1477.     int    21h
  1478.     mov    bl,dl
  1479. input_timed_1:
  1480.     call    check_for_key        ;character waiting?
  1481.     jne    input_timed_2        ;yes - return it.
  1482.     call    check_pick        ;pick waiting?
  1483.     jne    input_timed_5        ;yes - return it.
  1484.     mov    ah,2ch            ;gtime
  1485.     int    21h
  1486.     mov    al,dl            ;subtract the new time from the old.
  1487.     sub    al,bl
  1488.     mov    bl,dl            ;update the time in bl.
  1489.     cbw
  1490.     jns    input_timed_4        ;go if it's positive.
  1491.     add    ax,100            ;make it positive.
  1492. input_timed_4:
  1493.     add    si,ax            ;add in to the current time.
  1494.     cmp    si,bp            ;time to timeout yet?
  1495.     jb    input_timed_1        ;no.
  1496.     mov    ax,255            ;yes - timeout.
  1497.     jmp    short input_timed_3
  1498. input_timed_5:
  1499.     or    bp,bp            ;original wait time.
  1500.     jnz    input_timed_3        ;if non zero wait, we're inputting it.
  1501.     mov    mouse_buffer,ax        ;store the mouse button in a buffer.
  1502.     jmp    short input_timed_3
  1503. input_timed_2:
  1504.     or    bp,bp            ;original wait time.
  1505.     jz    input_timed_3        ;if zero wait, we're just checking.
  1506.     call    get_key_value
  1507. input_timed_3:
  1508.     ret
  1509.  
  1510.  
  1511. bc_prim:
  1512.     mov    cx,2        ;get 'from' argument.
  1513.     call    getarg
  1514.     mov    dl,'a'        ;default to ASCII
  1515.     jcxz    bc_prim_1
  1516.     mov    dl,[si]        ;get from type.
  1517. bc_prim_1:
  1518.     mov    cx,3        ;get 'to' argument.
  1519.     call    getarg
  1520.     mov    dh,'d'        ;default to decimal
  1521.     jcxz    bc_prim_2
  1522.     mov    dh,[si]
  1523. bc_prim_2:
  1524.     call    getarg1
  1525.     call    bc_prim_base    ;get the source base.
  1526.     or    bx,bx        ;ASCII?
  1527.     jnz    bc_prim_4    ;no.
  1528.     jcxz    bc_prim_6
  1529.     lodsb
  1530.     mov    ah,0
  1531.     jmp    bc_prim_3
  1532. bc_prim_6:
  1533.     mov    ax,-1        ;if ASCII, and null argument, use -1.
  1534.     jmp    bc_prim_3
  1535. bc_prim_4:
  1536.     push    dx        ;preserve dx.
  1537.     call    get_number
  1538.     pop    dx
  1539. bc_prim_3:
  1540. ;we now have the number in ax.
  1541.     mov    dl,dh
  1542.     call    bc_prim_base
  1543.     di_points_fbgn
  1544.     or    bx,bx
  1545.     jnz    bc_prim_5
  1546.     stosb
  1547.     jmp    return_tos
  1548. bc_prim_5:
  1549.     mov    cx,0        ;use only as many digits as are needed.
  1550.     call    put_number
  1551.     jmp    return_tos
  1552.  
  1553.  
  1554. ;private subroutine, used only bc_prim.
  1555. bc_prim_base:
  1556. ;enter with dl=base character.
  1557. ;exit with bx=base if number; bx=0 if ASCII.
  1558.     or    dl,20h        ;convert UPPER case to lower case.
  1559.     cmp    dl,'d'
  1560.     jne    bc_prim_base_1
  1561.     mov    bx,10
  1562.     ret
  1563. bc_prim_base_1:
  1564.     cmp    dl,'o'
  1565.     jne    bc_prim_base_2
  1566.     mov    bx,8
  1567.     ret
  1568. bc_prim_base_2:
  1569.     cmp    dl,'h'
  1570.     jne    bc_prim_base_3
  1571.     mov    bx,16
  1572.     ret
  1573. bc_prim_base_3:
  1574.     cmp    dl,'c'
  1575.     jne    bc_prim_base_4
  1576.     mov    bx,0
  1577.     ret
  1578. bc_prim_base_4:
  1579.     cmp    dl,'a'        ;a alias character.
  1580.     jne    bc_prim_base_5
  1581.     mov    bx,0
  1582.     ret
  1583. bc_prim_base_5:
  1584.     cmp    dl,'b'
  1585.     jne    bc_prim_base_6
  1586.     mov    bx,2
  1587.     ret
  1588. bc_prim_base_6:
  1589.     ret
  1590.  
  1591.  
  1592. getarg_mark1:
  1593.     mov    cx,1
  1594. getarg_mark:
  1595. ;enter with cx=arg number.
  1596. ;exit with al=mark, cx=arg size, si->arg.
  1597.     call    getarg
  1598.     mov    al,0        ;use null if no string specified.
  1599.     jcxz    getarg_mark_1
  1600.     mov    al,[si]        ;get the first character
  1601. getarg_mark_1:
  1602.     ret
  1603.  
  1604.  
  1605.     public    trace_result
  1606. trace_result:
  1607. ;enter with si->, cx=count of returning result of a primitive call.
  1608. ;doesn't modify si or cx.
  1609.     push    bx
  1610.     push    cx
  1611.     push    si
  1612.     mov    bx,trace_handle
  1613.     or    bx,bx
  1614.     js    trace_result_3
  1615.     mov    al,'{'
  1616.     call    printchar
  1617.     jcxz    trace_result_1
  1618. trace_result_2:
  1619.     lodsb
  1620.     call    printchar
  1621.     loop    trace_result_2
  1622. trace_result_1:
  1623.     mov    al,'}'
  1624.     call    printchar
  1625.     mov    al,CR
  1626.     call    printchar
  1627.     mov    al,LF
  1628.     call    printchar
  1629.     mov    ah,7
  1630.     int    21h
  1631. trace_result_3:
  1632.     pop    si
  1633.     pop    cx
  1634.     pop    bx
  1635.     ret
  1636.  
  1637.  
  1638. neutral_marker    equ    3
  1639.  
  1640.     public    trace_invoke
  1641. trace_invoke:
  1642. ;enter with bx->fbgn, al=function type (active or neutral)
  1643.     push    bx
  1644.     push    dx
  1645.     push    di
  1646.     mov    di,bx
  1647.     mov    bx,trace_handle
  1648.     or    bx,bx
  1649.     js    trace_result_3
  1650.     cmp    al,neutral_marker
  1651.     jne    trace_invoke_1
  1652.     mov    al,"#"
  1653.     call    printchar
  1654. trace_invoke_1:
  1655.     mov    al,"#"
  1656.     call    printchar
  1657.     mov    al,"("
  1658.     call    printchar
  1659. trace_invoke_3:
  1660.     mov    si,di
  1661.     mov    di,[di]
  1662.     cmp    si,di        ;at end?
  1663.     je    trace_invoke_2    ;yes.
  1664.     mov    cx,di
  1665.     sub    cx,si
  1666.     sub    cx,mark_overhead    ;remove overhead.
  1667.     add    si,mark_overhead-1        ;skip past overhead.
  1668.     jcxz    trace_invoke_5
  1669. trace_invoke_4:
  1670.     lodsb
  1671.     call    printchar
  1672.     loop    trace_invoke_4
  1673. trace_invoke_5:
  1674.     cmp    di,[di]            ;last argument?
  1675.     je    trace_invoke_3        ;yes - don't print comma.
  1676.     mov    al,","
  1677.     call    printchar
  1678.     jmp    trace_invoke_3
  1679. trace_invoke_2:
  1680.     mov    al,")"
  1681.     call    printchar
  1682.     pop    di
  1683.     pop    dx
  1684.     pop    bx
  1685. trace_invoke_6:
  1686.     ret
  1687.  
  1688.  
  1689. printchar:
  1690.     mov    dl,al
  1691.     mov    ah,6
  1692.     int    21h
  1693.     ret
  1694.  
  1695.  
  1696. redirect:
  1697. ;enter with bx = device to redirect (0..2).
  1698. ;exit with ax = new flag for this device.
  1699.     mov    cx,bx            ;get the filename.
  1700.     add    cx,3
  1701.     call    getarg_filename
  1702.     je    redirect_1        ;no filename - don't redirect.
  1703.  
  1704.     mov    ah,45h            ;make a copy of handle in bx
  1705.     int    21h            ;  into ax.
  1706.  
  1707.     push    ax            ;remember the old handle.
  1708.     mov    ah,3eh            ;close the original handle.
  1709.     int    21h
  1710.     mov    ax,3d00h        ;open for reading.
  1711.     cmp    bx,0            ;redirecting from stdin?
  1712.     je    redirect_2
  1713.     mov    ah,3ch            ;no - we have to create it.
  1714.     xor    cx,cx
  1715. redirect_2:
  1716.     mov    dx,si            ;point to the filename.
  1717.     int    21h            ;either open or create.
  1718.     jc    redirect_3        ;go if we failed to open it.
  1719.     pop    ax            ;get the old handle back.
  1720.     ret
  1721. redirect_3:
  1722.     mov    cx,bx            ;get the original handle (now closed).
  1723.     pop    bx            ;get the copy of the original handle.
  1724.     mov    ah,46h            ;copy the bx handle to cx.
  1725.     int    21h
  1726.     mov    ah,3eh            ;now close the copy.
  1727.     int    21h
  1728. redirect_1:
  1729.     mov    ax,-1            ;say that there is no file open.
  1730.     ret
  1731.  
  1732.  
  1733. unredirect:
  1734. ;enter with bx = stdxxx file number, cx = handle to restore.
  1735.     cmp    cx,-1
  1736.     je    unredirect_1
  1737.  
  1738.     mov    ah,3eh            ;close stdxxx file.
  1739.     int    21h
  1740.  
  1741.     xchg    bx,cx            ;force the original handle back.
  1742.     mov    ah,46h
  1743.     int    21h
  1744.  
  1745.     mov    ah,3eh            ;close the copy.
  1746.     int    21h
  1747. unredirect_1:
  1748.     ret
  1749.  
  1750.  
  1751. ex_prim:
  1752.     mov    bx,0
  1753.     call    redirect
  1754.     mov    ex_stdin,ax
  1755.  
  1756.     mov    bx,1
  1757.     call    redirect
  1758.     mov    ex_stdout,ax
  1759.  
  1760.     mov    bx,2
  1761.     call    redirect
  1762.     mov    ex_stderr,ax
  1763.  
  1764.     push    swap_screen_flag
  1765.     mov    ax,ex_stdout
  1766.     or    ax,ex_stderr
  1767.     cmp    ax,-1            ;are we redirecting both of them?
  1768.     je    ex_prim_1        ;no.
  1769.     mov    swap_screen_flag,0    ;yes - don't swap screens.
  1770. ex_prim_1:
  1771.  
  1772.     call    getarg1_filename
  1773.     push    si
  1774.     mov    cx,2
  1775.     call    getarg
  1776.     pop    di
  1777.     call    execute_program
  1778.     pop    swap_screen_flag
  1779.  
  1780.     di_points_fbgn
  1781.  
  1782.     push    ax
  1783.     mov    bx,0
  1784.     mov    cx,ex_stdin
  1785.     call    unredirect
  1786.  
  1787.     mov    bx,1
  1788.     mov    cx,ex_stdout
  1789.     call    unredirect
  1790.  
  1791.     mov    bx,2
  1792.     mov    cx,ex_stderr
  1793.     call    unredirect
  1794.     pop    ax
  1795.  
  1796.     jmp    return_number
  1797.  
  1798.     extrn    execute_program: near
  1799.  
  1800.     extrn    get_key_value: near
  1801.     extrn    decode_key: near
  1802.     extrn    buffer_insert: near
  1803.  
  1804.     extrn    return_arg: near
  1805.     extrn    return_number: near
  1806.     extrn    return_null: near
  1807.     extrn    return_sicx: near
  1808.     extrn    return_tos: near
  1809.     extrn    return_arg_active: near
  1810.     extrn    return_string: near
  1811.     extrn    getarg1_filename: near
  1812.     extrn    getarg_filename: near
  1813.     extrn    getarg1: near
  1814.     extrn    getarg: near
  1815.     extrn    get_decimal_arg1: near
  1816.     extrn    get_decimal_arg: near
  1817.     extrn    get_decimal: near
  1818.     extrn    get_number: near
  1819.     extrn    put_number: near
  1820.  
  1821. ;the following externs are defined in mintprim.asm
  1822.     extrn    dflt: near
  1823.     extrn    hl_prim: near
  1824.     extrn    eq_prim: near
  1825.     extrn    nc_prim: near
  1826.     extrn    db_prim: near
  1827.     extrn    ct_prim: near
  1828.     extrn    st_prim: near
  1829. ;forms
  1830.     extrn    ds_prim: near
  1831.     extrn    mp_prim: near
  1832.     extrn    gs_prim: near
  1833.     extrn    go_prim: near
  1834.     extrn    gn_prim: near
  1835.     extrn    rs_prim: near
  1836.     extrn    fm_prim: near
  1837.     extrn    ev_prim: near
  1838.     extrn    ls_prim: near
  1839.     extrn    es_prim: near
  1840.     extrn    sl_prim: near
  1841.     extrn    ll_prim: near
  1842.     extrn    nb_prim: near
  1843.     extrn    si_prim: near
  1844. ;math
  1845.     extrn    ad_prim: near
  1846.     extrn    su_prim: near
  1847.     extrn    ml_prim: near
  1848.     extrn    dv_prim: near
  1849.     extrn    md_prim: near
  1850.     extrn    gr_prim: near
  1851.  
  1852.     extrn    cc_prim: near        ;mbf
  1853.  
  1854.     public    ex_prim
  1855.     public    sc_prim
  1856.  
  1857.     public    rd_prim
  1858.     public    it_prim
  1859.  
  1860.     public    sa_prim
  1861.     public    is_prim
  1862.     public    bc_prim
  1863.     public    sv_prim
  1864.     public    lv_prim
  1865.     public    pp_prim
  1866.     public    bl_prim
  1867.     public    sm_prim
  1868.     public    sp_prim
  1869.     public    dm_prim
  1870.     public    rm_prim
  1871.     public    rc_prim
  1872.     public    mb_prim
  1873.     public    lp_prim
  1874.     public    lr_prim
  1875.     public    lk_prim
  1876.     public    rf_prim
  1877.     public    wf_prim
  1878.     public    an_prim
  1879.     public    ow_prim
  1880.     public    xy_prim
  1881.     public    pm_prim
  1882.     public    ba_prim
  1883.     public    bi_prim
  1884.     public    ff_prim
  1885.     public    rn_prim
  1886.     public    de_prim
  1887.   if test_prims
  1888.     public    ts_prim
  1889.     public    tt_prim
  1890.   endif
  1891.  
  1892.  
  1893. code    ends
  1894.  
  1895. data    segment    byte public
  1896.     public    function_name_table
  1897.     public    function_name_length
  1898.     public    function_address
  1899.  
  1900. function_name_table    label    word
  1901.     db    'rd'
  1902.     db    'it'
  1903.  
  1904.     db    '=='            ;equals
  1905.     db    'nc'            ;number of characters
  1906.     db    'ct'            ;convert time
  1907.     db    'a?'            ;alphabetic ordered?
  1908.     db    'sa'            ;sort ascending
  1909. ;forms
  1910.     db    'ds'            ;define string
  1911.     db    'mp'            ;make parameter
  1912.     db    'gs'            ;get string
  1913.     db    'go'            ;get one
  1914.     db    'gn'            ;get n
  1915.     db    'rs'            ;reset string
  1916.     db    'fm'            ;first match
  1917.     db    'ev'            ;read enviornment
  1918.     db    'ls'            ;list strings
  1919.     db    'es'            ;erase string
  1920.     db    'sl'            ;save library
  1921.     db    'll'            ;load library
  1922.     db    'n?'            ;name exists?
  1923.     db    'si'            ;string index
  1924. ;math
  1925.     db    '++'            ;add
  1926.     db    '--'            ;subtract
  1927.     db    '**'            ;multiply
  1928.     db    '//'            ;divide
  1929.     db    '%%'            ;modulus
  1930.     db    'g?'            ;numeric greater
  1931.  
  1932.     db    'cc'            ;cursor: mbf
  1933.  
  1934.     db    'is'            ;insert string
  1935.     db    'bc'            ;base conversion
  1936.     db    'sv'            ;set variable
  1937.     db    'lv'            ;load variable
  1938.     db    'pp'            ;pick position
  1939.     db    'bl'            ;bell
  1940.     db    'sm'            ;set mark
  1941.     db    'sp'            ;set point
  1942.     db    'dm'            ;del to mark
  1943.     db    'rm'            ;read to mark
  1944.     db    'rc'            ;read count
  1945.     db    'mb'            ;mark before
  1946.     db    'lp'            ;look pattern
  1947.     db    'lr'            ;look regexp
  1948.     db    'lk'            ;look
  1949.     db    'l?'            ;look&test
  1950.     db    'rf'            ;read file
  1951.     db    'wf'            ;write file
  1952.     db    'an'            ;announce
  1953.     db    'ow'            ;overwrite
  1954.     db    'xy'            ;gotoxy
  1955.     db    'pm'            ;push/pop mark
  1956.     db    'ba'            ;buffer allocate
  1957.     db    'bi'            ;buffer insert
  1958.     db    'ff'            ;find files
  1959.     db    'rn'            ;rename file
  1960.     db    'de'            ;delete file
  1961.     db    'st'            ;syntax table
  1962.     db    'hl'            ;halt
  1963.     db    'db'            ;debug
  1964.     db    'tr'            ;translate
  1965.     db    'ex'            ;execute
  1966.     db    'sc'            ;spell check
  1967.   if test_prims
  1968.     db    'ts'
  1969.     db    'tt'
  1970.   endif
  1971.  
  1972. function_name_length    equ ($-function_name_table)/2
  1973.  
  1974.     dw    dflt
  1975. function_address    label    word
  1976.     dw    rd_prim        ;redisplay
  1977.     dw    it_prim        ;input timed.
  1978.     dw    eq_prim
  1979.     dw    nc_prim
  1980.     dw    ct_prim
  1981.     dw    ao_prim
  1982.     dw    sa_prim
  1983. ;forms
  1984.     dw    ds_prim
  1985.     dw    mp_prim
  1986.     dw    gs_prim
  1987.     dw    go_prim
  1988.     dw    gn_prim
  1989.     dw    rs_prim
  1990.     dw    fm_prim
  1991.     dw    ev_prim
  1992.     dw    ls_prim
  1993.     dw    es_prim
  1994.     dw    sl_prim
  1995.     dw    ll_prim
  1996.     dw    nb_prim
  1997.     dw    si_prim
  1998. ;math
  1999.     dw    ad_prim
  2000.     dw    su_prim
  2001.     dw    ml_prim
  2002.     dw    dv_prim
  2003.     dw    md_prim
  2004.     dw    gr_prim
  2005.  
  2006.     dw    cc_prim        ;mbf
  2007.  
  2008.     dw    is_prim        ;insert string
  2009.     dw    bc_prim        ;base convert
  2010.     dw    sv_prim        ;set variable
  2011.     dw    lv_prim        ;load variable
  2012.     dw    pp_prim        ;pick position
  2013.     dw    bl_prim        ;bell
  2014.     dw    sm_prim        ;set mark
  2015.     dw    sp_prim        ;set point
  2016.     dw    dm_prim        ;delete to mark
  2017.     dw    rm_prim        ;read to mark
  2018.     dw    rc_prim        ;count to mark
  2019.     dw    mb_prim        ;mark before
  2020.     dw    lp_prim        ;look pattern
  2021.     dw    lr_prim        ;look regexp
  2022.     dw    lk_prim        ;look
  2023.     dw    lt_prim        ;look&test
  2024.     dw    rf_prim        ;read file
  2025.     dw    wf_prim        ;write file
  2026.     dw    an_prim        ;announce
  2027.     dw    ow_prim        ;overwrite
  2028.     dw    xy_prim        ;gotoxy
  2029.     dw    pm_prim        ;push/pop mark
  2030.     dw    ba_prim        ;buffer allocate
  2031.     dw    bi_prim        ;buffer insert
  2032.     dw    ff_prim        ;find first/next
  2033.     dw    rn_prim        ;rename file
  2034.     dw    de_prim        ;delete file
  2035.     dw    st_prim        ;set the syntax table.
  2036.     dw    hl_prim
  2037.     dw    db_prim
  2038.     dw    tr_prim
  2039.     dw    ex_prim
  2040.     dw    sc_prim
  2041.   if test_prims
  2042.     dw    ts_prim        ;test
  2043.     dw    tt_prim        ;test two
  2044.   endif
  2045.  
  2046. data    ends
  2047.  
  2048.  
  2049.     end
  2050.