* Exercise in Assembly Language: A memory meter.
* Same trouble as Screen program: eats a little ram at every
* WB startup, probably the WBenchMsg not being deallocated
* or something similarily intricate

_AbsExecBase equ 4

_LVOForbid       equ -$84
_LVOPermit       equ -$8a
_LVOReplyMsg     equ -$17a
_LVOOpenLibrary equ -$228
_LVOCloseLibrary equ -$19e
_LVODelay equ -$c6
_LVOAvailMem equ -$d8
_LVOText equ -$3c
_LVOMove equ -$f0
_LVOSetBPen equ -$15c
_LVOWaitPort equ -$180
_LVOGetMsg equ -$174
_LVODisplayBeep equ -$60
_LVOOpenWindow equ -$cc
_LVOCloseWindow equ -$48
_LVOSetWindowTitles equ -$114

SMART_REFRESH equ 0
WBENCHSCREEN  equ 1
CHIPMEM EQU 2
WINDOWDRAG equ 2
FASTMEM EQU 4
WINDOWDEPTH equ 4
WINDOWCLOSE equ 8
wd_RPort    equ $32
wd_UserPort equ $56
CLOSEWINDOW equ $200

pr_MsgPort       equ $5c
pr_CLI           equ $ac
ThisTask         equ $114

       movea.l _AbsExecBase,a6   test if WB or CLI
       movea.l ThisTask(a6),a0
       moveq   #0,d0
       tst.l   pr_CLI(a0)
       bne.s   isCLI

       lea     pr_MsgPort(a0),a0     for WB get WB Message
       jsr     _LVOWaitPort(a6)
       jsr     _LVOGetMsg(a6)

isCLI  move.l  d0,-(a7)

   lea      DosName(pc),a1
   clr.l    d0
   jsr      _LVOOpenLibrary(a6)
   move.l   d0,DosBase
   tst.l    d0                          ; Ought to make things secure.
   bne.s    1$         ; Got DosBase
   rts      ; Can't even get Dos library, let's get out of here!!!

1$ lea      IntuitionName(pc),a1
   clr.l    d0
   movea.l  _AbsExecBase,a6
   jsr      _LVOOpenLibrary(a6)
   move.l   d0,IntuiBase
   tst.l    d0                          ; Ought to make things secure.
   beq      error

   lea      GraphicsName(pc),a1
   clr.l    d0
   movea.l  _AbsExecBase,a6
   jsr      _LVOOpenLibrary(a6)
   move.l   d0,GraphicsBase
   tst.l    d0                          ; Ought to make things secure.
   beq      error

   movea.l  IntuiBase(pc),a6
   lea      MyNewWindow(pc),a0
   jsr      _LVOOpenWindow(a6)          ; Error checking
   tst.l    d0
   beq      error
   move.l   d0,MyWindow

* To Set Screen Title:
   move.l   d0,a0
   lea      WindowTitle(pc),a1
   lea      ScreenTitle(pc),a2
   movea.l  IntuiBase(pc),a6
   jsr      _LVOSetWindowTitles(a6)

DisplayMem:
* First, make sure there are spaces in the string, not old digits:
   move.l   #$20202020,d3       ; Four Spaces
   move.l   d3,ChipCount+6
   move.l   d3,ChipCount+10
   move.l   d3,FastCount+6
   move.l   d3,FastCount+10
   
* Now, get and display ram figures
   movea.l  _AbsExecBase,a6
   moveq    #FASTMEM,d1
   jsr      _LVOAvailMem(a6)    ; Gets Fast ram count
   move.l   d0,d4      ; Save result to test for ram low
   lea      FastCount+15(pc),a0
   jsr      Convert(pc)

   movea.l  _AbsExecBase,a6
   moveq    #CHIPMEM,d1
   jsr      _LVOAvailMem(a6)
   add.l    d0,d4
   cmpi.l   #$C000,d4   ; If ram is < 48k, we commit suicide
   ble       Suicide
   lea      ChipCount+15(pc),a0
   jsr      Convert(pc)

* Here, we've got the text strings. 

* Get a proper position to put text
   movea.l  GraphicsBase(pc),a6
   move.l   MyWindow(pc),a2
   move.l   wd_RPort(a2),a1
   moveq    #17,d1              ; Desired position
   moveq    #6,d0
   jsr      _LVOMove(a6)

