home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / SOURCE.ZIP / DOS-EDIT.ASM < prev    next >
Assembly Source File  |  1986-02-05  |  11KB  |  404 lines

  1. ;    DOS-EDIT.ASM -- Resident DOS Command Line Editor
  2. ;    ================================================
  3.  
  4. CSEG        Segment
  5.         Assume    CS:CSEG
  6.  
  7.         Org    0080h
  8. KeyboardBuffer    Label    Byte
  9.  
  10.         Org    0100h
  11. Entry:        Jmp    Initialize
  12.  
  13. ;    All Data
  14. ;    --------
  15.  
  16.         db    "(C) Copyright 1985 Ziff-Davis Publishing Co."
  17.  
  18. OldInterrupt21    dd    ?        ; Original Interrupt 21 vector
  19. OldInterrupt16    dd    ?        ; Original Interrupt 16 vector
  20. DoingBuffKey    db    0        ; Flag for doing Function Call 0Ah
  21. BufferPointer    dw    KeyboardBuffer    ; Pointer to Keyboard Buffer
  22. BufferCounter    db    0        ; Number of characters in buffer
  23. MaxCharCol    db    ?        ; Maximum Character Column on screen
  24. OriginalCursor    dw    ?        ; Place to save cursor on full-screen
  25. InsertOn    db    0        ; Insert mode flag
  26.  
  27. KeyRoutine    dw    Home,Up,PgUp,Dummy,Left,Dummy,Right
  28.         dw    Dummy,End,Down,PgDn,Insert,Delete
  29.  
  30. ;    New Interrupt 21 (DOS Function Calls)
  31. ;    -------------------------------------
  32.  
  33. NewInterrupt21    Proc    Far
  34.  
  35.         Mov    CS:[DoingBuffKey],0    ; Turn flag off initially
  36.  
  37.         Cmp    AH,0Ah            ; Check if doing buffered input
  38.         Jz    BufferedInput
  39.  
  40.         Jmp    CS:[OldInterrupt21]    ; If not, do regular interrupt
  41.  
  42. BufferedInput:    Mov    CS:[DoingBuffKey],-1    ; If so, turn on flag
  43.  
  44.         PushF                ; Simulate regular interrupt
  45.         Call    CS:[OldInterrupt21]
  46.  
  47.         Mov    CS:[DoingBuffKey],0    ; Turn off flag
  48.         Mov    CS:[BufferCounter],0    ; Re-set character counter
  49.  
  50.         IRet                ; Return to user program
  51.  
  52. NewInterrupt21    EndP
  53.  
  54. ;    New Interrupt 16 (BIOS Keyboard Routine)
  55. ;    ----------------------------------------
  56.  
  57. NewInterrupt16    Proc    Far
  58.  
  59.         Sti                ; Re-enable interrupts
  60.         Cmp    CS:[DoingBuffKey],0    ; Check if doing call 0Ah
  61.         Jz    DoNotIntercept        ; If not, do old interrupt
  62.  
  63.         Cmp    CS:[BufferCounter],0    ; Check if chars in buffer
  64.         Jnz    Substitute        ; If so, get them out
  65.  
  66.         Cmp    AH,0            ; See if doing a get key
  67.         Jz    CheckTheKey        ; If so, get the key
  68.  
  69. DoNotIntercept:    Jmp    CS:[OldInterrupt16]    ; Otherwise, do old interrupt
  70.  
  71. CheckTheKey:    PushF                ; Save flags
  72.         Call    CS:[OldInterrupt16]    ; Do regular interrupt
  73.  
  74.         Cmp    AX,4800h        ; Check if up cursor
  75.         Jnz    NotTriggerKey        ; If not, don't bother 
  76.  
  77.         Call    FullScreen        ; Move around the screen
  78.  
  79.         Cmp    CS:[BufferCounter],0    ; Any chars to deliver?
  80.         Jz    CheckTheKey        ; If not, get another key
  81.  
  82. ReturnBuffer:    Call    GetBufferChar        ; Otherwise, pull one out
  83.  
  84.         Inc    CS:[BufferPointer]    ; Kick up the pointer
  85.         Dec    CS:[BufferCounter]    ; And knock down the counter
  86.  
  87. NotTriggerKey:    IRet                ; And go back to calling prog
  88.  
  89. ;    Substitute Key from Buffer
  90. ;    --------------------------
  91.  
  92. Substitute:    Cmp    AH,2            ; See if shift status check
  93.         Jae    DoNotIntercept        ; If so, can't be bothered
  94.  
  95.         Cmp    AH,0            ; See if get a key
  96.         Jz    ReturnBuffer        ; If so, get the key above
  97.  
  98.         Call    GetBufferChar        ; Otherwise get a key
  99.         Cmp    CS:[BufferCounter],0    ; And clear zero flag
  100.  
  101.         Ret    2            ; Return with existing flags
  102.  
  103. NewInterrupt16    EndP
  104.  
  105. ;    Get Buffer Character
  106. ;    --------------------
  107.  
  108. GetBufferChar:    Push    BX        
  109.         Mov    BX,CS:[BufferPointer]    ; Get pointer to key buffer
  110.         Mov    AL,CS:[BX]        ; Get the key
  111.         Sub    AH,AH            ; Blank out scan code
  112.         Pop    BX
  113.         Ret
  114.  
  115. ;    Full Screen Routine
  116. ;    -------------------
  117.  
  118. FullScreen:    Push    AX            ; Save all these registers
  119.         Push    BX
  120.         Push    CX
  121.         Push    DX
  122.         Push    DI
  123.         Push    DS
  124.         Push    ES
  125.  
  126.         Mov    AX,CS            ; Set AX to this segment
  127.         Mov    DS,AX            ; Do DS is this segment
  128.         Mov    ES,AX            ; And ES is also
  129.  
  130.         Assume    DS:CSEG, ES:CSEG    ; Tell the assembler
  131.  
  132.         Mov    AH,0Fh            ; Get Video State
  133.         Int    10h            ;   through BIOS
  134.         Dec    AH            ; Number of columns on screen
  135.         Mov    [MaxCharCol],AH        ; Save maximum column
  136.                         ; BH = Page Number throughout
  137.         Mov    AH,03h            ; Get cursor in DX
  138.         Int    10h            ;   through BIOS
  139.         Mov    [OriginalCursor],DX    ; And save the cursor position
  140.  
  141.         Call    Up            ; Move cursor up    
  142.  
  143. MainLoop:    Cmp    DH,Byte Ptr [OriginalCursor + 1]    ; If at line
  144.         Jz    TermFullScreen        ; stated from, terminate
  145.  
  146.         Mov    AH,02h            ; Set cursor from DX
  147.         Int    10h            ;   through BIOS
  148.  
  149. GetKeyboard:    Mov    AH,0            ; Get the next key
  150.         PushF                ; By simulating Interrupt 16h
  151.         Call    CS:[OldInterrupt16]    ;   which goes to BIOS
  152.  
  153.         Cmp    AL,1Bh            ; See if Escape key
  154.         Jz    TermFullScreen        ; If so, terminate full screen
  155.  
  156. ;    Back Space
  157. ;    ----------
  158.  
  159.         Cmp    AL,08h            ; See if back space
  160.         Jnz    NotBackSpace        ; If not, continue test
  161.  
  162.         Or    DL,DL            ; Check if cursor at left
  163.         Jz    MainLoop        ; If so, do nothing    
  164.  
  165.         Dec    DL            ; Otherwise, move cursor back
  166.         Call    ShiftLeft        ; And shift line to the left
  167.  
  168.         Jmp    MainLoop        ; And continue for next key
  169.  
  170. ;    Carriage Return
  171. ;    ---------------
  172.  
  173. NotBackSpace:    Cmp    AL,0Dh            ; See if Carriage Return
  174.         Jnz    NotCarrRet        ; If not, continue test
  175.  
  176.         Call    End            ; Move line into buffer
  177.  
  178.         Mov    AL,0Dh            ; Tack on a Carriage Return
  179.         Stosb                ; By writing to buffer
  180.         Inc    [BufferCounter]        ; One more character in buffer
  181.  
  182.         Jmp    MainLoop        ; And continue
  183.  
  184. ;    Normal Character
  185. ;    ----------------
  186.  
  187. NotCarrRet:    Cmp    AL,' '            ; See if normal character
  188.         Jb    NotNormalChar        ; If not, continue test
  189.  
  190.         Cmp    [InsertOn],0        ; Check for Insert mode
  191.         Jz    OverWrite        ; If not, overwrite 
  192.  
  193.         Call    ShiftRight        ; Shift line right for insert
  194.         Jmp    Short NormalCharEnd    ; And get ready to print
  195.  
  196. OverWrite:    Mov    CX,1            ; Write one character
  197.         Mov    AH,0Ah            ; By calling BIOS
  198.         Int    10h
  199.  
  200. NormalCharEnd:    Call    Right            ; Cursor to right and print
  201.  
  202.         Jmp    MainLoop        ; Back for another key
  203.  
  204. ;    Cursor Key, Insert, or Delete Subroutine
  205. ;    ----------------------------------------
  206.  
  207. NotNormalChar:    Xchg    AL,AH            ; Put extended code in AL
  208.         Sub    AX,71            ; See if it's a cursor key
  209.         Jc    GetKeyboard        ; If not, no good
  210.  
  211.         Cmp    AX,12            ; Another check for cursor
  212.         Ja    GetKeyboard        ; If not, skip it 
  213.  
  214.         Add    AX,AX            ; Double for index
  215.         Mov    DI,AX            ;   into vector table
  216.  
  217.         Call    [KeyRoutine + DI]    ; Do the routine
  218.  
  219.         Jmp    MainLoop        ; Back for another key    
  220.  
  221. ;    Terminate Full Screen Movement
  222. ;    ------------------------------
  223.  
  224. TermFullScreen:    Mov    DX,[OriginalCursor]    ; Set cursor to original
  225.         Mov    AH,2            ; And set it
  226.         Int    10h            ;   through BIOS
  227.  
  228.         Pop    ES            ; Restore all registers
  229.         Pop    DS
  230.         Pop    DI
  231.         Pop    DX
  232.         Pop    CX
  233.         Pop    BX
  234.         Pop    AX
  235.  
  236.         Ret                ; And return to New Int. 16h
  237.  
  238. ;    Cursor Movement
  239. ;    ---------------
  240.  
  241. Home:        Mov    DL,Byte Ptr [OriginalCursor]    ; Move cursor to
  242.         Ret                ; to original column
  243.  
  244. Up:        Or    DH,DH            ; Check if at top row
  245.         Jz    UpEnd            ; If so, do nothing
  246.         Dec    DH            ; If not, decrement row
  247. UpEnd:        Ret
  248.  
  249. PgUp:        Sub    DL,DL            ; Move cursor to far left 
  250.         Ret
  251.  
  252. Left:        Or    DL,DL            ; Check if cursor at far left
  253.         Jnz    GoWest            ; If not, move it left
  254.         Mov    DL,[MaxCharCol]        ; Move cursor to right
  255.         Jmp    Up            ; And go up one line
  256. GoWest:        Dec    DL            ; Otherwise, decrement column
  257.         Ret
  258.  
  259. Right:        Cmp    DL,[MaxCharCol]        ; Check if cursor at far right
  260.         Jb    GoEast            ; If not, move it right
  261.         Sub    DL,DL            ; Set cursor to left of screen
  262.         Jmp    Down            ; And go down one line
  263. GoEast:        Inc    DL            ; Otherwise, increment column
  264.         Ret
  265.  
  266. End:        Call    TransferLine        ; Move line to buffer
  267.         Mov    DX,[OriginalCursor]    ; Set cursor to original
  268.         Ret
  269.  
  270. Down:        Inc    DH            ; Move cursor down one row
  271.         Ret
  272.  
  273. PgDn:        Mov    CL,[MaxCharCol]        ; Get last column on screen
  274.         Inc    CL            ; Kick it up by one
  275.         Sub    CL,DL            ; Subtract current column
  276.         Sub    CH,CH            ; Set top byte to zero
  277.         Mov    AL,' '            ; Character to write
  278.         Mov    AH,0Ah            ; Write blanks to screen
  279.         Int    10h            ;   through BIOS
  280. Dummy:        Ret
  281.  
  282. ;    Insert and Delete
  283. ;    -----------------
  284.  
  285. Insert:        Xor    [InsertOn],-1        ; Toggle the InsertOn flag
  286.         Ret                ;   and return    
  287.  
  288. Delete:        Call    ShiftLeft         ; Shift cursor line left
  289.         Ret                ;   and return
  290.  
  291. ;    Transfer Line on Screen to Keyboard Buffer
  292. ;    ------------------------------------------
  293.  
  294. TransferLine:    Sub    CX,CX            ; Count characters in line
  295.         Mov    DI,Offset KeyboardBuffer    ; Place to store 'em
  296.         Mov    [BufferPointer],DI    ; Save that address
  297.         Cld                ; String direction forward
  298.  
  299. GetCharLoop:    Mov    AH,02h            ; Set Cursor at DX
  300.         Int    10h            ;   through BIOS
  301.  
  302.         Mov    AH,08h            ; Read Character & Attribute
  303.         Int    10h            ;   through BIOS
  304.  
  305.         Stosb                ; Save the character
  306.  
  307.         Inc    CX            ; Increment the counter
  308.         Inc    DL            ; Increment the cursor column
  309.         Cmp    DL,[MaxCharCol]        ; See if at end of line yet
  310.         Jbe    GetCharLoop        ; If not, continue
  311.  
  312.         Dec    DI            ; Points to end of string
  313.         Mov    AL,' '            ; Character to search through
  314.         Std                ; Searching backwards
  315.         Repz    Scasb            ; Search for first non-blank
  316.         Cld                ; Forward direction again
  317.         Jz    SetBufferCount        ; If all blanks, skip down
  318.  
  319.         Inc    CL            ; Number of non-blanks
  320.         Inc    DI            ; At last character
  321. SetBufferCount:    Inc    DI            ; After last character
  322.         Mov    [BufferCounter],CL    ; Save the character count
  323.  
  324.         Ret                ; Return from routine
  325.  
  326. ;    Shift Line One Space Right (For Insert)
  327. ;    ---------------------------------------
  328.  
  329. ShiftRight:    Push    DX            ; Save original cursor
  330.         Mov    DI,AX            ; Character to insert
  331.  
  332. ShiftRightLoop:    Call    ReadAndWrite        ; Read character and write
  333.  
  334.         Inc    DL            ; Kick up cursor column 
  335.         Cmp    DL,[MaxCharCol]        ; Check if it's rightmost
  336.         Jbe    ShiftRightLoop        ; If not, keep going
  337.  
  338.         Pop    DX            ; Get back original cursor
  339.         Ret                ; And return from routine
  340.  
  341. ;    Shift Line One Space Left (For Delete)
  342. ;    --------------------------------------
  343.  
  344. ShiftLeft:    Mov    DI,0020h        ; Blank at end
  345.         Mov    BL,DL            ; Save cursor column
  346.         Mov    DL,[MaxCharCol]        ; Set cursor to end of line
  347.         
  348. ShiftLeftLoop:    Call    ReadAndWrite        ; Read character and write
  349.  
  350.         Dec    DL            ; Kick down cursor column
  351.         Cmp    DL,BL            ; See if at original yet
  352.         Jge    ShiftLeftLoop        ; If still higher, keep going 
  353.  
  354.         Inc    DL            ; Put cursor back to original
  355.         Ret                ; And return from routine
  356.  
  357. ;    Read and Write Character for Line Shifts
  358. ;    ----------------------------------------
  359.  
  360. ReadAndWrite:    Mov    AH,2            ; Set Cursor from DX
  361.         Int    10h            ;   through BIOS
  362.  
  363.         Mov    AH,08h            ; Read Character and Attribute
  364.         Int    10h            ;   through BIOS
  365.  
  366.         Xchg    AX,DI            ; Switch with previous char
  367.  
  368.         Mov    CX,1            ; One character to write
  369.         Mov    AH,0Ah            ; Write character only
  370.         Int    10h            ;   through BIOS
  371.  
  372.         Ret                ; Return from Routine
  373.  
  374. ;    Initialization on Entry
  375. ;    -----------------------
  376.  
  377. Initialize:    Sub    AX,AX            ; Make AX equal zero
  378.         Mov    DS,AX            ; To point to vector segment
  379.  
  380.         Les    BX,dword ptr DS:[21h * 4]; Get and save Int. 21h
  381.         Mov    Word Ptr CS:[OldInterrupt21],BX
  382.         Mov    Word Ptr CS:[OldInterrupt21 + 2],ES
  383.  
  384.         Les    BX,dword ptr DS:[16h * 4]; Get and save Int. 16h
  385.         Mov    Word Ptr CS:[OldInterrupt16],BX
  386.         Mov    Word Ptr CS:[OldInterrupt16 + 2],ES
  387.  
  388.         Push    CS            ; Restore DS register
  389.         Pop    DS            ;   by setting to CS
  390.  
  391.         Mov    DX,Offset NewInterrupt21
  392.         Mov    AX,2521h        ; Set new Interrupt 21h
  393.         Int    21h            ;   through DOS
  394.  
  395.         Mov    DX,Offset NewInterrupt16
  396.         Mov    AX,2516h        ; Set new Interrupt 16h
  397.         Int    21h            ;   through DOS
  398.  
  399.         Mov    DX,Offset Initialize    ; Number of bytes to stay
  400.         Int    27h            ; Terminate & remain resident
  401.  
  402. CSEG        EndS
  403.         End    Entry
  404.