home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 23 / IOPROG_23.ISO / SOFT / ASM / GRDBDL17.ZIP / INPUT.ASM < prev    next >
Encoding:
Assembly Source File  |  1998-10-26  |  12.9 KB  |  446 lines

  1. ;
  2. ; GRDB
  3. ;
  4. ; Copyright(c) LADsoft
  5. ;
  6. ; David Lindauer, camille@bluegrass.net
  7. ;
  8. ;
  9. ; Input.asm
  10. ;
  11. ; Function: Handle input
  12. ;
  13. ;   Handles numbers
  14. ;   Handles segments
  15. ;   Handles trapping page faults
  16. ;   Handles command input
  17. ;
  18.     ;MASM MODE
  19.     .model small
  20.     .386
  21.  
  22. include  edispatc.inc 
  23. include  eprints.inc 
  24. include  emtrap.inc 
  25. include  eregs.inc 
  26. include  edump.inc 
  27. include  eentry.inc 
  28. include  eexec.inc 
  29. include  ebreaks.inc 
  30. include  edis.inc 
  31. include  einout.inc
  32. include  eoptions.inc
  33. include  ehistory.inc
  34.  
  35.     extrn _exit : PROC,domath : PROC, drive : PROC, fill : PROC
  36.     extrn logging : PROC, help : PROC, pci : PROC
  37.     extrn DoFileRead : PROC, DoFileWrite : PROC, search : PROC
  38.     extrn fpcommand : PROC, move : proc, compare : proc, asm : PROC
  39.  
  40.     PUBLIC    qerr, ReadNumber, ReadAddress, Inputhandler
  41.     PUBLIC    wadeSpace, GetInputLine, WadeSpaceOnly, inputbuffer
  42.     PUBLIC    defDS,defCS
  43.  
  44. IBSIZE = 80    ;max size of iinput buffer for a line=width of screen
  45.  
  46.     .data
  47.  
  48. inputbuffer db    IBSIZE DUP (?)            ;Allocate Input buffer
  49. Commands db    "abcdefghilmnopqrstuwxy@?"    ; List of commands
  50. comlen    = $ - Commands                ; Length of list
  51. inquote db    0
  52.  
  53.     .code
  54. ;
  55. ; load defaults if dx is zero
  56. ; INPUT: EDX contains segment to use if not 0, OR if big real with offset 0
  57. ; OUTPUT: DX contains segment to use, could be default DX from bucket
  58. ;
  59. defDS    PROC
  60.     or    edx,edx        ;if edx has a value
  61.     jnz    ddsx        ;then use it
  62.     sub    dx,dx        ; waste one instruction
  63.     test    [optflat0],1    ;see if default seg is 0
  64.     jnz    ddsx        ;if so, use EDX=0
  65.     mov    dx,[RegdumpDS]    ;else use default DS
  66. ddsx:
  67.     ret
  68. defDS    ENDP
  69. ;
  70. ; for now we just default CS to the active CS, since it is only
  71. ; used on U and A commands and since we can't do linear addressing
  72. ; with those anyway right now. ???is this true???
  73. ;    If EDX <> 0, we are starting from a specified segment location,
  74. ; so use that instead of CS. (EDX contains the segment).
  75. ;
  76. defCS    PROC
  77.     or    edx,edx
  78.     jnz    dcsx
  79.     mov    dx,[RegdumpCS]
  80. dcsx:
  81.     ret
  82. defCS    ENDP
  83. ;
  84. ; Print an error if command wrong
  85. ;    Apparently, SI points to some location in the input buffer. We
  86. ; need to determine how many spaces to print before we found the actual
  87. ; error to point to from the line below. I guess if the error is in the
  88. ; first or second positions, we print the character right at the start of
  89. ; the line, else we space over to where the error is found.
  90. ;
  91. qerr    PROC    
  92.     call    crlf            ;new line for this
  93.     sub    si,offset inputbuffer-2    ; Calculate error pos
  94.     mov    cx,si            ;
  95.     jcxz    short qestart        ;
  96.     dec    cx            ;
  97.     jcxz    short qestart        ;
  98. qelp:                    
  99.     call    printspace              ; Space over to error pos
  100.          loop    qelp
  101. qestart:
  102.     mov    dl,'^'            ; Display error
  103.     call    PutChar
  104.     stc                ; Did an error
  105.     ret    
  106. qerr    ENDP    
  107. ;
  108. ; Read in a number.
  109. ;  In at least some cases, we have ALREADY called ReadReg to find a register,
  110. ;and failed so we are looking for a number anyway.
  111. ;    SI points to the input line from the user.
  112. ; OUTPUT: CY if we found 0 digits and did NOT find a register by name
  113. ;    EAX contains number found if NC
  114. ;
  115. ReadNumber    PROC    
  116.     push    ebx
  117.     push    cx
  118.     push    dx
  119.     call    ReadReg            ;find a non-number (mnemonic)
  120.     clc                ;ignore which type or reg found
  121.     jz    gotnum            ;if 0, we have value of this reg
  122.  
  123. ;We reach here if we found no mnemonic in our lookup table
  124.  
  125.     sub    ebx,ebx            ; Number = 0
  126.     sub    cx,cx            ; digits = 0
  127.     mov    al,[si]            ;get next user character
  128.     cmp    al,"'"            ;if single or double quotes
  129.     jz    getstring        ;get a string input
  130.     cmp    al,'"'
  131.     jz    getstring
  132.     cmp    al,'-'            ;if a hyphen
  133.     pushf                ;save result of compare
  134.     jnz    rnlp            ;not a hyphen, so SI is ok
  135.     inc    si            ;else skip the hyphen
  136. rnlp:
  137.     lodsb                ; Get char & convert to uppercase
  138.     cmp    al,60h
  139.     jc    notlower
  140.     and    al,NOT 20h
  141. notlower:
  142.     sub    al,'0'            ; Convert to binary
  143.     jc    short rn_done        ; < '0' is an error
  144.     cmp    al,10            ; See if is a digit
  145.     jc    short gotdigit        ; Yes, got it
  146.     sub    al,7            ; Convert letters to binary
  147.     cmp    al,16            ; Make sure is < 'G'
  148.     jnc    short rn_done        ; Quit if not
  149.     cmp    al,10            ; MAke sure not < 'A'
  150.     jc    short rn_done
  151. gotdigit:
  152.     shl    ebx,4            ; It is a hex digit, add in
  153.     or    bl,al            ; OR in the digit
  154.     inc    cx            ; Set flag to indicate we got digits
  155.     jmp    rnlp            ; go get the next digit
  156.  
  157. ;We have snagged all entered digits here, and in the process SI got bumped
  158. ;past the non-digit by lodsb, so back up to look at the first non-digit
  159. ;character. the Zero flag contains the result of our hyphen compare, ZF if
  160. ;we found a hyphen, NZ if we didn't.
  161. ;  NOTE also that if we found a string, EBX has up to 4 ASCII codes in it,
  162. ;NOT a value. Don't offhand see any way the caller can know this, though.
  163.  
  164. rn_done:
  165.     dec    si            ; Point at first non-digit
  166.     popf                   ;did we find a hyphen?
  167.     jnz    rm_done2        ; check for negation
  168.     neg    ebx            ;yes, negative, so negate value
  169. rm_done2:
  170.     mov    eax,ebx            ;final result into EAX
  171.     test    cl,-1            ; See if got any CX=digit count
  172.     jnz    gotnum            ;if non-0, we got at least one
  173.     stc                ; No, error
  174. gotnum:
  175.     pop    dx
  176.     pop    cx
  177.     pop    ebx
  178.     ret                ;return number/string in EAX
  179.  
  180. ;We found a quote character at [SI], so we move past the quote to try to
  181. ;snag a quoted string. We keep sticking ASCII codes into EBX, shifting it
  182. ;left as we go, and losing all but the last 4 ASCII codes.
  183.  
  184. getstring:
  185.     inc si                ;bump past quote character
  186. getstringl:
  187.     lodsb                ;get next char
  188.     cmp    al,13            ;if CR, end of input
  189.     jz    rm_done2        ;so leave SI alone?
  190.     cmp    al,"'"            ;find end of quotes already?
  191.     jz    rm_done2        ;if so, check if null string
  192.     cmp    al,'"'
  193.     jz    rm_done2
  194.     inc    cl                ;else we got a char
  195.     shl    ebx,8            ;stick in BL
  196.     mov    bl,al
  197.     jmp    getstringl        ;and get the next one
  198. ReadNumber    ENDP    
  199. ;
  200. ; Read an address, composed of a number and a possible selector
  201. ; INPUT: SI points at the input line just following the U (for unassemble).
  202. ; OUTPUT: EBX contains the address, which came either from a current
  203. ;    register bucket or from a string or number
  204. ;
  205. ReadAddress    PROC    
  206.     sub    edx,edx            ;EDX used for segment if found
  207.     call    ReadReg            ;chk for seg or non-seg register
  208.                     ; mnemonic (like 'AX')
  209.  
  210. ;ReadReg returns two flags: if NZ, we found nothing. if ZF, we found either
  211. ;a segment register or a non-segment register, so we examine the carry flag.
  212. ;CY means it was a non-segment register, and NC means we found a segment
  213. ;register.
  214. ;  If we found a register at all, the value returned is what was in the
  215. ;Regdump bucket for that register, and is returned in EAX unless it was not a
  216. ;32-bit register, in which case the low word is returned in AX and the high
  217. ;word of AX is zero. (undefined for segments)
  218.  
  219.     jnc    gotseg            ;if NC, we snagged a segment reg
  220.     mov    ebx,eax            ;else, get value into ebx
  221.     jz    gotaddr            ;ZF if non-segment reg found
  222.  
  223. ;We fall through here if we failed to find a register. The syntax from the
  224. ;user permits either REG:number, REG:REG, number:REG, number:number, or just 
  225. ;number. At this point, no register was asked for by name, so we check for a 
  226. ;number.
  227.  
  228. readseg:
  229.     call    ReadNumber              ; Read a number or string
  230.     jc    short raerr        ; Quit if error - no input
  231.     mov    ebx,eax            ;move number/string to EBX
  232.     call    WadeSpace        ;find next input
  233.     jz    gotaddr            ;if no more, we're done
  234.     cmp    al,':'            ;if not a colon
  235.     jnz    gotaddr            ;we are also done
  236.     inc    si            ;else move past colon
  237.  
  238. ;    We fell through above because the user did NOT ask for any
  239. ;register by name, then fell through to here because we found a colon after
  240. ;a number or quoted string.
  241. ;EBX now contains a number of up to the last 8 digits entered, or a string
  242. ;of up to the last 4 ASCII characters entered.  We take the low 4 digits or
  243. ;two characters and put them in DX, then set bit 16 of EDX
  244.  
  245.     mov    dx,bx            ;low order num/string to DX
  246.     or    edx,10000H        ;set bit 16 for segment
  247.     jmp    readofs            ;and go read an offset
  248.  
  249. ;EAX contains the value read out of the RegdumpREG bucket, with the high
  250. ;order word zeroed out.
  251.  
  252. gotseg:
  253.     sub    ebx,ebx            ;assume seg only, so offset is 0
  254.     mov    dx,ax            ;get segment value into DX
  255.     or    edx,10000H        ;set bit 16 for segment
  256.     call    WadeSpace        ;look for more input
  257.     jz    gotaddr            ;if no more, segment given only
  258.     cmp    al,':'            ;else see if colon for offset
  259.     jnz    gotaddr            ;if not, that's it
  260.     inc    si            ;else move past colon
  261.  
  262. ;We get here if the input contained a colon, indicating that there might
  263. ;be an offset following.  If nothing follows the colon, assume an offset
  264. ;of 0.
  265.  
  266. readofs:
  267.     call    WadeSpace        ;any further input
  268.     jz    gotaddr            ;ZF means we found a CR
  269.     call    ReadNumber        ; Read in offset
  270.     jc    short raerr        ; Quit if error - no number or
  271.                     ; quoted string with endquotes
  272.     mov    ebx,eax            ;else set offset into EBX
  273. gotaddr:
  274.     clc                ; OK, exit
  275.     ret
  276. raerr:
  277.     stc                ; Error on number input
  278.     ret
  279. ReadAddress    ENDP    
  280. ;
  281. ; Get an input line
  282. ; OUTPUT: SI points to the line of input.
  283. ;
  284. GetInputLine    PROC    
  285.     mov    [inquote],0        ;say input not in quotes
  286.     mov    di,offset InputBuffer    ;point to input buffer
  287.     mov    si,di            ;Return buffer pointer
  288.     mov    cx,IBSIZE        ; Size of buffer=80 bytes
  289. moreinput:
  290.     call    GetKey            ;wait, return keystroke
  291.     call    CheckHistory        ;check for history substitutions
  292.     jc    MoreInput        ;and go for more input if so
  293.     or    al,al           ; ignore function keys
  294.     jz    moreinput        ; 
  295.     cmp    al,9            ; is tab?
  296.     jz    dotab
  297.     cmp    al,8            ; Is delete or rubout?
  298.     jz    short bkspc        ; Yes - go do it
  299.     cmp    al,7fh            ;not on PC?
  300.     jz    short bkspc        ; yes - go do it
  301.     cmp    al,'"'            ;is it double quotes
  302.     jz    doquote            ;if so, set flag
  303.     cmp    al,"'"            ;is it single quotes
  304.     jnz    dochar            ;no, must be valid char
  305. doquote:
  306.     xor    [inquote],1        ;invert quote flag
  307. dochar:
  308.     push    ax            ;save keystroke
  309.     test    [inquote],1        ;was it quotes
  310.     jnz    nolc            ;if so, OK
  311.     cmp    al,'A'            ;see if below A
  312.     jc    nolc
  313.     cmp    al,'Z'            ;or above Z
  314.     ja    nolc
  315.     or    al,20h            ;if A-Z, force lowercase
  316. nolc:
  317.     stosb
  318.     pop    ax
  319.     cmp    al,13            ; Is CR
  320.     jz    short endinput        ; Yes, return
  321.     mov    dl,al            ; Echo character
  322.     call    PutChar
  323.     loop    moreinput        ; Loop till buffer full
  324. endinput:
  325.     call    EnterHistory
  326.     ret
  327. bkspc:
  328.     cmp    di,offset InputBuffer    ; Quit if nothing in buffer
  329.     jz    moreinput        ; And get more input
  330.     mov    dl,8            ; Erase last echoed char
  331.     call    PutChar
  332.     mov    dl,' '            ;
  333.     call    PutChar
  334.     mov    dl,8            ; Reset pointer
  335.     call    PutChar
  336.     dec    di            ; Point at last char
  337.     cmp    byte ptr [di],' '    ; check for multiple spaces
  338.     jnz    moreinput
  339.     cmp    byte ptr [di-1],' '    ;
  340.     jz    bkspc
  341.     jmp    moreinput        ; Get more input
  342. dotab:
  343.     push    cx
  344.     mov    cx,di            ; cx = current pos
  345.     sub    cx,si            ; Minus start pos
  346.     add    cl,7            ; now it equals number of
  347.     and    cx,7            ; spaces per tab
  348.     xor    cx,7
  349.     inc    cl            ; spaces = 1 to 8
  350. tablp:
  351.     mov    al,' '
  352.     stosb
  353.     mov    dl,' '
  354.     call    PutChar
  355.     loop    tablp
  356.     pop    cx
  357.     jmp    moreinput
  358. GetInputLine    ENDP    
  359. ;
  360. ; Wade past spaces
  361. ; Whoa! By subtle implication, the carry accidentally gets set if the non-
  362. ; space of comma character was less than 13 in ASCII sequence.  This means
  363. ; if we hit a tab (8), the carry gets returned set.
  364. ;   Turns out this is NO ACCIDENT, and callers rely on this somehow.
  365. ;
  366. WadeSpace    PROC    
  367.     lodsb                ; Get char
  368.     cmp    al,' '            ; if ' ' or ',' go again
  369.     je    short wadeSpace        ;
  370.     cmp    al,','            ;
  371.     je    short WadeSpace        ;
  372.     cmp    al,9             ;ignore tab also
  373.     je    WadeSpace
  374.     dec    si            ; Point at last space char
  375.     cmp    al,13
  376.     ret
  377. WadeSpace    ENDP    
  378. ;
  379. ; Wade through spaces only
  380. ;
  381. WadeSpaceOnly    PROC    
  382.     lodsb            ; Get a char
  383.     cmp    al,' '        ; Is space
  384.     je    WadeSpaceOnly    ; Loop if so
  385.     cmp    al,9        ; ignore tab also
  386.     je    WadeSpaceOnly
  387.     dec    si        ; Else point at char
  388.     cmp    al,13
  389.     ret
  390. WadeSpaceOnly    ENDP    
  391. ;
  392. ; Main Input routine
  393. ;
  394. InputHandler    PROC
  395.     call    LoadHistory
  396.     PRINT_MESSAGE    <13,10,"->">    ; MONITOR prompt
  397.     call    GetInputLine        ; Get an input line
  398.     call    WadeSpace        ; Wade through spaces       
  399.     jz    InputHandler        ; blank line, so try again
  400.     inc    si            ; Point at first non-space char
  401.     mov    di,offset commands    ; Get command list
  402.     mov    cx,comlen        ; Length of list
  403.     repne    scasb            ; search for command in list
  404.     jnz    ierr            ; Error if not in list
  405.     mov    ax,comlen-1        ; Calculate position
  406.     sub    ax,cx            ;
  407.  
  408. ;Dangerous practice - the list of commands is tightly coupled to the string
  409. ;of command characters. Some day, I should convert this to an array of
  410. ;structures, each containing the command and a pointer to its handler.
  411. ;Then we search through the structure list to find the command, and if found
  412. ;call the associated handler.
  413.  
  414.     push    0            ; Command arg = 0
  415.     call    TableDispatch        ; Dispatch command
  416.     dw    comlen-1
  417.     dw    asm                 ;A command 
  418.     dw    breaks            ;B command
  419.     dw    compare            ;C command
  420.     dw    Dump            ;D command
  421.     dw    entry            ;E command
  422.     dw    fill            ;F command
  423.     dw    go            ;G command
  424.     dw    domath            ;H command
  425.     dw    doin            ;I command
  426.     dw    DoFileRead        ;L command
  427.     dw    move            ;M command
  428.     dw    fpcommand        ;N command
  429.     dw    doout            ;O command
  430.     dw    proceed            ;P command
  431.     dw    _exit            ;Q command
  432.     dw    ModifyRegisters        ;R command
  433.     dw    search            ;S command
  434.     dw    trap            ;T command
  435.     dw    diss            ;U command
  436.     dw    DoFileWrite        ;W command
  437.     dw    drive            ;X command
  438.     dw    pci            ;Y command
  439.     dw    logging            ;@ command
  440.     dw    help            ;? command
  441.     jnc    InputHandler        ; Get more input if no err
  442. ierr:
  443.     call    qerr            ; Display error
  444.     jmp    InputHandler        ; Get more input
  445. InputHandler    ENDP
  446. END