* Put it:
   movea.l  GraphicsBase(pc),a6
   move.l   MyWindow(pc),a2
   move.l   wd_RPort(a2),a1
   lea      FastCount(pc),a0
   moveq    #15,d0              ; String Length
   jsr      _LVOText(a6)

* Do the same with chip text
   movea.l  GraphicsBase(pc),a6
   move.l   MyWindow(pc),a2
   move.l   wd_RPort(a2),a1
   moveq    #27,d1              : Where we want to write
   moveq    #6,d0
   jsr      _LVOMove(a6)

   movea.l  GraphicsBase(pc),a6
   move.l   MyWindow(pc),a2
   move.l   wd_RPort(a2),a1
   lea      ChipCount(pc),a0
   moveq    #15,d0              ; String Length
   jsr      _LVOText(a6)

   movea.l  DosBase(pc),a6
   moveq    #100,d1                     ; Wait 2 seconds
   jsr      _LVODelay(a6)

   move.l   MyWindow(pc),a0
   move.l   wd_UserPort(a0),a0          ;Get the IDCMP Port of the window
   movea.l  _AbsExecBase,a6
   jsr      _LVOGetMsg(a6)            ; Test for close gadget
   tst.l    d0                  ; Only Message we can get is CLOSEWINDOW
   beq      DisplayMem          ; If NULL ptr, loop back

* Getting Near the end.
exit:
   movea.l  IntuiBase(pc),a6
   movea.l  MyWindow(pc),a0
   jsr      _LVOCloseWindow(a6)

error:       ; OpenWindow or some OpenLibrary failed
   movea.l  _AbsExecBase,a6
   move.l   IntuiBase(pc),a1
   jsr      _LVOCloseLibrary(a6) ; This is not really needed

       move.l  (a7)+,d0
       beq.s   NoBenh
       jsr     _LVOForbid(a6)       reply to WB
       movea.l d0,a1
       jsr     _LVOReplyMsg(a6)
       jsr     _LVOPermit(a6)

NoBenh moveq   #0,d0
       rts


Suicide:      ; If ram is running low, we'll give ours up.
   lea   0,a0   ; To beep every screen. This is not a very
   movea.l   IntuiBase(pc),a6   ; polite thing to do, but low ram is a disaster
   jsr   _LVODisplayBeep(a6) 
   bra   exit   ; Now leave
   
Convert:
* Inputs: adress in a0, data i d0.
* Output: Numeric string in ASCII before the address, data spent.
   move.l   d0,d1       ; Divide long word by 10 may cause overflow.
   andi.l   #$FFFF0000,d1
   swap     d1

nextdigit:
   divu     #10,d1
   move.w   d1,d2       ; The very high part of the number
   ext.l    d2
   andi.l   #$FFFF0000,d1
   andi.l   #$0000FFFF,d0
   add.l    d1,d0
   divu     #10,d0
   swap     d0
   addi.b   #48,d0      ; low byte now contains ASCII digit
   move.b   d0,-(a0)    ; Move to string
   swap d0              ; Move remaining number back
   andi.l   #$0000FFFF,d0 ; Wipe out the digit.
   move.l   d2,d1       ; Put the high part where we need it
   add.l    d0,d2       ; This to test for the end: d2 is scratch, containing
   bne.s    nextdigit   ; data that have been copied to d1. We can then use it
                        ; to determine if we're done.

   rts                          ; All digits gone to the string.

* Data section

**************** Window data

MyWindow:
   dc.l 0

MyFlags       EQU SMART_REFRESH!WINDOWDEPTH!WINDOWDRAG!WINDOWCLOSE
MyNewWindow:  dc.w 0,30,132,30
              dc.b 1,2          ; Colours
              dc.l CLOSEWINDOW  ; IDCMP Flags
              dc.l MyFlags
              dc.l 0,0
              dc.l WindowTitle
              dc.l 0            ; Screen to be filled in later
              dc.l 0            ; Pointer to bitmap
              dc.w 0,0,0,0
              dc.w WBENCHSCREEN

WindowTitle:
   dc.b 'Memory:',0
ScreenTitle
   dc.b 'Assembly Language is fun!',0
IntuitionName:
   dc.b 'intuition.library',0
IntuiBase:
   dc.l 0
GraphicsName:
   dc.b 'graphics.library',0,0
GraphicsBase:
   dc.l 0
DosName:
   dc.b 'dos.library',0
DosBase:
   dc.l 0
ChipCount:
   dc.b 'Chip:          ',0
FastCount:
   dc.b 'Fast:          ',0
   end

