[= Demo - Simple block diagram Command: buses.bat =] [= main layout parameters =] Number BusLength = 400; Number BusWidth = 40; Number ArrowLen = 60; Number ArrowWidth = 20; Number BoxHeight = 50; Number BoxWidth = 80; Number UnitSize = 100; [= derived layout parameters =] Number LowerBusOffset = BusWidth + BoxHeight + 2 * ArrowLen; Program() Begin [= write the whole diagram at the desired location =] Diagram() => {40, 40}; End; [= DIAGRAM ------- Draw the whole diagram. All position relative to the top left corner of diagram. =] Shape Diagram() Begin [= draw the two buses =] Bus(BusLength, BusWidth, "Address Bus"); Bus(BusLength, BusWidth, "Data Bus") => { 0, LowerBusOffset}; [= link the three units to the buses =] LinkedUnit(UnitSize, "CPU"); LinkedUnit(2 * UnitSize, "Memory"); LinkedUnit(3 * UnitSize, "I/O"); End; [= BOX --- Draw a label box for a unit. =] Shape Box(Number width, Number height, Text boxname) Begin [= draw he box =] Rectangle(width, height) => { -width / 2, 0 }; [= label it =] TextBlock(boxname,halign -> Centre, valign -> Centre) => { 0, height / 2}; End; [= BUS --- Draw the label bus. =] Shape Bus(Number length, Number width, Text busname) Begin [= draw top line of width =] LineTo( { length, 0 } ); [= shift down by width =] LineTo( { length, 0 } ) => { 0, width }; [= write the name =] TextBlock(busname, halign -> Centre, valign -> Centre) => { length / 2, width / 2}; End; [= ARROW ----- Draw an arrow from the bus to the unit. Length = total length including head. Origin: Centre of the tail. =] Shape Arrow(Number length, Number width, Logical down) Number sign; [= based on direction =] Number hwidth = width // 2; [= half the width =] Number shaftlen = length - width; [= length of arrow excluding the head =] Begin [= set the sigh based on the direction =] If down Then sign := 1; Else sign := -1; EndIf; [= clear the section of bus edge where it joins =] Line( { -hwidth, 0}, { hwidth, 0} ) => Pen { colour -> { 100,100,100 } }; [= the two sides of the shaft =] Line( { -hwidth, 0}, {-hwidth, sign * shaftlen} ); Line( { hwidth, 0}, {hwidth, sign * shaftlen} ); [= the two side arms - back of the arrow head =] Line( {-hwidth, sign * shaftlen}, {-width, sign * shaftlen} ); Line( {hwidth, sign * shaftlen}, { width, sign * shaftlen} ); [= the two sides of the tip =] Line ( {-width, sign * shaftlen}, { 0, sign * length }); Line ( { width, sign * shaftlen}, { 0, sign * length }); End; [= LINKED UNIT ----------- Link a unit between the two units. =] Shape LinkedUnit(Number offset, Text boxname) Begin [= arrow form the upper bus =] Arrow(ArrowLen, ArrowWidth, True) => { offset, BusWidth }; [= the unit box itself =] Box(BoxWidth, BoxHeight, boxname) => { offset, BusWidth + ArrowLen}; [= arrow from the lower bus =] Arrow(ArrowLen, ArrowWidth, False) => { offset, LowerBusOffset }; End;