home *** CD-ROM | disk | FTP | other *** search
/ Phoenix CD 2.0 / Phoenix_CD.cdr / 02a / njfrer.zip / NJFRERAM.ASM < prev    next >
Assembly Source File  |  1987-05-14  |  14KB  |  575 lines

  1.  
  2. ;
  3. ;   Nifty James' FREE RAM program
  4. ;   Version 2.00 of 14 May 1987
  5. ;
  6. ;   Copyright 1987 by Mike Blaszczak, all Rights Reserved.
  7. ;
  8. ;   Shareware  $7
  9.  
  10. ;   ASCII Characters
  11.  
  12. tab        equ    9
  13. lf        equ    10
  14. cr        equ    13
  15. space        equ    32
  16.  
  17. ;   IBM Specific Keyboard Scan-codes
  18.  
  19. AltDown        equ    56        ; ALT scancode
  20. AltUp        equ    56 + 80h
  21. RShiftDown    equ    54        ; right-shift scancode
  22. RShiftUp    equ    54 + 80h
  23.  
  24. ;   BIOS Interrupts
  25.  
  26. Timer        equ    008h        ; BIOS 18.2Hz function
  27. Keyboard    equ    009h        ; BIOS keypress call
  28. Video        equ    010h        ; BIOS video function
  29. DiskService    equ    013h        ; BIOS/XT BIOS disk service
  30. TickTock    equ    01Ch        ; the BIOS timer trap
  31. SnagDOS        equ    028h        ; a function to snag DOS by
  32. SigVec        equ    0D0h        ; vector to see if we're installed
  33. EMM        equ    067h        ; the E/EMS memory manager
  34.  
  35. ;   I/O Ports
  36.  
  37. NMIPort        equ    020h        ; the Interrupt controller port
  38. KeyPort        equ    060h        ; the keyboard's I/O port
  39.  
  40. ;   DOS Calls
  41.  
  42. SetVec        equ    025h        ; call to set an int vector
  43. KEEP        equ    031h        ; call to Terminate and Stay Res
  44. Critical    equ    034h        ; call to get the DOS critical flag
  45. GetVec        equ    035h        ; call to get an int vector
  46. Allocate    equ    048h        ; call to allocate memory
  47. Terminate    equ    04Ch        ; call to Terminate
  48.  
  49. ;   E/EMS Routines
  50.  
  51. E_Status    equ    042h        ; call to determine free/total mem
  52.  
  53.  
  54.  ;   Public declarations for SYMDEB
  55.  
  56. PUBLIC First, StackArea, StackTop, Signature, SaveAX, SaveSS, SaveSP
  57. PUBLIC ClockVec, ClockVecO, ClockVecS, Display, DisplayOff, DisplaySeg
  58. PUBLIC DisplayPort, CriticalFlag, CriticalFlagO, CriticalFlagS, OTT, OTTO
  59. PUBLIC OTTS, OKeyVec, OKeyVecO, OKeyVecS, OSnagger, OSnaggerO, OSnaggerS
  60. PUBLIC ODiskCall, ODiskCallO, ODiskCallS, WorkFlag, UpdateFlag, AltFlag
  61. PUBLIC ShiftFlag, Ticks, InDisk, InThere, HasEMem, DiskTrap, TCTrap, TCDone
  62. PUBLIC TimeTrap, NotTime, KeyTrap, TryUpAlt, TryDnShift, TryUpShift, TripOut
  63. PUBLIC DontGotNone, CheckEMode, TripOutOut, KeyOut, WorkTrap, WorkHard
  64. PUBLIC NoWork, DoWork, EMSMode, DosMode, Calculate, CalcLoop, StickIt
  65. PUBLIC Convert2, Convert3, IsMono, SynchLow, SynchHigh, PutUp, GetOut
  66. PUBLIC CalcArea, AnswerArea, UnitsArea, BytesLine, EEMSLine, OverResident
  67. PUBLIC Already, Exit, InstallMe, NoEMM, NotMono, ExitNow, Banner
  68. PUBLIC DInstalled, EInstalled, Failed
  69. PUBLIC EMSSig
  70.  
  71.  
  72. CSeg        segment    para public 'CODE'
  73.         assume    ds:CSeg,ss:CSeg,cs:CSeg
  74.  
  75.         org    100h
  76.  
  77. extrn   Show:near    ; from NJLIB
  78.  
  79. First:        jmp    OverResident
  80.         nop
  81. StackArea    dw    19 dup(0DEADh)    ; the stack for interrupts
  82. StackTop    dw    0DEADh
  83.  
  84. Signature    db    'NJ'        ; the signature
  85.  
  86. SaveAX        dw    0        ; save the AX here
  87. SaveSS        dw    0        ; save the SS and SP here
  88. SaveSP        dw    0
  89.  
  90.  
  91.  
  92. ClockVec    label    dword        ; the original clock tick vector
  93. ClockVecO    dw    0
  94. ClockVecS    dw    0
  95.  
  96. Display        label    dword        ; pointer to display storage
  97. DisplayOff    dw    62*2
  98. DisplaySeg    dw    0B800h        ; assume the color card
  99. DisplayPort    dw    03DAh        ; display status port address
  100.  
  101. CriticalFlag    label    dword        ; the DOS critical flag
  102. CriticalFlagO    dw    0
  103. CriticalFlagS    dw    0
  104.  
  105. OTT        label    dword        ; the original BIOS Timer Trap
  106. OTTO        dw    0
  107. OTTS        dw    0
  108.  
  109. OKeyVec        label    dword        ; the original keypress vector
  110. OKeyVecO    dw    0
  111. OKeyVecS    dw    0
  112.  
  113. OSnagger    label    dword        ; the original DOS int 28h
  114. OSnaggerO    dw    0
  115. OSnaggerS    dw    0
  116.  
  117. ODiskCall    label    dword        ; the disk services place
  118. ODiskCallO    dw    0
  119. ODiskCallS    dw    0
  120.  
  121. WorkFlag    dw    0        ; semaphore; 1 if we should display
  122.                     ;         2 if we are in EEMS mode
  123. UpdateFlag    dw    0        ; semaphore; 1 if we should update
  124.  
  125. AltFlag        db    0        ; set if ALT is pressed
  126. ShiftFlag    db    0        ; set if RShift is pressed
  127.  
  128. Ticks        db    0        ; tick count for timer
  129. InDisk        db    0        ; semaphore; 1 if in disk control
  130.  
  131. InThere        db    0        ; recursiveness flag
  132. HasEMem        db    0        ; set to 1 if E/EMS is present
  133.  
  134. ; ---------------------------------------------------------------------------
  135.  
  136. DiskTrap:    inc    CS:InDisk    ; set disk handler flag
  137.         pushf
  138.         call    CS:[ODiskCall]    ; call the disk handler
  139.         pushf
  140.         dec    CS:InDisk    ; reset disk handler flag
  141.         popf
  142.         iret            ; return!
  143.  
  144. ; ---------------------------------------------------------------------------
  145.  
  146. TCTrap:        pushf
  147.         call    CS:[OTT]    ; call the original
  148.         pushf
  149.         cli
  150.         cmp    CS:[WorkFlag],0
  151.         je    TCDone
  152.         push    es
  153.         push    bx        ; check the critical flag
  154.         les    bx,CS:[CriticalFlag]
  155.         cmp    byte ptr es:[bx],0
  156.         pop    bx
  157.         pop    es
  158.         jne    TCDone
  159.  
  160.         cmp    CS:[InDisk],0    ; and the disk service flag
  161.         jne    TCDone
  162.  
  163.         jmp    WorkHard
  164.  
  165. TCDone:        popf
  166.         iret
  167.  
  168. ; ---------------------------------------------------------------------------
  169.  
  170. TimeTrap:    pushf            ; save flags
  171.         push    ax
  172.  
  173.         inc    CS:Ticks    ; increment ticks count
  174.         mov    al,CS:Ticks    ; is it time?
  175.         cmp    al,18
  176.         jne    NotTime        ; no, not yet
  177.  
  178.         xor    ax,ax        ; yes, zero time count
  179.         mov    CS:Ticks,al
  180.         mov    CS:UpdateFlag,1 ; set update flag
  181.  
  182. NotTime:    pop    ax
  183.         popf
  184.         jmp    CS:[ClockVec]
  185.         
  186. ; ---------------------------------------------------------------------------
  187.  
  188. KeyTrap:    pushf
  189.         push    ax
  190.  
  191.         in    al,KeyPort    ; get key from keyboard
  192.         cmp    al,AltDown    ; was ALT pressed?
  193.         jne    TryUpAlt    ; no.  Maybe it was released?
  194.  
  195.         mov    CS:AltFlag,1    ; yeah!  It was pressed, set flag
  196.         jmp    short TripOut    ; and flow through
  197.  
  198. TryUpAlt:    cmp    al,AltUp    ; was ALT released?
  199.         jne    TryDnShift    ; no, maybe it was shift?
  200.  
  201.         mov    CS:AltFlag,0    ; yeah!  ALT was released
  202.         jmp    short TripOut    ; reset flag and go through
  203.  
  204. TryDnShift:    cmp    al,RShiftDown    ; okay.  Maybe RShifty was pressed?
  205.         jne    TryUpShift    ;  nah, maybe  it was released?
  206.  
  207.         mov    CS:ShiftFlag,1    ; yeah! it was pressed, so set flag
  208.         jmp    short TripOut    ;  and jump through
  209.  
  210. TryUpShift:    cmp    al,RShiftUp    ; well, maybe it was released?
  211.         jne    KeyOut        ;  no, guess not, just pass it thru
  212.  
  213.         mov    CS:ShiftFlag,0    ;  yeah, it was released!
  214.  
  215. TripOut:    mov    al,CS:AltFlag    ; so, is it both ALT and RSHIFT?
  216.         and    al,CS:ShiftFlag
  217.         je    KeyOut        ; no, just pass thru
  218.  
  219.         mov    ax,CS:WorkFlag    ; yes, it was!  update workflag
  220.         inc    ax
  221.         cmp    ax,3        ; is it now off?
  222.         jne    CheckEMode    ;  no...
  223. DontGotNone:    xor    ax,ax        ;  yes, set to zero
  224.         je    TripOutOut    ;   and leave
  225.  
  226. CheckEMode:    cmp    ax,2        ; is it now EMS mode?
  227.         jne    TripOutOut    ;  no, no need to check
  228.         cmp    CS:HasEMem,1    ;  yes.  do we have EMS?
  229.         jne    DontGotNone    ;  no, set to zero
  230.  
  231. TripOutOut:    mov    CS:WorkFlag,ax
  232.  
  233. KeyOut:        pop    ax
  234.         popf
  235.  
  236.         jmp    CS:[OKeyVec]        
  237.         
  238. ; ---------------------------------------------------------------------------
  239.  
  240.  
  241. WorkTrap:    pushf            ; simulate a INT
  242.         call    CS:[OSnagger]
  243.         pushf
  244.  
  245. WorkHard:    cmp    CS:[WorkFlag],0        ; are we activated?
  246.         je    NoWork            ;  no, don't do work
  247.  
  248.         cmp    CS:[UpdateFlag],0    ; is it time to update?
  249.         je    NoWork            ;  no, don't do work
  250.  
  251.         cmp    CS:[InThere],0        ; are we getting recursive?
  252.         jne    NoWork            ;  yes, don't do work
  253.  
  254.         call    DoWork
  255. NoWork:        popf
  256.         iret        
  257.  
  258.  
  259. DoWork:        cli            ; turn off interrupts!
  260.         cld            ; and set direction up!!!
  261.         mov    CS:SaveAX,ax    ; save the stack seg from call
  262.         mov    CS:SaveSP,sp
  263.         mov    CS:SaveSS,ss
  264.  
  265.         mov    ax,cs            ; point to our local
  266.         mov    ss,ax            ;  stack segment
  267.         mov    ax,offset StackTop
  268.         mov    sp,ax
  269.  
  270.         push    bx        ; save all the regs we use
  271.         push    cx
  272.         push    dx
  273.         push    si
  274.         push    di
  275.         push    ds
  276.         push    es
  277.  
  278.         mov    ax,cs
  279.         mov    ds,ax        ; establish data seg addressing
  280.         mov    es,ax
  281.  
  282.         inc    InThere        ; don't be recursive
  283.         mov    UpDateFlag,0    ;  and don't do the work twice!
  284.  
  285.         cli            ; reallow interrupts for now
  286.  
  287.         mov    cx,5        ; move 10 bytes of message
  288.         mov    di,offset UnitsArea    ; into the units area
  289.         cmp    WorkFlag,1
  290.         je    DOSMode
  291.  
  292. EMSMode:    mov    si,offset EEMSLine
  293.     repnz    movsw
  294.         mov    ah,E_Status    ; get the E/EMS status
  295.         int    EMM        ; from the EMM
  296.     ; BX contains EEMS pages free
  297.  
  298.         xor    ax,ax
  299.         xchg    ax,bx        ; make BX:AX = number of pages
  300.         mov    cx,14        ; mulitply by 2^14
  301.         jmp    short CalcLoop    ; to get number of bytes
  302.         
  303.  
  304. DosMode:    mov    si,offset BytesLine
  305.     repnz    movsw
  306.         mov    ah,Allocate    ; try to get a major amount of mem
  307.         mov    bx,0FFFFh
  308.         int    21h        ; to see how much is free
  309.  
  310. Calculate:    xor    ax,ax        ; zero the AX
  311.         xchg    ax,bx        ; now, AX = paragraphs and BX = 0
  312.         mov    cx,4        ; get # of bytes
  313. CalcLoop:    rcl    ax,1        ; multiply by two
  314.         rcl    bx,1        ; add in carry
  315.         loop    CalcLoop
  316.  
  317. StickIt:
  318.     ; now, BX:AX contains bytes of free memory
  319.  
  320.         mov    CalcArea,ax        ; store bytes
  321.         mov    CalcArea+2,bx
  322.  
  323.         mov    di,offset AnswerArea
  324.         mov    al,space
  325.         mov    cx,7
  326.     repnz    stosb
  327.  
  328.     ; now, convert the number of bytes into ASCII, and store at
  329.     ; AnswerArea
  330.  
  331.         mov    si,offset CalcArea
  332.         dec    di
  333.  
  334. Convert2:    push    si            ; save source pointer
  335.  
  336.         xor    bx,bx            ; done flag
  337.         mov    cx,2            ; 2 words in number
  338.         xor    dx,dx            ; previous remainder
  339.         add    si,2            ; point to high end
  340.  
  341. Convert3:    push    cx            ; save count
  342.         mov    ax,[si]            ; get 16-bit digit
  343.         mov    cx,10            ; divisor of 10
  344.         div    cx            ; divide
  345.         mov    [si],ax            ; put 16-bit digit back
  346.         or    bx,ax            ; check for zero
  347.         sub    si,2            ; point to next 16-bit digit
  348.         pop    cx            ; restore count
  349.         loop    Convert3        ; do more
  350.  
  351.         or    dl,'0'        ; make remainder into decimal digit
  352.         mov    [di],dl        ; store it
  353.         dec    di        ; and fix pointer
  354.  
  355.         pop    si        ; restore source pointer
  356.         cmp    bx,0        ; was that the end?
  357.         jnz    Convert2    ; no, do more!
  358.  
  359.         mov    ah,15
  360.         int    Video
  361.         mov    cx,0B000h
  362.         cmp    al,7
  363.         je    IsMono
  364.         mov    cx,0B800h
  365.         add    ch,bh        ; add the current page to it
  366.         
  367. IsMono:        mov    DisplaySeg,cx
  368.  
  369.         les    di,Display    ; stuff it into the display!
  370.         mov    si,offset AnswerArea
  371.         mov    ah,7        ; attribute
  372.         mov    cx,18        ; 17 characters in the message:
  373.                     ; "xxxxxxx Bytes Free"
  374.  
  375.         mov    dx,DisplayPort    ; get the status port number
  376.         and    dx,dx        ;  or is it mono?
  377.         je    PutUp        ;  yeah, skip synchro
  378.  
  379. SynchLow:                ; wait for the synch to go low
  380.         in    al,dx
  381.         test    al,8
  382.         jne    SynchLow
  383.  
  384. SynchHigh:                ; wait for start of overscan
  385.         in    al,dx
  386.         test    al,8
  387.         je    SynchHigh
  388.     
  389. PutUp:        lodsb            ; load a byte of the message
  390.         stosw            ; store a word into the display
  391.         loop    PutUp        ; do the rest
  392.  
  393. GetOut:        cli            ; disallow interrupts for crucial code
  394.         dec    InThere        ; clear work flag
  395.         pop    es
  396.         pop    ds        ; reset the registers
  397.         pop    di
  398.         pop    si
  399.         pop    dx
  400.         pop    cx
  401.         pop    bx
  402.  
  403.         mov    sp,CS:SaveSP        ; restore the original stack
  404.         mov    ss,CS:SaveSS
  405.         mov    ax,CS:SaveAX
  406.  
  407.         sti                ; re-allow ints and
  408.         ret            ; return to caller
  409.  
  410. CalcArea    dw    2 dup(0)
  411.  
  412. AnswerArea    db    8 dup (' ')
  413. UnitsArea    db    "Bytes Free"
  414.  
  415. BytesLine    db    "Bytes Free"    ; message for DOS Bytes
  416. EEMSLine    db    "E/EMS Free"    ; message for EEMS Bytes
  417.  
  418. ; ---------------------------------------------------------------------------
  419.  
  420. OverResident:    mov    dx,offset Banner    ; print the banner
  421.         mov    cx,BannerLen
  422.         call    Show
  423.  
  424.         mov    ah,GetVec        ; see if already present
  425.         mov    al,SigVec
  426.         int    21h
  427.  
  428.         mov    ax,ES:[BX]        ; see if the signature
  429.         cmp    ax,'JN'            ;  is there?
  430.         jne    InstallMe
  431.  
  432. Already:    mov    dx,offset Failed    ; already installed!
  433.         mov    cx,FailedLen
  434.         call    Show
  435.  
  436. Exit:        mov    ah,Terminate        ; terminate with ERRORLEVEL
  437.         mov    al,1
  438.         int    21h
  439.  
  440. InstallMe:    ; we should install ourselves.  First, check to see if
  441.         ; there is E/EMS present.
  442.  
  443.         mov    ah,GetVec        ; get EMM Vector
  444.         mov    al,EMM
  445.         int    21h
  446.         mov    di,000Ah    ; point to device_name within
  447.                     ;  the EMM driver
  448.         mov    si,offset EMSSig
  449.         mov    cx,8
  450.         cld
  451.     repe    cmpsb            ; compare the bytes
  452.         jne    NoEMM
  453.  
  454.         mov    HasEMem,1    ; set EMEM flag to one
  455.  
  456. NoEMM:
  457.         mov    ah,Critical        ; get the DOS critical flag
  458.         int    21h
  459.         mov    CriticalFlagO,bx
  460.         mov    CriticalFlagS,es
  461.  
  462.         mov    ah,GetVec        ; handle the tick-tock
  463.         mov    al,TickTock
  464.         int    21h
  465.         mov    OTTO,bx
  466.         mov    OTTS,es
  467.  
  468.         mov    ah,SetVec
  469.         mov    al,TickTock
  470.         mov    dx,offset TCTrap
  471.         int    21h
  472.  
  473.         mov    ah,GetVec
  474.         mov    al,DiskService
  475.         int    21h
  476.         mov    ODiskCallO,bx
  477.         mov    ODiskCallS,es
  478.     
  479.         mov    ah,GetVec
  480.         mov    al,SnagDOS        ; get originial INT 028h
  481.         int    21h
  482.         mov    OSnaggerO,bx
  483.         mov    OSnaggerS,es
  484.     
  485.         mov    ah,GetVec        ; get the current keyboard vec
  486.         mov    al,Keyboard
  487.         int    21h
  488.  
  489.         mov    OKeyVecO,bx
  490.         mov    OKeyVecS,es
  491.  
  492.         mov    ah,GetVec        ; get the clock-tick vec
  493.         mov    al,Timer
  494.         int    21h
  495.  
  496.         mov    ClockVecO,bx        ; store clock vector
  497.         mov    ax,es
  498.         mov    ClockVecS,ax
  499.  
  500.         mov    ah,15        ; call BIOS to get video mode
  501.         int    Video
  502.         cmp    al,7        ; is it mono?
  503.         jne    NotMono
  504.  
  505.         mov    ax,0B000h    ; yes, change it to mono
  506.         mov    DisplaySeg,ax    
  507.         mov    ax,0
  508.         mov    DisplayPort,ax
  509.  
  510. NotMono:    mov    ah,SetVec        ; set an int vector
  511.         mov    al,Timer        ;  the timer's
  512.         mov    dx,offset TimeTrap    ; to our routine
  513.         int    21h
  514.  
  515.         mov    ah,SetVec        ; get the keypress vector
  516.         mov    al,Keyboard
  517.         mov    dx,offset KeyTrap
  518.         int    21h
  519.  
  520.         mov    ah,SetVec        ; get the snag DOS vector
  521.         mov    al,SnagDOS
  522.         mov    dx,offset WorkTrap
  523.         int    21h
  524.  
  525.         mov    ah,SetVec        ; set the signature pointer
  526.         mov    al,SigVec
  527.         mov    dx,offset Signature
  528.         int    21h
  529.  
  530.         mov    dx,offset DInstalled
  531.         mov    cx,DInstalledLen
  532.  
  533.         mov    al,HasEMem
  534.         cmp    al,0
  535.         je    ExitNow
  536.  
  537.         mov    dx,offset EInstalled
  538.         mov    cx,EInstalledLen
  539.  
  540. ExitNow:
  541.         call    Show
  542.  
  543.         mov    ah,KEEP        ; terminate and stay resident
  544.         mov    al,0    
  545.         mov    dx,offset OverResident
  546.         add    dx,15
  547.         mov    cx,4
  548.         shr    dx,cl
  549.         int    21h
  550.  
  551. ; ---------------------------------------------------------------------------
  552.  
  553. Banner        db    cr,lf,"Nifty James' FREE RAM program",cr,lf
  554.         db    "Version 2.00 of 14 May 1987",cr,lf,lf,lf
  555. BannerLen    equ    this byte - Banner
  556.  
  557. DInstalled    db    "NJFRERAM is installed!",cr,lf
  558.         db    "Press <Alt>+<RightShift> to toggle the display",cr,lf,lf
  559. DInstalledLen    equ    this byte - DInstalled
  560.  
  561. EInstalled    db    "NJFRERAM is installed!",cr,lf
  562.         db    "EEMS Mode is active.",cr,lf
  563.         db    "Press <Alt>+<RightShift> to move from DOS, to E/EMS, to off",cr,lf
  564. EInstalledLen    equ    this byte - EInstalled
  565.  
  566. Failed        db    "NJFRERAM was already present!",cr,lf,lf
  567. FailedLen    equ    this byte - Failed
  568.  
  569. EMSSig        db    "EMMXXXX0"
  570.  
  571. CSeg        ends
  572.         end    First
  573.  
  574.