home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1992 June / SIMTEL_0692.cdr / msdos / deskaces / conv.arc / CONV.ASM < prev    next >
Assembly Source File  |  1989-01-16  |  56KB  |  1,529 lines

  1.          page   60,132
  2. ;
  3. ;*****************************************************************************
  4. ;   This resident program performs few tasks:                     *
  5. ; 1. Full ascii table splitted into two parts: 0-7Fh and 80H-0FFh.         *
  6. ; 2. converts numbers between bases . The bases allowed are Binary, Octal,   *
  7. ;    Decimal, Hexadecimal . Data is entered in base Postfix, i.e. B,O,D,H .  *
  8. ;    For example 3F5Dh means it is an Hex number .                 *
  9. ; 3. Scan Code printing.                             *
  10. ; 4. Simple unsigned calculator of +,-,*,/ integer operations.             *
  11. ;                                         *
  12. ;   Hot key of this program is defined to be ALT-A. modification is simple - *
  13. ; simply change the scan code at offset 103h, just after the jump at 100, to *
  14. ; your choice. You may want to change the prolog message as well.         *
  15. ;   Windows positions may be set via the 2 (x,y) pair, immediatelly after    *
  16. ; the scan code at 103/104h location. First 2 bytes are the ascii table      *
  17. ; (x,y) pair, follows by the base conversion pair, math window, scan code    *
  18. ; window, and finally the main selection window pair.                 *
  19. ;   Support of AT enhanced keyboard is added (see BiosGetCh below)         *
  20. ;   Redefinition of Hot key can be defined at source level using HotKet def. *
  21. ;                                         *
  22. ;                                          Elber Gershon 1988                *
  23. ;*****************************************************************************
  24. ;
  25.          title  Number Conversions                                 E.G. 1987
  26. ;
  27. Null     equ    00
  28. Soh      equ    01
  29. Bell     equ    07
  30. Bs       equ    08
  31. Lf       equ    10
  32. Cr       equ    13
  33. Escape     equ    27
  34. Space    equ    32
  35. ;
  36. Quit     equ    00h                     ;Dos func call - Quit.
  37. DosGetLn equ    0Ah                     ;Dos func call - Get Line
  38. DosPutLn equ    09h                     ;Dos func call - Put Line
  39. BiosLocate equ  02h                     ;Bios func call - Locate Cursor
  40. BiosGetLoc equ  03h                     ;Bios func call - Get location
  41. BiosPutCh equ   09h                     ;Bios func call - Put Char (Int 010h)
  42. BiosGetMode equ 0fh            ;Bios func call - Get mode/page/width
  43. ;
  44. IFDEF     IS_AT_TYPE
  45. ;The following will work only in AT type machines with enhanced keyboard only:
  46. BiosGetCh equ   010h            ;Bios func call - Get Char (Int 016h)
  47. ;
  48. ELSE
  49. ;And the following if XT type machines with no enhanced keyboard:
  50. BiosGetCh equ   000h            ;Bios func call - Get Char (Int 016h)
  51. ;
  52. ENDIF
  53. ;
  54. HotKey     equ    01E00h                  ;Keyboard scan code for Alt - A
  55. ;
  56. NormalAttr equ  007h                    ;Screen Attribute - normal
  57. InversAttr equ  070h                    ;Screen Attribute - inverse
  58. ;
  59. BiosDs   equ    00040h                  ;Bios Data segment
  60. ScreenMode equ  00049h                  ;Screen mode offset within Bios DS
  61. CGAAddress  equ 0B800h                  ;ColorGraphic Adaptor Base
  62. MonoAddress equ 0B000h                  ;Mono Color Base
  63. ScreenSize equ  01000h                  ;Screen Buffer Size
  64. ;
  65. ;*****************************************************************************
  66. ;* Begining of Code :                                                        *
  67. ;*****************************************************************************
  68. code     segment  para public 'code'
  69.          assume   cs:code,ds:code
  70. ;
  71.          org      0100h
  72. ;
  73. starter: jmp      install               ;install the resident & parameters
  74. ;
  75. ScanCode dw      HotKey        ;Hot Key scan code
  76. ;
  77. WindowLeftA db    03                    ;Window left position - Ascii Table
  78. WindowTopA db     03                    ;Window Top position
  79. WindowLeftC db    20                    ;Window left position - Conversion
  80. WindowTopC db     05                    ;Window Top position
  81. WindowLeftM db    35                    ;Window left position - Math
  82. WindowTopM db     07                    ;Window Top position
  83. WindowLeftS db    40                    ;Window left position - Scan Code
  84. WindowTopS db     12                    ;Window Top position
  85. WindowLeftN db    25                    ;Window left position - Main
  86. WindowTopN db     08                    ;Window Top position
  87. ;
  88. ;*****************************************************************************
  89. ;procedure          KbdHandler                                               *
  90. ;procedure to get control of int 16 and test for Hot key appearance .        *
  91. ;In case of positive detection - Open the main window and...                 *
  92. ;*****************************************************************************
  93. KbdHandler        proc far
  94.          sti
  95.          or       ah,ah                 ;Read Extended Ascii code ?
  96.          jne      KbdHnd9               ;/
  97. ;
  98.          pushf                          ;Old keyboard rtn returns with IRET
  99.      call     cs:OldKbdHandler      ;/
  100. ;
  101.      pushf
  102. ;
  103.          cmp      ax,cs:ScanCode        ;Code we are searching for ?
  104.          jne      KbdHnd8               ;/
  105.          call     DoMain                ;Call the resident part
  106. ;
  107. KbdHnd8: popf
  108.      iret
  109. ;
  110. KbdHnd9: jmp      cs:OldKbdHandler      ;No - continue as before installation
  111. KbdHandler        endp
  112. ;
  113. ;*****************************************************************************
  114. ;procedure           DoMain                                                  *
  115. ;procedure to Open main window and ask for required operation to perform:    *
  116. ;*****************************************************************************
  117. DoMain   proc near
  118.          push     bp                    ;save all the used registers
  119.          push     di
  120.          push     si
  121.          push     es
  122.          push     ds
  123.          push     dx
  124.          push     cx
  125.          push     bx
  126.          push     ax
  127. ;
  128.          mov      bx,cs                 ;get back DS segment
  129.          mov      ds,bx                 ;/
  130. ;
  131.          test     byte ptr [ResActive],0ffh ;Already active ?
  132.          je       short DoMain0
  133.      jmp      DoMain99
  134. DoMain0: not      byte ptr [ResActive]  ;Set Buzy flag On
  135. ;
  136.      mov      byte ptr [WindowKind],'N';Main window is active
  137.          call     PushOldScreen         ;Save Old Screen and cursor position
  138.      mov      dx,00202h        ;Print the different options:
  139.      call      GotoXY        ; |
  140.      mov      dx, offset HeaderN1   ; |
  141.      call      WriteLn        ; |
  142.      mov      dx,00302h        ; |
  143.      call      GotoXY        ; |
  144.      mov      dx, offset HeaderN2   ; |
  145.      call      WriteLn        ; |
  146.      mov      dx,00402h        ; |
  147.      call      GotoXY        ; |
  148.      mov      dx, offset HeaderN3   ; |
  149.      call      WriteLn        ; |
  150.      mov      dx,00502h        ; |
  151.      call      GotoXY        ; |
  152.      mov      dx, offset HeaderN4   ; |
  153.      call      WriteLn        ; |
  154.      mov      dx,0070Ch        ; |
  155.      call      GotoXY        ; |
  156.      mov      dx, offset HeaderN9   ; |
  157.      call      WriteLn        ;/
  158. ;
  159.      
  160. DoMain1: mov      dx,00713h        ;Wait for entry
  161.      call      GotoXY        ; |
  162.      call     ReadCh                ;/
  163.      cmp      al,'1'                ;If it is Ascii Table
  164.          jne      short DoMain2         ;/
  165.      call      PopOldScreen        ;Restore screen
  166.      call      DoAscii        ;/
  167.      jmp      short DoMain98
  168. DoMain2: cmp      al,'2'        ;If it is Conv.
  169.      jne      short DoMain3        ;/
  170.      call      PopOldScreen        ;Restore screen
  171.      call      DoConversion        ;/
  172.      jmp      short DoMain98
  173. DoMain3: cmp      al,'3'        ;If it is Math
  174.      jne      short DoMain4        ;/
  175.      call      PopOldScreen        ;Restore screen
  176.      call      DoMath        ;/
  177.      jmp      short DoMain98
  178. DoMain4: cmp      al,'4'        ;If it is Scan Code
  179.      jne      short DoMain5        ;/
  180.      call      PopOldScreen        ;Restore screen
  181.      call      DoScanCode        ;/
  182.      jmp      short DoMain98
  183. DoMain5:
  184.      call      PopOldScreen        ;Restore screen
  185. ;
  186. DoMain98:
  187.      not      byte ptr [ResActive]  ;Set Buzy flag Off again
  188. ;
  189. DoMain99:
  190.      pop      ax                    ;restore all the used registers
  191.          pop      bx
  192.          pop      cx
  193.          pop      dx
  194.          pop      ds
  195.          pop      es
  196.          pop      si
  197.          pop      di
  198.          pop      bp
  199.          ret
  200. DoMain   endp
  201. ;
  202. ;*****************************************************************************
  203. ;procedure           DoAscii                                                 *
  204. ;procedure to Print the full ascii table :                                   *
  205. ;*****************************************************************************
  206. DoAscii  proc near
  207.          push     bp                    ;save all the used registers
  208.          push     di
  209.          push     si
  210.          push     es
  211.          push     ds
  212.          push     dx
  213.          push     cx
  214.          push     bx
  215.          push     ax
  216. ;
  217.          mov      byte ptr [WindowKind],'A';Draw Ascii Table window
  218.          call     PushOldScreen         ;Save Old Screen and cursor position
  219. ;
  220. DoAsc0:  mov      dx,00101h             ;Start with window X=1 , Y=1
  221.          mov      al,[CurrentChar]      ;Get current character to print
  222. DoAsc1:  call     GotoXY                ;GotoXY new position
  223.          call     PrintAsc              ;Print al in dec. hex. and ascii
  224.          inc      al                    ;Advance to next character
  225.          inc      dh                    ;advance Y
  226.          cmp      dh,17                 ;Bottom of Table ?
  227.          jb       short DoAsc1          ;/
  228.          mov      dh,001                ;return to window top line
  229.          add      dl,009                ;Skip to next column
  230.          cmp      dl,1+9*8              ;over the last column (8th) ?
  231.          jb       short DoAsc1          ;/
  232. ;
  233. DoAsc2:  call     ReadCh                ;Wait for entry
  234.          cmp      al,' '                ;If it is SP then Print second table
  235.          jne      short DoAsc3          ;/
  236.          add      byte ptr [CurrentChar],080h ;Swap hi <> lo ascii
  237.          jmp      short DoAsc0          ;And print other half
  238. ;
  239. DoAsc3:  cmp      al,Escape             ;If Escape then exit
  240.          jne      short DoAsc2
  241. ;
  242. DoAsc9:  call     PopOldScreen          ;Restore Old Screen and cursor position
  243. ;
  244.      pop      ax                    ;restore all the used registers
  245.          pop      bx
  246.          pop      cx
  247.          pop      dx
  248.          pop      ds
  249.          pop      es
  250.          pop      si
  251.          pop      di
  252.          pop      bp
  253.          ret
  254. DoAscii  endp
  255. ;
  256. ;*****************************************************************************
  257. ;procedure           DoConversion                                            *
  258. ;procedure to handle the base number conversions :                           *
  259. ;*****************************************************************************
  260. DoConversion proc near
  261.          push     bp                    ;save all the used registers
  262.          push     di
  263.          push     si
  264.          push     es
  265.          push     ds
  266.          push     dx
  267.          push     cx
  268.          push     bx
  269.          push     ax
  270. ;
  271. DoConv0: mov      byte ptr [WindowKind],'C' ;Draw Conversion window
  272.          call     PushOldScreen         ;Save Old Screen and cursor position
  273. ;
  274.          mov      dx,00101h             ;GotoXY 1,1 relative to window
  275.          call     GotoXY                ;/
  276.          mov      dx,offset HeaderC1    ;Print the header
  277.          call     WriteLn               ;/
  278.          mov      dx,00102h             ;GotoXY 1,2 relative to window
  279.          call     GotoXY                ;/
  280.          mov      dx,offset HeaderC2    ;Print the header
  281.          call     WriteLn               ;/
  282. DoConv1: mov      dx,00401h             ;GotoXY 1,4 relative to window
  283.          call     GotoXY                ;/
  284.          mov      cx,WindowWidthC       ;Clear the line
  285.          call     PrintSpc              ;/
  286. ;
  287.          mov      dx,00403h             ;GotoXY 3,4 relative to window
  288.          call     GotoXY                ;/
  289.          mov      dx,offset EnterData   ;Ask for entry
  290.          call     WriteLn               ;/
  291. ;
  292.          mov      dx,offset ReadBuf     ;Read the user entry
  293.          mov      ax,17                 ; / 17 bytes to read at the most
  294.          call     ReadLn                ;/
  295.          or       ax,ax                 ;No data entered ?
  296.          je       DoConv9               ;/ Exit - close
  297. ;
  298.          mov      bx,ax                 ;Find the last char - base
  299.          add      bx,dx                 ;  /
  300.          dec      bx                    ; / (Last char on '$' - EOS)
  301.          mov      al,[bx]               ;/
  302.          mov      byte ptr [bx],'$'     ;and put end of string instead
  303.      and      al,0dfh        ;Make sure its upper case
  304.          cmp      al,'B'                ;Base 2 ?
  305.          jne      short DoConv2         ;/
  306.          mov      al,02
  307.          jmp      short DoConv6
  308. ;
  309. DoConv2: cmp      al,'O'                ;Base 8 ?
  310.          jne      short DoConv3         ;/
  311.          mov      al,08
  312.          jmp      short DoConv6
  313. ;
  314. DoConv3: cmp      al,'T'                ;Base 10 ?
  315.          jne      short DoConv4         ;/
  316.          mov      al,10
  317.          jmp      short DoConv6
  318. ;
  319. DoConv4: cmp      al,'H'                ;Base 16 ?
  320.          jne      DoConv1               ;/
  321.          mov      al,16
  322.          jmp      short DoConv6
  323. ;
  324. DoConv6: call     Str2Int               ;Convert it to integer
  325.          or       bx,bx                 ;Test if error in conversion
  326.          jne      Short DoConv1         ;/ 
  327. ;
  328.          call     PrintNumBases         ;Print the integer in various bases
  329. ;
  330.          jmp      DoConv1
  331. ;
  332. DoConv9: call     PopOldScreen          ;Restore Old Screen and cursor position
  333. ;
  334.          pop      ax                    ;restore all the used registers
  335.          pop      bx
  336.          pop      cx
  337.          pop      dx
  338.          pop      ds
  339.          pop      es
  340.          pop      si
  341.          pop      di
  342.          pop      bp
  343.          ret
  344. DoConversion endp
  345. ;
  346. ;*****************************************************************************
  347. ;procedure           DoMath                                                  *
  348. ;procedure to handle the simple 4 operators math :                           *
  349. ;*****************************************************************************
  350. DoMath   proc     near
  351.          push     bp                    ;save all the used registers
  352.          push     di
  353.          push     si
  354.          push     es
  355.          push     ds
  356.          push     dx
  357.          push     cx
  358.          push     bx
  359.          push     ax
  360. ;
  361.          mov      byte ptr [WindowKind],'M';Draw Math window
  362.          call     PushOldScreen         ;Save Old Screen and cursor position
  363. ;
  364.      mov      dx,00104h        ;Print headers:
  365.      call     GotoXY                ; |
  366.      mov      dx,offset HeaderM1    ; |
  367.      call      WriteLn        ; |
  368.      mov      dx,00302h        ; |
  369.      call     GotoXY                ; |
  370.      mov      dx,offset HeaderM2    ; |
  371.      call      WriteLn        ; |
  372.      mov      dx,00402h        ; |
  373.      call     GotoXY                ; |
  374.      mov      dx,offset HeaderM3    ; |
  375.      call      WriteLn        ; |
  376.      mov      dx,00502h        ; |
  377.      call     GotoXY                ; |
  378.      mov      dx,offset HeaderM4    ; |
  379.      call      WriteLn        ; |
  380.      mov      dx,00702h        ; |
  381.      call     GotoXY                ; |
  382.      mov      dx,offset HeaderM5    ; |
  383.      call      WriteLn        ;/
  384. ;
  385. DoMath1: mov      dx,00114h        ;Get Current Base
  386.      call      GotoXY        ; |
  387.      call      ReadCh        ; |
  388.      and      al,0DFh        ; | Make sure its upper case
  389.      mov      BaseMchar,al        ; |
  390.      cmp      al,'B'        ; | Set base in numeric form
  391.      jne      short DoMath11    ; | |
  392.      mov      bx,01002h        ; | |
  393.      jmp      short DoMath2        ; | |
  394. DoMath11:                ; | |
  395.      cmp      al,'O'        ; | |
  396.      jne      short DoMath12    ; | |
  397.      mov      bx,00608h        ; | |
  398.      jmp      short DoMath2        ; | |
  399. DoMath12:                ; | |
  400.      cmp      al,'T'        ; | |
  401.      jne      short DoMath13    ; | |
  402.      mov      bx,0050Ah        ; | |
  403.      jmp      short DoMath2        ; | |
  404. DoMath13:                ; | |
  405.      cmp      al,'H'        ; | |
  406.      jne      short DoMath14    ; | |
  407.      mov      bx,00410h        ; | |
  408.      jmp      short DoMath2        ; | |
  409. DoMath14:                ; |/
  410.      cmp      al,Escape        ; |
  411.      jne      short DoMath1        ; |
  412.      jmp      DoMath9        ; |
  413. ;                    ; |
  414. DoMath2: mov      BaseMNum,bl        ; /
  415.      mov      BaseMWidth,bh        ;/
  416.      call      WriteCh        ;Print it
  417. ;
  418. DoMath3: mov      dx,00309h        ;Clear old (optional) data
  419.      call     GotoXY                ; |
  420.      mov      cx,16            ; |
  421.      call      PrintSpc        ; |
  422.      mov      dx,00413h        ; |
  423.      call     GotoXY                ; |
  424.      mov      al,' '        ; |
  425.      call      WriteCh        ; |
  426.      mov      dx,00509h        ; |
  427.      call     GotoXY                ; |
  428.      call      PrintSpc        ; |
  429.      mov      dx,0070Bh        ; |
  430.      call     GotoXY                ; |
  431.      call      PrintSpc        ;/
  432. ;
  433. DoMath4: mov      dx,00309h        ;Clear old (optional) data
  434.      call     GotoXY                ; |
  435.      mov      cx,16            ; |
  436.      call      PrintSpc        ; |
  437.      mov      dx,00309h        ;Get first operand
  438.      call      GotoXY        ; |
  439.          mov      dx,offset ReadBuf     ; | Read the user entry,
  440.          mov      ax,16                 ; | 16 bytes to read at the most
  441.          call     ReadLn                ; | /
  442.          or       ax,ax                 ; | No data entered ?
  443.          jne      short DoMath41        ; | / Exit - close
  444.          jmp      DoMath9               ; |
  445. DoMath41:                ; |
  446.      mov      al,BaseMNum        ; | Convert the string pointed by DX
  447.      call      Str2Int        ; | / to numeric data
  448.          or       bx,bx                 ; | Test if error in conversion
  449.          jne      Short DoMath4         ; |
  450.      mov      si,ax            ;/  Save it in si
  451. ;
  452. DoMath5: mov      dx,00413h        ;Clear old (optional) data
  453.      call     GotoXY                ; |
  454.      mov      al,' '        ; |
  455.      call      WriteCh        ; |
  456.      mov      dx,00413h        ;Get operator
  457.      call      GotoXY        ; |
  458.      call      ReadCh        ; |
  459.      cmp      al,'+'        ; |
  460.      je      short DoMath51    ; |
  461.      cmp      al,'-'        ; |
  462.      je      short DoMath51    ; |
  463.      cmp      al,'*'        ; |
  464.      je      short DoMath51    ; |
  465.      cmp      al,'/'        ; |
  466.      je      short DoMath51    ; |
  467.      cmp      al,Escape        ; |
  468.      jne      short DoMath5        ; |
  469.      jmp      DoMath9        ;/
  470. DoMath51:
  471.      call      WriteCh        ;Print it
  472.      mov      bp,ax            ;And save in bp
  473. ;
  474. DoMath6: mov      dx,00509h        ;Clear old (optional) data
  475.      call     GotoXY                ; |
  476.      mov      cx,16            ; |
  477.      call      PrintSpc        ; |
  478.      mov      dx,00509h        ;Get second operand
  479.      call      GotoXY        ; |
  480.          mov      dx,offset ReadBuf     ; | Read the user entry,
  481.          mov      ax,16                 ; | 16 bytes to read at the most
  482.          call     ReadLn                ; | /
  483.          or       ax,ax                 ; | No data entered ?
  484.          je       DoMath9               ; | / Exit - close
  485.      mov      al,BaseMNum        ; | Convert the string pointed by DX
  486.      call      Str2Int        ; | / to numeric data
  487.          or       bx,bx                 ; | Test if error in conversion
  488.          jne      Short DoMath6         ; |
  489.      mov      di,ax            ;/  Save it in di
  490. ;
  491.      mov      ax,bp            ;Find what operation to perform, and
  492.      xor      bx,bx            ; | do it. Result in ax. Range error
  493.      cmp      al,'+'        ; | if bx <> 0
  494.      jne      short DoMath71    ; |
  495.      mov      ax,si            ; |
  496.      add      ax,di            ; |
  497.      jnc      short DoMath8        ; |
  498.      inc      bx            ; |
  499.      jmp      short DoMath8        ; |
  500. ;                    ; |
  501. DoMath71:                ; |
  502.      cmp      al,'-'        ; |
  503.      jne      short DoMath72    ; |
  504.      mov      ax,si            ; |
  505.      sub      ax,di            ; |
  506.      jnc      short DoMath8        ; |
  507.      inc      bx            ; |
  508.      jmp      short DoMath8        ; |
  509. ;                    ; |
  510. DoMath72:                ; |
  511.      cmp      al,'*'        ; |
  512.      jne      short DoMath73    ; |
  513.      mov      ax,si            ; |
  514.      mul      di            ; |
  515.      mov      bx,dx            ; | if dx <> 0 - range error
  516.      jmp      short DoMath8        ; |
  517. ;                    ; |
  518. DoMath73:                ; |
  519.      mov      ax,si            ; | Must be division
  520.      xor      dx,dx            ; |
  521.      or      di,di            ; | Test for divide by zero
  522.      je      short DoMath733    ; | /
  523.      div      di            ; |
  524.      jmp      short DoMath8        ; |
  525. DoMath733:                ; |
  526.      inc      bx            ; |
  527.      jmp      short DoMath8        ;/
  528. ;
  529. DoMath8: mov      dx,0070Bh        ;Print result
  530.      call      GotoXY        ; |
  531.      or      bx,bx            ; | Range Error ?
  532.      jne      DoMath82        ; | /
  533.      mov      bl,BaseMNum        ; | No - print the number in AX
  534.      mov      bh,BaseMWidth        ; | |
  535.      mov      cl,' '        ; | |
  536.      cmp      bl,010        ; | |
  537.      je      DoMath81        ; | |
  538.      mov      cl,'0'        ; | |
  539. DoMath81:                ; | |
  540.      call      PrintNum        ; |/
  541.      jmp      short DoMath83
  542. ;
  543. DoMath82:
  544.      mov      dx,offset HeaderMr    ;Print "Range Error"
  545.      call      WriteLn        ;/
  546. ;
  547. DoMath83:
  548.      call      ReadCh        ;Wait for keystroke
  549.      cmp      al,Escape
  550.      je      short DoMath9
  551.      jmp      DoMath3
  552. ;
  553. DoMath9: call     PopOldScreen          ;Restore Old Screen and cursor position
  554. ;
  555.      pop      ax                    ;restore all the used registers
  556.          pop      bx
  557.          pop      cx
  558.          pop      dx
  559.          pop      ds
  560.          pop      es
  561.          pop      si
  562.          pop      di
  563.          pop      bp
  564.          ret
  565. DoMath   endp
  566. ;
  567. ;*****************************************************************************
  568. ;procedure           DoScanCode                                              *
  569. ;procedure to handle scan code printing :                                    *
  570. ;*****************************************************************************
  571. DoScanCode proc   near
  572.          push     bp                    ;save all the used registers
  573.          push     di
  574.          push     si
  575.          push     es
  576.          push     ds
  577.          push     dx
  578.          push     cx
  579.          push     bx
  580.          push     ax
  581. ;
  582.          mov      byte ptr [WindowKind],'S';Draw Scan COde window
  583.          call     PushOldScreen         ;Save Old Screen and cursor position
  584. ;
  585.      mov      dx,00103h        ;Print headers:
  586.      call     GotoXY                ; |
  587.      mov      dx,offset HeaderS1    ; |
  588.      call      WriteLn        ; |
  589.      mov      dx,00301h        ; |
  590.      call     GotoXY                ; |
  591.      mov      dx,offset HeaderS2    ; |
  592.      call      WriteLn        ; |
  593.      mov      dx,00401h        ; |
  594.      call     GotoXY                ; |
  595.      mov      dx,offset HeaderS3    ; |
  596.      call      WriteLn        ;/
  597. ;
  598. DoScan1: mov      dx,0010Dh        ;Wait for a key
  599.      call     GotoXY        ; |
  600.      call      ReadCh        ; |
  601.      push      ax            ; |
  602.      mov      cx,2            ; | Clear old one
  603.      call      PrintSpc        ; | /
  604.      mov      dx,0010Dh        ; |
  605.      call      GotoXY        ; |
  606.      cmp      al,' '        ; | Print it if printable
  607.      jae      DoScan10        ; | |
  608.      mov      ah,al            ; | |
  609.      mov      al,'^'        ; | |
  610.      call      WriteCh        ; | |
  611.      mov      al,ah            ; | |
  612.      add      al,'@'        ; | |
  613. DoScan10:                ; | |
  614.      call      WriteCh        ; |/
  615.      pop      ax            ; |
  616. ;                    ; |
  617.      cmp      al,Escape        ;Quit ?
  618.      je      short DoScan9        ;/
  619. ;
  620.      or      al,al            ;Is it extended ascii code ?
  621.      jne      DoScan2        ;/
  622.      mov      dx,0030Ah        ;Print "Extended"
  623.      call      GotoXY        ; |
  624.      mov      dx,offset HeaderS4    ; |
  625.      call      WriteLn        ; |
  626.      mov      dx,0040Ah        ; |
  627.      call      GotoXY        ; |
  628.      mov      dx,offset HeaderS4    ; |
  629.      call      WriteLn        ;/
  630.      mov      al,ah
  631.      jmp      short DoScan3
  632. ;
  633. DoScan2: mov      dx,0030Ah        ;Clear optional old "Extended"
  634.      call      GotoXY        ; |
  635.      mov      cx,8            ; |
  636.      call      PrintSpc        ; |
  637.      mov      dx,0040Ah        ; |
  638.      call      GotoXY        ; |
  639.      mov      cx,8            ; |
  640.      call      PrintSpc        ;/
  641. ;
  642. DoScan3: mov      dx,00306h        ;Print in Hex form
  643.      call      GotoXY        ; |
  644.      mov      bx,00310h        ; | 3 places, base 10h
  645.      mov      cl,'0'        ; | The prefix char
  646.      xor      ah,ah            ; |
  647.      call      PrintNum        ;/
  648.      mov      dx,00406h        ;Print in Dec form
  649.      call      GotoXY        ; |
  650.      mov      bx,0030Ah        ; | 3 places, base 10
  651.      mov      cl,' '        ; | The prefix char
  652.      call      PrintNum        ;/
  653. ;
  654.      jmp      DoScan1        ;Continue to next char
  655. ;
  656. DoScan9: call     PopOldScreen          ;Restore Old Screen and cursor position
  657. ;
  658.      pop      ax                    ;restore all the used registers
  659.          pop      bx
  660.          pop      cx
  661.          pop      dx
  662.          pop      ds
  663.          pop      es
  664.          pop      si
  665.          pop      di
  666.          pop      bp
  667.          ret
  668. DoScanCode endp
  669. ;
  670. ;
  671. ;Save Old Screen status , to recover when exit :
  672. PushOldScreen proc near
  673.          push     ax
  674.          push     bx
  675.          push     cx
  676.          push     dx
  677.          push     si
  678.          push     di
  679.          push     es
  680.          push     ds
  681.          mov      ah,BiosGetMode        ;Test what Mode in On
  682.          int      010h                  ; /
  683.          cmp      al,7            ;/ ( Is it mono ? )
  684.          je       short PushOldScreen1
  685. ;
  686.          mov      word ptr [ScreenBase],CGAAddress ;Set up as CGA
  687.          jmp      short PushOldScreen2
  688. ;
  689. PushOldScreen1:
  690.          mov      word ptr [ScreenBase],MonoAddress ;Set up as Mono
  691. ;
  692. PushOldScreen2:
  693. ;
  694.      push      bx            ;Save current active display page
  695.          mov      ah,BiosGetLoc         ;Get Cursor Location
  696.          int      010h                  ; / ( bh hold page from mode test )
  697.          mov      [OldCursor],dx        ;/
  698.      pop      bx
  699. ;
  700.      and      bh, 003h        ;Make page number between 0-3 only
  701.      mov      bl,bh            ;Multiply it by ScreenSize
  702.      xor      bh,bh            ; \
  703.      mov      ax,ScreenSize        ;  | Preper source offset
  704.      mul      bx            ; /
  705.      mov      si,ax            ;Get current page offset into si
  706.      mov      word ptr [ScreenOffCur],ax
  707.      inc      bx
  708.      and      bx,00003h        ;Make sure its within range (mod 4)
  709.      mov      ax,ScreenSize        ; \
  710.      mul      bx            ;  | Preper destination offset
  711.      mov      di,ax            ; /  save page offset into di
  712.      mov      word ptr [ScreenOffSav],ax
  713. ;
  714.          push     ds
  715.          cld
  716.          mov      es,[ScreenBase]       ;Save Old Screen buffer -
  717.          mov      ds,[ScreenBase]       ;Save all the 4k for the simplicity
  718.          mov      cx,ScreenSize / 2     ; | (Move Words)
  719.          rep      movsw                 ;/ ds:si --> es:di ,  cx times
  720.          pop      ds
  721. ;
  722.          cmp      byte ptr [WindowKind],'C' ;Is it Converstion Screen ?
  723.          jne      PushOldScreen4        ;/
  724. ;
  725.          xor      dx,dx                 ;Print our window
  726.          call     GotoXY                ; |
  727.          mov      byte ptr [CharAttr],InversAttr
  728.          mov      bx,offset BorderC1    ; |
  729.          xchg     bx,dx                 ; |
  730.          call     WriteLn               ; | (border1 - top)
  731.          xchg     bx,dx                 ; |
  732.          mov      cx,WindowHeightC      ; |
  733. PushOldScreen3:                         ; |
  734.          inc      dh                    ; | (Y position)
  735.          call     GotoXY                ; |
  736.          push     dx
  737.          mov      dx,offset BorderC21   ; |
  738.          call     WriteLn               ; | (border2 - middle)
  739. ;
  740.          mov      dx,offset BorderC22   ; |
  741.          mov      byte ptr [CharAttr],NormalAttr
  742.          call     WriteLn               ; | (border2 - middle)
  743. ;
  744.          mov      dx,offset BorderC23   ; |
  745.          mov      byte ptr [CharAttr],InversAttr
  746.          call     WriteLn               ; | (border2 - middle)
  747. ;
  748.          pop      dx                    ; |
  749.          loop     PushOldScreen3        ; |
  750. ;                                       ; |
  751.          inc      dh                    ; | (Y position)
  752.          call     GotoXY                ; |
  753.          mov      dx,offset BorderC3    ; |
  754.          call     WriteLn               ;/  (border3 - bottom)
  755.          mov      byte ptr [CharAttr],NormalAttr
  756.          jmp      PushOldScreen99
  757. ;
  758. PushOldScreen4:
  759.          cmp      byte ptr [WindowKind],'A' ;Is it Ascii Table Screen ?
  760.          jne      PushOldScreen6        ;/
  761. ;
  762.          xor      dx,dx                 ;Print our window
  763.          call     GotoXY                ; |
  764.          mov      bx,offset BorderA1    ; |
  765.          mov      byte ptr [CharAttr],InversAttr
  766.          xchg     bx,dx                 ; |
  767.          call     WriteLn               ; | (border1 - top)
  768.          xchg     bx,dx                 ; |
  769.          mov      cx,WindowHeightA      ; |
  770. PushOldScreen5:                         ; |
  771.          inc      dh                    ; | (Y position)
  772.          call     GotoXY                ; |
  773.          push     dx
  774.          mov      dx,offset BorderA21   ; |
  775.          call     WriteLn               ; | (border2 - middle)
  776. ;
  777.          mov      dx,offset BorderA22   ; |
  778.          mov      byte ptr [CharAttr],NormalAttr
  779.          call     WriteLn               ; | (border2 - middle)
  780. ;
  781.          mov      dx,offset BorderA23   ; |
  782.          mov      byte ptr [CharAttr],InversAttr
  783.          call     WriteLn               ; | (border2 - middle)
  784. ;
  785.          pop      dx                    ; |
  786.          loop     PushOldScreen5        ; |
  787. ;                                       ; |
  788.          inc      dh                    ; | (Y position)
  789.          call     GotoXY                ; |
  790.          mov      dx,offset BorderA3    ; |
  791.          call     WriteLn               ;/  (border3 - bottom)
  792.          mov      byte ptr [CharAttr],NormalAttr
  793.          jmp      PushOldScreen99
  794. ;
  795. PushOldScreen6:
  796.      cmp      byte ptr [WindowKind],'M' ;Is it Math Screen ?
  797.          jne      PushOldScreen8        ;/
  798. ;
  799.          xor      dx,dx                 ;Print our window
  800.          call     GotoXY                ; |
  801.          mov      byte ptr [CharAttr],InversAttr
  802.          mov      bx,offset BorderM1    ; |
  803.          xchg     bx,dx                 ; |
  804.          call     WriteLn               ; | (border1 - top)
  805.          xchg     bx,dx                 ; |
  806.          mov      cx,WindowHeightM      ; |
  807. PushOldScreen7:                         ; |
  808.          inc      dh                    ; | (Y position)
  809.          call     GotoXY                ; |
  810.          push     dx
  811.          mov      dx,offset BorderM21   ; |
  812.          call     WriteLn               ; | (border2 - middle)
  813. ;
  814.          mov      dx,offset BorderM22   ; |
  815.          mov      byte ptr [CharAttr],NormalAttr
  816.          call     WriteLn               ; | (border2 - middle)
  817. ;
  818.          mov      dx,offset BorderM23   ; |
  819.          mov      byte ptr [CharAttr],InversAttr
  820.          call     WriteLn               ; | (border2 - middle)
  821. ;
  822.          pop      dx                    ; |
  823.          loop     PushOldScreen7        ; |
  824. ;                                       ; |
  825.          inc      dh                    ; | (Y position)
  826.          call     GotoXY                ; |
  827.          mov      dx,offset BorderM3    ; |
  828.          call     WriteLn               ;/  (border3 - bottom)
  829.          mov      byte ptr [CharAttr],NormalAttr
  830.          jmp      PushOldScreen99
  831. ;
  832. PushOldScreen8:
  833.          cmp      byte ptr [WindowKind],'S' ;Is it Scan Code Screen ?
  834.          jne      PushOldScreen10       ;/
  835. ;
  836.          xor      dx,dx                 ;Print our window
  837.          call     GotoXY                ; |
  838.          mov      byte ptr [CharAttr],InversAttr
  839.          mov      bx,offset BorderS1    ; |
  840.          xchg     bx,dx                 ; |
  841.          call     WriteLn               ; | (border1 - top)
  842.          xchg     bx,dx                 ; |
  843.          mov      cx,WindowHeightS      ; |
  844. PushOldScreen9:                         ; |
  845.          inc      dh                    ; | (Y position)
  846.          call     GotoXY                ; |
  847.          push     dx
  848.          mov      dx,offset BorderS21   ; |
  849.          call     WriteLn               ; | (border2 - middle)
  850. ;
  851.          mov      dx,offset BorderS22   ; |
  852.          mov      byte ptr [CharAttr],NormalAttr
  853.          call     WriteLn               ; | (border2 - middle)
  854. ;
  855.          mov      dx,offset BorderS23   ; |
  856.          mov      byte ptr [CharAttr],InversAttr
  857.          call     WriteLn               ; | (border2 - middle)
  858. ;
  859.          pop      dx                    ; |
  860.          loop     PushOldScreen9        ; |
  861. ;                                       ; |
  862.          inc      dh                    ; | (Y position)
  863.          call     GotoXY                ; |
  864.          mov      dx,offset BorderS3    ; |
  865.          call     WriteLn               ;/  (border3 - bottom)
  866.          mov      byte ptr [CharAttr],NormalAttr
  867.          jmp      PushOldScreen99
  868. ;
  869. PushOldScreen10:
  870.          cmp      byte ptr [WindowKind],'N' ;Is it Main Screen ?
  871.          jne      PushOldScreen99       ;/
  872. ;
  873.          xor      dx,dx                 ;Print our window
  874.          call     GotoXY                ; |
  875.          mov      byte ptr [CharAttr],InversAttr
  876.          mov      bx,offset BorderN1    ; |
  877.          xchg     bx,dx                 ; |
  878.          call     WriteLn               ; | (border1 - top)
  879.          xchg     bx,dx                 ; |
  880.          mov      cx,WindowHeightN      ; |
  881. PushOldScreen11:                        ; |
  882.          inc      dh                    ; | (Y position)
  883.          call     GotoXY                ; |
  884.          push     dx
  885.          mov      dx,offset BorderN21   ; |
  886.          call     WriteLn               ; | (border2 - middle)
  887. ;
  888.          mov      dx,offset BorderN22   ; |
  889.          mov      byte ptr [CharAttr],NormalAttr
  890.          call     WriteLn               ; | (border2 - middle)
  891. ;
  892.          mov      dx,offset BorderN23   ; |
  893.          mov      byte ptr [CharAttr],InversAttr
  894.          call     WriteLn               ; | (border2 - middle)
  895. ;
  896.          pop      dx                    ; |
  897.          loop     PushOldScreen11       ; |
  898. ;                                       ; |
  899.          inc      dh                    ; | (Y position)
  900.          call     GotoXY                ; |
  901.          mov      dx,offset BorderN3    ; |
  902.          call     WriteLn               ;/  (border3 - bottom)
  903.          mov      byte ptr [CharAttr],NormalAttr
  904.          jmp      PushOldScreen99
  905. ;
  906. ;
  907. PushOldScreen99:
  908.          pop      ds
  909.          pop      es
  910.          pop      di
  911.          pop      si
  912.          pop      dx
  913.          pop      cx
  914.          pop      bx
  915.          pop      ax
  916.          ret
  917. PushOldScreen endp
  918. ;
  919. ;Restore Old Screen status - recover to exit :
  920. PopOldScreen proc near
  921.          push     ax
  922.          push     bx
  923.          push     cx
  924.          push     dx
  925.          push     si
  926.          push     di
  927.          push     es
  928.          push     ds
  929.          mov      ah,BiosGetMode    ;Get current page number into bh
  930.      int      010h            ;/
  931.      mov      dx,[OldCursor]        ;Set to Old Cursor Location
  932.          mov      ah,BiosLocate
  933.          int      010h                  ;Call Bios
  934. ;
  935.          push     ds
  936.          cld
  937.          mov      si,[ScreenOffSav]     ;Restore Old Screen buffer -
  938.          mov      di,[ScreenOffCur]     ;Restore all the 4k for the simplicity
  939.          mov      es,[ScreenBase]       ; |
  940.          mov      ds,[ScreenBase]       ; | (change ds last!)
  941.          mov      cx,ScreenSize / 2     ; | (Move Words)
  942.          rep      movsw                 ;/ ds:si --> es:di ,  cx times
  943.          pop      ds
  944. ;
  945.          pop      ds
  946.          pop      es
  947.          pop      di
  948.          pop      si
  949.          pop      dx
  950.          pop      cx
  951.          pop      bx
  952.          pop      ax
  953.          ret
  954. PopOldScreen endp
  955. ;
  956. ;Print the char in al in decimal, hexadecimal and ascii forms:
  957. PrintAsc proc     near
  958.          push     ax
  959.          push     bx
  960.          push     cx
  961. ;
  962.          xor      ah,ah                 ;Print in Decimal form
  963.          mov      bl,010                ; | Base - 10
  964.          mov      bh,003                ; | On 3 places
  965.          mov      cl,' '                ; | Prefix - space
  966.          call     PrintNum              ;/
  967. ;
  968.          push     ax
  969.          mov      al,' '                ;Print one Space
  970.          call     WriteCh               ;/
  971.          pop      ax
  972. ;
  973.          mov      bl,016                ;Print in HexaDecimal form : Base - 16
  974.          mov      bh,002                ; | On 2 places
  975.          mov      cl,'0'                ; | Prefix - '0'
  976.          call     PrintNum              ;/
  977. ;
  978.          push     ax
  979.          mov      al,' '                ;Print one Space
  980.          call     WriteCh               ;/
  981.          pop      ax
  982. ;
  983.          call     WriteCh               ;Print it in Ascii form
  984. ;
  985.          pop      cx
  986.          pop      bx
  987.          pop      ax
  988.          ret
  989. PrintAsc endp
  990. ;
  991. ;Print cx spaces from current XY on screen
  992. PrintSpc proc     near
  993.          push     ax
  994.          push     cx
  995. ;
  996.          mov      al,' '                ;Preper Space to print
  997. PrintSpc1:
  998.          call     WriteCh               ;Print it cx times
  999.          loop     PrintSpc1             ;/
  1000. ;
  1001.          pop      cx
  1002.          pop      ax
  1003.          ret
  1004. PrintSpc endp
  1005. ;
  1006. ;Print the number in variouse base (note the registers are affected) :
  1007. PrintNumBases proc near
  1008. ;
  1009.          mov      bh,16                 ;Print base 2 in 16 places
  1010.          mov      dx,00603h             ;GotoXY 3,6 relative to window
  1011.          call     GotoXY                ;/
  1012.          mov      dx,offset Base2       ;Print the number in base 2
  1013.          call     WriteLn               ; |
  1014.          mov      cl,'0'                ; | Prefix fill character
  1015.          mov      bl,02                 ; |
  1016.          call     PrintNum              ;/
  1017. ;
  1018.          mov      bh,06                 ;Print base 8 in 6 places
  1019.          mov      dx,00703h             ;GotoXY 3,7 relative to window
  1020.          call     GotoXY                ;/
  1021.          mov      dx,offset Base8       ;Print the number in base 8
  1022.          call     WriteLn               ; |
  1023.          mov      cx,10                 ; | Print 10 leedin spaces
  1024.          call     PrintSpc              ; | /
  1025.          mov      cl,'0'                ; | Prefix fill character          
  1026.          mov      bl,08                 ; |
  1027.          call     PrintNum              ;/
  1028. ;
  1029.          mov      bh,16                 ;Print base 10 in 16 places
  1030.          mov      dx,00803h             ;GotoXY 3,8 relative to window
  1031.          call     GotoXY                ;/
  1032.          mov      dx,offset Base10      ;Print the number in base 10
  1033.          call     WriteLn               ; |
  1034.          mov      cl,' '                ; | Prefix fill character
  1035.          mov      bl,10                 ; |
  1036.          call     PrintNum              ;/
  1037. ;
  1038.          mov      bh,04                 ;Print base 16 in 4 places
  1039.          mov      dx,00903h             ;GotoXY 3,9 relative to window
  1040.          call     GotoXY                ;/
  1041.          mov      dx,offset Base16      ;Print the number in base 16
  1042.          call     WriteLn               ; |
  1043.          mov      cx,12                 ; | Print 12 leedin spaces
  1044.          call     PrintSpc              ; | /
  1045.          mov      cl,'0'                ; | Prefix fill character          
  1046.          mov      bl,16                 ; |
  1047.          call     PrintNum              ;/
  1048. ;
  1049.          ret
  1050. PrintNumBases endp
  1051. ;
  1052. ;Print the given integer number AX in base Bl, in Bh places (less then 20).
  1053. ;The prefix fill character is in cl (i.e. in 00001000 = 8 cl = '0')
  1054. ;
  1055. PrintNum proc     near
  1056.          push     ax
  1057.          push     bx
  1058.          push     cx
  1059.          push     dx
  1060.          push     di
  1061.          push     es
  1062. ;
  1063.          mov      dx,ds                 ;Trasfer seg. to es
  1064.          mov      es,dx
  1065.          push     cx                    ;Save fill char in cl
  1066. ;
  1067.          std
  1068.          mov      di,offset PrNumEnd-1  ;Current byte to save
  1069.          mov      cl,bl                 ;Preper the divisor
  1070.          xor      ch,ch                 ;/
  1071. ;
  1072.          or       ax,ax                ;Is it 0 to be print ?
  1073.          je       PrNum5               ;If so handle seperately
  1074. ;
  1075. PrNum1:  xor      dx,dx
  1076.          div      cx                    ;Quontient in ax, remainder in dx
  1077.          or       ax,ax                 ;No quontient ?
  1078.          jne      short PrNum2
  1079.          or       dx,dx                 ;No remainder ?
  1080.          je       PrNum3
  1081. PrNum2:  xchg     dx,ax
  1082.          cmp      al,10                 ;Covnert it to ascii code
  1083.          jae      PrNum21               ; |
  1084.          add      al,'0'-('A'-10)       ; |
  1085. PrNum21: add      al,'A'-10             ;/
  1086.          stosb                          ;Save the remainder
  1087.          xchg     dx,ax
  1088.          dec      bh                    ;Decrease current number of places
  1089.          jmp      short PrNum1
  1090. ;
  1091. PrNum3:  pop      ax                    ;The fill character
  1092.          test     bh,080h               ;Places - overflow ?
  1093.          jne      PrNum6                ;/
  1094.          or       bh,bh                 ;Places fit exactly ?
  1095.          je       PrNum6                ;/
  1096. PrNum4:  stosb                          ;Fill with prefix fill char(s)
  1097.          dec      bh                    ; |
  1098.          jne      PrNum4                ;/
  1099.          jmp      short PrNum6          ;Skip the ax = 0 case
  1100. ;
  1101. ;If we get here then ax=0 and a zero in the right format must be printed
  1102. PrNum5:  mov      al,'0'
  1103.          stosb                          ;Save one zero
  1104.          dec      bh                    ;One less place
  1105.          jmp      short PrNum3          ;And handle as usual
  1106. ;
  1107. PrNum6:  mov      dx,di                 ;Print it
  1108.          inc      dx                    ; |
  1109.          call     WriteLn               ;/
  1110.          pop      es
  1111.          pop      di
  1112.          pop      dx
  1113.          pop      cx
  1114.          pop      bx
  1115.          pop      ax
  1116.          ret
  1117. ;
  1118. PrNumBfLn equ     21                   ;Buffer length up to 20
  1119. PrNumBuf db       PrNumBfLn dup(' ')   ;Buffer to create the number here
  1120. PrNumEnd db       '$'
  1121. ;
  1122. PrintNum endp
  1123. ;
  1124. ;Transfer a string pointed by DS:DX into an integer. The string is terminated
  1125. ;by a '$' char . Base of convertion is in al (2..16) . Return result in ax
  1126. ;If succesfull then bx = 0 ,  else bx = 1 (error) .
  1127. Str2Int  proc     near
  1128.          push     cx
  1129.          push     dx
  1130.          push     si
  1131. ;
  1132.          mov      si,dx
  1133.          mov      cl,al                 ;Save Base in cx
  1134.          xor      ch,ch                 ;/
  1135.          xor      ax,ax                 ;Clear current integer value1
  1136. ;
  1137.          cld                            ;Direction up
  1138. Str2In1: mov      dx,ax                 ;Save it temporary
  1139.          lodsb
  1140.          cmp      al,'$'                ;End of data ?
  1141.          je       Str2In8               ;/
  1142.          mov      ah,cl                 ;Give Chr2Dig the base
  1143.          call     Chr2Dig
  1144.          mov      bl,al                 ;Save new digit in bx
  1145.          xor      bh,bh                 ;/
  1146.          mov      ax,dx                 ;Get Old integer back
  1147.          cmp      bl,0ffh               ;Wrong digit ?
  1148.          je       Str2In7               ;/
  1149.          mul      cx                    ;Multiply old value by base
  1150.          add      ax,bx                 ;and add new data
  1151.          jmp      short Str2In1         ;/
  1152. ;
  1153. Str2In7: mov      bx,0001h              ;Error
  1154.          jmp      short Str2In9
  1155. Str2In8: mov      ax,dx                 ;Get Integer back
  1156.          mov      bx,0000h              ;O.K.
  1157. Str2In9: pop      si
  1158.          pop      dx
  1159.          pop      cx
  1160.          ret
  1161. Str2Int  endp
  1162. ;
  1163. ;Return 0ffh in al if the char in al is not a digit in range 0 .. base-1, where
  1164. ;base is in ah. The digit is given in Ascii form and returned in binary (in al)
  1165. Chr2Dig  proc     near
  1166.      call      ToLower              ;if in A..F convert to a..f
  1167.          sub      al,'0'
  1168.          cmp      al,10                ;if hex digit
  1169.          jb       chr2Dg1
  1170.          sub      al,('a'-'0')-10
  1171. Chr2Dg1: cmp      al,ah                ;must be less the base
  1172.          jb       Chr2Dg9
  1173.          mov      al,0ffh              ;wrong digit
  1174. Chr2Dg9: ret
  1175. Chr2dig  endp
  1176. ;
  1177. ;COnvert the char in al into lower case :
  1178. ToLower  proc     near
  1179.          cmp      al,'A'               ;if below A
  1180.          jb       ToLow9
  1181.          cmp      al,'Z'               ;if above Z
  1182.          ja       ToLow9
  1183.          add      al,'a'-'A'
  1184. ToLow9:  ret
  1185. ToLower  endp
  1186. ;
  1187. ;Locate the cursor at position X = Dl, Y = Dh (Relative to Top Left of screen)
  1188. GotoXY   proc     near
  1189.          push     ax
  1190.          push     bx
  1191.          push     cx
  1192.          push     dx
  1193.          mov      [CursorX],dl          ;Save Current position
  1194.          mov      [CursorY],dh          ;/
  1195. ;
  1196.          cmp      byte ptr [WindowKind],'A' ;Is it ascii table window ?
  1197.          jne      GotoXY1               ;/
  1198.          mov      al,[WindowLeftA]      ;Preper to add Top Left of window offset
  1199.          mov      ah,[WindowTopA]       ;/
  1200.          jmp      short GotoXY9
  1201. ;
  1202. GotoXY1: cmp      byte ptr [WindowKind],'C' ;Is it conversion window ?
  1203.          jne      GotoXY2               ;/
  1204.          mov      al,[WindowLeftC]      ;Preper to add Top Left of window offset
  1205.          mov      ah,[WindowTopC]       ;/
  1206.          jmp      short GotoXY9
  1207. ;
  1208. GotoXY2: cmp      byte ptr [WindowKind],'M' ;Is it math window ?
  1209.          jne      GotoXY3               ;/
  1210.          mov      al,[WindowLeftM]      ;Preper to add Top Left of window offset
  1211.          mov      ah,[WindowTopM]       ;/
  1212.          jmp      short GotoXY9
  1213. ;
  1214. GotoXY3: cmp      byte ptr [WindowKind],'S' ;Is it conversion window ?
  1215.          jne      GotoXY4               ;/
  1216.          mov      al,[WindowLeftS]      ;Preper to add Top Left of window offset
  1217.          mov      ah,[WindowTopS]       ;/
  1218.          jmp      short GotoXY9
  1219. ;
  1220. GotoXY4: cmp      byte ptr [WindowKind],'N' ;Is it Main window ?
  1221.          jne      GotoXY5               ;/
  1222.          mov      al,[WindowLeftN]      ;Preper to add Top Left of window offset
  1223.          mov      ah,[WindowTopN]       ;/
  1224.          jmp      short GotoXY9
  1225. GotoXY5:
  1226. ;
  1227. GotoXY9: add      dx,ax                 ;Top Left of window position
  1228.          mov      bh,0                  ;Screen number 0
  1229.          mov      ah,BiosLocate
  1230.          int      010h                  ;Call Bios
  1231.          pop      dx
  1232.          pop      cx
  1233.          pop      bx
  1234.          pop      ax
  1235.          ret
  1236. GotoXY   endp
  1237. ;
  1238. ;Read one character into al (Result) ,  ah (ScanCode).
  1239. ReadCh   proc     near
  1240.          push     bx
  1241.          push     cx
  1242.          push     dx
  1243.          mov      ah,BiosGetCh
  1244.          int      016h                  ;Call Bios
  1245.          pop      dx
  1246.          pop      cx
  1247.          pop      bx
  1248.          ret
  1249. ReadCh   endp
  1250. ;
  1251. ;Write one character from al, at current cursor location, and advance to next :
  1252. WriteCh  proc     near
  1253.          push     ax
  1254.          push     bx
  1255.          push     cx
  1256.          push     dx
  1257.          mov      ah,BiosPutCh
  1258.          mov      bl,[CharAttr]         ;SetAttribute
  1259.          mov      bh,000h               ;Page 0
  1260.          mov      cx,001h               ;Number of Chars
  1261.          int      010h                  ;Call Bios
  1262. ;
  1263.          inc      byte ptr [CursorX]    ;Advance to next char
  1264.          mov      dl,[CursorX]          ;by updating Current position
  1265.          mov      dh,[CursorY]          ; /
  1266.          call     GotoXY                ;/
  1267. ;
  1268.          pop      dx
  1269.          pop      cx
  1270.          pop      bx
  1271.          pop      ax
  1272.          ret
  1273. WriteCh  endp
  1274. ;
  1275. ;Read one line terminated by CR into the buffer DS:DX :
  1276. ;In ax the maximum number of chars to read.
  1277. ;On return ax contains actual number read. '$' sign is entered after the last char
  1278. ReadLn   proc     near
  1279.          push     bx
  1280.          push     cx
  1281.          push     dx
  1282.          push     di
  1283.          push     si
  1284.          push     es
  1285.          mov      bx,ds                 ;Copy ds to es
  1286.          mov      es,bx                 ;/
  1287.          mov      cx,ax                 ;Maximum to read
  1288.          mov      di,dx                 ;transfer pointer of buffer
  1289.      mov      si,dx            ;/
  1290.      mov      dl,[CursorX]          ;GotoXY the right position
  1291.          mov      dh,[CursorY]          ; /
  1292.          call     GotoXY                ;/
  1293.          xor      dx,dx                 ;number of chars actually read
  1294.          cld
  1295. ;
  1296. ReadLn1: call     ReadCh                ;Get One char
  1297.          cmp      al,' '                ;Printable ?
  1298.          jb       short ReadLn2
  1299.          call     WriteCh               ;Print it
  1300. ReadLn2: cmp      al,Cr                 ;Is it Cr ?
  1301.          je       short ReadLn9
  1302.      cmp      al,Escape        ;Is it Escape ?
  1303.      jne      short ReadLn3
  1304.      mov      byte ptr [si],'$'    ;If Escape pressed - exit with empty
  1305.      xor      ax,ax            ;line
  1306.      jmp      short ReadLn91
  1307. ;
  1308. ReadLn3: cmp      al,Bs                 ;Is it Back Space ?
  1309.          jne      short ReadLn4
  1310.          or       dx,dx                 ;Buffer not empty ?
  1311.          je       short ReadLn1
  1312.          dec      di                    ;eliminate one char
  1313.          dec      dx                    ; /
  1314.          inc      cx                    ;/
  1315.          push     dx
  1316.          dec      byte ptr [CursorX]    ;Return to last char
  1317.          mov      dl,[CursorX]          ;by updating Current position
  1318.          mov      dh,[CursorY]          ; /
  1319.          call     GotoXY                ;/
  1320.          mov      al,' '
  1321.          call     WriteCh               ;Erase the char
  1322.          dec      byte ptr [CursorX]    ;And return to last char again
  1323.          mov      dl,[CursorX]          ;by updating Current position
  1324.          mov      dh,[CursorY]          ; /
  1325.          call     GotoXY                ;/
  1326.          pop      dx
  1327.          jmp      short ReadLn1
  1328. ;
  1329. ReadLn4: stosb
  1330.          inc      dx
  1331. ReadLn8: loop     ReadLn1
  1332. ;
  1333. ReadLn9: mov      al,'$'
  1334.          stosb
  1335.          mov      ax,dx                 ;back into dx
  1336. ReadLn91:
  1337.      pop      es
  1338.          pop      si
  1339.          pop      di
  1340.          pop      dx
  1341.          pop      cx
  1342.          pop      bx
  1343.          ret
  1344. ReadLn   endp
  1345. ;
  1346. ;Write one line terminated by a '$' from the buffer DS:DX :
  1347. WriteLn  proc     near
  1348.          push     ax
  1349.          push     bx
  1350.          push     cx
  1351.          push     dx
  1352.          xchg     bx,dx
  1353. WriteLn1:
  1354.          mov      al,[bx]
  1355.          cmp      al,'$'
  1356.          je       WriteLn9
  1357.          call     WriteCh
  1358.          inc      bx
  1359.          jmp      WriteLn1
  1360. ;
  1361. WriteLn9:
  1362.          pop      dx
  1363.          pop      cx
  1364.          pop      bx
  1365.          pop      ax
  1366.          ret
  1367. WriteLn  endp
  1368. ;
  1369. OldCursor dw      00000h                ;Save old Cursor Position
  1370. WindowKind db     000h                  ;Kind of window : A)scii , C)onversion
  1371. CursorX    db     00                    ;Cursor Position X
  1372. CursorY    db     00                    ;Cursor Position Y
  1373. ResActive  db     00h                   ;Prevent from reentrance flag
  1374. CharAttr   db     NormalAttr            ;Current attribute to write to screen
  1375. ScreenBase    dw  0B000h                ;Screen Base Address
  1376. ScreenOffCur  dw  00000h        ;Screen Offset - current page
  1377. ScreenOffSav  dw  00000h        ;Screen Offset - saved page
  1378. OldKbdHandler dd  00000h                ;Save here old keyboard int16h
  1379. ReadBuf  db       17 dup (' ')          ;Save here the user entered data
  1380. ;
  1381. ;Base Conversion Window Parameters and Constants :
  1382. ;
  1383. BorderC1 db       '╔════════════════════════════════╗$'  ;Ascii 201,205,187
  1384. BorderC21 db      '║$'                                   ;Ascii 186
  1385. BorderC22 db      '                                $'
  1386. BorderC23 db      '║$'                                   ;Ascii 186
  1387. BorderC3 db       '╚══════════Esc to exit═══════════╝$'  ;Ascii 200,205,188
  1388. WindowWidthC equ   ($ - BorderC3) - 3    ;The Clear width inside
  1389. WindowHeightC equ  10                    ;Realy number of BorderC2? printing
  1390. InstallStamp equ  $
  1391. HeaderC1 db       '   Base Numeric Conversion$'
  1392. HeaderC2 db       'Enter number follow by B,O,T,H$'
  1393. EnterData db      'Number : $'
  1394. Base2    db       'Base  2 : $'
  1395. Base8    db       'Base  8 : $'
  1396. Base10   db       'Base 10 : $'
  1397. Base16   db       'Base 16 : $'
  1398. InstallStampLen    equ $ - InstallStamp
  1399. ;
  1400. ;Ascii Table Window Parameters and Constants :
  1401. ;
  1402. CurrentChar db    00                     ;The char to start the Ascii table
  1403. BorderA1  db      '╔═D══H══C╤═D══H══C╤═D══H══C╤═D══H══C╤═D══H══C╤═D══H══C╤═D══H══C╤═D══H══C╗$'
  1404. BorderA21 db      '║$'
  1405. BorderA22 db      '        │        │        │        │        │        │        │        $'
  1406. BorderA23 db      '║$'
  1407. BorderA3  db      '╚════════╧════Space to Toggle Ascii Low / High , Esc to Exit═══╧════════╝$'
  1408. WindowWidthA equ   ($ - BorderA3) - 3    ;The Clear width inside
  1409. WindowHeightA equ  16                    ;Realy number of BorderA2? printing
  1410. ;
  1411. ;Math Calculation Window Parameters and Constants :
  1412. ;
  1413. BorderM1 db       '╔═════Unsigned Calculus══════╗$'  ;Ascii 201,205,187
  1414. BorderM21 db      '║$'                                 ;Ascii 186
  1415. BorderM22 db      '                            $'
  1416. BorderM23 db      '║$'                                 ;Ascii 186
  1417. BorderM3 db       '╚════════Esc to exit═════════╝$'  ;Ascii 200,205,188
  1418. WindowWidthM equ   ($ - BorderM3) - 3    ;The Clear width inside
  1419. WindowHeightM equ  7                     ;Realy number of BorderM2? printing
  1420. BaseMchar db      'H'             ;Default - base 16
  1421. BaseMNum db      16             ; /
  1422. BaseMWidth db      4             ;/
  1423. HeaderM1 db      'Base (B,O,T,H):$'
  1424. HeaderM2 db      'Num1 :$'
  1425. HeaderM3 db      'Oper (+,-,*,/) :$'
  1426. HeaderM4 db      'Num2 :$'
  1427. HeaderM5 db      'Result :$'
  1428. HeaderMr db      'Range Error$'
  1429. ;
  1430. ;Scan Code Window Parameters and Constants :
  1431. ;
  1432. BorderS1 db       '╔══Press Any Key══╗$'           ;Ascii 201,205,187
  1433. BorderS21 db      '║$'                                 ;Ascii 186
  1434. BorderS22 db      '                 $'
  1435. BorderS23 db      '║$'                                 ;Ascii 186
  1436. BorderS3 db       '╚═══Esc to exit═══╝$'           ;Ascii 200,205,188
  1437. WindowWidthS equ   ($ - BorderS3) - 3    ;The Clear width inside
  1438. WindowHeightS equ  4                     ;Realy number of BorderM2? printing
  1439. HeaderS1 db      'Scan Code:$'
  1440. HeaderS2 db      'Hex:$'
  1441. HeaderS3 db      'Dec:$'
  1442. HeaderS4 db      'Extended$'
  1443. ;
  1444. ;
  1445. ;Main Window Parameters and Constants :
  1446. ;
  1447. BorderN1 db       '╔═════════════════════╗$'  ;Ascii 201,205,187
  1448. BorderN21 db      '║$'                                 ;Ascii 186
  1449. BorderN22 db      '                     $'
  1450. BorderN23 db      '║$'                                 ;Ascii 186
  1451. BorderN3 db       '╚═════════════════════╝$'  ;Ascii 200,205,188
  1452. WindowWidthN equ   ($ - BorderN3) - 3    ;The Clear width inside
  1453. WindowHeightN equ  8                     ;Realy number of BorderN2? printing
  1454. HeaderN1 db      '1. Ascii Table$'
  1455. HeaderN2 db      '2. Base Conversion$'
  1456. HeaderN3 db      '3. Math Operations$'
  1457. HeaderN4 db      '4. Scan Code$'
  1458. HeaderN9 db      'Select:$'
  1459. ;
  1460. EndOfResident Equ     $                      ;End of resident part
  1461. ;
  1462. ;*****************************************************************************
  1463. ;
  1464. ExistsMsg db      'Conv was already installed, ignored',cr,lf,'$'
  1465. InstMsg  db       'Conv is installed: Alt - A to activate,      '
  1466.      db       'Elber Gershon 88 Ver 1.1',cr,lf,'$'
  1467. ;
  1468. ;*****************************************************************************
  1469. ;procedure          install                                                  *
  1470. ;procedure to install all the system parameters and quit .                   *
  1471. ;*****************************************************************************
  1472. Install:
  1473. ;
  1474. ;Test if we already installed this once - search all segments below our CS
  1475. ;for the existance of the data code "InstallStamp":
  1476. ;I dont know was is the beginning value of segment to search which will be
  1477. ;safe for all dos versions, so we start just above the vector interrupt...
  1478. ;
  1479.      mov      bx,040h        ;End of Vector Interrupt as start seg.
  1480.      mov      ax,cs            ;Save current segment in ax
  1481. Install1:
  1482.      inc      bx            ;Go to next segment
  1483.      cmp      ax,bx            ;if Equal - we didnt find it!
  1484.      jbe      Install2        ;/
  1485.      mov      es,bx
  1486.      mov      si,offset InstallStamp
  1487.      mov      di,si
  1488.      mov      cx,InstallStampLen
  1489.      repe      cmpsb            ;Search in current segment
  1490.      jne      Install1
  1491. ;
  1492.      mov      dx,offset ExistsMsg   ;Print its already installed
  1493.          mov      ah,DosPutLn           ; /
  1494.          int      021h                  ;/
  1495. ;
  1496.      mov      ax,04c01h        ;And exit with return code of 1
  1497.      int      021h            ;/
  1498. ;     
  1499. Install2:     
  1500.      cli                            ;Disable interrupts
  1501. ;
  1502. ;Save old Keyboard interrupt routine & install ours (Hot key detection) :
  1503.          mov      al,016h               ;get old int 16 address
  1504.          mov      ah,035h               ; /
  1505.          int      021h                  ;/
  1506.          mov      word ptr cs:OldKbdHandler,bx    ;save it !
  1507.          mov      word ptr cs:OldKbdHandler[2],es ;/
  1508. ;
  1509.          mov      al,016h               ;Istall procedure - KbdHandler
  1510.          mov      dx,offset KbdHandler  ; |
  1511.          mov      ah,025h               ; |
  1512.          int      021h                  ;/
  1513. ;
  1514.          sti                            ;int enable
  1515. ;
  1516. Install9:
  1517.          mov      dx,offset InstMsg     ;Print it when install
  1518.          mov      ah,DosPutLn           ; /
  1519.          int      021h                  ;/
  1520. ;
  1521. ;Set the length of resident part (in paragraphs) to leave, and quit:
  1522.          mov      dx,(offset EndOfResident - offset code + 15) shr 4
  1523.      mov      ax,03100h        ;Return with ret code 0
  1524.      int      021h                  ;Terminate & stay resident
  1525. ;
  1526. code     ends
  1527. ;
  1528.          end      starter
  1529.