Tuesday, November 10, 2009

Why Is SCM Important?










 < Free Open Study > 





Why Is SCM Important?



Software project managers pay attention to the planning and execution of configuration management, an integral task, because it facilitates the ability to communicate status of documents and code as well as changes that have been made to them. High-quality released software has been tested and used, making it a reusable asset and saving development costs. Reused components aren't free, though�they require integration into new products, a difficult task without knowing exactly what they are and where they are.



CM enhances the ability to provide maintenance support necessary once the software is deployed. If software didn't change, maintenance wouldn't exist. Of course, changes do occur. The National Institute of Standards and Technology (NIST) says that software will be changed to adapt, perfect, or correct it. Pressman points out that new business, new customer needs, reorganizations, and budgetary or scheduling constraints may lead to software revision.



CM works for the project and the organization in other ways as well. It helps to eliminate confusion, chaos, double maintenance, the shared data problem, and the simultaneous update problem, to name but a few issues to be discussed in this chapter.












     < Free Open Study > 



    Workshop



    [ Team LiB ]





    Workshop


    The Workshop is designed to help you review what you have learned and to help you further increase your understanding of the material covered in this hour.


    Quiz


    1:

    What are the two tag forms an XML element may take?

    2:

    How do you tell the browser you are sending it XML?

    3:

    How can you convert XML into HTML?



    Answers

    A1:

    An XML element may be represented as an opening/closing tag pair like <page></page> or by a single tag like <page/>.

    A2:

    Use the response.setContentType method and set the content type to text/xml.

    A3:

    Create an XSLT stylesheet to convert the various elements in the XML document into the desired HTML equivalents.



    Activities


    1. Create a simple XSLT stylesheet that converts XML into a simple HTML document. Use a JSTL transform action to display the HTML.

    2. Amazon has a Web Services Program available at http://www.amazon.com/webservices. Through this program, you can search Amazon and receive an XML response. Create a JSP that displays the results of an Amazon XML search using the JSTL XML tags.





      [ Team LiB ]



      Guide to the Reader











       < Day Day Up > 














      Guide to the Reader



      This book is constructed so that you can read it from cover to cover. If you know what you want to achieve, however, you may want to choose your own route through the book. In this case, the following hints can help you decide which topics to focus on and the order in which to read them:







      • To see how individual patterns can be used in practice and how they work together, start with the problem and solution sections of the patterns, then continue with the case studies in Chapters 6 and 7.







      • To get a feeling for the broad applicability of the pattern language, look for the abstracts and known uses of each pattern in Chapters 2 to 4.







      • To see how the resource management pattern language fits into existing patterns work, especially those that touch on the area of resource management, refer to Section 1.5, Related Work.







      We summarize the pattern language inside the front and back covers. Inside the front cover, we present a quick overview of the pattern language by listing the abstracts of all patterns. Inside the back cover, we present a pattern map illustrating the relationships between the patterns.


















       < Day Day Up > 



      gloss_I














      I



      IBM 3270

      The ubiquitous mainframe terminals and their controllers belong to the 3270 family. Common terminal models are the 3278, which supports color text, and the 3279, which supports graphics. Other members include the modern 3290 and 3187 terminals and the 3287 printer. The 3270 devices operate in block mode, where an entire page of text is transmitted at once, rather than character-by-character as keyed by the user. From the SNA perspective, these are LU2 devices. IBM 3270 terminals are emulated in the TCP/IP environment with the TN3270 service, which is an extension of telnet that is designed to handle ASCII-EBCDIC translation, keyboard mapping, and block-mode operation. See EBCDIC, IBM 5250, LU.




      IBM 5250

      IBM's LU7 terminals for midrange systems, such as the AS/400, constitute the 5250 family. Like IBM 3270 terminals, these are EBCDIC devices, which transmit information a page at a time. In the TCP/IP environment, the 5250 is emulated by the TN5250 service. See EBCDIC, IBM 3270, LU.




      IEEE 802

      The main IEEE standard for local area networking (LAN) and metropolitan area networking (MAN), including an overview of networking architecture, approved in 1990. According to the IEEE, the numbering for IEEE's 802-series LAN standards follows a unique pattern. If the number is followed by a capital letter, the designation refers to a stand-alone standard. If it is followed by a lower-case letter, it is a supplement to a standard or part of a multiple-number standard.




      IEEE 802.1B

      Standard for LAN/WAN management, approved in 1992 and, along with 802.1k, became the basis of ISO/IEC 15802-2.




      IEEE 802.1D

      Standard for interconnecting LANs using MAC bridges. Approved in 1990, it became the basis of ISO/IEC 10038.




      IEEE 802.1E

      Standard for LAN and MAN system load protocols. Approved in 1990, it became the basis of ISO/IEC 15802-4.




      IEEE 802.1F

      The standard for defining management information specified in 802, approved in 1993.




      IEEE 802.1g

      A proposed standard for remote MAC bridging.




      IEEE 802.1H

      Recommended practices for MAC bridging of Ethernet 2.0 LANs, approved in 1995.




      IEEE 802.1i

      Standard for using Fiber Distributed Data Interface (FDDI) as a MAC bridge. The standard was approved in 1992 and included in ISO/IEC 10038.




      IEEE 802.1j

      A supplement to 802.1D, this standard covers LAN connectivity using MAC bridges. It was approved in 1996.




      IEEE 802.1k

      Standard for LAN and MAN networks' discovery and dynamic control of event forwarding. It was approved in 1993 and, along with 802.1B, became the basis of ISO/IEC 15802-2.




      IEEE 802.1m

      Conformance statement for 802.1E. It covers the managed-object definitions and protocols for system load protocol. It was approved in 1993 and incorporated into ISO/IEC 15802-4.




      IEEE 802.1p

      Proposed standard for LANs and MANs that deals with expediting traffic and multicast filtering using MAC bridges.




      IEEE 802.1Q

      Proposed standard for virtual bridged LANs.




      IEEE 802.2

      Standard for logical link control in LAN and MAN connectivity, mainly using bridges. It is the basis of ISO/IEC 8802-2. The current version, approved in 1994, replaced an earlier 802.2 standard that was approved in 1989.




      IEEE 802.3

      Standard for LAN-based Carrier Sense Multiple Access with Collision Detection (CSMA/CD) access methods and Physical layers, as well as the basis of ISO/IEC 8802-3. This is sometimes referred to as the "Ethernet standard." It was revised in 1996.




      IEEE 802.3b

      Standard for broadband media attachment unit and specifications for 10Broad36. It was approved in 1985 and incorporated into ISO/IEC 8802-3.




      IEEE 802.3c

      Standard for 10Mbit/sec baseband network repeaters. It was approved in 1985 and incorporated into ISO/IEC 8802-3.




      IEEE 802.3d

      Standard for media attachment units and baseband media specifications over fiber-optic repeater links. It was approved in 1987 and incorporated into ISO/IEC 8802-3.




      IEEE 802.3e

      Standard for Physical signaling, media attachment, and baseband media specifications for a 1Mbit/sec network—that is, 1Base5. It was approved in 1987 and incorporated into ISO/IEC 8802-3.




      IEEE 802.3h

      Standard for layer management in Carrier Sense Multiple Access with Collision Detection (CSMA/CD) networks. It was approved in 1990 and incorporated into ISO/IEC 8802-3.




      IEEE 802.3i

      Standard covering two areas: multisegment 10Mbit/sec baseband networks and twisted-pair media for 10BaseT networks. It was approved in 1990 and incorporated into ISO/IEC 8802-3.




      IEEE 802.3j

      Standard for 10Mbit/sec active and passive star-based segments using fiber optics—that is, 10BaseF. It was approved in 1993 and incorporated into ISO/IEC 8802-3.




      IEEE 802.3k

      Standard for layer management for 10Mbit/sec baseband repeaters. Approved in 1992, it was incorporated into ISO/IEC 8802-3.




      IEEE 802.3l

      Conformance statement for the 10BaseT media attachment unit protocol. It was approved in 1992 and incorporated into ISO/IEC 8802-3.




      IEEE 802.3p

      Standard for the 10Mbit/sec baseband media attachment units' layer management. It was approved in 1993 and incorporated into ISO/IEC 8802-3.




      IEEE 802.3q

      Guidelines for the development of managed objects. It was approved in 1993 and incorporated into ISO/IEC 8802-3.




      IEEE 802.3r

      The standard for the Carrier Sense Multiple Access with Collision Detection (CSMA/CD) access method and Physical layer specifications using 10Base5. It was updated in 1996.




      IEEE 802.3t

      Standard for supporting 120-ohm cables in 10BaseT simplex link segments. It was approved in 1995 and incorporated into ISO/IEC 8802-3.




      IEEE 802.3u

      Supplement to 802.3 covering MAC parameters, the Physical layer, and repeaters for 100Mbit/sec operation—that is, 100BaseT, generally known as Fast Ethernet. It was approved in 1995.




      IEEE 802.3v

      Standard for supporting 150-ohm cables in 10BaseT link segments. It was approved in 1995 and incorporated into ISO/IEC 8802-3.




      IEEE 802.3w

      Proposed standard for enhanced MAC algorithms.




      IEEE 802.3x

      Proposed standard for 802.3 full-duplex operation.




      IEEE 802.3y

      Proposed Physical-layer specification for 100Mbit/sec operation on two pairs of Category 3 or better balanced twisted-pair cable—that is, 100BaseT2.




      IEEE 802.3z

      Proposed standard for Physical-layer, repeater, and management parameters for 1,000Mbit/sec operation; often referred to as "Gigabit Ethernet."




      IEEE 802.4

      Standard for token-passing bus access methods and Physical-layer specifications. It was approved in 1990.




      IEEE 802.5

      Standard for token-ring access methods and Physical-layer specifications—that is, common Token Ring architecture. It became the basis of ISO/IEC 8802-5. The current version was approved in 1995.




      IEEE 802.6

      The family of standards for a LAN's Distributed-Queue Dual-Bus (DQDB) subnetwork. It was approved in 1990.




      IEEE 802.9

      Standard for Integrated Services LAN (ISLAN), designed to connect 802.x LANs to publicly and privately administered backbone networks such as FDDI or ISDN. It was approved in 1994 and is the basis of ISO/IEC 8802-9.




      IEEE 802.10

      Standard for Interoperable LAN Security, also known as SILS. It was approved in 1992.




      IEEE 802.11

      Standard for wireless LAN MAC and Physical-layer specifications. Current drafts focus on the 2.4GHz band.




      IEEE 802.12

      Standard for 100Mbit/sec demand-priority access method Physical-layer and repeater specifications, also known as 100VG-AnyLAN. It was approved in 1995.




      IEEE

      Institute for Electrical and Electronics Engineers; for information, browse www.ieee.org . Many IEEE-approved networking standards became the basis of the international networking standards specified by the International Organization for Standardization (ISO) and the International Electrotechnical Commission (IEC). See ISO/IEC.




      impedance.

      Impedance is the resistance equivalent for AC, and it affects a network's propagation delay and attenuation. Each protocol and topology has its own impedance standards. For example, 10BaseT UTP cable has an impedance of 100 ohms to 105 ohms, while 10Base2 coaxial cable has an impedance of 50 ohms.




      IND$FILE

      This program runs on mainframes to support file transfers between the mainframe and LU2 terminal devices, such as 3270 terminals or PCs running TN3270. IND$FILE is analogous to ftp under TCP/IP. TN3270 and TN5250 emulators often use IND$FILE to transfer files between PCs and mainframe and midrange computers. See IBM 3270.




      infrared.

      Infrared electromagnetic waves have frequencies higher than microwaves but lower than the visible spectrum. Infrared transmission is used for wireless LANs, as well as for point-to-point communications with portable devices.

      Infrared may also be used as a wireless medium, and has greatest applicability for mobile applications due to its low cost. Infrared allows for higher throughput—measured in megabits per second—than spread spectrum, but it offers more limited distances. Infrared beams cannot pass through walls.




      Institute of Electronics and Electrical Engineers (IEEE).

      The IEEE is a professional society of electrical engineers. One of its functions is to coordinate, develop, and publish data communications standards for use in the United States. See IEEE.




      Integrated Services Digital Network (ISDN).

      ISDN is the ITU standard for carrying voice and data to the same destination. Although ISDN has not been popular in the United States, it is commonly available in Europe (especially in the U.K., Germany, and France) and in Japan.




      intermediate system.

      In OSI terminology, an intermediate system is a router.




      Intermediate System-to-Intermediate System (IS-IS).

      IS-IS is an OSI routing protocol that provides dynamic routing between routers or intermediate systems.




      International Organization for Standardization (ISO).

      ISO is a multinational standards-setting organization that formulates computer and communication standards, among others. ISO defined the OSI reference model, which divides computer communications into seven layers: Physical, Data-link, Network, Transport, Session, Presentation, and Application.




      Internet Activities Board (IAB).

      The IAB is the coordinating committee for the design, engineering, and management of the Internet. The IAB has two main committees: the Internet Engineering Task Force (IETF) and the Internet Research Task Force (IRTF). The IETF specifies protocols and recommends Internet standards. The IRTF researches technologies and refers them to the IETF.




      Internet Protocol (IP).

      IP is part of the TCP/IP suite. It is a network-layer protocol that governs packet forwarding from network to network.




      Internet.

      The Internet is a collection of packet-switched networks all linked using the TCP/IP protocol.




      Internetwork Packet Exchange (IPX).

      IPX is the part of Novell's NetWare stack that governs packet forwarding. This network protocol is based on the Xerox Network System (XNS).




      internetwork.

      An internetwork is a collection of several networks that are connected by bridges, switches, or routers, so all users and devices can communicate, regardless of the network segment to which they are attached.




      interoperability.

      Interoperability is the ability of one manufacturer's computer equipment to operate alongside, communicate with, and exchange information with another vendor's dissimilar computer equipment or software.




      inverted backbone.

      An inverted backbone is a network architecture in which the wiring hub and routers become the center of the network, and all subnetworks connect to this hub. In a backbone network, the cable is the main venue of the network, to which many bridges and routers attach.




      ISO/IEC 10038

      Standard for interconnecting LANs using MAC bridges. Based on IEEE 802.1D and incorporating 802.1i and 802.1m, it was approved in 1993.




      ISO/IEC 11802-4

      Technical report, not a standard, based on IEEE 802.5j. It covers Token Ring access methods using fiber optic stations. The report was issued in June 1994.




      ISO/IEC 15802-2

      Common specifications for LAN and MAN management. Based on IEEE 802.1B and 802.1k, it was approved in 1995.




      ISO/IEC 15802-4

      Standard for LAN and MAN system load protocols. Based on IEEE 802.1E and incorporating 802.1m, it was approved in 1994.




      ISO/IEC 8802-2

      Standard for logical link control in LAN and MAN connectivity, mainly using bridges. This is based on IEEE 802.2 (1994 edition) and incorporates 802.2a, 802.2b, 802.2d, 802.2e, and 802.5p. This standard replaced the 1989 versions of both standards and was approved in 1994.




      ISO/IEC 8802-3

      Standard for LAN CSMA/CD access methods and Physical layers. It is based on IEEE 802.3 and incorporates 802.3b, 802.3c, 802.3d, 802.3e, 802.3h, 802.3i, 802.3j, 802.3k, 802.3l, 802.3m, 802.3n, 802.3p, 802.3q, 802.3s, 802.3t, and 802.3v. Approved in 1996, it replaced the 1993 version of the standard.




      ISO/IEC 8802-5

      Standard for Token Ring access methods and Physical-layer specifications—that is, common Token Ring architecture. It is based on IEEE 802.5, incorporating 802.5b, and was approved in 1995, replacing a 1992 version.




      ISO/IEC 8802-9

      Standard for LAN interfaces at the MAC and Physical layers. Based on IEEE 802.9, it was approved in 1996.




      ISO/IEC

      ISO is the International Organization for Standardization ( www.iso.ch ). IEC is the International Electrotechnical Commission (www.iec.ch). The organizations have a joint committee, called JTC1, which has created international networking standards largely based on IEEE's approved standards.




      isochronous transmission.

      An isochronous service transmits asynchronous data over a synchronous data link. An isochronous service must be able to deliver bandwidth at specific, regular intervals. It is required when time-dependent data, such as video or voice, is to be transmitted. For example, Asynchronous Transfer Mode can provide isochronous service.
















      Leadership-Collaboration Management











       < Day Day Up > 





      Leadership-Collaboration Management



      Most projects are overmanaged and underled. Admiral Grace Hopper once said, "You cannot manage men into battle: You manage things ... you lead people." What is the difference between project management and project leadership? Although there is an elusive line between them, the core difference is that management deals with complexity, while leadership deals with change. Without adequate management, complex projects rapidly descend into chaos. Plans, controls, budgets, and processes help project managers stave off potential project-threatening complexity. However, when uncertainty, risk, and change are prominent, these practices are insufficient.



      Project managers should be both managers and leaders, with the importance of the latter escalating rapidly as the exploratory nature of projects increases.[1] Good leadership contributes significantly to project success. As authors Carl Larson and Frank LaFasto (1989) point out, "Our research strongly indicates that the right person in a leadership role can add tremendous value to any collective effort."

      [1] The terms "project manager" and "team leader" are commonly used. I will use these terms also, but I will emphasize the leadership characteristics of the project manager's role.



      Leaders are leaders not because of what they do, but because of who they are. Authoritarian managers use power, often in the form of fear, to get people to do something their way. Leaders depend for the most part on influence rather than power, and influence derives from respect rather than fear. Respect, in turn, is based on qualities such as integrity, ability, fairness, truthfulness�in short, on character. Leaders are part of the project team, and although they are given organizational authority, their real authority isn't delegated top down but earned bottom up. From the outside a managed team and a led team can look the same, but from the inside they feel very different.



      Project managers who are effective at delivering in complex situations�planning in detail, creating organizational positions and roles, monitoring through detailed budget and progress reports, and solving the myriad day-to-day project problems�don't like change. Change leads to paradox and ambiguity, and these managers spend enormous energy trying to drive ambiguity and change out of their projects.



      Leaders, as opposed to managers, encourage change�by creating a vision of future possibilities (which are usually short on details), by interacting with a large network of people to discover new information that will help turn the product vision into reality, and by creating a sense of purpose in the endeavor that will motivate people to work on something outside the norm.



      Projects, like organizations, need both leaders and managers. Unfortunately, it is often difficult to find both skill sets in the same person. And since creating a project budget is more tangible than, say, resolving the ambiguity that arises when trying to satisfy conflicting customer groups, project management training tends to focus on tangible practices and tools. Growing leadership skills in managers is clearly possible, but it requires a dedication to understanding the differences between the two roles.



      As authors Phillip Hodgson and Randall White (2001) observe, "Leadership is what crosses the frontier between what we did yesterday and what we'll do tomorrow. We'll argue … that the real mark of a leader is confidence with uncertainty�the ability to admit to it and deal with it." The authors pose six questions that illustrate the damaging illusions of our 20th-century approaches to management:



      • Why do you believe you are in control?

      • Why do you behave as if you can predict the future, its consequences and outcomes?

      • Why do you think that because you've done it before and it worked that it will work again?

      • Why do you believe everything important is measurable?

      • Why do you think that words like leadership, management, and change have the same meaning for everyone?

      • Why do you think that reducing uncertainty will necessarily increase certainty? (Hodgson and White 2001)



      Agile project managers help their team balance at the edge of chaos�some structure, but not too much; adequate documentation, but not too much; some up-front architecture work, but not too much. Finding these balance points is the "art" of management. While books like this can help readers understand the issues and identify practices that help, only experience can refine a manager's art. High exploration-factor projects are full of anxiety, change, ambiguity, and uncertainty that the project team must deal with. It takes a different style of project management, a different pattern of project team operation, and a different type of project manager. I've labeled this type of management leadership-collaboration.



      A leadership-collaboration management style creates a certain kind of social architecture, one that enables organizations and teams to face the volatility of their environment. Such a social architecture blends performance and passion, results and egalitarianism. As I've written elsewhere, "Commanders know the objective; leaders grasp the direction. Commanders dictate; leaders influence. Controllers demand; collaborators facilitate. Controllers micro-manage; collaborators encourage. Managers who embrace the leadership-collaboration model understand their primary role is to set direction, to provide guidance, and to facilitate connecting people and teams" (Highsmith 2000). The values of APM resonate with concepts such as egalitarianism, competence, self-discipline, and self-organization. A leadership-collaboration management style creates a social architecture in which these values flourish.



      Jim Collins (2001) has a similar concept that he refers to as a "culture of discipline," meaning self-discipline, not imposed discipline. In discussing company growth and the frequent imposition of "professional management" to control that growth, Collins says, "The company begins to hire MBAs and seasoned executives from blue-chip companies. Processes, procedures, checklists, and all the rest begin to sprout up like weeds. What was once an egalitarian environment gets replaced with a hierarchy. They create order out of chaos, but they also kill the entrepreneurial spirit. The purpose of bureaucracy is to compensate for incompetence and lack of discipline."



      Or, as Dee Hock (1999) so eloquently puts it, "In the Chaordic Age, success will depend less on rote and more on reason; less on the authority of the few and more on the judgment of the many; less on compulsion and more on motivation; less on external control of people and more on internal discipline." So, the last three guiding principles of APM address how to achieve a leadership-collaboration management style�Encourage Exploration, Build Adaptive (Self-Organizing, Self-Disciplined) Teams, and Simplify.













         < Day Day Up > 



        Section 8.1.&nbsp; The Kick-Off Meeting and Other Presentations










        8.1. The Kick-Off Meeting and Other Presentations



        8.1.1. The Opening Meeting


        At an opening meeting, the assessment sponsor explains to his organization why he has authorized the assessment and what he expects from his people. Depending on the maturity of the organization, the kick-off meeting can last from 30 minutes to one hour. In more mature organizations that have experienced prior assessments, the details of what will happen during the assessment are already known, and the meeting concerns developments since the last assessment and improvement plans for the next year.


        The assessment sponsor, the assessment team members, and all assessment participants must attend the opening meeting. Anyone else whom the sponsor wants to invite can also attend the opening meeting. A broad participation of the organization can enhance understanding and buy-in of the assessment results.


        The organization site coordinator keeps track of which assessment participants are able to attend the opening meeting and those who can't come. If a person who is to be interviewed misses the assessment participants briefing or the opening meeting, he will need to be specially briefed before his interview.


        The logistics for the opening meeting are discussed in advance between the Lead Assessor and the organization site coordinator so that an appropriate room can be scheduled, attendees can be invited, and any other details can be handled, including audio and video equipment.


        After the sponsor finishes his portion of the opening meeting, the Lead Assessor should present the members of the assessment team. Each team member introduces himself or herself and makes a short statement about his or her background.


        The objectives of the opening meeting are to display senior management sponsorship for the assessment clearly and to supply necessary information. Topics addressed should include the assessment principles (above all, confidentialityparticipants must not feel threatened, no matter what they say) and the assessment's objectives. The latter will include a summary of assessment activities conducted to date, an account of activities that are about to occur, the kinds of questions they will be asked, and something about the general conduct of the interviews. The participants are also given an up-to-date schedule of the assessment.


        The senior manager must make it absolutely clear that he or she is the sponsor of the assessment and that he or she fully supports the assessment and subsequent improvement efforts. He or she should make sure that the assessment is one of the organization's top priorities for the onsite period and should insist that people who are scheduled to be interviewed must be available at the scheduled time. The sponsor must also (publicly and privately) encourage the assessment participants to be open and forthcoming and must explain why this is important. Without such a display of sponsorship at the highest level, the authority of the assessment team can be challenged and undermined.


        The sponsor must set the opening meeting as an important event on his or her calendar. Although technically the SEI acknowledges that it might be sufficient "to read a letter of sponsorship from a senior site manager" at the opening meeting, this is recommended only in extreme circumstances. If the senior manager does not take the assessment seriously enough to be present at the opening meeting, why should anyone else take it seriously?



        In one assessment, the managing director was unable to attend the opening meeting because he was called to corporate headquarters at the last minute. However, he arranged for two-way videoconferencing equipment both at the assessment site and at the corporate headquarters site. He opened the meeting and listened to the Lead Assessor's presentation and to his organization's responses. It probably was the next best thing to him actually being there. The people in the organization understood the trouble he had gone to and got the message that the assessment was important.


        On another occasion, the assessment involved an organization that was used to working by telephone conferencing. A time for the opening meeting was selected, and everyone in the organization was required to telephone in, even if it was the middle of the night. They got the message.





        Opening Meeting Features for Organizations with Little Assessment Experience

        If the organization has little assessment or process improvement experience, the opening meeting should also review the fundamental concepts of the software improvement model on which the assessment is based. Explaining how much (or how little) interviewees need to know about the practices of the model can be very useful. Organizations that are struggling with concepts at the repeatable level (Maturity Level 2) especially will gain from full explanations, while such explanations don't need to be as thorough for organizations at or near the managed level (Maturity Level 3) and defined level (Maturity Level 4).





        8.1.2. Other Presentations


        Presentations by the organization to the assessment team can be useful at the beginning of an onsite assessment. Many organizations arrange 30- to 60-minute presentations by project managers about their projects, demonstrations by project teams of what they produce, and briefings by department managers about how they run their departments and how they interact with other departments. Also useful are presentations by directors about organizational strengths and weaknesses or by process improvement managers about future plans.


        These kinds of presentations set the stage for the interviews to come, and they also help organization personnel to relax. In addition, they give managers and developers a forum to voice their most important concerns at the beginning of the assessment.


        When project managers are later interviewed, they are usually more open about their work because they have already established a connection to the members of the team.


        Sometimes it is also useful to arrange short demonstrations or presentations from a few people from the assessed project, even though they are not scheduled to be interviewed. Establishing a connection with as many people as possible in the assessed projects helps the entire organization to "buy in" to the assessment.











          Section 4.8. Programming Examples










          4.8. Programming Examples


          In this section, we will look at examples of programming in the Open Firmware environment. While doing so, we will also come across several device support extensions implemented by Apple's version of Open Firmware. These device-specific extensions allow programs to access the keyboard, mouse, real-time clock (RTC), NVRAM, and so on.



          4.8.1. Dumping NVRAM Contents


          In the example shown in Figure 44, we dump the entire contentsin a raw formatof the NVRAM device. The following relevant methods are provided by the NVRAM device:


          size ( -- <size in bytes> )
          seek ( position.low position.high -- <boolean status> )
          read ( <buffer address> <bytes to read> -- <bytes read> )


          Figure 44. Dumping NVRAM contents





          0 > 0 value mynvram  ok
          0 > " nvram" open-dev to mynvram ok
          0 > " size" mynvram $call-method ok
          1 > . 2000 ok
          0 > 2000 buffer: mybuffer ok
          0 > 0 0 " seek" mynvram $call-method ok
          1 > . fffffff ok
          0 > mybuffer 2000 " read" mynvram $call-method ok
          1 > . 2000 ok
          0 > mybuffer 2000 dump
          ffbba000: 5a 82 00 02 6e 76 72 61 6d 00 00 00 00 00 00 00 |Z...nvram.......|
          ffbba010: bb f1 64 59 00 00 03 3c 00 00 00 00 00 00 00 00 |..dY...<........|
          ffbba020: 5f 45 00 3e 73 79 73 74 65 6d 00 00 00 00 00 00 |_E.>system......|
          ffbba030: 00 02 00 00 64 61 79 74 00 06 00 00 00 00 00 00 |....dayt........|
          ...
          ffbba400: 70 bd 00 c1 63 6f 6d 6d 6f 6e 00 00 00 00 00 00 |p...common......|
          ffbba410: 6c 69 74 74 6c 65 2d 65 6e 64 69 61 6e 3f 3d 66 |little-endian?=f|
          ffbba420: 61 6c 73 65 00 72 65 61 6c 2d 6d 6f 64 65 3f 3d |alse.real-mode?=|
          ffbba430: 66 61 6c 73 65 00 61 75 74 6f 2d 62 6f 6f 74 3f |false.auto-boot?|
          ffbba440: 3d 74 72 75 65 00 64 69 61 67 2d 73 77 69 74 63 |=true.diag-switc|
          ffbba450: 68 3f 3d 66 61 6c 73 65 00 66 63 6f 64 65 2d 64 |h?=false.fcode-d|
          ffbba460: 65 62 75 67 3f 3d 66 61 6c 73 65 00 6f 65 6d 2d |ebug?=false.oem-|
          ffbba470: 62 61 6e 6e 65 72 3f 3d 66 61 6c 73 65 00 6f 65 |banner?=false.oe|
          ffbba480: 6d 2d 6c 6f 67 6f 3f 3d 66 61 6c 73 65 00 75 73 |m-logo?=false.us|
          ffbba490: 65 2d 6e 76 72 61 6d 72 63 3f 3d 66 61 6c 73 65 |e-nvramrc?=false|
          ffbba4a0: 00 75 73 65 2d 67 65 6e 65 72 69 63 3f 3d 66 61 |.use-generic?=fa|
          ffbba4b0: 6c 73 65 00 64 65 66 61 75 6c 74 2d 6d 61 63 2d |lse.default-mac-|
          ffbba4c0: 61 64 64 72 65 73 73 3f 3d 66 61 6c 73 65 00 73 |address?=false.s|
          ffbba4d0: 6b 69 70 2d 6e 65 74 62 6f 6f 74 3f 3d 66 61 6c |kip-netboot?=fal|
          ffbba4e0: 73 65 00 72 65 61 6c 2d 62 61 73 65 3d 2d 31 00 |se.real-base=-1.|
          ffbba4f0: 72 65 61 6c 2d 73 69 7a 65 3d 2d 31 00 6c 6f 61 |real-size=-1.loa|
          ffbba500: 64 2d 62 61 73 65 3d 30 78 38 30 30 30 30 30 00 |d-base=0x800000.|
          ffbba510: 76 69 72 74 2d 62 61 73 65 3d 2d 31 00 76 69 72 |virt-base=-1.vir|
          ffbba520: 74 2d 73 69 7a 65 3d 2d 31 00 6c 6f 67 67 65 72 |t-size=-1.logger|
          ffbba530: 2d 62 61 73 65 3d 2d 31 00 6c 6f 67 67 65 72 2d |-base=-1.logger-|
          ...




          We first open the NVRAM device and query its size, which is reported to be 8KB (0x2000 bytes). We allocate an 8KB buffer to pass to the read method. Before we read from the device, we seek to its beginning. We use the dump word to display the contents of the buffer in a meaningful format. Among the NVRAM's contents, you can see the computer's serial number and the various Open Firmware variables.





          4.8.2. Determining Screen Dimensions


          In this example, we call the dimensions method of the screen device to retrieve the horizontal and vertical pixel counts of the display associated with the device. Alternatively, the screen-width and screen-height words can be used to query this information.


          0 > showstack  ok
          -> <- Empty 0 value myscreen ok
          -> <- Empty " screen" open-dev to myscreen ok
          -> <- Empty " dimensions" myscreen $call-method ok
          -> 1280 854 <- Top 2drop ok
          -> <- Empty




          4.8.3. Working with Colors


          In Open Firmware's default (8-bit) graphics model, each pixel is represented by an 8-bit value that defines the pixel's color. This valuethe color numbermaps to one of 256 colors according to entries in a color lookup table (CLUT). Each entry is a triplet of red, green, and blue (RGB) values. For example, the default CLUT defines color number 0 to be blackcorresponding to the (0, 0, 0) RGB tripletand defines color number 255 to be whitecorresponding to the (255, 255, 255) RGB triplet. The color! and color@ methods of the display device allow individual CLUT entries to be set and retrieved, respectively.


          color@     ( color# -- red blue green )
          color! ( red blue green color# -- )
          get-colors ( clut-dest-address starting# count -- )
          set-colors ( clut-src-address starting# count -- )


          get-colors and set-colors, respectively, can be used to retrieve or set a range of consecutive colors, including an entire CLUT.


          0 > showstack   ok
          -> <- Empty 0 value myscreen ok
          -> <- Empty " screen" open-dev to myscreen ok
          -> <- Empty 0 " color@" myscreen $call-method ok
          -> 0 0 0 <- Top 3drop ok
          -> <- Empty 255 " color@" myscreen $call-method ok
          -> 255 255 255 <- Top 3drop ok
          -> <- Empty foreground-color ok
          -> 0 <- Top drop ok
          -> <- Empty background-color ok
          -> 15 <- Top " color@" myscreen $call-method ok
          -> 255 255 255 <- Top 3drop ok
          -> <- Empty 256 3 * buffer: myclut ok
          -> <- Empty myclut 0 256 " get-colors" myscreen $call-method ok
          -> <- Empty myclut 256 3 * dump
          ffbbc000: 00 00 00 00 aa 00 aa 00 00 ...
          ...
          ffbbd2e0: d5 fd 68 ... ff ff ff
          -> <- Empty


          The foreground-color and background-color words, respectively, fetch the color numbers of the foreground colorsdefined to be 0 (black)and background colorsdefined to be 15 (white). Note that color number 15 also maps to the white color in the default CLUT. This is in accordance with Open Firmware's 16-color text extension, which states that the display driver shall initialize the first 16 colors per a predefined list.




          4.8.4. Drawing a Color-Filled Rectangle


          Open Firmware's graphics extension standard provides a method to draw a color-filled rectangle (fill-rectangle), a method to draw a rectangle using a specified pixel map (draw-rectangle), and a method to read a rectangular pixel map from the display buffer (read-rectangle). Using these methods as primitives, more sophisticated drawing routines can be constructed.


          draw-rectangle ( src-pixmap x y width height -- )
          fill-rectangle ( color# x y width height -- )
          read-rectangle ( dest-pixmap x y width height -- )


          The following program draws a black rectangle that is 100 pixels wide and 100 pixels tall, with its top-left corner at the center of the screen.


          \ fill-rectangle-demo
          \ fill-rectangle usage example

          0 value myscreen
          " screen" open-dev to myscreen

          0 value mycolor

          \ color x y width height
          mycolor screen-width 2 / screen-height 2 / 100 100
          " fill-rectangle" myscreen $call-method


          Running the fill-rectangle-demo program, say, by "booting" it using the TFTP method, should draw the desired black rectangle. Note that the screen's origin, that is, position (0, 0), is located at the top left of the physical display.




          4.8.5. Creating an Animated Solution to the "Towers of Hanoi" Problem


          Given the ability to draw a rectangle at a specified location on the screen, let us look at a more complex example: an animated solution to the Towers of Hanoi problem.[13] We will use the ms word, which sleeps for a specified number of milliseconds, to control the rate of animation. Figure 45 shows the layout and relative dimensions of the objects we will draw on the screen.

          [13] There are three towers arranged left to right. The leftmost tower contains some number of unequally sized disks, arranged such that a smaller disk is never below a larger disk. The objective is to move all the disks to the rightmost tower, one at a time, while using the middle tower as temporary storage. At no time during the transfer may a larger disk be on top of a smaller one.




          Figure 45. The Towers of Hanoi: layout and relative dimensions of on-screen objects

          [View full size image]




          The code for the program can be conveniently divided into two parts: the code for animating and the code for generating moves for the Towers of Hanoi problem. We will use the stack-based algorithm shown as pseudocode in Figure 46 for solving an N-disk Towers of Hanoi problem.



          Figure 46. The Towers of Hanoi: simulating recursion using a stack





          stack = (); /* empty */
          push(stack, N, 1, 3, 0);
          while (notempty(stack)) {
          processed = pop(stack);
          to = pop(stack);
          from = pop(stack);
          n = pop(stack);
          left = 6 - from - to;
          if (processed == 0) {
          if (n == 1)
          movedisk(from, to);
          else
          push(stack, n, from, to, 1, n - 1, from, left, 0);
          } else {
          movedisk(from, to);
          push(stack, n - 1, left, to, 0);
          }
          }




          The movedisk function in Figure 46 is required to graphically move a disk from one tower to another. It could be broken down into distinct steps from an animation standpoint, corresponding to the horizontal and vertical motion of the disk. For example, moving a disk from the left tower to the right tower requires us to first move the disk up on the source tower, move it to the right so that it reaches the destination tower, and finally move it down until it comes to rest in its appropriate position on the destination tower. The code shown in Figure 47 is the first part of the program that provides the following key functionality:


          • Initializes and draws all static graphical objects on the screenthat is, the tower bases, the tower poles, and the specified number of disks on the source tower (hanoi-init)

          • Implements a function to animate the upward motion of a disk (hanoi-disk-move-up)

          • Implements a function to animate the horizontal (left or rightbased on a function argument) motion of a disk (hanoi-disk-move-lr)

          • Implements a function to animate the downward motion of a disk (hanoi-disk-move-down)


          Figure 47. The Towers of Hanoi: Forth code for animation





          \ Towers of Hanoi Demo
          \ Commentary required for "booting" this program.

          \ Configurable values
          variable h-delay 1 h-delay !
          variable h-maxdisks 8 h-maxdisks !

          : hanoi-about ( -- ) cr ." The Towers of Hanoi in Open Firmware" cr ;
          : hanoi-usage ( -- ) cr ." usage: n hanoi, 1 <= n <= " h-maxdisks @ . cr ;

          decimal \ Switch base to decimal

          \ Open primary display
          0 value myscreen
          " screen" open-dev to myscreen

          \ Convenience wrapper function
          : hanoi-fillrect ( color x y w h -- ) " fill-rectangle" myscreen $call-method ;

          \ Calculate display constants

          screen-height 100 / 3 * value h-bh \ 3% of screen height
          screen-width 100 / 12 * value h-bw \ 12% of screen width
          screen-width 4 / value h-xmaxby4 \ 25% of screen width
          screen-height 100 / 75 * value h-th \ 75% of screen height
          h-bh 2 / value h-tw
          screen-height h-th h-bh + - value h-tower-ymin
          screen-height 100 / 2 * value h-disk-height \ 2% of screen height
          screen-width 100 / 1 * value h-disk-delta
          h-tower-ymin h-disk-height - value h-disk-ymin

          \ Colors
          2 value h-color-base
          15 value h-color-bg
          50 value h-color-disk
          4 value h-color-tower

          \ Miscellaneous variables
          variable h-dx \ A disk's x-coordinate
          variable h-dy \ A disk's y-coordinate
          variable h-dw \ A disk's width
          variable h-dh \ A disk's height
          variable h-tx \ A tower's x-coordinate
          variable h-N \ Number of disks to solve for
          variable h-dcolor
          variable h-delta

          3 buffer: h-tower-disks
          : hanoi-draw-tower-base ( n -- )
          h-color-base swap
          h-xmaxby4 * h-bw -
          screen-height h-bh -
          h-bw 2 *
          h-bh
          hanoi-fillrect
          ;

          : hanoi-draw-tower-pole ( tid -- )
          dup 1 - 0 swap h-tower-disks + c!
          h-color-tower swap
          h-xmaxby4 * h-tw -
          screen-height h-th h-bh + -
          h-tw 2 *
          h-th
          hanoi-fillrect
          ;

          : hanoi-disk-width ( did -- cdw )
          h-bw swap h-disk-delta * -
          ;

          : hanoi-disk-x ( tid did -- x )
          hanoi-disk-width ( tid cdw )
          swap ( cdw tid )
          h-xmaxby4 * swap ( [tid * h-xmaxby4] cdw )
          - ( [tid * h-xmaxby4] - cdw )
          ;

          : hanoi-disk-y ( tn -- y )
          screen-height swap ( screen-height tn )
          1 + ( screen-height [tn + 1] )
          h-disk-height * ( screen-height [[tn + 1] * h-disk-height] )
          h-bh + ( screen-height [[[tn + 1] * h-disk-height] + h-bh] )
          - ( screen-height - [[[tn + 1] * h-disk-height] + h-bh] )
          ;

          : hanoi-tower-disks-inc ( tid -- tn )
          dup ( tid tid )
          1 - h-tower-disks + c@ \ fetch cn, current number of disks
          dup ( tid cn cn )
          1 + ( tid cn [cn + 1] )
          rot ( cn [cn + 1] tid )
          1 - h-tower-disks + c!
          ;
          : hanoi-tower-disks-dec ( tid -- tn )
          dup ( tid tid )
          1 - h-tower-disks + c@ \ fetch cn, current number of disks
          dup ( tid cn cn )
          1 - ( tid cn [cn - 1] )
          rot ( cn [cn + 1] tid )
          1 - h-tower-disks + c!
          ;
          : hanoi-tower-disk-add ( tid did -- )
          h-color-disk ( tid did color )
          -rot ( color tid did )
          2dup ( color tid did tid did )
          hanoi-disk-x ( color tid did x )
          -rot ( color x tid did )
          over ( color x tid did tid )
          hanoi-tower-disks-inc ( color x tid did tn )
          hanoi-disk-y ( color x tid did y )
          -rot ( color x y tid did )
          hanoi-disk-width 2 * ( color x y tid w )
          swap ( color x y w tid )
          drop ( color x y w )
          h-disk-height ( color x y w h )
          hanoi-fillrect
          ;

          : hanoi-init ( n -- )

          \ Initialize variables
          0 h-dx !
          0 h-dy !
          0 h-tower-disks c!
          0 h-tower-disks 1 + c!
          0 h-tower-disks 2 + c!

          \ Draw tower bases
          1 hanoi-draw-tower-base
          2 hanoi-draw-tower-base
          3 hanoi-draw-tower-base

          \ Draw tower poles
          1 hanoi-draw-tower-pole
          2 hanoi-draw-tower-pole
          3 hanoi-draw-tower-pole

          \ Add disks to source tower
          1 +
          1
          do
          1 i hanoi-tower-disk-add
          loop
          ;

          : hanoi-sleep ( msec -- )
          ms
          ;

          : hanoi-drawloop-up ( limit start -- )
          do

          h-color-bg
          h-dx @
          h-dy @ i - h-dh @ + 1 -
          h-dw @
          1
          hanoi-fillrect

          h-color-disk
          h-dx @
          h-dy @ i - 1 -
          h-dw @
          1
          hanoi-fillrect

          h-dy @ i - h-disk-ymin >
          if
          h-color-tower
          h-tx @
          h-dy @ i - h-dh @ + 1 -
          h-tw 2 *
          1
          hanoi-fillrect
          then

          h-delay @ hanoi-sleep
          loop
          ;

          : hanoi-drawloop-down ( limit start -- )
          do
          h-color-bg
          h-dx @
          h-disk-ymin i +
          h-dw @
          1
          hanoi-fillrect

          h-color-disk
          h-dx @
          h-disk-ymin i + 1 + h-dh @ +
          h-dw @
          1
          hanoi-fillrect

          i h-dh @ >
          if
          h-color-tower
          h-tx @
          h-disk-ymin i +
          h-tw 2 *
          1
          hanoi-fillrect
          then

          h-delay @ hanoi-sleep
          loop
          ;

          : hanoi-drawloop-lr ( limit start -- )
          do
          h-color-bg
          h-dx @ i +
          h-disk-ymin
          h-dw @
          h-dh @
          hanoi-fillrect

          h-color-disk
          h-dx @ i + h-delta @ +
          h-disk-ymin
          h-dw @
          h-dh @
          hanoi-fillrect

          h-delay @ hanoi-sleep

          h-delta @
          +loop
          ;

          : hanoi-disk-move-up ( tid did -- )
          h-color-disk ( tid did color )
          -rot ( color tid did )
          2dup ( color tid did tid did )
          hanoi-disk-x ( color tid did x )
          -rot ( color x tid did )
          over ( color x tid did tid )
          hanoi-tower-disks-dec ( color x tid did tn )
          1 - ( color x tid tid [tn - 1] )
          hanoi-disk-y ( color x tid did y )
          -rot ( color x y tid did )
          hanoi-disk-width ( color x y tid w )
          swap ( color x y w tid )
          drop ( color x y w )
          h-disk-height ( color x y w h )
          h-dh !
          2 * h-dw !
          h-dy !
          h-dx !
          h-dcolor !
          h-dx @ h-dw @ 2 / + h-tw - h-tx !
          h-dy @ h-disk-ymin -
          0
          hanoi-drawloop-up
          ;

          : hanoi-disk-move-down ( tid did -- )
          h-color-disK ( tid did color )
          -rot ( color tid did )
          2dup ( color tid did tid did )
          hanoi-disk-x ( color tid did x )
          -rot ( color x tid did )
          over ( color x tid did tid )
          hanoi-tower-disks-inc ( color x tid did tn )
          hanoi-disk-y ( color x tid did y )
          -rot ( color x y tid did )
          hanoi-disk-width 2 * ( color x y tid w )
          swap ( color x y w tid )
          drop ( color x y w )
          h-disk-height ( color x y w h )
          h-dh !
          h-dw !
          h-dy !
          h-dx !
          h-dcolor !
          h-dx @ h-dw @ 2 / + h-tw - h-tx !
          h-dy @ h-disk-ymin -
          0
          hanoi-drawloop-down
          ;
          : hanoi-disk-move-lr ( tto tfrom -- )
          2dup <
          if
          \ We are moving left
          1 negate h-delta !
          - h-xmaxby4 * h-delta @ -
          0
          else
          \ We are moving right
          1 h-delta !
          - h-xmaxby4 *
          0
          then

          hanoi-drawloop-lr
          ;

          : hanoi-disk-move ( totid fromtid did -- )
          h-N @ 1 + swap -
          1 pick 1 pick hanoi-disk-move-up
          2 pick 2 pick hanoi-disk-move-lr
          2 pick 1 pick hanoi-disk-move-down
          3drop
          ;




          The functions are subdivided into smaller functions. The hanoi-disk-move function is a harness function that is equivalent to movedisk in Figure 46.


          Now that we have an implementation of movedisk, we can implement the algorithm in Figure 46, which will give us a complete implementation. Figure 48 shows the remaining part of the overall program. Note that we will provide the end user with a simple Forth word called hanoi, which requires one argumentthe number of diskson the stack. Figure 49 shows a screenshot of the running program.


          Figure 48. The Towers of Hanoi: Forth code for the program's core logic





          : hanoi-solve
          begin
          depth
          0 >
          while
          6 3 pick 3 pick + - ( n from to processed left )
          1 pick
          0 =
          if
          4 pick
          1 =
          if
          2 pick
          4 pick
          6 pick
          hanoi-disk-move
          2drop 2drop drop
          else
          ( n from to processed left )
          1 -rot ( n from to 1 processed left )
          swap drop ( n from to 1 left )
          4 pick 1 - swap ( n from to 1 [n - 1] left )
          4 pick swap 0 ( n from to 1 [n - 1] from left 0 )
          then
          else
          ( n from to processed left )
          swap drop ( n from to left )
          1 pick
          3 pick
          5 pick
          hanoi-disk-move
          ( n from to left )
          swap ( n from left to )
          rot drop ( n left to )
          rot 1 - ( left to [n - 1] )
          -rot 0 ( [n - 1] left to 0 )
          then
          repeat
          ;

          : hanoi-validate ( n -- n true|false )
          depth
          1 < \ assert that the stack has exactly one value
          if
          cr ." usage: n hanoi, where 1 <= n <= " h-maxdisks @ . cr
          false
          else
          dup 1 h-maxdisks @ between
          if
          true
          else
          cr ." usage: n hanoi, where 1 <= n <= " h-maxdisks @ . cr
          drop
          false
          then
          then
          ;
          : hanoi ( n -- )
          hanoi-validate
          if
          erase-screen cr
          ." Press control-z to quit the animation." cr
          dup h-N !
          dup hanoi-init
          1 3 0 hanoi-solve
          then
          ;






          Figure 49. Actual photo of the Towers of Hanoi program in Open Firmware












          4.8.6. Fabricating and Using a Mouse Pointer


          In this example, we will write a program to move a "pointer"one that we will fabricateon the screen using the mouse. Moreover, clicking a mouse button will print the coordinates of the click on the screen. We will use the fill-rectangle method to draw, erase, and redraw the pointer, which will be a small square. Opening the mouse device gives us access to its get-event method.


          get-event ( ms -- pos.x pos.y buttons true|false )


          get-event is called with one argument: the time in milliseconds to wait for an event before returning failure. It returns four values: the coordinates of the mouse event, a bit mask containing information about any buttons pressed, and a Boolean value indicating whether an event happened in that interval. An interval of zero milliseconds causes get-event to wait until an event occurs.


          The event coordinates returned by get-event may be absolute (for a device such as a tablet), or they may be relative to the last event, as in the case of a mouse. This implies that the pos.x and pos.y values should be treated as signed or unsigned depending on the type of device. This may be programmatically determined by checking for the presence of the absolute-position property.


          The mouse demonstration program is shown in Figure 410. It starts by drawing a pointer at position (0, 0) and then goes into an infinite loop, waiting for get-event to return. Note that this programand Open Firmware programs in generalcan be interrupted by typing control-z.


          Figure 410. Fabricating and using a mouse pointer in Open Firmware





          \ Mouse Pointer Demo
          \ Commentary required for "booting" this program.

          decimal
          \ Our mouse pointer's dimensions in pixels
          8 value m-ptrwidth
          8 value m-ptrheight

          \ Colors
          foreground-color value m-color-ptr
          background-color value m-color-bg

          \ Variables for saving pointer position
          variable m-oldx 0 m-oldx !
          variable m-oldy 0 m-oldy !
          0 value myscreen
          " screen" open-dev to myscreen

          0 value mymouse
          " mouse" open-dev to mymouse

          : mouse-fillrect ( color x y w h -- )
          " fill-rectangle" myscreen $call-method ;

          : mouse-get-event ( ms -- pos.x pos.y buttons true|false )
          " get-event" mymouse $call-method ;

          : mouse-demo ( -- )
          cr ." Press control-z to quit the mouse demo." cr
          begin
          0
          mouse-get-event
          if
          \ Check for button presses
          0 = ( pos.x pos.y buttons 0 = )
          if
          \ no buttons pressed
          else
          ( pos.x pos.y )
          2dup m-oldy @ + swap m-oldx @ +
          ." button pressed ( " . ." , " . ." )" cr
          then

          m-color-bg ( pos.x pos.y m-color-bg )
          m-oldx @ ( pos.x pos.y m-color-bg m-oldx )
          m-oldy @ ( pos.x pos.y m-color-bg m-oldx m-oldy )
          m-ptrwidth ( pos.x pos.y m-color-bg m-oldx m-oldy )
          m-ptrheight ( pos.x pos.y m-color-bg m-oldx m-oldy )
          mouse-fillrect ( pos.x pos.y )
          m-color-ptr ( pos.x pos.y m-color-ptr )
          -rot ( m-color-ptr pos.x pos.y )
          m-oldy @ ( m-color-ptr pos.x pos.y m-oldy )
          + ( m_color pos.x newy )
          swap ( m-color-ptr newy pos.x )
          m-oldx @ ( m-color-ptr newy pos.x m-oldx )
          + ( m-color-ptr newy newx )
          swap ( m-color-ptr newx newy )
          2dup ( m-color-ptr newx newy newx newy )
          m-oldy ! ( m-color-ptr newx newy newx )
          m-oldx ! ( m-color-ptr newx newy )
          m-ptrwidth ( m-color-ptr newx newy m-ptrwidth )
          m-ptrheight ( m-color-ptr newx newy m-ptrwidth )
          mouse-fillrect
          then
          again
          ;




          Because we are using a mouse, get-event will give us the new position relative to the old one. Therefore, we need to remember the old coordinates. Once we get the new position, we will erase the old pointer and draw one in the new position. For the sake of simplicity, we will not handle the case when the pointer is moved "outside" one of the edges of the screen. Moreover, our mouse pointer is essentially an eraser in the drawing sense too: Since we will not save the region under the pointer, anything that the pointer moves over will be erased as we will simply redraw the newly uncovered region using the background color.


          We can also create an arbitrarily shaped mouse pointer, including a familiar arrow-shaped one that is partially transparent, by using a well-known masking technique. Suppose we wish to create a 5x5 pointer in the shape of an X. If C is the pointer's color and S is the screen background color, then the 5x5 square containing the pointer would look like the following when displayed on the screen:


          C S S S C
          S C S C S
          S S C S S
          S C S C S
          C S S S C


          We can achieve this effect by having two masks: an AND mask and an XOR mask, as shown in Figure 411.


          Figure 411. AND and XOR masks for an X-shaped pointer





          0 1 1 1 0        C 0 0 0 C        S S S S S
          1 0 1 0 1 0 C 0 C 0 S S S S S
          1 1 0 1 1 0 0 C 0 0 S S S S S
          1 0 1 0 1 0 C 0 C 0 S S S S S
          0 1 1 1 0 C 0 0 0 C S S S S S

          AND mask (A) XOR mask (X) Screen (S)




          While displaying the cursor on the screen, we use the following sequence of operations, which yields the desired 5x5 square:


          Snew = (Scurrent AND A) XOR X


          We now need to maintain in-memory bitmaps for the pointer and the region underneath it. Before drawing the contents of the pointer's bitmap on the screen (using draw-rectangle instead of fill-rectangle), we need to perform the masking operation, which will give us the desired partially transparent mouse pointer.




          4.8.7. Stealing a Font


          Apple's Open Firmware includes the terminal-emulator support package, which presents a display framebuffer device as a cursor-addressable text terminal. Another support package, fb8, provides generic framebuffer routines that can be used by display device drivers to perform low-level operations. Thus, there are several ways to display characters on the screen in Open Firmware. We shall devise yet anotherrather contrivedway in this example.


          We will create a function called font-print that takes an input ASCII string and draws it on the screen, starting at a specified pixel location. To achieve this, we will use the display device's draw-rectangle method, which requires a memory address containing data for the rectangle to be drawn. We can consider each character in a font to be contained in an imaginary rectangle. Our program will perform the following operations.


          • Create a font containing ASCII characters.

          • Allocate a font buffer.

          • For each character in the font, store its font data in the font buffer at an offset that either is the same as or is a function of the character's ASCII code.

          • For each character in the input string, calculate the address of its font data in the font buffer and call draw-rectangle to draw the character at an appropriate position on the screen.


          Although these steps appear straightforward, the first step of creating a font is rather arduousat least in our context. We will bypass this step in our example by stealing Open Firmware's default font.


          As our program is booted by Open Firmware, we will output on the screen a template string containing all ASCII characters of interest. Open Firmware provides Forth words to determine the height and width of a character: char-height and char-width, respectively. Since we have a priori knowledge that our string will appear on the first line of the screen, we know the position and dimensions of the screen region containing the template string that we print. We will simply copy this region using read-rectangle, which will give us a ready-made font buffer. Figure 412 shows the implementation of the font-print word.


          Figure 412. Pixel-addressable printing in Open Firmware made possible by stealing a font





          \ Font Demo
          \ Commentary required for "booting" this program.

          decimal

          0 value myscreen
          " screen" open-dev to myscreen
          : font-drawrect ( adr x y w h -- ) " draw-rectangle" myscreen $call-method ;
          : font-readrect ( adr x y w h -- ) " read-rectangle" myscreen $call-method ;

          \ Starts from (x, y) = (4 * 6, 6 + 6 + 11) = (24, 23)
          \ =
          \ _ok
          \ =
          \ 0_>_0123...
          \
          \ ASCII 32 (space) to 126 (~) decimal
          \
          ." ! #$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmno
          pqrstuvwxyz{|}~"
          cr cr
          32 value f-ascii-min
          126 value f-ascii-max
          f-ascii-max f-ascii-min - 1 +
          value f-nchars

          char-height char-width * value f-size

          \ Steal the default font
          variable f-buffer
          f-nchars f-size * alloc-mem
          f-buffer !
          f-nchars
          0
          do
          f-buffer @ f-size i * +
          i char-width *
          4
          char-width
          char-height
          font-readrect
          loop
          erase-screen

          variable f-string
          variable f-x
          variable f-y

          \ If character is not within the supported range, replace it
          : font-validate-char ( char -- char )
          dup
          f-ascii-min f-ascii-max between
          if
          \ ok
          else
          drop
          f-ascii-min
          then
          ;

          \ Print a string starting at a specified position
          : font-print ( string x y -- )
          f-y !
          f-x !
          0
          rot
          f-string !
          do
          f-string @ i + c@
          font-validate-char
          f-ascii-min -
          f-size *
          f-buffer @ +
          f-x @ i char-width * +
          f-y @
          char-width
          char-height
          font-drawrect
          loop
          ;







          4.8.8. Implementing a Clock


          Given the functionality of font-print from Figure 412, we can make a clock appear, say, in a corner of the screen. We will use two additional functions for this: one to retrieve the current time and another that will allow us to update the clock every second.


          Open Firmware provides the get-time function, which retrieves the current time. Calling the function results in six items being pushed on the stack:


          0 > decimal get-time .s -> 32 16 12 20 3 2004 <- Top  ok


          The items are (from the bottom to the top on the stack): seconds, minutes, hours, day of the month, month, and year. For our clock, we will discard the date-related items.


          The alarm function allows us to periodically invoke another function. Thus, we can arrange for a clock-drawing function to be invoked every second. alarm takes two arguments: an execution token of the function to be periodically invoked and the period in milliseconds.



          The method to be periodically invoked through alarm must neither consume any stack items nor leave any items on the stack once it has finished. In other words, this function's stack notation must be ( -- ).




          A function's execution token is its identification. ['] returns the execution token of the function name that follows it, as shown by the following example:


          0 > : myhello ( -- ) ." Hello!" ;  ok
          0 > myhello Hello ok
          0 > ['] myhello . ff9d0a30 ok
          0 > ff9d0a30 execute Hello ok


          Given an execution token of a function, the execute word can be used to execute the corresponding function. Note that retrieving a function's execution token is context-specific: ['] is not a valid way to get a method's execution token inside a word definition, for example.


          The code shown in Figure 413 creates a clock that updates every second. It is displayed at the top-right corner of the screen. Note that (u.) converts an unsigned number into a text string, which is what font-print requires as one of the arguments.


          Figure 413. A clock implemented in the Open Firmware environment





          : mytime ( -- )
          get-time ( seconds minutes hour day month year )
          3drop ( seconds minutes hour )
          swap ( seconds hour minutes )
          rot ( hour minutes seconds )
          (u.) screen-width 2 char-width * - 0 font-print
          " :" screen-width 3 char-width * - 0 font-print
          (u.) screen-width 5 char-width * - 0 font-print
          " :" screen-width 6 char-width * - 0 font-print
          (u.) screen-width 8 char-width * - 0 font-print
          ;

          ' mytime 1000 alarm







          4.8.9. Drawing Images


          In this example, let us examine how to draw images in Open Firmware. In fact, we have already encountered all the functionality required to do so: The draw-rectangle function can draw a memory buffer's contents to screen. The buffer requires the image data to be in an appropriate format. We can make the task easier by choosing to draw the Apple logo drawn during booting, since we can find the corresponding data in the correct format in the bootloader's source code.


          Drawing the Apple logoor any image in generalwill require the logo data and the custom CLUT (if one is needed) to be in memory. The Apple logo data can be found in a C header file called appleboot.h in BootX's source (bootx.tproj/sl.subproj/appleboot.h). The custom CLUT can be found in another header fileclut.hin the same directory as appleboot.h. Both files contain byte arrays that can be readily used with Open Firmware. For example, the CLUT data can be simply passed to set-colors. Thus, we can draw the Apple logo using the following steps.


          • Open the screen device.


          • Call set-colors to set up the custom CLUT.


          • Load the logo data in memory.


          • Call draw-rectangle to draw the logo at the desired position.



          If you wish to draw an arbitrary image, you could do so by converting the image to a format that makes it easy to view the RGB values for each pixel. The ASCII-based portable pixmap (PPM) is such a format. Given a PPM file, we could write a script that reads the file and generates Forth versions of both the CLUT and the image data. Consider the example of a 4x4-pixel image, whose PPM file looks like the one in Figure 414.


          Figure 414. PPM image data for a 4x4-pixel image





          P3
          4 4
          15
          0 0 0 0 0 0 0 0 0 15 0 15
          0 0 0 0 15 7 0 0 0 0 0 0
          0 0 0 0 0 0 0 15 7 0 0 0
          15 0 15 0 0 0 0 0 0 0 0 0




          The first line shown in Figure 414 is a magic number.[14] The second line contains the image's width and height. The value 15 on the third line specifies the maximum decimal value that a color component has. The last four lines contain RGB values for each of the 16 pixels of the image. Since this image has only three distinct RGB triplets, our custom CLUT needs only three entries:

          [14] A constant entity (often a number) used to identify some aspect of another entity. For example, the byte sequence 0xcafebabe, which is used as the beginning of a Universal Binary file, serves as a magic number identifying the file's type.


          decimal
          0 0 0 0 color! \ CLUT entry with index 0
          15 0 15 1 color! \ CLUT entry with index 1
          0 15 7 2 color! \ CLUT entry with index 2



          Since Open Firmware's 8-bits-per-pixel model means a CLUT can have at most 256 entries, you may need to reduce the number of colors in an image before you draw it using the approach described in this example.






          4.8.10. Creating Windows


          Given the various examples discussed so far, we are now in a position to create a window that can be dragged around using the mouse. Doing so may be a worth-while exercise for those interested in learning how to create graphical environments from scratch. We could combine multiple techniques in the following way.


          • Create a "true" mouse pointer using the AND/XOR mask technique.

          • Create a window with a title bar. This is tantamount to creating a related set of rectangles and lines, along with some textual or perhaps graphical window content.

          • Create backing stores for repairing damage to the portions of the screen under the window and the pointer.

          • Move the window, if necessary, in the mouse event handler function.


          Figure 415 shows a rudimentary implementation in Open Firmware of a window that can be dragged.[15]

          [15] The source code for the implementation pictured here is available on this book's accompanying web site (www.osxbook.com).





          Figure 415. A window created using Open Firmware primitives










          Open Firmware provides various other types of functionality that is beyond the scope of this book. For example, you can "talk" to IDE, SATA, and SCSI drives directly in Open Firmware, thus allowing you to fabricate your own command packets to such devices and perform I/O.