home *** CD-ROM | disk | FTP | other *** search
/ Chip 2005 March / CMCD0305.ISO / Software / Shareware / Utilitare / emu / Emu8086_Setup_307c.exe / {app} / Inc / emu8086.inc
Encoding:
Text File  |  2003-01-09  |  14.7 KB  |  613 lines

  1. ; Copyright (C) 2002 emu8086, Inc.
  2. ;    http://www.emu8086.com
  3. ;         info@emu8086.com
  4. ; All rights reserved.
  5.  
  6.  
  7. ; this macro prints a
  8. ; char in AL and advances
  9. ; the current cursor
  10. ; position:
  11. PUTC    MACRO   char
  12.         PUSH    AX
  13.         MOV     AL, char
  14.         MOV     AH, 0Eh
  15.         INT     10h     
  16.         POP     AX
  17. ENDM
  18.  
  19.  
  20. ; this macro prints a string that is
  21. ; given as a parameter, example:
  22. ; PRINT 'hello world!'
  23. ; (new line is NOT added).
  24. PRINT   MACRO   sdat
  25. LOCAL   next_char, s_dcl, printed, skip_dcl
  26.  
  27. PUSH    AX      ; store registers...
  28. PUSH    SI      ;
  29.  
  30. JMP     skip_dcl        ; skip declaration.
  31.         s_dcl DB sdat, 0
  32.  
  33. skip_dcl:
  34.         LEA     SI, s_dcl
  35.         
  36. next_char:      
  37.         MOV     AL, CS:[SI]
  38.         CMP     AL, 0
  39.         JZ      printed
  40.         INC     SI
  41.         MOV     AH, 0Eh ; teletype function.
  42.         INT     10h
  43.         JMP     next_char
  44. printed:
  45.  
  46. POP     SI      ; re-store registers...
  47. POP     AX      ;
  48. ENDM
  49.  
  50.  
  51. ; this macro prints a string that is
  52. ; given as a parameter, example:
  53. ; PRINTN 'hello world!'
  54. ; (the same as PRINT, but
  55. ; new line is automatically added).
  56. PRINTN   MACRO   sdat
  57. LOCAL   next_char, s_dcl, printed, skip_dcl
  58.  
  59. PUSH    AX      ; store registers...
  60. PUSH    SI      ;
  61.  
  62. JMP     skip_dcl        ; skip declaration.
  63.         s_dcl DB sdat, 13, 10, 0
  64.  
  65. skip_dcl:
  66.         LEA     SI, s_dcl
  67.         
  68. next_char:      
  69.         MOV     AL, CS:[SI]
  70.         CMP     AL, 0
  71.         JZ      printed
  72.         INC     SI
  73.         MOV     AH, 0Eh ; teletype function.
  74.         INT     10h
  75.         JMP     next_char
  76. printed:
  77.  
  78. POP     SI      ; re-store registers...
  79. POP     AX      ;
  80. ENDM
  81.  
  82.  
  83. ; turns off the cursor:
  84. CURSOROFF       MACRO
  85.         PUSH    AX
  86.         PUSH    CX
  87.         MOV     AH, 1
  88.         MOV     CH, 28h
  89.         MOV     CL, 09h
  90.         INT     10h
  91.         POP     CX
  92.         POP     AX
  93. ENDM
  94.  
  95.  
  96.  
  97. ; turns on the cursor:
  98. CURSORON        MACRO
  99.         PUSH    AX
  100.         PUSH    CX
  101.         MOV     AH, 1
  102.         MOV     CH, 08h
  103.         MOV     CL, 09h
  104.         INT     10h
  105.         POP     CX
  106.         POP     AX
  107. ENDM
  108.  
  109. ; sets current cursor
  110. ; position:
  111. GOTOXY  MACRO   col, row
  112.         PUSH    AX
  113.         PUSH    BX
  114.         PUSH    DX
  115.         MOV     AH, 02h
  116.         MOV     DH, row
  117.         MOV     DL, col
  118.         MOV     BH, 0
  119.         INT     10h
  120.         POP     DX
  121.         POP     BX
  122.         POP     AX
  123. ENDM
  124.  
  125.  
  126. ;***************************************************************
  127.  
  128. ; This macro defines a procedure that
  129. ; gets the multi-digit SIGNED number from the keyboard,
  130. ; and stores the result in CX register:
  131. DEFINE_SCAN_NUM         MACRO
  132. LOCAL make_minus, ten, next_digit, set_minus
  133. LOCAL too_big, backspace_checked, too_big2
  134. LOCAL stop_input, not_minus, skip_proc_scan_num
  135. LOCAL remove_not_digit, ok_AE_0, ok_digit, not_cr
  136.  
  137. ; protect from wrong definition location:
  138. JMP     skip_proc_scan_num
  139.  
  140. SCAN_NUM        PROC    NEAR
  141.         PUSH    DX
  142.         PUSH    AX
  143.         PUSH    SI
  144.         
  145.         MOV     CX, 0
  146.  
  147.         ; reset flag:
  148.         MOV     CS:make_minus, 0
  149.  
  150. next_digit:
  151.  
  152.         ; get char from keyboard
  153.         ; into AL:
  154.         MOV     AH, 00h
  155.         INT     16h
  156.         ; and print it:
  157.         MOV     AH, 0Eh
  158.         INT     10h
  159.  
  160.         ; check for MINUS:
  161.         CMP     AL, '-'
  162.         JE      set_minus
  163.  
  164.         ; check for ENTER key:
  165.         CMP     AL, 13  ; carriage return?
  166.         JNE     not_cr
  167.         JMP     stop_input
  168. not_cr:
  169.  
  170.  
  171.         CMP     AL, 8                   ; 'BACKSPACE' pressed?
  172.         JNE     backspace_checked
  173.         MOV     DX, 0                   ; remove last digit by
  174.         MOV     AX, CX                  ; division:
  175.         DIV     CS:ten                  ; AX = DX:AX / 10 (DX-rem).
  176.         MOV     CX, AX
  177.         PUTC    ' '                     ; clear position.
  178.         PUTC    8                       ; backspace again.
  179.         JMP     next_digit
  180. backspace_checked:
  181.  
  182.  
  183.         ; allow only digits:
  184.         CMP     AL, '0'
  185.         JAE     ok_AE_0
  186.         JMP     remove_not_digit
  187. ok_AE_0:        
  188.         CMP     AL, '9'
  189.         JBE     ok_digit
  190. remove_not_digit:       
  191.         PUTC    8       ; backspace.
  192.         PUTC    ' '     ; clear last entered not digit.
  193.         PUTC    8       ; backspace again.        
  194.         JMP     next_digit ; wait for next input.       
  195. ok_digit:
  196.  
  197.  
  198.         ; multiply CX by 10 (first time the result is zero)
  199.         PUSH    AX
  200.         MOV     AX, CX
  201.         MUL     CS:ten                  ; DX:AX = AX*10
  202.         MOV     CX, AX
  203.         POP     AX
  204.  
  205.         ; check if the number is too big
  206.         ; (result should be 16 bits)
  207.         CMP     DX, 0
  208.         JNE     too_big
  209.  
  210.         ; convert from ASCII code:
  211.         SUB     AL, 30h
  212.  
  213.         ; add AL to CX:
  214.         MOV     AH, 0
  215.         MOV     DX, CX      ; backup, in case the result will be too big.
  216.         ADD     CX, AX
  217.         JC      too_big2    ; jump if the number is too big.
  218.  
  219.         JMP     next_digit
  220.  
  221. set_minus:
  222.         MOV     CS:make_minus, 1
  223.         JMP     next_digit
  224.  
  225. too_big2:
  226.         MOV     CX, DX      ; restore the backuped value before add.
  227.         MOV     DX, 0       ; DX was zero before backup!
  228. too_big:
  229.         MOV     AX, CX
  230.         DIV     CS:ten  ; reverse last DX:AX = AX*10, make AX = DX:AX / 10
  231.         MOV     CX, AX
  232.         PUTC    8       ; backspace.
  233.         PUTC    ' '     ; clear last entered digit.
  234.         PUTC    8       ; backspace again.        
  235.         JMP     next_digit ; wait for Enter/Backspace.
  236.         
  237.         
  238. stop_input:
  239.         ; check flag:
  240.         CMP     CS:make_minus, 0
  241.         JE      not_minus
  242.         NEG     CX
  243. not_minus:
  244.  
  245.         POP     SI
  246.         POP     AX
  247.         POP     DX
  248.         RET
  249. make_minus      DB      ?       ; used as a flag.
  250. ten             DW      10      ; used as multiplier.
  251. SCAN_NUM        ENDP
  252.  
  253. skip_proc_scan_num:
  254.  
  255. DEFINE_SCAN_NUM         ENDM
  256. ;***************************************************************
  257.  
  258.  
  259. ;***************************************************************
  260. ; this macro defines a procedure to print a null terminated
  261. ; string at current cursor position,
  262. ; receives address of string in DS:SI
  263. ; register:
  264. DEFINE_PRINT_STRING     MACRO
  265. LOCAL   next_char, printed, skip_proc_print_string
  266.  
  267. ; protect from wrong definition location:
  268. JMP     skip_proc_print_string
  269.  
  270. PRINT_STRING PROC NEAR
  271. PUSH    AX      ; store registers...
  272. PUSH    SI      ;
  273.  
  274. next_char:      
  275.         MOV     AL, [SI]
  276.         CMP     AL, 0
  277.         JZ      printed
  278.         INC     SI
  279.         MOV     AH, 0Eh ; teletype function.
  280.         INT     10h
  281.         JMP     next_char
  282. printed:
  283.  
  284. POP     SI      ; re-store registers...
  285. POP     AX      ;
  286.  
  287. RET
  288. PRINT_STRING ENDP
  289.  
  290. skip_proc_print_string:
  291.  
  292. DEFINE_PRINT_STRING     ENDM
  293. ;***************************************************************
  294.  
  295.  
  296. ;***************************************************************
  297. ; This macro defines a procedure to print a null terminated
  298. ; string at current cursor position.
  299. ; The ZERO TERMINATED string should be defined just after
  300. ; the CALL. For example:
  301. ;
  302. ; CALL PTHIS
  303. ; db 'Hello World!', 0
  304. ;
  305. ; Address of string is stored in the Stack as return address.
  306. ; Procedure updates value in the Stack to make return
  307. ; after string definition.
  308. DEFINE_PTHIS     MACRO
  309. LOCAL   next_char, printed, skip_proc_pthis, temp1
  310.  
  311. ; protect from wrong definition location:
  312. JMP     skip_proc_pthis
  313.  
  314. PTHIS PROC NEAR
  315.  
  316. MOV     CS:temp1, SI  ; re-store SI register.
  317.  
  318. POP     SI            ; get return address (IP).
  319.  
  320. PUSH    AX            ; store AX register.
  321.  
  322. next_char:      
  323.         MOV     AL, CS:[SI]
  324.         INC     SI            ; next byte.
  325.         CMP     AL, 0
  326.         JZ      printed        
  327.         MOV     AH, 0Eh       ; teletype function.
  328.         INT     10h
  329.         JMP     next_char     ; loop.
  330. printed:
  331.  
  332. POP     AX            ; re-store AX register.
  333.  
  334. ; SI should point to next command after
  335. ; the CALL instruction and string definition:
  336. PUSH    SI            ; save new return address into the Stack.
  337.  
  338. MOV     SI, CS:temp1  ; re-store SI register.
  339.  
  340. RET
  341. temp1  DW  ?    ; variable to store original value of SI register.
  342. PTHIS ENDP
  343.  
  344. skip_proc_pthis:
  345.  
  346. DEFINE_PTHIS     ENDM
  347. ;***************************************************************
  348.  
  349.  
  350. ;***************************************************************
  351. ; This macro defines a procedure to get a null terminated
  352. ; string from user, the received string is written to buffer
  353. ; at DS:DI, buffer size should be in DX.
  354. ; Procedure stops the input when 'Enter' is pressed.
  355. DEFINE_GET_STRING       MACRO
  356. LOCAL   empty_buffer, wait_for_key, skip_proc_get_string
  357. LOCAL   exit, add_to_buffer
  358.  
  359. ; protect from wrong definition location:
  360. JMP     skip_proc_get_string
  361.  
  362. GET_STRING      PROC    NEAR
  363. PUSH    AX
  364. PUSH    CX
  365. PUSH    DI
  366. PUSH    DX
  367.  
  368. MOV     CX, 0                   ; char counter.
  369.  
  370. CMP     DX, 1                   ; buffer too small?
  371. JBE     empty_buffer            ;
  372.  
  373. DEC     DX                      ; reserve space for last zero.
  374.  
  375.  
  376. ;============================
  377. ; Eternal loop to get
  378. ; and processes key presses:
  379.  
  380. wait_for_key:
  381.  
  382. MOV     AH, 0                   ; get pressed key.
  383. INT     16h
  384.  
  385. CMP     AL, 13                  ; 'RETURN' pressed?
  386. JZ      exit
  387.  
  388.  
  389. CMP     AL, 8                   ; 'BACKSPACE' pressed?
  390. JNE     add_to_buffer
  391. JCXZ    wait_for_key            ; nothing to remove!
  392. DEC     CX
  393. DEC     DI
  394. PUTC    8                       ; backspace.
  395. PUTC    ' '                     ; clear position.
  396. PUTC    8                       ; backspace again.
  397. JMP     wait_for_key
  398.  
  399. add_to_buffer:
  400.  
  401.         CMP     CX, DX          ; buffer is full?
  402.         JAE     wait_for_key    ; if so wait for 'BACKSPACE' or 'RETURN'...
  403.  
  404.         MOV     [DI], AL
  405.         INC     DI
  406.         INC     CX
  407.         
  408.         ; print the key:
  409.         MOV     AH, 0Eh
  410.         INT     10h
  411.  
  412. JMP     wait_for_key
  413. ;============================
  414.  
  415. exit:
  416.  
  417. ; terminate by null:
  418. MOV     [DI], 0
  419.  
  420. empty_buffer:
  421.  
  422. POP     DX
  423. POP     DI
  424. POP     CX
  425. POP     AX
  426. RET
  427. GET_STRING      ENDP
  428.  
  429.  
  430. skip_proc_get_string:
  431.  
  432. DEFINE_GET_STRING       ENDM
  433. ;***************************************************************
  434.  
  435. ;***************************************************************
  436. ; this macro defines procedure to clear the screen,
  437. ; (done by scrolling entire screen window),
  438. ; and set cursor position to top of it:
  439. DEFINE_CLEAR_SCREEN     MACRO
  440. LOCAL skip_proc_clear_screen
  441.  
  442. ; protect from wrong definition location:
  443. JMP     skip_proc_clear_screen
  444.  
  445. CLEAR_SCREEN PROC NEAR
  446.         PUSH    AX      ; store registers...
  447.         PUSH    DS      ;
  448.         PUSH    BX      ;
  449.         PUSH    CX      ;
  450.         PUSH    DI      ;
  451.  
  452.         MOV     AX, 40h
  453.         MOV     DS, AX  ; for getting screen parameters.
  454.         MOV     AH, 06h ; scroll up function id.
  455.         MOV     AL, 0   ; scroll all lines!
  456.         MOV     BH, 07  ; attribute for new lines.
  457.         MOV     CH, 0   ; upper row.
  458.         MOV     CL, 0   ; upper col.
  459.         MOV     DI, 84h ; rows on screen -1,
  460.         MOV     DH, [DI] ; lower row (byte).
  461.         MOV     DI, 4Ah ; columns on screen,
  462.         MOV     DL, [DI]
  463.         DEC     DL      ; lower col.
  464.         INT     10h
  465.  
  466.         ; set cursor position to top
  467.         ; of the screen:
  468.         MOV     BH, 0   ; current page.
  469.         MOV     DL, 0   ; col.
  470.         MOV     DH, 0   ; row.
  471.         MOV     AH, 02
  472.         INT     10h
  473.  
  474.         POP     DI      ; re-store registers...
  475.         POP     CX      ;
  476.         POP     BX      ;
  477.         POP     DS      ;
  478.         POP     AX      ;
  479.  
  480.         RET
  481. CLEAR_SCREEN ENDP
  482.  
  483. skip_proc_clear_screen:
  484.  
  485. DEFINE_CLEAR_SCREEN     ENDM
  486. ;***************************************************************
  487.  
  488.  
  489. ;***************************************************************
  490.  
  491. ; This macro defines a procedure that prints number in AX,
  492. ; used with PRINT_NUM_UNS to print signed numbers:
  493. ; Requires DEFINE_PRINT_NUM_UNS !!!
  494. DEFINE_PRINT_NUM        MACRO
  495. LOCAL not_zero, positive, printed, skip_proc_print_num
  496.  
  497. ; protect from wrong definition location:
  498. JMP     skip_proc_print_num
  499.  
  500. PRINT_NUM       PROC    NEAR
  501.         PUSH    DX
  502.         PUSH    AX
  503.  
  504.         CMP     AX, 0
  505.         JNZ     not_zero
  506.  
  507.         PUTC    '0'
  508.         JMP     printed
  509.  
  510. not_zero:
  511.         ; the check SIGN of AX,
  512.         ; make absolute if it's negative:
  513.         CMP     AX, 0
  514.         JNS     positive
  515.         NEG     AX
  516.  
  517.         PUTC    '-'
  518.  
  519. positive:
  520.         CALL    PRINT_NUM_UNS
  521. printed:
  522.         POP     AX
  523.         POP     DX
  524.         RET
  525. PRINT_NUM       ENDP
  526.  
  527. skip_proc_print_num:
  528.  
  529. DEFINE_PRINT_NUM        ENDM
  530.  
  531. ;***************************************************************
  532.  
  533. ; This macro defines a procedure that prints out an unsigned
  534. ; number in AX (not just a single digit)
  535. ; allowed values from 0 to 65535 (0FFFFh)
  536. DEFINE_PRINT_NUM_UNS    MACRO
  537. LOCAL begin_print, calc, skip, print_zero, end_print, ten
  538. LOCAL skip_proc_print_num_uns
  539.  
  540. ; protect from wrong definition location:
  541. JMP     skip_proc_print_num_uns
  542.  
  543. PRINT_NUM_UNS   PROC    NEAR
  544.         PUSH    AX
  545.         PUSH    BX
  546.         PUSH    CX
  547.         PUSH    DX
  548.  
  549.         ; flag to prevent printing zeros before number:
  550.         MOV     CX, 1
  551.  
  552.         ; (result of "/ 10000" is always less or equal to 9).
  553.         MOV     BX, 10000       ; 2710h - divider.
  554.  
  555.         ; AX is zero?
  556.         CMP     AX, 0
  557.         JZ      print_zero
  558.  
  559. begin_print:
  560.  
  561.         ; check divider (if zero go to end_print):
  562.         CMP     BX,0
  563.         JZ      end_print
  564.  
  565.         ; avoid printing zeros before number:
  566.         CMP     CX, 0
  567.         JE      calc
  568.         ; if AX<BX then result of DIV will be zero:
  569.         CMP     AX, BX
  570.         JB      skip
  571. calc:
  572.         MOV     CX, 0   ; set flag.
  573.  
  574.         MOV     DX, 0
  575.         DIV     BX      ; AX = DX:AX / BX   (DX=remainder).
  576.  
  577.         ; print last digit
  578.         ; AH is always ZERO, so it's ignored
  579.         ADD     AL, 30h    ; convert to ASCII code.
  580.         PUTC    AL
  581.  
  582.  
  583.         MOV     AX, DX  ; get remainder from last div.
  584.  
  585. skip:
  586.         ; calculate BX=BX/10
  587.         PUSH    AX
  588.         MOV     DX, 0
  589.         MOV     AX, BX
  590.         DIV     CS:ten  ; AX = DX:AX / 10   (DX=remainder).
  591.         MOV     BX, AX
  592.         POP     AX
  593.  
  594.         JMP     begin_print
  595.         
  596. print_zero:
  597.         PUTC    '0'
  598.         
  599. end_print:
  600.  
  601.         POP     DX
  602.         POP     CX
  603.         POP     BX
  604.         POP     AX
  605.         RET
  606. ten             DW      10      ; used as divider.      
  607. PRINT_NUM_UNS   ENDP
  608.  
  609. skip_proc_print_num_uns:
  610.  
  611. DEFINE_PRINT_NUM_UNS    ENDM
  612. ;***************************************************************
  613.