The CPU has a somewhat complex way of looking at memory. For all but a few instructions, addresses are treated as sixteen bits wide, but the CPU actually has a 19-bit address bus. This limitation is addressed by using Intel-style segment registers, which are shifted left into the high eight bits of the address and added to the provided 16-bit address to form a 19-bit physical address. This means that each segment is 64 kilowords long and can start on any 2-kiloword boundary. There are three different segment registers, each for a different type of memory access:

CS Code Segment, for instruction fetch.
DSData Segment, for memory access by instructions.
SSStack Segment, for stack access.

Like the 8086 architecture this is borrowed from, this has the odd effect that sufficiently high segment offsets and address values can overflow the 19-bit address space and wrap around to the bottom of address space. When this happens, an Address exception is generated.

While the program counter is 16-bit, program counter arithmetic is performed in 19 bits; this means that relative jumps and branches can cross segment boundaries. Furthermore, when the program counter increment overflows, the CS register is incremented by 32, so that normal code execution automatically crosses segment boundaries.

This address bus is meant only for memory, that is, RAM and ROM. The CPU has another address bus for connected devices, called the port bus. This bus is eight bits wide, so port space ranges from 0x00-FF. It is accessed only by the In and Out instructions. The ports are sixteen bits wide, but some devices may only use the low eight bits.