Skip to content

Everything is a Database

Julie Montoya edited this page May 20, 2021 · 1 revision

Everything Is a Database

In BCP, everything is treated as a database. The parts list says which footprint is associated with each component in the design and where on the board it is positioned. The footprints themselves are held in a database, which gives the instructions to draw them on the screen or the photoplotter. The wiring list says which pin of each component in the design is connected to which circuit node. When we are wiring a track, we ensure that the destination is connected to the same circuit node in the wiring list as the starting pin.

The database has several tables (relations) which are layered thus:

  1. The Apertures table determines what size and shape aperture will be used to plot various features, and the sizes of holes to use for vias (connections from one side of the board to the other, away from a component pin). It is necessary to specify some apertures to begin with, before it is possible to define any footprints.
  2. The Footprints table defines how a component is drawn: the positions and apertures for pads on the copper layers and the sizes of any holes drilled through them, and a series of instructions to draw its outline on the silkscreen layer. It is necessary to define a footprint for each component that will be used in a design.
  3. The Parts List determines which footprint is used for each component in the design, where and how on the board it is positioned, and supplies the address of the component's entry in the wiring list.
  4. The Wiring List determines the circuit node to which each pin of each component is connected. The Parts List and Wiring List tables are created initially from a wiring list file. This is similar to (and syntactically valid as) a SPICE input file with additional, BCP-specific data fields in a *comment following each component value. The wiring list must be generated separately; either by hand or using some host-side schematic capture tool, and modifying the output with your favourite text editor. It gets modified as components are moved about.
  5. The Routes table determines how connections are routed, with each contiguous section of track being split into a series of waypoints.
    This table is generated by the interactive design process.

Extensive use is made throughout of the 6502's (zp),Y addressing mode, including to populate zero-page pointers for a second level of indirect addressing.

The Database Structure

The diagram below shows the structure of the database, with the number of bytes assigned to each element. Values packed as bits are shown as fractional numbers of bytes, i.e. 1/2 for a nybble, 1/8 for a bit.

4       2                       1              1
ROUTE---WAYPOINTS LIST OFFSET---CIRCUIT NODE---LENGTH
          |
      1 STARTING LAYER + WIDTH
      3 WAYPOINT 1
      3 WAYPOINT 2
          ...
      3 WAYPOINT n

3                3/2             3/2
WAYPOINT---------X CO-ORDINATE---Y CO-ORDINATE
   OR-----------------COMPONENT------------PIN
   OR-----------------LAYER--------------WIDTH

8           2            2                    3          1/8    2/8     5/8
COMPONENT---DESIGNATOR---WIRING LIST OFFSET---POSITION---SIDE---ANGLE---FOOTPRINT
                           |                              |       |       |
                       1 NODE PIN 1                       |       |     PIN COUNT
                       1 NODE PIN 2                       |     ROTATION SUBROUTINE
                           ...                           FLIP SUBROUTINE
                       1 NODE PIN n
2
DESIGNATOR---|L|L|L|L|L|L|N|N|---|N|N|N|N|N|N|N|N|
                |         |
                |        |0|0|   |0|0|0|0|0|0|0|0| = 1
                |     TO |1|1|   |1|1|1|0|0|1|1|1| = 999
                |
             |0|0|0|0|0|0| => SINGLE LETTER
          TO |0|1|1|0|1|0|
             |1|x|x|x|x|x| => LETTER PAIR

23          7      1           6          4        2             2                   1
FOOTPRINT---NAME---PIN COUNT---BOUNDARY---LEGEND---PINS OFFSET---SILKSCREEN OFFSET---SILKSCREEN LENGTH
                                 |          |         |             |
                               LEFT X       X       PIN 1         VERTEX 1
                               BOTTOM Y     Y       PIN 2         VERTEX 2
                               RIGHT X    ANGLE      ...            ...
                               TOP Y      SIZE      PIN n         VERTEX n

5     3/2             3/2             1/2                1/2                 1  
PIN---X CO-ORDINATE---Y CO-ORDINATE---MOUNTED SIDE PAD---OPPOSITE SIDE PAD---HOLE

3                   11/8            11/8            2/8
SILKSCREEN VERTEX---X CO-ORDINATE---Y CO-ORDINATE---PLOT MODE
                 ---|K1|X7|X6|X5|X4|X3|X2|X1|---|K0|Y7|Y6|Y5|Y4|Y3|Y2|Y1|---|YB|YA|Y9|Y8|XB|XA|X9|X8|

OTHER CO-ORDINATES--|X7|X6|X5|X4|X3|X2|X1|X0|---|Y7|Y6|Y5|Y4|Y3|Y2|Y1|Y0|---|YB|YA|Y9|Y8|XB|XA|X9|X8|

Searching

BCP uses a simple linear search technique, which is good enough for a database of this size. Much of the data is already stored in packed representation. We do not need to unpack it to search it, if we just want a simple same/different test; we can pack up the search term and look for its packed representation, moving on as soon as a match becomes impossible, and avoid unnecessary searches by using direct indexing wherever possible.

The slowest search is always for a component pin connected to a given node; we have to unpack each component's footprint in turn to get the number of pins, so we know how far to search before giving up and moving onto the next component. In the worst case, this could involve almost two full passes through the parts list to determine there is no connected pin.

Alternative idea. Search forwards through wiring data without caring which component the current pin belongs to. Search backwards through parts list until start of part wiring data is before or at current location in wiring list. Determine pin within part by subtracting location of first pin from current location.

Where records are directly indexed, we simply multiply the record length by the record number and add the base address. We can do this "for free" by simply copying the base address into the preload register, and entering the multiply subroutine after this would have been zeroed.

Fixed and Variable Length Records

Fixed-length records are stored in a flat list. A record is retrieved by multiplying the record length by the record number and adding a base address. This gives an address within the list which is stored in a pair of bytes in zero page. The (zp),Y addressing mode is then used to access individual bytes within the record.

Variable-length records require an associated fixed-length record, giving (at least) an offset into a list and the length of the record. The offset is added to the base address of the list and stored in a pair of bytes in zero page. The (zp),Y addressing mode is used to access the record, and allows a maximum record length of 256 bytes.

Components

Each component has an 8-byte entry in a parts list with its designator, positioning information, the index of its footprint (so as to avoid a search and afford a space saving) and a pointer into the wiring list, which contains the node numbers to which each pin of the component is connected. (The number of pins is part of the footprint record.)

The rotation angle and mounted side actually specify the addresses of a pair of subroutines which are used in transforming co-ordinates from the space within a component footprint to the design space.

Footprints

A component footprint includes details of each pin, the silkscreen outline and some additional data. The pin data consists of a 5-byte record for each pin; the silkscreen outline consists of a series of co-ordinate pairs and plot modes packed into 3-byte records. Each footprint also has a name, up to 7 characters long, giving a total record length of 23 bytes.

Wiring

A routed track consists of a starting layer and width (packed into one byte) followed by series of waypoints; each of which is a 3-byte record which may represent an X,Y co-ordinate pair, a component (directly indexed so as to avoid an unnecessary search) and pin or a layer/width change. It also has an associated circuit node. The offset into the list of waypoints, length and node number are stored in a 4-byte record.