home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1992 September / Simtel20_Sept92.cdr / msdos / turbopas / toadln5.arc / TOADLN5A.ASM < prev    next >
Assembly Source File  |  1988-08-24  |  12KB  |  458 lines

  1. ;v1.5
  2. ; - fixed BS error
  3. ; - handling/addressing local variables with conventional
  4. ;   .ASM format.
  5. ;   [bp+4] = VAR S doubleword vector
  6. ;   [bp-4] = string starting xy coordinates
  7. ;   [bp-6] = screen width
  8. ; - adding insert key toggle (default insert On)
  9.  
  10. ;Codes returned in AX from a svc 0, Int 16H call:
  11. CTRLU    EQU    1615H        ;^U
  12. CTRLZ    EQU    2C1AH        ;^Z
  13. DNARR    EQU    5000H        ;Cursor down
  14. UPARR    EQU    4800H        ;Cursor up
  15. HOMKEY    EQU    4700H        ;Home key
  16. ENDKEY    EQU    4F00H        ;End key
  17. LFTARR    EQU    4B00H        ;Cursor left
  18. RTARR    EQU    4D00H        ;Cursor right
  19. INSKEY    EQU    5200H        ;Insert key
  20. DELKEY    EQU    5300H        ;Delete key
  21. BSKEY    EQU    0E08H        ;Backspace/Rubout key
  22. CRKEY    EQU    1C0DH        ;Return key
  23. ;
  24. GRAPH    EQU    0B0H        ;Selected graphics pad char
  25. ;
  26. CSEG    Segment Public Para 'CODE'
  27.     ASSUME    CS:CSEG, DS:CSEG, ES:CSEG
  28.  
  29. Toadln    proc    near            ;keep MASM happy
  30.     push    bp            ;Do like Turbo does
  31.     mov    bp,sp
  32.     push    bp
  33.     sub    sp,5            ;space for 2 integers, 1 boolean
  34.     push    DS            ;save DS
  35.     call    InitScr            ;init screen vars
  36. ;
  37.     lds    si,dword ptr [bp+4]    ;DS:SI = string vector (>S[bp])
  38.     mov    ax,DS
  39.     mov    ES,ax            ;ES:DI also string vector
  40.     mov    byte ptr [bp-7],0FFH    ;default= insert mode
  41.     call    PadStr            ;pad, display, home cursor
  42. ;
  43. ;Clear keyboard buffer
  44. ClrKbd:
  45.     mov    ah,1            ;report if char is ready
  46.     int    16H            ;BIOS
  47.     jz    KeyIn            ;kbd buff is empty
  48.      xor    ah,ah            ; Svc 0, read next kbd char
  49.      int    16H            ; BIOS
  50.      jmp    short ClrKbd        ; Until kbd buff is empty
  51. ;
  52. ;Kbd buffer is now empty
  53. ;Now get/process the user's keyboard input.
  54. KeyIn:
  55.     call    GetKey            ;Read, process kbd char
  56.     or    ax,ax            ;no cursor moving?
  57.     je    KeyIn            ;right, next key
  58.      cmp    ax,CRKEY        ; Was it a CR or ^Z?
  59.      je    ReturnStr        ; yep, done
  60. ;insure cursor is updated
  61.       call    AbsCur            ;  repsn cursor, update len
  62.       jmp    short Keyin        ;  next key, please
  63. ;
  64. ReturnStr:
  65.     mov    di,0FFFFH        ;force char ptr to end
  66.     call    AbsCur            ;cursor to screen end
  67.     call    ShowStr            ;update length, display
  68.     mov    ax,0E0DH        ;CR
  69.     int    10H
  70.     mov    al,0AH            ;LF
  71.     int    10H
  72.     pop    DS            ;restore DS
  73.     mov    sp,bp            ;do like Turbo does
  74.     pop    bp
  75.     ret    4            ;allow for the VAR
  76. ;
  77. GetKey:
  78. ;Processes the keyboard char, acts as required.
  79.     xor    ah,ah            ;svc 0, read next kbd char
  80.     int    16H            ;BIOS
  81. ;^U clears the string and screen line.
  82.     cmp    ax,CTRLU        ;Is it a ^U?
  83.     jne    LftArrTst        ;nope
  84.      mov    byte ptr [si],0        ; clear str length
  85.      call    PadStr            ; clear screen/string
  86.      ret
  87. ;
  88. LftArrTst:
  89. ;Left Arrow key moves left 1 char, stops at 1st char.
  90.     cmp    ax,LFTARR        ;how about cursor left?
  91.     jne    RtArrTst        ;nope
  92.      dec    di            ; back up ptr
  93.      ret
  94. ;
  95. RtArrTst:
  96. ;Right Arrow key moves right 1 char,
  97. ;stops at last char (+1 if not 255th char)
  98.     cmp    ax,RTARR        ;right cursor?
  99.     jne    DelTst            ;nope
  100.      inc    di            ; bump 1 to right
  101.      ret
  102. ;
  103. DelTst:
  104. ;Delete key rubs out the cursor char,
  105. ; does NOT move cursor, moves rest of string left.
  106.     cmp    ax,DELKEY        ;Delete key?
  107.     je    DoBS            ;yep, skip to common code
  108. ;
  109. BSTst:
  110. ;BS moves left 1 char and deletes THAT char.
  111. ;No action if we're at first char
  112.     cmp    ax,BSKEY        ;Is it a BS? (Rubout)
  113.     jne    DnArrTst        ;nope
  114. ;
  115.     dec    di            ;back up next char ptr
  116.     cmp    di,si            ;did we back up to length byte
  117.     jbe    NoBS            ;yep, no action
  118. ;
  119. DoBS:
  120.     mov    byte ptr [di],GRAPH    ;"delete" char right here
  121.     call    AbsCur            ;fix cursor psn,current str psn
  122.     mov    ax,di            ;new current psn
  123.     sub    ax,si            ;- start = next char ofs
  124.     cmp    ax,cx            ;is cursor within string? (not at end)
  125.     jae    BS_Show            ;nope, at end or beyond
  126. ;
  127. ;Move string (from current char pointer to end) left 1 char
  128.     sub    cx,ax            ;len - cur psn = bytes to move
  129.     push    si            ;save str start
  130.     push    di            ;save this new psn
  131.     mov    si,di            ;new char ptr
  132.     inc    si            ;move from old char ptr
  133.     cld                ;insure fwd
  134.     rep    movsb
  135.     mov    byte ptr [di],GRAPH    ;clear last char
  136.     pop    di            ;restore current psn
  137.     pop    si            ;restore str start
  138. BS_Show:
  139.     call    ShowStr
  140.     ret
  141. NoBS:
  142.      inc    di            ;restore DI
  143.      xor    ax,ax            ;flag no cursor move
  144.      ret
  145. ;
  146. DnArrTst:
  147. ;Down Arrow key goes straight down 1 line,
  148. ;OR to last str char (+1 if not 255th char)
  149.     cmp    ax,DNARR        ;down cursor?
  150.     jne    EndTst            ;nope
  151.      add    di,[bp-6]        ; + scr width = 1 line down
  152.      jc    End1            ; went beyond MAXINT
  153.       ret                ;  done
  154. ;
  155. EndTst:
  156. ;End key goes to last str char (+1 if not 255th char)
  157.     cmp    ax,ENDKEY        ;End key?
  158.     jne    UpArrTst        ;nope
  159. End1:
  160.      mov    di,0FFFFH        ; max out next char ptr
  161.      ret
  162. ;
  163. UpArrTst:
  164. ;Up Arrow key goes straight up 1 line,
  165. ;OR to first str char.
  166.     cmp    ax,UPARR        ;up cursor?
  167.     jne    HomTst            ;nope
  168.      sub    di,[bp-6]        ;- scr width = 1 line up
  169.      jb    DoHome            ;went negative, home
  170.       ret                ;done
  171. ;
  172. HomTst:
  173. ;Home key goes to first str char.
  174.     cmp    ax,HOMKEY        ;home key?
  175.     jne    InsTst            ;nope
  176. DoHome:
  177.      xor    di,di            ; back to start
  178.      ret
  179. ;
  180. InsTst:
  181. ;Insert key toggles insert/overwrite mode
  182.     cmp    ax,INSKEY        ;Insert key?
  183.     jne    CrTst            ;nope
  184.      not    byte ptr [bp-7]        ;reverse all the bits
  185.      xor    ax,ax            ;no cursor updating
  186.      ret
  187. ;
  188. CrTst:
  189. ;Return or ^Z terminate input, exit procedure.
  190.     cmp    ax,CRKEY        ;Is it a CR?
  191.     je    GetKeyX            ;yep, done
  192.      cmp    ax,CTRLZ        ; how about ^Z
  193.      jne    FunTst            ; nope
  194.       mov    ax,CRKEY        ;  force to CR
  195.       ret
  196. ;
  197. FunTst:
  198. ;We gobble any other function or cursor keys
  199. ;so spurious chars won't get in the string.
  200.     xor    ah,ah            ;clear msb (aux byte)
  201.     or    al,al            ;is it a special? (cursor/function)
  202.     je    GetKeyX            ;yep, ignore it (AX=0)
  203. ;
  204. ;We assume it's a legal char now, so we display it.
  205. ;Legals include other control keys.
  206. PrChr:
  207. ;If insert mode, we must first move the string right 1
  208. ;from current char (losing chars beyond 255th).
  209. ;
  210.     cmp    byte ptr [bp-7],0    ;overwrite mode?
  211.     jz    PrC            ;yep, just stuff it
  212. ;
  213.     push    ax            ;save current char
  214.     call    FixLen            ;CX=current length,AX=rel psn
  215.     sub    cx,ax            ;length - cur psn = chars to move
  216.     pop    ax            ;restore char
  217.     jb    PrC            ;curr char is next char (empty), stuff
  218.     jnz    Pr1            ;more than 1 char to move
  219. ;We're sitting on last real char,
  220. ;so just 1 to move to right.  Do it manually:
  221.      mov    ah,[di]            ; snarf old char
  222.      push    ax            ; save
  223.      call    PrC            ; display,stuff
  224.      call    AbsCur            ; doublecheck psn, DI, etc.
  225.      pop    ax            ; get back char
  226.      mov    al,ah            ; old char into AL
  227.      cmp    cl,255            ; length maxed out?
  228.      jb    PrC            ; nope, stuff it and return
  229.       ret                ;  gobble last char
  230. ;
  231. Pr1:    push    si            ;save str start
  232.     push    di            ;save this new psn
  233.     inc    cx            ;adjust chars to move
  234.     add    di,cx            ;curr char + chars to move
  235. ;di points to last char in string
  236.     mov    si,di            ;same place
  237.     dec    si            ;back up to char before
  238.     std                ;insure backward
  239.     rep    movsb            ;do the move DI-1 to DI
  240.     cld                ;be neat: forward again
  241.     pop    di            ;restore current psn
  242.     pop    si            ;restore str start
  243.     stosb                ;stuff ASCII char, bump DI
  244.     call    ShowStr            ;display the string (AX=0)
  245.     not    ax            ;AX <> 0,flag cursor updating
  246.     ret
  247. ;
  248. PrC:
  249.     stosb                ;stuff ASCII char, bump DI
  250.     mov    ah,0EH            ;write char TTY
  251.     int    10H            ;BIOS
  252. GetKeyX:
  253.     ret
  254. ;
  255. PadStr:
  256. ;Pads from past last char to 255 chars with graphic char.
  257. ;Displays str, homes cursor.
  258. ;Returns CX=str length, DI=str start
  259. ;
  260.     xor    ch,ch            ;clear msb
  261.     mov    cl,[si]            ;get str length
  262.     mov    di,si            ;current char = str start
  263.     inc    di            ;bump past len byte
  264.     push    si            ;str start
  265.     push    di            ;and next char ptr
  266. ;
  267.     add    di,cx            ;add in length (if any)
  268.     not    cl            ;255-str len
  269.     mov    al,GRAPH        ;pad with graphic char
  270.     cld                ;insure fwd (sigh...)
  271.     rep    stosb            ;do the pad
  272.     pop    di            ;restore str start
  273.     pop    si            ;and next char ptr
  274.     mov    dx,[bp-4]        ;home cursor to str start
  275. ;fall thru to ShowStr and return
  276. ;
  277. ShowStr:
  278. ;Display str at starting coordinates,
  279. ;Clear to EOL (e.g., full 255 chars).
  280. ;Exit with CX=current str length, DI unchanged,
  281. ; cursor psn unchanged.
  282.     push    dx            ;remember current cursor psn
  283.     mov    ah,3            ;read cur psn (want cursor size)
  284.     int    10H            ;BIOS CX = current cursor size
  285. ;
  286.     push    cx            ;save cursor size
  287.     mov    ch,20H            ;turn cursor off
  288.     mov    ah,1            ;set cursor size
  289.     int    10H            ;BIOS
  290.     mov    dx,[bp-4]        ;home cursor to str start
  291.     mov    ah,2            ;position cursor
  292.     int    10H            ;BIOS
  293. ;
  294. ;We display all 255 chars. Str buffer may be padded
  295. ;with graphic chars (not part of real length),
  296. ;but we show them to "Clr EOL".
  297.     push    si            ;str start
  298.     inc    si            ;bump past length byte
  299.     mov    cx,255            ;255 chars
  300.     mov    ah,0EH            ;BIOS display char TTY
  301. SL1:
  302.     lodsb                ;next string char
  303.     int    10H            ;display it
  304.     loop    SL1            ;do them all
  305.     pop    si            ;restore str start
  306. ;
  307.     pop    cx            ;old cursor size
  308. ;
  309.     mov    ah,1            ;set cursor size
  310.     int    10H            ;BIOS
  311.     pop    dx            ;old cursor psn
  312.     mov    ah,2            ;set cursor psn
  313.     int    10H            ;BIOS
  314.     call    GetLen            ;update CX=len
  315.     mov    [si],cl            ;and force into len byte
  316.     xor    ax,ax            ;so we don't call AbsCur
  317.     ret
  318. ;
  319. AbsCur:
  320. ;Absolute cursor movement to next char ptr (DI).
  321. ;Enter with DI = ptr to next str char.
  322. ;Test to insure DI doesn't point beyond
  323. ; 255 chars past start (from FixLen)
  324. ;Exit with
  325. ; DX= adjusted xy coords
  326. ; DI = adjusted current char ptr (from FixLen)
  327. ; CX = str length (from GetLen)
  328. ; cursor pointing to next str char
  329. ;
  330.     mov    dx,[bp-4]        ;get str's starting cursor psn
  331.     call    FixLen            ;check str len,char ptr
  332. ;Returns CX=str len, AX=next char ofs
  333.     or    ax,ax            ;curr char = start?
  334.     je    PsnCur            ;yep, go "home" cursor
  335. ;
  336.     dec    ax
  337.     push    cx            ;save str len
  338.     mov    cx,[bp-6]        ;get scr width
  339.     add    al,dl            ;add in starting col
  340.     adc    ah,0            ;in case of carry
  341. AL1:
  342.     cmp    ax,cx            ;less than 1 line?
  343.     jbe    A3            ;yep
  344.      sub    ax,cx            ;>width, subtract width
  345.      inc    dh            ;bump row
  346.      jmp    short AL1        ;until col < = width
  347. A3:                    ;updated DL=col,DH=row
  348.     pop    cx            ;restore length
  349.     mov    dl,al            ;update row
  350. ;
  351. PsnCur:
  352.     mov    ah,2            ;svc 2, position cursor
  353.     int    10H            ;BIOS
  354.     ret
  355. ;
  356. FixLen:
  357. ;Insures str len (and CX) are legal,
  358. ;keeps DI within legal limits (start + 0..254)
  359. ;Enters with DI = current char ptr (could be beyond str length),
  360. ;Exits with CX = str len, AX=rel cursor psn within string
  361. ;
  362. ;first scan for our terminating GRAPH graphics char
  363.     call    GetLen            ;returns with CX=len
  364.     jcxz    F0            ;no str length, force to start
  365. ;now insure str ptr is legal (within string)
  366.     mov    ax,di            ;str ptr
  367.     sub    ax,si            ;- str start = next char ofs
  368.     ja    F1            ;ok, next char > start
  369. F0:
  370.      xor    ax,ax            ; next char ofs = 0
  371.      mov    di,si            ; force next char to start
  372.      inc    di            ; bump to 1st char
  373.      ret                ; done
  374. ;
  375. ;at or above 1st char, how about beyond str end?
  376. F1:
  377.     cmp    ax,cx            ;< len?
  378.     jbe    F2            ;yep
  379.      mov    di,si            ; start
  380.      mov    ax,cx            ; get length
  381.      cmp    al,255            ; maxed out?
  382.      je    F1A            ; yep
  383.       inc    ax            ;  no, so bump to next char
  384. F1A:
  385.      add    di,ax            ; point to last char
  386. F2:
  387.     ret
  388. ;
  389. GetLen:
  390.     push    di            ;save next char ptr
  391.     mov    di,si            ;start
  392.     mov    cx,255            ;max possible len
  393.     add    di,cx            ;point to end
  394.     std                ;scan backwards
  395.     mov    al,GRAPH        ;graphics char ends it
  396.     repe    scasb            ;scan until we run out of GRAPH's
  397.     cld
  398. ;CX points to the non-GRAPH char (or 0)
  399.     jz    G1            ;didn't find ANY
  400.      inc    cx            ; adjust from the scasb
  401. G1:
  402.     pop    di            ;restore next char ptr
  403.     ret                ;with CX=len
  404. ;
  405. InitScr:
  406. ;Get required screen stuff
  407.     mov    ah,0FH            ;get current video mode
  408.     int    10H            ;BIOS
  409. ;BH = active display page (protect it!)
  410.     mov    al,ah            ;need width as LSB
  411.     xor    ah,ah            ;clear msb
  412.     mov    [bp-6],ax        ;save current scr width
  413. ;
  414. ;We need 255 chars of screen space WITHOUT SCROLLING,
  415. ;or our cursor positioning will be screwed up.
  416. ;Test now to see if we have enough room.
  417. ;If not, do our scrolling NOW instead of letting BIOS do it.
  418. ;
  419.     mov    si,ax            ;save width in SI
  420.     mov    ah,3            ;get current cursor psn in DX
  421.     int    10H            ;BIOS
  422.     cmp    dh,21            ;row 21 or less?
  423.     jbe    NoScroll        ;yep, scroll testing
  424. ;
  425.     mov    al,dh            ;current row
  426.     mov    cx,si            ;CL = width multiplier
  427.     mul    cl            ;AX=row * width
  428. C1:
  429.     add    al,dl            ;add in current col
  430.     adc    ah,0            ;in case of carry
  431.     mov    cx,ax            ;remember as abs scr psn
  432.     add    ax,255            ;plus full line length
  433.     mov    di,ax            ;abs scrn psn + string
  434. CL1:
  435.     cmp    di,cx            ;less than 1 line?
  436.     jbe    CDone            ;yep, ok
  437.      mov    ax,0E0AH        ; display LF via BIOS
  438.      int    10H            ; BIOS
  439.      sub    di,si            ; subtract width
  440.      dec    dh            ; back up 1 row
  441.      jmp    short CL1
  442. CDone:
  443.     mov    ah,2            ;svc 2, position cursor
  444.     int    10H            ;BIOS
  445. NoScroll:
  446.     mov    [bp-4],dx        ;now save current cursor psn
  447. ;
  448. ;Get screen attributes at current cursor psn
  449.     mov    ah,8            ;Read char & attrib
  450.     int    10H            ;BIOS
  451.     mov    bl,ah
  452. ;BL = screen attribute (protect it!)
  453.     ret
  454.  
  455. Toadln    endp
  456. CSEG    ENDS
  457.     end    Toadln
  458.