home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / PCACHSRC.ZIP / OBJECT.ASM < prev    next >
Assembly Source File  |  1991-05-08  |  7KB  |  215 lines

  1. ;exe format.  demonstrates OOP.  B.Kauler 1991
  2. ;Note that this listing is very cluttered with comments and suggestions.
  3. ;after basically digesting them you might like to erase them, to be
  4. ;able to more clearly see the overall program.
  5. ;
  6. ;...................................................
  7. stack1    SEGMENT  stack  'stack'
  8.     db    128  DUP(0)
  9. stack1    ENDS
  10. ;...................................................
  11. data    SEGMENT  'data'
  12. ;    ......
  13. ;The structure SHAPES contains "variables" and also
  14. ;pointers to methods -- but note that we cannot specify the
  15. ;the address of a method, as MASM will not accept a forward
  16. ;reference from within a STRUC. 
  17. ;(A solutiion is to put the STRUC definitions after the code is
  18. ; assembled, but that introduces other problems).
  19. ;The STRUC definition below is only used by Asm -- it is the
  20. ;instances that are actually assembled (BOX1, BOX2). When 
  21. ;defining the instances we can initialise the fields, including
  22. ;insertion of the procedure addresses for each method.
  23. ;(Note that in the case of dynamically allocated objects, the
  24. ; pointers would have to be inserted by code, and if they are
  25. ; far pointers then the structure would have to use DD).
  26. ;Note that TASM allows nested STRUCs and MASM doesn't.  The definition
  27. ;of BOX below shows the case for TASM, which is conceptually neater.
  28. ;the comment alongside shows what you would have to replace it with
  29. ;for MASM. Either way, there is a problem when you come to declare
  30. ;instances, as you cannot initialise the fields inherited from SHAPE
  31. ;(only the first field).  Whatever fields have been declared in BOX
  32. ;can be initialised (in this case there's just one; ROUNDED).
  33. ;hence the rather messy macro (that I've called "instance_box").
  34. ;Note also that TASM has an "ideal mode" in which structure field-
  35. ;labels are local to that structure, thus allowing other structures
  36. ;to have identical labels -- which is what we ideally want for OOP --
  37. ;but the NOW override no longer works -- perhaps someone can find a
  38. ;fix for this.  At the moment, structure field-labels are global.
  39.  
  40. SHAPES     STRUC
  41. REDRAW      DW  ?        ;dummy pointer. **see below
  42. VERT        DB  5
  43. HORIZ    DB  10
  44. SYZE        DW  ?        ;near pointer to SIZE_SHAPES **see below
  45. ROW        DB  0
  46. COL        DB  0
  47. PLACE    DW  ?        ;near pointer to PLACE_SHAPES **see below
  48. SHAPES    ENDS
  49.                     ;** the pointers would have to be Define
  50.                     ;Doubleword (DD) if program has multiple
  51.                     ;code segments.
  52.  
  53. ;    .......
  54. BOX  STRUC
  55.     SHAPES  <>    ;TASM only. MASM; replace with (SIZE SHAPES) DUP(?)
  56. ROUNDED  DB  0
  57. BOX  ENDS
  58. ;    .....
  59. ;macro to create instance of BOX, with data initialisations....
  60. ;(messy, due to limitations of Asm -- have to create an instance of BOX
  61. ; then overwrite part of it with an instance of SHAPES)
  62. MAKE_BOX    MACRO    ibox
  63. ibox        BOX    < ,0>    ;cant initialise SHAPE's inherited data here.
  64.         ORG    ibox        ;backtrack.
  65.         SHAPES    <REDRAW_BOX,,,SIZE_SHAPES,2,5,PLACE_SHAPES>
  66.         ORG    ibox+(SIZE BOX)    ;ret. location ptr to normal position.
  67.     ENDM
  68.  
  69. ;create instances of BOX....
  70.     MAKE_BOX    BOX1
  71.     MAKE_BOX    BOX2
  72.  
  73. ;    ......
  74. NOW    EQU  [bx]    ;es:[bx] required for multiple data segments. see below.
  75.             ;note: TASM treats "THIS" as reserved word, so use NOW.
  76. ;    .....
  77. data    ENDS
  78.  
  79. ;........................................................
  80. code    SEGMENT  'code'
  81.     ASSUME  cs:code
  82. ;    ......
  83. NOWIS    MACRO   instance_label
  84.     mov    bx,OFFSET instance_label
  85.  
  86. ;note:    For multiple data segments, ES:BX must be loaded, by replacing
  87. ;        the above code with the instruction below, however
  88. ;        instance_label is no longer the actual address loaded to ES:BX
  89. ;        but is the label of a memory location that contains the
  90. ;         far address.(instance_label DD far_address).
  91. ;        Extra steps are required to set up the program for this.
  92. ;    les    bx,instance_label
  93.  
  94.     ENDM
  95. ;    ......
  96. ;..........................................................
  97. main    PROC  FAR
  98.     mov    ax,data
  99.     mov    ds,ax
  100.     ASSUME  ds:data
  101. ;    .......
  102. ;    .....
  103.     NOWIS  BOX1
  104.     mov    dx,0105h        ;change row & col
  105.     call    NOW.PLACE        ;update ROW & COL of BOX1.
  106.     call    NOW.REDRAW    ;display the box.
  107.  
  108. ;note: at this point should only call those methods belonging to BOX1.
  109. ;      If you want to call CIRCLE1.REDRAW (for example), first execute
  110. ;      NOWIS CIRCLE1
  111.  
  112. ;note2:    procedure calls to execute only one or two instructions, is
  113. ;        very wasteful, and C++ optimises this situation by treating
  114. ;        some small methods like macros, expanding them in-line.
  115. ;        Thus, although it is not good OOP practice, you can do what
  116. ;        C++ does anyway -- instead of calling PLACE, just put the two
  117. ;        instructions straight in
  118. ;        -- or define the method as a macro. No, don't do it.
  119.  
  120. ;note3:    one thing you may have noticed in the Figure (textbook 
  121. ;        hierarchy diagram of the objects) is that I created variable
  122. ;        ROUNDED, attached to BOX, but I did not create a method for it.
  123. ;        I should have, as all data must only be changed by methods
  124. ;        attached to the same object.  However I left the Figure 
  125. ;        uncluttered as I haven't actually implemented any setting
  126. ;        of ROUNDED in this demo program.
  127.  
  128.     NOWIS    BOX2
  129.     mov    dx,1020h        ;row & col
  130.     call    NOW.PLACE
  131.     call    NOW.REDRAW    ;draws box2
  132.  
  133.     mov    ax,4C00h    ;back to DOS
  134.     int    21h
  135. main    ENDP
  136. ;...........................................................
  137. PLACE_SHAPES  PROC  NEAR
  138. ;the new row and column coordinates are
  139. ;passed to PLACE via DX.  DH=row (0-24)
  140. ;DL=column (0-79).
  141.     mov    NOW.ROW,dh
  142.     mov    NOW.COL,dl
  143.  
  144. ;note:    a method can call other methods, even methods belonging to
  145. ;        other objects.  The standard rule is always use NOWIS before
  146. ;        calling any object that is not the current one.
  147.  
  148.     ret
  149. PLACE_SHAPES  ENDP
  150. ;..........................................................
  151. REDRAW_BOX  PROC NEAR
  152. ;no parameters passed to this one.  It just
  153. ;uses ROW, COL, VERT, HORIZ
  154. ;& ROUNDED to redraw the box.
  155. ;note again that NOW override is used to
  156. ;access only the data at the currently pointed
  157. ;-to instance.
  158. ;    ......
  159. ;some code here to draw box on scrn....
  160.  
  161. ;note:    don't forget when writing code that BX (or ES:BX) is/are used
  162. ;        for the NOW override, which means that we have to save it/them
  163. ;         if we want to use it/them for anything else.
  164.  
  165.     mov     dh,NOW.ROW
  166.     mov    ch,0
  167.     mov    cl,NOW.VERT
  168.  
  169. vertloop:
  170.     mov     dl,NOW.COL
  171.     push    cx            ;save vert loop count
  172.     mov    ch,0
  173.     mov    cl,NOW.HORIZ    ;horiz loop count
  174.     push    bx            ;save NOW override
  175.  
  176. horizloop:
  177.     push    cx            ;save horiz loop count
  178.     mov    bh,0
  179.     mov    ah,2            ;set_cursor 
  180.     int    10h
  181.     mov    cx,1
  182.     mov    al,219        ;ibm block-character.
  183.     mov    bx,0003h        ;page, colour.
  184.     mov ah,0Ah        ;write_char
  185.     int    10h
  186.     pop    cx            ;restore horiz loop count
  187.     inc    dl            ;row no. for set_cursor
  188.     loop    horizloop        ;next horizontal char
  189.     
  190.     pop    bx            ;restore NOW override
  191.     pop    cx            ;restore vert loop count
  192.     inc    dh            ;col no. for set_cursor
  193.     loop    vertloop        ;next line
  194. ;    ......
  195.     ret
  196. REDRAW_BOX ENDP
  197. ;..........................................................
  198. SIZE_SHAPES  PROC  NEAR
  199. ;perhaps this could have some parameters
  200. ;passed to it, to update VERT & HORIZ,
  201. ;then return with a pass/fail in AX.
  202. ;    ......
  203. ;    .....
  204.     ret
  205. SIZE_SHAPES  ENDP
  206. ;.......................................................
  207.  
  208. code    ENDS
  209.     END    main
  210.  
  211. ;NOTE ON USING TURBO-DEBUGGER:
  212. ;    The debugger's Watch window is particularly nice for viewing
  213. ;    all the data for an object, since all you have to do is change
  214. ;    to the Watch window by pressing <F6> then type the name of the
  215. ;    instance you want to view, for example "BOX1".