# inventory

A demo inventory application for the Psion Workabout MX: scan UPC barcodes, and
(Phase 2) keep stock counts in a database file, adding stock or consuming it by
scanning.

Written in PLIB C, built with the TopSpeed compiler (`tsc /m scan`).

## Phases

- **Phase 1 (this commit): scan and validate.** Reads barcodes from the scanner
  and prints each one, flagging whether it is a valid UPC-A.
  Modules: `upc` (validation), `bcode` (scanner input), `scan` (the demo).
- **Phase 2 (next): inventory database.** A DBF file keyed on UPC holding a
  quantity and a name. Scan to add stock (increment, or create on first sight),
  scan to consume by a quantity unit. Built on the SIBO `Dbf*` API.

## Build

```
tsc /m scan
```

Produces `scan.img`. `scan.pr` compiles `upc.c`, `bcode.c` and `scan.c` and
links them.

## How the scanner is read

On the Workabout the barcode module decodes the label in hardware and sends the
result as an RS232 stream, so there is no special barcode driver call: the app
opens the serial port and reads it. The scanner is on the top internal slot,
which is port **D**, so the device is `TTY:D` (`bcode.c`).

The scan loop is blocking: it reads the scanner and prints each barcode; you
exit via the System screen. (An asynchronous scan-or-Esc loop was tried but
panicked the Window Server: on SIBO the keyboard is event-driven through the
window server, not a raw `CON:` byte read, and a proper async loop needs the
Window Server event API, whose reference manual is not in this repo's `docs/`.)

This Phase 1 build also prints the byte length of each decoded barcode, so the
exact format the scanner emits for a UPC can be confirmed before Phase 2 uses
it as a database key.

## Things to confirm on the device

Because this cannot be compiled or run off-device, these points are written to
the SDK docs but may need adjusting once you build and test:

- **Serial line settings.** `bcodeOpen` opens `TTY:D` with the default mode. If
  the scanner needs a specific baud/parity/framing, configure the channel with
  `p_iow(chan, P_FSET, &config)` (E_CONFIG, `p_config.h`) after opening.
- **Terminator.** `BCODE_TERM` in `bcode.h` is set to CR (`0x0D`), the common
  case. Change it if your scanner suffixes LF or something else.
- **Raw scan format.** The build prints `len=NN [text]` per scan. Confirm
  whether a UPC arrives as exactly 12 digits or with extra characters (a
  leading zero / EAN-13, or a symbology prefix); Phase 2 normalises to the
  database key based on this.
