home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / cpm86 / c86xfj.a86 < prev    next >
Text File  |  2020-01-01  |  15KB  |  607 lines

  1. ; * * * * * * * * * * * * * * *  version 2.7  * * * * * * * * * * * * * * *
  2. ; [30e] Add support for Fujitsu Micro 16s
  3. ;    Chris Barker, 01/04/85
  4. ; [30d] Add SET PORT command, currently unimplemented.
  5. ; [30c] Isolate all machine dependencies in KERIO.
  6. ; [30a] Add keyboard DEL key alteration for APC
  7. ;    RonB, 04/18/84
  8. ; * * * * * * * * * * * * * * *  version 2.6  * * * * * * * * * * * * * * *
  9. ; [28e] Switch to local stack on interrupts.
  10. ;    RonB, 03/28/84
  11. ; * * * * * * * * * * * * * * *  version 2.4  * * * * * * * * * * * * * * *
  12. ; [20b] Add PRTBRK to send break & set correct clock rate for NEC.
  13. ; [20d] Add a pseudo time-out to PRTOUT so it doesn't loop forever.
  14. ;    RonB,03/02/84
  15. ; [19a] Add XON/XOFF type flow control
  16. ; [19b]    Clear screen and beginning and end of program.
  17. ; [19e]    Add PRTBRK to send break to port (Rainbow only)
  18. ; [19g]    Put in EQU for clock rate for timing loops.
  19. ;    Rg, 2/84     <Oc.Garland%CU20B@Columbia-20>
  20. ; * * * * * * * * * * * * * * *  version 2.3  * * * * * * * * * * * * * * *
  21. ;  [par] Added calls to set parity, strip parity on input if
  22. ;        other than none parity is called for.
  23. ;     JD, 2/84
  24. ; * * * * * * * * * * * * * * *  version 2.2  * * * * * * * * * * * * * * *
  25. ;  [2]    Add a de-initialization routine for the serial port, to restore
  26. ;    changed interrupt vectors, etc.
  27. ;    RonB,12/23/83
  28. ;  [1]    Add I/O support for the NEC Advanced Personal Computer
  29. ;    RonB,12/23/83
  30. ; * * * * * * * * * * * * * * *  version 2.0  * * * * * * * * * * * * * * *
  31.  
  32. ; This module contains all the low level communications port I/O
  33. ; routines.
  34.  
  35. ; Here are the I/O routines for the Fujitsu Micro 16s
  36.  
  37.     CSEG $
  38.  
  39. ; Clock rate *10 for timing loops    ;[19g]
  40. clckrt    equ    80        ;[19g]  8.0 Mhz            ;[30e]
  41.  
  42. ; Interrupt vector locations, in data segment 0
  43.  
  44. mnioff    equ    30h        ;sio interrupt offset
  45. mniseg    equ    32h        ;sio interrupt segment
  46.  
  47. ; 8259 Interrupt controller (master)
  48.  
  49. iccmd    equ    00h        ;interrupt command register
  50. icmask    equ    02h        ;interrupt mask register
  51.  
  52. ; 8259 commands and masks
  53.  
  54. icEOI    equ    20h        ;end of interrupt (command)
  55. ;ictmof    equ    08h        ;disable timer (mask)
  56. icmnof    equ    04h        ;disable RS232 (mask)
  57.  
  58. ; Baud Rate controller (MB 14417)
  59.  
  60. bdport    equ    0FD59h        ;baud rate select (read/write)
  61.  
  62. ; 8251A USART controller
  63.  
  64. mndata    equ    0FD06h        ;    data port
  65. mnsts1    equ    0FD07h        ;in  status port
  66. mncmd    equ    0FD07h        ;out command port
  67.  
  68. ; 8251 status port 1 bits
  69.  
  70. mninp    equ    02h        ;receive ready value
  71. mnout    equ    01h        ;send ready value
  72. mndsr    equ    80h        ;data set ready
  73.  
  74. ; 8251 initialization instructions
  75.  
  76. ;    command instructions
  77.  
  78. ctxe    equ    01h        ;transmit enable
  79. cdtr    equ    02h        ;dtr signal high
  80. crxe    equ    04h        ;receive enable
  81. cbrk    equ    08h        ;send break
  82. cerr    equ    10h        ;error reset
  83. crts    equ    20h        ;rts signal high
  84. cmode    equ    40h        ;reset - go to mode instruction format
  85. chunt    equ    80h        ;hunt for sync characters
  86.  
  87. ;    mode instructions
  88.  
  89. m1x    equ    01h        ;baud rate factor: 1x
  90. m16x    equ    02h        ;                  16x
  91. m64x    equ    03h        ;                  64x
  92. m5d    equ    00h        ;data bits: 5
  93. m6d    equ    04h        ;           6
  94. m7d    equ    08h        ;           7
  95. m8d    equ    0Ch        ;           8
  96. mpn    equ    00h        ;parity: none
  97. mpo    equ    10h        ;        odd
  98. mpe    equ    30h        ;        even
  99. m1s    equ    40h        ;stop bits: 1
  100. m15s    equ    80h        ;           1.5
  101. m2s    equ    0C0h        ;           2
  102.  
  103. outlmt    equ    1000h        ;Number of times to check output status
  104.                 ; before giving up on send.        ;[20d]
  105.  
  106.  
  107. ; Test if port is ready to send next char.  Returns RSKP if ready.
  108. ; Trashes dx.
  109.  
  110. outwt:    cmp    floctl, floxon    ;are we doing flow-control?    [19a] start
  111.     jne    outwta        ;no - go on
  112.     cmp    xofrcv, true    ;are we being held?
  113.     jne    outwta        ;no - ok go on
  114.     ret            ;held - say we're busy.    [19a] end
  115. outwta:    push    ax
  116.     mov    dx,mnsts1
  117.     in    al,dx
  118.     and    al,mndsr+mnout
  119.     sub    al,mndsr+mnout
  120.     jz    outwt2
  121. outwt1:    pop    ax
  122.      ret
  123. outwt2:    pop    ax
  124.     jmp    rskp
  125.  
  126.  
  127. ; Output data to port. Trashes DX and prints char in AL.
  128.  
  129. outchr:    mov    dx,mndata
  130.     out    dx,al
  131.     ret
  132.  
  133.  
  134. ; Output the character in AL, checking first to make sure the port is clear.
  135.  
  136. prtout:    call    dopar        ;[par] set parity
  137.     push    dx
  138.     push    cx                        ;[20d] begin
  139.     mov    cx,outlmt
  140. prtou2:    call    outwt        ;Wait until the port is ready
  141.      loop    prtou2        ; or too much time has passed.
  142.      nop
  143.     call    outchr        ;Output it.
  144.     pop    cx                        ;[20d] end
  145.     pop    dx
  146.     ret
  147.  
  148.  
  149. ; Test if data is available from port.
  150.  
  151. instat:    cmp    mnchrn,0    ;Any chars in the buffer?
  152.     jnz    inst2
  153.      ret
  154. inst2:    jmp    rskp
  155.  
  156.  
  157. ; Input data from port.  Preserves all registers and returns char in
  158. ; AL.  Gets the char from the ring buffer.  Assumes a char is
  159. ; already there.
  160.  
  161. inchr:    push    bx
  162.     cli            ;Disable interrupts while were are playing.
  163.     dec    mnchrn        ;Decrement the number of chars in the buffer.
  164.     mov    bx,mnchop    ;Get the pointer into the buffer.
  165.     inc    bx        ;Increment to the next char.
  166.     cmp    bx,offset mnchrs+mnchnd ;Past the end?
  167.     jb    inchr2
  168.     lea    bx,mnchrs    ;If so wrap around to the start.
  169. inchr2:    mov    mnchop,bx    ;Save the updated pointer.
  170.     mov    al,[bx]        ;Get the character.
  171.     sti            ;All done, we can restore interrupts.
  172.     pop    bx
  173.     cmp    parflg,parnon    ;[par] no parity?
  174.     je    inchr3        ;[par] yup, don't bother stripping
  175.     and    al,7fh        ;[par] checking parity, strip off
  176. inchr3:    cmp    floctl, floxon    ;do flow-control?        [19a] start
  177.     je    inchr4        ;If yes jump
  178.     ret
  179. inchr4:    cmp    xofsnt, true    ;Have we sent an XOFF
  180.     je    inchr5        ;Jump if yes
  181.     ret
  182. inchr5:    cmp    mnchrn, mntrg1    ;Under the low trigger point?
  183.     jb    inchr6        ;yes - jump
  184.     ret
  185. inchr6:    push    ax        ;save current character
  186.     mov    al, xon
  187.     call    prtout        ;send an XON
  188.     mov    xofsnt, false    ;turn off the flag
  189.     pop    ax        ;get back character
  190.     ret            ;                [19a] end
  191.  
  192.  
  193.  
  194. mnax    dw    0        ;Storage in CSEG        ;[28e] begin
  195. mnsp    dw    0        ;  for use by interrupt handler
  196. mnsseg    dw    0
  197. mndseg    dw    0
  198.  
  199. ; This routine handles the interrupts on input.
  200.  
  201. mnint:    cli
  202.     mov    cs:mnax, ax    ;Save interrupt stack location.
  203.     mov    ax, sp
  204.     mov    cs:mnsp, ax
  205.     mov    ax, ss
  206.     mov    cs:mnsseg, ax
  207.     mov    ax, cs:mndseg    ;Switch to our internal stack.
  208.     mov    ss, ax
  209.     lea    sp, mnstk
  210.     push    ds        ;Save all registers.
  211.     push    es
  212.     push    bp
  213.     push    di
  214.     push    si
  215.     push    dx
  216.     push    cx
  217.     push    bx
  218.     mov    ds, ax        ;Get our data segment address.
  219.     call    mnproc        ;Process the character.
  220.     mov    dx, iccmd
  221.     mov    al, icEOI    ;signal end of interrupt to 8259A
  222.     out    dx, al
  223.     pop    bx        ;Restore all registers.
  224.     pop    cx
  225.     pop    dx
  226.     pop    si
  227.     pop    di
  228.     pop    bp
  229.     pop    es
  230.     pop    ds
  231.     mov    ax, cs:mnsp    ;Restore the original stack.
  232.     mov    sp, ax
  233.     mov    ax, cs:mnsseg
  234.     mov    ss, ax
  235.     mov    ax, cs:mnax
  236.     iret            ;Return from the interrupt.    ;[28e] end
  237.  
  238.  
  239. ; This routine (called by MNINT) gets a char from the serial port
  240. ; and puts it in the ring buffer.
  241.  
  242. mnproc:    mov    dx,mnsts1
  243.     in    al,dx        ;Get the port status.
  244.     and    al,mninp    ;Is a character waiting?
  245.     jnz    mnpro2        ;   Yes, go take care of it.
  246.      ret            ;   No, just a false alarm.
  247.  
  248. mnpro2:    mov    dx,mndata
  249.     in    al,dx        ;Read the char.
  250.     cmp    floctl, floxon    ;are we doing flow-control ?    [19a] start
  251.     jne    mnpr2b        ;no - go on
  252.     cmp    al, xoff    ;is it an XOFF?
  253.     jne    mnpr2a        ;no - go on
  254.     mov    xofrcv, true    ;set the flag
  255.     ret
  256. mnpr2a:    cmp    al, xon        ;an XON?
  257.     jne    mnpr2b        ;no
  258.     mov    xofrcv, false    ;clear the flag
  259.     ret            ;                [19a] end
  260. mnpr2b:    cmp    mnchrn,mnchnd    ;Is the buffer full?
  261.     je    mnperr        ;If so, take care of the error.
  262.     inc    mnchrn        ;Increment the character count.
  263.     mov    bx,mnchip    ;Get the buffer input pointer.
  264.     inc    bx        ;Increment it.
  265.     cmp    bx,offset mnchrs+mnchnd ;Past the end?
  266.     jb    mnpro3
  267.     lea    bx,mnchrs    ;Yes, point to the start again.
  268. mnpro3:    mov    mnchip,bx    ;Save the pointer.
  269.     mov    [bx],al        ;Put the character in the buffer.
  270.     cmp    floctl, floxon    ;do flow-control?        [19a] start
  271.     je    mnpro4        ;If yes jump
  272.     ret
  273. mnpro4:    cmp    xofsnt, true    ;Have we sent an XOFF
  274.     jnz    mnpro5
  275.     ret            ;return if we have
  276. mnpro5:    cmp    mnchrn, mntrg2    ;Past the High trigger point?
  277.     ja    mnpro6        ;yes - jump
  278.     ret
  279. mnpro6:    mov    al, xoff
  280.     call    prtout        ;send an XOFF
  281.     mov    xofsnt, true    ;set the flag
  282.     ret            ;                [19a] End
  283.  
  284. mnperr:    ret            ;Just return on an error for now.
  285.  
  286.  
  287. ; prtbrk - send a break        ;                [20b] start
  288.  
  289. prtbrk:
  290.     mov    dx,mncmd    ;break goes to command port
  291.     mov    al,cbrk+crts+cerr+crxe+cdtr+ctxe ;add break to normal command
  292.     out    dx,al
  293.     mov    cx, 25000    ;sit for a while
  294. prtbk1:    loop    prtbk1
  295.     mov    al,crts+cerr+crxe+cdtr+ctxe ;RTS & DTR high, Rx & Tx enabled
  296.     out    dx,al        ;return to normal setting
  297.     ret            ;                 [20b] end
  298.  
  299.  
  300. ; serini - This routine initializes all devices that need it.
  301. ;       Called at the start of the program.
  302.  
  303. serini:    cmp    mninit,0FFh    ; must only do this initialization once
  304.     je    serin2
  305.     mov    mninit,0FFh
  306.  
  307.     push    es
  308.  
  309.     mov    dx,icmask
  310.     in    al,dx        ;get current interrupt mask
  311.     mov    mnxmsk,al    ;save it for restore
  312.  
  313. ;    or    al,ictmof+icmnof;mask off timer and sio interrupts
  314.     or    al,icmnof    ;mask off sio interrupt
  315.     out    dx,al
  316.  
  317.     mov    ax,ds        ;save data segment in cseg
  318.     mov    cs:mndseg,ax    ;   for use by the interrupt handler
  319.  
  320.     mov    ax,0        ;point to zero page to replace
  321.     mov    es,ax        ;the sio interrupt vector
  322.     mov    ax,es:.mniseg    ;after first saving the current vector
  323.     mov    mnxseg,ax
  324.     mov    ax,es:.mnioff
  325.     mov    mnxoff,ax
  326.     cli
  327.     mov    ax,cs
  328.     mov    es:.mniseg,ax
  329.     mov    ax,offset mnint
  330.     mov    es:.mnioff,ax
  331.     sti
  332.  
  333. ;    call    stmode        ;set mode & baud to defaults
  334.     call    stbaud
  335.  
  336.     mov    dx,mndata    ;dummy read to clear buffer
  337.     in    al,dx
  338.  
  339.     mov    dx,icmask
  340.     in    al,dx        ;enable sio interrupts
  341.     and    al,not icmnof
  342.     out    dx,al
  343.  
  344.     pop    es
  345.  
  346. serin2:    ret
  347.  
  348.  
  349. ; serfin - this routine is used to "undo" what serini has done, called
  350. ;       just before exiting back to cp/m.
  351.  
  352. serfin:
  353.     call    clrscr        ;[19b] clear screen    ;[30c]
  354.  
  355.     cmp    mninit,0FFh    ;check if initialization has been done
  356.     jne    serfn2        ;if not, don't de-initialize
  357.     mov    mninit,0
  358.  
  359.     push    es
  360.  
  361.     cli
  362.     mov    dx,icmask
  363.     mov    al,mnxmsk    ;restore the old interrupt mask
  364.     out    dx,al
  365.     mov    ax,0
  366.     mov    es,ax
  367.     mov    ax,mnxseg    ;restore sio interrupt vector
  368.     mov    es:.mniseg,ax
  369.     mov    ax,mnxoff
  370.     mov    es:.mnioff,ax
  371.     sti
  372.  
  373.     pop    es
  374.  
  375. serfn2:    ret
  376.  
  377.  
  378. ; This routine clears the serial port input buffer.  It is called to
  379. ; clear out excess NAKs that can result from server mode operation.
  380.  
  381. cfibf:    mov    mnchrn, 0    ;Say no characters in the buffer.
  382.     mov    mnchip, OFFSET mnchrs-1+mnchnd ;Reset input pointer.
  383.     mov    mnchop, OFFSET mnchrs-1+mnchnd ;Reset output pointer.
  384.     ret
  385.  
  386. ; set the parity, number of data bits, and number of stop bits
  387.  
  388. stmode:                ;do this all in stbaud for micro16s
  389. ; set the baud rate
  390. stbaud:    mov    al,mnbaud    ;get the baud rate information
  391.     cmp    al,6        ;check for valid range (0-6)
  392.     ja    stb03        ;j/ out of valid range
  393.     mov    bx,offset baudtb;get address of baud rate table
  394.     mov    ah,0
  395.     add    bx,ax
  396.     mov    dx,bdport
  397.     mov    al,[bx]        ;get value
  398.     out    dx,al        ;output byte
  399.     mov    al,m64x
  400.     jne    stb02        ;
  401.     mov    al,m16x        ;for 19200 bd
  402. stb02:    push    ax
  403.     mov    dx,mncmd
  404.     mov    al,0        ;recommended reset procedure:
  405.     out    dx,al        ;three 0's followed by a cmode
  406.     mov    al,0
  407.     out    dx,al
  408.     mov    al,0
  409.     out    dx,al
  410.     mov    al,cmode    ;enable mode setting
  411.     out    dx,al
  412.     pop    ax
  413.     add    al,m1s        ;1 stop, no parity, 8 data, 16x baud
  414.     add    al,mpn        ;Note: these adds are distinct to
  415.     add    al,m8d        ;      allow the 8251 time to reset
  416.     out    dx,al
  417.     mov    al,crts+cerr+crxe+cdtr+ctxe ;RTS & DTR high, Rx & Tx enabled
  418.     out    dx,al
  419.  
  420. stb03:    ret
  421.  
  422.     dseg $
  423.  
  424. ;    Serial port default parameters
  425.  
  426. mnbaud    db    5        ;9600 baud
  427.  
  428. ;    Interval Timer values (assumes 64x baud rate mode)
  429.  
  430. baudtb    db    00h        ;300 baud    0
  431.     db    11h        ;600 baud    1
  432.     db    22h        ;1200 baud    2
  433.     db    33h        ;2400 baud    3
  434.     db    44h        ;4800 baud    4
  435.     db    55h        ;9600 baud    5
  436.     db    44h        ;19200 baud    6 - requires 16x rate mode
  437.  
  438. mninit    db    0        ;set to 0FFh if initialization has been done
  439. mnxmsk     db    0        ;8259 interrupt mask storage
  440. mnxseg    dw    0        ;system sio interrupt vector
  441. mnxoff    dw    0
  442.  
  443. mnchnd    equ    512        ;Size of circular buffer.
  444. mnchrs    rb    mnchnd        ;Circular character buffer for input.
  445. mnchip    dw    mnchrs-1+mnchnd    ;Input pointer into character buffer.
  446. mnchop    dw    mnchrs-1+mnchnd    ;Output pointer into character buffer.
  447. mnchrn    dw    0        ;Number of chars in the buffer.
  448.  
  449. mntrg1    equ    128        ;[19a] Low trigger point for Auto XON/XOFF
  450. mntrg2    equ    384        ;[19a] High trigger point for Auto XON/XOFF
  451.  
  452. floctl    db    1        ;[19a] If floctl=floxon do Auto XON/XOFF logic
  453. xofsnt    db    0        ;[19a] set if XOFF was sent
  454. xofrcv    db    0        ;[19a] set if XOFF was recieved
  455.  
  456.     rw    32        ;Interrupt stack        ;[28e]
  457. mnstk    dw    0        ;bottom of stack        ;[28e]
  458.  
  459.  
  460.     CSEG $
  461.  
  462. ; The following routines do the SET and SHOW for the machine dependent
  463. ; features of Kermit.  At present there are only two:  baud rate setting
  464. ; and port selection.
  465.  
  466. ;    This is the SET BAUD rate subcommand
  467.  
  468. bdset:    lea    dx, bdtab
  469.     lea    bx, bdhlp
  470.     mov    ah, cmkey
  471.     call    comnd
  472.     jmp    r
  473.     mov    temp1, bx
  474.     mov    ah, cmcfm
  475.     call    comnd        ;Get a confirm.
  476.     jmp    r        ; Didn't get a confirm.
  477.     mov    bx, temp1
  478.     mov    mnbaud, bl    ;Set the baud rate table index.
  479.     call    stbaud
  480.     jmp    rskp
  481.  
  482. ;    This is the SET PORT subcommand (not implemented in APC)
  483.  
  484. prtset:    mov    ah, cmcfm
  485.     call    comnd        ;Get a confirm.
  486.     jmp    $+3        ; Didn't get a confirm.
  487.     lea    dx, infms6    ;Tell user it's not implemented
  488.     call    tcrmsg
  489.     jmp    rskp
  490.  
  491.  
  492. ; The following procedures implement the SHOW command for the system
  493. ; dependent features of baud rate and port selection.
  494.  
  495. shobd:    lea    dx, bdst    ;Baud rate string.
  496.     call    tcrmsg
  497.     mov    al, mnbaud    ;Print the keyword corresponding to the
  498.     lea    bx, bdtab    ;   current value of mnbaud.
  499.     call    tabprt
  500.     ret
  501.  
  502. shoprt:    ret            ;Port selection not implemented.
  503.  
  504.  
  505.     DSEG $
  506.  
  507. bdtab    db    7        ;Thirteen entries        ;[6] begin
  508.     db    4,'1200$'
  509.     dw    0002h
  510.     db    5,'19200$'
  511.     dw    0006h
  512.     db    4,'2400$'
  513.     dw    0003h
  514.     db    3,'300$'
  515.     dw    0000h
  516.     db    4,'4800$'
  517.     dw    0004h
  518.     db    3,'600$'
  519.     dw    0001h
  520.     db    4,'9600$'
  521.     dw    0006h                        ;[6] end
  522.  
  523. bdhlp    db    cr,lf,' 300    600    1200    2400'
  524.     db    cr,lf,'    4800    9600    19200$'
  525.  
  526.  
  527.  
  528. ; The following routines do screen control.  These are isolated here because
  529. ; the screen control sequences are likely to vary from system to system, even
  530. ; though the Rainbow and APC (the only systems implemented to date) both use
  531. ; ANSI sequences for this purpose.
  532.  
  533.     CSEG $
  534.  
  535. ; POSCUR - positions cursor to row and col (each 1 byte) pointed to by dx.
  536.  
  537. poscur:    mov    bx, dx        ;Do ANSI cursor positioning.
  538.     mov    ax, [bx]    ;
  539.     add    ax, '  '    ;Add 20h to both row and column
  540.     mov    word ptr anspos+2, ax
  541.     lea    dx, anspos    ;Print cursor positioning string.
  542.     call    tmsg
  543.     ret
  544.  
  545. ; CLRSCR - homes cursor and clears screen.
  546.  
  547. clrscr:    lea    dx, fujcls
  548.     call    tmsg
  549.     ret
  550.  
  551. ; CLRLIN - clears from cursor to end of line.
  552.  
  553. clrlin:    mov    dl, cr        ;Go to beginning of line
  554.     call    bout
  555. clreol:    lea    dx, ansclr    ;Clear from cursor to end of line
  556.     call    tmsg
  557.     ret
  558.  
  559. ; REVON - turns on reverse video display
  560.  
  561. revon:    lea    dx, ansron
  562.     call    tmsg
  563.     ret
  564.  
  565. ; REVOFF - turns off reverse video display
  566.  
  567. revoff:    lea    dx, ansrof
  568.     call    tmsg
  569.     ret
  570.  
  571. ; BLDON - turns on bold (highlighted) display
  572.  
  573. bldon:    lea    dx, ansbon    ;
  574.     call    tmsg        ;
  575.     ret
  576.  
  577. ; BLDOFF - turns off bold (highlighted) display
  578.  
  579. bldoff:    lea    dx, ansbof    ;
  580.     call    tmsg        ;
  581.     ret
  582.  
  583.  
  584.     DSEG $
  585.  
  586. anspos    db    esc,'=00$'    ;Position cursor to row and column
  587. fujcls    db    1Eh,1Ah,'$'    ;Home cursor and clear screen
  588. ansclr    db    esc,'T$'    ;Clear from cursor to end of line
  589. ansron    db    esc,'G',0Ch,'$'    ;Turn on reverse video (green)
  590. ansrof    db    esc,'G',04h,'$'    ;Turn off reverse video (green)
  591. ansbon    db    esc,'G',05h,'$'    ;Turn on bold (uses blue)
  592. ansbof    db    esc,'G',04h,'$'    ;Turn off bold (back to green)
  593.  
  594.  
  595. ; Here tab expansion is done if necessary.  If not, just return retskp.
  596.  
  597.     cseg $
  598.  
  599. dotab:    jmp    rskp        ;No, just proceed.
  600.  
  601.     dseg $
  602. curbuf    db    2,0,0        ;command, row, column of cursor position
  603.  
  604. delstr    db    10O, 10O, '$'    ;Delete string.
  605.  
  606. system    db    '           FUJITSU Micro 16s     $'    ;[1][20a]
  607.