16Bit 16Register Computer - 16bit 2Address Instruction Set - 2nd Design author Neil Franklin, last modification 2011.05.29 design features registers+ALU 16bit data 2-address system without dedicated accumulator/temporary 2-operand direct on 16 regs and regindirekt on memory, like in PDP-11 not only reg+mem/reg as in 8086, not only reg+reg as in AVR operations only full 16bit, saves 8/16bit switch instruction bits/space 8bit (only use for packed chars) handled by 8bit rotating decrement-and-jump, like in Z80 and 8048/8051 DJNZ, save separate DEC time in particular fast block copy, together with auto-postincrement strictly also possible design for 32bit (or even 64bit) computer memory 16bit address, word addressed 16bit programm counter all branches (conditional) w 6bit offset, similar 6800/6802 6809 6502 and fitting also jump (uncondit) variant w 6bit offset, like 6809 8086 only register based addressing, full 16bit full 16bit stack pointer, not 8bit part-of-memory stack stack pointer one of the general purpose registers, for more flexible full 16bit address registers, register indirect memory adressing to prevent slow memory-indirect addressing, unlike 6800/6802 or 6502 but can double as normal data registers, not only-16bit like 6809 mult registerr indirect memory accesses, like in 8048/8051 and 6809 address registers with autoincrement/decrement, save separate INX/DEX time like in 6809 registers, and in Z80 LD[ID]/CP[ID], but no LD[ID]R/CP[ID]R IO space 4bit address separate IO space, to not cut off small stuff from large memory Instructions 16bit opcodes, must be word alligned, no bit addresses if 32bit (or even 64bit) computer, then word as instruction bundle requires "byte" addressbits extension of program counter jump simply sets these to 0, can only jump to begin of an bundle undecided how to handle these when call/return, mult calls in one bundle in 32bit possibly require call always be 2*16bit and 32bit alligned in 64bit unlikely require call always be 64bit alligned hex friendly 4+4+4+4bit format instr, not n*(2+3+3)bit or even worse format call(1)+op(3)+mode-s2(2)+mode-s1-d(2)+addr-s2(4)+addr-s1-d(4) with special cases of mode-s2(2) as op(2) and addr-s2(4) as op(4) possibly for nibbleserial or bitserial reverse, call(1) at bit 0 result is a mixture of multiple previous designs of mine shows how much the 16bit_16Reg_16bit_2Addr (and 8 and 8or16) can be approved with the many ideas that merged in the 8bit_64Reg_8bit_1or2Addr I consider it to be about the optimally possible 16bit register design from 16bit_16Reg_16bit_2Addr 16bit without any 8bit operations, back to 16bit instructions from Novix NC4000 (mid 1980s 16bit Forth Processor) 1bit subroutine call with 15bit address in it from 8bit_16Reg_16bit_2Addr (6800/6802 and 8086/8088 influences in it) 4bit/16combinations as conditions for branch instructions from 8bit_16Reg_16bit_2Addr (and 8bit_16Reg_16bit_2Addr) (AVR influences) 2-address, 2-ported register file interrupt request as flag (not just interrupt enable) from 16bit_16Reg_16bit_2Addr (and 8bit_16Reg_16bit_2Addr) (PDP-11 influences) 2-address instructons with 2 full any register/memory mode operands from 8bit_64Reg_8bit_1or2Addr (and also direct PDP-11 influences) fully orthogonal use of all registers, also all as memory addresses only without memory-indirect, so 3->2bit mode and instead 3->4bit regaddr and indexed/relative replaced by the elsewise lost register indirect and without 1bit byte/word switch, and consequently only word operations and instead using this bit for 1bit+15bit address subroutine call from 8bit_Accu8Reg_8bit_1Addr (8080 influences in it) 1 cycle interrupt lockout after enabling from 8bit_Accu8Reg_8bit_1Addr (Z80 influences in it) DJNZ-style down-counter loops (but with any register, and name DBN) from 8bit_Accu8Reg_8bit_1Addr (6800/6802 influences in it) shift/rotate of memory, not just accu (and all 5 ops this time) style and partially selection or flags, overflow, not parity, set on LDA from 8bit_Accu8Reg_8bit_1Addr (6809 influences in it) auto-increment/decrement addressing modes jump and branches short and long prog counter relative, with 10-style prfix call also long program counter relative use ANF and ORF for setting flags, interrupt enable as flag (not int mask) and also AVR/PDP-8/own int request and proc halt and proc reset as flags from 8bit_Accu8Reg_8bit_1Addr (6502 influences in it) entirely 3 character mnemonic names (but not extreme as on 8008) registers 16bit R0..R15 orthogonal general purpose data and address registers with R0 or R15 as stackpointer S, use [--S]/[S++] for PSH/POP 16bit P program counter, dedicated, not in arithmetic or very unlikely R0 or R15 as P, stifting S to R1 or R14 8bit F flags status flags are: 7:Minus 6:Overflow 1:Zero 0:Carry changed when Arith/Shift all MOZC, Logic/Load only MZ control flags are: 5:ProcReset 4:ProcHalt 3:IntReqest 2:IntEnable setting IntEnable has an automatic 1-cycle delay, allows using PPF or ORF #$04; *locked*; RTS; *unlocked* for return from interrupt setting ProcHalt halts the processor until interrupt or reset is applied memory 64k*16bit general purpose program and data memory, word addressed alternatively 32k*2*8bit memory, byte addressed, possibly auto-ByteSWAP or 4G*32bit, word addressed, if 32bit computer alternatively 1G*4*8bit memory, byte addressed, possibly auto-ByteROT 16*16bit separate IO space, only 4bit constant addressing requires one address to be an device select register instructions 1aaa aaaa aaaa aaaa call instructions JSR with 15bit constant address, [--S]=P; P=aaa..a either P=0aaa..a, subroutines only start in first 32k 16bit words better P=aaa..a0. subroutines only start on every second address possibly if memory byte addressed, subroutines only byte-pair alligned alternative JSR with signed 15bit relative offset, inside code but further requires other JSR, with computed or 16bit immediate address no opcode space for this, must use MOV/PSH and JMP computed/immediate if 32bit, followed by further 16bit immediate, for 15+16bit, using 14+16bit this will allow to have another 16k opcodes free, currently reserved alternative use first bit for converting ss ssss to an 6bit constant source2 gives short form instead of always 2-word [P++] 16bit immediate but at price of all calls being then 2-word [P++] 16bit immediate as such shortens and speeds up low level calculating routines while lengthening and slowing all high level call series routines full memory kills, slow processsing only waits, so compact JSR preferable 0ooo dddd ddss ssss 2-address arithmetic instructions ooo operation: 000 used for non dest+s1 instructions (because P as destination) 001 used for non source2 instructions (because 1-addr or immed or IO) 010 = ADD, with dd dddd + ss ssss 011 = SUB, with dd dddd - ss ssss 100 = MOV, with dd dddd = ss ssss 101 = AND, with dd dddd & ss ssss 110 = IOR, with dd dddd | ss ssss 111 = XOR, with dd dddd ^ ss ssss dddd dest+s1 regaddr: register 0..15 dd dest+s1 mode: for destination (and first source), format: 00 = register dddd direct 01 = register dddd indirect memory 10 = register dddd indirect memory, autopostincrement, with rd stack POP 11 = register dddd indirect memory, autopredecrement, with wr stack PUSH unlikely instead offer autopredecrement offer indexed in that case for stack PSH need MOV with partially autopredecrement ss source2 mode: for second source, same format as dd ssss source2 regaddr: same format as dddd 0001 dddd ddoo oooo non source2 instructions (because 1-addr or immed or INP) oo operation: 00 = dest+s 1-address instructions (no source2) oooo operation: 0000 = CRY, with dd dddd (carry as 0/1 into dd dddd, for "ADC") 0001 = BRW, with dd dddd (carry/borrow as 0/-1 into dd dddd, for "SBC") 0010 = INC, with dd dddd (short duplicate of ADD dd dddd + immed 1) 0011 = DEC, with dd dddd (short duplicate of SUB dd dddd - immed 1) 0100 = SWP, with dd dddd (2*8bit byte swap) 0101 = SEX, with dd dddd (2*8bit byte sign extend) 0110 = CLR, with dd dddd (mem faster duplic of XOR dd dddd ^ same) 0111 = SET, with dd dddd (short duplicate of MOV dd dddd = immed -1) 1000 = INV, with dd dddd (short duplicate of XOR dd dddd = immed -1) 1001 = NEG, with dd dddd (short duplicate of SUB 0 - dd dddd) 1010 = ABS, with dd dddd (if negative then NEG else NOP) 1011 = SAR, with dd dddd (arithmetical shift, bit7=bit7) 1100 = SHL, with dd dddd (mem faster duplic of ADD dd dddd & dame) 1101 = SHR, with dd dddd (logical shift, bit7=0) 1110 = ROL, with dd dddd (9bit with bit0=carry, no duplic as no ADC) 1111 = ROR, with dd dddd (9bit with bit7=carry) 01 = dest+s1 and and immediate source2 instructions (ss ssss = [P++]) oooo operation: 0000 used for non dest+s1 and s2 instr (dddd dd = P or OUT and immed) 0001 reserved 0010 = ADD or ADI, with dd dddd + immediate 0011 = SUB or SBI, with dd dddd - immediate 0100 = MOV or MVI, with dd dddd = immediate 0101 = AND or ANI, with dd dddd & immediate 0110 = IOR or ORI, with dd dddd | immediate 0111 = XOR or XRI, with dd dddd ^ immediate 1000 = PSM push multiple, with immed as 16bit pattern of registers 1001 = PPM pop multiple, with immed as 16bit pattern of registers 1010 = PSF push flags, ignores immed (or XOR flags with immed?) 1011 = PPF pop flags, ignores immed (or XOR flags with immed?) 1100 = MVF MOV/load flags, with immed as 8of16bit pattern of flags 1101 = ANF AND/clear flags, with immed as 8of16bit pattern of flags 1110 = ORF IOR/set flags, with immed as 8of16bit pattern of flags 1111 = XRF XOR/invert flags, with immed as 8of16bit pattern of flags the first half of these are redundant if P is in regs, use normal [reg++] possibly handle flags as IO, drop PSF/PPF and MVF/ANF/ORF/XRF if done so also drop other special case for PSM/PPM 10 reserved 11 = INP, with dd dddd only dest, oooo as aaaa 4bit const IO address dddd dest+s|dest+s1 regaddr: same format as above dd dest+s|dest+s1 mode: same format as above 0000 oooo ooss ssss non dest+s1 instructions (because dddd dd = P or OUT) oo operation: 0x = NOP/JMP/BRA, with oooo as fffv (flag and value) condition fff = condition flag: 1/ZorC/MxorO/Zor(MxorO)/Carry/Zero/Overflow/Minus fff=000(1) and val=0 does nothing, is NOP fff=000(1) and val=1 gives unconditional JMP fff<>000 and val=any gives 14 BRA variants v = condition value: 0/1 fffv combination: 0000 = NOP "1" test clear (= never) 0001 = JMP "1" test set (= always) 0010 = BPC positiv test clear, = BHI subtr s2 higher (unsigned) 0011 = BPS positiv test set, = BLS subtr s2 lower or same (unsigned) 0100 = BRC range test clear, = BGE subtr s2 greater or equal (signed) 0101 = BRS range test set, = BLT subtr s2 less than (signed) 0110 = BSC sign test clear, = BGT subtr s2 greater than (signed) 0111 = BSS sign test set, = BLE subtr s2 less or equal (signed) 1000 = BCC carry flag clear, = BHS subtr s2 higher or same (unsigned) 1001 = BCS carry flag set, = BLO subtr s2 lower (unsigned) 1010 = BZC zero flag clear, = BNE subtr non equal 1011 = BZS zero flag set, = BEQ subtr equal 1100 = BOC overflow flag clear 1101 = BOS overflow flag set 1110 = BMC minus flag clear 1111 = BMS minus flag set oo 00 = with ss ssss signed 6bit relative offset, P = +/- 32Words/64Bytes oo 01 = with ss ssss normal source2 mode+regaddr, P = computed address with [S++] is JMP POP stack, gives RTS (return subroutine) 10 = DBN, with oooo as dddd dest+s1 regaddr (reg direct only, no mem modes) is decrement branch nonzero, dest+s1 reg -1, with no flags changed with ss ssss signed 6bit relative offset, P = P+/-32Words/64Bytes 11 = OUT, with oooo as aaaa 4bit const IO address with ss ssss normal source2 mode+regaddr data 0001 oooo oo01 0000 non dest+s1 and s2 (dddd dd = P or OUT, ss ssss = [P++]) oo operation: 0x = NOP/JMP/BRA, with oooo as fffv (flag and value) condition fff and v are the same combinations as above in 0 000 fffv 0x ss ssss oo x0 = with immed(ss ssss = [P++]), P +/- signed 16bit relative offset oo x1 = with immed(ss ssss = [P++]), P = 16bit immediate address 10 = DBN, with oooo as dddd dest+s1 regaddr (reg direct only, no mem modes) dddd are the same dest+s1 regaddr as above in 0 000 dddd 1x ss ssss with immed(ss ssss = [P++]), P +/- signed 16bit relative offset 11 = OUT, with oooo as aaaa 4bit const IO address with immed(ss ssss = [P++]) 16bit immediate data