How can I access more than 15 addresses of data from my 8 bit incomplete computer?

the half of the byte in memory is the opcode and other half is the address

Well, that's one way of doing it, but there are lots of ways of doing it.

Instructions don't have to contain the address. Instructions containing the address or operand is usually known as "immediate" mode, but there are various other addressing modes. You could have those four bits tell you which register contains the address to use, and the registers can be longer.

The 6502 has a number of different addressing modes that use its 8-bit registers, its 16-bit program counter, and immediate addresses.

Instructions don't have to be one byte (or word) long. It's certainly easier to do it this way, but you can have multi-byte instructions. X86 is notorious for this; instructions can be anything from one byte long to fifteen if you add enough prefixes and modifiers.

As you can see from the 6502 modes page, there is a "load immediate" mode which has a one byte instruction followed by two bytes defining the address to load from.

(I strongly suggest finding some good non-video sources to learn from, such as "NAND to Tetris")


An approach which has used by the PIC series of microcontrollers since the 1970s is to have a pair of addresses which the PIC refers to as FSR (address 4) and INDF (address 0), but could be given other names. The FSR may be read or written like any other register, but an apparent access to INDF (i.e. an instruction whose address field is all zeroes) will use the address specified in FSR rather than the one specified in the instruction. In some processors, the FSR is 8 bits long even though the instruction address field is only 7; there's no reason the principle couldn't be applied to let a machine with a 4-byte address field access 256 bytes of RAM.

If you want to go beyond 256 bytes, you could add an FSRH register, and make accesses to address zero use address FSRH:FSR. Additionally, instead of using a single FSRH:FSR pair, you could use two of them so that e.g. an access to address 0 would use address FSR1H:FSR1, address 1 would use address FSR2H:FSR2, addresses 4 and 5 would access FSR1 and FSR1H, respectively, and addresses 6 and 7 would access FSR2 and FSR2H. To minimize the amount of circuitry required to handle the register accesses, one could implement FSR1/FSR1H/FSR2/FSR2H as write-only registers (simply use 74HC373 or equivalent), but make accesses to them also access bytes 4-7 of RAM.