home *** CD-ROM | disk | FTP | other *** search
/ RBBS in a Box Volume 1 #2 / RBBS_vol1_no2.iso / add2 / addram10.zip / ADDRAM.ASM next >
Assembly Source File  |  1989-02-14  |  15KB  |  404 lines

  1. ;   Copyright (c) 1989 by Marty Del Vecchio for personal use only.
  2. ;   May not be sold under any circumstances.  For questions call me
  3. ;   at (508) 820-1544, or the Channel 1 BBS at (617) 354-8873).
  4. ;
  5. ;   To create ADDRAM.COM, you must assemble this file:
  6. ;
  7. ;       MASM addram;
  8. ;
  9. ;   then link it to an executable:
  10. ;
  11. ;       LINK addram;
  12. ;
  13. ;   then turn it into a .COM file:
  14. ;
  15. ;       EXE2BIN addram.exe addram.com
  16. ;
  17. ;   then delete the .EXE file:
  18. ;
  19. ;       DEL addram.exe
  20. ;
  21.  
  22. get_vector      equ     35h
  23. emm_int         equ     67h
  24. EMM_name_length equ     8
  25.  
  26.  
  27. code_seg_a      segment
  28.                 assume  cs:code_seg_a, ds:code_seg_a
  29.  
  30.                 org     100h
  31.  
  32. addram          proc    far
  33.  
  34. start:          jmp     begin
  35.  
  36. copyrt          db      0Dh, 0Ah
  37.                 db      'ADDRAM 1.00  Copyright (C) 1989 by Marty Del Vecchio', 0Dh, 0Ah, 00h
  38. no_EMM_msg      db      'Expanded Memory Manager not found--no EMS installed.', 0Dh, 0Ah, 00h
  39. EMM_error_msg   db      'Expanded Memory Manager reports an error.', 0Dh, 0Ah, 00h
  40. bad_ver_msg     db      'This program requires version 4.0 expanded memory.', 0Dh, 0Ah, 00h
  41. need_640_msg    db      'This program requires exactly 640K of installed DOS memory.', 0Dh, 0Ah, 00h
  42. not_last_msg    db      'This program''s memory allocation block is not the last', 0Dh, 0Ah
  43.                 db      'in DOS''s chain.  Cannot change memory if not at end.', 0Dh, 0Ah, 00h
  44. no_A000_msg     db      'Expanded Memory Manager cannot map memory at segment A000.', 0Dh, 0Ah, 00h
  45. no_alloc_msg    db      'Not enough expanded memory available.', 0Dh, 0Ah, 00h
  46. no_map_msg      db      'Error while mapping expanded memory at A000.', 0Dh, 0Ah, 00h
  47. bad_name_msg    db      'Error assigning name to expanded memory handle.', 0Dh, 0Ah, 00h
  48. name_used_msg   db      'ADDRAM''s name already in use by another handle.', 0Dh, 0Ah, 00h
  49. added_msg       db      ' KB memory succesfully added to DOS.', 0Dh, 0Ah, 00h
  50. usage_msg       db      'Usage:  ADDRAM [/#]', 0Dh, 0Ah
  51.                 db      '        /# = add # 16KB pages to DOS (1-6 pages, 16-96KB)', 0Dh, 0Ah, 00h
  52.  
  53. EMM_name        db      'EMMXXXX0'
  54. handle_name     db      'ADDRAM00'      ; 8 characters, pad with 0
  55. handle          dw      0
  56.  
  57. mappable_buf    dd      64 dup (0)      ; Buffer for mappable address array
  58. mappable_count  dw      0               ; # of consec. mappable addresses
  59. pages_asked     db      6               ; Assume they want 96K for now
  60. pages_used      db      0
  61.  
  62. map_array       label   byte            ; 6 map entries for map function
  63.                 dw      00h, 0A000h
  64.                 dw      01h, 0A400h
  65.                 dw      02h, 0A800h
  66.                 dw      03h, 0AC00h
  67.                 dw      04h, 0B000h
  68.                 dw      05h, 0B400h
  69.  
  70. ;  Program entry point
  71.  
  72. begin:          call    say_hello       ; Print messages, check command line
  73.                 jc      error_exit
  74.  
  75.                 call    check_DOS       ; Can we add memory to DOS?
  76.                 jc      error_exit
  77.  
  78.                 call    check_EMM       ; Is EMM around and acceptable?
  79.                 jc      error_exit
  80.  
  81.                 call    check_A000      ; Are pages mappable and available?
  82.                 jc      error_exit
  83.  
  84.                 call    map_pages       ; Allocate memory and map at A000
  85.                 jc      error_exit
  86.  
  87.                 call    tell_DOS        ; Tell DOS about new memory
  88.                 jc      error_exit
  89.  
  90.                 call    tell_user       ; Tell user about new memory
  91.  
  92. success_exit:   mov     ax, 4C00h       ; Terminate, signal success
  93.                 int     21h
  94.  
  95. error_exit:     mov     ax, 4C01h       ; Terminate, signal failure
  96.                 int     21h
  97.  
  98. addram          endp
  99.  
  100.  
  101. say_hello       PROC    near
  102.                 mov     si, offset copyrt       ; Say hello first
  103.                 call    printf_si
  104.  
  105. check_params:   mov     byte ptr pages_asked, 6  ; Assume they want 6 pages
  106.                 mov     si, 81h
  107.                 call    skip_white      ; Skip white space
  108.                 cmp     al, 0Dh         ; All done?
  109.                 je      hello_exit      ; Yes, exit
  110.                 cmp     al, '/'         ; Specifying parameter?
  111.                 jne     usage           ; No, invalid command line
  112.  
  113. found_param:    lodsb                   ; Get character specified
  114.                 cmp     al, '1'         ; Is it 1?
  115.                 jb      usage           ; Below, error!
  116.                 cmp     al, '6'         ; Is it 6?
  117.                 ja      usage           ; Above, error!
  118.  
  119. found_num:      sub     al, '0'         ; Convert to number
  120.                 mov     byte ptr pages_asked, al ; Store as requested # of pages
  121.                 clc
  122.                 jmp     hello_exit
  123.  
  124. usage:          mov     si, offset usage_msg
  125.                 call    printf_si
  126.                 stc
  127.                 jmp     hello_exit
  128.  
  129. hello_exit:     ret
  130. say_hello       ENDP
  131.  
  132. skip_white      PROC    near
  133. next_ch:        lodsb                   ; Load next character
  134.                 cmp     al, 20h         ; Is it space?
  135.                 je      next_ch         ; Yes, get next
  136.                 cmp     al, 09h         ; Is it tab?
  137.                 je      next_ch         ; Yes, get next
  138.                 ret
  139. skip_white      ENDP
  140.  
  141. check_DOS       PROC    near
  142.                 mov     ax, ds:0002     ; Get end of mem allocation block (PSP)
  143.                 cmp     ax, 0A000h      ; Is it A000?
  144.                 jne     need_640        ; No, signal error
  145.  
  146. have_640:       push    ds
  147.                 mov     ax, cs          ; Point ds to our MCB
  148.                 dec     ax
  149.                 mov     ds, ax
  150.                 mov     al, ds:0000     ; 4Dh if not last, 5Ah if last
  151.                 pop     ds
  152.                 cmp     al, 5Ah         ; Is this the last block:
  153.                 jne     not_last        ; No, signal error
  154.  
  155. is_last:        clc                     ; Everything OK, signal
  156.                 jmp     DOS_exit        ; Get out
  157.  
  158. need_640:       mov     si, offset need_640_msg
  159.                 jmp     DOS_print
  160.  
  161. not_last:       mov     si, offset not_last_msg
  162.  
  163. DOS_print:      call    printf_si
  164.                 stc
  165.                 jmp     DOS_exit
  166. DOS_exit:       ret
  167. check_DOS       endp
  168.  
  169. check_EMM       PROC    near
  170.                 mov     ah, get_vector
  171.                 mov     al, emm_int
  172.                 int     21h
  173.                 mov     di, 0Ah
  174.                 lea     si, EMM_name
  175.                 mov     cx, EMM_name_length
  176.                 cld
  177.                 repe    cmpsb
  178.                 jne     not_installed
  179.  
  180. check_version:  mov     ah, 46h         ; Get EMM version #
  181.                 int     67h             ; Major number hi nibble of al
  182.                 or      ah, ah          ; Status OK?
  183.                 jnz     EMM_error       ; No, signal error.
  184.  
  185.                 mov     cl, 4
  186.                 shr     al, cl          ; al = major version number
  187.                 cmp     al, 4           ; Is it 4 or above?
  188.                 jb      bad_version     ; No, signal error
  189.  
  190. check_name:     mov     ax, 5401h       ; Check if handle name exists
  191.                 mov     si, offset handle_name
  192.                 int     67h
  193.                 or      ah, ah          ; Return 0?
  194.                 jz      name_used       ; No, some type of error
  195.  
  196. EMM_is_ok:      clc
  197.                 jmp     check_exit
  198.  
  199. not_installed:  mov     si, offset no_EMM_msg
  200.                 call    printf_si
  201.                 stc
  202.                 jmp     check_exit
  203.  
  204. EMM_error:      mov     si, offset EMM_error_msg
  205.                 jmp     EMM_print
  206.  
  207. bad_version:    mov     si, offset bad_ver_msg
  208.                 jmp     EMM_print
  209.  
  210. name_used:      mov     si, offset name_used_msg
  211. EMM_print:      call    printf_si
  212.                 stc
  213.  
  214. check_exit:     ret
  215. check_EMM       ENDP
  216.  
  217.  
  218. check_A000      PROC    near
  219.                 mov     ax, ds
  220.                 mov     es, ax
  221.                 mov     ax, 5800h       ; Get mappable physical address array
  222.                 mov     di, offset mappable_buf
  223.                 int     67h
  224.                 inc     cx              ; cx = # of entries + 1 now
  225.  
  226. find_A000:      mov     si, offset mappable_buf
  227.  
  228. next_entry:     dec     cx              ; One more looked at
  229.                 or      cx, cx          ; Are we finished?
  230.                 jz      no_A000         ; Yes, didn't find A000 in table
  231.  
  232.                 lodsw                   ; DS:SI into ax
  233.                 cmp     ax, 0A000h      ; Do we have A000?
  234.                 je      A000_ok         ; Yes, proceed
  235.                 inc     si
  236.                 inc     si              ; Point to next entry
  237.                 jmp     next_entry
  238.  
  239. A000_ok:        add     si, 2
  240.                 mov     bl, 01h         ; BL = number of mappables found
  241.  
  242.                 lodsw                   ; Get next segment address
  243.                 cmp     ax, 0A400h      ; Is it A400?
  244.                 jne     can_map         ; No, only one page mappable, OK
  245.                 add     si, 2
  246.                 inc     bl              ; Found two now
  247.                 cmp     bl, byte ptr pages_asked
  248.                 je      can_map         ; This is all they want, proceed
  249.  
  250.                 lodsw                   ; Get next segment address
  251.                 cmp     ax, 0A800h      ; Is it A800?
  252.                 jne     can_map         ; No, only two pages mappable, OK
  253.                 add     si, 2
  254.                 inc     bl              ; Found three now
  255.                 cmp     bl, byte ptr pages_asked
  256.                 je      can_map         ; This is all they want, proceed
  257.  
  258.                 lodsw                   ; Get next segment address
  259.                 cmp     ax, 0AC00h      ; Is it AC00?
  260.                 jne     can_map         ; No, only three pages mappable, OK
  261.                 add     si, 2
  262.                 inc     bl              ; Found four now
  263.                 cmp     bl, byte ptr pages_asked
  264.                 je      can_map         ; This is all they want, proceed
  265.  
  266.                 lodsw                   ; Get next segment address
  267.                 cmp     ax, 0B000h      ; Is it B000?
  268.                 jne     can_map         ; No, only four pages mappable, OK
  269.                 add     si, 2
  270.                 inc     bl              ; Found five now
  271.                 cmp     bl, byte ptr pages_asked
  272.                 je      can_map         ; This is all they want, proceed
  273.  
  274.                 lodsw                   ; Get next segment address
  275.                 cmp     ax, 0B400h      ; Is it B400?
  276.                 jne     can_map         ; No, only five pages mappable, OK
  277.                 add     si, 2
  278.                 inc     bl              ; Found six now
  279.  
  280. can_map:        mov     byte ptr pages_used, bl
  281.                 clc
  282.                 jmp     A000_exit
  283.  
  284. no_A000:        mov     si, offset no_A000_msg
  285.                 call    printf_si
  286.                 stc
  287.                 jmp     A000_exit
  288.  
  289.  
  290. A000_exit:      ret
  291. check_A000      ENDP
  292.  
  293. map_pages       PROC    near
  294.                 mov     ah, 43h         ; Function 43h--allocate pages
  295.                 xor     bh, bh
  296.                 mov     bl, byte ptr pages_used
  297.                 int     67h
  298.                 or      ah, ah                  ; EMM status OK?
  299.                 jnz     alloc_error             ; No, signal error
  300.                 mov     word ptr handle, dx     ; Yes, store handle
  301.  
  302. name_handle:    mov     si, offset handle_name  ; Give handle a name
  303.                 mov     ax, 5301h
  304.                 int     67h
  305.                 or      ah, ah                  ; Error naming?
  306.                 jnz     name_error              ; Yes
  307.  
  308. alloc_OK:       mov     ax, 5001h       ; Function 50h, map multiple pages
  309.                 xor     ch, ch
  310.                 mov     cl, byte ptr pages_used   ; CX=count of pages
  311.                 mov     si, offset map_array      ; DS:SI = map array
  312.                 int     67h                       ; Map memory
  313.                 or      ah, ah          ; Error mapping?
  314.                 jnz     map_error       ; Yes, signal error
  315.  
  316. map_OK:         clc                     ; Signal success
  317.                 jmp     map_exit        ; And exit
  318.  
  319. alloc_error:    mov     si, offset no_alloc_msg
  320.                 call    printf_si
  321.                 stc
  322.  
  323.                 jmp     map_exit
  324.  
  325. name_error:     mov     si, offset bad_name_msg
  326.                 jmp     map_print
  327.  
  328. map_error:      mov     si, offset no_map_msg
  329.  
  330. map_print:      call    printf_si
  331.                 mov     ah, 45h         ; Deallocate pages first
  332.                 mov     dx, word ptr handle
  333.                 int     67h
  334.                 stc
  335.  
  336. map_exit:       ret
  337. map_pages       ENDP
  338.  
  339. tell_DOS        PROC    near
  340.                 mov     ax, ds          ; es = ds, make sure
  341.                 mov     es, ax
  342.                 xor     ah, ah
  343.                 mov     al, byte ptr pages_used ; retrieve # of pages to add
  344.                 mov     cl, 0Ah
  345.                 shl     ax, cl          ; ax = paragraphs adding
  346.                 mov     dx, cs
  347.                 dec     dx
  348.                 mov     ds, dx          ; ds = our Memory Control Block
  349.                 add     word ptr ds:[0003], ax  ; MCB: paragraphs allocated
  350.                 add     word ptr es:[0002], ax  ; PSP: end of memory allocation
  351.                 mov     cl, 6
  352.                 shr     ax, cl          ; ax = KB adding now
  353.                 mov     dx, 40h
  354.                 mov     ds, dx          ; ds-> BIOS data area
  355.                 add     word ptr ds:[0013h], ax         ; Add to BIOS mem size
  356.                 mov     ax, cs
  357.                 mov     ds, ax          ; Restore ds
  358.  
  359.                 ret
  360. tell_DOS        ENDP
  361.  
  362. tell_user       PROC    near
  363.                 xor     ah, ah
  364.                 mov     al, byte ptr pages_used
  365.                 mov     cl, 4
  366.                 shl     al, cl          ; al = KB added
  367.                 mov     bl, 10
  368.                 div     bl              ; al = (al div 10), ah = remainder
  369.                 mov     bx, ax          ; Save in bx
  370.                 mov     ah, 06h         ; DOS function 6, character output
  371.                 mov     dl, bl
  372.                 add     dl, '0'
  373.                 int     21h             ; Print out tens digit
  374.                 mov     ah, 06h
  375.                 mov     dl, bh
  376.                 add     dl, '0'
  377.                 int     21h             ; Print out ones digit
  378.  
  379.                 mov     si, offset added_msg
  380.                 call    printf_si
  381.                 ret
  382. tell_user       ENDP
  383.  
  384.  
  385. printf_si       PROC    near
  386.                 mov     ah, 06h         ; DOS function 06h, console output
  387.  
  388. next_char:      lodsb                   ; Next char into al
  389.                 or      al, al          ; Is it zero?
  390.                 jz      printf_done     ; Yes, exit
  391.                 mov     dl, al          ; Put char into dl
  392.                 int     21h             ; Output character
  393.                 jmp     next_char       ; Loop to next character
  394.  
  395. printf_done:    ret
  396. printf_si       ENDP
  397.                 
  398. code_seg_a      ends
  399.  
  400.                 end     start
  401.  
  402.  
  403.  
  404.